- added an internal io_error flag. Whenever an io error occurs (such
authorAndrew Tridgell <tridge@samba.org>
Thu, 26 Mar 1998 04:18:47 +0000 (04:18 +0000)
committerAndrew Tridgell <tridge@samba.org>
Thu, 26 Mar 1998 04:18:47 +0000 (04:18 +0000)
as not being able to open a directory) this flag is set and propogated
to the other end. When this flag is set the --delete code is
disabled. This prevents the problem that io or permission errors could
cause files to be incorrectly deleted on the destination.

- added a --timeout option. This allows you to set an IO timeout in
seconds. If no io occurs in that time then rsync exits with a timeout
error.

- changed some FERROR fds to FINFO

exclude.c
flist.c
io.c
main.c
match.c
rsync.c
rsync.h

index 139c0b4..935c0c5 100644 (file)
--- a/exclude.c
+++ b/exclude.c
@@ -24,6 +24,7 @@
 #include "rsync.h"
 
 extern int verbose;
+extern int am_server;
 
 static char **exclude_list;
 
@@ -86,7 +87,7 @@ void add_exclude_list(char *pattern,char ***list)
 
   if (strcmp(pattern,"!") == 0) {
     if (verbose > 2)
-      fprintf(FERROR,"clearing exclude list\n");
+      fprintf(FINFO,"clearing exclude list\n");
     while ((len)--) 
       free((*list)[len]);
     free((*list));
@@ -104,7 +105,7 @@ void add_exclude_list(char *pattern,char ***list)
     out_of_memory("add_exclude");
 
   if (verbose > 2)
-    fprintf(FERROR,"add_exclude(%s)\n",pattern);
+    fprintf(FINFO,"add_exclude(%s)\n",pattern);
   
   (*list)[len+1] = NULL;
 }
diff --git a/flist.c b/flist.c
index e67d4b2..0a61d34 100644 (file)
--- a/flist.c
+++ b/flist.c
@@ -44,6 +44,7 @@ extern int preserve_times;
 extern int relative_paths;
 extern int copy_links;
 extern int remote_version;
+extern int io_error;
 
 static char **local_exclude_list;
 
@@ -68,7 +69,7 @@ static int match_file_name(char *fname,struct stat *st)
 {
   if (check_exclude(fname,local_exclude_list)) {
     if (verbose > 2)
-      fprintf(FERROR,"excluding file %s\n",fname);
+      fprintf(FINFO,"excluding file %s\n",fname);
     return 0;
   }
   return 1;
@@ -356,13 +357,14 @@ static struct file_struct *make_file(char *fname)
        bzero(sum,SUM_LENGTH);
 
        if (link_stat(fname,&st) != 0) {
+               io_error = 1;
                fprintf(FERROR,"%s: %s\n",
                        fname,strerror(errno));
                return NULL;
        }
 
        if (S_ISDIR(st.st_mode) && !recurse) {
-               fprintf(FERROR,"skipping directory %s\n",fname);
+               fprintf(FINFO,"skipping directory %s\n",fname);
                return NULL;
        }
        
@@ -375,7 +377,7 @@ static struct file_struct *make_file(char *fname)
                return NULL;
        
        if (verbose > 2)
-               fprintf(FERROR,"make_file(%s)\n",fname);
+               fprintf(FINFO,"make_file(%s)\n",fname);
        
        file = (struct file_struct *)malloc(sizeof(*file));
        if (!file) out_of_memory("make_file");
@@ -413,6 +415,7 @@ static struct file_struct *make_file(char *fname)
                int l;
                char lnk[MAXPATHLEN];
                if ((l=readlink(fname,lnk,MAXPATHLEN-1)) == -1) {
+                       io_error=1;
                        fprintf(FERROR,"readlink %s : %s\n",
                                fname,strerror(errno));
                        return NULL;
@@ -494,6 +497,7 @@ static void send_directory(int f,struct file_list *flist,char *dir)
 
        d = opendir(dir);
        if (!d) {
+               io_error = 1;
                fprintf(FERROR,"%s: %s\n",
                        dir,strerror(errno));
                return;
@@ -504,6 +508,7 @@ static void send_directory(int f,struct file_list *flist,char *dir)
        l = strlen(fname);
        if (fname[l-1] != '/') {
                if (l == MAXPATHLEN-1) {
+                       io_error = 1;
                        fprintf(FERROR,"skipping long-named directory %s\n",fname);
                        closedir(d);
                        return;
@@ -518,7 +523,8 @@ static void send_directory(int f,struct file_list *flist,char *dir)
                        strcpy(p,".cvsignore");
                        local_exclude_list = make_exclude_list(fname,NULL,0);
                } else {
-                       fprintf(FERROR,"cannot cvs-exclude in long-named directory %s\n",fname);
+                       io_error = 1;
+                       fprintf(FINFO,"cannot cvs-exclude in long-named directory %s\n",fname);
                }
        }  
        
@@ -571,12 +577,13 @@ struct file_list *send_file_list(int f,int argc,char *argv[])
                }
 
                if (link_stat(fname,&st) != 0) {
+                       io_error=1;
                        fprintf(FERROR,"%s : %s\n",fname,strerror(errno));
                        continue;
                }
 
                if (S_ISDIR(st.st_mode) && !recurse) {
-                       fprintf(FERROR,"skipping directory %s\n",fname);
+                       fprintf(FINFO,"skipping directory %s\n",fname);
                        continue;
                }
 
@@ -618,6 +625,7 @@ struct file_list *send_file_list(int f,int argc,char *argv[])
                                exit_cleanup(1);
                        }
                        if (chdir(dir) != 0) {
+                               io_error=1;
                                fprintf(FERROR,"chdir %s : %s\n",
                                        dir,strerror(errno));
                                continue;
@@ -656,6 +664,11 @@ struct file_list *send_file_list(int f,int argc,char *argv[])
                send_uid_list(f);
        }
 
+       /* if protocol version is >= 17 then send the io_error flag */
+       if (f != -1 && remote_version >= 17) {
+               write_int(f, io_error);
+       }
+
        return flist;
 }
 
