]> git.tuebingen.mpg.de Git - paraslash.git/blobdiff - aft.c
README,INSTALL: Fix some spelling errors.
[paraslash.git] / aft.c
diff --git a/aft.c b/aft.c
index 362ce1cccca09e5f54e7447063076b851a8fc532..bcceb4b0b7911707f88644c6f505189db2189934 100644 (file)
--- a/aft.c
+++ b/aft.c
@@ -1642,60 +1642,99 @@ int com_add(int fd, int argc, char * const * const argv)
 
 }
 
+enum touch_flags {
+       TOUCH_FLAG_FNM_PATHNAME = 1,
+       TOUCH_FLAG_VERBOSE = 2
+};
+
 struct com_touch_options {
-       long num_played;
-       long last_played;
-       long lyrics_id;
-       long image_id;
+       int32_t num_played;
+       int64_t last_played;
+       int32_t lyrics_id;
+       int32_t image_id;
+       unsigned flags;
 };
 
-static int com_touch_callback(const struct osl_object *query,
-               __a_unused struct osl_object *result)
+struct touch_action_data {
+       struct com_touch_options *cto;
+       struct para_buffer pb;
+};
+
+static int touch_audio_file(__a_unused struct osl_table *table,
+               struct osl_row *row, const char *name, void *data)
 {
-       struct com_touch_options *cto = query->data;
-       char *p = (char *)query->data + sizeof(*cto);
-       size_t len;
-       int ret, no_options = cto->num_played < 0 && cto->last_played < 0 &&
-               cto->lyrics_id < 0 && cto->image_id < 0;
-
-       for (;p < (char *)query->data + query->size; p += len + 1) {
-               struct afs_info old_afsi, new_afsi;
-               struct osl_object obj;
-               struct osl_row *row;
+       struct touch_action_data *tad = data;
+       struct osl_object obj;
+       struct afs_info old_afsi, new_afsi;
+       int ret, no_options = tad->cto->num_played < 0 && tad->cto->last_played < 0 &&
+               tad->cto->lyrics_id < 0 && tad->cto->image_id < 0;
 
-               len = strlen(p);
-               ret = aft_get_row_of_path(p, &row);
-               if (ret < 0)
-                       return ret;
-               ret = get_afsi_object_of_row(row, &obj);
-               if (ret < 0)
-                       return ret;
-               ret = load_afsi(&old_afsi, &obj);
-               if (ret < 0)
-                       return ret;
-               new_afsi = old_afsi;
-               if (no_options) {
-                       new_afsi.num_played++;
-                       new_afsi.last_played = time(NULL);
-               } else {
-                       if (cto->lyrics_id >= 0)
-                               new_afsi.lyrics_id = cto->lyrics_id;
-                       if (cto->image_id >= 0)
-                               new_afsi.image_id = cto->image_id;
-                       if (cto->num_played >= 0)
-                               new_afsi.num_played = cto->num_played;
-                       if (cto->last_played >= 0)
-                               new_afsi.last_played = cto->last_played;
-               }
-               save_afsi(&new_afsi, &obj); /* in-place update */
-               ret = mood_update_audio_file(row, &old_afsi);
-               if (ret < 0)
-                       return ret;
+       ret = get_afsi_object_of_row(row, &obj);
+       if (ret < 0) {
+               para_printf(&tad->pb, "%s: %s\n", name, PARA_STRERROR(-ret));
+               return 1;
+       }
+       ret = load_afsi(&old_afsi, &obj);
+       if (ret < 0) {
+               para_printf(&tad->pb, "%s: %s\n", name, PARA_STRERROR(-ret));
+               return 1;
+       }
+       new_afsi = old_afsi;
+       if (no_options) {
+               new_afsi.num_played++;
+               new_afsi.last_played = time(NULL);
+               if (tad->cto->flags & TOUCH_FLAG_VERBOSE)
+                       para_printf(&tad->pb, "%s: num_played = %u, "
+                               "last_played = now()\n", name,
+                               new_afsi.num_played);
+       } else {
+               if (tad->cto->flags & TOUCH_FLAG_VERBOSE)
+                       para_printf(&tad->pb, "touching %s\n", name);
+               if (tad->cto->lyrics_id >= 0)
+                       new_afsi.lyrics_id = tad->cto->lyrics_id;
+               if (tad->cto->image_id >= 0)
+                       new_afsi.image_id = tad->cto->image_id;
+               if (tad->cto->num_played >= 0)
+                       new_afsi.num_played = tad->cto->num_played;
+               if (tad->cto->last_played >= 0)
+                       new_afsi.last_played = tad->cto->last_played;
        }
+       save_afsi(&new_afsi, &obj); /* in-place update */
+       ret = mood_update_audio_file(row, &old_afsi);
+       if (ret < 0)
+               para_printf(&tad->pb, "%s: %s\n", name, PARA_STRERROR(-ret));
        return 1;
 }
 
-int com_touch(__a_unused int fd, int argc, char * const * const argv)
+static int com_touch_callback(const struct osl_object *query,
+               struct osl_object *result)
+{
+       struct touch_action_data tad = {.cto = query->data};
+       int ret;
+       struct pattern_match_data pmd = {
+               .table = audio_file_table,
+               .loop_col_num = AFTCOL_HASH,
+               .match_col_num = AFTCOL_PATH,
+               .patterns = {.data = (char *)query->data + sizeof(*tad.cto),
+                       .size = query->size - sizeof(*tad.cto)},
+               .data = &tad,
+               .action = touch_audio_file
+       };
+       if (tad.cto->flags & TOUCH_FLAG_FNM_PATHNAME)
+               pmd.fnmatch_flags |= FNM_PATHNAME;
+       ret = for_each_matching_row(&pmd);
+       if (ret < 0)
+               para_printf(&tad.pb, "%s\n", PARA_STRERROR(-ret));
+       if (tad.pb.buf) {
+               result->data = tad.pb.buf;
+               result->size = tad.pb.size;
+               return 1;
+       }
+       return ret < 0? ret : 0;
+}
+
+
+int com_touch(int fd, int argc, char * const * const argv)
 {
        struct com_touch_options cto = {
                .num_played = -1,
@@ -1703,7 +1742,8 @@ int com_touch(__a_unused int fd, int argc, char * const * const argv)
                .lyrics_id = -1,
                .image_id = -1
        };
-       struct osl_object options = {.data = &cto, .size = sizeof(cto)};
+       struct osl_object query = {.data = &cto, .size = sizeof(cto)},
+               result;
        int i, ret;
 
 
@@ -1716,36 +1756,48 @@ int com_touch(__a_unused int fd, int argc, char * const * const argv)
                        break;
                }
                if (!strncmp(arg, "-n", 2)) {
-                       ret = para_atol(arg + 2, &cto.num_played);
+                       ret = para_atoi32(arg + 2, &cto.num_played);
                        if (ret < 0)
-                               goto err;
+                               return ret;
                        continue;
                }
                if (!strncmp(arg, "-l", 2)) {
-                       ret = para_atol(arg + 2, &cto.last_played);
+                       ret = para_atoi64(arg + 2, &cto.last_played);
                        if (ret < 0)
-                               goto err;
+                               return ret;
                        continue;
                }
                if (!strncmp(arg, "-y", 2)) {
-                       ret = para_atol(arg + 2, &cto.lyrics_id);
+                       ret = para_atoi32(arg + 2, &cto.lyrics_id);
                        if (ret < 0)
-                               goto err;
+                               return ret;
                        continue;
                }
                if (!strncmp(arg, "-i", 2)) {
-                       ret = para_atol(arg + 2, &cto.image_id);
+                       ret = para_atoi32(arg + 2, &cto.image_id);
                        if (ret < 0)
-                               goto err;
+                               return ret;
+                       continue;
+               }
+               if (!strcmp(arg, "-p")) {
+                       cto.flags |= TOUCH_FLAG_FNM_PATHNAME;
+                       continue;
+               }
+               if (!strcmp(arg, "-v")) {
+                       cto.flags |= TOUCH_FLAG_VERBOSE;
                        continue;
                }
+               break; /* non-option starting with dash */
        }
-       ret = -E_AFT_SYNTAX;
        if (i >= argc)
-               goto err;
-       return send_option_arg_callback_request(&options, argc - i,
-               argv + i, com_touch_callback, NULL);
-err:
+               return -E_AFT_SYNTAX;
+       ret = send_option_arg_callback_request(&query, argc - i,
+               argv + i, com_touch_callback, &result);
+       if (ret > 0) {
+               send_buffer(fd, (char *)result.data);
+               free(result.data);
+       } else
+               send_va_buffer(fd, "%s\n", PARA_STRERROR(-ret));
        return ret;
 }
 
@@ -1841,6 +1893,7 @@ int com_afs_rm(int fd, int argc,  char * const * const argv)
                        flags |= RM_FLAG_VERBOSE;
                        continue;
                }
+               break;
        }
        if (i >= argc)
                return -E_AFT_SYNTAX;