afs: Provide pbout para_buffer for each callback.
authorAndre Noll <maan@tuebingen.mpg.de>
Wed, 8 Apr 2015 03:35:21 +0000 (03:35 +0000)
committerAndre Noll <maan@tuebingen.mpg.de>
Wed, 12 Aug 2015 21:23:48 +0000 (23:23 +0200)
Most afs callbacks define a para_buffer to pass output from the
callback to the command handler. Hence the code which defines and
initializes the para_buffer is duplicated many times.

This commit gets rid of the duplication by moving the initialization
to the common call_callback(). The para_buffer becomes part of
struct afs_callback_arg, a pointer to which is passed to every
callback. The buffer is also flushed and freed in call_callback()
so that the callbacks don't need to care about it any more. This also
allows to make flush_and_free_pb() static since only a single caller
in afs.c remains.

This change simplifies the callbacks considerably. The callbacks of the
rm, setatt, lsatt, lsblob and touch commands don't even need their own
"action_data" structure any more since it was only necessary to pass
the para_buffer to the ->action method.

afs.c
afs.h
aft.c
attribute.c
blob.c
mood.c
playlist.c

diff --git a/afs.c b/afs.c
index 30acfa0..bd70505 100644 (file)
--- a/afs.c
+++ b/afs.c
@@ -574,7 +574,7 @@ int afs_cb_result_handler(struct osl_object *result, uint8_t band,
        }
 }
 
