diff -u -r --new-file --exclude=CVS rsync-1.7.3/cvs.log rsync-1.7.4/cvs.log --- rsync-1.7.3/cvs.log Mon Apr 13 17:01:04 1998 +++ rsync-1.7.4/cvs.log Fri Apr 17 16:49:15 1998 @@ -2392,3 +2392,66 @@ Log Message: preparing for release of 1.7.3 + +**************************************** +Date: Monday April 13, 1998 @ 17:26 +Author: tridge + +Update of /data/cvs/rsync +In directory samba:/tmp/cvs-serv5919 + +Modified Files: + hlink.c match.c +Log Message: + +a few code cleanups + + + +**************************************** +Date: Friday April 17, 1998 @ 16:07 +Author: tridge + +Update of /data/cvs/rsync +In directory samba:/tmp/cvs-serv884 + +Modified Files: + flist.c proto.h rsync.c rsync.h +Log Message: + +revamped the -delete code. The last few bugs with it revealed that it +had a fundamental flaw in the way it detected duplicate deletion +scanning (which is very important when -R is used). I now store +inode/device numbers and use those to do the detection. This should be +a much less fragile method. + + + +**************************************** +Date: Friday April 17, 1998 @ 16:08 +Author: tridge + +Update of /data/cvs/rsync +In directory samba:/tmp/cvs-serv15916 + +Added Files: + test.sh +Log Message: + +this is a little test script to test some of rsyncs features +(contributed by Phil Hands) + + + +**************************************** +Date: Friday April 17, 1998 @ 16:49 +Author: rsync-bu + +Update of /data/cvs/rsync +In directory samba:/data/people/rsync-bugs/rsync + +Modified Files: + version.h +Log Message: +preparing for release of 1.7.4 + diff -u -r --new-file --exclude=CVS rsync-1.7.3/flist.c rsync-1.7.4/flist.c --- rsync-1.7.3/flist.c Mon Apr 13 16:42:13 1998 +++ rsync-1.7.4/flist.c Fri Apr 17 16:48:43 1998 @@ -134,7 +134,7 @@ -void send_file_entry(struct file_struct *file,int f) +void send_file_entry(struct file_struct *file,int f,unsigned base_flags) { unsigned char flags; static time_t last_time; @@ -155,7 +155,7 @@ fname = f_name(file); - flags = FILE_VALID; + flags = base_flags; if (file->mode == last_mode) flags |= SAME_MODE; if (file->rdev == last_rdev) flags |= SAME_RDEV; @@ -224,8 +224,8 @@ -void receive_file_entry(struct file_struct **fptr, - unsigned char flags,int f) +static void receive_file_entry(struct file_struct **fptr, + unsigned flags,int f) { static time_t last_time; static mode_t last_mode; @@ -280,6 +280,7 @@ if (!file->basename) out_of_memory("receive_file_entry 1"); + file->flags = flags; file->length = read_longint(f); file->modtime = (flags & SAME_TIME) ? last_time : (time_t)read_int(f); file->mode = (flags & SAME_MODE) ? last_mode : (mode_t)read_int(f); @@ -460,7 +461,7 @@ static void send_file_name(int f,struct file_list *flist,char *fname, - int recursive) + int recursive, unsigned base_flags) { struct file_struct *file; @@ -482,7 +483,7 @@ if (strcmp(file->basename,"")) { flist->files[flist->count++] = file; - send_file_entry(file,f); + send_file_entry(file,f,base_flags); } if (S_ISDIR(file->mode) && recursive) { @@ -541,7 +542,7 @@ strcmp(di->d_name,"..")==0) continue; strncpy(p,di->d_name,MAXPATHLEN-(l+1)); - send_file_name(f,flist,fname,recurse); + send_file_name(f,flist,fname,recurse,FLAG_DELETE); } closedir(d); @@ -616,7 +617,7 @@ *p = '/'; for (p=fname+1; (p=strchr(p,'/')); p++) { *p = 0; - send_file_name(f, flist, fname, 0); + send_file_name(f, flist, fname, 0, 0); *p = '/'; } } else { @@ -641,7 +642,7 @@ flist_dir = dir; if (one_file_system) set_filesystem(fname); - send_file_name(f,flist,fname,recurse); + send_file_name(f,flist,fname,recurse,FLAG_DELETE); flist_dir = NULL; if (chdir(dbuf) != 0) { fprintf(FERROR,"chdir %s : %s\n", @@ -653,11 +654,11 @@ if (one_file_system) set_filesystem(fname); - send_file_name(f,flist,fname,recurse); + send_file_name(f,flist,fname,recurse,FLAG_DELETE); } if (f != -1) { - send_file_entry(NULL,f); + send_file_entry(NULL,f,0); write_flush(f); } diff -u -r --new-file --exclude=CVS rsync-1.7.3/hlink.c rsync-1.7.4/hlink.c --- rsync-1.7.3/hlink.c Sun Apr 5 16:10:30 1998 +++ rsync-1.7.4/hlink.c Fri Apr 17 16:48:43 1998 @@ -31,10 +31,10 @@ if (!S_ISREG(f2->mode)) return 1; if (f1->dev != f2->dev) - return (int)(f1->dev - f2->dev); + return (int)(f1->dev>f2->dev?1:-1); if (f1->inode != f2->inode) - return (f1->inode - f2->inode); + return (int)(f1->inode>f2->inode?1:-1); return file_compare(&f1,&f2); } @@ -103,47 +103,55 @@ } +#if SUPPORT_HARD_LINKS +static void hard_link_one(int i) +{ + struct stat st1,st2; + + if (link_stat(f_name(&hlink_list[i-1]),&st1) != 0) return; + + if (link_stat(f_name(&hlink_list[i]),&st2) != 0) { + if (do_link(f_name(&hlink_list[i-1]),f_name(&hlink_list[i])) != 0) { + if (verbose > 0) + fprintf(FINFO,"link %s => %s : %s\n", + f_name(&hlink_list[i]), + f_name(&hlink_list[i-1]),strerror(errno)); + return; + } + } else { + if (st2.st_dev == st1.st_dev && st2.st_ino == st1.st_ino) return; + + if (do_unlink(f_name(&hlink_list[i])) != 0 || + do_link(f_name(&hlink_list[i-1]),f_name(&hlink_list[i])) != 0) { + if (verbose > 0) + fprintf(FINFO,"link %s => %s : %s\n", + f_name(&hlink_list[i]), + f_name(&hlink_list[i-1]),strerror(errno)); + return; + } + } + if (verbose > 0) + fprintf(FINFO,"%s => %s\n", + f_name(&hlink_list[i]),f_name(&hlink_list[i-1])); +} +#endif + /* create any hard links in the flist */ void do_hard_links(struct file_list *flist) { #if SUPPORT_HARD_LINKS - int i; + int i; - if (!hlink_list) return; + if (!hlink_list) return; - for (i=1;i 0) - fprintf(FINFO,"link %s => %s : %s\n", - f_name(&hlink_list[i]), - f_name(&hlink_list[i-1]),strerror(errno)); - continue; + for (i=1;i 0) - fprintf(FINFO,"link %s => %s : %s\n", - f_name(&hlink_list[i]), - f_name(&hlink_list[i-1]),strerror(errno)); - continue; - } - } - if (verbose > 0) - fprintf(FINFO,"%s => %s\n", - f_name(&hlink_list[i]),f_name(&hlink_list[i-1])); - } - } #endif } diff -u -r --new-file --exclude=CVS rsync-1.7.3/match.c rsync-1.7.4/match.c --- rsync-1.7.3/match.c Thu Mar 26 15:51:10 1998 +++ rsync-1.7.4/match.c Fri Apr 17 16:48:43 1998 @@ -56,7 +56,7 @@ static int compare_targets(struct target *t1,struct target *t2) { - return(t1->t - t2->t); + return((int)t1->t - (int)t2->t); } diff -u -r --new-file --exclude=CVS rsync-1.7.3/proto.h rsync-1.7.4/proto.h --- rsync-1.7.3/proto.h Sun Apr 5 16:45:20 1998 +++ rsync-1.7.4/proto.h Fri Apr 17 16:48:43 1998 @@ -17,9 +17,7 @@ void recv_exclude_list(int f); void add_cvs_excludes(void); int link_stat(const char *Path, struct stat *Buffer) ; -void send_file_entry(struct file_struct *file,int f); -void receive_file_entry(struct file_struct **fptr, - unsigned char flags,int f); +void send_file_entry(struct file_struct *file,int f,unsigned base_flags); struct file_list *send_file_list(int f,int argc,char *argv[]); struct file_list *recv_file_list(int f); int file_compare(struct file_struct **f1,struct file_struct **f2); diff -u -r --new-file --exclude=CVS rsync-1.7.3/rsync.c rsync-1.7.4/rsync.c --- rsync-1.7.3/rsync.c Mon Apr 13 16:42:13 1998 +++ rsync-1.7.4/rsync.c Fri Apr 17 16:48:43 1998 @@ -627,61 +627,50 @@ } -/* yuck! This function wouldn't have been necessary if I had the sorting - algorithm right. Unfortunately fixing the sorting algorithm would introduce - a backward incompatibility as file list indexes are sent over the link. - The aim is to see if a directory has already had the deletion algorithm applied - to it (due to recursion), and if so to skip it. The bisection is to - prevent this being an n^2 algorithm */ -static int delete_already_done(struct file_list *flist,int j) -{ - int low=0,high=j-1; - char *name; - char *p; - - if (j == 0) return 0; +static struct delete_list { + dev_t dev; + ino_t inode; +} *delete_list; +static int dlist_len, dlist_alloc_len; - name = strdup(f_name(flist->files[j])); - - if (!name) { - fprintf(FERROR,"out of memory in delete_already_done"); - exit_cleanup(1); +static void add_delete_entry(struct file_struct *file) +{ + if (dlist_len == dlist_alloc_len) { + dlist_alloc_len += 1024; + if (!delete_list) { + delete_list = (struct delete_list *)malloc(sizeof(delete_list[0])*dlist_alloc_len); + } else { + delete_list = (struct delete_list *)realloc(delete_list, sizeof(delete_list[0])*dlist_alloc_len); + } + if (!delete_list) out_of_memory("add_delete_entry"); } - name[strlen(name)-2] = 0; - - p = strrchr(name,'/'); - if (!p) { - free(name); - return 0; - } - *p = 0; + delete_list[dlist_len].dev = file->dev; + delete_list[dlist_len].inode = file->inode; + dlist_len++; - strcat(name,"/."); + if (verbose > 3) + fprintf(FINFO,"added %s to delete list\n", f_name(file)); +} - while (low != high) { - int mid = (low+high)/2; - int ret = strcmp(f_name(flist->files[flist_up(flist, mid)]),name); - if (ret == 0) { - free(name); - return 1; - } - if (ret > 0) { - high=mid; - } else { - low=mid+1; - } - } +/* yuck! This function wouldn't have been necessary if I had the sorting + algorithm right. Unfortunately fixing the sorting algorithm would introduce + a backward incompatibility as file list indexes are sent over the link. +*/ +static int delete_already_done(struct file_list *flist,int j) +{ + int i; + struct stat st; - low = flist_up(flist, low); + if (link_stat(f_name(flist->files[j]), &st)) return 1; - if (strcmp(f_name(flist->files[low]),name) == 0) { - free(name); - return 1; + for (i=0;icount;j++) { - char *name = f_name(flist->files[j]); + if (io_error) { + fprintf(FINFO,"IO error encountered - skipping file deletion\n"); + return; + } - if (!S_ISDIR(flist->files[j]->mode)) continue; + for (j=0;jcount;j++) { + if (!S_ISDIR(flist->files[j]->mode) || + !(flist->files[j]->flags & FLAG_DELETE)) continue; - if (strlen(name)<2 || strcmp(name+strlen(name)-2,"/.")!=0) continue; + if (delete_already_done(flist, j)) continue; - if (delete_already_done(flist, j)) continue; + name = strdup(f_name(flist->files[j])); - if (!(local_file_list = send_file_list(-1,1,&name))) - continue; + if (!(local_file_list = send_file_list(-1,1,&name))) { + free(name); + continue; + } - if (verbose > 1) - fprintf(FINFO,"deleting in %s\n", name); + if (verbose > 1) + fprintf(FINFO,"deleting in %s\n", name); - for (i=local_file_list->count-1;i>=0;i--) { - if (!local_file_list->files[i]->basename) continue; - if (-1 == flist_find(flist,local_file_list->files[i])) { - delete_one(local_file_list->files[i]); - } - } - flist_free(local_file_list); - } + for (i=local_file_list->count-1;i>=0;i--) { + if (!local_file_list->files[i]->basename) continue; + if (S_ISDIR(local_file_list->files[i]->mode)) + add_delete_entry(local_file_list->files[i]); + if (-1 == flist_find(flist,local_file_list->files[i])) { + delete_one(local_file_list->files[i]); + } + } + flist_free(local_file_list); + free(name); + } } static char *cleanup_fname; diff -u -r --new-file --exclude=CVS rsync-1.7.3/rsync.h rsync-1.7.4/rsync.h --- rsync-1.7.3/rsync.h Sun Apr 5 16:45:21 1998 +++ rsync-1.7.4/rsync.h Fri Apr 17 16:48:43 1998 @@ -28,7 +28,7 @@ #define CHAR_OFFSET 0 -#define FILE_VALID 1 +#define FLAG_DELETE (1<<0) #define SAME_MODE (1<<1) #define SAME_RDEV (1<<2) #define SAME_UID (1<<3) @@ -216,6 +216,7 @@ #endif struct file_struct { + unsigned flags; time_t modtime; off_t length; mode_t mode; diff -u -r --new-file --exclude=CVS rsync-1.7.3/test.sh rsync-1.7.4/test.sh --- rsync-1.7.3/test.sh Thu Jan 1 10:00:00 1970 +++ rsync-1.7.4/test.sh Fri Apr 17 16:08:59 1998 @@ -0,0 +1,54 @@ +#!/bin/sh -e +# This is a simple test script that tests a few rsync +# features to make sure I haven't broken them before a release. Thanks +# to Phil Hands for writing this + +export PATH=.:$PATH +TMP=/tmp/rsync-test.$$ +F1=README + +mkdir $TMP + +pause() { + echo ... press enter to continue + read +} + +echo "Test 1 basic operation" +rsync -av testin/ ${TMP}/rsync +diff -ur testin/ ${TMP}/rsync +pause + +echo "Test 2 - one file" +rm ${TMP}/rsync/${F1} +rsync -av testin/ ${TMP}/rsync +diff -ur testin/ ${TMP}/rsync +pause + +echo "Test 3 - extra data" +echo "extra line" >> ${TMP}/rsync/${F1} +rsync -av testin/ ${TMP}/rsync +diff -ur testin/ ${TMP}/rsync +pause + +echo "Test 4 - --delete" +cp testin/${F1} ${TMP}/rsync/f1 +rsync --delete -av testin/ ${TMP}/rsync +diff -ur testin/ ${TMP}/rsync +pause + +echo "Test 5 (uses ssh, so will fail if you don't have it) " +rm -rf ${TMP}/rsync +rsync -av -e ssh testin/ localhost:${TMP}/rsync +diff -ur testin/ ${TMP}/rsync +pause + +echo "Test 6 (uses ssh, so will fail if you don't have it) " +mv ${TMP}/rsync/${F1} ${TMP}/rsync/f1 +rsync --delete -av -e ssh testin/ localhost:${TMP}/rsync +diff -ur testin/ ${TMP}/rsync +pause + +rm -rf ${TMP} + +echo Tests Completed diff -u -r --new-file --exclude=CVS rsync-1.7.3/version.h rsync-1.7.4/version.h --- rsync-1.7.3/version.h Mon Apr 13 17:00:52 1998 +++ rsync-1.7.4/version.h Fri Apr 17 16:49:03 1998 @@ -1 +1 @@ -#define VERSION "1.7.3" +#define VERSION "1.7.4"