preparing for release of 2.1.0
[rsync/rsync.git] / flist.c
diff --git a/flist.c b/flist.c
index 138894f..c33323e 100644 (file)
--- a/flist.c
+++ b/flist.c
 
 #include "rsync.h"
 
+extern struct stats stats;
+
 extern int csum_length;
 
 extern int verbose;
 extern int am_server;
 extern int always_checksum;
-extern int64 total_size;
 
 extern int cvs_exclude;
 
@@ -93,95 +94,95 @@ static char *flist_dir;
 
 void send_file_entry(struct file_struct *file,int f,unsigned base_flags)
 {
-  unsigned char flags;
-  static time_t last_time;
-  static mode_t last_mode;
-  static dev_t last_rdev;
-  static uid_t last_uid;
-  static gid_t last_gid;
-  static char lastname[MAXPATHLEN];
-  char *fname;
-  int l1,l2;
-
-  if (f == -1) return;
-
-  if (!file) {
-    write_byte(f,0);
-    return;
-  }
+       unsigned char flags;
+       static time_t last_time;
+       static mode_t last_mode;
+       static dev_t last_rdev;
+       static uid_t last_uid;
+       static gid_t last_gid;
+       static char lastname[MAXPATHLEN];
+       char *fname;
+       int l1,l2;
+
+       if (f == -1) return;
+
+       if (!file) {
+               write_byte(f,0);
+               return;
+       }
 
-  fname = f_name(file);
-
-  flags = base_flags;
-
-  if (file->mode == last_mode) flags |= SAME_MODE;
-  if (file->rdev == last_rdev) flags |= SAME_RDEV;
-  if (file->uid == last_uid) flags |= SAME_UID;
-  if (file->gid == last_gid) flags |= SAME_GID;
-  if (file->modtime == last_time) flags |= SAME_TIME;
-
-  for (l1=0;lastname[l1] && (fname[l1] == lastname[l1]) && (l1 < 255);l1++) ;  
-  l2 = strlen(fname) - l1;
-
-  if (l1 > 0) flags |= SAME_NAME;
-  if (l2 > 255) flags |= LONG_NAME;
-
-  /* we must make sure we don't send a zero flags byte or the other
-     end will terminate the flist transfer */
-  if (flags == 0 && !S_ISDIR(file->mode)) flags |= FLAG_DELETE;
-  if (flags == 0) flags |= LONG_NAME;
-
-  write_byte(f,flags);  
-  if (flags & SAME_NAME)
-    write_byte(f,l1);
-  if (flags & LONG_NAME)
-    write_int(f,l2);
-  else
-    write_byte(f,l2);
-  write_buf(f,fname+l1,l2);
-
-  write_longint(f,file->length);
-  if (!(flags & SAME_TIME))
-    write_int(f,(int)file->modtime);
-  if (!(flags & SAME_MODE))
-    write_int(f,(int)file->mode);
-  if (preserve_uid && !(flags & SAME_UID)) {
-         add_uid(file->uid);
-         write_int(f,(int)file->uid);
-  }
-  if (preserve_gid && !(flags & SAME_GID)) {
-         add_gid(file->gid);
-         write_int(f,(int)file->gid);
-  }
-  if (preserve_devices && IS_DEVICE(file->mode) && !(flags & SAME_RDEV))
-    write_int(f,(int)file->rdev);
+       fname = f_name(file);
+
+       flags = base_flags;
+
+       if (file->mode == last_mode) flags |= SAME_MODE;
+       if (file->rdev == last_rdev) flags |= SAME_RDEV;
+       if (file->uid == last_uid) flags |= SAME_UID;
+       if (file->gid == last_gid) flags |= SAME_GID;
+       if (file->modtime == last_time) flags |= SAME_TIME;
+
+       for (l1=0;lastname[l1] && (fname[l1] == lastname[l1]) && (l1 < 255);l1++) ;  
+       l2 = strlen(fname) - l1;
+
+       if (l1 > 0) flags |= SAME_NAME;
+       if (l2 > 255) flags |= LONG_NAME;
+
+       /* we must make sure we don't send a zero flags byte or the other
+          end will terminate the flist transfer */
+       if (flags == 0 && !S_ISDIR(file->mode)) flags |= FLAG_DELETE;
+       if (flags == 0) flags |= LONG_NAME;
+
+       write_byte(f,flags);  
+       if (flags & SAME_NAME)
+               write_byte(f,l1);
+       if (flags & LONG_NAME)
+               write_int(f,l2);
+       else
+               write_byte(f,l2);
+       write_buf(f,fname+l1,l2);
+
+       write_longint(f,file->length);
+       if (!(flags & SAME_TIME))
+               write_int(f,(int)file->modtime);
+       if (!(flags & SAME_MODE))
+               write_int(f,(int)file->mode);
+       if (preserve_uid && !(flags & SAME_UID)) {
+               add_uid(file->uid);
+               write_int(f,(int)file->uid);
+       }
+       if (preserve_gid && !(flags & SAME_GID)) {
+               add_gid(file->gid);
+               write_int(f,(int)file->gid);
+       }
+       if (preserve_devices && IS_DEVICE(file->mode) && !(flags & SAME_RDEV))
+               write_int(f,(int)file->rdev);
 
 #if SUPPORT_LINKS
-  if (preserve_links && S_ISLNK(file->mode)) {
-    write_int(f,strlen(file->link));
-    write_buf(f,file->link,strlen(file->link));
-  }
+       if (preserve_links && S_ISLNK(file->mode)) {
+               write_int(f,strlen(file->link));
+               write_buf(f,file->link,strlen(file->link));
+       }
 #endif
 
 #if SUPPORT_HARD_LINKS
-  if (preserve_hard_links && S_ISREG(file->mode)) {
-    write_int(f,(int)file->dev);
-    write_int(f,(int)file->inode);
-  }
+       if (preserve_hard_links && S_ISREG(file->mode)) {
+               write_int(f,(int)file->dev);
+               write_int(f,(int)file->inode);
+       }
 #endif
 
-  if (always_checksum) {
-         write_buf(f,file->sum,csum_length);
-  }       
+       if (always_checksum) {
+               write_buf(f,file->sum,csum_length);
+       }       
 
-  last_mode = file->mode;
-  last_rdev = file->rdev;
-  last_uid = file->uid;
-  last_gid = file->gid;
-  last_time = file->modtime;
+       last_mode = file->mode;
+       last_rdev = file->rdev;
+       last_uid = file->uid;
+       last_gid = file->gid;
+       last_time = file->modtime;
 
-  strlcpy(lastname,fname,MAXPATHLEN-1);
-  lastname[MAXPATHLEN-1] = 0;
+       strlcpy(lastname,fname,MAXPATHLEN-1);
+       lastname[MAXPATHLEN-1] = 0;
 }
 
 
