]> git.tuebingen.mpg.de Git - paraslash.git/commitdiff
Send command output via sideband.
authorAndre Noll <maan@systemlinux.org>
Sat, 5 May 2012 10:11:54 +0000 (12:11 +0200)
committerAndre Noll <maan@systemlinux.org>
Mon, 7 May 2012 10:47:07 +0000 (12:47 +0200)
The next step towards sideband connections is to send the output of
each command as a sideband packet. To this aim, afs_cb_result_handler(),
pass_buffer_as_shm() and the callback_result_handler typedef are modified
to receive an additional "band" parameter.

For regular command output the value of this parameter is SBD_OUTPUT,
the sideband designator for normal output. The client code is patched
to add the contents of received SBD_OUTPUT sidband packets to the
buffer tree for the normal ouput.

However, log messages, which are only written to the log output
of the server at the moment, may also passed to the client via the
SBD_XXX_LOG designators, where XXX is the name of one of the usual
log levels for para_log().

The patch contains quite a few changes of the form

if (use_sideband)
do_new_stuff()
else
do_it_as_before()

which is a bit ugly, but we may remove the old method in 0.5.0,
which will support only sideband connections.

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

diff --git a/afs.c b/afs.c
index f76da3dc17a398e2b273ec3a12b5b166520b6d56..23f2a93bc8610be978a98e61af6fd43ae6d1785f 100644 (file)
--- a/afs.c
+++ b/afs.c
@@ -142,6 +142,8 @@ struct callback_query {
 struct callback_result {
        /** The number of bytes of the result. */
        size_t result_size;
+       /** The band designator (loglevel for the result). */
+       uint8_t band;
 };
 
 static int dispatch_result(int result_shmid, callback_result_handler *handler,
@@ -149,7 +151,8 @@ static int dispatch_result(int result_shmid, callback_result_handler *handler,
 {
        struct osl_object result;
        void *result_shm;
-       int ret2, ret = shm_attach(result_shmid, ATTACH_RO, &result_shm);
+       /* must attach r/w as result.data might get encrypted in-place. */
+       int ret2, ret = shm_attach(result_shmid, ATTACH_RW, &result_shm);
        struct callback_result *cr = result_shm;
 
        if (ret < 0) {
@@ -160,7 +163,7 @@ static int dispatch_result(int result_shmid, callback_result_handler *handler,
        result.data = result_shm + sizeof(*cr);
        if (result.size) {
                assert(handler);
-               ret = handler(&result, private_result_data);
+               ret = handler(&result, cr->band, private_result_data);
                if (ret < 0)
                        PARA_NOTICE_LOG("result handler error: %s\n",
                                para_strerror(-ret));
@@ -549,6 +552,7 @@ static void com_select_callback(int fd, const struct osl_object *query)
                .max_size = shm_get_shmmax(),
                .private_data = &(struct afs_max_size_handler_data) {
                        .fd = fd,
+                       .band = SBD_OUTPUT
                },
                .max_size_handler = afs_max_size_handler,
        };
@@ -580,7 +584,7 @@ static void com_select_callback(int fd, const struct osl_object *query)
                        current_mop : "dummy mood", num_admissible);
 out:
        if (ret2 >= 0 && pb.offset)
-               pass_buffer_as_shm(fd, pb.buf, pb.offset);
+               pass_buffer_as_shm(fd, SBD_OUTPUT, pb.buf, pb.offset);
        free(pb.buf);
 }
 
@@ -588,23 +592,24 @@ out:
  * Result handler for sending data to the para_client process.
  *
  * \param result The data to be sent.
- * \param private Pointer to the context.
+ * \param band The band designator.
+ * \param private Pointer to the command context.
  *
- * \return The return value of the underlying call to sc_send_bin_buffer().
+ * \return The return value of the underlying call to \ref command.c::send_sb.
  *
- * \sa \ref callback_result_handler, \ref sc_send_bin_buffer().
+ * \sa \ref callback_result_handler, \ref command.c::send_sb.
  */
-int afs_cb_result_handler(struct osl_object *result, void *private)
+int afs_cb_result_handler(struct osl_object *result, uint8_t band,
+               void *private)
 {
        struct command_context *cc = private;
-       int ret;
 
        if (!result->size)
                return 1;
-       ret = sc_send_bin_buffer(&cc->scc, result->data, result->size);
-       if (ret < 0 || ret == result->size)
-               return ret;
-       return -E_SHORT_WRITE;
+       if (cc->use_sideband)
+               return send_sb(&cc->scc, result->data, result->size, band,
+                       true);
+       return sc_send_bin_buffer(&cc->scc, result->data, result->size);
 }
 
 int com_select(struct command_context *cc)
@@ -787,6 +792,7 @@ static void command_pre_select(struct sched *s, struct task *t)
  * Send data as shared memory to a file descriptor.
  *
  * \param fd File descriptor to send the shmid to.
+ * \param band The band designator for this data.
  * \param buf The buffer holding the data to be sent.
  * \param size The size of \a buf.
  *
@@ -800,7 +806,7 @@ static void command_pre_select(struct sched *s, struct task *t)
  * \return Zero if \a buf is \p NULL or \a size is zero. Negative on errors,
  * and positive on success.
  */
-int pass_buffer_as_shm(int fd, char *buf, size_t size)
+int pass_buffer_as_shm(int fd, uint8_t band, char *buf, size_t size)
 {
        int ret, shmid;
        void *shm;
@@ -808,7 +814,7 @@ int pass_buffer_as_shm(int fd, char *buf, size_t size)
 
        if (!buf || !size)
                return 0;
-       ret = shm_new(size + sizeof(struct callback_result));
+       ret = shm_new(size + sizeof(*cr));
        if (ret < 0)
                return ret;
        shmid = ret;
@@ -817,6 +823,7 @@ int pass_buffer_as_shm(int fd, char *buf, size_t size)
                goto err;
        cr = shm;
        cr->result_size = size;
+       cr->band = band;
        memcpy(shm + sizeof(*cr), buf, size);
        ret = shm_detach(shm);
        if (ret < 0)
@@ -1025,7 +1032,7 @@ out:
        if (ret < 0)
                para_printf(&pb, "%s\n", para_strerror(-ret));
        if (pb.buf)
-               pass_buffer_as_shm(fd, pb.buf, pb.offset);
+               pass_buffer_as_shm(fd, SBD_OUTPUT, pb.buf, pb.offset);
        free(pb.buf);
 }
 
diff --git a/afs.h b/afs.h
index d30621a7ddfcbd519cad7873065335b47bce1598..2789e94e91e0b2fc4def72671165ea043e0970a4 100644 (file)
--- a/afs.h
+++ b/afs.h
@@ -205,14 +205,16 @@ typedef void callback_function(int fd, const struct osl_object *);
  *
  * \sa \ref send_callback_request().
  */
-typedef int callback_result_handler(struct osl_object *result, void *private);
-int afs_cb_result_handler(struct osl_object *result, void *private);
-int pass_buffer_as_shm(int fd, char *buf, size_t size);
+typedef int callback_result_handler(struct osl_object *result, uint8_t band, void *private);
+int afs_cb_result_handler(struct osl_object *result, uint8_t band, void *private);
+int pass_buffer_as_shm(int fd, uint8_t band, char *buf, size_t size);
 
 /** Structure passed to the AFS max_size handler. */
 struct afs_max_size_handler_data {
        /** Local socket connecting the command handler and the AFS process. */
        int fd;
+       /** The sideband designator for this data packet. */
+       uint8_t band;
 };
 
 /**
@@ -233,7 +235,7 @@ struct afs_max_size_handler_data {
 _static_inline_ int afs_max_size_handler(char *buf, size_t size, void *private)
 {
        struct afs_max_size_handler_data *amshd = private;
-       return pass_buffer_as_shm(amshd->fd, buf, size);
+       return pass_buffer_as_shm(amshd->fd, amshd->band, buf, size);
 }
 
 __noreturn void afs_init(uint32_t cookie, int socket_fd);
diff --git a/aft.c b/aft.c
index 2c123ce3e480f8b1d8d9e19cb4825fc2e0f664c0..2732790938442822e983205a164cc5f09185a049 100644 (file)
--- a/aft.c
+++ b/aft.c
@@ -1356,6 +1356,7 @@ static void com_ls_callback(int fd, const struct osl_object *query)
                .max_size_handler = afs_max_size_handler,
                .private_data = &(struct afs_max_size_handler_data) {
                        .fd = fd,
+                       .band = SBD_OUTPUT
                }
        };
        int i = 0, ret;
@@ -1399,7 +1400,7 @@ static void com_ls_callback(int fd, const struct osl_object *query)
                }
 out:
        if (b.offset)
-               pass_buffer_as_shm(fd, b.buf, b.offset);
+               pass_buffer_as_shm(fd, SBD_OUTPUT, b.buf, b.offset);
        free(b.buf);
        free(opts->data);
        free(opts->data_ptr);
@@ -1685,6 +1686,7 @@ static void com_add_callback(int fd, const struct osl_object *query)
                .max_size_handler = afs_max_size_handler,
                .private_data = &(struct afs_max_size_handler_data) {
                        .fd = fd,
+                       .band = SBD_OUTPUT
                }
        };
        uint16_t afhi_offset, chunks_offset;
@@ -1807,7 +1809,7 @@ out:
        if (ret < 0)
                para_printf(&msg, "%s\n", para_strerror(-ret));
        if (msg.offset)
-               pass_buffer_as_shm(fd, msg.buf, msg.offset);
+               pass_buffer_as_shm(fd, SBD_OUTPUT, msg.buf, msg.offset);
        free(msg.buf);
 }
 
@@ -1826,7 +1828,8 @@ static void path_brother_callback(int fd, const struct osl_object *query)
        int ret = aft_get_row_of_path(path, &path_brother);
        if (ret < 0)
                return;
-       pass_buffer_as_shm(fd, (char *)&path_brother, sizeof(path_brother));
+       pass_buffer_as_shm(fd, SBD_OUTPUT, (char *)&path_brother,
+               sizeof(path_brother));
 }
 
 static void hash_sister_callback(int fd, const struct osl_object *query)
@@ -1837,10 +1840,12 @@ static void hash_sister_callback(int fd, const struct osl_object *query)
        hash_sister = find_hash_sister(hash);
        if (!hash_sister)
                return;
-       pass_buffer_as_shm(fd, (char *)&hash_sister, sizeof(hash_sister));
+       pass_buffer_as_shm(fd, SBD_OUTPUT, (char *)&hash_sister,
+               sizeof(hash_sister));
 }
 
-static int get_row_pointer_from_result(struct osl_object *result, void *private)
+static int get_row_pointer_from_result(struct osl_object *result,
+               __a_unused uint8_t band, void *private)
 {
        struct osl_row **row = private;
        *row = *(struct osl_row **)(result->data);
@@ -1869,8 +1874,12 @@ static int add_one_audio_file(const char *path, void *private_data)
        ret = 1;
        if (pb && (pad->flags & ADD_FLAG_LAZY)) { /* lazy is really cheap */
                if (pad->flags & ADD_FLAG_VERBOSE)
-                       send_ret = sc_send_va_buffer(&pad->cc->scc,
-                               "lazy-ignore: %s\n", path);
+                       send_ret = pad->cc->use_sideband?
+                               send_sb_va(&pad->cc->scc, SBD_OUTPUT,
+                                       "lazy-ignore: %s\n", path)
+                       :
+                               sc_send_va_buffer(&pad->cc->scc,
+                                       "lazy-ignore: %s\n", path);
                goto out_free;
        }
        /* We still want to add this file. Compute its hash. */
@@ -1890,8 +1899,12 @@ static int add_one_audio_file(const char *path, void *private_data)
        ret = 1;
        if (pb && hs && hs == pb && !(pad->flags & ADD_FLAG_FORCE)) {
                if (pad->flags & ADD_FLAG_VERBOSE)
-                       send_ret = sc_send_va_buffer(&pad->cc->scc,
-                               "%s exists, not forcing update\n", path);
+                       send_ret = pad->cc->use_sideband?
+                               send_sb_va(&pad->cc->scc, SBD_OUTPUT,
+                                       "%s exists, not forcing update\n", path)
+                       :
+                               sc_send_va_buffer(&pad->cc->scc,
+                                       "%s exists, not forcing update\n", path);
                goto out_unmap;
        }
        /*
@@ -1908,7 +1921,12 @@ static int add_one_audio_file(const char *path, void *private_data)
        munmap(map.data, map.size);
        close(fd);
        if (pad->flags & ADD_FLAG_VERBOSE) {
-               send_ret = sc_send_va_buffer(&pad->cc->scc, "adding %s\n", path);
+               send_ret = pad->cc->use_sideband?
+                       send_sb_va(&pad->cc->scc, SBD_OUTPUT,
+                               "adding %s\n", path)
+               :
+                       sc_send_va_buffer(&pad->cc->scc,
+                               "adding %s\n", path);
                if (send_ret < 0)
                        goto out_free;
        }
@@ -1923,8 +1941,14 @@ out_unmap:
        munmap(map.data, map.size);
 out_free:
        if (ret < 0 && send_ret >= 0)
-               send_ret = sc_send_va_buffer(&pad->cc->scc,
-                       "failed to add %s (%s)\n", path, para_strerror(-ret));
+               send_ret = pad->cc->use_sideband?
+                       send_sb_va(&pad->cc->scc, SBD_ERROR_LOG,
+                               "failed to add %s (%s)\n", path,
+                               para_strerror(-ret))
+               :
+                       sc_send_va_buffer(&pad->cc->scc,
+                               "failed to add %s (%s)\n", path,
+                               para_strerror(-ret));
        free(obj.data);
        clear_afhi(afhi_ptr);
        /* Stop adding files only on send errors. */
@@ -1968,7 +1992,11 @@ int com_add(struct command_context *cc)
                char *path;
                ret = verify_path(cc->argv[i], &path);
                if (ret < 0) {
-                       ret = sc_send_va_buffer(&cc->scc, "%s: %s\n",
+                       ret = cc->use_sideband?
+                               send_sb_va(&cc->scc, SBD_ERROR_LOG, "%s: %s\n",
+                               cc->argv[i], para_strerror(-ret))
+                       :
+                               sc_send_va_buffer(&cc->scc, "%s: %s\n",
                                cc->argv[i], para_strerror(-ret));
                        if (ret < 0)
                                return ret;
@@ -1976,9 +2004,14 @@ int com_add(struct command_context *cc)
                }
                ret = stat(path, &statbuf);
                if (ret < 0) {
-                       ret = sc_send_va_buffer(&cc->scc,
-                               "failed to stat %s (%s)\n", path,
-                               strerror(errno));
+                       ret = cc->use_sideband?
+                               send_sb_va(&cc->scc, SBD_ERROR_LOG,
+                                       "failed to stat %s (%s)\n", path,
+                                       strerror(errno))
+                               :
+                               sc_send_va_buffer(&cc->scc,
+                                       "failed to stat %s (%s)\n", path,
+                                       strerror(errno));
                        free(path);
                        if (ret < 0)
                                return ret;
@@ -1990,8 +2023,12 @@ int com_add(struct command_context *cc)
                else
                        ret = add_one_audio_file(path, &pad);
                if (ret < 0) {
-                       sc_send_va_buffer(&cc->scc, "%s: %s\n", path,
-                               para_strerror(-ret));
+                       if (cc->use_sideband)
+                               send_sb_va(&cc->scc, SBD_OUTPUT, "%s: %s\n", path,
+                                       para_strerror(-ret));
+                       else
+                               sc_send_va_buffer(&cc->scc, "%s: %s\n", path,
+                                       para_strerror(-ret));
                        free(path);
                        return ret;
                }
@@ -2115,7 +2152,7 @@ static void com_touch_callback(int fd, const struct osl_object *query)
        else if (pmd.num_matches == 0)
                ret2 = para_printf(&tad.pb, "no matches\n");
        if (ret2 >= 0 && tad.pb.offset)
-               pass_buffer_as_shm(fd, tad.pb.buf, tad.pb.offset);
+               pass_buffer_as_shm(fd, SBD_OUTPUT, tad.pb.buf, tad.pb.offset);
        free(tad.pb.buf);
 }
 
@@ -2262,7 +2299,7 @@ static void com_rm_callback(int fd, const struct osl_object *query)
                        pmd.num_matches);
        }
        if (ret >= 0 && crd.pb.offset)
-               pass_buffer_as_shm(fd, crd.pb.buf, crd.pb.offset);
+               pass_buffer_as_shm(fd, SBD_OUTPUT, crd.pb.buf, crd.pb.offset);
        free(crd.pb.buf);
 }
 
@@ -2408,7 +2445,7 @@ out:
                        para_printf(&cad.pb, "nothing copied\n");
        }
        if (cad.pb.offset)
