X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/blobdiff_plain/a10186910dc0771ea907f92b1364cbb4912f37e3..73cb6738b33846130c21f2903b2200fa3f1903ab:/main.c diff --git a/main.c b/main.c index ba470481..ad4fb0af 100644 --- a/main.c +++ b/main.c @@ -4,7 +4,7 @@ * Copyright (C) 1996-2001 Andrew Tridgell * Copyright (C) 1996 Paul Mackerras * Copyright (C) 2001, 2002 Martin Pool - * Copyright (C) 2003-2007 Wayne Davison + * Copyright (C) 2003-2008 Wayne Davison * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -45,6 +45,7 @@ extern int got_xfer_error; extern int module_id; extern int copy_links; extern int copy_dirlinks; +extern int copy_unsafe_links; extern int keep_dirlinks; extern int preserve_hard_links; extern int protocol_version; @@ -77,11 +78,9 @@ extern char *batch_name; extern char *password_file; extern char curr_dir[MAXPATHLEN]; extern struct file_list *first_flist; -extern struct filter_list_struct server_filter_list; -#ifdef ICONV_OPTION -extern iconv_t ic_send; -#endif +extern struct filter_list_struct daemon_filter_list; +uid_t our_uid; int local_server = 0; int daemon_over_rsh = 0; mode_t orig_umask = 0; @@ -278,7 +277,7 @@ static void output_summary(void) rprintf(FINFO, "total size is %s speedup is %.2f%s\n", human_num(stats.total_size), (double)stats.total_size / (total_written+total_read), - dry_run ? " (DRY RUN)" : ""); + write_batch < 0 ? " (BATCH ONLY)" : dry_run ? " (DRY RUN)" : ""); } fflush(stdout); @@ -332,7 +331,7 @@ static pid_t do_cmd(char *cmd, char *machine, char *user, char **remote_argv, in { int i, argc = 0; char *args[MAX_ARGS]; - pid_t ret; + pid_t pid; int dash_l_set = 0; if (!read_batch && !local_server) { @@ -342,7 +341,7 @@ static pid_t do_cmd(char *cmd, char *machine, char *user, char **remote_argv, in cmd = rsh_env; if (!cmd) cmd = RSYNC_RSH; - cmd = strdup(cmd); + cmd = strdup(cmd); /* MEMORY LEAK */ if (!cmd) goto oom; @@ -451,7 +450,7 @@ static pid_t do_cmd(char *cmd, char *machine, char *user, char **remote_argv, in batch_gen_fd = from_gen_pipe[0]; *f_out_p = from_gen_pipe[1]; *f_in_p = batch_fd; - ret = -1; /* no child pid */ + pid = (pid_t)-1; /* no child pid */ #ifdef ICONV_CONST setup_iconv(); #endif @@ -461,54 +460,20 @@ static pid_t do_cmd(char *cmd, char *machine, char *user, char **remote_argv, in if (whole_file < 0 && !write_batch) whole_file = 1; set_allow_inc_recurse(); - ret = local_child(argc, args, f_in_p, f_out_p, child_main); + pid = local_child(argc, args, f_in_p, f_out_p, child_main); #ifdef ICONV_CONST setup_iconv(); #endif } else { + pid = piped_child(args, f_in_p, f_out_p); #ifdef ICONV_CONST setup_iconv(); #endif - if (protect_args) { - 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); - - 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); + if (protect_args) + send_protected_args(*f_out_p, args); } - return ret; + return pid; oom: out_of_memory("do_cmd"); @@ -542,6 +507,14 @@ static char *get_local_name(struct file_list *flist, char *dest_path) if (!dest_path || list_only) return NULL; + if (daemon_filter_list.head + && (check_filter(&daemon_filter_list, dest_path, 0 != 0) < 0 + || check_filter(&daemon_filter_list, dest_path, 1 != 0) < 0)) { + rprintf(FERROR, "skipping daemon-excluded destination \"%s\"\n", + dest_path); + exit_cleanup(RERR_FILESELECT); + } + /* See what currently exists at the destination. */ if ((statret = do_stat(dest_path, &st)) == 0) { /* If the destination is a dir, enter it and use mode 1. */ @@ -640,7 +613,7 @@ static char *get_local_name(struct file_list *flist, char *dest_path) * dry-run mode and the destination dir does not yet exist, we'll try to * tweak any dest-relative paths to make them work for a dry-run (the * destination dir must be in curr_dir[] when this function is called). - * We also report if any arg that is non-existent or not a directory. */ + * We also warn about any arg that is non-existent or not a directory. */ static void check_alt_basis_dirs(void) { STRUCT_STAT st; @@ -758,7 +731,7 @@ static int do_recv(int f_in, int f_out, char *local_name) /* The receiving side mustn't obey this, or an existing symlink that * points to an identical file won't be replaced by the referent. */ - copy_links = copy_dirlinks = 0; + copy_links = copy_dirlinks = copy_unsafe_links = 0; #ifdef SUPPORT_HARD_LINKS if (preserve_hard_links && !inc_recurse) @@ -929,15 +902,15 @@ static void do_server_recv(int f_in, int f_out, int argc, char *argv[]) if (sanitize_paths) { char **dir_p; for (dir_p = basis_dir; *dir_p; dir_p++) - *dir_p = sanitize_path(NULL, *dir_p, NULL, curr_dir_depth); + *dir_p = sanitize_path(NULL, *dir_p, NULL, curr_dir_depth, SP_DEFAULT); if (partial_dir) - partial_dir = sanitize_path(NULL, partial_dir, NULL, curr_dir_depth); + partial_dir = sanitize_path(NULL, partial_dir, NULL, curr_dir_depth, SP_DEFAULT); } check_alt_basis_dirs(); - if (server_filter_list.head) { + if (daemon_filter_list.head) { char **dir_p; - struct filter_list_struct *elp = &server_filter_list; + struct filter_list_struct *elp = &daemon_filter_list; for (dir_p = basis_dir; *dir_p; dir_p++) { char *dir = *dir_p; @@ -1065,11 +1038,6 @@ int client_run(int f_in, int f_out, pid_t pid, int argc, char *argv[]) io_start_multiplex_out(); } - if (argc == 0) { - list_only |= 1; - xfer_dirs |= 1; - } - send_filter_list(read_batch ? -1 : f_out); if (filesfrom_fd >= 0) { @@ -1180,8 +1148,6 @@ static int start_client(int argc, char *argv[]) static char *dotarg[1] = { "." }; p = dotarg[0]; remote_argv = dotarg; - list_only |= 1; - xfer_dirs |= 1; } remote_argc = 1; @@ -1253,10 +1219,6 @@ static int start_client(int argc, char *argv[]) } remote_argv[i] = arg; } - if (argc == 0) { - list_only |= 1; - xfer_dirs |= 1; - } } if (daemon_over_rsh < 0) @@ -1427,7 +1389,8 @@ int main(int argc,char *argv[]) #endif starttime = time(NULL); - am_root = (MY_UID() == 0); + our_uid = MY_UID(); + am_root = our_uid == 0; memset(&stats, 0, sizeof(stats)); @@ -1444,7 +1407,7 @@ int main(int argc,char *argv[]) setlocale(LC_CTYPE, ""); #endif - if (!parse_arguments(&argc, (const char ***) &argv, 1)) { + if (!parse_arguments(&argc, (const char ***) &argv)) { /* FIXME: We ought to call the same error-handling * code here, rather than relying on getopt. */ option_error(); @@ -1509,7 +1472,7 @@ int main(int argc,char *argv[]) char buf[MAXPATHLEN]; protect_args = 2; read_args(STDIN_FILENO, NULL, buf, sizeof buf, 1, &argv, &argc, NULL); - if (!parse_arguments(&argc, (const char ***) &argv, 1)) { + if (!parse_arguments(&argc, (const char ***) &argv)) { option_error(); exit_cleanup(RERR_SYNTAX); }