X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/blobdiff_plain/f7e5068d94b5de8f568cb835654dc83a31695ddf..1b42f628f495ff0cdaa8a7c219d8ce33192281fe:/main.c diff --git a/main.c b/main.c index efcd0603..9f2e2a9f 100644 --- a/main.c +++ b/main.c @@ -21,6 +21,7 @@ */ #include "rsync.h" +#include "ifuncs.h" #include "io.h" #if defined CONFIG_LOCALE && defined HAVE_LOCALE_H #include @@ -71,11 +72,13 @@ extern char *shell_cmd; extern char *batch_name; extern char *password_file; extern char curr_dir[MAXPATHLEN]; -extern struct file_list *cur_flist; +extern struct file_list *first_flist; extern struct filter_list_struct server_filter_list; +#ifdef ICONV_OPTION +extern iconv_t ic_send; +#endif int local_server = 0; -int new_root_dir = 0; int daemon_over_rsh = 0; mode_t orig_umask = 0; int batch_gen_fd = -1; @@ -452,21 +455,40 @@ static pid_t do_cmd(char *cmd, char *machine, char *user, char **remote_argv, in ret = local_child(argc, args, f_in_p, f_out_p, child_main); } else { if (protect_args) { - char *save_opts1, *save_opts2; - for (i = 0; strcmp(args[i], "--server") != 0; i++) {} - save_opts1 = args[i+1]; - save_opts2 = args[i+2]; - args[i+1] = "-s"; - args[i+2] = NULL; + int fd; +#ifdef ICONV_OPTION + int convert = ic_send != (iconv_t)-1; + xbuf outbuf, inbuf; + + if (convert) + alloc_xbuf(&outbuf, 1024); +#endif + ret = piped_child(args, f_in_p, f_out_p); - args[i] = args[i-1]; /* move command name over --server */ - args[i+1] = save_opts1; - args[i+2] = save_opts2; - while (args[i]) { - write_sbuf(*f_out_p, args[i++]); - write_byte(*f_out_p, 0); - } - write_byte(*f_out_p, 0); + + for (i = 0; args[i]; i++) {} /* find first NULL */ + args[i] = "rsync"; /* set a new arg0 */ + if (verbose > 1) + print_child_argv("protected args:", args + i + 1); + fd = *f_out_p; + do { +#ifdef ICONV_OPTION + if (convert) { + INIT_XBUF_STRLEN(inbuf, args[i]); + iconvbufs(ic_send, &inbuf, &outbuf, + ICB_EXPAND_OUT | ICB_INCLUDE_BAD | ICB_INCLUDE_INCOMPLETE); + outbuf.buf[outbuf.len] = '\0'; + write_buf(fd, outbuf.buf, outbuf.len + 1); + outbuf.len = 0; + } else +#endif + write_buf(fd, args[i], strlen(args[i]) + 1); + } while (args[++i]); + write_byte(fd, 0); +#ifdef ICONV_OPTION + if (convert) + free(outbuf.buf); +#endif } else ret = piped_child(args, f_in_p, f_out_p); } @@ -560,7 +582,8 @@ static char *get_local_name(struct file_list *flist, char *dest_path) exit_cleanup(RERR_FILEIO); } - new_root_dir = 1; + if (strcmp(flist->files[0]->basename, ".") == 0) + flist->files[0]->flags |= FLAG_DIR_CREATED; if (verbose) rprintf(FINFO, "created directory %s\n", dest_path); @@ -721,7 +744,7 @@ static int do_recv(int f_in, int f_out, char *local_name) #ifdef SUPPORT_HARD_LINKS if (preserve_hard_links && !inc_recurse) - match_hard_links(cur_flist); + match_hard_links(first_flist); #endif if (fd_pair(error_pipe) < 0) { @@ -796,6 +819,14 @@ static int do_recv(int f_in, int f_out, char *local_name) set_msg_fd_in(error_pipe[0]); io_start_buffering_in(error_pipe[0]); +#ifdef SUPPORT_HARD_LINKS + if (preserve_hard_links && inc_recurse) { + struct file_list *flist; + for (flist = first_flist; flist; flist = flist->next) + match_hard_links(flist); + } +#endif + generate_files(f_out, local_name); handle_stats(-1); @@ -925,9 +956,6 @@ void start_server(int f_in, int f_out, int argc, char *argv[]) io_set_sock_fds(f_in, f_out); setup_protocol(f_out, f_in); -#ifdef ICONV_CONST - setup_iconv(); -#endif if (protocol_version >= 23) io_start_multiplex_out(); @@ -962,9 +990,6 @@ int client_run(int f_in, int f_out, pid_t pid, int argc, char *argv[]) io_set_sock_fds(f_in, f_out); setup_protocol(f_out,f_in); -#ifdef ICONV_CONST - setup_iconv(); -#endif /* We set our stderr file handle to blocking because ssh might have * set it to non-blocking. This can be particularly troublesome if @@ -1434,7 +1459,7 @@ int main(int argc,char *argv[]) if (am_server && protect_args) { char buf[MAXPATHLEN]; - protect_args = 0; + protect_args = 2; read_args(STDIN_FILENO, NULL, buf, sizeof buf, 1, &argv, &argc, NULL); if (!parse_arguments(&argc, (const char ***) &argv, 1)) { option_error();