From 16c6fc10f3344e3eec66e51580821d854d49aa62 Mon Sep 17 00:00:00 2001 From: Andre Noll Date: Wed, 14 Jan 2015 00:00:41 +0100 Subject: [PATCH] server: Remove command pointer from struct command_context. Command handlers should not know about this implementation detail. This commit also changes parse_sb_command() to not only parse the command line but to actually run the command in case the caller has sufficient permissions. The function is renamed to run_command() to reflect this change. We use the opportunity to clean up the allocation and freeing of the command buffer and the argument vector. Both are now freed in the same function they were allocated, which is considered good programming practice. --- command.c | 42 ++++++++++++++++++++---------------------- command.h | 2 -- 2 files changed, 20 insertions(+), 24 deletions(-) diff --git a/command.c b/command.c index 2db2d9cc..5d6a0990 100644 --- a/command.c +++ b/command.c @@ -850,22 +850,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; @@ -876,9 +877,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; } @@ -999,17 +1006,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: @@ -1021,8 +1021,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) { diff --git a/command.h b/command.h index ab76d602..5e1a4ce3 100644 --- a/command.h +++ b/command.h @@ -10,8 +10,6 @@ struct command_context { int argc; /** Argument vector. */ char **argv; - /** The command being executed. */ - const struct server_command *cmd; /** File descriptor and crypto keys. */ struct stream_cipher_context scc; }; -- 2.39.5