+static int run_command(struct command_context *cc, struct iovec *iov,
+ const char *peername)
+{
+ int ret, i;
+ char *p, *end;
+ struct server_command *cmd;
+
+ if (iov->iov_base == NULL || iov->iov_len == 0)
+ return -E_BAD_CMD;
+ p = iov->iov_base;
+ p[iov->iov_len - 1] = '\0'; /* just to be sure */
+ cmd = get_cmd_ptr(p, NULL);
+ if (!cmd)
+ return -E_BAD_CMD;
+ ret = check_perms(cc->u->perms, cmd);
+ if (ret < 0)
+ return ret;
+ end = iov->iov_base + iov->iov_len;
+ for (i = 0; p < end; i++)
+ p += strlen(p) + 1;
+ cc->argc = i;
+ cc->argv = para_malloc((cc->argc + 1) * sizeof(char *));
+ for (i = 0, p = iov->iov_base; p < end; i++) {
+ cc->argv[i] = para_strdup(p);
+ p += strlen(p) + 1;
+ }
+ cc->argv[cc->argc] = NULL;
+ 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;
+}
+