@@ -705,12 +718,12 @@ struct file_list *recv_file_list(int f)
     flist->count++;
 
     if (verbose > 2)
-      fprintf(FERROR,"recv_file_name(%s)\n",f_name(flist->files[i]));
+      fprintf(FINFO,"recv_file_name(%s)\n",f_name(flist->files[i]));
   }
 
 
   if (verbose > 2)
-    fprintf(FERROR,"received %d names\n",flist->count);
+    fprintf(FINFO,"received %d names\n",flist->count);
 
   clean_flist(flist);
 
@@ -723,6 +736,11 @@ struct file_list *recv_file_list(int f)
          recv_uid_list(f, flist);
   }
 
+  /* if protocol version is >= 17 then recv the io_error flag */
+  if (f != -1 && remote_version >= 17) {
+         io_error |= read_int(f);
+  }
+
   return flist;
 
 oom:
@@ -816,7 +834,7 @@ void clean_flist(struct file_list *flist)
                    strcmp(f_name(flist->files[i]),
                           f_name(flist->files[i-1])) == 0) {
                        if (verbose > 1 && !am_server)
-                               fprintf(FERROR,"removing duplicate name %s from file list %d\n",
+                               fprintf(FINFO,"removing duplicate name %s from file list %d\n",
                                        f_name(flist->files[i-1]),i-1);
                        free_file(flist->files[i]);
                } 
diff --git a/io.c b/io.c
index aae64b7..b5ceff1 100644 (file)
--- a/io.c
+++ b/io.c
@@ -29,6 +29,7 @@ static int64 total_read;
 
 extern int verbose;
 extern int sparse_files;
+extern int io_timeout;
 
 int64 write_total(void)
 {
@@ -95,39 +96,70 @@ static void read_check(int f)
   }
 }
 
+static time_t last_io;
+
+
+static void check_timeout(void)
+{
+       time_t t;
+       
+       if (!io_timeout) return;
+
+       if (!last_io) {
+               last_io = time(NULL);
+               return;
+       }
+
+       t = time(NULL);
+
+       if (last_io && io_timeout && (t-last_io)>io_timeout) {
+               fprintf(FERROR,"read timeout after %d second - exiting\n", 
+                       (int)(t-last_io));
+               exit_cleanup(1);
+       }
+}
 
 static int readfd(int fd,char *buffer,int N)
 {
-  int  ret;
-  int total=0;  
-
-  if (read_buffer_len < N)
-         read_check(buffer_f_in);
-  while (total < N)
-    {
-      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;
-       read_buffer_len -= ret;
-      } else {
-       while ((ret = read(fd,buffer + total,N - total)) == -1) {
-         fd_set fds;
-
-         if (errno != EAGAIN && errno != EWOULDBLOCK)
-           return -1;
-         FD_ZERO(&fds);
-         FD_SET(fd, &fds);
-         select(fd+1, &fds, NULL, NULL, NULL);
+       int  ret;
+       int total=0;  
+       struct timeval tv;
+       
+       if (read_buffer_len < N)
+               read_check(buffer_f_in);
+       
+       while (total < N) {
+               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;
+                       read_buffer_len -= ret;
+                       continue;
+               } 
+
+               while ((ret = read(fd,buffer + total,N-total)) == -1) {
+                       fd_set fds;
+
+                       if (errno != EAGAIN && errno != EWOULDBLOCK)
+                               return -1;
+                       FD_ZERO(&fds);
+                       FD_SET(fd, &fds);
+                       tv.tv_sec = io_timeout;
+                       tv.tv_usec = 0;
+
+                       if (select(fd+1, &fds, NULL, NULL, &tv) != 1) {
+                               check_timeout();
+                       }
+               }
+
+               if (ret <= 0)
+                       return total;
+               total += ret;
        }
-      }
 
-      if (ret <= 0)
+       if (io_timeout)
+               last_io = time(NULL);
        return total;
-      total += ret;
-    }
-  return total;
 }
 
 