@@ -189,101 +190,108 @@ void send_file_entry(struct file_struct *file,int f,unsigned base_flags)
 static void receive_file_entry(struct file_struct **fptr,
                               unsigned flags,int f)
 {
-  static time_t last_time;
-  static mode_t last_mode;
-  static dev_t last_rdev;
-  static uid_t last_uid;
-  static gid_t last_gid;
-  static char lastname[MAXPATHLEN];
-  char thisname[MAXPATHLEN];
-  int l1=0,l2=0;
-  char *p;
-  struct file_struct *file;
+       static time_t last_time;
+       static mode_t last_mode;
+       static dev_t last_rdev;
+       static uid_t last_uid;
+       static gid_t last_gid;
+       static char lastname[MAXPATHLEN];
+       char thisname[MAXPATHLEN];
+       int l1=0,l2=0;
+       char *p;
+       struct file_struct *file;
 
-  if (flags & SAME_NAME)
-    l1 = read_byte(f);
+       if (flags & SAME_NAME)
+               l1 = read_byte(f);
   
-  if (flags & LONG_NAME)
-    l2 = read_int(f);
-  else
-    l2 = read_byte(f);
+       if (flags & LONG_NAME)
+               l2 = read_int(f);
+       else
+               l2 = read_byte(f);
 
-  file = (struct file_struct *)malloc(sizeof(*file));
-  if (!file) out_of_memory("receive_file_entry");
-  bzero((char *)file,sizeof(*file));
-  (*fptr) = file;
+       file = (struct file_struct *)malloc(sizeof(*file));
+       if (!file) out_of_memory("receive_file_entry");
+       memset((char *)file, 0, sizeof(*file));
+       (*fptr) = file;
 
-  if (l2 >= MAXPATHLEN-l1) overflow("receive_file_entry");
+       if (l2 >= MAXPATHLEN-l1) overflow("receive_file_entry");
 
-  strlcpy(thisname,lastname,l1);
-  read_sbuf(f,&thisname[l1],l2);
-  thisname[l1+l2] = 0;
+       strlcpy(thisname,lastname,l1);
+       read_sbuf(f,&thisname[l1],l2);
+       thisname[l1+l2] = 0;
 
-  strlcpy(lastname,thisname,MAXPATHLEN-1);
-  lastname[MAXPATHLEN-1] = 0;
+       strlcpy(lastname,thisname,MAXPATHLEN-1);
+       lastname[MAXPATHLEN-1] = 0;
 
-  clean_fname(thisname);
+       clean_fname(thisname);
 
-  if (relative_paths && thisname[0] == '/') {
-         /* strip / off absolute paths in destination */
-         memmove(thisname, thisname+1, strlen(thisname));
-         if (!thisname[0]) strcpy(thisname,".");
-  }
+       if (relative_paths && thisname[0] == '/') {
+               /* strip / off absolute paths in destination */
+               memmove(thisname, thisname+1, strlen(thisname));
+               if (!thisname[0]) strcpy(thisname,".");
+       }
 
-  if ((p = strrchr(thisname,'/'))) {
-         static char *lastdir;
-         *p = 0;
-         if (lastdir && strcmp(thisname, lastdir)==0) {
-                 file->dirname = lastdir;
-         } else {
-                 file->dirname = strdup(thisname);
-                 lastdir = file->dirname;
-         }
-         file->basename = strdup(p+1);
-  } else {
-         file->dirname = NULL;
-         file->basename = strdup(thisname);
-  }
+       if ((p = strrchr(thisname,'/'))) {
+               static char *lastdir;
+               *p = 0;
+               if (lastdir && strcmp(thisname, lastdir)==0) {
+                       file->dirname = lastdir;
+               } else {
+                       file->dirname = strdup(thisname);
+                       lastdir = file->dirname;
+               }
+               file->basename = strdup(p+1);
+       } else {
+               file->dirname = NULL;
+               file->basename = strdup(thisname);
+       }
 
-  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);
-  if (preserve_uid)
-    file->uid = (flags & SAME_UID) ? last_uid : (uid_t)read_int(f);
-  if (preserve_gid)
-    file->gid = (flags & SAME_GID) ? last_gid : (gid_t)read_int(f);
-  if (preserve_devices && IS_DEVICE(file->mode))
-    file->rdev = (flags & SAME_RDEV) ? last_rdev : (dev_t)read_int(f);
-
-  if (preserve_links && S_ISLNK(file->mode)) {
-    int l = read_int(f);
-    file->link = (char *)malloc(l+1);
-    if (!file->link) out_of_memory("receive_file_entry 2");
-    read_sbuf(f,file->link,l);
-  }
+       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);
+       if (preserve_uid)
+               file->uid = (flags & SAME_UID) ? last_uid : (uid_t)read_int(f);
+       if (preserve_gid)
+               file->gid = (flags & SAME_GID) ? last_gid : (gid_t)read_int(f);
+       if (preserve_devices && IS_DEVICE(file->mode))
+               file->rdev = (flags & SAME_RDEV) ? last_rdev : (dev_t)read_int(f);
+
+       if (preserve_links && S_ISLNK(file->mode)) {
+               int l = read_int(f);
+               file->link = (char *)malloc(l+1);
+               if (!file->link) out_of_memory("receive_file_entry 2");
+               read_sbuf(f,file->link,l);
+       }
 
 #if SUPPORT_HARD_LINKS
