From: Andre Noll Date: Tue, 13 Jan 2015 23:00:41 +0000 (+0100) Subject: server: Remove command pointer from struct command_context. X-Git-Tag: v0.5.5~19 X-Git-Url: http://git.tuebingen.mpg.de/?p=paraslash.git;a=commitdiff_plain;h=16c6fc10f3344e3eec66e51580821d854d49aa62 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. --- 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; };