-void flush_and_free_pb(struct para_buffer *pb)
+static void flush_and_free_pb(struct para_buffer *pb)
 {
        int ret;
        struct afs_max_size_handler_data *amshd = pb->private_data;
@@ -590,20 +590,12 @@ void flush_and_free_pb(struct para_buffer *pb)
 
 static int com_select_callback(struct afs_callback_arg *aca)
 {
-       struct para_buffer pb = {
-               .max_size = shm_get_shmmax(),
-               .private_data = &(struct afs_max_size_handler_data) {
-                       .fd = aca->fd,
-                       .band = SBD_OUTPUT
-               },
-               .max_size_handler = afs_max_size_handler,
-       };
        char *arg = aca->query.data;
        int num_admissible, ret;
 
        ret = clear_score_table();
        if (ret < 0) {
-               para_printf(&pb, "could not clear score table: %s\n",
+               para_printf(&aca->pbout, "could not clear score table: %s\n",
                        para_strerror(-ret));
                return ret;
        }
@@ -614,20 +606,19 @@ static int com_select_callback(struct afs_callback_arg *aca)
        ret = activate_mood_or_playlist(arg, &num_admissible);
        if (ret >= 0)
                goto out;
-       para_printf(&pb, "could not activate %s: %s\n"
+       /* ignore subsequent errors (but log them) */
+       para_printf(&aca->pbout, "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",
+       para_printf(&aca->pbout, "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",
+       para_printf(&aca->pbout, "activated %s (%d admissible files)\n",
                current_mop? current_mop : "dummy mood", num_admissible);
-       flush_and_free_pb(&pb);
        return ret;
 }
 
@@ -858,6 +849,12 @@ static int call_callback(int fd, int query_shmid)
        cq = query_shm;
        aca.query.data = (char *)query_shm + sizeof(*cq);
        aca.query.size = cq->query_size;
+       aca.pbout.max_size = shm_get_shmmax();
+       aca.pbout.max_size_handler = afs_max_size_handler;
+       aca.pbout.private_data = &(struct afs_max_size_handler_data) {
+               .fd = fd,
+               .band = SBD_OUTPUT
+       };
        ret = cq->handler(&aca);
        ret2 = shm_detach(query_shm);
        if (ret2 < 0) {
@@ -867,6 +864,7 @@ static int call_callback(int fd, int query_shmid)
                else
                        ret = ret2;
        }
+       flush_and_free_pb(&aca.pbout);
        if (ret < 0) {
                ret2 = pass_buffer_as_shm(fd, SBD_AFS_CB_FAILURE,
                        (const char *)&ret, sizeof(ret));
@@ -1037,13 +1035,6 @@ static int com_init_callback(struct afs_callback_arg *aca)
 {
        uint32_t table_mask = *(uint32_t *)aca->query.data;
        int i, ret;
-       struct para_buffer pb = {
-               .max_size = shm_get_shmmax(),
-               .private_data = &(struct afs_max_size_handler_data) {
-                       .fd = aca->fd,
-                       .band = SBD_OUTPUT
-               }
-       };
 
        close_afs_tables();
        for (i = 0; i < NUM_AFS_TABLES; i++) {
@@ -1055,16 +1046,17 @@ static int com_init_callback(struct afs_callback_arg *aca)
                        continue;
                ret = t->create(database_dir);
                if (ret < 0) {
-                       para_printf(&pb, "cannot create table %s\n", t->name);
+                       para_printf(&aca->pbout, "cannot create table %s\n",
+                               t->name);
                        goto out;
                }
-               para_printf(&pb, "successfully created %s table\n", t->name);
+               para_printf(&aca->pbout, "successfully created %s table\n",
+                       t->name);
        }
        ret = open_afs_tables();
        if (ret < 0)
-               para_printf(&pb, "cannot open afs tables\n");
+               para_printf(&aca->pbout, "cannot open afs tables\n");
 out:
-       flush_and_free_pb(&pb);
        return ret;
 }
 
diff --git a/afs.h b/afs.h
index 81012ff..e77cdf0 100644 (file)
--- a/afs.h
+++ b/afs.h
@@ -163,6 +163,8 @@ struct afs_callback_arg {
        int fd;
        /** Callback-specific data. */
        struct osl_object query;
+       /** Will be written on band SBD_OUTPUT, fully buffered. */
+       struct para_buffer pbout;
 };
 
 /**
@@ -230,7 +232,6 @@ int send_standard_callback_request(int argc,  char * const * const argv,
                void *private_result_data);
 int string_compare(const struct osl_object *obj1, const struct osl_object *obj2);
 int for_each_matching_row(struct pattern_match_data *pmd);
-void flush_and_free_pb(struct para_buffer *pb);
 
 /* score */
 void score_init(struct afs_table *t);
diff --git a/aft.c b/aft.c
index 07d8805..4793165 100644 (file)
--- a/aft.c
+++ b/aft.c
@@ -1297,18 +1297,10 @@ static int com_ls_callback(struct afs_callback_arg *aca)
 {
        struct ls_options *opts = aca->query.data;
        char *p, *pattern_start = (char *)aca->query.data + sizeof(*opts);
-       struct para_buffer b = {
-               .max_size = shm_get_shmmax(),
-               .flags = (opts->mode == LS_MODE_PARSER)? PBF_SIZE_PREFIX : 0,
-               .max_size_handler = afs_max_size_handler,
-               .private_data = &(struct afs_max_size_handler_data) {
-                       .fd = aca->fd,
-                       .band = SBD_OUTPUT
-               }
-       };
        int i = 0, ret;
        time_t current_time;
 
+       aca->pbout.flags = (opts->mode == LS_MODE_PARSER)? PBF_SIZE_PREFIX : 0;
        if (opts->num_patterns) {
                opts->patterns = para_malloc(opts->num_patterns * sizeof(char *));
                for (i = 0, p = pattern_start; i < opts->num_patterns; i++) {
@@ -1334,18 +1326,19 @@ static int com_ls_callback(struct afs_callback_arg *aca)
        time(&current_time);
        if (opts->flags & LS_FLAG_REVERSE)
                for (i = opts->num_matching_paths - 1; i >= 0; i--) {
-                       ret = print_list_item(opts->data_ptr[i], opts, &b, current_time);
+                       ret = print_list_item(opts->data_ptr[i], opts,
+                               &aca->pbout, current_time);
                        if (ret < 0)
                                goto out;
                }
        else
                for (i = 0; i < opts->num_matching_paths; i++) {
-                       ret = print_list_item(opts->data_ptr[i], opts, &b, current_time);
+                       ret = print_list_item(opts->data_ptr[i], opts,
+                               &aca->pbout, current_time);
                        if (ret < 0)
                                goto out;
                }
 out:
-       flush_and_free_pb(&b);
        free(opts->data);
        free(opts->data_ptr);
        free(opts->patterns);
@@ -1625,14 +1618,6 @@ static int com_add_callback(struct afs_callback_arg *aca)
        char afsi_buf[AFSI_SIZE];
        uint32_t flags = read_u32(buf + CAB_FLAGS_OFFSET);
        struct afs_info default_afsi = {.last_played = 0};
-       struct para_buffer msg = {
-               .max_size = shm_get_shmmax(),
-               .max_size_handler = afs_max_size_handler,
-               .private_data = &(struct afs_max_size_handler_data) {
-                       .fd = aca->fd,
-                       .band = SBD_OUTPUT
-               }
-       };
        uint16_t afhi_offset, chunks_offset;
 
        hash = (unsigned char *)buf + CAB_HASH_OFFSET;
@@ -1651,7 +1636,7 @@ static int com_add_callback(struct afs_callback_arg *aca)
                goto out;
        if (hs && pb && hs == pb && !(flags & ADD_FLAG_FORCE)) {
                if (flags & ADD_FLAG_VERBOSE)
-                       para_printf(&msg, "ignoring duplicate\n");
+                       para_printf(&aca->pbout, "ignoring duplicate\n");
                ret = 1;
                goto out;
        }
@@ -1659,8 +1644,8 @@ static int com_add_callback(struct afs_callback_arg *aca)
                struct osl_object obj;
                if (pb) { /* hs trumps pb, remove pb */
                        if (flags & ADD_FLAG_VERBOSE)
-                               para_printf(&msg, "removing %s\n", path);
-                       ret = afs_event(AUDIO_FILE_REMOVE, &msg, pb);
+                               para_printf(&aca->pbout, "removing %s\n", path);
+                       ret = afs_event(AUDIO_FILE_REMOVE, &aca->pbout, pb);
                        if (ret < 0)
                                goto out;
                        ret = osl(osl_del_row(audio_file_table, pb));
@@ -1674,13 +1659,14 @@ static int com_add_callback(struct afs_callback_arg *aca)
                                AFTCOL_PATH, &obj));
                        if (ret < 0)
                                goto out;
-                       para_printf(&msg, "renamed from %s\n", (char *)obj.data);
+                       para_printf(&aca->pbout, "renamed from %s\n",
+                               (char *)obj.data);
                }
                ret = osl(osl_update_object(audio_file_table, hs, AFTCOL_PATH,
                        &objs[AFTCOL_PATH]));
                if (ret < 0)
                        goto out;
-               ret = afs_event(AUDIO_FILE_RENAME, &msg, hs);
+               ret = afs_event(AUDIO_FILE_RENAME, &aca->pbout, hs);
                if (ret < 0)
                        goto out;
                if (!(flags & ADD_FLAG_FORCE))
@@ -1705,8 +1691,8 @@ static int com_add_callback(struct afs_callback_arg *aca)
                        goto out;
                hash_to_asc(old_hash, old_asc);
                if (flags & ADD_FLAG_VERBOSE)
-                       para_printf(&msg, "file change: %s -> %s\n", old_asc,
-                               asc);
+                       para_printf(&aca->pbout, "file change: %s -> %s\n",
+                               old_asc, asc);
                ret = osl_update_object(audio_file_table, pb, AFTCOL_HASH,
                        &objs[AFTCOL_HASH]);
                if (ret < 0)
@@ -1716,7 +1702,8 @@ static int com_add_callback(struct afs_callback_arg *aca)
                struct osl_row *row = pb? pb : hs;
                /* update afhi and chunk_table */
                if (flags & ADD_FLAG_VERBOSE)
-                       para_printf(&msg, "updating afhi and chunk table\n");
+                       para_printf(&aca->pbout,
+                               "updating afhi and chunk table\n");
                ret = osl(osl_update_object(audio_file_table, row, AFTCOL_AFHI,
                        &objs[AFTCOL_AFHI]));
                if (ret < 0)
@@ -1725,14 +1712,14 @@ static int com_add_callback(struct afs_callback_arg *aca)
                        &objs[AFTCOL_CHUNKS]));
                if (ret < 0)
                        goto out;
-               ret = afs_event(AFHI_CHANGE, &msg, row);
+               ret = afs_event(AFHI_CHANGE, &aca->pbout, row);
                if (ret < 0)
                        goto out;
                goto out;
        }
        /* new entry, use default afsi */
        if (flags & ADD_FLAG_VERBOSE)
-               para_printf(&msg, "new file\n");
+               para_printf(&aca->pbout, "new file\n");
        default_afsi.last_played = time(NULL) - 365 * 24 * 60 * 60;
        default_afsi.audio_format_id = read_u8(buf + CAB_AUDIO_FORMAT_OFFSET);
 
@@ -1740,11 +1727,10 @@ static int com_add_callback(struct afs_callback_arg *aca)
        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));
-       ret = afs_event(AUDIO_FILE_ADD, &msg, aft_row);
+       ret = afs_event(AUDIO_FILE_ADD, &aca->pbout, aft_row);
 out:
        if (ret < 0)
-               para_printf(&msg, "could not add %s\n", path);
-       flush_and_free_pb(&msg);
+               para_printf(&aca->pbout, "could not add %s\n", path);
        return ret;
 }
 
@@ -1962,90 +1948,77 @@ struct com_touch_options {
        unsigned flags;
 };
 
-/** Data passed to the action handler of com_touch(). */
-struct touch_action_data {
-       /** Command line options (see \ref com_touch_options). */
-       struct com_touch_options *cto;
-       /** Message buffer. */
-       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 touch_action_data *tad = data;
+       struct afs_callback_arg *aca = data;
+       struct com_touch_options *cto = aca->query.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 && tad->cto->amp < 0;
+       int ret, no_options = cto->num_played < 0 && cto->last_played < 0 &&
+               cto->lyrics_id < 0 && cto->image_id < 0 && cto->amp < 0;
        struct afsi_change_event_data aced;
 
        ret = get_afsi_object_of_row(row, &obj);
        if (ret < 0) {
-               para_printf(&tad->pb, "cannot touch %s\n", name);
+               para_printf(&aca->pbout, "cannot touch %s\n", name);
                return ret;
        }
        ret = load_afsi(&old_afsi, &obj);
        if (ret < 0) {
-               para_printf(&tad->pb, "cannot touch %s\n", name);
+               para_printf(&aca->pbout, "cannot touch %s\n", name);
                return ret;
        }
        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, "
+               if (cto->flags & TOUCH_FLAG_VERBOSE)
+                       para_printf(&aca->pbout, "%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;
-               if (tad->cto->amp >= 0)
-                       new_afsi.amp = tad->cto->amp;
+               if (cto->flags & TOUCH_FLAG_VERBOSE)
+                       para_printf(&aca->pbout, "touching %s\n", name);
+               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;
+               if (cto->amp >= 0)
+                       new_afsi.amp = cto->amp;
        }
        save_afsi(&new_afsi, &obj); /* in-place update */
        aced.aft_row = row;
        aced.old_afsi = &old_afsi;
-       return afs_event(AFSI_CHANGE, &tad->pb, &aced);
+       return afs_event(AFSI_CHANGE, &aca->pbout, &aced);
 }
 
 static int com_touch_callback(struct afs_callback_arg *aca)
 {
-       struct touch_action_data tad = {.cto = aca->query.data,
-               .pb = {
-                       .max_size = shm_get_shmmax(),
-                       .private_data = &(struct afs_max_size_handler_data) {
-                               .fd = aca->fd,
-                               .band = SBD_OUTPUT
-                       },
-                       .max_size_handler = afs_max_size_handler
-               }
-       };
        int ret;
+       struct com_touch_options *cto = aca->query.data;
        struct pattern_match_data pmd = {
                .table = audio_file_table,
                .loop_col_num = AFTCOL_HASH,
                .match_col_num = AFTCOL_PATH,
-               .patterns = {.data = (char *)aca->query.data + sizeof(*tad.cto),
-                       .size = aca->query.size - sizeof(*tad.cto)},
-               .data = &tad,
+               .patterns = {
+                       .data = (char *)aca->query.data
+                               + sizeof(struct com_touch_options),
+                       .size = aca->query.size
+                               - sizeof(struct com_touch_options)
+               },
+               .data = aca,
                .action = touch_audio_file
        };
-       if (tad.cto->flags & TOUCH_FLAG_FNM_PATHNAME)
+       if (cto->flags & TOUCH_FLAG_FNM_PATHNAME)
                pmd.fnmatch_flags |= FNM_PATHNAME;
        ret = for_each_matching_row(&pmd);
        if (ret >= 0 && pmd.num_matches == 0)
                ret = -E_NO_MATCH;
-       flush_and_free_pb(&tad.pb);
        return ret;
 }
 
@@ -2130,64 +2103,48 @@ enum rm_flags {
        RM_FLAG_FNM_PATHNAME = 4
 };
 
-/** Data passed to the action handler of com_rm(). */
-struct com_rm_action_data {
-       /** Command line flags ((see \ref rm_flags). */
-       uint32_t flags;
-       /** Message buffer. */
-       struct para_buffer pb;
-};
-
 static int remove_audio_file(__a_unused struct osl_table *table,
                struct osl_row *row, const char *name, void *data)
 {
-       struct com_rm_action_data *crd = data;
+       struct afs_callback_arg *aca = data;
+       uint32_t flags =*(uint32_t *)aca->query.data;
        int ret;
 
-       if (crd->flags & RM_FLAG_VERBOSE)
-               para_printf(&crd->pb, "removing %s\n", name);
-       ret = afs_event(AUDIO_FILE_REMOVE, &crd->pb, row);
+       if (flags & RM_FLAG_VERBOSE)
+               para_printf(&aca->pbout, "removing %s\n", name);
+       ret = afs_event(AUDIO_FILE_REMOVE, &aca->pbout, 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);
+               para_printf(&aca->pbout, "cannot remove %s\n", name);
        return ret;
 }
 
 static int com_rm_callback(struct afs_callback_arg *aca)
 {
-       struct com_rm_action_data crd = {.flags = *(uint32_t *)aca->query.data,
-               .pb = {
-                       .max_size = shm_get_shmmax(),
-                       .private_data = &(struct afs_max_size_handler_data) {
-                               .fd = aca->fd,
-                               .band = SBD_OUTPUT
-                       },
-                       .max_size_handler = afs_max_size_handler
-               }
-       };
        int ret;
+       uint32_t flags = *(uint32_t *)aca->query.data;
        struct pattern_match_data pmd = {
                .table = audio_file_table,
                .loop_col_num = AFTCOL_HASH,
                .match_col_num = AFTCOL_PATH,
                .patterns = {.data = (char *)aca->query.data + sizeof(uint32_t),
                        .size = aca->query.size - sizeof(uint32_t)},
-               .data = &crd,
+               .data = aca,
                .action = remove_audio_file
        };
-       if (crd.flags & RM_FLAG_FNM_PATHNAME)
+       if (flags & RM_FLAG_FNM_PATHNAME)
                pmd.fnmatch_flags |= FNM_PATHNAME;
        ret = for_each_matching_row(&pmd);
        if (ret < 0)
                goto out;
        if (pmd.num_matches == 0)
                ret = -E_NO_MATCH;
-       else if (crd.flags & RM_FLAG_VERBOSE)
-               para_printf(&crd.pb, "removed %u file(s)\n", pmd.num_matches);
+       else if (flags & RM_FLAG_VERBOSE)
+               para_printf(&aca->pbout, "removed %u file(s)\n",
+                       pmd.num_matches);
 out:
-       flush_and_free_pb(&crd.pb);
        return ret;
 }
 
@@ -2250,10 +2207,10 @@ enum cpsi_flags {
 struct cpsi_action_data {
        /** command line flags (see \ref cpsi_flags). */
        unsigned flags;
-       /** Message buffer. */
-       struct para_buffer pb;
        /** Values are copied from here. */
        struct afs_info source_afsi;
+       /** What was passed to com_cpsi_callback(). */
+       struct afs_callback_arg *aca;
 };
 
 static int copy_selector_info(__a_unused struct osl_table *table,
@@ -2282,24 +2239,17 @@ static int copy_selector_info(__a_unused struct osl_table *table,
                target_afsi.attributes = cad->source_afsi.attributes;
        save_afsi(&target_afsi, &target_afsi_obj); /* in-place update */
        if (cad->flags & CPSI_FLAG_VERBOSE)
-               para_printf(&cad->pb, "copied afsi to %s\n", name);
+               para_printf(&cad->aca->pbout, "copied afsi to %s\n", name);
        aced.aft_row = row;
        aced.old_afsi = &old_afsi;
-       return afs_event(AFSI_CHANGE, &cad->pb, &aced);
+       return afs_event(AFSI_CHANGE, &cad->aca->pbout, &aced);
 }
 
 static int com_cpsi_callback(struct afs_callback_arg *aca)
 {
        struct cpsi_action_data cad = {
                .flags = *(unsigned *)aca->query.data,
-               .pb = {
-                       .max_size = shm_get_shmmax(),
-                       .private_data = &(struct afs_max_size_handler_data) {
-                               .fd = aca->fd,
-                               .band = SBD_OUTPUT
-                       },
-                       .max_size_handler = afs_max_size_handler
-               }
+               .aca = aca
        };
        int ret;
        char *source_path = (char *)aca->query.data + sizeof(cad.flags);
@@ -2322,12 +2272,11 @@ static int com_cpsi_callback(struct afs_callback_arg *aca)
                goto out;
        if (pmd.num_matches > 0) {
                if (cad.flags & CPSI_FLAG_VERBOSE)
-                       para_printf(&cad.pb, "updated afsi of %u file(s)\n",
+                       para_printf(&aca->pbout, "updated afsi of %u file(s)\n",
                                pmd.num_matches);
        } else
                ret = -E_NO_MATCH;
 out:
-       flush_and_free_pb(&cad.pb);
        return ret;
 }
 
@@ -2381,7 +2330,7 @@ int com_cpsi(struct command_context *cc)
 
 struct change_atts_data {
        uint64_t add_mask, del_mask;
-       struct para_buffer pb;
+       struct afs_callback_arg *aca;
 };
 
 static int change_atts(__a_unused struct osl_table *table,
@@ -2406,7 +2355,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 */
-       return afs_event(AFSI_CHANGE, &cad->pb, &aced);
+       return afs_event(AFSI_CHANGE, &cad->aca->pbout, &aced);
 }
 
 static int com_setatt_callback(struct afs_callback_arg *aca)
@@ -2414,16 +2363,7 @@ static int com_setatt_callback(struct afs_callback_arg *aca)
        char *p;
        int ret;
        size_t len;
-       struct change_atts_data cad = {
-               .pb = {
-                       .max_size = shm_get_shmmax(),
-                       .max_size_handler = afs_max_size_handler,
-                       .private_data = &(struct afs_max_size_handler_data) {
-                               .fd = aca->fd,
-                               .band = SBD_OUTPUT
-                       }
-               }
-       };
+       struct change_atts_data cad = {.aca = aca};
        struct pattern_match_data pmd = {
                .table = audio_file_table,
                .loop_col_num = AFTCOL_HASH,
@@ -2451,7 +2391,7 @@ static int com_setatt_callback(struct afs_callback_arg *aca)
                p[len - 1] = '\0';
                ret = get_attribute_bitnum_by_name(p, &bitnum);
                if (ret < 0) {
-                       para_printf(&cad.pb, "attribute not found: %s\n", p);
+                       para_printf(&aca->pbout, "attribute not found: %s\n", p);
                        goto out;
                }
                if (c == '+')
@@ -2471,7 +2411,6 @@ static int com_setatt_callback(struct afs_callback_arg *aca)
        if (pmd.num_matches == 0)
                ret = -E_NO_MATCH;
 out:
-       flush_and_free_pb(&cad.pb);
        return ret;
 }
 
@@ -2562,19 +2501,8 @@ static int check_audio_file(struct osl_row *row, void *data)
  */
 int aft_check_callback(struct afs_callback_arg *aca)
 {
-       int ret;
-       struct para_buffer pb = {
-               .max_size = shm_get_shmmax(),
-               .private_data = &(struct afs_max_size_handler_data) {
-                       .fd = aca->fd,
-                       .band = SBD_OUTPUT
-               },
-               .max_size_handler = afs_max_size_handler
-       };
-       para_printf(&pb, "checking audio file table...\n");
-       ret = audio_file_loop(&pb, check_audio_file);
-       flush_and_free_pb(&pb);
-       return ret;
+       para_printf(&aca->pbout, "checking audio file table...\n");
+       return audio_file_loop(&aca->pbout, check_audio_file);
 }
 
 struct aft_check_atts_data {
index 313f7af..688d78f 100644 (file)
@@ -121,62 +121,45 @@ enum lsatt_flags {
 };
 
 /** Data passed to the action function of lsatt */
-struct lsatt_action_data {
-       /** The result buffer. */
-       struct para_buffer pb;
-       /** The given flags for the lsatt command. */
-       unsigned flags;
-};
-
 static int print_attribute(struct osl_table *table, struct osl_row *row,
                const char *name, void *data)
 {
-       struct lsatt_action_data *laad = data;
+       struct afs_callback_arg *aca = data;
+       unsigned flags = *(unsigned *)aca->query.data;
        struct osl_object bitnum_obj;
        int ret;
 
-       if (!(laad->flags & LSATT_FLAG_LONG)) {
-               para_printf(&laad->pb, "%s\n", name);
+       if (!(flags & LSATT_FLAG_LONG)) {
+               para_printf(&aca->pbout, "%s\n", name);
                return 1;
        }
        ret = osl(osl_get_object(table, row, ATTCOL_BITNUM, &bitnum_obj));
        if (ret < 0) {
-               para_printf(&laad->pb, "%s: %s\n", name, para_strerror(-ret));
+               para_printf(&aca->pbout, "%s: %s\n", name, para_strerror(-ret));
                return ret;
        }
-       para_printf(&laad->pb, "%u\t%s\n", *(unsigned char*)bitnum_obj.data,
+       para_printf(&aca->pbout, "%u\t%s\n", *(unsigned char*)bitnum_obj.data,
                name);
        return 1;
 }
 
 static int com_lsatt_callback(struct afs_callback_arg *aca)
 {
+       unsigned flags = *(unsigned *)aca->query.data;
        int ret;
-       struct lsatt_action_data laad = {
-               .flags = *(unsigned *)aca->query.data,
-               .pb = {
-                       .max_size = shm_get_shmmax(),
-                       .private_data = &(struct afs_max_size_handler_data) {
-                               .fd = aca->fd,
-                               .band = SBD_OUTPUT
-                       },
-                       .max_size_handler = afs_max_size_handler
-               }
-
-       };
        struct pattern_match_data pmd = {
                .table = attribute_table,
                .loop_col_num = ATTCOL_BITNUM,
                .match_col_num = ATTCOL_NAME,
-               .patterns = {.data = (char *)aca->query.data + sizeof(laad.flags),
-                       .size = aca->query.size - sizeof(laad.flags)},
+               .patterns = {.data = (char *)aca->query.data + sizeof(flags),
+                       .size = aca->query.size - sizeof(flags)},
                .pm_flags = PM_NO_PATTERN_MATCHES_EVERYTHING,
-               .data = &laad,
+               .data = aca,
                .action = print_attribute
        };
-       if (laad.flags & LSATT_FLAG_SORT_BY_ID)
+       if (flags & LSATT_FLAG_SORT_BY_ID)
                pmd.loop_col_num = ATTCOL_NAME;
-       if (laad.flags & LSATT_FLAG_REVERSE)
+       if (flags & LSATT_FLAG_REVERSE)
                pmd.pm_flags |= PM_REVERSE_LOOP;
        ret = for_each_matching_row(&pmd);
        if (ret < 0)
@@ -184,7 +167,6 @@ static int com_lsatt_callback(struct afs_callback_arg *aca)
        if (pmd.num_matches == 0)
                ret = -E_NO_MATCH;
 out:
-       flush_and_free_pb(&laad.pb);
        return ret;
 }
 
@@ -229,14 +211,6 @@ static int com_addatt_callback(struct afs_callback_arg *aca)
 {
        char *p;
        int ret = 1;
-       struct para_buffer pb = {
-               .max_size = shm_get_shmmax(),
-               .private_data = &(struct afs_max_size_handler_data) {
-                       .fd = aca->fd,
-                       .band = SBD_OUTPUT
-               },
-               .max_size_handler = afs_max_size_handler
-       };
        size_t len;
 
        for (
@@ -251,12 +225,12 @@ static int com_addatt_callback(struct afs_callback_arg *aca)
 
                len = strlen(p);
                if (!len || p[len - 1] == '-' || p[len - 1] == '+') {
-                       para_printf(&pb, "invalid attribute name: %s\n", p);
+                       para_printf(&aca->pbout, "invalid attribute name: %s\n", p);
                        continue;
                }
                ret = get_attribute_bitnum_by_name(p, &bitnum);
                if (ret >= 0) {
-                       para_printf(&pb, "attribute \"%s\" already exists\n", p);
+                       para_printf(&aca->pbout, "attribute \"%s\" already exists\n", p);
                        continue;
                }
                if (ret != -OSL_ERRNO_TO_PARA_ERROR(E_OSL_RB_KEY_NOT_FOUND)) /* error */
@@ -284,15 +258,14 @@ static int com_addatt_callback(struct afs_callback_arg *aca)
                        goto out;
                aed.name = p;
                aed.bitnum = bitnum;
-               ret = afs_event(ATTRIBUTE_ADD, &pb, &aed);
+               ret = afs_event(ATTRIBUTE_ADD, &aca->pbout, &aed);
                if (ret < 0)
                        goto out;
                greatest_att_bitnum = PARA_MAX(greatest_att_bitnum, (int)bitnum);
        }
 out:
        if (ret < 0)
-               para_printf(&pb, "%s: %s\n", p, para_strerror(-ret));
-       flush_and_free_pb(&pb);
+               para_printf(&aca->pbout, "%s: %s\n", p, para_strerror(-ret));
        return 0;
 }
 
@@ -316,14 +289,6 @@ static int com_mvatt_callback(struct afs_callback_arg *aca)
        char *new = old + size;
        struct osl_object obj = {.data = old, .size = size};
        struct osl_row *row;
-       struct para_buffer pb = {
-               .max_size = shm_get_shmmax(),
-               .private_data = &(struct afs_max_size_handler_data) {
-                       .fd = aca->fd,
-                       .band = SBD_OUTPUT
-               },
-               .max_size_handler = afs_max_size_handler,
-       };
        int ret;
 
        ret = osl(osl_get_row(attribute_table, ATTCOL_NAME, &obj, &row));
@@ -334,10 +299,9 @@ static int com_mvatt_callback(struct afs_callback_arg *aca)
        ret = osl(osl_update_object(attribute_table, row, ATTCOL_NAME, &obj));
 out:
        if (ret < 0)
-               para_printf(&pb, "cannot rename %s to %s\n", old, new);
+               para_printf(&aca->pbout, "cannot rename %s to %s\n", old, new);
        else
-               ret = afs_event(ATTRIBUTE_RENAME, &pb, NULL);
-       flush_and_free_pb(&pb);
+               ret = afs_event(ATTRIBUTE_RENAME, &aca->pbout, NULL);
        return ret;
 }
 
@@ -352,41 +316,33 @@ int com_mvatt(struct command_context *cc)
 static int remove_attribute(struct osl_table *table, struct osl_row *row,
                const char *name, void *data)
 {
-       struct para_buffer *pb = data;
+       struct afs_callback_arg *aca = data;
        int ret;
        struct rmatt_event_data red = {.name = name};
 
        ret = get_attribute_bitnum_by_name(name, &red.bitnum);
        if (ret < 0) {
-               para_printf(pb, "cannot remove %s\n", name);
+               para_printf(&aca->pbout, "cannot remove %s\n", name);
                return ret;
        }
-       para_printf(pb, "removing attribute %s\n", name);
+       para_printf(&aca->pbout, "removing attribute %s\n", name);
        ret = osl(osl_del_row(table, row));
        if (ret < 0) {
-               para_printf(pb, "cannot remove %s\n", name);
+               para_printf(&aca->pbout, "cannot remove %s\n", name);
                return ret;
        }
-       return afs_event(ATTRIBUTE_REMOVE, pb, &red);
+       return afs_event(ATTRIBUTE_REMOVE, &aca->pbout, &red);
 }
 
 static int com_rmatt_callback(struct afs_callback_arg *aca)
 {
-       struct para_buffer pb = {
-               .max_size = shm_get_shmmax(),
-               .private_data = &(struct afs_max_size_handler_data) {
-                       .fd = aca->fd,
-                       .band = SBD_OUTPUT
-               },
-               .max_size_handler = afs_max_size_handler,
-       };
        int ret;
        struct pattern_match_data pmd = {
                .table = attribute_table,
                .patterns = aca->query,
                .loop_col_num = ATTCOL_BITNUM,
                .match_col_num = ATTCOL_NAME,
-               .data = &pb,
+               .data = aca,
                .action = remove_attribute
        };
        ret = for_each_matching_row(&pmd);
@@ -395,7 +351,6 @@ static int com_rmatt_callback(struct afs_callback_arg *aca)
        if (pmd.num_matches == 0)
                ret = -E_NO_MATCH;
 out:
-       flush_and_free_pb(&pb);
        return ret;
 }
 
@@ -510,14 +465,6 @@ int attribute_check_callback(struct afs_callback_arg *aca)
 {
        int ret;
        uint64_t att_mask = 0; /* bits corresponding to a attributes */
-       struct para_buffer pb = {
-               .max_size = shm_get_shmmax(),
-               .private_data = &(struct afs_max_size_handler_data) {
-                       .fd = aca->fd,
-                       .band = SBD_OUTPUT
-               },
-               .max_size_handler = afs_max_size_handler,
-       };
 
        ret = osl_rbtree_loop(attribute_table, ATTCOL_BITNUM, &att_mask,
                att_logical_or);
@@ -526,9 +473,7 @@ int attribute_check_callback(struct afs_callback_arg *aca)
                        para_strerror(-ret));
                return ret;
        }
-       ret = aft_check_attributes(att_mask, &pb);
-       flush_and_free_pb(&pb);
-       return ret;
+       return aft_check_attributes(att_mask, &aca->pbout);
 }
 
 /**
diff --git a/blob.c b/blob.c
index 0b5f1f9..1a41182 100644 (file)
--- a/blob.c
+++ b/blob.c
@@ -100,64 +100,47 @@ enum blob_ls_flags {
        BLOB_LS_FLAG_SORT_BY_ID = 4,
 };
 
-/** Structure passed to the \p print_blob function. */
-struct lsblob_action_data {
-       /** The flags given at the command line. */
-       uint32_t flags;
-       /** Message buffer. */
-       struct para_buffer pb;
-};
-
 static int print_blob(struct osl_table *table, struct osl_row *row,
                const char *name, void *data)
 {
-       struct lsblob_action_data *lbad = data;
+       struct afs_callback_arg *aca = data;
+       uint32_t flags = *(uint32_t *)aca->query.data;
        struct osl_object obj;
        uint32_t id;
        int ret;
 
-       if (!(lbad->flags & BLOB_LS_FLAG_LONG)) {
-               para_printf(&lbad->pb, "%s\n", name);
+       if (!(flags & BLOB_LS_FLAG_LONG)) {
+               para_printf(&aca->pbout, "%s\n", name);
                return 0;
        }
        ret = osl(osl_get_object(table, row, BLOBCOL_ID, &obj));
        if (ret < 0) {
-               para_printf(&lbad->pb, "cannot list %s\n", name);
+               para_printf(&aca->pbout, "cannot list %s\n", name);
                return ret;
        }
        id = *(uint32_t *)obj.data;
-       para_printf(&lbad->pb, "%u\t%s\n", id, name);
+       para_printf(&aca->pbout, "%u\t%s\n", id, name);
        return 1;
 }
 
 static int com_lsblob_callback(struct osl_table *table,
                struct afs_callback_arg *aca)
 {
-       struct lsblob_action_data lbad = {
-               .flags = *(uint32_t *)aca->query.data,
-               .pb = {
-                       .max_size = shm_get_shmmax(),
-                       .private_data = &(struct afs_max_size_handler_data) {
-                               .fd = aca->fd,
-                               .band = SBD_OUTPUT
-                       },
-                       .max_size_handler = afs_max_size_handler,
-               }
-       };
+       uint32_t flags = *(uint32_t *)aca->query.data;
        struct pattern_match_data pmd = {
                .table = table,
                .patterns = {.data = (char *)aca->query.data + sizeof(uint32_t),
                        .size = aca->query.size - sizeof(uint32_t)},
                .pm_flags = PM_NO_PATTERN_MATCHES_EVERYTHING | PM_SKIP_EMPTY_NAME,
                .match_col_num = BLOBCOL_NAME,
-               .data = &lbad,
+               .data = aca,
                .action = print_blob,
        };
        int ret;
 
-       if (lbad.flags & BLOB_LS_FLAG_REVERSE)
+       if (flags & BLOB_LS_FLAG_REVERSE)
                pmd.pm_flags |= PM_REVERSE_LOOP;
-       if (!(lbad.flags & BLOB_LS_FLAG_SORT_BY_ID))
+       if (!(flags & BLOB_LS_FLAG_SORT_BY_ID))
                pmd.loop_col_num = BLOBCOL_NAME;
        else
                pmd.loop_col_num = BLOBCOL_ID;
@@ -167,7 +150,6 @@ static int com_lsblob_callback(struct osl_table *table,
        if (pmd.num_matches == 0 && pmd.patterns.size > 0)
                ret = -E_NO_MATCH;
 out:
-       flush_and_free_pb(&lbad.pb);
        return ret;
 }
 
@@ -252,10 +234,10 @@ static int com_catblob(afs_callback *f, struct command_context *cc)
 static int remove_blob(struct osl_table *table, struct osl_row *row,
                const char *name, void *data)
 {
-       struct para_buffer *pb = data;
+       struct afs_callback_arg *aca = data;
        int ret = osl(osl_del_row(table, row));
        if (ret < 0) {
-               para_printf(pb, "cannot remove %s\n", name);
+               para_printf(&aca->pbout, "cannot remove %s\n", name);
                return ret;
        }
        return 1;
@@ -265,21 +247,13 @@ static int com_rmblob_callback(struct osl_table *table,
                struct afs_callback_arg *aca)
 {
        int ret;
-       struct para_buffer pb = {
-               .max_size = shm_get_shmmax(),
-               .private_data = &(struct afs_max_size_handler_data) {
-                       .fd = aca->fd,
-                       .band = SBD_OUTPUT
-               },
-               .max_size_handler = afs_max_size_handler,
-       };
        struct pattern_match_data pmd = {
                .table = table,
                .patterns = aca->query,
                .loop_col_num = BLOBCOL_NAME,
                .match_col_num = BLOBCOL_NAME,
                .pm_flags = PM_SKIP_EMPTY_NAME,
-               .data = &pb,
+               .data = aca,
                .action = remove_blob
        };
        ret = for_each_matching_row(&pmd);
@@ -288,11 +262,11 @@ static int com_rmblob_callback(struct osl_table *table,
        if (pmd.num_matches == 0)
                ret = -E_NO_MATCH;
        else {
-               para_printf(&pb, "removed %d blob(s)\n", pmd.num_matches);
+               para_printf(&aca->pbout, "removed %d blob(s)\n",
+                       pmd.num_matches);
                ret = afs_event(BLOB_RENAME, NULL, table);
        }
 out:
-       flush_and_free_pb(&pb);
        return ret;
 }
 
@@ -308,8 +282,8 @@ static int com_addblob_callback(struct osl_table *table,
                struct afs_callback_arg *aca)
 {
        struct osl_object objs[NUM_BLOB_COLUMNS];
-       char *name = aca->query.data, *msg;
-       size_t name_len = strlen(name) + 1, msg_len;
+       char *name = aca->query.data;
+       size_t name_len = strlen(name) + 1;
        uint32_t id;
        unsigned num_rows;
        int ret;
@@ -374,11 +348,9 @@ static int com_addblob_callback(struct osl_table *table,
        ret = afs_event(BLOB_ADD, NULL, table);
 out:
        if (ret < 0)
-               msg_len = xasprintf(&msg, "cannot add %s\n", name);
+               para_printf(&aca->pbout, "cannot add %s\n", name);
        else
-               msg_len = xasprintf(&msg, "added %s as id %u\n", name, id);
-       pass_buffer_as_shm(aca->fd, SBD_OUTPUT, msg, msg_len);
-       free(msg);
+               para_printf(&aca->pbout, "added %s as id %u\n", name, id);
        return ret;
 }
 
@@ -471,27 +443,22 @@ static int com_mvblob_callback(struct osl_table *table,
        struct osl_object obj = {.data = src, .size = strlen(src) + 1};
        char *dest = src + obj.size;
        struct osl_row *row;
-       struct para_buffer pb = {
-               .max_size = shm_get_shmmax(),
-               .private_data = &aca->fd,
-               .max_size_handler = afs_max_size_handler
-       };
        int ret = osl(osl_get_row(table, BLOBCOL_NAME, &obj, &row));
 
        if (ret < 0) {
-               para_printf(&pb, "cannot find source blob %s\n", src);
+               para_printf(&aca->pbout, "cannot find source blob %s\n", src);
                goto out;
        }
        obj.data = dest;
        obj.size = strlen(dest) + 1;
        ret = osl(osl_update_object(table, row, BLOBCOL_NAME, &obj));
        if (ret < 0) {
-               para_printf(&pb, "cannot rename blob %s to %s\n", src, dest);
+               para_printf(&aca->pbout, "cannot rename blob %s to %s\n",
+                       src, dest);
                goto out;
        }
        ret = afs_event(BLOB_RENAME, NULL, table);
 out:
-       flush_and_free_pb(&pb);
        return ret;
 }
 
diff --git a/mood.c b/mood.c
index 639818c..f709aa8 100644 (file)
--- a/mood.c
+++ b/mood.c
@@ -437,21 +437,9 @@ out:
  */
 int mood_check_callback(struct afs_callback_arg *aca)
 {
-       int ret;
-       struct para_buffer pb = {
-               .max_size = shm_get_shmmax(),
-               .private_data = &(struct afs_max_size_handler_data) {
-                       .fd = aca->fd,
-                       .band = SBD_OUTPUT
-               },
-               .max_size_handler = afs_max_size_handler
-       };
-
-       para_printf(&pb, "checking moods...\n");
-       ret = osl(osl_rbtree_loop(moods_table, BLOBCOL_ID, &pb,
+       para_printf(&aca->pbout, "checking moods...\n");
+       return osl(osl_rbtree_loop(moods_table, BLOBCOL_ID, &aca->pbout,
                check_mood));
-       flush_and_free_pb(&pb);
-       return ret;
 }
 
 static int64_t normalized_value(int64_t x, int64_t n, int64_t sum, int64_t qd)
index 4b2d17c..9616ed0 100644 (file)
@@ -131,20 +131,9 @@ static int check_playlist(struct osl_row *row, void *data)
  */
 int playlist_check_callback(struct afs_callback_arg *aca)
 {
-       int ret;
-       struct para_buffer pb = {
-               .max_size = shm_get_shmmax(),
-               .private_data = &(struct afs_max_size_handler_data) {
-                       .fd = aca->fd,
-                       .band = SBD_OUTPUT
-               },
-               .max_size_handler = afs_max_size_handler,
-       };
-       para_printf(&pb, "checking playlists...\n");
-       ret = osl(osl_rbtree_loop(playlists_table, BLOBCOL_ID, &pb,
+       para_printf(&aca->pbout, "checking playlists...\n");
+       return osl(osl_rbtree_loop(playlists_table, BLOBCOL_ID, &aca->pbout,
                check_playlist));
-       flush_and_free_pb(&pb);
-       return ret;
 }
 
 /**