Main Page   Alphabetical List   Data Structures   File List   Data Fields   Globals   Related Pages  

sender.c

Go to the documentation of this file.
00001 /* 
00002    Copyright (C) Andrew Tridgell 1996
00003    Copyright (C) Paul Mackerras 1996
00004    
00005    This program is free software; you can redistribute it and/or modify
00006    it under the terms of the GNU General Public License as published by
00007    the Free Software Foundation; either version 2 of the License, or
00008    (at your option) any later version.
00009    
00010    This program is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013    GNU General Public License for more details.
00014    
00015    You should have received a copy of the GNU General Public License
00016    along with this program; if not, write to the Free Software
00017    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00018 */
00019 
00020 #include "rsync.h"
00021 
00022 extern int verbose;
00023 extern int remote_version;
00024 extern int csum_length;
00025 extern struct stats stats;
00026 extern int io_error;
00027 extern int dry_run;
00028 extern int am_server;
00029 
00030 
00031 /**
00032  * @file
00033  *
00034  * The sender gets checksums from the generator, calculates deltas,
00035  * and transmits them to the receiver.  The sender process runs on the
00036  * machine holding the source files.
00037  **/
00038 
00039 
00040 /**
00041  * Receive the checksums for a buffer
00042  **/
00043 static struct sum_struct *receive_sums(int f)
00044 {
00045         struct sum_struct *s;
00046         int i;
00047         OFF_T offset = 0;
00048 
00049         s = (struct sum_struct *)malloc(sizeof(*s));
00050         if (!s) out_of_memory("receive_sums");
00051 
00052         s->count = read_int(f);
00053         s->n = read_int(f);
00054         s->remainder = read_int(f);  
00055         s->sums = NULL;
00056 
00057         if (verbose > 3)
00058                 rprintf(FINFO,"count=%ld n=%ld rem=%ld\n",
00059                         (long) s->count, (long) s->n, (long) s->remainder);
00060 
00061         if (s->count == 0) 
00062                 return(s);
00063 
00064         s->sums = (struct sum_buf *)malloc(sizeof(s->sums[0])*s->count);
00065         if (!s->sums) out_of_memory("receive_sums");
00066 
00067         for (i=0; i < (int) s->count;i++) {
00068                 s->sums[i].sum1 = read_int(f);
00069                 read_buf(f,s->sums[i].sum2,csum_length);
00070 
00071                 s->sums[i].offset = offset;
00072                 s->sums[i].i = i;
00073 
00074                 if (i == (int) s->count-1 && s->remainder != 0) {
00075                         s->sums[i].len = s->remainder;
00076                 } else {
00077                         s->sums[i].len = s->n;
00078                 }
00079                 offset += s->sums[i].len;
00080 
00081                 if (verbose > 3)
00082                         rprintf(FINFO,"chunk[%d] len=%d offset=%.0f sum1=%08x\n",
00083                                 i,s->sums[i].len,(double)s->sums[i].offset,s->sums[i].sum1);
00084         }
00085 
00086         s->flength = offset;
00087 
00088         return s;
00089 }
00090 
00091 
00092 
00093 void send_files(struct file_list *flist,int f_out,int f_in)
00094 { 
00095         int fd = -1;
00096         struct sum_struct *s;
00097         struct map_struct *buf = NULL;
00098         STRUCT_STAT st;
00099         char fname[MAXPATHLEN];  
00100         int i;
00101         struct file_struct *file;
00102         int phase = 0;
00103         extern struct stats stats;              
00104         struct stats initial_stats;
00105         extern int write_batch;   /* dw */
00106         extern int read_batch;    /* dw */
00107         int checksums_match;   /* dw */
00108         int buff_len;  /* dw */
00109         char buff[CHUNK_SIZE];    /* dw */
00110         int j;   /* dw */
00111         int done;   /* dw */
00112 
00113         if (verbose > 2)
00114                 rprintf(FINFO,"send_files starting\n");
00115 
00116         while (1) {
00117                 int offset=0;
00118 
00119                 i = read_int(f_in);
00120                 if (i == -1) {
00121                         if (phase==0 && remote_version >= 13) {
00122                                 phase++;
00123                                 csum_length = SUM_LENGTH;
00124                                 write_int(f_out,-1);
00125                                 if (verbose > 2)
00126                                         rprintf(FINFO,"send_files phase=%d\n",phase);
00127                                 continue;
00128                         }
00129                         break;
00130                 }
00131 
00132                 if (i < 0 || i >= flist->count) {
00133                         rprintf(FERROR,"Invalid file index %d (count=%d)\n", 
00134                                 i, flist->count);
00135                         exit_cleanup(RERR_PROTOCOL);
00136                 }
00137 
00138                 file = flist->files[i];
00139 
00140                 stats.num_transferred_files++;
00141                 stats.total_transferred_size += file->length;
00142 
00143                 fname[0] = 0;
00144                 if (file->basedir) {
00145                         strlcpy(fname,file->basedir,MAXPATHLEN);
00146                         if (strlen(fname) == MAXPATHLEN-1) {
00147                                 io_error = 1;
00148                                 rprintf(FERROR, "send_files failed on long-named directory %s\n",
00149                                         fname);
00150                                 return;
00151                         }
00152                         strlcat(fname,"/",MAXPATHLEN);
00153                         offset = strlen(file->basedir)+1;
00154                 }
00155                 strlcat(fname,f_name(file),MAXPATHLEN);
00156           
00157                 if (verbose > 2) 
00158                         rprintf(FINFO,"send_files(%d,%s)\n",i,fname);
00159           
00160                 if (dry_run) {  
00161                         if (!am_server) {
00162                                 log_transfer(file, fname+offset);
00163                         }
00164                         write_int(f_out,i);
00165                         continue;
00166                 }
00167 
00168                 initial_stats = stats;
00169 
00170                 s = receive_sums(f_in);
00171                 if (!s) {
00172                         io_error = 1;
00173                         rprintf(FERROR,"receive_sums failed\n");
00174                         return;
00175                 }
00176 
00177                 if (write_batch)
00178                     write_batch_csum_info(&i,flist->count,s);
00179           
00180                 if (!read_batch) {
00181                         fd = do_open(fname, O_RDONLY, 0);
00182                         if (fd == -1) {
00183                                 io_error = 1;
00184                                 rprintf(FERROR,"send_files failed to open %s: %s\n",
00185                                         fname,strerror(errno));
00186                                 free_sums(s);
00187                                 continue;
00188                         }
00189           
00190                         /* map the local file */
00191                         if (do_fstat(fd,&st) != 0) {
00192                                 io_error = 1;
00193                                 rprintf(FERROR,"fstat failed : %s\n",strerror(errno));
00194                                 free_sums(s);
00195                                 close(fd);
00196                                 return;
00197                         }
00198           
00199                         if (st.st_size > 0) {
00200                                 buf = map_file(fd,st.st_size);
00201                         } else {
00202                                 buf = NULL;
00203                         }
00204           
00205                         if (verbose > 2)
00206                                 rprintf(FINFO,"send_files mapped %s of size %.0f\n",
00207                                         fname,(double)st.st_size);
00208 
00209                         write_int(f_out,i);
00210           
00211                         if (write_batch)
00212                                 write_batch_delta_file((char *)&i,sizeof(i));
00213 
00214                         write_int(f_out,s->count);
00215                         write_int(f_out,s->n);
00216                         write_int(f_out,s->remainder);
00217                 }
00218           
00219                 if (verbose > 2)
00220                         if (!read_batch)
00221                             rprintf(FINFO,"calling match_sums %s\n",fname);
00222           
00223                 if (!am_server) {
00224                         log_transfer(file, fname+offset);
00225                 }
00226 
00227                 set_compression(fname);
00228 
00229                 if (read_batch) { /* dw */
00230                    /* read checksums originally computed on sender side */
00231                    read_batch_csum_info(i, s, &checksums_match);
00232                    if (checksums_match) {
00233                        read_batch_delta_file( (char *) &j, sizeof(int) );
00234                        if (j != i) {    /* if flist index entries don't match*/ 
00235                           rprintf(FINFO,"index mismatch in send_files\n");
00236                           rprintf(FINFO,"read index = %d flist ndx = %d\n",j,i);
00237                           close_batch_delta_file();
00238                           close_batch_csums_file();
00239                           exit_cleanup(1);
00240                        }
00241                        else {
00242                          write_int(f_out,j);
00243                          write_int(f_out,s->count);
00244                          write_int(f_out,s->n);
00245                          write_int(f_out,s->remainder);
00246                          done=0;
00247                          while (!done) {
00248                             read_batch_delta_file( (char *) &buff_len, sizeof(int) );
00249                             write_int(f_out,buff_len);
00250                             if (buff_len == 0) {
00251                                done = 1;
00252                             }
00253                             else {
00254                                if (buff_len > 0) {
00255                                   read_batch_delta_file(buff, buff_len);
00256                                   write_buf(f_out,buff,buff_len);
00257                                }
00258                             }
00259                          }  /* end while  */
00260                          read_batch_delta_file( buff, MD4_SUM_LENGTH);
00261                          write_buf(f_out, buff, MD4_SUM_LENGTH);
00262 
00263                        }  /* j=i */
00264                    } else {  /* not checksum match */
00265                       rprintf (FINFO,"readbatch & checksums don't match\n");
00266                       rprintf (FINFO,"filename=%s is being skipped\n",
00267                                fname);
00268                       continue;
00269                    }
00270                 } else  {
00271                     match_sums(f_out,s,buf,st.st_size);
00272                     log_send(file, &initial_stats);
00273                 }
00274 
00275                 if (!read_batch) { /* dw */
00276                     if (buf) unmap_file(buf);
00277                     close(fd);
00278                 }
00279           
00280                 free_sums(s);
00281           
00282                 if (verbose > 2)
00283                         rprintf(FINFO,"sender finished %s\n",fname);
00284         }
00285 
00286         if (verbose > 2)
00287                 rprintf(FINFO,"send files finished\n");
00288 
00289         match_report();
00290 
00291         write_int(f_out,-1);
00292         if (write_batch || read_batch) { /* dw */
00293             close_batch_csums_file();
00294             close_batch_delta_file();
00295         }
00296 
00297 }
00298 
00299 
00300 
00301 
00302 

Generated on Tue Apr 16 12:37:37 2002 for rsync by doxygen1.2.15