]> git.tuebingen.mpg.de Git - paraslash.git/blobdiff - aft.c
afs: Rename callback_function to afs_callback.
[paraslash.git] / aft.c
diff --git a/aft.c b/aft.c
index 96e0ab9ab2a0142f564d4a9387b1a6a92dfcea9d..3d5170cca76df4861739202733856c5afe6d6cdf 100644 (file)
--- a/aft.c
+++ b/aft.c
@@ -1072,7 +1072,9 @@ again:
         * No need to update the status items as the AFSI_CHANGE event will
         * recreate them.
         */
-       afs_event(AFSI_CHANGE, NULL, &aced);
+       ret = afs_event(AFSI_CHANGE, NULL, &aced);
+       if (ret < 0)
+               goto out;
        ret = save_afd(afd);
 out:
        free(afd->afhi.chunk_table);
@@ -1658,7 +1660,9 @@ static int com_add_callback(int fd, const struct osl_object *query)
                if (pb) { /* hs trumps pb, remove pb */
                        if (flags & ADD_FLAG_VERBOSE)
                                para_printf(&msg, "removing %s\n", path);
-                       afs_event(AUDIO_FILE_REMOVE, &msg, pb);
+                       ret = afs_event(AUDIO_FILE_REMOVE, &msg, pb);
+                       if (ret < 0)
+                               goto out;
                        ret = osl(osl_del_row(audio_file_table, pb));
                        if (ret < 0)
                                goto out;
@@ -1676,7 +1680,9 @@ static int com_add_callback(int fd, const struct osl_object *query)
                        &objs[AFTCOL_PATH]));
                if (ret < 0)
                        goto out;
-               afs_event(AUDIO_FILE_RENAME, &msg, hs);
+               ret = afs_event(AUDIO_FILE_RENAME, &msg, hs);
+               if (ret < 0)
+                       goto out;
                if (!(flags & ADD_FLAG_FORCE))
                        goto out;
        }
@@ -1719,7 +1725,9 @@ static int com_add_callback(int fd, const struct osl_object *query)
                        &objs[AFTCOL_CHUNKS]));
                if (ret < 0)
                        goto out;
-               afs_event(AFHI_CHANGE, &msg, row);
+               ret = afs_event(AFHI_CHANGE, &msg, row);
+               if (ret < 0)
+                       goto out;
                goto out;
        }
        /* new entry, use default afsi */
@@ -1732,7 +1740,7 @@ static int com_add_callback(int fd, const struct osl_object *query)
        objs[AFTCOL_AFSI].size = AFSI_SIZE;
        save_afsi(&default_afsi, &objs[AFTCOL_AFSI]);
        ret = osl(osl_add_and_get_row(audio_file_table, objs, &aft_row));
-       afs_event(AUDIO_FILE_ADD, &msg, aft_row);
+       ret = afs_event(AUDIO_FILE_ADD, &msg, aft_row);
 out:
        if (ret < 0)
                para_printf(&msg, "could not add %s\n", path);
@@ -2007,8 +2015,7 @@ static int touch_audio_file(__a_unused struct osl_table *table,
        save_afsi(&new_afsi, &obj); /* in-place update */
        aced.aft_row = row;
        aced.old_afsi = &old_afsi;
-       afs_event(AFSI_CHANGE, &tad->pb, &aced);
-       return 1;
+       return afs_event(AFSI_CHANGE, &tad->pb, &aced);
 }
 
 static int com_touch_callback(int fd, const struct osl_object *query)
@@ -2139,7 +2146,9 @@ static int remove_audio_file(__a_unused struct osl_table *table,
 
        if (crd->flags & RM_FLAG_VERBOSE)
                para_printf(&crd->pb, "removing %s\n", name);
-       afs_event(AUDIO_FILE_REMOVE, &crd->pb, row);
+       ret = afs_event(AUDIO_FILE_REMOVE, &crd->pb, row);
+       if (ret < 0)
+               return ret;
        ret = osl(osl_del_row(audio_file_table, row));
        if (ret < 0)
                para_printf(&crd->pb, "cannot remove %s\n", name);
@@ -2276,8 +2285,7 @@ static int copy_selector_info(__a_unused struct osl_table *table,
                para_printf(&cad->pb, "copied afsi to %s\n", name);
        aced.aft_row = row;
        aced.old_afsi = &old_afsi;
-       afs_event(AFSI_CHANGE, &cad->pb, &aced);
-       return 1;
+       return afs_event(AFSI_CHANGE, &cad->pb, &aced);
 }
 
 static int com_cpsi_callback(int fd, const struct osl_object *query)
@@ -2398,8 +2406,7 @@ static int change_atts(__a_unused struct osl_table *table,
        new_afsi.attributes |= cad->add_mask;
        new_afsi.attributes &= ~cad->del_mask;
        save_afsi(&new_afsi, &obj); /* in-place update */
-       afs_event(AFSI_CHANGE, &cad->pb, &aced);
-       return 1;
+       return afs_event(AFSI_CHANGE, &cad->pb, &aced);
 }
 
 static int com_setatt_callback(int fd, const struct osl_object *query)
@@ -2458,12 +2465,10 @@ static int com_setatt_callback(int fd, const struct osl_object *query)
        if (ret < 0)
                goto out;
        if (pmd.num_matches == 0)
-               para_printf(&cad.pb, "no matches\n");
+               ret = -E_NO_MATCH;
 out:
-       if (ret < 0)
-               para_printf(&cad.pb, "%s\n", para_strerror(-ret));
        flush_and_free_pb(&cad.pb);
-       return 0;
+       return ret;
 }
 
 int com_setatt(struct command_context *cc)
