finished 64 bit file offset support. Hopefully rsync can now transfer
authorAndrew Tridgell <tridge@samba.org>
Mon, 23 Mar 1998 12:52:57 +0000 (12:52 +0000)
committerAndrew Tridgell <tridge@samba.org>
Mon, 23 Mar 1998 12:52:57 +0000 (12:52 +0000)
files up to 2^64 bytes in size. Now I just need to find enough disk
space to test this :-)

The 64 bit offset code only works if off_t is 64 bits (or bigger!) on
both ends of the link. If one end tries to send a file greater than
2^31 in size and the other end doesn't support it then rsync will
abort.

This commit also cleans up some static declarations so they are in a
unitinitialised segment to save load time.

checksum.c
exclude.c
flist.c
hlink.c
io.c
main.c
match.c
rsync.c
rsync.h
token.c

index a7ee070..32299f0 100644 (file)
@@ -65,8 +65,8 @@ void get_checksum2(char *buf,int len,char *sum)
 {
   int i;
   MDstruct MD;
-  static char *buf1 = NULL;
-  static int len1 = 0;
+  static char *buf1;
+  static int len1;
 
   if (len > len1) {
     if (buf1) free(buf1);
index a55b2f6..139c0b4 100644 (file)
--- a/exclude.c
+++ b/exclude.c
@@ -25,7 +25,7 @@
 
 extern int verbose;
 
-static char **exclude_list = NULL;
+static char **exclude_list;
 
 static int is_regex(char *str)
 {
diff --git a/flist.c b/flist.c
index d53c815..94935f4 100644 (file)
--- a/flist.c
+++ b/flist.c
@@ -45,7 +45,7 @@ extern int relative_paths;
 extern int copy_links;
 extern int remote_version;
 
-static char **local_exclude_list = NULL;
+static char **local_exclude_list;
 
 int link_stat(const char *Path, struct stat *Buffer) 
 {
@@ -87,7 +87,7 @@ static void set_filesystem(char *fname)
 
 static void send_directory(int f,struct file_list *flist,char *dir);
 
-static char *flist_dir = NULL;
+static char *flist_dir;
 
 static void clean_fname(char *name)
 {
@@ -136,12 +136,12 @@ static void clean_fname(char *name)
 void send_file_entry(struct file_struct *file,int f)
 {
   unsigned char flags;
-  static time_t last_time=0;
-  static mode_t last_mode=0;
-  static dev_t last_rdev=0;
-  static uid_t last_uid=0;
-  static gid_t last_gid=0;
-  static char lastname[MAXPATHLEN]="";
+  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;
 
@@ -177,7 +177,7 @@ void send_file_entry(struct file_struct *file,int f)
     write_byte(f,l2);
   write_buf(f,fname+l1,l2);
 
-  write_int(f,(int)file->length);
+  write_longint(f,file->length);
   if (!(flags & SAME_TIME))
     write_int(f,(int)file->modtime);
   if (!(flags & SAME_MODE))
@@ -202,8 +202,8 @@ void send_file_entry(struct file_struct *file,int f)
 
 #if SUPPORT_HARD_LINKS
   if (preserve_hard_links && S_ISREG(file->mode)) {
-    write_int(f,file->dev);
-    write_int(f,file->inode);
+    write_int(f,(int)file->dev);
+    write_int(f,(int)file->inode);
   }
 #endif
 
@@ -226,11 +226,11 @@ void send_file_entry(struct file_struct *file,int f)
 void receive_file_entry(struct file_struct **fptr,
                        unsigned char flags,int f)
 {
-  static time_t last_time=0;
-  static mode_t last_mode=0;
-  static dev_t last_rdev=0;
-  static uid_t last_uid=0;
-  static gid_t last_gid=0;
+  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;
@@ -277,7 +277,7 @@ void receive_file_entry(struct file_struct **fptr,
   if (!file->basename) out_of_memory("receive_file_entry 1");
 
 
-  file->length = (off_t)read_int(f);
+  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)
diff --git a/hlink.c b/hlink.c
index 7360a02..a0db280 100644 (file)
--- a/hlink.c
+++ b/hlink.c
@@ -31,7 +31,7 @@ static int hlink_compare(struct file_struct *f1,struct file_struct *f2)
   if (!S_ISREG(f2->mode)) return 1;
 
   if (f1->dev != f2->dev) 
-    return (f1->dev - f2->dev);
+    return (int)(f1->dev - f2->dev);
 
   if (f1->inode != f2->inode) 
     return (f1->inode - f2->inode);
@@ -40,8 +40,8 @@ static int hlink_compare(struct file_struct *f1,struct file_struct *f2)
 }
 
 
-static struct file_struct *hlink_list = NULL;
-static int hlink_count=0;
+static struct file_struct *hlink_list;
+static int hlink_count;
 #endif
 
 void init_hard_links(struct file_list *flist)
diff --git a/io.c b/io.c
index 54ceb28..75127f0 100644 (file)
--- a/io.c
+++ b/io.c
   */
 #include "rsync.h"
 
-static int total_written = 0;
-static int total_read = 0;
+static off_t total_written;
+static off_t total_read;
 
 extern int verbose;
 extern int sparse_files;
 
-int write_total(void)
+off_t write_total(void)
 {
   return total_written;
 }
 
-int read_total(void)
+off_t read_total(void)
 {
   return total_read;
 }
@@ -49,10 +49,10 @@ void setup_nonblocking(int f_in,int f_out)
 }
 
 
-static char *read_buffer = NULL;
-static char *read_buffer_p = NULL;
-static int read_buffer_len = 0;
-static int read_buffer_size = 0;
+static char *read_buffer;
+static char *read_buffer_p;
+static int read_buffer_len;
+static int read_buffer_size;
 
 
 /* This function was added to overcome a deadlock problem when using
@@ -145,6 +145,29 @@ int read_int(int f)
   return IVAL(b,0);
 }
 
+off_t read_longint(int f)
+{
+       extern int remote_version;
+       off_t ret;
+       char b[8];
+       ret = read_int(f);
+       if (ret == -1 && remote_version >= 16) {
+               if (sizeof(off_t) <= 4) {
+                       fprintf(FERROR,"Integer overflow - attempted 64 bit offset\n");
+                       exit_cleanup(1);
+               }
+               if ((ret=readfd(f,b,8)) != 8) {
+                       if (verbose > 1) 
+                               fprintf(FERROR,"(%d) Error reading %d bytes : %s\n",
+                                       getpid(),8,ret==-1?strerror(errno):"EOF");
+                       exit_cleanup(1);
+               }
+               total_read += 8;
+               ret = IVAL(b,0) | (((off_t)IVAL(b,4))<<32);
+       }
+       return ret;
+}
+
 void read_buf(int f,char *buf,int len)
 {
   int ret;
@@ -165,8 +188,8 @@ unsigned char read_byte(int f)
 }
 
 
-static char last_byte=0;
-static int last_sparse = 0;
+static char last_byte;
+static int last_sparse;
 
 int sparse_end(int f)
 {
@@ -295,6 +318,29 @@ void write_int(int f,int x)
   total_written += 4;
 }
 
+void write_longint(int f, off_t x)
+{
+       extern int remote_version;
+       char b[8];
+       int ret;
+
+       if (remote_version < 16 || x <= 0x7FFFFFFF) {
+               write_int(f, (int)x);
+               return;
+       }
+
+       write_int(f, -1);
+       SIVAL(b,0,(x&0xFFFFFFFF));
+       SIVAL(b,4,((x>>32)&0xFFFFFFFF));
+
+       if ((ret=writefd(f,b,8)) != 8) {
+               fprintf(FERROR,"write_longint failed : %s\n",
+                       ret==-1?strerror(errno):"EOF");
+               exit_cleanup(1);
+       }
+       total_written += 8;
+}
+
 void write_buf(int f,char *buf,int len)
 {
   int ret;
diff --git a/main.c b/main.c
index 23a465c..08d0929 100644 (file)
--- a/main.c
+++ b/main.c
@@ -58,22 +58,22 @@ int numeric_ids = 0;
 extern int csum_length;
 
 int am_server = 0;
-static int sender = 0;
+static int sender;
 int recurse = 0;
 
 static void usage(FILE *f);
 
 static void report(int f)
 {
-  int in,out,tsize;
+  off_t in,out,tsize;
   time_t t = time(NULL);
   
   if (!verbose) return;
 
   if (am_server && sender) {
-    write_int(f,read_total());
-    write_int(f,write_total());
-    write_int(f,total_size);
+    write_longint(f,read_total());
+    write_longint(f,write_total());
+    write_longint(f,total_size);
     write_flush(f);
     return;
   }
@@ -81,17 +81,17 @@ static void report(int f)
   if (sender) {
     in = read_total();
     out = write_total();
-    tsize = (int)total_size;
+    tsize = total_size;
   } else {
-    in = read_int(f);
-    out = read_int(f);
-    tsize = read_int(f);
+    in = read_longint(f);
+    out = read_longint(f);
+    tsize = read_longint(f);
   }
 
-  printf("wrote %d bytes  read %d bytes  %g bytes/sec\n",
-        out,in,(in+out)/(0.5 + (t-starttime)));        
-  printf("total size is %d  speedup is %g\n",
-        tsize,(1.0*tsize)/(in+out));
+  printf("wrote %ld bytes  read %ld bytes  %g bytes/sec\n",
+        (long)out,(long)in,(in+out)/(0.5 + (t-starttime)));
+  printf("total size is %ld  speedup is %g\n",
+        (long)tsize,(1.0*tsize)/(in+out));
 }
 
 
@@ -359,7 +359,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 %d\n",read_total());
+      fprintf(FERROR,"receiver read %ld\n",(long)read_total());
     exit_cleanup(0);
   }
 
@@ -526,7 +526,7 @@ int main(int argc,char *argv[])
 
     /* we set a 0 umask so that correct file permissions can be
        carried across */
-    orig_umask = umask(0);
+    orig_umask = (int)umask(0);
 
     while ((opt = getopt_long(argc, argv, 
                              short_options, long_options, &option_index)) 
diff --git a/match.c b/match.c
index 86f4b3e..d5ceba3 100644 (file)
--- a/match.c
+++ b/match.c
@@ -36,10 +36,10 @@ static int tag_hits;
 static int matches;
 static int data_transfer;
 
-static int total_false_alarms=0;
-static int total_tag_hits=0;
-static int total_matches=0;
-static int total_data_transfer=0;
+static int total_false_alarms;
+static int total_tag_hits;
+static int total_matches;
+static off_t total_data_transfer;
 
 
 struct target {
@@ -47,9 +47,9 @@ struct target {
   int i;
 };
 
-static struct target *targets=NULL;
+static struct target *targets;
 
-static tag *tag_table = NULL;
+static tag *tag_table;
 
 #define gettag2(s1,s2) (((s1) + (s2)) & 0xFFFF)
 #define gettag(sum) gettag2((sum)&0xFFFF,(sum)>>16)
@@ -273,7 +273,7 @@ void match_report(void)
                return;
 
        fprintf(FINFO,
-               "total: matches=%d  tag_hits=%d  false_alarms=%d  data=%d\n",
+               "total: matches=%d  tag_hits=%d  false_alarms=%d  data=%ld\n",
                total_matches,total_tag_hits,
-               total_false_alarms,total_data_transfer);
+               total_false_alarms,(long)total_data_transfer);
 }
diff --git a/rsync.c b/rsync.c
index 5240530..7dab528 100644 (file)
--- a/rsync.c
+++ b/rsync.c
@@ -651,7 +651,7 @@ static void delete_files(struct file_list *flist)
   }
 }
 
-static char *cleanup_fname = NULL;
+static char *cleanup_fname;
 
 void exit_cleanup(int code)
 {
@@ -1053,7 +1053,7 @@ void generate_files(int f,struct file_list *flist,char *local_name,int f_recv)
 
 
   if (verbose > 2)
-    fprintf(FERROR,"generator wrote %d\n",write_total());
+    fprintf(FERROR,"generator wrote %ld\n",(long)write_total());
 }
 
 
diff --git a/rsync.h b/rsync.h
index cc349f1..9c0e24c 100644 (file)
--- a/rsync.h
+++ b/rsync.h
@@ -39,7 +39,7 @@
 #define SAME_TIME (1<<7)
 
 /* update this if you make incompatible changes */
-#define PROTOCOL_VERSION 15
+#define PROTOCOL_VERSION 16
 #define MIN_PROTOCOL_VERSION 11
 #define MAX_PROTOCOL_VERSION 20
 
diff --git a/token.c b/token.c
index 1aa107c..29978ce 100644 (file)
--- a/token.c
+++ b/token.c
@@ -26,8 +26,8 @@ extern int do_compression;
 /* non-compressing recv token */
 static int simple_recv_token(int f,char **data)
 {
-  static int residue = 0;
-  static char *buf = NULL;
+  static int residue;
+  static char *buf;
   int n;
 
   if (!buf) {
@@ -99,7 +99,7 @@ static int last_run_end;
 static z_stream tx_strm;
 
 /* Output buffer */
-static char *obuf = NULL;
+static char *obuf;
 
 /* Send a deflated token */
 static void
@@ -220,8 +220,8 @@ static int
 recv_deflated_token(int f, char **data)
 {
     int n, r, flag;
-    static int init_done = 0;
-    static int saved_flag = 0;
+    static int init_done;
+    static int saved_flag;
 
     for (;;) {
        switch (recv_state) {