X-Git-Url: http://git.tuebingen.mpg.de/?p=paraslash.git;a=blobdiff_plain;f=command.c;h=22948dbb3bc06034d384ad5447c780619840fa80;hp=175b496ca799820bc5d891676f71970d31ba7cc9;hb=26dc18b2c1faa0d284b579d6ed3ccf1d479e65d3;hpb=bb3daee7cc11561159f168fe4f5427b53e54917f diff --git a/command.c b/command.c index 175b496c..22948dbb 100644 --- a/command.c +++ b/command.c @@ -40,6 +40,26 @@ #include "signal.h" #include "version.h" +typedef int server_command_handler_t(struct command_context *); +static server_command_handler_t SERVER_COMMAND_HANDLERS; +server_command_handler_t AFS_COMMAND_HANDLERS; + +/* Defines one command of para_server. */ +struct server_command { + /* The name of the command. */ + const char *name; + /* Pointer to the function that handles the command. */ + server_command_handler_t *handler; + /* The privileges a user must have to execute this command. */ + unsigned int perms; + /* One-line description of the command. */ + const char *description; + /* Summary of the command line options. */ + const char *usage; + /* The long help text. */ + const char *help; +}; + static struct server_command afs_cmds[] = {DEFINE_AFS_CMD_ARRAY}; static struct server_command server_cmds[] = {DEFINE_SERVER_CMD_ARRAY}; @@ -405,9 +425,10 @@ static int com_version(struct command_context *cc) char *msg; size_t len; - if (cc->argc != 1) - return -E_COMMAND_SYNTAX; - len = xasprintf(&msg, "%s", version_text("server")); + if (cc->argc > 1 && strcmp(cc->argv[1], "-v") == 0) + len = xasprintf(&msg, "%s", version_text("server")); + else + len = xasprintf(&msg, "%s\n", version_single_line("server")); return send_sb(&cc->scc, msg, len, SBD_OUTPUT, false); } @@ -834,22 +855,23 @@ out: #define HANDSHAKE_BUFSIZE 4096 -static int parse_sb_command(struct command_context *cc, struct iovec *iov) +static int run_command(struct command_context *cc, struct iovec *iov, + const char *peername) { int ret, i; char *p, *end; + struct server_command *cmd; - ret = -E_BAD_CMD; if (iov->iov_base == NULL || iov->iov_len == 0) - goto out; + return -E_BAD_CMD; p = iov->iov_base; p[iov->iov_len - 1] = '\0'; /* just to be sure */ - cc->cmd = get_cmd_ptr(p, NULL); - if (!cc->cmd) - goto out; - ret = check_perms(cc->u->perms, cc->cmd); + cmd = get_cmd_ptr(p, NULL); + if (!cmd) + return -E_BAD_CMD; + ret = check_perms(cc->u->perms, cmd); if (ret < 0) - goto out; + return ret; end = iov->iov_base + iov->iov_len; for (i = 0; p < end; i++) p += strlen(p) + 1; @@ -860,9 +882,15 @@ static int parse_sb_command(struct command_context *cc, struct iovec *iov) p += strlen(p) + 1; } cc->argv[cc->argc] = NULL; - ret = cc->argc; -out: - free(iov->iov_base); + PARA_NOTICE_LOG("calling com_%s() for %s@%s\n", cmd->name, + cc->u->name, peername); + ret = cmd->handler(cc); + free_argv(cc->argv); + mutex_lock(mmd_mutex); + mmd->num_commands++; + if (ret >= 0 && (cmd->perms & AFS_WRITE)) + mmd->events++; + mutex_unlock(mmd_mutex); return ret; } @@ -983,17 +1011,10 @@ __noreturn void handle_connect(int fd, const char *peername) ret = recv_sb(&cc->scc, SBD_COMMAND, MAX_COMMAND_LEN, &iov); if (ret < 0) goto net_err; - ret = parse_sb_command(cc, &iov); + ret = run_command(cc, &iov, peername); + free(iov.iov_base); if (ret < 0) goto err_out; - 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: @@ -1005,8 +1026,6 @@ out: free(buf); free(command); mutex_lock(mmd_mutex); - if (cc->cmd && (cc->cmd->perms & AFS_WRITE) && ret >= 0) - mmd->events++; mmd->active_connections--; mutex_unlock(mmd_mutex); if (ret >= 0) {