]> git.tuebingen.mpg.de Git - paraslash.git/blobdiff - afs.c
afs: Rename callback_function to afs_callback.
[paraslash.git] / afs.c
diff --git a/afs.c b/afs.c
index 4bc7871cac868a45a2d487cdf5761d9509f19bfa..fa750d21c2424e1beb3e08a42226e54c5feff40d 100644 (file)
--- a/afs.c
+++ b/afs.c
@@ -130,7 +130,7 @@ extern uint32_t afs_socket_cookie;
  */
 struct callback_query {
        /** The function to be called. */
-       callback_function *handler;
+       afs_callback *handler;
        /** The number of bytes of the query */
        size_t query_size;
 };
@@ -201,7 +201,7 @@ static int dispatch_result(int result_shmid, callback_result_handler *handler,
  *
  * \sa send_option_arg_callback_request(), send_standard_callback_request().
  */
-int send_callback_request(callback_function *f, struct osl_object *query,
+int send_callback_request(afs_callback *f, struct osl_object *query,
                callback_result_handler *result_handler,
                void *private_result_data)
 {
@@ -299,7 +299,7 @@ out:
  * \sa send_standard_callback_request(), send_callback_request().
  */
 int send_option_arg_callback_request(struct osl_object *options,
-               int argc,  char * const * const argv, callback_function *f,
+               int argc,  char * const * const argv, afs_callback *f,
                callback_result_handler *result_handler,
                void *private_result_data)
 {
@@ -341,7 +341,7 @@ int send_option_arg_callback_request(struct osl_object *options,
  * send_option_arg_callback_request().
  */
 int send_standard_callback_request(int argc,  char * const * const argv,
-               callback_function *f, callback_result_handler *result_handler,
+               afs_callback *f, callback_result_handler *result_handler,
                void *private_result_data)
 {
        return send_option_arg_callback_request(NULL, argc, argv, f, result_handler,
@@ -501,6 +501,7 @@ static int activate_mood_or_playlist(char *arg, int *num_admissible)
        enum play_mode mode;
        int ret;
 
+       PARA_INFO_LOG("new playlist: %s\n", arg);
        if (!arg) {
                ret = change_current_mood(NULL); /* always successful */
                mode = PLAY_MODE_MOOD;
@@ -602,31 +603,32 @@ static int com_select_callback(int fd, const struct osl_object *query)
 
        ret = clear_score_table();
        if (ret < 0) {
-               para_printf(&pb, "%s\n", para_strerror(-ret));
-               goto out;
+               para_printf(&pb, "could not clear score table: %s\n",
+                       para_strerror(-ret));
+               return ret;
        }
        if (current_play_mode == PLAY_MODE_MOOD)
                close_current_mood();
        else
                playlist_close();
        ret = activate_mood_or_playlist(arg, &num_admissible);
-       if (ret < 0) {
-               para_printf(&pb, "%s\nswitching back to %s\n",
-                       para_strerror(-ret), current_mop?
-                       current_mop : "dummy");
-               ret = activate_mood_or_playlist(current_mop, &num_admissible);
-               if (ret < 0) {
-                       para_printf(&pb, "failed (%s), switching to dummy\n",
-                               para_strerror(-ret));
-                       activate_mood_or_playlist(NULL, &num_admissible);
-               }
-       } else
-               para_printf(&pb, "activated %s (%d admissible files)\n",
-                       current_mop?  current_mop : "dummy mood",
-                       num_admissible);
+       if (ret >= 0)
+               goto out;
+       para_printf(&pb, "could not activate %s: %s\n"
+               "switching back to %s\n",
+               arg, para_strerror(-ret), current_mop? current_mop : "dummy");
+       /* ignore subsequent errors (but log them) */
+       ret = activate_mood_or_playlist(current_mop, &num_admissible);
+       if (ret >= 0)
+               goto out;
+       para_printf(&pb, "could not activate %s: %s\nswitching to dummy\n",
+               current_mop, para_strerror(-ret));
+       activate_mood_or_playlist(NULL, &num_admissible);
 out:
+       para_printf(&pb, "activated %s (%d admissible files)\n",
+               current_mop? current_mop : "dummy mood", num_admissible);
        flush_and_free_pb(&pb);
-       return 0;
+       return ret;
 }
 
 int com_select(struct command_context *cc)
@@ -1031,7 +1033,7 @@ out:
        exit(EXIT_FAILURE);
 }
 
-static int create_tables_callback(int fd, const struct osl_object *query)
+static int com_init_callback(int fd, const struct osl_object *query)
 {
        uint32_t table_mask = *(uint32_t *)query->data;
        int i, ret;
@@ -1052,16 +1054,18 @@ static int create_tables_callback(int fd, const struct osl_object *query)
                if (!t->create)
                        continue;
                ret = t->create(database_dir);
-               if (ret < 0)
+               if (ret < 0) {
+                       para_printf(&pb, "cannot create table %s\n", t->name);
                        goto out;
+               }
                para_printf(&pb, "successfully created %s table\n", t->name);
        }
        ret = open_afs_tables();
-out:
        if (ret < 0)
-               para_printf(&pb, "%s\n", para_strerror(-ret));
+               para_printf(&pb, "cannot open afs tables\n");
+out:
        flush_and_free_pb(&pb);
-       return 0;
+       return ret;
 }
 
 int com_init(struct command_context *cc)
@@ -1089,7 +1093,7 @@ int com_init(struct command_context *cc)
                                return -E_BAD_TABLE_NAME;
                }
        }
-       return send_callback_request(create_tables_callback, &query,
+       return send_callback_request(com_init_callback, &query,
                afs_cb_result_handler, cc);
 }
 
@@ -1104,7 +1108,9 @@ enum com_check_flags {
        /** Check the mood table. */
        CHECK_MOODS = 2,
        /** Check the playlist table. */
-       CHECK_PLAYLISTS = 4
+       CHECK_PLAYLISTS = 4,
+       /** Check the attribute table against the audio file table. */
+       CHECK_ATTS = 8
 };
 
 int com_check(struct command_context *cc)
@@ -1124,6 +1130,10 @@ int com_check(struct command_context *cc)
                        flags |= CHECK_AFT;
                        continue;
                }
+               if (!strcmp(arg, "-A")) {
+                       flags |= CHECK_ATTS;
+                       continue;
+               }
                if (!strcmp(arg, "-p")) {
                        flags |= CHECK_PLAYLISTS;
                        continue;
@@ -1144,6 +1154,12 @@ int com_check(struct command_context *cc)
                if (ret < 0)
                        return ret;
        }
+       if (flags & CHECK_ATTS) {
+               ret = send_callback_request(attribute_check_callback, NULL,
+                       afs_cb_result_handler, cc);
+               if (ret < 0)
+                       return ret;
+       }
        if (flags & CHECK_PLAYLISTS) {
                ret = send_callback_request(playlist_check_callback,
                        NULL, afs_cb_result_handler, cc);
@@ -1166,10 +1182,14 @@ int com_check(struct command_context *cc)
  * \param pb May be \p NULL.
  * \param data Type depends on \a event.
  *
- * This function calls the table handlers of all tables and passes \a pb and \a
- * data verbatim. It's up to the handlers to interpret the \a data pointer.
+ * This function calls each table event handler, passing \a pb and \a data
+ * verbatim. It's up to the handlers to interpret the \a data pointer. If a
+ * handler returns negative, the loop is aborted.
+ *
+ * \return The (negative) error code of the first handler that failed, or non-negative
+ * if all handlers succeeded.
  */
-void afs_event(enum afs_events event, struct para_buffer *pb,
+__must_check int afs_event(enum afs_events event, struct para_buffer *pb,
                void *data)
 {
        int i, ret;
@@ -1179,10 +1199,13 @@ void afs_event(enum afs_events event, struct para_buffer *pb,
                if (!t->event_handler)
                        continue;
                ret = t->event_handler(event, pb, data);
-               if (ret < 0)
+               if (ret < 0) {
                        PARA_CRIT_LOG("table %s, event %d: %s\n", t->name,
                                event, para_strerror(-ret));
+                       return ret;
+               }
        }
+       return 1;
 }
 
 /**