X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/blobdiff_plain/ee8e2b15478e93d1ba340bb3f8dfb5e854766d53..de3438407c4f976c55172093795b87e49cb4a6e2:/main.c diff --git a/main.c b/main.c index 9d8723b9..3acdfd31 100644 --- a/main.c +++ b/main.c @@ -40,8 +40,8 @@ extern int kluge_around_eof; extern int do_stats; extern int log_got_error; extern int module_id; -extern int orig_umask; extern int copy_links; +extern int copy_dirlinks; extern int keep_dirlinks; extern int preserve_hard_links; extern int protocol_version; @@ -62,6 +62,7 @@ extern char *shell_cmd; extern char *batch_name; int local_server = 0; +mode_t orig_umask = 0; struct file_list *the_file_list; /* There's probably never more than at most 2 outstanding child processes, @@ -437,8 +438,8 @@ static pid_t do_cmd(char *cmd, char *machine, char *user, char *path, /* The receiving side operates in one of two modes: * - * 1. it enters a directory and receives one or more files, placing them - * according to their names in the file-list. + * 1. it receives any number of files into a destination directory, + * placing them according to their names in the file-list. * * 2. it receives a single file and saves it using the name in the * destination path instead of its file-list name. This requires a @@ -479,6 +480,17 @@ static char *get_local_name(struct file_list *flist, char *dest_path) " copying more than 1 file\n"); exit_cleanup(RERR_FILESELECT); } + /* Caution: flist->count could be 0! */ + if (flist->count == 1 && S_ISDIR(flist->files[0]->mode)) { + rprintf(FERROR, + "ERROR: cannot overwrite non-directory" + " with a directory\n"); + exit_cleanup(RERR_FILESELECT); + } + } else if (errno != ENOENT) { + rsyserr(FERROR, errno, "cannot stat destination %s", + full_fname(dest_path)); + exit_cleanup(RERR_FILESELECT); } cp = strrchr(dest_path, '/'); @@ -491,13 +503,11 @@ static char *get_local_name(struct file_list *flist, char *dest_path) if (cp && !cp[1]) *cp = '\0'; - umask(orig_umask); - if (do_mkdir(dest_path, 0777) != 0) { + if (mkdir_defmode(dest_path) != 0) { rsyserr(FERROR, errno, "mkdir %s failed", full_fname(dest_path)); exit_cleanup(RERR_FILEIO); } - umask(0); if (verbose) rprintf(FINFO, "created directory %s\n", dest_path); @@ -627,7 +637,7 @@ static int do_recv(int f_in,int f_out,struct file_list *flist,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 = 0; + copy_links = copy_dirlinks = 0; if (preserve_hard_links) init_hard_links(); @@ -1208,7 +1218,7 @@ int main(int argc,char *argv[]) /* we set a 0 umask so that correct file permissions can be * carried across */ - orig_umask = (int)umask(0); + orig_umask = umask(0); #if defined CONFIG_LOCALE && defined HAVE_SETLOCALE setlocale(LC_CTYPE, "");