-               pass_buffer_as_shm(fd, cad.pb.buf, cad.pb.offset);
+               pass_buffer_as_shm(fd, SBD_OUTPUT, cad.pb.buf, cad.pb.offset);
        free(cad.pb.buf);
 }
 
@@ -2471,7 +2508,7 @@ static void afs_stat_callback(int fd, const struct osl_object *query)
 
        if (!buf)
                return;
-       pass_buffer_as_shm(fd, buf, strlen(buf));
+       pass_buffer_as_shm(fd, SBD_OUTPUT, buf, strlen(buf));
 }
 
 /**
@@ -2553,6 +2590,7 @@ void aft_check_callback(int fd, __a_unused const struct osl_object *query)
                .max_size = shm_get_shmmax(),
                .private_data = &(struct afs_max_size_handler_data) {
                        .fd = fd,
+                       .band = SBD_OUTPUT
                },
                .max_size_handler = afs_max_size_handler
        };
@@ -2562,7 +2600,7 @@ void aft_check_callback(int fd, __a_unused const struct osl_object *query)
                return;
        audio_file_loop(&pb, check_audio_file);
        if (pb.offset)
-               pass_buffer_as_shm(fd, pb.buf, pb.offset);
+               pass_buffer_as_shm(fd, SBD_OUTPUT, pb.buf, pb.offset);
        free(pb.buf);
 }
 
index f4e2012044ecb20c20333fe5a2d294131140b149..638e22ea70fe5e5bb5ebac55f0e296db387adc5c 100644 (file)
@@ -154,6 +154,7 @@ static void com_lsatt_callback(int fd, const struct osl_object *query)
                        .max_size = shm_get_shmmax(),
                        .private_data = &(struct afs_max_size_handler_data) {
                                .fd = fd,
+                               .band = SBD_OUTPUT
                        },
                        .max_size_handler = afs_max_size_handler
                }
@@ -175,7 +176,7 @@ static void com_lsatt_callback(int fd, const struct osl_object *query)
                pmd.pm_flags |= PM_REVERSE_LOOP;
        for_each_matching_row(&pmd);
        if (laad.pb.offset)
-               pass_buffer_as_shm(fd, laad.pb.buf, laad.pb.offset);
+               pass_buffer_as_shm(fd, SBD_OUTPUT, laad.pb.buf, laad.pb.offset);
        free(laad.pb.buf);
 }
 
@@ -208,12 +209,13 @@ int com_lsatt(struct command_context *cc)
        }
        ret = send_option_arg_callback_request(&options, cc->argc - i, cc->argv + i,
                com_lsatt_callback, afs_cb_result_handler, cc);
-
-       if (!ret) {
-               if (cc->argc > 1)
-                       ret = sc_send_va_buffer(&cc->scc, "no matches\n");
-       } else if (ret < 0)
+       if (ret < 0)
                send_strerror(cc, -ret);
+       else if (ret == 0 && cc->argc > 1)
+               ret = cc->use_sideband?
+                       send_sb_va(&cc->scc, SBD_ERROR_LOG, "no matches\n")
+               :
+                       sc_send_va_buffer(&cc->scc, "no matches\n");
        return ret;
 }
 
@@ -303,6 +305,7 @@ static void com_addatt_callback(int fd, const struct osl_object *query)
                .max_size = shm_get_shmmax(),
                .private_data = &(struct afs_max_size_handler_data) {
                        .fd = fd,
+                       .band = SBD_OUTPUT
                },
                .max_size_handler = afs_max_size_handler
        };
@@ -360,7 +363,7 @@ out:
        if (ret < 0 && ret2 >= 0)
                para_printf(&pb, "%s: %s\n", p, para_strerror(-ret));
        if (pb.offset)
-               pass_buffer_as_shm(fd, pb.buf, pb.offset);
+               pass_buffer_as_shm(fd, SBD_OUTPUT, pb.buf, pb.offset);
        free(pb.buf);
 }
 
@@ -388,6 +391,7 @@ static void com_mvatt_callback(int fd, const struct osl_object *query)
                .max_size = shm_get_shmmax(),
                .private_data = &(struct afs_max_size_handler_data) {
                        .fd = fd,
+                       .band = SBD_OUTPUT
                },
                .max_size_handler = afs_max_size_handler,
        };
@@ -405,7 +409,7 @@ out:
        else
                afs_event(ATTRIBUTE_RENAME, &pb, NULL);
        if (pb.offset)
-               pass_buffer_as_shm(fd, pb.buf, pb.offset);
+               pass_buffer_as_shm(fd, SBD_OUTPUT, pb.buf, pb.offset);
        free(pb.buf);
 }
 
@@ -460,6 +464,7 @@ static void com_rmatt_callback(int fd, const struct osl_object *query)
                        .max_size = shm_get_shmmax(),
                        .private_data = &(struct afs_max_size_handler_data) {
                                .fd = fd,
+                               .band = SBD_OUTPUT
                        },
                        .max_size_handler = afs_max_size_handler,
                }
@@ -479,7 +484,7 @@ static void com_rmatt_callback(int fd, const struct osl_object *query)
        else if (!raad.num_removed)
                ret2 = para_printf(&raad.pb, "no match -- nothing removed\n");
        if (ret2 >= 0 && raad.pb.offset)
-               pass_buffer_as_shm(fd, raad.pb.buf, raad.pb.offset);
+               pass_buffer_as_shm(fd, SBD_OUTPUT, raad.pb.buf, raad.pb.offset);
        free(raad.pb.buf);
 }
 
diff --git a/blob.c b/blob.c
index 5c70f04fc6ec95b197c37170d581f58b27810c98..f51f4de0257ede9e9bfaea933d6e1077f823d1fd 100644 (file)
--- a/blob.c
+++ b/blob.c
@@ -136,6 +136,7 @@ static void com_lsblob_callback(struct osl_table *table,
                        .max_size = shm_get_shmmax(),
                        .private_data = &(struct afs_max_size_handler_data) {
                                .fd = fd,
+                               .band = SBD_OUTPUT
                        },
                        .max_size_handler = afs_max_size_handler,
                }
@@ -163,7 +164,7 @@ static void com_lsblob_callback(struct osl_table *table,
        else if (pmd.num_matches == 0 && pmd.patterns.size > 0)
                para_printf(&lbad.pb, "no matches\n");
        if (lbad.pb.offset)
-               pass_buffer_as_shm(fd, lbad.pb.buf, lbad.pb.offset);
+               pass_buffer_as_shm(fd, SBD_OUTPUT, lbad.pb.buf, lbad.pb.offset);
        free(lbad.pb.buf);
 }
 
@@ -211,7 +212,7 @@ static int cat_blob(struct osl_table *table, struct osl_row *row,
        if (ret < 0)
                return (ret == osl(-E_OSL_EMPTY))? 0 : ret;
        assert(obj.size > 0);
-       ret = pass_buffer_as_shm(fd, obj.data, obj.size);
+       ret = pass_buffer_as_shm(fd, SBD_OUTPUT, obj.data, obj.size);
        ret2 = osl(osl_close_disk_object(&obj));
        return (ret < 0)? ret : ret2;
 }
@@ -231,7 +232,7 @@ static void com_catblob_callback(struct osl_table *table, int fd,
        for_each_matching_row(&pmd);
        if (pmd.num_matches == 0) {
                char err_msg[] = "no matches\n";
-               pass_buffer_as_shm(fd, err_msg, sizeof(err_msg));
+               pass_buffer_as_shm(fd, SBD_OUTPUT, err_msg, sizeof(err_msg));
        }
 }
 
@@ -270,6 +271,7 @@ static void com_rmblob_callback(struct osl_table *table, int fd,
                        .max_size = shm_get_shmmax(),
                        .private_data = &(struct afs_max_size_handler_data) {
                                .fd = fd,
+                               .band = SBD_OUTPUT
                        },
                        .max_size_handler = afs_max_size_handler,
                }
@@ -297,7 +299,7 @@ static void com_rmblob_callback(struct osl_table *table, int fd,
        }
 out:
        if (ret2 >= 0 && rmbd.pb.offset)
-               pass_buffer_as_shm(fd, rmbd.pb.buf, rmbd.pb.offset);
+               pass_buffer_as_shm(fd, SBD_OUTPUT, rmbd.pb.buf, rmbd.pb.offset);
        free(rmbd.pb.buf);
 }
 
@@ -437,7 +439,10 @@ static int stdin_command(struct command_context *cc, struct osl_object *arg_obj,
        struct osl_object query, stdin_obj;
        int ret;
 
-       ret = sc_send_buffer(&cc->scc, AWAITING_DATA_MSG);
+       if (cc->use_sideband)
+               ret = send_sb(&cc->scc, NULL, 0, SBD_AWAITING_DATA, false);
+       else
+               ret = sc_send_buffer(&cc->scc, AWAITING_DATA_MSG);
        if (ret < 0)
                return ret;
        ret = fd2buf(&cc->scc, max_len, &stdin_obj);
index ff351e8902e42fba250345878d60d7d55df1db62..daead879faa7f4dff4d9016c68f95426269551f0 100644 (file)
@@ -240,6 +240,41 @@ static char **parse_features(char *buf)
        return features;
 }
 
+static int dispatch_sbb(struct client_task *ct, struct sb_buffer *sbb)
+{
+       int ret, ll;
+
+       if (!sbb || !sbb->iov.iov_base || sbb->iov.iov_len == 0)
+               return 0;
+
+       switch (sbb->band) {
+       case SBD_OUTPUT:
+               btr_add_output(sbb->iov.iov_base, sbb->iov.iov_len, ct->btrn);
+               ret = 1;
+               goto out;
+       case SBD_DEBUG_LOG:
+       case SBD_INFO_LOG:
+       case SBD_NOTICE_LOG:
+       case SBD_WARNING_LOG:
+       case SBD_ERROR_LOG:
+       case SBD_CRIT_LOG:
+       case SBD_EMERG_LOG:
+               ll = sbb->band - SBD_DEBUG_LOG;
+               para_log(ll, "remote: %s", (char *)sbb->iov.iov_base);
+               ret = 1;
+               goto deallocate;
+       default:
+               PARA_ERROR_LOG("invalid band %d\n", sbb->band);
+               ret = -E_BAD_BAND;
+               goto deallocate;
+       }
+deallocate:
+       free(sbb->iov.iov_base);
+out:
+       sbb->iov.iov_base = NULL;
+       return ret;
+}
+
 static bool has_feature(const char *feature, struct client_task *ct)
 {
        return find_arg(feature, ct->features) >= 0? true : false;
@@ -430,6 +465,20 @@ static void client_post_select(struct sched *s, struct task *t)
        case CL_SENT_COMMAND:
                {
                char *buf2;
+               if (ct->use_sideband) {
+                       struct sb_buffer sbb;
+                       ret = recv_sb(ct, &s->rfds, &sbb);
+                       if (ret <= 0)
+                               goto out;
+                       if (sbb.band == SBD_AWAITING_DATA) {
+                               ct->status = CL_SENDING;
+                               free(sbb.iov.iov_base);
+                               goto out;
+                       }
+                       ct->status = CL_RECEIVING;
+                       ret = dispatch_sbb(ct, &sbb);
+                       goto out;
+               }
                /* can not use "buf" here because we need a malloced buffer */
                buf2 = para_malloc(CLIENT_BUFSIZE);
                ret = client_recv_buffer(ct, &s->rfds, buf2, CLIENT_BUFSIZE, &n);
