aft.c: Fix com_add().
[paraslash.git] / afs.c
diff --git a/afs.c b/afs.c
index 143103de98c2e63ab5c76528439e74bfc07edaba..a7778a5854ce782221cc7090b09eaa1a07e62049 100644 (file)
--- a/afs.c
+++ b/afs.c
@@ -535,9 +535,9 @@ static void unregister_tasks(void)
        unregister_task(&signal_task_struct.task);
 }
 
-static void afs_shutdown(enum osl_close_flags flags)
+static void close_afs_tables(enum osl_close_flags flags)
 {
-       PARA_NOTICE_LOG("cleaning up\n");
+       PARA_NOTICE_LOG("closing afs_tables\n");
        score_shutdown(flags);
        attribute_shutdown(flags);
        mood_close();
@@ -725,45 +725,58 @@ void register_tasks(uint32_t cookie)
        register_command_task(cookie);
 }
 
-static int open_afs_tables(void)
+static char *database_dir;
+
+static int make_database_dir(void)
 {
        int ret;
-       char *db;
-
-       if (conf.afs_database_dir_given)
-               db = conf.afs_database_dir_arg;
-       else {
-               char *home = para_homedir();
-               db = make_message("%s/.paraslash/afs_database", home);
-               free(home);
+
+       if (!database_dir) {
+               if (conf.afs_database_dir_given)
+                       database_dir = para_strdup(conf.afs_database_dir_arg);
+               else {
+                       char *home = para_homedir();
+                       database_dir = make_message(
+                               "%s/.paraslash/afs_database", home);
+                       free(home);
+               }
        }
-       PARA_INFO_LOG("afs_database dir %s\n", db);
-       ret = para_mkdir(db, 0777);
-       if (ret < 0 && ret != -E_EXIST)
-               goto err;
-       ret = attribute_init(&afs_tables[TBLNUM_ATTRIBUTES], db);
+       PARA_INFO_LOG("afs_database dir %s\n", database_dir);
+       ret = para_mkdir(database_dir, 0777);
+       if (ret >= 0 || ret == -E_EXIST)
+               return 1;
+       free(database_dir);
+       database_dir = NULL;
+       return ret;
+}
+
+static int open_afs_tables(void)
+{
+       int ret = make_database_dir();
+
+       if (ret < 0)
+               return ret;
+       ret = attribute_init(&afs_tables[TBLNUM_ATTRIBUTES], database_dir);
        if (ret < 0)
-               goto err;
-       ret = moods_init(&afs_tables[TBLNUM_MOODS], db);
+               return ret;
+       ret = moods_init(&afs_tables[TBLNUM_MOODS], database_dir);
        if (ret < 0)
                goto moods_init_error;
-       ret = playlists_init(&afs_tables[TBLNUM_PLAYLIST], db);
+       ret = playlists_init(&afs_tables[TBLNUM_PLAYLIST], database_dir);
        if (ret < 0)
                goto playlists_init_error;
-       ret = lyrics_init(&afs_tables[TBLNUM_LYRICS], db);
+       ret = lyrics_init(&afs_tables[TBLNUM_LYRICS], database_dir);
        if (ret < 0)
                goto lyrics_init_error;
-       ret = images_init(&afs_tables[TBLNUM_IMAGES], db);
+       ret = images_init(&afs_tables[TBLNUM_IMAGES], database_dir);
        if (ret < 0)
                goto images_init_error;
-       ret = score_init(&afs_tables[TBLNUM_SCORES], db);
+       ret = score_init(&afs_tables[TBLNUM_SCORES], database_dir);
        if (ret < 0)
                goto score_init_error;
-       ret = aft_init(&afs_tables[TBLNUM_AUDIO_FILES], db);
+       ret = aft_init(&afs_tables[TBLNUM_AUDIO_FILES], database_dir);
        if (ret < 0)
                goto aft_init_error;
-       if (!conf.afs_database_dir_given)
-               free(db);
        return 1;
 
 aft_init_error:
@@ -778,9 +791,6 @@ playlists_init_error:
        moods_shutdown(OSL_MARK_CLEAN);
 moods_init_error:
        attribute_shutdown(OSL_MARK_CLEAN);
-err:
-       if (!conf.afs_database_dir_given)
-               free(db);
        return ret;
 }
 
@@ -804,54 +814,58 @@ __noreturn int afs_init(uint32_t cookie, int socket_fd)
        ret = sched(&s);
        if (ret < 0)
                PARA_EMERG_LOG("%s\n", PARA_STRERROR(-ret));
-       afs_shutdown(OSL_MARK_CLEAN);
+       close_afs_tables(OSL_MARK_CLEAN);
        exit(EXIT_FAILURE);
 }
 
-static int create_all_tables(void)
+static int create_tables_callback(const struct osl_object *query,
+               __a_unused struct osl_object *result)
 {
+       uint32_t table_mask = *(uint32_t *)query->data;
        int i, ret;
 
+       close_afs_tables(OSL_MARK_CLEAN);
        for (i = 0; i < NUM_AFS_TABLES; i++) {
                struct table_info *ti = afs_tables + i;
 
                if (ti->flags & TBLFLAG_SKIP_CREATE)
                        continue;
+               if (!(table_mask & (1 << i)))
+                       continue;
                ret = osl_create_table(ti->desc);
                if (ret < 0)
                        return ret;
        }
-       return 1;
+       ret = open_afs_tables();
+       return ret < 0? ret: 0;
 }
 
 int com_init(int fd, int argc, char * const * const argv)
 {
        int i, j, ret;
-
-       if (argc == 1) {
-               ret = create_all_tables();
-               if (ret < 0)
-                       return ret;
-               return open_afs_tables();
-       }
-       for (i = 1; i < argc; i++) {
-               for (j = 0; j < NUM_AFS_TABLES; j++) {
-                       struct table_info *ti = afs_tables + j;
-
-                       if (ti->flags & TBLFLAG_SKIP_CREATE)
-                               continue;
-                       if (strcmp(argv[i], ti->desc->name))
-                               continue;
-                       ret = send_va_buffer(fd, "creating table %s\n", argv[i]);
-                       if (ret < 0)
-                               return ret;
-                       ret = osl_create_table(ti->desc);
-                       if (ret < 0)
-                               return ret;
-                       break;
+       uint32_t table_mask = (1 << (NUM_AFS_TABLES + 1)) - 1;
+       struct osl_object query = {.data = &table_mask,
+               .size = sizeof(table_mask)};
+
+       if (argc != 1) {
+               table_mask = 0;
+               for (i = 1; i < argc; i++) {
+                       for (j = 0; j < NUM_AFS_TABLES; j++) {
+                               struct table_info *ti = afs_tables + j;
+
+                               if (ti->flags & TBLFLAG_SKIP_CREATE)
+                                       continue;
+                               if (strcmp(argv[i], ti->desc->name))
+                                       continue;
+                               table_mask |= (1 << j);
+                               break;
+                       }
+                       if (j == NUM_AFS_TABLES)
+                               return -E_BAD_TABLE_NAME;
                }
-               if (j == NUM_AFS_TABLES)
-                       return -E_BAD_TABLE_NAME;
        }
-       return open_afs_tables();
+       ret = send_callback_request(create_tables_callback, &query, NULL);
+       if (ret < 0)
+               return ret;
+       return send_va_buffer(fd, "successfully created afs table(s)\n");
 }