X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/blobdiff_plain/a1d2685b08312addc2c6bf772c6f4dd801629a4a..ce72de30ce4d850bdd0985cbcd5d686470745934:/clientserver.c diff --git a/clientserver.c b/clientserver.c index 4c636664..8cbde16b 100644 --- a/clientserver.c +++ b/clientserver.c @@ -192,21 +192,31 @@ static int exchange_protocols(int f_in, int f_out, char *buf, size_t bufsiz, int int start_inband_exchange(int f_in, int f_out, const char *user, int argc, char *argv[]) { - int i; + int i, modlen; char line[BIGPATHBUFLEN]; char *sargs[MAX_ARGS]; int sargc = 0; - char *p, *path = *argv; + char *p, *modname; - if (argc == 0 && !am_sender) - list_only |= 1; + assert(argc > 0); - if (*path == '/') { + if (**argv == '/') { rprintf(FERROR, "ERROR: The remote path must start with a module name\n"); return -1; } + if (!(p = strchr(*argv, '/'))) + modlen = strlen(*argv); + else + modlen = p - *argv; + + if (!(modname = new_array(char, modlen+1+1))) /* room for '/' & '\0' */ + out_of_memory("start_inband_exchange"); + strlcpy(modname, *argv, modlen + 1); + modname[modlen] = '/'; + modname[modlen+1] = '\0'; + if (!user) user = getenv("USER"); if (!user) @@ -215,9 +225,6 @@ int start_inband_exchange(int f_in, int f_out, const char *user, int argc, char if (exchange_protocols(f_in, f_out, line, sizeof line, 1) < 0) return -1; - if (list_only && protocol_version >= 29) - list_only |= 2; - /* set daemon_over_rsh to false since we need to build the * true set of args passed through the rsh/ssh connection; * this is a no-op for direct-socket-connection mode */ @@ -235,7 +242,12 @@ int start_inband_exchange(int f_in, int f_out, const char *user, int argc, char rprintf(FERROR, "internal: args[] overflowed in do_cmd()\n"); exit_cleanup(RERR_SYNTAX); } - sargs[sargc++] = *argv++; + if (list_only && strncmp(*argv, modname, modlen) == 0 + && argv[0][modlen] == '\0') + sargs[sargc++] = modname; /* we send "modname/" */ + else + sargs[sargc++] = *argv; + argv++; argc--; } @@ -244,10 +256,7 @@ int start_inband_exchange(int f_in, int f_out, const char *user, int argc, char if (verbose > 1) print_child_argv("sending daemon args:", sargs); - p = strchr(path, '/'); - if (p) *p = '\0'; - io_printf(f_out, "%s\n", path); - if (p) *p = '/'; + io_printf(f_out, "%.*s\n", modlen, modname); /* Old servers may just drop the connection here, rather than sending a proper EXIT command. Yuck. */ @@ -306,6 +315,8 @@ int start_inband_exchange(int f_in, int f_out, const char *user, int argc, char io_start_multiplex_in(); } + free(modname); + return 0; } @@ -839,18 +850,20 @@ int start_daemon(int f_in, int f_out) return rsync_module(f_in, f_out, i, addr, host); } -static void create_pid_file(pid_t pid) +static void create_pid_file(void) { char *pid_file = lp_pid_file(); char pidbuf[16]; + pid_t pid = getpid(); int fd; if (!pid_file || !*pid_file) return; cleanup_set_pid(pid); - if ((fd = do_open(pid_file, O_WRONLY|O_CREAT|O_TRUNC, 0666 & ~orig_umask)) == -1) { + if ((fd = do_open(pid_file, O_WRONLY|O_CREAT|O_EXCL, 0666 & ~orig_umask)) == -1) { cleanup_set_pid(0); + fprintf(stderr, "failed to create pid file %s: %s\n", pid_file, strerror(errno)); rsyserr(FLOG, errno, "failed to create pid file %s", pid_file); exit_cleanup(RERR_FILEIO); } @@ -866,10 +879,15 @@ static void become_daemon(void) pid_t pid = fork(); if (pid) { - create_pid_file(pid); + if (pid < 0) { + fprintf(stderr, "failed to fork: %s\n", strerror(errno)); + exit_cleanup(RERR_FILEIO); + } _exit(0); } + create_pid_file(); + /* detach from the terminal */ #ifdef HAVE_SETSID setsid(); @@ -890,6 +908,13 @@ static void become_daemon(void) int daemon_main(void) { + if (!config_file) { + if (am_server && am_root <= 0) + config_file = RSYNCD_USERCONF; + else + config_file = RSYNCD_SYSCONF; + } + if (is_a_socket(STDIN_FILENO)) { int i; @@ -910,7 +935,7 @@ int daemon_main(void) } if (no_detach) - create_pid_file(getpid()); + create_pid_file(); else become_daemon();