@@ -477,6 +526,13 @@ static void client_post_select(struct sched *s, struct task *t)
                 */
                if (!FD_ISSET(ct->scc.fd, &s->rfds))
                        return;
+               if (ct->use_sideband) {
+                       struct sb_buffer sbb;
+                       ret = recv_sb(ct, &s->rfds, &sbb);
+                       if (ret > 0)
+                               ret = dispatch_sbb(ct, &sbb);
+                       goto out;
+               }
                buf2 = para_malloc(CLIENT_BUFSIZE);
                ret = client_recv_buffer(ct, &s->rfds, buf2, CLIENT_BUFSIZE, &n);
                if (n > 0) {
index 82194adf8b0c4568427b38f35a1eb1a7cadf70ae..7b474ab1e9337c85dfc5db7b1a997a0c81e59da0 100644 (file)
--- a/command.c
+++ b/command.c
@@ -258,7 +258,10 @@ __printf_3_4 int send_sb_va(struct stream_cipher_context *scc, int band,
 
 int send_strerror(struct command_context *cc, int err)
 {
-       return sc_send_va_buffer(&cc->scc, "%s\n", para_strerror(err));
+       return cc->use_sideband?
+               send_sb_va(&cc->scc, SBD_ERROR_LOG, "%s\n", para_strerror(err))
+       :
+               sc_send_va_buffer(&cc->scc, "%s\n", para_strerror(err));
 }
 
 /**
@@ -313,17 +316,20 @@ fail:
 
 int com_sender(struct command_context *cc)
 {
-       int i, ret;
+       int i, ret = 0;
        char *msg = NULL;
        struct sender_command_data scd;
 
        if (cc->argc < 2) {
                for (i = 0; senders[i].name; i++) {
-                       char *tmp = make_message("%s%s\n",
-                               msg? msg : "", senders[i].name);
+                       char *tmp;
+                       ret = xasprintf(&tmp, "%s%s\n", msg? msg : "",
+                               senders[i].name);
                        free(msg);
                        msg = tmp;
                }
+               if (cc->use_sideband)
+                       return send_sb(&cc->scc, msg, ret, SBD_OUTPUT, false);
                ret = sc_send_buffer(&cc->scc, msg);
                free(msg);
                return ret;
@@ -333,6 +339,9 @@ int com_sender(struct command_context *cc)
                if (scd.sender_num < 0)
                        return ret;
                msg = senders[scd.sender_num].help();
+               if (cc->use_sideband)
+                       return send_sb(&cc->scc, msg, strlen(msg), SBD_OUTPUT,
+                               false);
                ret = sc_send_buffer(&cc->scc, msg);
                free(msg);
                return ret;
@@ -365,8 +374,7 @@ int com_sender(struct command_context *cc)
 int com_si(struct command_context *cc)
 {
        int i, ret;
-       char *ut;
-       char *sender_info = NULL;
+       char *msg, *ut, *sender_info = NULL;
 
        if (cc->argc != 1)
                return -E_COMMAND_SYNTAX;
@@ -377,7 +385,7 @@ int com_si(struct command_context *cc)
                free(info);
        }
        ut = get_server_uptime_str(now);
-       ret = sc_send_va_buffer(&cc->scc, "version: " GIT_VERSION "\n"
+       ret = xasprintf(&msg, "version: " GIT_VERSION "\n"
                "up: %s\nplayed: %u\n"
                "server_pid: %d\n"
                "afs_pid: %d\n"
@@ -398,18 +406,27 @@ int com_si(struct command_context *cc)
        mutex_unlock(mmd_mutex);
        free(ut);
        free(sender_info);
+       if (cc->use_sideband)
+               return send_sb(&cc->scc, msg, ret, SBD_OUTPUT, false);
+       ret = sc_send_bin_buffer(&cc->scc, msg, ret);
+       free(msg);
        return ret;
 }
 
 /* version */
 int com_version(struct command_context *cc)
 {
+       char *msg;
+       size_t len;
+
        if (cc->argc != 1)
                return -E_COMMAND_SYNTAX;
-       return sc_send_buffer(&cc->scc, VERSION_TEXT("server")
-               "built: " BUILD_DATE "\n"
-               UNAME_RS ", " CC_VERSION "\n"
-       );
+       msg = VERSION_TEXT("server") "built: " BUILD_DATE "\n" UNAME_RS
+               ", " CC_VERSION "\n";
+       len = strlen(msg);
+       if (cc->use_sideband)
+               return send_sb(&cc->scc, msg, len, SBD_OUTPUT, true);
+       return sc_send_bin_buffer(&cc->scc, msg, len);
 }
 
 #define EMPTY_STATUS_ITEMS \
@@ -445,10 +462,16 @@ int com_version(struct command_context *cc)
  *
  * This is used by vss when currently no audio file is open.
  */
-static char *empty_status_items(int parser_friendly)
+static unsigned empty_status_items(int parser_friendly, char **result)
 {
+       static char *esi;
+       static unsigned len;
+
+       if (esi)
+               goto out;
+
        if (parser_friendly)
-               return make_message(
+               len = xasprintf(&esi,
                        #define ITEM(x) "0004 %02x:\n"
                        EMPTY_STATUS_ITEMS
                        #undef ITEM
@@ -456,14 +479,18 @@ static char *empty_status_items(int parser_friendly)
                        EMPTY_STATUS_ITEMS
                        #undef ITEM
                );
-       return make_message(
-               #define ITEM(x) "%s:\n"
-               EMPTY_STATUS_ITEMS
-               #undef ITEM
-               #define ITEM(x) ,status_item_list[SI_ ## x]
-               EMPTY_STATUS_ITEMS
-               #undef ITEM
-       );
+       else
+               len = xasprintf(&esi,
+                       #define ITEM(x) "%s:\n"
+                       EMPTY_STATUS_ITEMS
+                       #undef ITEM
+                       #define ITEM(x) ,status_item_list[SI_ ## x]
+                       EMPTY_STATUS_ITEMS
+                       #undef ITEM
+               );
+out:
+       *result = esi;
+       return len;
 }
 #undef EMPTY_STATUS_ITEMS
 
@@ -472,7 +499,7 @@ int com_stat(struct command_context *cc)
 {
        int i, ret;
        struct misc_meta_data tmp, *nmmd = &tmp;
-       char *s;
+       char *s, *esi = NULL;
        int32_t num = 0;
        int parser_friendly = 0;
 
@@ -503,15 +530,21 @@ int com_stat(struct command_context *cc)
        for (;;) {
                mmd_dup(nmmd);
                ret = get_status(nmmd, parser_friendly, &s);
-               ret = sc_send_bin_buffer(&cc->scc, s, ret);
-               free(s);
+               if (cc->use_sideband)
+                       ret = send_sb(&cc->scc, s, ret, SBD_OUTPUT, false);
+               else {
+                       ret = sc_send_bin_buffer(&cc->scc, s, ret);
+                       free(s);
+               }
                if (ret < 0)
                        goto out;
                if (nmmd->vss_status_flags & VSS_NEXT) {
-                       static char *esi;
-                       if (!esi)
-                               esi = empty_status_items(parser_friendly);
-                       ret = sc_send_buffer(&cc->scc, esi);
+                       ret = empty_status_items(parser_friendly, &esi);
+                       if (cc->use_sideband)
+                               ret = send_sb(&cc->scc, esi, ret, SBD_OUTPUT,
+                                       true);
+                       else
+                               ret = sc_send_bin_buffer(&cc->scc, esi, ret);
                        if (ret < 0)
                                goto out;
                } else
@@ -520,29 +553,34 @@ int com_stat(struct command_context *cc)
                if (num > 0 && !--num)
                        goto out;
                sleep(50);
+               ret = -E_SERVER_CRASH;
                if (getppid() == 1)
-                       return -E_SERVER_CRASH;
+                       goto out;
        }
 out:
+       free(esi);
        return ret;
 }
 
-static int send_list_of_commands(struct stream_cipher_context *scc, struct server_command *cmd,
+static int send_list_of_commands(struct command_context *cc, struct server_command *cmd,
                const char *handler)
 {
-       int ret, i;
+       int ret;
+       char *msg = NULL;
 
-       for (i = 1; cmd->name; cmd++, i++) {
-               char *perms = cmd_perms_itohuman(cmd->perms);
-               ret = sc_send_va_buffer(scc, "%s\t%s\t%s\t%s\n", cmd->name,
-                       handler,
-                       perms,
-                       cmd->description);
+       for (; cmd->name; cmd++) {
+               char *tmp, *perms = cmd_perms_itohuman(cmd->perms);
+               tmp = make_message("%s\t%s\t%s\t%s\n", cmd->name, handler,
+                       perms, cmd->description);
                free(perms);
-               if (ret < 0)
-                       return ret;
+               msg = para_strcat(msg, tmp);
+               free(tmp);
        }
-       return 1;
+       if (cc->use_sideband)
+               return send_sb(&cc->scc, msg, strlen(msg), SBD_OUTPUT, false);
+       ret = sc_send_buffer(&cc->scc, msg);
+       free(msg);
+       return ret;
 }
 
 /* returns string that must be freed by the caller */
@@ -570,22 +608,21 @@ static struct server_command *get_cmd_ptr(const char *name, char **handler)
 int com_help(struct command_context *cc)
 {
        struct server_command *cmd;
-       char *perms, *handler;
+       char *perms, *handler, *buf;
        int ret;
 
        if (cc->argc < 2) {
                /* no argument given, print list of commands */
-               if ((ret = send_list_of_commands(&cc->scc, server_cmds, "server")) < 0)
+               if ((ret = send_list_of_commands(cc, server_cmds, "server")) < 0)
                        return ret;
-               return send_list_of_commands(&cc->scc, afs_cmds, "afs");
+               return send_list_of_commands(cc, afs_cmds, "afs");
        }
        /* argument given for help */
        cmd = get_cmd_ptr(cc->argv[1], &handler);
        if (!cmd)
                return -E_BAD_CMD;
        perms = cmd_perms_itohuman(cmd->perms);
-       ret = sc_send_va_buffer(&cc->scc,
-               "%s - %s\n\n"
+       ret = xasprintf(&buf, "%s - %s\n\n"
                "handler: %s\n"
                "permissions: %s\n"
                "usage: %s\n\n"
@@ -599,6 +636,10 @@ int com_help(struct command_context *cc)
        );
        free(perms);
        free(handler);
+       if (cc->use_sideband)
+               return send_sb(&cc->scc, buf, ret, SBD_OUTPUT, false);
+       ret = sc_send_buffer(&cc->scc, buf);
+       free(buf);
        return ret;
 }
 
diff --git a/mood.c b/mood.c
index 6046137d31b63bc8406182b01ef650e2eafa5f0f..bafe710c09372a7e8a1f82168324d9a64a0e633e 100644 (file)
--- a/mood.c
+++ b/mood.c
@@ -17,6 +17,7 @@
 #include "list.h"
 #include "ipc.h"
 #include "mm.h"
+#include "sideband.h"
 
 /**
  * Contains statistical data of the currently admissible audio files.
@@ -427,6 +428,7 @@ void mood_check_callback(int fd, __a_unused const struct osl_object *query)
                .max_size = shm_get_shmmax(),
                .private_data = &(struct afs_max_size_handler_data) {
                        .fd = fd,
+                       .band = SBD_OUTPUT
                },
                .max_size_handler = afs_max_size_handler
        };
@@ -437,7 +439,7 @@ void mood_check_callback(int fd, __a_unused const struct osl_object *query)
        osl_rbtree_loop(moods_table, BLOBCOL_ID, &pb,
                check_mood);
        if (pb.offset)
-               pass_buffer_as_shm(fd, pb.buf, pb.offset);
+               pass_buffer_as_shm(fd, SBD_OUTPUT, pb.buf, pb.offset);
        free(pb.buf);
 }
 
index efd27476f2199cb1dd82a3af50ee9f26aaded8af..48ee4ca78d8174ed32da793749566214f5ecd721 100644 (file)
@@ -13,6 +13,7 @@
 #include "afh.h"
 #include "afs.h"
 #include "ipc.h"
+#include "sideband.h"
 
 /** \file playlist.c Functions for loading and saving playlists. */
 
@@ -134,6 +135,7 @@ void playlist_check_callback(int fd, __a_unused const struct osl_object *query)
                .max_size = shm_get_shmmax(),
                .private_data = &(struct afs_max_size_handler_data) {
                        .fd = fd,
+                       .band = SBD_OUTPUT
                },
                .max_size_handler = afs_max_size_handler,
        };
@@ -144,7 +146,7 @@ void playlist_check_callback(int fd, __a_unused const struct osl_object *query)
        osl_rbtree_loop(playlists_table, BLOBCOL_ID, &pb,
                check_playlist);
        if (pb.offset)
-               pass_buffer_as_shm(fd, pb.buf, pb.offset);
+               pass_buffer_as_shm(fd, SBD_OUTPUT, pb.buf, pb.offset);
        free(pb.buf);
 }