-  if (preserve_hard_links && S_ISREG(file->mode)) {
-    file->dev = read_int(f);
-    file->inode = read_int(f);
-  }
+       if (preserve_hard_links && S_ISREG(file->mode)) {
+               file->dev = read_int(f);
+               file->inode = read_int(f);
+       }
 #endif
   
-  if (always_checksum) {
-         file->sum = (char *)malloc(MD4_SUM_LENGTH);
-         if (!file->sum) out_of_memory("md4 sum");
-         read_buf(f,file->sum,csum_length);
-  }
+       if (always_checksum) {
+               file->sum = (char *)malloc(MD4_SUM_LENGTH);
+               if (!file->sum) out_of_memory("md4 sum");
+               read_buf(f,file->sum,csum_length);
+       }
   
-  last_mode = file->mode;
-  last_rdev = file->rdev;
-  last_uid = file->uid;
-  last_gid = file->gid;
-  last_time = file->modtime;
+       last_mode = file->mode;
+       last_rdev = file->rdev;
+       last_uid = file->uid;
+       last_gid = file->gid;
+       last_time = file->modtime;
+
+       if (!preserve_perms) {
+               extern int orig_umask;
+               /* set an appropriate set of permissions based on original
+                  permissions and umask. This emulates what GNU cp does */
+               file->mode &= ~orig_umask;
+       }
 }
 
 
