From 3a6a366fc5ac1f418446128de50b4f2a174399fc Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 23 Mar 1998 12:52:57 +0000 Subject: [PATCH] finished 64 bit file offset support. Hopefully rsync can now transfer 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 | 4 ++-- exclude.c | 2 +- flist.c | 34 ++++++++++++++-------------- hlink.c | 6 ++--- io.c | 66 +++++++++++++++++++++++++++++++++++++++++++++--------- main.c | 30 ++++++++++++------------- match.c | 16 ++++++------- rsync.c | 4 ++-- rsync.h | 2 +- token.c | 10 ++++----- 10 files changed, 110 insertions(+), 64 deletions(-) diff --git a/checksum.c b/checksum.c index a7ee0707..32299f0c 100644 --- a/checksum.c +++ b/checksum.c @@ -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); diff --git a/exclude.c b/exclude.c index a55b2f62..139c0b43 100644 --- 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 d53c815f..94935f4b 100644 --- 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 7360a021..a0db2804 100644 --- 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 54ceb281..75127f01 100644 --- a/io.c +++ b/io.c @@ -24,18 +24,18 @@ */ #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 23a465c8..08d09298 100644 --- 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 86f4b3ee..d5ceba39 100644 --- 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 52405309..7dab5288 100644 --- 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 cc349f1a..9c0e24c7 100644 --- 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 1aa107c9..29978ce8 100644 --- 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) { -- 2.34.1