From 69b3a249fb8f0f4a01e26f7a414dbe79f480a78c Mon Sep 17 00:00:00 2001 From: Andre Noll Date: Sat, 24 Dec 2011 01:22:58 +0100 Subject: [PATCH] command: Introduce struct command_context. This exposes a couple of variables which were previously local to handle_connect() to the command handlers, allowing them to make use of the full command context. All newly exposed variables are stored in an instance of the new structure, and the command handlers now take a pointer to such a structure. The patch is large but also straight forward. --- afs.c | 41 ++++++++------- afs.cmd | 10 ++-- aft.c | 97 +++++++++++++++++----------------- attribute.c | 55 ++++++++++---------- blob.c | 61 +++++++++++----------- command.c | 147 +++++++++++++++++++++++++--------------------------- command.h | 18 ++++++- 7 files changed, 222 insertions(+), 207 deletions(-) diff --git a/afs.c b/afs.c index 73f2c65a..5939cbe6 100644 --- a/afs.c +++ b/afs.c @@ -26,6 +26,7 @@ #include "signal.h" #include "fd.h" #include "mood.h" +#include "command.h" /** The osl tables used by afs. \sa blob.c. */ enum afs_table_num { @@ -592,27 +593,27 @@ out: */ int sc_send_result(struct osl_object *result, void *private) { - struct stream_cipher_context *scc = private; + struct command_context *cc = private; int ret; if (!result->size) return 1; - ret = sc_send_bin_buffer(scc, result->data, result->size); + ret = sc_send_bin_buffer(&cc->scc, result->data, result->size); if (ret < 0 || ret == result->size) return ret; return -E_SHORT_WRITE; } -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); + &sc_send_result, cc); } static void init_admissible_files(char *arg) @@ -1026,7 +1027,7 @@ out: 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 +1037,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 +1053,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); + sc_send_result, cc); if (ret < 0) /* 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 +1074,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 +1101,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); + sc_send_result, cc); if (ret < 0) return ret; } if (flags & CHECK_PLAYLISTS) { ret = send_callback_request(playlist_check_callback, - NULL, sc_send_result, scc); + NULL, sc_send_result, cc); if (ret < 0) return ret; } if (flags & CHECK_MOODS) { ret = send_callback_request(mood_check_callback, NULL, - sc_send_result, scc); + sc_send_result, cc); if (ret < 0) return ret; } diff --git a/afs.cmd b/afs.cmd index 22a0786b..c7808040 100644 --- a/afs.cmd +++ b/afs.cmd @@ -260,7 +260,7 @@ H: loads the mood named 'foo'. --- T: add N: add@member@ -O: int com_add@member@(struct stream_cipher_context *scc, int argc, char * const * const argv); +O: int com_add@member@(struct command_context *cc); P: AFS_READ | AFS_WRITE D: Read data from stdin and add it as a blob to the @member@ table. U: add@member@ @member@_name @@ -273,7 +273,7 @@ H: given name already exists, its contents are replaced by the new data. --- T: cat N: cat@member@ -O: int com_cat@member@(struct stream_cipher_context *scc, int argc, char * const * const argv); +O: int com_cat@member@(struct command_context *cc); P: AFS_READ D: Dump the contents of a blob of type @member@ to stdout. U: cat@member@ @member@_name @@ -283,7 +283,7 @@ H: they were previously added. --- T: ls N: ls@member@ -O: int com_ls@member@(struct stream_cipher_context *scc, int argc, char * const * const argv); +O: int com_ls@member@(struct command_context *cc); P: AFS_READ D: List blobs of type @member@ matching a pattern. U: ls@member@ [-i] [-l] [-r] [pattern] @@ -303,7 +303,7 @@ H: -r Reverse sort order. --- T: rm N: rm@member@ -O: int com_rm@member@(struct stream_cipher_context *scc, int argc, char * const * const argv); +O: int com_rm@member@(struct command_context *cc); P: AFS_READ | AFS_WRITE D: Remove blob(s) of type @member@ from the @member@ table. U: rm@member@ pattern... @@ -312,7 +312,7 @@ H: any given pattern. --- T: mv N: mv@member@ -O: int com_mv@member@(struct stream_cipher_context *scc, int argc, char * const * const argv); +O: int com_mv@member@(struct command_context *cc); P: AFS_READ | AFS_WRITE D: Rename a blob of type @member@. U: mv@member@ old_@member@_name new_@member@_name diff --git a/aft.c b/aft.c index 9d87c748..f89235a4 100644 --- a/aft.c +++ b/aft.c @@ -21,6 +21,7 @@ #include "fd.h" #include "ipc.h" #include "portable_io.h" +#include "command.h" static struct osl_table *audio_file_table; static char *status_items; @@ -1402,7 +1403,7 @@ out: /* * TODO: flags -h (sort by hash) */ -int com_ls(struct stream_cipher_context *scc, int argc, char * const * const argv) +int com_ls(struct command_context *cc) { int i, ret; unsigned flags = 0; @@ -1411,8 +1412,8 @@ int com_ls(struct stream_cipher_context *scc, int argc, char * const * const arg struct ls_options opts = {.patterns = NULL}; struct osl_object query = {.data = &opts, .size = sizeof(opts)}; - 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, "--")) { @@ -1512,9 +1513,9 @@ int com_ls(struct stream_cipher_context *scc, int argc, char * const * const arg opts.flags = flags; opts.sorting = sort; opts.mode = mode; - opts.num_patterns = argc - i; + opts.num_patterns = cc->argc - i; ret = send_option_arg_callback_request(&query, opts.num_patterns, - argv + i, com_ls_callback, sc_send_result, scc); + cc->argv + i, com_ls_callback, sc_send_result, cc); return ret; } @@ -1801,8 +1802,8 @@ out: /** Used by com_add(). */ struct private_add_data { - /** The socket file descriptor, including stream cipher keys. */ - struct stream_cipher_context *scc; + /** The pointer passed to the original command handler. */ + struct command_context *cc; /** The given add flags. */ uint32_t flags; }; @@ -1857,7 +1858,7 @@ 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->scc, + send_ret = sc_send_va_buffer(&pad->cc->scc, "lazy-ignore: %s\n", path); goto out_free; } @@ -1878,7 +1879,7 @@ 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->scc, + send_ret = sc_send_va_buffer(&pad->cc->scc, "%s exists, not forcing update\n", path); goto out_unmap; } @@ -1896,13 +1897,13 @@ 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->scc, "adding %s\n", path); + send_ret = sc_send_va_buffer(&pad->cc->scc, "adding %s\n", path); if (send_ret < 0) goto out_free; } save_add_callback_buffer(hash, path, afhi_ptr, pad->flags, format_num, &obj); /* Ask afs to consider this entry for adding. */ - ret = send_callback_request(com_add_callback, &obj, sc_send_result, pad->scc); + ret = send_callback_request(com_add_callback, &obj, sc_send_result, pad->cc); goto out_free; out_unmap: @@ -1910,7 +1911,7 @@ out_unmap: munmap(map.data, map.size); out_free: if (ret < 0 && send_ret >= 0) - send_ret = sc_send_va_buffer(pad->scc, + send_ret = sc_send_va_buffer(&pad->cc->scc, "failed to add %s (%s)\n", path, para_strerror(-ret)); free(obj.data); if (afhi_ptr) { @@ -1926,14 +1927,14 @@ out_free: return send_ret; } -int com_add(struct stream_cipher_context *scc, int argc, char * const * const argv) +int com_add(struct command_context *cc) { int i, ret; - struct private_add_data pad = {.scc = scc, .flags = 0}; + struct private_add_data pad = {.cc = cc, .flags = 0}; struct stat statbuf; - 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, "--")) { @@ -1957,21 +1958,22 @@ int com_add(struct stream_cipher_context *scc, int argc, char * const * const ar continue; } } - if (argc <= i) + if (cc->argc <= i) return -E_AFT_SYNTAX; - for (; i < argc; i++) { + for (; i < cc->argc; i++) { char *path; - ret = verify_path(argv[i], &path); + ret = verify_path(cc->argv[i], &path); if (ret < 0) { - ret = sc_send_va_buffer(scc, "%s: %s\n", argv[i], - para_strerror(-ret)); + ret = sc_send_va_buffer(&cc->scc, "%s: %s\n", + cc->argv[i], para_strerror(-ret)); if (ret < 0) return ret; continue; } ret = stat(path, &statbuf); if (ret < 0) { - ret = sc_send_va_buffer(scc, "failed to stat %s (%s)\n", path, + ret = sc_send_va_buffer(&cc->scc, + "failed to stat %s (%s)\n", path, strerror(errno)); free(path); if (ret < 0) @@ -1984,7 +1986,8 @@ int com_add(struct stream_cipher_context *scc, int argc, char * const * const ar else ret = add_one_audio_file(path, &pad); if (ret < 0) { - sc_send_va_buffer(scc, "%s: %s\n", path, para_strerror(-ret)); + sc_send_va_buffer(&cc->scc, "%s: %s\n", path, + para_strerror(-ret)); free(path); return ret; } @@ -2112,7 +2115,7 @@ static void com_touch_callback(int fd, const struct osl_object *query) free(tad.pb.buf); } -int com_touch(struct stream_cipher_context *scc, int argc, char * const * const argv) +int com_touch(struct command_context *cc) { struct com_touch_options cto = { .num_played = -1, @@ -2125,8 +2128,8 @@ int com_touch(struct stream_cipher_context *scc, int argc, char * const * const 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, "--")) { @@ -2177,12 +2180,12 @@ int com_touch(struct stream_cipher_context *scc, int argc, char * const * const } break; /* non-option starting with dash */ } - if (i >= argc) + if (i >= cc->argc) return -E_AFT_SYNTAX; - ret = send_option_arg_callback_request(&query, argc - i, - argv + i, com_touch_callback, sc_send_result, scc); + ret = send_option_arg_callback_request(&query, cc->argc - i, + cc->argv + i, com_touch_callback, sc_send_result, cc); if (ret < 0) - sc_send_va_buffer(scc, "%s\n", para_strerror(-ret)); + sc_send_va_buffer(&cc->scc, "%s\n", para_strerror(-ret)); return ret; } @@ -2260,14 +2263,14 @@ static void com_rm_callback(int fd, const struct osl_object *query) } /* TODO options: -r (recursive) */ -int com_rm(struct stream_cipher_context *scc, int argc, char * const * const argv) +int com_rm(struct command_context *cc) { uint32_t flags = 0; struct osl_object query = {.data = &flags, .size = sizeof(flags)}; 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, "--")) { @@ -2288,12 +2291,12 @@ int com_rm(struct stream_cipher_context *scc, int argc, char * const * const ar } break; } - if (i >= argc) + if (i >= cc->argc) return -E_AFT_SYNTAX; - ret = send_option_arg_callback_request(&query, argc - i, argv + i, - com_rm_callback, sc_send_result, scc); + ret = send_option_arg_callback_request(&query, cc->argc - i, + cc->argv + i, com_rm_callback, sc_send_result, cc); if (ret < 0) - sc_send_va_buffer(scc, "%s\n", para_strerror(-ret)); + sc_send_va_buffer(&cc->scc, "%s\n", para_strerror(-ret)); return ret; } @@ -2405,14 +2408,14 @@ out: free(cad.pb.buf); } -int com_cpsi(struct stream_cipher_context *scc, int argc, char * const * const argv) +int com_cpsi(struct command_context *cc) { unsigned flags = 0; int i, ret; struct osl_object options = {.data = &flags, .size = sizeof(flags)}; - 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, "--")) { @@ -2445,14 +2448,14 @@ int com_cpsi(struct stream_cipher_context *scc, int argc, char * const * const } break; } - if (i + 1 >= argc) /* need at least source file and pattern */ + if (i + 1 >= cc->argc) /* need at least source file and pattern */ return -E_AFT_SYNTAX; if (!(flags & ~CPSI_FLAG_VERBOSE)) /* no copy flags given */ flags = ~(unsigned)CPSI_FLAG_VERBOSE | flags; - ret = send_option_arg_callback_request(&options, argc - i, argv + i, - com_cpsi_callback, sc_send_result, scc); + ret = send_option_arg_callback_request(&options, cc->argc - i, + cc->argv + i, com_cpsi_callback, sc_send_result, cc); if (ret < 0) - sc_send_va_buffer(scc, "%s\n", para_strerror(-ret)); + sc_send_va_buffer(&cc->scc, "%s\n", para_strerror(-ret)); return ret; } @@ -2470,7 +2473,7 @@ static void afs_stat_callback(int fd, const struct osl_object *query) /** * Get the current afs status items from the afs process and send it. * - * \param scc The stream cipher context for data encryption. + * \param cc The command context, used e.g. for data encryption. * \param parser_friendly Whether parser-friendly output format should be used. * * As the contents of the afs status items change in time and the command @@ -2481,12 +2484,12 @@ static void afs_stat_callback(int fd, const struct osl_object *query) * * \return The return value of the underyling call to \ref send_callback_request(). */ -int send_afs_status(struct stream_cipher_context *scc, int parser_friendly) +int send_afs_status(struct command_context *cc, int parser_friendly) { struct osl_object query = {.data = &parser_friendly, .size = sizeof(parser_friendly)}; - return send_callback_request(afs_stat_callback, &query, sc_send_result, scc); + return send_callback_request(afs_stat_callback, &query, sc_send_result, cc); } /* TODO: optionally fix problems by removing offending rows */ diff --git a/attribute.c b/attribute.c index b56a9574..19700944 100644 --- a/attribute.c +++ b/attribute.c @@ -16,6 +16,7 @@ #include "afh.h" #include "afs.h" #include "ipc.h" +#include "command.h" static struct osl_table *attribute_table; static int greatest_att_bitnum; @@ -175,14 +176,14 @@ static void com_lsatt_callback(int fd, const struct osl_object *query) free(laad.pb.buf); } -int com_lsatt(struct stream_cipher_context *scc, int argc, char * const * const argv) +int com_lsatt(struct command_context *cc) { unsigned flags = 0; struct osl_object options = {.data = &flags, .size = sizeof(flags)}; int ret, i; - 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, "--")) { @@ -202,13 +203,13 @@ int com_lsatt(struct stream_cipher_context *scc, int argc, char * const * const continue; } } - ret = send_option_arg_callback_request(&options, argc - i, argv + i, - com_lsatt_callback, sc_send_result, scc); + ret = send_option_arg_callback_request(&options, cc->argc - i, cc->argv + i, + com_lsatt_callback, sc_send_result, cc); if (!ret) { - if (argc > 1) - ret = sc_send_va_buffer(scc, "no matches\n"); + if (cc->argc > 1) + ret = sc_send_va_buffer(&cc->scc, "no matches\n"); } else if (ret < 0) - sc_send_va_buffer(scc, "%s\n", para_strerror(-ret)); + sc_send_va_buffer(&cc->scc, "%s\n", para_strerror(-ret)); return ret; } @@ -276,12 +277,12 @@ out: PARA_NOTICE_LOG("%s\n", para_strerror(-ret)); } -int com_setatt(__a_unused struct stream_cipher_context *scc, int argc, char * const * const argv) +int com_setatt(struct command_context *cc) { - if (argc < 3) + if (cc->argc < 3) return -E_ATTR_SYNTAX; - return send_standard_callback_request(argc - 1, argv + 1, com_setatt_callback, - NULL, NULL); + return send_standard_callback_request(cc->argc - 1, cc->argv + 1, + com_setatt_callback, NULL, NULL); } struct addatt_event_data { @@ -357,16 +358,16 @@ out: free(pb.buf); } -int com_addatt(struct stream_cipher_context *scc, int argc, char * const * const argv) +int com_addatt(struct command_context *cc) { int ret; - if (argc < 2) + if (cc->argc < 2) return -E_ATTR_SYNTAX; - ret = send_standard_callback_request(argc - 1, argv + 1, com_addatt_callback, - sc_send_result, scc); + ret = send_standard_callback_request(cc->argc - 1, cc->argv + 1, + com_addatt_callback, sc_send_result, cc); if (ret < 0) - sc_send_va_buffer(scc, "%s\n", para_strerror(-ret)); + sc_send_va_buffer(&cc->scc, "%s\n", para_strerror(-ret)); return ret; } @@ -400,16 +401,16 @@ out: free(pb.buf); } -int com_mvatt(struct stream_cipher_context *scc, int argc, char * const * const argv) +int com_mvatt(struct command_context *cc) { int ret; - if (argc != 3) + if (cc->argc != 3) return -E_ATTR_SYNTAX; - ret = send_standard_callback_request(argc - 1, argv + 1, com_mvatt_callback, - sc_send_result, scc); + ret = send_standard_callback_request(cc->argc - 1, cc->argv + 1, + com_mvatt_callback, sc_send_result, cc); if (ret < 0) - sc_send_va_buffer(scc, "%s\n", para_strerror(-ret)); + sc_send_va_buffer(&cc->scc, "%s\n", para_strerror(-ret)); return ret; } @@ -472,16 +473,16 @@ static void com_rmatt_callback(int fd, const struct osl_object *query) free(raad.pb.buf); } -int com_rmatt(struct stream_cipher_context *scc, int argc, char * const * const argv) +int com_rmatt(struct command_context *cc) { int ret; - if (argc < 2) + if (cc->argc < 2) return -E_ATTR_SYNTAX; - ret = send_standard_callback_request(argc - 1, argv + 1, com_rmatt_callback, - sc_send_result, scc); + ret = send_standard_callback_request(cc->argc - 1, cc->argv + 1, + com_rmatt_callback, sc_send_result, cc); if (ret < 0) - sc_send_va_buffer(scc, "%s\n", para_strerror(-ret)); + sc_send_va_buffer(&cc->scc, "%s\n", para_strerror(-ret)); return ret; } diff --git a/blob.c b/blob.c index ee4e405e..409e3487 100644 --- a/blob.c +++ b/blob.c @@ -18,6 +18,7 @@ #include "afs.h" #include "ipc.h" #include "portable_io.h" +#include "command.h" /** * Compare two osl objects pointing to unsigned integers of 32 bit size. @@ -163,14 +164,14 @@ static void com_lsblob_callback(struct osl_table *table, free(lbad.pb.buf); } -static int com_lsblob(callback_function *f, struct stream_cipher_context *scc, int argc, char * const * const argv) +static int com_lsblob(callback_function *f, struct command_context *cc) { uint32_t flags = 0; struct osl_object options = {.data = &flags, .size = sizeof(flags)}; int i; - 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, "--")) { @@ -193,8 +194,8 @@ static int com_lsblob(callback_function *f, struct stream_cipher_context *scc, i } // if (argc > i) // return -E_BLOB_SYNTAX; - return send_option_arg_callback_request(&options, argc - i, - argv + i, f, sc_send_result, scc); + return send_option_arg_callback_request(&options, cc->argc - i, + cc->argv + i, f, sc_send_result, cc); } static int cat_blob(struct osl_table *table, struct osl_row *row, @@ -231,13 +232,12 @@ static void com_catblob_callback(struct osl_table *table, int fd, } } -static int com_catblob(callback_function *f, struct stream_cipher_context *scc, int argc, - char * const * const argv) +static int com_catblob(callback_function *f, struct command_context *cc) { - if (argc < 2) + if (cc->argc < 2) return -E_BLOB_SYNTAX; - return send_standard_callback_request(argc - 1, argv + 1, f, - sc_send_result, scc); + return send_standard_callback_request(cc->argc - 1, cc->argv + 1, f, + sc_send_result, cc); } /** Used for removing rows from a blob table. */ @@ -296,13 +296,12 @@ out: free(rmbd.pb.buf); } -static int com_rmblob(callback_function *f, struct stream_cipher_context *scc, int argc, - char * const * const argv) +static int com_rmblob(callback_function *f, struct command_context *cc) { - if (argc < 2) + if (cc->argc < 2) return -E_MOOD_SYNTAX; - return send_option_arg_callback_request(NULL, argc - 1, argv + 1, f, - sc_send_result, scc); + return send_option_arg_callback_request(NULL, cc->argc - 1, cc->argv + 1, f, + sc_send_result, cc); } static void com_addblob_callback(struct osl_table *table, __a_unused int fd, @@ -425,7 +424,7 @@ static int fd2buf(struct stream_cipher_context *scc, unsigned max_size, struct o * \return Negative on errors, the return value of the underlying call to * send_callback_request() otherwise. */ -static int stdin_command(struct stream_cipher_context *scc, struct osl_object *arg_obj, +static int stdin_command(struct command_context *cc, struct osl_object *arg_obj, callback_function *f, unsigned max_len, callback_result_handler *result_handler, void *private_result_data) @@ -433,10 +432,10 @@ static int stdin_command(struct stream_cipher_context *scc, struct osl_object *a struct osl_object query, stdin_obj; int ret; - ret = sc_send_buffer(scc, AWAITING_DATA_MSG); + ret = sc_send_buffer(&cc->scc, AWAITING_DATA_MSG); if (ret < 0) return ret; - ret = fd2buf(scc, max_len, &stdin_obj); + ret = fd2buf(&cc->scc, max_len, &stdin_obj); if (ret < 0) return ret; query.size = arg_obj->size + stdin_obj.size; @@ -449,18 +448,17 @@ static int stdin_command(struct stream_cipher_context *scc, struct osl_object *a return ret; } -static int com_addblob(callback_function *f, struct stream_cipher_context *scc, int argc, - char * const * const argv) +static int com_addblob(callback_function *f, struct command_context *cc) { struct osl_object arg_obj; - if (argc != 2) + if (cc->argc != 2) return -E_BLOB_SYNTAX; - if (!*argv[1]) /* empty name is reserved for the dummy row */ + if (!*cc->argv[1]) /* empty name is reserved for the dummy row */ return -E_BLOB_SYNTAX; - arg_obj.size = strlen(argv[1]) + 1; - arg_obj.data = (char *)argv[1]; - return stdin_command(scc, &arg_obj, f, 10 * 1024 * 1024, NULL, NULL); + arg_obj.size = strlen(cc->argv[1]) + 1; + arg_obj.data = (char *)cc->argv[1]; + return stdin_command(cc, &arg_obj, f, 10 * 1024 * 1024, NULL, NULL); } /* FIXME: Print output to client, not to log file */ @@ -486,13 +484,12 @@ out: PARA_NOTICE_LOG("%s\n", para_strerror(-ret)); } -static int com_mvblob(callback_function *f, __a_unused struct stream_cipher_context *scc, - int argc, char * const * const argv) +static int com_mvblob(callback_function *f, struct command_context *cc) { - if (argc != 3) + if (cc->argc != 3) return -E_MOOD_SYNTAX; - return send_option_arg_callback_request(NULL, argc - 1, argv + 1, f, - NULL, NULL); + return send_option_arg_callback_request(NULL, cc->argc - 1, + cc->argv + 1, f, NULL, NULL); } #define DEFINE_BLOB_COMMAND(cmd_name, table_name, cmd_prefix) \ @@ -500,9 +497,9 @@ static int com_mvblob(callback_function *f, __a_unused struct stream_cipher_cont { \ return com_ ## cmd_name ## blob_callback(table_name ## _table, fd, query); \ } \ - int com_ ## cmd_name ## cmd_prefix(struct stream_cipher_context *scc, int argc, char * const * const argv) \ + int com_ ## cmd_name ## cmd_prefix(struct command_context *cc) \ { \ - return com_ ## cmd_name ## blob(com_ ## cmd_name ## cmd_prefix ## _callback, scc, argc, argv); \ + return com_ ## cmd_name ## blob(com_ ## cmd_name ## cmd_prefix ## _callback, cc); \ } static int blob_get_name_by_id(struct osl_table *table, uint32_t id, diff --git a/command.c b/command.c index 4aa262ce..4a464ebf 100644 --- a/command.c +++ b/command.c @@ -41,7 +41,7 @@ extern int mmd_mutex; extern struct misc_meta_data *mmd; extern struct sender senders[]; -int send_afs_status(struct stream_cipher_context *scc, int parser_friendly); +int send_afs_status(struct command_context *cc, int parser_friendly); const char *status_item_list[] = {STATUS_ITEM_ARRAY}; @@ -193,29 +193,29 @@ static int check_sender_args(int argc, char * const * argv, struct sender_comman return 1; } -int com_sender(struct stream_cipher_context *scc, int argc, char * const * argv) +int com_sender(struct command_context *cc) { int i, ret; char *msg = NULL; struct sender_command_data scd; - if (argc < 2) { + if (cc->argc < 2) { for (i = 0; senders[i].name; i++) { char *tmp = make_message("%s%s\n", msg? msg : "", senders[i].name); free(msg); msg = tmp; } - ret = sc_send_buffer(scc, msg); + ret = sc_send_buffer(&cc->scc, msg); free(msg); return ret; } - ret = check_sender_args(argc, argv, &scd); + ret = check_sender_args(cc->argc, cc->argv, &scd); if (ret < 0) { if (scd.sender_num < 0) return ret; msg = senders[scd.sender_num].help(); - ret = sc_send_buffer(scc, msg); + ret = sc_send_buffer(&cc->scc, msg); free(msg); return ret; } @@ -224,7 +224,7 @@ int com_sender(struct stream_cipher_context *scc, int argc, char * const * argv) case SENDER_ADD: case SENDER_DELETE: assert(senders[scd.sender_num].resolve_target); - ret = senders[scd.sender_num].resolve_target(argv[3], &scd); + ret = senders[scd.sender_num].resolve_target(cc->argv[3], &scd); if (ret < 0) return ret; } @@ -244,13 +244,13 @@ int com_sender(struct stream_cipher_context *scc, int argc, char * const * argv) } /* server info */ -int com_si(struct stream_cipher_context *scc, int argc, __a_unused char * const * argv) +int com_si(struct command_context *cc) { int i, ret; char *ut; char *sender_info = NULL; - if (argc != 1) + if (cc->argc != 1) return -E_COMMAND_SYNTAX; mutex_lock(mmd_mutex); for (i = 0; senders[i].name; i++) { @@ -259,7 +259,7 @@ int com_si(struct stream_cipher_context *scc, int argc, __a_unused char * const free(info); } ut = get_server_uptime_str(now); - ret = sc_send_va_buffer(scc, "version: " GIT_VERSION "\n" + ret = sc_send_va_buffer(&cc->scc, "version: " GIT_VERSION "\n" "up: %s\nplayed: %u\n" "server_pid: %d\n" "afs_pid: %d\n" @@ -284,11 +284,11 @@ int com_si(struct stream_cipher_context *scc, int argc, __a_unused char * const } /* version */ -int com_version(struct stream_cipher_context *scc, int argc, __a_unused char * const * argv) +int com_version(struct command_context *cc) { - if (argc != 1) + if (cc->argc != 1) return -E_COMMAND_SYNTAX; - return sc_send_buffer(scc, VERSION_TEXT("server") + return sc_send_buffer(&cc->scc, VERSION_TEXT("server") "built: " BUILD_DATE "\n" UNAME_RS ", " CC_VERSION "\n" ); @@ -350,7 +350,7 @@ static char *empty_status_items(int parser_friendly) #undef EMPTY_STATUS_ITEMS /* stat */ -int com_stat(struct stream_cipher_context *scc, int argc, char * const * argv) +int com_stat(struct command_context *cc) { int i, ret; struct misc_meta_data tmp, *nmmd = &tmp; @@ -360,8 +360,8 @@ int com_stat(struct stream_cipher_context *scc, int argc, char * const * argv) para_sigaction(SIGUSR1, dummy); - 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, "--")) { @@ -380,12 +380,12 @@ int com_stat(struct stream_cipher_context *scc, int argc, char * const * argv) } return -E_COMMAND_SYNTAX; } - if (i != argc) + if (i != cc->argc) return -E_COMMAND_SYNTAX; for (;;) { mmd_dup(nmmd); s = get_status(nmmd, parser_friendly); - ret = sc_send_buffer(scc, s); + ret = sc_send_buffer(&cc->scc, s); free(s); if (ret < 0) goto out; @@ -393,11 +393,11 @@ int com_stat(struct stream_cipher_context *scc, int argc, char * const * argv) static char *esi; if (!esi) esi = empty_status_items(parser_friendly); - ret = sc_send_buffer(scc, esi); + ret = sc_send_buffer(&cc->scc, esi); if (ret < 0) goto out; } else - send_afs_status(scc, parser_friendly); + send_afs_status(cc, parser_friendly); ret = 1; if (num > 0 && !--num) goto out; @@ -449,30 +449,30 @@ static struct server_command *get_cmd_ptr(const char *name, char **handler) } /* help */ -int com_help(struct stream_cipher_context *scc, int argc, char * const * argv) +int com_help(struct command_context *cc) { struct server_command *cmd; char *perms, *handler; int ret; - if (argc < 2) { + if (cc->argc < 2) { /* no argument given, print list of commands */ - if ((ret = send_list_of_commands(scc, server_cmds, "server")) < 0) + if ((ret = send_list_of_commands(&cc->scc, server_cmds, "server")) < 0) return ret; - return send_list_of_commands(scc, afs_cmds, "afs"); + return send_list_of_commands(&cc->scc, afs_cmds, "afs"); } /* argument given for help */ - cmd = get_cmd_ptr(argv[1], &handler); + 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(scc, + ret = sc_send_va_buffer(&cc->scc, "%s - %s\n\n" "handler: %s\n" "permissions: %s\n" "usage: %s\n\n" "%s\n", - argv[1], + cc->argv[1], cmd->description, handler, perms, @@ -485,39 +485,38 @@ int com_help(struct stream_cipher_context *scc, int argc, char * const * argv) } /* hup */ -int com_hup(__a_unused struct stream_cipher_context *scc, int argc, __a_unused char * const * argv) +int com_hup(struct command_context *cc) { - if (argc != 1) + if (cc->argc != 1) return -E_COMMAND_SYNTAX; kill(getppid(), SIGHUP); return 1; } /* term */ -int com_term(__a_unused struct stream_cipher_context *scc, int argc, __a_unused char * const * argv) +int com_term(struct command_context *cc) { - if (argc != 1) + if (cc->argc != 1) return -E_COMMAND_SYNTAX; kill(getppid(), SIGTERM); return 1; } -int com_play(__a_unused struct stream_cipher_context *scc, int argc, __a_unused char * const * argv) +int com_play(struct command_context *cc) { - if (argc != 1) + if (cc->argc != 1) return -E_COMMAND_SYNTAX; mutex_lock(mmd_mutex); mmd->new_vss_status_flags |= VSS_PLAYING; mmd->new_vss_status_flags &= ~VSS_NOMORE; mutex_unlock(mmd_mutex); return 1; - } /* stop */ -int com_stop(__a_unused struct stream_cipher_context *scc, int argc, __a_unused char * const * argv) +int com_stop(struct command_context *cc) { - if (argc != 1) + if (cc->argc != 1) return -E_COMMAND_SYNTAX; mutex_lock(mmd_mutex); mmd->new_vss_status_flags &= ~VSS_PLAYING; @@ -528,9 +527,9 @@ int com_stop(__a_unused struct stream_cipher_context *scc, int argc, __a_unused } /* pause */ -int com_pause(__a_unused struct stream_cipher_context *scc, int argc, __a_unused char * const * argv) +int com_pause(struct command_context *cc) { - if (argc != 1) + if (cc->argc != 1) return -E_COMMAND_SYNTAX; mutex_lock(mmd_mutex); if (!vss_paused() && !vss_stopped()) { @@ -543,9 +542,9 @@ int com_pause(__a_unused struct stream_cipher_context *scc, int argc, __a_unused } /* next */ -int com_next(__a_unused struct stream_cipher_context *scc, int argc, __a_unused char * const * argv) +int com_next(struct command_context *cc) { - if (argc != 1) + if (cc->argc != 1) return -E_COMMAND_SYNTAX; mutex_lock(mmd_mutex); mmd->events++; @@ -555,9 +554,9 @@ int com_next(__a_unused struct stream_cipher_context *scc, int argc, __a_unused } /* nomore */ -int com_nomore(__a_unused struct stream_cipher_context *scc, int argc, __a_unused char * const * argv) +int com_nomore(struct command_context *cc) { - if (argc != 1) + if (cc->argc != 1) return -E_COMMAND_SYNTAX; mutex_lock(mmd_mutex); if (vss_playing() || vss_paused()) @@ -567,16 +566,16 @@ int com_nomore(__a_unused struct stream_cipher_context *scc, int argc, __a_unuse } /* ff */ -int com_ff(__a_unused struct stream_cipher_context *scc, int argc, char * const * argv) +int com_ff(struct command_context *cc) { long promille; int ret, backwards = 0; unsigned i; char c; - if (argc != 2) + if (cc->argc != 2) return -E_COMMAND_SYNTAX; - if (!(ret = sscanf(argv[1], "%u%c", &i, &c))) + if (!(ret = sscanf(cc->argv[1], "%u%c", &i, &c))) return -E_COMMAND_SYNTAX; if (ret > 1 && c == '-') backwards = 1; /* jmp backwards */ @@ -606,14 +605,14 @@ out: } /* jmp */ -int com_jmp(__a_unused struct stream_cipher_context *scc, int argc, char * const * argv) +int com_jmp(struct command_context *cc) { long unsigned int i; int ret; - if (argc != 2) + if (cc->argc != 2) return -E_COMMAND_SYNTAX; - if (sscanf(argv[1], "%lu", &i) <= 0) + if (sscanf(cc->argv[1], "%lu", &i) <= 0) return -E_COMMAND_SYNTAX; mutex_lock(mmd_mutex); ret = -E_NO_AUDIO_FILE; @@ -733,17 +732,15 @@ static void reset_signals(void) */ __noreturn void handle_connect(int fd, const char *peername) { - int ret, argc; + int ret; char buf[4096]; unsigned char rand_buf[CHALLENGE_SIZE + 2 * SESSION_KEY_LEN]; unsigned char challenge_hash[HASH_SIZE]; - struct user *u; - struct server_command *cmd = NULL; - char **argv = NULL; char *p, *command = NULL; size_t numbytes; - struct stream_cipher_context scc = {.fd = fd}; + struct command_context cc_struct = {.peer = peername}, *cc = &cc_struct; + cc->scc.fd = fd; reset_signals(); /* we need a blocking fd here as recv() might return EAGAIN otherwise. */ ret = mark_fd_blocking(fd); @@ -767,10 +764,10 @@ __noreturn void handle_connect(int fd, const char *peername) goto net_err; p = buf + strlen(AUTH_REQUEST_MSG); PARA_DEBUG_LOG("received auth request for user %s\n", p); - u = lookup_user(p); - if (u) { + cc->u = lookup_user(p); + if (cc->u) { get_random_bytes_or_die(rand_buf, sizeof(rand_buf)); - ret = pub_encrypt(u->pubkey, rand_buf, sizeof(rand_buf), + ret = pub_encrypt(cc->u->pubkey, rand_buf, sizeof(rand_buf), (unsigned char *)buf); if (ret < 0) goto net_err; @@ -796,7 +793,7 @@ __noreturn void handle_connect(int fd, const char *peername) numbytes = ret; PARA_DEBUG_LOG("received %d bytes challenge response\n", ret); ret = -E_BAD_USER; - if (!u) + if (!cc->u) goto net_err; /* * The correct response is the hash of the first CHALLENGE_SIZE bytes @@ -810,50 +807,50 @@ __noreturn void handle_connect(int fd, const char *peername) goto net_err; /* auth successful */ alarm(0); - PARA_INFO_LOG("good auth for %s\n", u->name); + PARA_INFO_LOG("good auth for %s\n", cc->u->name); /* init stream cipher keys with the second part of the random buffer */ - scc.recv = sc_new(rand_buf + CHALLENGE_SIZE, SESSION_KEY_LEN); - scc.send = sc_new(rand_buf + CHALLENGE_SIZE + SESSION_KEY_LEN, SESSION_KEY_LEN); - ret = sc_send_buffer(&scc, PROCEED_MSG); + cc->scc.recv = sc_new(rand_buf + CHALLENGE_SIZE, SESSION_KEY_LEN); + cc->scc.send = sc_new(rand_buf + CHALLENGE_SIZE + SESSION_KEY_LEN, SESSION_KEY_LEN); + ret = sc_send_buffer(&cc->scc, PROCEED_MSG); if (ret < 0) goto net_err; - ret = read_command(&scc, &command); + ret = read_command(&cc->scc, &command); if (ret == -E_COMMAND_SYNTAX) goto err_out; if (ret < 0) goto net_err; ret = -E_BAD_CMD; - cmd = parse_cmd(command); - if (!cmd) + cc->cmd = parse_cmd(command); + if (!cc->cmd) goto err_out; /* valid command, check permissions */ - ret = check_perms(u->perms, cmd); + ret = check_perms(cc->u->perms, cc->cmd); if (ret < 0) goto err_out; /* valid command and sufficient perms */ - ret = create_argv(command, "\n", &argv); + ret = create_argv(command, "\n", &cc->argv); if (ret < 0) goto err_out; - argc = ret; - PARA_NOTICE_LOG("calling com_%s() for %s@%s\n", cmd->name, u->name, - peername); - ret = cmd->handler(&scc, argc, argv); - free_argv(argv); + cc->argc = ret; + PARA_NOTICE_LOG("calling com_%s() for %s@%s\n", cc->cmd->name, + cc->u->name, peername); + ret = cc->cmd->handler(cc); + free_argv(cc->argv); mutex_lock(mmd_mutex); mmd->num_commands++; mutex_unlock(mmd_mutex); if (ret >= 0) goto out; err_out: - sc_send_va_buffer(&scc, "%s\n", para_strerror(-ret)); + sc_send_va_buffer(&cc->scc, "%s\n", para_strerror(-ret)); net_err: PARA_NOTICE_LOG("%s\n", para_strerror(-ret)); out: free(command); - sc_free(scc.recv); - sc_free(scc.send); + sc_free(cc->scc.recv); + sc_free(cc->scc.send); mutex_lock(mmd_mutex); - if (cmd && (cmd->perms & AFS_WRITE) && ret >= 0) + if (cc->cmd && (cc->cmd->perms & AFS_WRITE) && ret >= 0) mmd->events++; mmd->active_connections--; mutex_unlock(mmd_mutex); diff --git a/command.h b/command.h index fd879829..05510cc0 100644 --- a/command.h +++ b/command.h @@ -1,5 +1,21 @@ /** \file command.h The structure of server and afs commands. */ +/** Per connection data available to command handlers. */ +struct command_context { + /** Network address of the peer. */ + const char *peer; + /** The paraslash user that executes this command. */ + struct user *u; + /** Argument count. */ + int argc; + /** Argument vector. */ + char **argv; + /** The command being executed. */ + struct server_command *cmd; + /** File descriptor and crypto keys. */ + struct stream_cipher_context scc; +}; + /** * Defines one command of para_server. */ @@ -7,7 +23,7 @@ struct server_command { /** The name of the command. */ const char *name; /** Pointer to the function that handles the command. */ - int (*handler)(struct stream_cipher_context *, int, char * const * const); + int (*handler)(struct command_context *); /** The privileges a user must have to execute this command. */ unsigned int perms; /** One-line description of the command. */ -- 2.39.5