heaps of cleanup in the io code.
[rsync/rsync.git] / rsync.c
diff --git a/rsync.c b/rsync.c
index 9d11b72..555c009 100644 (file)
--- a/rsync.c
+++ b/rsync.c
@@ -111,10 +111,7 @@ static int delete_file(char *fname)
                if (strcmp(dname,".")==0 ||
                    strcmp(dname,"..")==0)
                        continue;
-               strlcpy(buf, fname, (MAXPATHLEN-strlen(dname))-2);
-               strcat(buf, "/");
-               strcat(buf, dname);
-               buf[MAXPATHLEN-1] = 0;
+               slprintf(buf, sizeof(buf)-1, "%s/%s", fname, dname);
                if (verbose > 0)
                        rprintf(FINFO,"deleting %s\n", buf);
                if (delete_file(buf) != 0) {
@@ -150,7 +147,6 @@ static void send_sums(struct sum_struct *s,int f_out)
       write_int(f_out,s->sums[i].sum1);
       write_buf(f_out,s->sums[i].sum2,csum_length);
     }
-  write_flush(f_out);
 }
 
 
@@ -270,6 +266,7 @@ static int set_perms(char *fname,struct file_struct *file,STRUCT_STAT *st,
 {
   int updated = 0;
   STRUCT_STAT st2;
+  extern int am_daemon;
 
   if (dry_run) return 0;
 
@@ -303,8 +300,9 @@ static int set_perms(char *fname,struct file_struct *file,STRUCT_STAT *st,
   }
 #endif
 
-  if ((am_root && preserve_uid && st->st_uid != file->uid) || 
-      (preserve_gid && st->st_gid != file->gid)) {
+  if ((am_root || !am_daemon) &&
+      ((am_root && preserve_uid && st->st_uid != file->uid) || 
+       (preserve_gid && st->st_gid != file->gid))) {
          if (do_lchown(fname,
                        (am_root&&preserve_uid)?file->uid:-1,
                        preserve_gid?file->gid:-1) != 0) {
@@ -529,7 +527,6 @@ void recv_generator(char *fname,struct file_list *flist,int i,int f_out)
 
   write_int(f_out,i);
   send_sums(s,f_out);
-  write_flush(f_out);
 
   close(fd);
   if (buf) unmap_file(buf);
@@ -697,7 +694,8 @@ static void delete_files(struct file_list *flist)
                if (!S_ISDIR(flist->files[j]->mode) || 
                    !(flist->files[j]->flags & FLAG_DELETE)) continue;
 
-               if (delete_already_done(flist, j)) continue;
+               if (remote_version < 19 &&
+                   delete_already_done(flist, j)) continue;
 
                name = strdup(f_name(flist->files[j]));
 
@@ -711,7 +709,8 @@ static void delete_files(struct file_list *flist)
 
                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))
+                       if (remote_version < 19 &&
+                           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]);
@@ -726,6 +725,7 @@ static char *cleanup_fname;
 
 void exit_cleanup(int code)
 {
+       io_flush();
        if (cleanup_fname)
                do_unlink(cleanup_fname);
        signal(SIGUSR1, SIG_IGN);
@@ -771,7 +771,6 @@ int recv_files(int f_in,struct file_list *flist,char *local_name,int f_gen)
          if (verbose > 2)
            rprintf(FINFO,"recv_files phase=%d\n",phase);
          write_int(f_gen,-1);
-         write_flush(f_gen);
          continue;
        }
        break;
@@ -831,8 +830,10 @@ int recv_files(int f_in,struct file_list *flist,char *local_name,int f_gen)
                      close(fd1);
                      continue;
              }
-             sprintf(fnametmp,"%s/.%s.XXXXXX",tmpdir,f);
+             slprintf(fnametmp,sizeof(fnametmp)-1, "%s/.%s.XXXXXX",tmpdir,f);
       } else {
+             char *f = strrchr(fname,'/');
+
              if (strlen(fname)+9 > MAXPATHLEN) {
                      rprintf(FERROR,"filename too long\n");
                      if (buf) unmap_file(buf);
@@ -840,7 +841,13 @@ int recv_files(int f_in,struct file_list *flist,char *local_name,int f_gen)
                      continue;
              }
 
-             sprintf(fnametmp,".%s.XXXXXX",fname);
+             if (f) {
+                     *f = 0;
+                     slprintf(fnametmp,sizeof(fnametmp)-1,"%s/.%s.XXXXXX",fname,f+1);
+                     *f = '/';
+             } else {
+                     slprintf(fnametmp,sizeof(fnametmp)-1,".%s.XXXXXX",fname);
+             }
       }
       if (NULL == do_mktemp(fnametmp)) {
        rprintf(FERROR,"mktemp %s failed\n",fnametmp);
@@ -885,7 +892,7 @@ int recv_files(int f_in,struct file_list *flist,char *local_name,int f_gen)
                rprintf(FERROR,"backup filename too long\n");
                continue;
        }
