X-Git-Url: http://git.tuebingen.mpg.de/?p=paraslash.git;a=blobdiff_plain;f=afs.c;h=f1e28f14982779ee0fff694ddf95a97c3e6bf318;hp=73f2c65a3d87cdd4a2ab3861985d25047140e44a;hb=30112f921d2bc97160e4b7ef3762a9ad3ad15ea3;hpb=2e2f91c92bbdd4107925bcaf521242c588afbfe4 diff --git a/afs.c b/afs.c index 73f2c65a..f1e28f14 100644 --- a/afs.c +++ b/afs.c @@ -26,6 +26,8 @@ #include "signal.h" #include "fd.h" #include "mood.h" +#include "sideband.h" +#include "command.h" /** The osl tables used by afs. \sa blob.c. */ enum afs_table_num { @@ -140,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, @@ -147,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) { @@ -158,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)); @@ -545,8 +550,11 @@ static void com_select_callback(int fd, const struct osl_object *query) { struct para_buffer pb = { .max_size = shm_get_shmmax(), - .private_data = &fd, - .max_size_handler = pass_buffer_as_shm + .private_data = &(struct afs_max_size_handler_data) { + .fd = fd, + .band = SBD_OUTPUT + }, + .max_size_handler = afs_max_size_handler, }; char *arg = query->data; int num_admissible, ret, ret2; @@ -576,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(pb.buf, pb.offset, &fd); + pass_buffer_as_shm(fd, SBD_OUTPUT, pb.buf, pb.offset); free(pb.buf); } @@ -584,35 +592,36 @@ 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 sc_send_result(struct osl_object *result, void *private) +int afs_cb_result_handler(struct osl_object *result, uint8_t band, + void *private) { - struct stream_cipher_context *scc = private; - int ret; + struct command_context *cc = private; if (!result->size) return 1; - ret = sc_send_bin_buffer(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 stream_cipher_context *scc, int argc, char * const * const argv) +int com_select(struct command_context *cc) { struct osl_object query; - if (argc != 2) + if (cc->argc != 2) return -E_AFS_SYNTAX; - query.data = argv[1]; - query.size = strlen(argv[1]) + 1; + query.data = cc->argv[1]; + query.size = strlen(cc->argv[1]) + 1; return send_callback_request(com_select_callback, &query, - &sc_send_result, scc); + &afs_cb_result_handler, cc); } static void init_admissible_files(char *arg) @@ -782,30 +791,30 @@ 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. - * \param fd_ptr A pointer to the file descriptor. - * - * This function is used as the \a max_size handler in a \ref para_buffer - * structure. If used this way, it is called by \ref para_printf() whenever - * the buffer passed to para_printf() is about to exceed its maximal size. * * This function creates a shared memory area large enough to hold * the content given by \a buf and \a size and sends the identifier - * of this area to the file descriptor given by \a fd_ptr. + * of this area to the file descriptor \a fd. + * + * It is called by the AFS max_size handler as well as directly by the AFS + * command callbacks to send command output to the command handlers. * * \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(char *buf, size_t size, void *fd_ptr) +int pass_buffer_as_shm(int fd, uint8_t band, char *buf, size_t size) { - int ret, shmid, fd = *(int *)fd_ptr; + int ret, shmid; void *shm; struct callback_result *cr; 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; @@ -814,6 +823,7 @@ int pass_buffer_as_shm(char *buf, size_t size, void *fd_ptr) goto err; cr = shm; cr->result_size = size; + cr->band = band; memcpy(shm + sizeof(*cr), buf, size); ret = shm_detach(shm); if (ret < 0) @@ -1022,11 +1032,11 @@ out: if (ret < 0) para_printf(&pb, "%s\n", para_strerror(-ret)); if (pb.buf) - pass_buffer_as_shm(pb.buf, pb.offset, &fd); + pass_buffer_as_shm(fd, SBD_OUTPUT, pb.buf, pb.offset); free(pb.buf); } -int com_init(struct stream_cipher_context *scc, int argc, char * const * const argv) +int com_init(struct command_context *cc) { int i, j, ret; uint32_t table_mask = (1 << (NUM_AFS_TABLES + 1)) - 1; @@ -1036,13 +1046,13 @@ int com_init(struct stream_cipher_context *scc, int argc, char * const * const a ret = make_database_dir(); if (ret < 0) return ret; - if (argc != 1) { + if (cc->argc != 1) { table_mask = 0; - for (i = 1; i < argc; i++) { + for (i = 1; i < cc->argc; i++) { for (j = 0; j < NUM_AFS_TABLES; j++) { struct afs_table *t = &afs_tables[j]; - if (strcmp(argv[i], t->name)) + if (strcmp(cc->argv[i], t->name)) continue; table_mask |= (1 << j); break; @@ -1052,10 +1062,10 @@ int com_init(struct stream_cipher_context *scc, int argc, char * const * const a } } ret = send_callback_request(create_tables_callback, &query, - sc_send_result, scc); - if (ret < 0) + afs_cb_result_handler, cc); + if (ret < 0 && !cc->use_sideband) /* ignore return value */ - sc_send_va_buffer(scc, "%s\n", para_strerror(-ret)); + sc_send_va_buffer(&cc->scc, "%s\n", para_strerror(-ret)); return ret; } @@ -1073,13 +1083,13 @@ enum com_check_flags { CHECK_PLAYLISTS = 4 }; -int com_check(struct stream_cipher_context *scc, int argc, char * const * const argv) +int com_check(struct command_context *cc) { unsigned flags = 0; int i, ret; - for (i = 1; i < argc; i++) { - const char *arg = argv[i]; + for (i = 1; i < cc->argc; i++) { + const char *arg = cc->argv[i]; if (arg[0] != '-') break; if (!strcmp(arg, "--")) { @@ -1100,25 +1110,25 @@ int com_check(struct stream_cipher_context *scc, int argc, char * const * const } return -E_AFS_SYNTAX; } - if (i < argc) + if (i < cc->argc) return -E_AFS_SYNTAX; if (!flags) flags = ~0U; if (flags & CHECK_AFT) { ret = send_callback_request(aft_check_callback, NULL, - sc_send_result, scc); + afs_cb_result_handler, cc); if (ret < 0) return ret; } if (flags & CHECK_PLAYLISTS) { ret = send_callback_request(playlist_check_callback, - NULL, sc_send_result, scc); + NULL, afs_cb_result_handler, cc); if (ret < 0) return ret; } if (flags & CHECK_MOODS) { ret = send_callback_request(mood_check_callback, NULL, - sc_send_result, scc); + afs_cb_result_handler, cc); if (ret < 0) return ret; }