server: Remove command pointer from struct command_context.
authorAndre Noll <maan@tuebingen.mpg.de>
Tue, 13 Jan 2015 23:00:41 +0000 (00:00 +0100)
committerAndre Noll <maan@tuebingen.mpg.de>
Wed, 12 Aug 2015 21:23:47 +0000 (23:23 +0200)
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
command.h

index 2db2d9c..5d6a099 100644 (file)
--- 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) {
index ab76d60..5e1a4ce 100644 (file)
--- 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;
 };