00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
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
00033
00034
00035
00036
00037
00038
00039
00040
00041
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;
00106 extern int read_batch;
00107 int checksums_match;
00108 int buff_len;
00109 char buff[CHUNK_SIZE];
00110 int j;
00111 int done;
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
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) {
00230
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) {
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 }
00260 read_batch_delta_file( buff, MD4_SUM_LENGTH);
00261 write_buf(f_out, buff, MD4_SUM_LENGTH);
00262
00263 }
00264 } else {
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) {
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) {
00293 close_batch_csums_file();
00294 close_batch_delta_file();
00295 }
00296
00297 }
00298
00299
00300
00301
00302