Only in rsync-1.6.4: .cvsignore Only in rsync-1.6.4: .ignore diff -u rsync-1.6.3/Makefile.in rsync-1.6.4/Makefile.in --- rsync-1.6.3/Makefile.in Fri Apr 11 16:18:34 1997 +++ rsync-1.6.4/Makefile.in Tue Dec 16 04:57:28 1997 @@ -4,11 +4,10 @@ INSTALL_BIN=@prefix@/bin INSTALL_MAN=@prefix@/man -CCOPTFLAGS = -O - LIBS=@LIBS@ -CC=@CC@ $(CCOPTFLAGS) - +CC=@CC@ +CFLAGS=@CFLAGS@ + INSTALLCMD=@INSTALL@ SRC=@srcdir@ diff -u rsync-1.6.3/README rsync-1.6.4/README --- rsync-1.6.3/README Fri Apr 11 16:18:34 1997 +++ rsync-1.6.4/README Mon Dec 15 23:05:07 1997 @@ -3,7 +3,7 @@ rsync is a replacement for rcp that has many more features. -rsyns uses the "rsync algorithm" which provides a very fast method for +rsync uses the "rsync algorithm" which provides a very fast method for bringing remote files into sync. It does this by sending just the differences in the files across the link, without requiring that both sets of files are present at one of the ends of the link beforehand. @@ -26,6 +26,7 @@ -c, --checksum always checksum -a, --archive archive mode (same as -rlptDog) -r, --recursive recurse into directories +-R, --relative use relative path names -b, --backup make backups (default ~ extension) -u, --update update only (don't overwrite newer files) -l, --links preserve soft links @@ -81,6 +82,36 @@ To send mail to everyone on the list send it to rsync@samba.anu.edu.au +BUG REPORTS +----------- + +If you have web access then please look at +http://samba.anu.edu.au/cgi-bin/rsync + +This will give you access to the bug tracking system used by the +developers of rsync and will allow you to look at other bug reports or +submit a new bug report. + +If you don't have web access then mail bug reports to +rsync-bugs@samba.anu.edu.au or (if you think it will be of interest to +lots of people) send it to rsync@samba.anu.edu.au + + +CVS TREE +-------- + +If you want to get the very latest version of rsync direct from the +source code repository then you can use anonymous cvs. You will need a +recent version of cvs then use the following commands: + + cvs -d :pserver:cvs@samba.anu.edu.au:/cvsroot login + Password: cvs + + cvs -d :pserver:cvs@samba.anu.edu.au:/cvsroot co rsync + +Look at the cvs documentation for more details. + + COPYRIGHT --------- @@ -96,6 +127,7 @@ The main ftp site for rsync is ftp://samba.anu.edu.au/pub/rsync -A european mirror of this directory is available at -ftp://sunsite.auc.dk/pub/unix/rsync +Mirrors are available at: +ftp://sunsite.auc.dk/pub/unix/rsync +ftp://ftp.sunet.se/pub/unix/admin/rsync diff -u rsync-1.6.3/checksum.c rsync-1.6.4/checksum.c --- rsync-1.6.3/checksum.c Fri Apr 11 16:18:34 1997 +++ rsync-1.6.4/checksum.c Mon Dec 15 23:37:40 1997 @@ -30,10 +30,11 @@ a simple 32 bit checksum that can be upadted from either end (inspired by Mark Adler's Adler-32 checksum) */ -uint32 get_checksum1(char *buf,int len) +uint32 get_checksum1(char *buf1,int len) { int i; uint32 s1, s2; + signed char *buf = (signed char *)buf1; s1 = s2 = 0; for (i = 0; i < (len-4); i+=4) { diff -u rsync-1.6.3/config.h.in rsync-1.6.4/config.h.in --- rsync-1.6.3/config.h.in Fri Apr 11 16:18:34 1997 +++ rsync-1.6.4/config.h.in Tue Dec 16 03:27:01 1997 @@ -38,6 +38,8 @@ #undef HAVE_UTIME_H #undef HAVE_STRING_H #undef HAVE_STDLIB_H +#undef HAVE_SYS_SOCKET_H +#undef HAVE_SYS_MODE_H /* specific functions */ #undef HAVE_FCHMOD diff -u rsync-1.6.3/configure rsync-1.6.4/configure --- rsync-1.6.3/configure Fri Apr 11 16:18:34 1997 +++ rsync-1.6.4/configure Tue Dec 16 03:27:02 1997 @@ -1071,7 +1071,7 @@ fi done -for ac_hdr in sys/filio.h string.h stdlib.h +for ac_hdr in sys/filio.h string.h stdlib.h sys/socket.h sys/mode.h do ac_safe=`echo "$ac_hdr" | tr './\055' '___'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 diff -u rsync-1.6.3/configure.in rsync-1.6.4/configure.in --- rsync-1.6.3/configure.in Fri Apr 11 16:18:34 1997 +++ rsync-1.6.4/configure.in Tue Dec 16 03:27:04 1997 @@ -15,7 +15,7 @@ AC_HEADER_SYS_WAIT AC_CHECK_HEADERS(sys/fcntl.h sys/select.h fcntl.h sys/time.h sys/unistd.h unistd.h utime.h grp.h) AC_CHECK_HEADERS(compat.h sys/param.h ctype.h sys/wait.h sys/ioctl.h) -AC_CHECK_HEADERS(sys/filio.h string.h stdlib.h) +AC_CHECK_HEADERS(sys/filio.h string.h stdlib.h sys/socket.h sys/mode.h) AC_CHECK_SIZEOF(int) AC_CHECK_SIZEOF(long) Only in rsync-1.6.4: cvs.log diff -u rsync-1.6.3/exclude.c rsync-1.6.4/exclude.c --- rsync-1.6.3/exclude.c Fri Apr 11 16:18:34 1997 +++ rsync-1.6.4/exclude.c Mon Dec 15 21:35:52 1997 @@ -188,7 +188,7 @@ for (i=0; cvs_ignore_list[i]; i++) add_exclude(cvs_ignore_list[i]); - if ((p=getenv("HOME"))) { + if ((p=getenv("HOME")) && strlen(p) < (MAXPATHLEN-12)) { sprintf(fname,"%s/.cvsignore",p); add_exclude_file(fname,0); } diff -u rsync-1.6.3/flist.c rsync-1.6.4/flist.c --- rsync-1.6.3/flist.c Fri Apr 11 16:18:34 1997 +++ rsync-1.6.4/flist.c Mon Dec 15 21:35:52 1997 @@ -41,6 +41,7 @@ extern int preserve_uid; extern int preserve_gid; extern int preserve_times; +extern int relative_paths; static char **local_exclude_list = NULL; @@ -158,8 +159,8 @@ last_gid = file->gid; last_time = file->modtime; - strcpy(lastname,file->name); - lastname[255] = 0; + strncpy(lastname,file->name,MAXPATHLEN-1); + lastname[MAXPATHLEN-1] = 0; } @@ -228,8 +229,8 @@ last_gid = file->gid; last_time = file->modtime; - strcpy(lastname,file->name); - lastname[255] = 0; + strncpy(lastname,file->name,MAXPATHLEN-1); + lastname[MAXPATHLEN-1] = 0; } @@ -315,15 +316,18 @@ if (!file) return; if (flist->count >= flist->malloced) { - flist->malloced += 100; - flist->files = (struct file_struct *)realloc(flist->files, - sizeof(flist->files[0])* - flist->malloced); - if (!flist->files) - out_of_memory("send_file_name"); + if (flist->malloced < 100) + flist->malloced += 100; + else + flist->malloced *= 1.8; + flist->files = (struct file_struct *)realloc(flist->files, + sizeof(flist->files[0])* + flist->malloced); + if (!flist->files) + out_of_memory("send_file_name"); } - if (strcmp(file->name,".") && strcmp(file->name,"/")) { + if (strcmp(file->name,"/")) { flist->files[flist->count++] = *file; send_file_entry(file,f); } @@ -353,7 +357,8 @@ return; } - strcpy(fname,dir); + strncpy(fname,dir,MAXPATHLEN-1); + fname[MAXPATHLEN-1]=0; l = strlen(fname); if (fname[l-1] != '/') strcat(fname,"/"); @@ -368,7 +373,7 @@ if (strcmp(di->d_name,".")==0 || strcmp(di->d_name,"..")==0) continue; - strcpy(p,di->d_name); + strncpy(p,di->d_name,MAXPATHLEN-l); send_file_name(f,flist,fname); } @@ -403,7 +408,8 @@ char fname2[MAXPATHLEN]; char *fname = fname2; - strcpy(fname,argv[i]); + strncpy(fname,argv[i],MAXPATHLEN-1); + fname[MAXPATHLEN-1] = 0; l = strlen(fname); if (l != 1 && fname[l-1] == '/') { @@ -421,15 +427,19 @@ } dir = NULL; - p = strrchr(fname,'/'); - if (p) { - *p = 0; - if (p == fname) - dir = "/"; - else - dir = fname; - fname = p+1; + + if (!relative_paths) { + p = strrchr(fname,'/'); + if (p) { + *p = 0; + if (p == fname) + dir = "/"; + else + dir = fname; + fname = p+1; + } } + if (!*fname) fname = "."; @@ -499,12 +509,15 @@ int i = flist->count; if (i >= flist->malloced) { - flist->malloced += 100; - flist->files =(struct file_struct *)realloc(flist->files, - sizeof(flist->files[0])* - flist->malloced); - if (!flist->files) - goto oom; + if (flist->malloced < 100) + flist->malloced += 100; + else + flist->malloced *= 1.8; + flist->files =(struct file_struct *)realloc(flist->files, + sizeof(flist->files[0])* + flist->malloced); + if (!flist->files) + goto oom; } receive_file_entry(&flist->files[i],flags,f); @@ -547,7 +560,7 @@ int flist_find(struct file_list *flist,struct file_struct *f) { - int low=0,high=flist->count; + int low=0,high=flist->count-1; while (low != high) { int mid = (low+high)/2; diff -u rsync-1.6.3/hlink.c rsync-1.6.4/hlink.c --- rsync-1.6.3/hlink.c Fri Apr 11 16:18:34 1997 +++ rsync-1.6.4/hlink.c Mon Dec 15 23:05:07 1997 @@ -71,7 +71,7 @@ int check_hard_link(struct file_struct *file) { #if SUPPORT_HARD_LINKS - int low=0,high=hlink_count; + int low=0,high=hlink_count-1; int mid=0,ret=0; if (!hlink_list || !S_ISREG(file->mode)) return 0; diff -u rsync-1.6.3/io.c rsync-1.6.4/io.c --- rsync-1.6.3/io.c Fri Apr 11 16:18:34 1997 +++ rsync-1.6.4/io.c Mon Dec 15 21:35:52 1997 @@ -62,6 +62,8 @@ { int n; + if (f == -1) return; + if (read_buffer_len == 0) { read_buffer_p = read_buffer; } @@ -69,6 +71,9 @@ if ((n=num_waiting(f)) <= 0) return; + /* things could deteriorate if we read in really small chunks */ + if (n < 10) n = 1024; + if (read_buffer_p != read_buffer) { memmove(read_buffer,read_buffer_p,read_buffer_len); read_buffer_p = read_buffer; @@ -95,10 +100,13 @@ { int ret; int total=0; + + if (read_buffer_len < N) + read_check(buffer_f_in); while (total < N) { - if (read_buffer_len > 0) { + if (read_buffer_len > 0 && buffer_f_in == fd) { ret = MIN(read_buffer_len,N-total); memcpy(buffer+total,read_buffer_p,ret); read_buffer_p += ret; @@ -228,7 +236,8 @@ static int writefd(int fd,char *buf,int len) { int total = 0; - fd_set fds; + fd_set w_fds, r_fds; + int fd_count, count, got_select=0; struct timeval tv; if (buffer_f_in == -1) @@ -242,14 +251,41 @@ if (ret == -1 && !(errno == EWOULDBLOCK || errno == EAGAIN)) return -1; + if (ret == -1 && got_select) { + fprintf(FERROR,"write exception\n"); + exit_cleanup(1); + } + if (ret == -1) { read_check(buffer_f_in); - FD_ZERO(&fds); - FD_SET(fd,&fds); + fd_count = fd+1; + FD_ZERO(&w_fds); + FD_ZERO(&r_fds); + FD_SET(fd,&w_fds); + if (buffer_f_in != -1) { + FD_SET(buffer_f_in,&r_fds); + if (buffer_f_in > fd) + fd_count = buffer_f_in+1; + } + + got_select = 0; + tv.tv_sec = BLOCKING_TIMEOUT; tv.tv_usec = 0; - select(fd+1,NULL,&fds,NULL,&tv); + count = select(fd_count,buffer_f_in == -1? NULL: &r_fds, + &w_fds,NULL,&tv); + if (count == -1 && errno != EINTR) { + if (verbose > 1) + fprintf(FERROR,"select error: %s\n", strerror(errno)); + exit_cleanup(1); + } + + if (count == 0) continue; + + if (FD_ISSET(fd, &w_fds)) { + got_select = 1; + } } else { total += ret; } Common subdirectories: rsync-1.6.3/lib and rsync-1.6.4/lib diff -u rsync-1.6.3/main.c rsync-1.6.4/main.c --- rsync-1.6.3/main.c Fri Apr 11 16:18:34 1997 +++ rsync-1.6.4/main.c Mon Dec 15 23:05:07 1997 @@ -49,6 +49,7 @@ int do_compression=0; int am_root=0; int orig_umask=0; +int relative_paths=0; extern int csum_length; @@ -134,6 +135,8 @@ 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) @@ -199,7 +202,7 @@ if (path && *path) { char *dir = strdup(path); p = strrchr(dir,'/'); - if (p) { + if (p && !relative_paths) { *p = 0; if (!dir[0]) args[argc++] = "/"; @@ -240,7 +243,7 @@ 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; @@ -259,14 +262,14 @@ 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); } @@ -285,8 +288,8 @@ 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--; @@ -331,8 +334,6 @@ if ((pid=fork()) == 0) { recv_files(f_in,flist,local_name,recv_pipe[1]); - if (preserve_hard_links) - do_hard_links(flist); if (verbose > 2) fprintf(FERROR,"receiver read %d\n",read_total()); exit_cleanup(0); @@ -361,7 +362,7 @@ 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); } } @@ -399,6 +400,7 @@ 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"); @@ -431,7 +433,7 @@ 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}, @@ -453,6 +455,7 @@ {"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'}, @@ -619,6 +622,10 @@ recurse = 1; break; + case 'R': + relative_paths = 1; + break; + case 'e': shell_cmd = optarg; break; @@ -722,6 +729,9 @@ pid = do_cmd(shell_cmd,shell_machine,shell_user,shell_path,&f_in,&f_out); setup_protocol(f_out,f_in); + + setlinebuf(FINFO); + setlinebuf(FERROR); if (verbose > 3) fprintf(FERROR,"parent=%d child=%d sender=%d recurse=%d\n", diff -u rsync-1.6.3/match.c rsync-1.6.4/match.c --- rsync-1.6.3/match.c Fri Apr 11 16:18:35 1997 +++ rsync-1.6.4/match.c Mon Dec 15 18:40:56 1997 @@ -91,7 +91,6 @@ static void matched(int f,struct sum_struct *s,struct map_struct *buf, - off_t len, int offset,int i) { int n = offset - last_match; @@ -130,16 +129,16 @@ int end; char sum2[SUM_LENGTH]; uint32 s1, s2, sum; - char *map; + signed char *map; if (verbose > 2) fprintf(FERROR,"hash search b=%d len=%d\n",s->n,(int)len); k = MIN(len, s->n); - map = map_ptr(buf,0,k); + map = (signed char *)map_ptr(buf,0,k); - sum = get_checksum1(map, k); + sum = get_checksum1((char *)map, k); s1 = sum & 0xFFFF; s2 = sum >> 16; if (verbose > 3) @@ -175,16 +174,16 @@ if (!done_csum2) { int l = MIN(s->n,len-offset); - map = map_ptr(buf,offset,l); - get_checksum2(map,l,sum2); + map = (signed char *)map_ptr(buf,offset,l); + get_checksum2((char *)map,l,sum2); done_csum2 = 1; } if (memcmp(sum2,s->sums[i].sum2,csum_length) == 0) { - matched(f,s,buf,len,offset,i); + matched(f,s,buf,offset,i); offset += s->sums[i].len - 1; k = MIN((len-offset), s->n); - map = map_ptr(buf,offset,k); - sum = get_checksum1(map, k); + map = (signed char *)map_ptr(buf,offset,k); + sum = get_checksum1((char *)map, k); s1 = sum & 0xFFFF; s2 = sum >> 16; ++matches; @@ -198,7 +197,7 @@ } /* Trim off the first byte from the checksum */ - map = map_ptr(buf,offset,k+1); + map = (signed char *)map_ptr(buf,offset,k+1); s1 -= map[0] + CHAR_OFFSET; s2 -= k * (map[0]+CHAR_OFFSET); @@ -212,7 +211,7 @@ } while (++offset < end); - matched(f,s,buf,len,len,-1); + matched(f,s,buf,len,-1); map_ptr(buf,len-1,1); } @@ -240,7 +239,7 @@ if (verbose > 2) fprintf(FERROR,"done hash search\n"); } else { - matched(f,s,buf,len,len,-1); + matched(f,s,buf,len,-1); } sum_end(file_sum); diff -u rsync-1.6.3/proto.h rsync-1.6.4/proto.h --- rsync-1.6.3/proto.h Fri Apr 11 16:18:35 1997 +++ rsync-1.6.4/proto.h Tue Dec 16 01:43:30 1997 @@ -1,6 +1,6 @@ /* This file is automatically generated with "make proto". DO NOT EDIT */ -uint32 get_checksum1(char *buf,int len); +uint32 get_checksum1(char *buf1,int len); void get_checksum2(char *buf,int len,char *sum); void file_checksum(char *fname,char *sum,off_t size); void checksum_init(void); @@ -67,3 +67,4 @@ void out_of_memory(char *str); int set_modtime(char *fname,time_t modtime); int set_blocking(int fd, int set); +int create_directory_path(char *fname); diff -u rsync-1.6.3/rsync.1 rsync-1.6.4/rsync.1 --- rsync-1.6.3/rsync.1 Fri Apr 11 16:18:35 1997 +++ rsync-1.6.4/rsync.1 Mon Dec 15 21:35:52 1997 @@ -29,7 +29,7 @@ - can use any transparent remote shell, including rsh or ssh -- does not require root privilages +- does not require root privileges - pipelining of file transfers to minimise latency costs @@ -113,8 +113,8 @@ .SH OPTIONS rsync uses the GNU long options package. Many of the command line -options have two varients, one short and one long. These are shown -below separated by commas. Some options only have a long varient. +options have two variants, one short and one long. These are shown +below separated by commas. Some options only have a long variant. .B -h, --help .RS 3 @@ -162,6 +162,26 @@ This tells rsync to copy directories recursively .RE +.B -R, --relative +.RS 3 +Use relative paths. This means that the full path names specified on +the command line are sent to the server rather than just the last +parts of the filenames. This is particularly useful when you want to +sent several different directories at the same time. For example if +you used the command + + rsync foo/bar/foo.c remote:/tmp/ + +then this would create a file called foo.c in /tmp/ on the remote +machine. If instead you used + + rsync -R foo/bar/foo.c remote:/tmp/ + +then a file called /tmp/foo/bar/foo.c would be created on the remote +machine. The full path name is preserved. + +.RE + .B -b, --backup .RS 3 With this option pre-existing destination files are renamed with a ~ @@ -251,22 +271,14 @@ see what files would be deleted to make sure important files aren't listed. -For example, one user was burnt by the following command: - - rsync -av --delete /usr/src remote:/tmp - -rsync happily transferred the contents of /usr/src to /tmp/src on the -destination then deleted everything else in /tmp. Nasty! It would have -been even nastier if he had used his home directory instead of /tmp. - -The correct way to achieve what this user probably wanted is this: - - rsync -av --delete /usr/src/ remote:/tmp/src - -in this case the deletions only occur inside the tree /tmp/src. - -The moral of the story is to use the -n option until you get used to -the behaviour of --delete. +rsync 1.6.4 changed the behaviour of --delete to make it less +dangerous. rsync now only scans directories on the receiving side that +are explicitly transferred from the sending side. Only files in these +directories are deleted. + +Still, it is probably easy to get burnt with this option. The moral of +the story is to use the -n option until you get used to the behaviour +of --delete. NOTE: It also may delete files on the destination if the sending side can't open them or stat them. This is a bug that hopefully will be @@ -290,7 +302,7 @@ environment variable. .RE -.B -e, --rsync-path PATH +.B --rsync-path PATH .RS 3 Use this to specify the path to the copy of rsync on the remote machine. Useful when its not in your path. @@ -411,4 +423,4 @@ Thanks to Richard Brent, Brendan Mackay, Bill Waite, Stephen Rothwell and David Bell for helpful suggestions and testing of rsync. I've -proabably missed some people, my apologies if I have. +probably missed some people, my apologies if I have. diff -u rsync-1.6.3/rsync.c rsync-1.6.4/rsync.c --- rsync-1.6.3/rsync.c Fri Apr 11 16:18:35 1997 +++ rsync-1.6.4/rsync.c Mon Dec 15 23:05:08 1997 @@ -46,6 +46,7 @@ extern int delete_mode; extern int cvs_exclude; extern int am_root; +extern int relative_paths; /* free a sums struct @@ -146,7 +147,6 @@ struct sum_struct *s; int i; off_t offset = 0; - int block_len; s = (struct sum_struct *)malloc(sizeof(*s)); if (!s) out_of_memory("receive_sums"); @@ -160,8 +160,6 @@ fprintf(FERROR,"count=%d n=%d rem=%d\n", s->count,s->n,s->remainder); - block_len = s->n; - if (s->count == 0) return(s); @@ -277,8 +275,14 @@ } 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; @@ -523,23 +527,38 @@ } +/* this deletes any files on the receiving side that are not present + on the sending side. For version 1.6.4 I have changed the behaviour + to match more closely what most people seem to expect of this option */ static void delete_files(struct file_list *flist) { struct file_list *local_file_list; char *dot="."; - int i; + int i, j; + char *last_name=NULL; if (cvs_exclude) add_cvs_excludes(); - if (!(local_file_list = send_file_list(-1,1,&dot))) - return; - - for (i=local_file_list->count-1;i>=0;i--) { - if (!local_file_list->files[i].name) continue; - if (-1 == flist_find(flist,&local_file_list->files[i])) { - delete_one(&local_file_list->files[i]); - } + for (j=0;jcount;j++) { + if (!S_ISDIR(flist->files[j].mode)) continue; + if (strcmp(flist->files[j].name,".")==0) continue; + if (last_name && + flist->files[j].name[strlen(last_name)] == '/' && + strncmp(flist->files[j].name,last_name, strlen(last_name))==0) + continue; + last_name = flist->files[j].name; + if (verbose > 1) + fprintf(FINFO,"deleting in %s\n", last_name); + if (!(local_file_list = send_file_list(-1,1,&last_name))) + return; + + for (i=local_file_list->count-1;i>=0;i--) { + if (!local_file_list->files[i].name) continue; + if (-1 == flist_find(flist,&local_file_list->files[i])) { + delete_one(&local_file_list->files[i]); + } + } } } @@ -635,6 +654,10 @@ } /* open tmp file */ + if (strlen(fname) > (MAXPATHLEN-8)) { + fprintf(FERROR,"filename too long\n"); + continue; + } sprintf(fnametmp,"%s.XXXXXX",fname); if (NULL == mktemp(fnametmp)) { fprintf(FERROR,"mktemp %s failed\n",fnametmp); @@ -644,6 +667,10 @@ 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); @@ -671,6 +698,10 @@ if (make_backups) { char fnamebak[MAXPATHLEN]; + if (strlen(fname) + strlen(backup_suffix) > (MAXPATHLEN-1)) { + fprintf(FERROR,"backup filename too long\n"); + continue; + } sprintf(fnamebak,"%s%s",fname,backup_suffix); if (rename(fname,fnamebak) != 0 && errno != ENOENT) { fprintf(FERROR,"rename %s %s : %s\n",fname,fnamebak,strerror(errno)); @@ -698,16 +729,16 @@ } } + if (preserve_hard_links) + do_hard_links(flist); + /* now we need to fix any directory permissions that were modified during the transfer */ - if (!am_root) { - for (i = 0; i < flist->count; i++) { - struct file_struct *file = &flist->files[i]; - if (!file->name || !S_ISDIR(file->mode)) continue; - recv_generator(file->name,flist,i,-1); - } + for (i = 0; i < flist->count; i++) { + struct file_struct *file = &flist->files[i]; + if (!file->name || !S_ISDIR(file->mode)) continue; + recv_generator(file->name,flist,i,-1); } - if (verbose > 2) fprintf(FERROR,"recv_files finished\n"); @@ -754,10 +785,11 @@ fname[0] = 0; if (file->dir) { - strcpy(fname,file->dir); + strncpy(fname,file->dir,MAXPATHLEN-1); + fname[MAXPATHLEN-1] = 0; strcat(fname,"/"); } - strcat(fname,file->name); + strncat(fname,file->name,MAXPATHLEN-strlen(fname)); if (verbose > 2) fprintf(FERROR,"send_files(%d,%s)\n",i,fname); diff -u rsync-1.6.3/rsync.h rsync-1.6.4/rsync.h --- rsync-1.6.3/rsync.h Fri Apr 11 16:18:35 1997 +++ rsync-1.6.4/rsync.h Mon Dec 15 18:35:12 1997 @@ -75,6 +75,10 @@ #include #endif +#ifdef HAVE_SYS_SOCKET_H +#include +#endif + #ifdef HAVE_STRING_H #include #endif @@ -138,6 +142,13 @@ #ifdef HAVE_SYS_SELECT_H #include +#endif + +#ifdef HAVE_SYS_MODE_H +/* apparently AIX needs this for S_ISLNK */ +#ifndef S_ISLNK +#include +#endif #endif #ifdef HAVE_FNMATCH Only in rsync-1.6.3: tech_report.ps diff -u rsync-1.6.3/token.c rsync-1.6.4/token.c --- rsync-1.6.3/token.c Fri Apr 11 16:18:35 1997 +++ rsync-1.6.4/token.c Mon Dec 15 21:40:42 1997 @@ -157,13 +157,13 @@ if (tx_strm.avail_in == 0 && nb != 0) { /* give it some more input */ n = MIN(nb, CHUNK_SIZE); - tx_strm.next_in = map_ptr(buf, offset, n); + tx_strm.next_in = (Bytef *)map_ptr(buf, offset, n); tx_strm.avail_in = n; nb -= n; offset += n; } if (tx_strm.avail_out == 0) { - tx_strm.next_out = obuf + 2; + tx_strm.next_out = (Bytef *)(obuf + 2); tx_strm.avail_out = MAX_DATA_COUNT; } r = deflate(&tx_strm, nb? Z_NO_FLUSH: Z_PACKET_FLUSH); @@ -185,7 +185,7 @@ if (token != -1) { /* add the data in the current block to the compressor's history and hash table */ - tx_strm.next_in = map_ptr(buf, offset, toklen); + tx_strm.next_in = (Bytef *)map_ptr(buf, offset, toklen); tx_strm.avail_in = toklen; tx_strm.next_out = NULL; tx_strm.avail_out = 2 * toklen; @@ -255,7 +255,7 @@ if ((flag & 0xC0) == DEFLATED_DATA) { n = ((flag & 0x3f) << 8) + read_byte(f); read_buf(f, cbuf, n); - rx_strm.next_in = cbuf; + rx_strm.next_in = (Bytef *)cbuf; rx_strm.avail_in = n; recv_state = r_inflating; break; @@ -263,7 +263,7 @@ if (recv_state == r_inflated) { /* check previous inflated stuff ended correctly */ rx_strm.avail_in = 0; - rx_strm.next_out = dbuf; + rx_strm.next_out = (Bytef *)dbuf; rx_strm.avail_out = CHUNK_SIZE; r = inflate(&rx_strm, Z_PACKET_FLUSH); n = CHUNK_SIZE - rx_strm.avail_out; @@ -303,7 +303,7 @@ return -1 - rx_token; case r_inflating: - rx_strm.next_out = dbuf; + rx_strm.next_out = (Bytef *)dbuf; rx_strm.avail_out = CHUNK_SIZE; r = inflate(&rx_strm, Z_NO_FLUSH); n = CHUNK_SIZE - rx_strm.avail_out; @@ -337,7 +337,7 @@ { int r; - rx_strm.next_in = buf; + rx_strm.next_in = (Bytef *)buf; rx_strm.avail_in = len; r = inflateIncomp(&rx_strm); if (r != Z_OK) { diff -u rsync-1.6.3/util.c rsync-1.6.4/util.c --- rsync-1.6.3/util.c Fri Apr 11 16:18:35 1997 +++ rsync-1.6.4/util.c Tue Dec 16 01:43:34 1997 @@ -55,6 +55,8 @@ char *map_ptr(struct map_struct *map,off_t offset,int len) { + int nread = -2; + if (map->map) return map->map+offset; @@ -79,8 +81,9 @@ } if (lseek(map->fd,offset,SEEK_SET) != offset || - read(map->fd,map->p,len) != len) { - fprintf(FERROR,"EOF in map_ptr!\n"); + (nread=read(map->fd,map->p,len)) != len) { + fprintf(FERROR,"EOF in map_ptr! (offset=%d len=%d nread=%d errno=%d)\n", + (int)offset, len, nread, errno); exit_cleanup(1); } @@ -124,6 +127,7 @@ 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 || @@ -131,6 +135,9 @@ fprintf(FERROR,"Failed to dup/close : %s\n",strerror(errno)); exit_cleanup(1); } + 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)); @@ -220,4 +227,27 @@ val |= FLAG_TO_SET; 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; } diff -u rsync-1.6.3/version.h rsync-1.6.4/version.h --- rsync-1.6.3/version.h Fri Apr 11 16:18:35 1997 +++ rsync-1.6.4/version.h Mon Dec 15 23:08:28 1997 @@ -1 +1 @@ -#define VERSION "1.6.2" +#define VERSION "1.6.4"