@@ -2508,7 +2513,7 @@ int send_afs_status(struct command_context *cc, int parser_friendly)
                afs_cb_result_handler, cc);
 }
 
-/* returns success even on errors to keep the loop going */
+/* returns success on non-fatal errors to keep the loop going */
 static int check_audio_file(struct osl_row *row, void *data)
 {
        char *path;
@@ -2520,7 +2525,7 @@ static int check_audio_file(struct osl_row *row, void *data)
 
        if (ret < 0) {
                para_printf(pb, "%s\n", para_strerror(-ret));
-               return 0;
+               return ret;
        }
        if (stat(path, &statbuf) < 0)
                para_printf(pb, "%s: stat error (%s)\n", path, strerror(errno));
@@ -2548,12 +2553,13 @@ static int check_audio_file(struct osl_row *row, void *data)
  * \param fd The afs socket.
  * \param query Unused.
  *
- * \return This function always returns zero.
+ * \return Standard. Inconsistencies are reported but not regarded as an error.
  *
  * \sa com_check().
  */
 int aft_check_callback(int fd, __a_unused const struct osl_object *query)
 {
+       int ret;
        struct para_buffer pb = {
                .max_size = shm_get_shmmax(),
                .private_data = &(struct afs_max_size_handler_data) {
@@ -2563,9 +2569,65 @@ int aft_check_callback(int fd, __a_unused const struct osl_object *query)
                .max_size_handler = afs_max_size_handler
        };
        para_printf(&pb, "checking audio file table...\n");
-       audio_file_loop(&pb, check_audio_file);
+       ret = audio_file_loop(&pb, check_audio_file);
        flush_and_free_pb(&pb);
-       return 0;
+       return ret;
+}
+
+struct aft_check_atts_data {
+       uint64_t att_mask;
+       struct para_buffer *pb;
+};
+
+static int check_atts_of_audio_file(struct osl_row *row, void *data)
+{
+       struct aft_check_atts_data *acad = data;
+       int ret;
+       struct afs_info afsi;
+       char *path;
+       uint64_t bad_bits;
+
+       ret = get_afsi_of_row(row, &afsi);
+       if (ret < 0) {
+               para_printf(acad->pb, "cannot get afsi\n");
+               return ret;
+       }
+       bad_bits = afsi.attributes & ~acad->att_mask;
+       if (bad_bits == 0) /* OK */
+               return 0;
+       ret = get_audio_file_path_of_row(row, &path);
+       if (ret < 0) {
+               para_printf(acad->pb, "cannot get path\n");
+               return ret;
+       }
+       para_printf(acad->pb, "invalid attribute bits (%" PRIu64 "): %s\n",
+               bad_bits, path);
+       /* return success to keep looping */
+       return 1;
+}
+
+/**
+ * Iterate over all audio files and check the attribute bit mask.
+ *
+ * \param att_mask The mask of all valid attributes.
+ * \param pb Used for reporting inconsistencies.
+ *
+ * This reads the attribute bit mask of each audio file from the afs info
+ * structure stored in the audio file table and verifies that all set bits are
+ * also turned on in \a att_mask, i.e., correspond to an attribute of the
+ * attribute table. Audio files for which this is not the case are reported via
+ * \a pb.
+ *
+ * \return Standard. Inconsistencies are not regarded as errors.
+ *
+ * \sa \ref attribute_check_callback().
+ */
+int aft_check_attributes(uint64_t att_mask, struct para_buffer *pb)
+{
+       struct aft_check_atts_data acad = {.att_mask = att_mask, .pb = pb};
+
+       para_printf(pb, "checking attributes, mask: %" PRIx64 "\n", att_mask);
+       return audio_file_loop(&acad, check_atts_of_audio_file);
 }
 
 /**