@@ -324,7 +332,7 @@ static struct file_struct *make_file(char *fname)
        clean_fname(cleaned_name);
        fname = cleaned_name;
 
-       bzero(sum,SUM_LENGTH);
+       memset(sum,0,SUM_LENGTH);
 
        if (link_stat(fname,&st) != 0) {
                io_error = 1;
@@ -351,7 +359,7 @@ static struct file_struct *make_file(char *fname)
        
        file = (struct file_struct *)malloc(sizeof(*file));
        if (!file) out_of_memory("make_file");
-       bzero((char *)file,sizeof(*file));
+       memset((char *)file,0,sizeof(*file));
 
        if ((p = strrchr(fname,'/'))) {
                static char *lastdir;
@@ -421,7 +429,7 @@ static struct file_struct *make_file(char *fname)
        }
 
        if (!S_ISDIR(st.st_mode))
-               total_size += st.st_size;
+               stats.total_size += st.st_size;
 
        return file;
 }
@@ -525,12 +533,15 @@ struct file_list *send_file_list(int f,int argc,char *argv[])
        char *p,*dir;
        char lastpath[MAXPATHLEN]="";
        struct file_list *flist;
+       int64 start_write;
 
        if (verbose && recurse && !am_server && f != -1) {
                rprintf(FINFO,"building file list ... ");
                rflush(FINFO);
        }
 
+       start_write = stats.total_written;
+
        flist = (struct file_list *)malloc(sizeof(flist[0]));
        if (!flist) out_of_memory("send_file_list");
 
@@ -651,6 +662,8 @@ struct file_list *send_file_list(int f,int argc,char *argv[])
 
        if (f != -1) {
                io_end_buffering(f);
+               stats.flist_size = stats.total_written - start_write;
+               stats.num_files = flist->count;
        }
 
        if (verbose > 2)
@@ -664,12 +677,15 @@ struct file_list *recv_file_list(int f)
 {
   struct file_list *flist;
   unsigned char flags;
+  int64 start_read;
 
   if (verbose && recurse && !am_server) {
     rprintf(FINFO,"receiving file list ... ");
     rflush(FINFO);
   }
 
+  start_read = stats.total_read;
+
   flist = (struct file_list *)malloc(sizeof(flist[0]));
   if (!flist)
     goto oom;
@@ -700,7 +716,7 @@ struct file_list *recv_file_list(int f)
     receive_file_entry(&flist->files[i],flags,f);
 
     if (S_ISREG(flist->files[i]->mode))
-      total_size += flist->files[i]->length;
+           stats.total_size += flist->files[i]->length;
 
     flist->count++;
 
@@ -731,6 +747,9 @@ struct file_list *recv_file_list(int f)
   if (verbose > 2)
     rprintf(FINFO,"recv_file_list done\n");
 
+  stats.flist_size = stats.total_read - start_read;
+  stats.num_files = flist->count;
+
   return flist;
 
 oom:
@@ -745,8 +764,8 @@ int file_compare(struct file_struct **f1,struct file_struct **f2)
        if (!(*f1)->basename) return -1;
        if (!(*f2)->basename) return 1;
        if ((*f1)->dirname == (*f2)->dirname)
-               return strcmp((*f1)->basename, (*f2)->basename);
-       return strcmp(f_name(*f1),f_name(*f2));
+               return u_strcmp((*f1)->basename, (*f2)->basename);
+       return u_strcmp(f_name(*f1),f_name(*f2));
 }
 
 
@@ -782,7 +801,7 @@ static void free_file(struct file_struct *file)
        if (file->basename) free(file->basename);
        if (file->link) free(file->link);
        if (file->sum) free(file->sum);
-       bzero((char *)file, sizeof(*file));
+       memset((char *)file, 0, sizeof(*file));
 }
 
 
@@ -796,9 +815,9 @@ void flist_free(struct file_list *flist)
                free_file(flist->files[i]);
                free(flist->files[i]);
        }       
-       bzero((char *)flist->files, sizeof(flist->files[0])*flist->count);
+       memset((char *)flist->files, 0, sizeof(flist->files[0])*flist->count);
        free(flist->files);
-       bzero((char *)flist, sizeof(*flist));
+       memset((char *)flist, 0, sizeof(*flist));
        free(flist);
 }