@@ -295,7 +327,10 @@ static int writefd(int fd,char *buf,int len)
              exit_cleanup(1);
       }
 
-      if (count == 0) continue;
+      if (count == 0) {
+             check_timeout();
+             continue;
+      }
       
       if (FD_ISSET(fd, &w_fds)) {
              got_select = 1;
@@ -305,6 +340,9 @@ static int writefd(int fd,char *buf,int len)
     }
   }
 
+  if (io_timeout)
+         last_io = time(NULL);
+
   return total;
 }
 
diff --git a/main.c b/main.c
index 206a24c..33496cc 100644 (file)
--- a/main.c
+++ b/main.c
@@ -55,6 +55,8 @@ int orig_umask=0;
 int relative_paths=0;
 int numeric_ids = 0;
 int force_delete = 0;
+int io_timeout = 0;
+int io_error = 0;
 
 extern int csum_length;
 
@@ -108,6 +110,7 @@ static void server_options(char **args,int *argc)
   int ac = *argc;
   static char argstr[50];
   static char bsize[30];
+  static char iotime[30];
   int i, x;
 
   args[ac++] = "--server";
@@ -168,6 +171,11 @@ static void server_options(char **args,int *argc)
     args[ac++] = bsize;
   }    
 
+  if (io_timeout) {
+    sprintf(iotime,"--timeout=%d",io_timeout);
+    args[ac++] = iotime;
+  }    
+
   if (strcmp(backup_suffix, BACKUP_SUFFIX)) {
          args[ac++] = "--suffix";
          args[ac++] = backup_suffix;
@@ -239,10 +247,10 @@ static int do_cmd(char *cmd,char *machine,char *user,char *path,int *f_in,int *f
   args[argc] = NULL;
 
   if (verbose > 3) {
-    fprintf(FERROR,"cmd=");
+    fprintf(FINFO,"cmd=");
     for (i=0;i<argc;i++)
-      fprintf(FERROR,"%s ",args[i]);
-    fprintf(FERROR,"\n");
+      fprintf(FINFO,"%s ",args[i]);
+    fprintf(FINFO,"\n");
   }
 
   ret = piped_child(args,f_in,f_out);
@@ -308,7 +316,7 @@ void do_server_sender(int argc,char *argv[])
   char *dir = argv[0];
 
   if (verbose > 2)
-    fprintf(FERROR,"server_sender starting pid=%d\n",(int)getpid());
+    fprintf(FINFO,"server_sender starting pid=%d\n",(int)getpid());
   
   if (!relative_paths && chdir(dir) != 0) {
          fprintf(FERROR,"chdir %s: %s (3)\n",dir,strerror(errno));
@@ -357,7 +365,7 @@ static int do_recv(int f_in,int f_out,struct file_list *flist,char *local_name)
   if ((pid=do_fork()) == 0) {
     recv_files(f_in,flist,local_name,recv_pipe[1]);
     if (verbose > 2)
-      fprintf(FERROR,"receiver read %ld\n",(long)read_total());
+      fprintf(FINFO,"receiver read %ld\n",(long)read_total());
     exit_cleanup(0);
   }
 
@@ -377,7 +385,7 @@ void do_server_recv(int argc,char *argv[])
   char *dir = NULL;
   
   if (verbose > 2)
-    fprintf(FERROR,"server_recv(%d) starting pid=%d\n",argc,(int)getpid());
+    fprintf(FINFO,"server_recv(%d) starting pid=%d\n",argc,(int)getpid());
 
   if (argc > 0) {
          dir = argv[0];
@@ -445,6 +453,7 @@ static void usage(FILE *f)
   fprintf(f,"    --delete             delete files that don't exist on the sending side\n");
   fprintf(f,"    --force              force deletion of directories even if not empty\n");
   fprintf(f,"    --numeric-ids        don't map uid/gid values by user/group name\n");
+  fprintf(f,"    --timeout TIME       set IO timeout in seconds\n");
   fprintf(f,"-I, --ignore-times       don't exclude files that match length and time\n");
   fprintf(f,"-T  --temp-dir DIR       create temporary files in directory DIR\n");
   fprintf(f,"-z, --compress           compress file data\n");
@@ -459,7 +468,8 @@ static void usage(FILE *f)
 }
 
 enum {OPT_VERSION,OPT_SUFFIX,OPT_SENDER,OPT_SERVER,OPT_EXCLUDE,
-      OPT_EXCLUDE_FROM,OPT_DELETE,OPT_NUMERIC_IDS,OPT_RSYNC_PATH,OPT_FORCE};
+      OPT_EXCLUDE_FROM,OPT_DELETE,OPT_NUMERIC_IDS,OPT_RSYNC_PATH,
+      OPT_FORCE,OPT_TIMEOUT};
 
 static char *short_options = "oblLWHpguDCtcahvrRIxnSe:B:T:z";
 
@@ -498,6 +508,7 @@ static struct option long_options[] = {
   {"rsh",         1,     0,    'e'},
   {"suffix",      1,     0,    OPT_SUFFIX},
   {"block-size",  1,     0,    'B'},
+  {"timeout",     1,     0,    OPT_TIMEOUT},
   {"temp-dir",    1,     0,    'T'},
   {"compress",   0,     0,    'z'},
   {0,0,0,0}};
@@ -690,6 +701,10 @@ int main(int argc,char *argv[])
          block_size = atoi(optarg);
          break;
 
+       case OPT_TIMEOUT:
+         io_timeout = atoi(optarg);
+         break;
+
        case 'T':
                tmpdir = optarg;
                break;
@@ -781,7 +796,7 @@ int main(int argc,char *argv[])
     }
 
     if (verbose > 3) {
-      fprintf(FERROR,"cmd=%s machine=%s user=%s path=%s\n",
+      fprintf(FINFO,"cmd=%s machine=%s user=%s path=%s\n",
              shell_cmd?shell_cmd:"",
              shell_machine?shell_machine:"",
              shell_user?shell_user:"",
@@ -803,7 +818,7 @@ int main(int argc,char *argv[])
 #endif
 
     if (verbose > 3) 
-      fprintf(FERROR,"parent=%d child=%d sender=%d recurse=%d\n",
+      fprintf(FINFO,"parent=%d child=%d sender=%d recurse=%d\n",
              (int)getpid(),pid,sender,recurse);
 
     if (sender) {
@@ -813,10 +828,10 @@ int main(int argc,char *argv[])
        send_exclude_list(f_out);
       flist = send_file_list(f_out,argc,argv);
       if (verbose > 3) 
-       fprintf(FERROR,"file list sent\n");
+       fprintf(FINFO,"file list sent\n");
       send_files(flist,f_out,f_in);
       if (verbose > 3)
-       fprintf(FERROR,"waiting on %d\n",pid);
+       fprintf(FINFO,"waiting on %d\n",pid);
       waitpid(pid, &status, 0);
       report(-1);
       exit_cleanup(status);
@@ -826,7 +841,7 @@ int main(int argc,char *argv[])
 
     flist = recv_file_list(f_in);
     if (!flist || flist->count == 0) {
-      fprintf(FERROR,"nothing to do\n");
+      fprintf(FINFO,"nothing to do\n");
       exit_cleanup(0);
     }
 
diff --git a/match.c b/match.c
index dd289e1..a97e7e1 100644 (file)
--- a/match.c
+++ b/match.c
@@ -97,7 +97,7 @@ static void matched(int f,struct sum_struct *s,struct map_struct *buf,
        int j;
 
        if (verbose > 2 && i >= 0)
-               fprintf(FERROR,"match at %d last_match=%d j=%d len=%d n=%d\n",
+               fprintf(FINFO,"match at %d last_match=%d j=%d len=%d n=%d\n",
                        (int)offset,(int)last_match,i,(int)s->sums[i].len,(int)n);
 
        send_token(f,i,buf,last_match,n,i==-1?0:s->sums[i].len);
@@ -133,7 +133,7 @@ static void hash_search(int f,struct sum_struct *s,
        signed char *map;
 
        if (verbose > 2)
-               fprintf(FERROR,"hash search b=%d len=%d\n",s->n,(int)len);
+               fprintf(FINFO,"hash search b=%d len=%d\n",s->n,(int)len);
 
        k = MIN(len, s->n);
        
@@ -143,14 +143,14 @@ static void hash_search(int f,struct sum_struct *s,
        s1 = sum & 0xFFFF;
        s2 = sum >> 16;
        if (verbose > 3)
-               fprintf(FERROR, "sum=%.8x k=%d\n", sum, k);
+               fprintf(FINFO, "sum=%.8x k=%d\n", sum, k);
        
        offset = 0;
        
        end = len + 1 - s->sums[s->count-1].len;
        
        if (verbose > 3)
-               fprintf(FERROR,"hash search s->n=%d len=%d count=%d\n",
+               fprintf(FINFO,"hash search s->n=%d len=%d count=%d\n",
                        s->n,(int)len,s->count);
        
        do {
@@ -159,7 +159,7 @@ static void hash_search(int f,struct sum_struct *s,
                        
                j = tag_table[t];
                if (verbose > 4)
-                       fprintf(FERROR,"offset=%d sum=%08x\n",(int)offset,sum);
+                       fprintf(FINFO,"offset=%d sum=%08x\n",(int)offset,sum);
                
                if (j == NULL_TAG) {
                        goto null_tag;
@@ -173,7 +173,7 @@ static void hash_search(int f,struct sum_struct *s,
                        if (sum != s->sums[i].sum1) continue;
                        
                        if (verbose > 3)
-                               fprintf(FERROR,"potential match at %d target=%d %d sum=%08x\n",
+                               fprintf(FINFO,"potential match at %d target=%d %d sum=%08x\n",
                                        (int)offset,j,i,sum);
                        
                        if (!done_csum2) {
@@ -236,12 +236,12 @@ void match_sums(int f,struct sum_struct *s,struct map_struct *buf,off_t len)
                build_hash_table(s);
                
                if (verbose > 2) 
-                       fprintf(FERROR,"built hash table\n");
+                       fprintf(FINFO,"built hash table\n");
                
                hash_search(f,s,buf,len);
                
                if (verbose > 2) 
-                       fprintf(FERROR,"done hash search\n");
+                       fprintf(FINFO,"done hash search\n");
        } else {
                matched(f,s,buf,len,-1);
        }
@@ -250,7 +250,7 @@ void match_sums(int f,struct sum_struct *s,struct map_struct *buf,off_t len)
 
        if (remote_version >= 14) {
                if (verbose > 2)
-                       fprintf(FERROR,"sending file_sum\n");
+                       fprintf(FINFO,"sending file_sum\n");
                write_buf(f,file_sum,MD4_SUM_LENGTH);
        }
 
@@ -260,7 +260,7 @@ void match_sums(int f,struct sum_struct *s,struct map_struct *buf,off_t len)
        }
        
        if (verbose > 2)
-               fprintf(FERROR, "false_alarms=%d tag_hits=%d matches=%d\n",
+               fprintf(FINFO, "false_alarms=%d tag_hits=%d matches=%d\n",
                        false_alarms, tag_hits, matches);
        
        total_tag_hits += tag_hits;
diff --git a/rsync.c b/rsync.c
index 3b4ff1b..82035f5 100644 (file)
--- a/rsync.c
+++ b/rsync.c
@@ -49,6 +49,8 @@ extern int delete_mode;
 extern int cvs_exclude;
 extern int am_root;
 extern int relative_paths;
+extern int io_timeout;
+extern int io_error;
 
 /*
   free a sums struct
@@ -181,7 +183,7 @@ static struct sum_struct *generate_sums(struct map_struct *buf,off_t len,int n)
   }
 
   if (verbose > 3)
-    fprintf(FERROR,"count=%d rem=%d n=%d flength=%d\n",
+    fprintf(FINFO,"count=%d rem=%d n=%d flength=%d\n",
            s->count,s->remainder,s->n,(int)s->flength);
 
   s->sums = (struct sum_buf *)malloc(sizeof(s->sums[0])*s->count);
@@ -199,7 +201,7 @@ static struct sum_struct *generate_sums(struct map_struct *buf,off_t len,int n)
     s->sums[i].i = i;
 
     if (verbose > 3)
-      fprintf(FERROR,"chunk[%d] offset=%d len=%d sum1=%08x\n",
+      fprintf(FINFO,"chunk[%d] offset=%d len=%d sum1=%08x\n",
              i,(int)s->sums[i].offset,s->sums[i].len,s->sums[i].sum1);
 
     len -= n1;
@@ -228,7 +230,7 @@ static struct sum_struct *receive_sums(int f)
   s->sums = NULL;
 
   if (verbose > 3)
-    fprintf(FERROR,"count=%d n=%d rem=%d\n",
+    fprintf(FINFO,"count=%d n=%d rem=%d\n",
            s->count,s->n,s->remainder);
 
   if (s->count == 0) 
@@ -252,7 +254,7 @@ static struct sum_struct *receive_sums(int f)
     offset += s->sums[i].len;
 
     if (verbose > 3)
-      fprintf(FERROR,"chunk[%d] len=%d offset=%d sum1=%08x\n",
+      fprintf(FINFO,"chunk[%d] len=%d offset=%d sum1=%08x\n",
              i,s->sums[i].len,(int)s->sums[i].offset,s->sums[i].sum1);
   }
 
@@ -369,7 +371,7 @@ void recv_generator(char *fname,struct file_list *flist,int i,int f_out)
   struct file_struct *file = flist->files[i];
 
   if (verbose > 2)
-    fprintf(FERROR,"recv_generator(%s,%d)\n",fname,i);
+    fprintf(FINFO,"recv_generator(%s,%d)\n",fname,i);
 
   statret = link_stat(fname,&st);
 
@@ -430,7 +432,7 @@ void recv_generator(char *fname,struct file_list *flist,int i,int f_out)
        st.st_rdev != file->rdev) {     
       delete_file(fname);
       if (verbose > 2)
-       fprintf(FERROR,"mknod(%s,0%o,0x%x)\n",
+       fprintf(FINFO,"mknod(%s,0%o,0x%x)\n",
                fname,(int)file->mode,(int)file->rdev);
       if (do_mknod(fname,file->mode,file->rdev) != 0) {
        fprintf(FERROR,"mknod %s : %s\n",fname,strerror(errno));
@@ -453,7 +455,7 @@ void recv_generator(char *fname,struct file_list *flist,int i,int f_out)
   }
 
   if (!S_ISREG(file->mode)) {
-    fprintf(FERROR,"skipping non-regular file %s\n",fname);
+    fprintf(FINFO,"skipping non-regular file %s\n",fname);
     return;
   }
 
@@ -481,7 +483,7 @@ void recv_generator(char *fname,struct file_list *flist,int i,int f_out)
 
   if (update_only && st.st_mtime > file->modtime) {
     if (verbose > 1)
-      fprintf(FERROR,"%s is newer\n",fname);
+      fprintf(FINFO,"%s is newer\n",fname);
     return;
   }
 
@@ -517,12 +519,12 @@ void recv_generator(char *fname,struct file_list *flist,int i,int f_out)
   }
 
   if (verbose > 3)
-    fprintf(FERROR,"gen mapped %s of size %d\n",fname,(int)st.st_size);
+    fprintf(FINFO,"gen mapped %s of size %d\n",fname,(int)st.st_size);
 
   s = generate_sums(buf,st.st_size,adapt_block_size(file, block_size));
 
   if (verbose > 2)
-    fprintf(FERROR,"sending sums for %d\n",i);
+    fprintf(FINFO,"sending sums for %d\n",i);
 
   write_int(f_out,i);
   send_sums(s,f_out);
@@ -555,7 +557,7 @@ static int receive_data(int f_in,struct map_struct *buf,int fd,char *fname)
   for (i=recv_token(f_in,&data); i != 0; i=recv_token(f_in,&data)) {
     if (i > 0) {
       if (verbose > 3)
-       fprintf(FERROR,"data recv %d at %d\n",i,(int)offset);
+       fprintf(FINFO,"data recv %d at %d\n",i,(int)offset);
 
       sum_update(data,i);
 
@@ -572,7 +574,7 @@ static int receive_data(int f_in,struct map_struct *buf,int fd,char *fname)
        len = remainder;
 
       if (verbose > 3)
-       fprintf(FERROR,"chunk[%d] of size %d at %d offset=%d\n",
+       fprintf(FINFO,"chunk[%d] of size %d at %d offset=%d\n",
                i,len,(int)offset2,(int)offset);
 
       map = map_ptr(buf,offset2,len);
@@ -598,7 +600,7 @@ static int receive_data(int f_in,struct map_struct *buf,int fd,char *fname)
   if (remote_version >= 14) {
     read_buf(f_in,file_sum2,MD4_SUM_LENGTH);
     if (verbose > 2)
-      fprintf(FERROR,"got file_sum\n");
+      fprintf(FINFO,"got file_sum\n");
     if (fd != -1 && memcmp(file_sum1,file_sum2,MD4_SUM_LENGTH) != 0)
       return 0;
   }
@@ -612,14 +614,14 @@ static void delete_one(struct file_struct *f)
     if (do_unlink(f_name(f)) != 0) {
       fprintf(FERROR,"unlink %s : %s\n",f_name(f),strerror(errno));
     } else if (verbose) {
-      fprintf(FERROR,"deleting %s\n",f_name(f));
+      fprintf(FINFO,"deleting %s\n",f_name(f));
     }
   } else {    
     if (do_rmdir(f_name(f)) != 0) {
       if (errno != ENOTEMPTY)
        fprintf(FERROR,"rmdir %s : %s\n",f_name(f),strerror(errno));
     } else if (verbose) {
-      fprintf(FERROR,"deleting directory %s\n",f_name(f));      
+      fprintf(FINFO,"deleting directory %s\n",f_name(f));      
     }
   }
 }
@@ -691,6 +693,11 @@ static void delete_files(struct file_list *flist)
   if (cvs_exclude)
     add_cvs_excludes();
 
+  if (io_error) {
+         fprintf(FINFO,"IO error encountered - skipping file deletion\n");
+         return;
+  }
+
   for (j=0;j<flist->count;j++) {
          char *name = f_name(flist->files[j]);
 
@@ -746,7 +753,7 @@ int recv_files(int f_in,struct file_list *flist,char *local_name,int f_gen)
   int recv_ok;
 
   if (verbose > 2) {
-    fprintf(FERROR,"recv_files(%d) starting\n",flist->count);
+    fprintf(FINFO,"recv_files(%d) starting\n",flist->count);
   }
 
   if (recurse && delete_mode && !local_name && flist->count>0) {
@@ -761,7 +768,7 @@ int recv_files(int f_in,struct file_list *flist,char *local_name,int f_gen)
          phase++;
          csum_length = SUM_LENGTH;
          if (verbose > 2)
-           fprintf(FERROR,"recv_files phase=%d\n",phase);
+           fprintf(FINFO,"recv_files phase=%d\n",phase);
          write_int(f_gen,-1);
          write_flush(f_gen);
          continue;
@@ -782,7 +789,7 @@ int recv_files(int f_in,struct file_list *flist,char *local_name,int f_gen)
       }
 
       if (verbose > 2)
-       fprintf(FERROR,"recv_files(%s)\n",fname);
+       fprintf(FINFO,"recv_files(%s)\n",fname);
 
       /* open the file */  
       fd1 = open(fname,O_RDONLY);
@@ -804,7 +811,7 @@ int recv_files(int f_in,struct file_list *flist,char *local_name,int f_gen)
       if (fd1 != -1 && st.st_size > 0) {
        buf = map_file(fd1,st.st_size);
        if (verbose > 2)
-         fprintf(FERROR,"recv mapped %s of size %d\n",fname,(int)st.st_size);
+         fprintf(FINFO,"recv mapped %s of size %d\n",fname,(int)st.st_size);
       } else {
        buf = NULL;
       }
@@ -862,7 +869,7 @@ int recv_files(int f_in,struct file_list *flist,char *local_name,int f_gen)
       close(fd2);
 
       if (verbose > 2)
-       fprintf(FERROR,"renaming %s to %s\n",fnametmp,fname);
+       fprintf(FINFO,"renaming %s to %s\n",fnametmp,fname);
 
       if (make_backups) {
        char fnamebak[MAXPATHLEN];
@@ -907,7 +914,7 @@ int recv_files(int f_in,struct file_list *flist,char *local_name,int f_gen)
                              fname);
              } else {
                      if (verbose > 1)
-                             fprintf(FERROR,"redoing %s(%d)\n",fname,i);
+                             fprintf(FINFO,"redoing %s(%d)\n",fname,i);
                      write_int(f_gen,i);
              }
       }
@@ -925,7 +932,7 @@ int recv_files(int f_in,struct file_list *flist,char *local_name,int f_gen)
   }
 
   if (verbose > 2)
-    fprintf(FERROR,"recv_files finished\n");
+    fprintf(FINFO,"recv_files finished\n");
   
   return 0;
 }
@@ -945,7 +952,7 @@ void send_files(struct file_list *flist,int f_out,int f_in)
   int offset=0;
 
   if (verbose > 2)
-    fprintf(FERROR,"send_files starting\n");
+    fprintf(FINFO,"send_files starting\n");
 
   setup_nonblocking(f_in,f_out);
 
@@ -958,7 +965,7 @@ void send_files(struct file_list *flist,int f_out,int f_in)
                          write_int(f_out,-1);
                          write_flush(f_out);
                          if (verbose > 2)
-                                 fprintf(FERROR,"send_files phase=%d\n",phase);
+                                 fprintf(FINFO,"send_files phase=%d\n",phase);
                          continue;
                  }
                  break;
@@ -971,6 +978,7 @@ void send_files(struct file_list *flist,int f_out,int f_in)
                  strncpy(fname,file->basedir,MAXPATHLEN-1);
                  fname[MAXPATHLEN-1] = 0;
                  if (strlen(fname) == MAXPATHLEN-1) {
+                         io_error = 1;
                          fprintf(FERROR, "send_files failed on long-named directory %s\n",
                                  fname);
                          return;
@@ -981,7 +989,7 @@ void send_files(struct file_list *flist,int f_out,int f_in)
          strncat(fname,f_name(file),MAXPATHLEN-strlen(fname));
          
          if (verbose > 2) 
-                 fprintf(FERROR,"send_files(%d,%s)\n",i,fname);
+                 fprintf(FINFO,"send_files(%d,%s)\n",i,fname);
          
          if (dry_run) {        
                  if (!am_server && verbose)
@@ -992,12 +1000,14 @@ void send_files(struct file_list *flist,int f_out,int f_in)
 
          s = receive_sums(f_in);
          if (!s) {
+                 io_error = 1;
                  fprintf(FERROR,"receive_sums failed\n");
                  return;
          }
          
          fd = open(fname,O_RDONLY);
          if (fd == -1) {
+                 io_error = 1;
                  fprintf(FERROR,"send_files failed to open %s: %s\n",
                          fname,strerror(errno));
                  free_sums(s);
@@ -1006,6 +1016,7 @@ void send_files(struct file_list *flist,int f_out,int f_in)
          
          /* map the local file */
          if (fstat(fd,&st) != 0) {
+                 io_error = 1;
                  fprintf(FERROR,"fstat failed : %s\n",strerror(errno));
                  free_sums(s);
                  close(fd);
@@ -1019,7 +1030,7 @@ void send_files(struct file_list *flist,int f_out,int f_in)
          }
          
          if (verbose > 2)
-                 fprintf(FERROR,"send_files mapped %s of size %d\n",
+                 fprintf(FINFO,"send_files mapped %s of size %d\n",
                          fname,(int)st.st_size);
          
          write_int(f_out,i);
@@ -1029,7 +1040,7 @@ void send_files(struct file_list *flist,int f_out,int f_in)
          write_int(f_out,s->remainder);
          
          if (verbose > 2)
-                 fprintf(FERROR,"calling match_sums %s\n",fname);
+                 fprintf(FINFO,"calling match_sums %s\n",fname);
          
          if (!am_server && verbose)
                  printf("%s\n",fname+offset);
@@ -1043,11 +1054,11 @@ void send_files(struct file_list *flist,int f_out,int f_in)
          free_sums(s);
          
          if (verbose > 2)
-                 fprintf(FERROR,"sender finished %s\n",fname);
+                 fprintf(FINFO,"sender finished %s\n",fname);
   }
 
   if (verbose > 2)
-         fprintf(FERROR,"send files finished\n");
+         fprintf(FINFO,"send files finished\n");
 
   match_report();
 
@@ -1063,7 +1074,7 @@ void generate_files(int f,struct file_list *flist,char *local_name,int f_recv)
   int phase=0;
 
   if (verbose > 2)
-    fprintf(FERROR,"generator starting pid=%d count=%d\n",
+    fprintf(FINFO,"generator starting pid=%d count=%d\n",
            (int)getpid(),flist->count);
 
   for (i = 0; i < flist->count; i++) {
@@ -1089,11 +1100,15 @@ void generate_files(int f,struct file_list *flist,char *local_name,int f_recv)
   ignore_times=1;
 
   if (verbose > 2)
-    fprintf(FERROR,"generate_files phase=%d\n",phase);
+    fprintf(FINFO,"generate_files phase=%d\n",phase);
 
   write_int(f,-1);
   write_flush(f);
 
+  /* we expect to just sit around now, so don't exit on a timeout. If we
+     really get a timeout then the other process should exit */
+  io_timeout = 0;
+
   if (remote_version >= 13) {
     /* in newer versions of the protocol the files can cycle through
        the system more than once to catch initial checksum errors */
@@ -1105,7 +1120,7 @@ void generate_files(int f,struct file_list *flist,char *local_name,int f_recv)
 
     phase++;
     if (verbose > 2)
-      fprintf(FERROR,"generate_files phase=%d\n",phase);
+      fprintf(FINFO,"generate_files phase=%d\n",phase);
 
     write_int(f,-1);
     write_flush(f);
@@ -1113,7 +1128,7 @@ void generate_files(int f,struct file_list *flist,char *local_name,int f_recv)
 
 
   if (verbose > 2)
-    fprintf(FERROR,"generator wrote %ld\n",(long)write_total());
+    fprintf(FINFO,"generator wrote %ld\n",(long)write_total());
 }
 
 
diff --git a/rsync.h b/rsync.h
index 8de94ce..a669276 100644 (file)
--- a/rsync.h
+++ b/rsync.h
@@ -39,9 +39,9 @@
 #define SAME_TIME (1<<7)
 
 /* update this if you make incompatible changes */
-#define PROTOCOL_VERSION 16
+#define PROTOCOL_VERSION 17
 #define MIN_PROTOCOL_VERSION 11
-#define MAX_PROTOCOL_VERSION 20
+#define MAX_PROTOCOL_VERSION 30
 
 #define SPARSE_WRITE_SIZE (4*1024)
 #define WRITE_SIZE (32*1024)