int do_compression=0;
int am_root=0;
int orig_umask=0;
+int relative_paths=0;
extern int csum_length;
argstr[x++] = 'C';
if (ignore_times)
argstr[x++] = 'I';
+ if (relative_paths)
+ argstr[x++] = 'R';
if (one_file_system)
argstr[x++] = 'x';
if (sparse_files)
if (path && *path) {
char *dir = strdup(path);
p = strrchr(dir,'/');
- if (p) {
+ if (p && !relative_paths) {
*p = 0;
if (!dir[0])
args[argc++] = "/";
if (stat(name,&st) == 0) {
if (S_ISDIR(st.st_mode)) {
if (chdir(name) != 0) {
- fprintf(FERROR,"chdir %s : %s\n",name,strerror(errno));
+ fprintf(FERROR,"chdir %s : %s (1)\n",name,strerror(errno));
exit_cleanup(1);
}
return NULL;
return NULL;
if (mkdir(name,0777 & ~orig_umask) != 0) {
- fprintf(FERROR,"mkdir %s : %s\n",name,strerror(errno));
+ fprintf(FERROR,"mkdir %s : %s (1)\n",name,strerror(errno));
exit_cleanup(1);
} else {
fprintf(FINFO,"created directory %s\n",name);
}
if (chdir(name) != 0) {
- fprintf(FERROR,"chdir %s : %s\n",name,strerror(errno));
+ fprintf(FERROR,"chdir %s : %s (2)\n",name,strerror(errno));
exit_cleanup(1);
}
if (verbose > 2)
fprintf(FERROR,"server_sender starting pid=%d\n",(int)getpid());
- if (chdir(dir) != 0) {
- fprintf(FERROR,"chdir %s: %s\n",dir,strerror(errno));
+ if (!relative_paths && chdir(dir) != 0) {
+ fprintf(FERROR,"chdir %s: %s (3)\n",dir,strerror(errno));
exit_cleanup(1);
}
argc--;
argc--;
argv++;
if (chdir(dir) != 0) {
- fprintf(FERROR,"chdir %s : %s\n",dir,strerror(errno));
+ fprintf(FERROR,"chdir %s : %s (4)\n",dir,strerror(errno));
exit_cleanup(1);
}
}
fprintf(f,"-c, --checksum always checksum\n");
fprintf(f,"-a, --archive archive mode (same as -rlptDog)\n");
fprintf(f,"-r, --recursive recurse into directories\n");
+ fprintf(f,"-R, --relative use relative path names\n");
fprintf(f,"-b, --backup make backups (default ~ extension)\n");
fprintf(f,"-u, --update update only (don't overwrite newer files)\n");
fprintf(f,"-l, --links preserve soft links\n");
enum {OPT_VERSION,OPT_SUFFIX,OPT_SENDER,OPT_SERVER,OPT_EXCLUDE,
OPT_EXCLUDE_FROM,OPT_DELETE,OPT_RSYNC_PATH};
-static char *short_options = "oblHpguDCtcahvrIxnSe:B:z";
+static char *short_options = "oblHpguDCtcahvrRIxnSe:B:z";
static struct option long_options[] = {
{"version", 0, 0, OPT_VERSION},
{"update", 0, 0, 'u'},
{"verbose", 0, 0, 'v'},
{"recursive", 0, 0, 'r'},
+ {"relative", 0, 0, 'R'},
{"devices", 0, 0, 'D'},
{"perms", 0, 0, 'p'},
{"links", 0, 0, 'l'},
recurse = 1;
break;
+ case 'R':
+ relative_paths = 1;
+ break;
+
case 'e':
shell_cmd = optarg;
break;
extern int delete_mode;
extern int cvs_exclude;
extern int am_root;
+extern int relative_paths;
/*
free a sums struct
}
statret = -1;
}
- if (statret != 0 && mkdir(fname,file->mode) != 0 && errno != EEXIST)
- fprintf(FERROR,"mkdir %s : %s\n",fname,strerror(errno));
+ if (statret != 0 && mkdir(fname,file->mode) != 0 && errno != EEXIST) {
+ if (!(relative_paths && errno==ENOENT &&
+ create_directory_path(fname)==0 &&
+ mkdir(fname,file->mode)==0)) {
+ fprintf(FERROR,"mkdir %s : %s (2)\n",
+ fname,strerror(errno));
+ }
+ }
if (set_perms(fname,file,NULL,0) && verbose)
fprintf(FINFO,"%s/\n",fname);
return;
continue;
}
fd2 = open(fnametmp,O_WRONLY|O_CREAT,file->mode);
+ if (relative_paths && errno == ENOENT &&
+ create_directory_path(fnametmp) == 0) {
+ fd2 = open(fnametmp,O_WRONLY|O_CREAT,file->mode);
+ }
if (fd2 == -1) {
fprintf(FERROR,"open %s : %s\n",fnametmp,strerror(errno));
receive_data(f_in,buf,-1,NULL);
if (pid == 0)
{
+ extern int orig_umask;
if (dup2(to_child_pipe[0], STDIN_FILENO) < 0 ||
close(to_child_pipe[1]) < 0 ||
close(from_child_pipe[0]) < 0 ||
}
if (to_child_pipe[0] != STDIN_FILENO) close(to_child_pipe[0]);
if (from_child_pipe[1] != STDOUT_FILENO) close(from_child_pipe[1]);
+ umask(orig_umask);
execvp(command[0], command);
fprintf(FERROR,"Failed to exec %s : %s\n",
command[0],strerror(errno));
return fcntl( fd, F_SETFL, val);
#undef FLAG_TO_SET
}
+
+/****************************************************************************
+create any necessary directories in fname. Unfortunately we don't know
+what perms to give the directory when this is called so we need to rely
+on the umask
+****************************************************************************/
+int create_directory_path(char *fname)
+{
+ extern int orig_umask;
+ char *p;
+
+ while (*fname == '/') fname++;
+ while (strncmp(fname,"./",2)==0) fname += 2;
+
+ p = fname;
+ while ((p=strchr(p,'/'))) {
+ *p = 0;
+ mkdir(fname,0777 & ~orig_umask);
+ *p = '/';
+ p++;
+ }
+ return 0;
+}