Err, actually it would probably be a good idea to s/char *home = getenv("HOME");/const char *home = getenv("HOME");/ Greg On Wed, Jul 28, 2010 at 5:31 PM, Greg Brockman <gdb@xxxxxxx> wrote: > This provides a mechanism for the server to expose custom > functionality to clients. My particular use case is that I would like > a way of discovering all repositories available for cloning. A > client that clones via > > git clone user@xxxxxxxxxxx > > can invoke a command by > > ssh user@xxxxxxxxxxx $command > > Signed-off-by: Greg Brockman <gdb@xxxxxxx> > --- > shell.c | 44 ++++++++++++++++++++++++++++++++++++++++++-- > 1 files changed, 42 insertions(+), 2 deletions(-) > > As discussed on-list, it should be fine to trust the value of HOME. > This patch differs from the previous only in the implementation of > cd_to_homedir. > > diff --git a/shell.c b/shell.c > index e4864e0..1e6077d 100644 > --- a/shell.c > +++ b/shell.c > @@ -3,6 +3,8 @@ > #include "exec_cmd.h" > #include "strbuf.h" > > +#define COMMAND_DIR "git-shell-commands" > + > static int do_generic_cmd(const char *me, char *arg) > { > const char *my_argv[4]; > @@ -33,6 +35,29 @@ static int do_cvs_cmd(const char *me, char *arg) > return execv_git_cmd(cvsserver_argv); > } > > +static int is_valid_cmd_name(const char *cmd) > +{ > + /* Test command contains no . or / characters */ > + return cmd[strcspn(cmd, "./")] == '\0'; > +} > + > +static char *make_cmd(const char *prog) > +{ > + char *prefix = xmalloc((strlen(prog) + strlen(COMMAND_DIR) + 2)); > + strcpy(prefix, COMMAND_DIR); > + strcat(prefix, "/"); > + strcat(prefix, prog); > + return prefix; > +} > + > +static void cd_to_homedir(void) > +{ > + char *home = getenv("HOME"); > + if (!home) > + die("could not determine user's home directory; HOME is unset"); > + if (chdir(home) == -1) > + die("could not chdir to user's home directory"); > +} > > static struct commands { > const char *name; > @@ -48,6 +73,7 @@ static struct commands { > int main(int argc, char **argv) > { > char *prog; > + const char **user_argv; > struct commands *cmd; > int devnull_fd; > > @@ -76,7 +102,7 @@ int main(int argc, char **argv) > else if (argc != 3 || strcmp(argv[1], "-c")) > die("What do you think I am? A shell?"); > > - prog = argv[2]; > + prog = xstrdup(argv[2]); > if (!strncmp(prog, "git", 3) && isspace(prog[3])) > /* Accept "git foo" as if the caller said "git-foo". */ > prog[3] = '-'; > @@ -99,5 +125,19 @@ int main(int argc, char **argv) > } > exit(cmd->exec(cmd->name, arg)); > } > - die("unrecognized command '%s'", prog); > + > + cd_to_homedir(); > + if (split_cmdline(prog, &user_argv) != -1) { > + if (is_valid_cmd_name(user_argv[0])) { > + prog = make_cmd(user_argv[0]); > + user_argv[0] = prog; > + execv(user_argv[0], (char *const *) user_argv); > + } > + free(prog); > + free(user_argv); > + die("unrecognized command '%s'", argv[2]); > + } else { > + free(prog); > + die("invalid command format '%s'", argv[2]); > + } > } > -- > 1.7.0.4 > -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html