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.
#include "signal.h"
#include "fd.h"
#include "mood.h"
#include "signal.h"
#include "fd.h"
#include "mood.h"
/** The osl tables used by afs. \sa blob.c. */
enum afs_table_num {
/** The osl tables used by afs. \sa blob.c. */
enum afs_table_num {
*/
int sc_send_result(struct osl_object *result, void *private)
{
*/
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;
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;
}
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;
{
struct osl_object query;
- 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,
return send_callback_request(com_select_callback, &query,
}
static void init_admissible_files(char *arg)
}
static void init_admissible_files(char *arg)
-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;
{
int i, j, ret;
uint32_t table_mask = (1 << (NUM_AFS_TABLES + 1)) - 1;
ret = make_database_dir();
if (ret < 0)
return ret;
ret = make_database_dir();
if (ret < 0)
return ret;
- 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];
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;
continue;
table_mask |= (1 << j);
break;
}
}
ret = send_callback_request(create_tables_callback, &query,
}
}
ret = send_callback_request(create_tables_callback, &query,
if (ret < 0)
/* ignore return value */
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));
-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;
{
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, "--")) {
if (arg[0] != '-')
break;
if (!strcmp(arg, "--")) {
}
return -E_AFS_SYNTAX;
}
}
return -E_AFS_SYNTAX;
}
return -E_AFS_SYNTAX;
if (!flags)
flags = ~0U;
if (flags & CHECK_AFT) {
ret = send_callback_request(aft_check_callback, NULL,
return -E_AFS_SYNTAX;
if (!flags)
flags = ~0U;
if (flags & CHECK_AFT) {
ret = send_callback_request(aft_check_callback, NULL,
if (ret < 0)
return ret;
}
if (flags & CHECK_PLAYLISTS) {
ret = send_callback_request(playlist_check_callback,
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,
if (ret < 0)
return ret;
}
if (flags & CHECK_MOODS) {
ret = send_callback_request(mood_check_callback, NULL,
if (ret < 0)
return ret;
}
if (ret < 0)
return ret;
}
---
T: add
N: add@member@
---
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
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
---
T: cat
N: cat@member@
---
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
P: AFS_READ
D: Dump the contents of a blob of type @member@ to stdout.
U: cat@member@ @member@_name
-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]
P: AFS_READ
D: List blobs of type @member@ matching a pattern.
U: ls@member@ [-i] [-l] [-r] [pattern]
-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...
P: AFS_READ | AFS_WRITE
D: Remove blob(s) of type @member@ from the @member@ table.
U: rm@member@ pattern...
-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
P: AFS_READ | AFS_WRITE
D: Rename a blob of type @member@.
U: mv@member@ old_@member@_name new_@member@_name
#include "fd.h"
#include "ipc.h"
#include "portable_io.h"
#include "fd.h"
#include "ipc.h"
#include "portable_io.h"
static struct osl_table *audio_file_table;
static char *status_items;
static struct osl_table *audio_file_table;
static char *status_items;
/*
* TODO: flags -h (sort by hash)
*/
/*
* 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;
{
int i, ret;
unsigned flags = 0;
struct ls_options opts = {.patterns = NULL};
struct osl_object query = {.data = &opts, .size = sizeof(opts)};
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, "--")) {
if (arg[0] != '-')
break;
if (!strcmp(arg, "--")) {
opts.flags = flags;
opts.sorting = sort;
opts.mode = mode;
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,
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);
/** Used by com_add(). */
struct private_add_data {
/** 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;
};
/** The given add flags. */
uint32_t flags;
};
ret = 1;
if (pb && (pad->flags & ADD_FLAG_LAZY)) { /* lazy is really cheap */
if (pad->flags & ADD_FLAG_VERBOSE)
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;
}
"lazy-ignore: %s\n", path);
goto out_free;
}
ret = 1;
if (pb && hs && hs == pb && !(pad->flags & ADD_FLAG_FORCE)) {
if (pad->flags & ADD_FLAG_VERBOSE)
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;
}
"%s exists, not forcing update\n", path);
goto out_unmap;
}
munmap(map.data, map.size);
close(fd);
if (pad->flags & ADD_FLAG_VERBOSE) {
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. */
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:
goto out_free;
out_unmap:
munmap(map.data, map.size);
out_free:
if (ret < 0 && send_ret >= 0)
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) {
"failed to add %s (%s)\n", path, para_strerror(-ret));
free(obj.data);
if (afhi_ptr) {
-int com_add(struct stream_cipher_context *scc, int argc, char * const * const argv)
+int com_add(struct command_context *cc)
- struct private_add_data pad = {.scc = scc, .flags = 0};
+ struct private_add_data pad = {.cc = cc, .flags = 0};
- 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, "--")) {
if (arg[0] != '-')
break;
if (!strcmp(arg, "--")) {
- for (; i < argc; i++) {
+ for (; i < cc->argc; i++) {
- ret = verify_path(argv[i], &path);
+ ret = verify_path(cc->argv[i], &path);
- 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) {
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)
strerror(errno));
free(path);
if (ret < 0)
else
ret = add_one_audio_file(path, &pad);
if (ret < 0) {
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;
}
free(path);
return ret;
}
-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,
{
struct com_touch_options cto = {
.num_played = -1,
- 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, "--")) {
if (arg[0] != '-')
break;
if (!strcmp(arg, "--")) {
}
break; /* non-option starting with dash */
}
}
break; /* non-option starting with dash */
}
- 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);
- sc_send_va_buffer(scc, "%s\n", para_strerror(-ret));
+ sc_send_va_buffer(&cc->scc, "%s\n", para_strerror(-ret));
}
/* TODO options: -r (recursive) */
}
/* 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;
{
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, "--")) {
if (arg[0] != '-')
break;
if (!strcmp(arg, "--")) {
- 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);
- sc_send_va_buffer(scc, "%s\n", para_strerror(-ret));
+ sc_send_va_buffer(&cc->scc, "%s\n", para_strerror(-ret));
-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)};
{
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, "--")) {
if (arg[0] != '-')
break;
if (!strcmp(arg, "--")) {
- 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;
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);
- sc_send_va_buffer(scc, "%s\n", para_strerror(-ret));
+ sc_send_va_buffer(&cc->scc, "%s\n", para_strerror(-ret));
/**
* Get the current afs status items from the afs process and send it.
*
/**
* 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
* \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
*
* \return The return value of the underyling call to \ref send_callback_request().
*/
*
* \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)};
{
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 */
}
/* TODO: optionally fix problems by removing offending rows */
#include "afh.h"
#include "afs.h"
#include "ipc.h"
#include "afh.h"
#include "afs.h"
#include "ipc.h"
static struct osl_table *attribute_table;
static int greatest_att_bitnum;
static struct osl_table *attribute_table;
static int greatest_att_bitnum;
-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;
{
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, "--")) {
if (arg[0] != '-')
break;
if (!strcmp(arg, "--")) {
- 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 (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");
- sc_send_va_buffer(scc, "%s\n", para_strerror(-ret));
+ sc_send_va_buffer(&cc->scc, "%s\n", para_strerror(-ret));
PARA_NOTICE_LOG("%s\n", para_strerror(-ret));
}
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)
- 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 {
}
struct addatt_event_data {
-int com_addatt(struct stream_cipher_context *scc, int argc, char * const * const argv)
+int com_addatt(struct command_context *cc)
- 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);
- sc_send_va_buffer(scc, "%s\n", para_strerror(-ret));
+ sc_send_va_buffer(&cc->scc, "%s\n", para_strerror(-ret));
-int com_mvatt(struct stream_cipher_context *scc, int argc, char * const * const argv)
+int com_mvatt(struct command_context *cc)
- 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);
- sc_send_va_buffer(scc, "%s\n", para_strerror(-ret));
+ sc_send_va_buffer(&cc->scc, "%s\n", para_strerror(-ret));
-int com_rmatt(struct stream_cipher_context *scc, int argc, char * const * const argv)
+int com_rmatt(struct command_context *cc)
- 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);
- sc_send_va_buffer(scc, "%s\n", para_strerror(-ret));
+ sc_send_va_buffer(&cc->scc, "%s\n", para_strerror(-ret));
#include "afs.h"
#include "ipc.h"
#include "portable_io.h"
#include "afs.h"
#include "ipc.h"
#include "portable_io.h"
/**
* Compare two osl objects pointing to unsigned integers of 32 bit size.
/**
* Compare two osl objects pointing to unsigned integers of 32 bit size.
-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;
{
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, "--")) {
if (arg[0] != '-')
break;
if (!strcmp(arg, "--")) {
}
// if (argc > i)
// return -E_BLOB_SYNTAX;
}
// 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,
}
static int cat_blob(struct osl_table *table, struct osl_row *row,
-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)
- 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. */
}
/** Used for removing rows from a blob table. */
-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)
- 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,
}
static void com_addblob_callback(struct osl_table *table, __a_unused int fd,
* \return Negative on errors, the return value of the underlying call to
* send_callback_request() otherwise.
*/
* \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)
callback_function *f, unsigned max_len,
callback_result_handler *result_handler,
void *private_result_data)
struct osl_object query, stdin_obj;
int ret;
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);
- 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;
if (ret < 0)
return ret;
query.size = arg_obj->size + stdin_obj.size;
-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;
{
struct osl_object arg_obj;
- if (!*argv[1]) /* empty name is reserved for the dummy row */
+ if (!*cc->argv[1]) /* empty name is reserved for the dummy row */
- 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 */
}
/* FIXME: Print output to client, not to log file */
PARA_NOTICE_LOG("%s\n", para_strerror(-ret));
}
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)
- 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) \
}
#define DEFINE_BLOB_COMMAND(cmd_name, table_name, cmd_prefix) \
{ \
return com_ ## cmd_name ## blob_callback(table_name ## _table, fd, query); \
} \
{ \
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,
}
static int blob_get_name_by_id(struct osl_table *table, uint32_t id,
extern int mmd_mutex;
extern struct misc_meta_data *mmd;
extern struct sender senders[];
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};
const char *status_item_list[] = {STATUS_ITEM_ARRAY};
-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;
{
int i, ret;
char *msg = NULL;
struct sender_command_data scd;
for (i = 0; senders[i].name; i++) {
char *tmp = make_message("%s%s\n",
msg? msg : "", senders[i].name);
free(msg);
msg = tmp;
}
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);
- 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();
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);
case SENDER_ADD:
case SENDER_DELETE:
assert(senders[scd.sender_num].resolve_target);
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;
}
if (ret < 0)
return ret;
}
-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;
{
int i, ret;
char *ut;
char *sender_info = NULL;
return -E_COMMAND_SYNTAX;
mutex_lock(mmd_mutex);
for (i = 0; senders[i].name; i++) {
return -E_COMMAND_SYNTAX;
mutex_lock(mmd_mutex);
for (i = 0; senders[i].name; i++) {
free(info);
}
ut = get_server_uptime_str(now);
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"
"up: %s\nplayed: %u\n"
"server_pid: %d\n"
"afs_pid: %d\n"
-int com_version(struct stream_cipher_context *scc, int argc, __a_unused char * const * argv)
+int com_version(struct command_context *cc)
return -E_COMMAND_SYNTAX;
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"
);
"built: " BUILD_DATE "\n"
UNAME_RS ", " CC_VERSION "\n"
);
#undef EMPTY_STATUS_ITEMS
/* stat */
#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;
{
int i, ret;
struct misc_meta_data tmp, *nmmd = &tmp;
para_sigaction(SIGUSR1, dummy);
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, "--")) {
if (arg[0] != '-')
break;
if (!strcmp(arg, "--")) {
}
return -E_COMMAND_SYNTAX;
}
}
return -E_COMMAND_SYNTAX;
}
return -E_COMMAND_SYNTAX;
for (;;) {
mmd_dup(nmmd);
s = get_status(nmmd, parser_friendly);
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;
free(s);
if (ret < 0)
goto out;
static char *esi;
if (!esi)
esi = empty_status_items(parser_friendly);
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
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;
ret = 1;
if (num > 0 && !--num)
goto out;
-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;
{
struct server_command *cmd;
char *perms, *handler;
int ret;
/* no argument given, print list of commands */
/* 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 send_list_of_commands(scc, afs_cmds, "afs");
+ return send_list_of_commands(&cc->scc, afs_cmds, "afs");
}
/* argument given for help */
}
/* 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);
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",
"%s - %s\n\n"
"handler: %s\n"
"permissions: %s\n"
"usage: %s\n\n"
"%s\n",
cmd->description,
handler,
perms,
cmd->description,
handler,
perms,
-int com_hup(__a_unused struct stream_cipher_context *scc, int argc, __a_unused char * const * argv)
+int com_hup(struct command_context *cc)
return -E_COMMAND_SYNTAX;
kill(getppid(), SIGHUP);
return 1;
}
/* term */
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)
return -E_COMMAND_SYNTAX;
kill(getppid(), SIGTERM);
return 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)
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;
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;
-int com_stop(__a_unused struct stream_cipher_context *scc, int argc, __a_unused char * const * argv)
+int com_stop(struct command_context *cc)
return -E_COMMAND_SYNTAX;
mutex_lock(mmd_mutex);
mmd->new_vss_status_flags &= ~VSS_PLAYING;
return -E_COMMAND_SYNTAX;
mutex_lock(mmd_mutex);
mmd->new_vss_status_flags &= ~VSS_PLAYING;
-int com_pause(__a_unused struct stream_cipher_context *scc, int argc, __a_unused char * const * argv)
+int com_pause(struct command_context *cc)
return -E_COMMAND_SYNTAX;
mutex_lock(mmd_mutex);
if (!vss_paused() && !vss_stopped()) {
return -E_COMMAND_SYNTAX;
mutex_lock(mmd_mutex);
if (!vss_paused() && !vss_stopped()) {
-int com_next(__a_unused struct stream_cipher_context *scc, int argc, __a_unused char * const * argv)
+int com_next(struct command_context *cc)
return -E_COMMAND_SYNTAX;
mutex_lock(mmd_mutex);
mmd->events++;
return -E_COMMAND_SYNTAX;
mutex_lock(mmd_mutex);
mmd->events++;
-int com_nomore(__a_unused struct stream_cipher_context *scc, int argc, __a_unused char * const * argv)
+int com_nomore(struct command_context *cc)
return -E_COMMAND_SYNTAX;
mutex_lock(mmd_mutex);
if (vss_playing() || vss_paused())
return -E_COMMAND_SYNTAX;
mutex_lock(mmd_mutex);
if (vss_playing() || vss_paused())
-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;
{
long promille;
int ret, backwards = 0;
unsigned i;
char c;
return -E_COMMAND_SYNTAX;
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 */
return -E_COMMAND_SYNTAX;
if (ret > 1 && c == '-')
backwards = 1; /* jmp backwards */
-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;
{
long unsigned int i;
int ret;
return -E_COMMAND_SYNTAX;
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;
return -E_COMMAND_SYNTAX;
mutex_lock(mmd_mutex);
ret = -E_NO_AUDIO_FILE;
*/
__noreturn void handle_connect(int fd, const char *peername)
{
*/
__noreturn void handle_connect(int fd, const char *peername)
{
char buf[4096];
unsigned char rand_buf[CHALLENGE_SIZE + 2 * SESSION_KEY_LEN];
unsigned char challenge_hash[HASH_SIZE];
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;
char *p, *command = NULL;
size_t numbytes;
- struct stream_cipher_context scc = {.fd = fd};
+ struct command_context cc_struct = {.peer = peername}, *cc = &cc_struct;
reset_signals();
/* we need a blocking fd here as recv() might return EAGAIN otherwise. */
ret = mark_fd_blocking(fd);
reset_signals();
/* we need a blocking fd here as recv() might return EAGAIN otherwise. */
ret = mark_fd_blocking(fd);
goto net_err;
p = buf + strlen(AUTH_REQUEST_MSG);
PARA_DEBUG_LOG("received auth request for user %s\n", p);
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));
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;
(unsigned char *)buf);
if (ret < 0)
goto net_err;
numbytes = ret;
PARA_DEBUG_LOG("received %d bytes challenge response\n", ret);
ret = -E_BAD_USER;
numbytes = ret;
PARA_DEBUG_LOG("received %d bytes challenge response\n", ret);
ret = -E_BAD_USER;
goto net_err;
/*
* The correct response is the hash of the first CHALLENGE_SIZE bytes
goto net_err;
/*
* The correct response is the hash of the first CHALLENGE_SIZE bytes
goto net_err;
/* auth successful */
alarm(0);
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 */
/* 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;
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;
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 */
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 */
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;
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:
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);
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);
- 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);
mmd->events++;
mmd->active_connections--;
mutex_unlock(mmd_mutex);
/** \file command.h The structure of server and afs commands. */
/** \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.
*/
/**
* Defines one command of para_server.
*/
/** The name of the command. */
const char *name;
/** Pointer to the function that handles the 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. */
/** The privileges a user must have to execute this command. */
unsigned int perms;
/** One-line description of the command. */