-       sprintf(fnamebak,"%s%s",fname,backup_suffix);
+       slprintf(fnamebak,sizeof(fnamebak)-1,"%s%s",fname,backup_suffix);
        if (do_rename(fname,fnamebak) != 0 && errno != ENOENT) {
          rprintf(FERROR,"rename %s %s : %s\n",fname,fnamebak,strerror(errno));
          continue;
@@ -934,7 +941,7 @@ int recv_files(int f_in,struct file_list *flist,char *local_name,int f_gen)
   /* now we need to fix any directory permissions that were 
      modified during the transfer */
   for (i = 0; i < flist->count; i++) {
-         struct file_struct *file = flist->files[i];
+         file = flist->files[i];
          if (!file->basename || !S_ISDIR(file->mode)) continue;
          recv_generator(f_name(file),flist,i,-1);
   }
@@ -962,7 +969,7 @@ void send_files(struct file_list *flist,int f_out,int f_in)
   if (verbose > 2)
     rprintf(FINFO,"send_files starting\n");
 
-  setup_nonblocking(f_in,f_out);
+  setup_readbuffer(f_in);
 
   while (1) {
          i = read_int(f_in);
@@ -971,7 +978,6 @@ void send_files(struct file_list *flist,int f_out,int f_in)
                          phase++;
                          csum_length = SUM_LENGTH;
                          write_int(f_out,-1);
-                         write_flush(f_out);
                          if (verbose > 2)
                                  rprintf(FINFO,"send_files phase=%d\n",phase);
                          continue;
@@ -990,10 +996,10 @@ void send_files(struct file_list *flist,int f_out,int f_in)
                                  fname);
                          return;
                  }
-                 strcat(fname,"/");
+                 strlcat(fname,"/",MAXPATHLEN-1);
                  offset = strlen(file->basedir)+1;
          }
-         strncat(fname,f_name(file),MAXPATHLEN-strlen(fname));
+         strlcat(fname,f_name(file),MAXPATHLEN-strlen(fname));
          
          if (verbose > 2) 
                  rprintf(FINFO,"send_files(%d,%s)\n",i,fname);
@@ -1053,7 +1059,6 @@ void send_files(struct file_list *flist,int f_out,int f_in)
                  printf("%s\n",fname+offset);
          
          match_sums(f_out,s,buf,st.st_size);
-         write_flush(f_out);
          
          if (buf) unmap_file(buf);
          close(fd);
@@ -1070,7 +1075,6 @@ void send_files(struct file_list *flist,int f_out,int f_in)
   match_report();
 
   write_int(f_out,-1);
-  write_flush(f_out);
 }
 
 
@@ -1110,7 +1114,6 @@ void generate_files(int f,struct file_list *flist,char *local_name,int f_recv)
     rprintf(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 */
@@ -1130,7 +1133,6 @@ void generate_files(int f,struct file_list *flist,char *local_name,int f_recv)
       rprintf(FINFO,"generate_files phase=%d\n",phase);
 
     write_int(f,-1);
-    write_flush(f);
   }