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 do_xfers;
00024 extern int am_server;
00025 extern int am_daemon;
00026 extern int log_before_transfer;
00027 extern int log_format_has_i;
00028 extern int daemon_log_format_has_i;
00029 extern int csum_length;
00030 extern int append_mode;
00031 extern int io_error;
00032 extern int allowed_lull;
00033 extern int protocol_version;
00034 extern int remove_sent_files;
00035 extern int updating_basis_file;
00036 extern int make_backups;
00037 extern int do_progress;
00038 extern int inplace;
00039 extern int batch_fd;
00040 extern int write_batch;
00041 extern struct stats stats;
00042 extern struct file_list *the_file_list;
00043 extern char *log_format;
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057 static struct sum_struct *receive_sums(int f)
00058 {
00059 struct sum_struct *s;
00060 int32 i;
00061 int lull_mod = allowed_lull * 5;
00062 OFF_T offset = 0;
00063
00064 if (!(s = new(struct sum_struct)))
00065 out_of_memory("receive_sums");
00066
00067 read_sum_head(f, s);
00068
00069 s->sums = NULL;
00070
00071 if (verbose > 3) {
00072 rprintf(FINFO, "count=%.0f n=%ld rem=%ld\n",
00073 (double)s->count, (long)s->blength, (long)s->remainder);
00074 }
00075
00076 if (append_mode) {
00077 s->flength = (OFF_T)s->count * s->blength;
00078 if (s->remainder)
00079 s->flength -= s->blength - s->remainder;
00080 return s;
00081 }
00082
00083 if (s->count == 0)
00084 return(s);
00085
00086 if (!(s->sums = new_array(struct sum_buf, s->count)))
00087 out_of_memory("receive_sums");
00088
00089 for (i = 0; i < s->count; i++) {
00090 s->sums[i].sum1 = read_int(f);
00091 read_buf(f, s->sums[i].sum2, s->s2length);
00092
00093 s->sums[i].offset = offset;
00094 s->sums[i].flags = 0;
00095
00096 if (i == s->count-1 && s->remainder != 0)
00097 s->sums[i].len = s->remainder;
00098 else
00099 s->sums[i].len = s->blength;
00100 offset += s->sums[i].len;
00101
00102 if (allowed_lull && !(i % lull_mod))
00103 maybe_send_keepalive();
00104
00105 if (verbose > 3) {
00106 rprintf(FINFO,
00107 "chunk[%d] len=%d offset=%.0f sum1=%08x\n",
00108 i, s->sums[i].len, (double)s->sums[i].offset,
00109 s->sums[i].sum1);
00110 }
00111 }
00112
00113 s->flength = offset;
00114
00115 return s;
00116 }
00117
00118 void successful_send(int ndx)
00119 {
00120 char fname[MAXPATHLEN];
00121 struct file_struct *file;
00122 unsigned int offset;
00123
00124 if (ndx < 0 || ndx >= the_file_list->count)
00125 return;
00126
00127 file = the_file_list->files[ndx];
00128
00129 if (!(file->flags & FLAG_SENT) && !S_ISLNK(file->mode))
00130 return;
00131 if (file->dir.root) {
00132 offset = stringjoin(fname, sizeof fname,
00133 file->dir.root, "/", NULL);
00134 } else
00135 offset = 0;
00136 f_name(file, fname + offset);
00137 if (remove_sent_files && do_unlink(fname) == 0 && verbose > 1)
00138 rprintf(FINFO, "sender removed %s\n", fname + offset);
00139 }
00140
00141 static void write_ndx_and_attrs(int f_out, int ndx, int iflags,
00142 uchar fnamecmp_type, char *buf, int len)
00143 {
00144 write_int(f_out, ndx);
00145 if (protocol_version < 29)
00146 return;
00147 write_shortint(f_out, iflags);
00148 if (iflags & ITEM_BASIS_TYPE_FOLLOWS)
00149 write_byte(f_out, fnamecmp_type);
00150 if (iflags & ITEM_XNAME_FOLLOWS)
00151 write_vstring(f_out, buf, len);
00152 }
00153
00154
00155 int read_item_attrs(int f_in, int f_out, int ndx, uchar *type_ptr,
00156 char *buf, int *len_ptr)
00157 {
00158 int len;
00159 uchar fnamecmp_type = FNAMECMP_FNAME;
00160 int iflags = protocol_version >= 29 ? read_shortint(f_in)
00161 : ITEM_TRANSFER | ITEM_MISSING_DATA;
00162
00163
00164 if (ndx == the_file_list->count && iflags == ITEM_IS_NEW)
00165 ;
00166 else if (ndx < 0 || ndx >= the_file_list->count) {
00167 rprintf(FERROR, "Invalid file index: %d (count=%d) [%s]\n",
00168 ndx, the_file_list->count, who_am_i());
00169 exit_cleanup(RERR_PROTOCOL);
00170 } else if (iflags == ITEM_IS_NEW) {
00171 rprintf(FERROR, "Invalid itemized flag word: %x [%s]\n",
00172 iflags, who_am_i());
00173 exit_cleanup(RERR_PROTOCOL);
00174 }
00175
00176 if (iflags & ITEM_BASIS_TYPE_FOLLOWS)
00177 fnamecmp_type = read_byte(f_in);
00178 *type_ptr = fnamecmp_type;
00179
00180 if (iflags & ITEM_XNAME_FOLLOWS) {
00181 if ((len = read_vstring(f_in, buf, MAXPATHLEN)) < 0)
00182 exit_cleanup(RERR_PROTOCOL);
00183 } else {
00184 *buf = '\0';
00185 len = -1;
00186 }
00187 *len_ptr = len;
00188
00189 if (iflags & ITEM_TRANSFER) {
00190 if (!S_ISREG(the_file_list->files[ndx]->mode)) {
00191 rprintf(FERROR,
00192 "received request to transfer non-regular file: %d [%s]\n",
00193 ndx, who_am_i());
00194 exit_cleanup(RERR_PROTOCOL);
00195 }
00196 } else if (f_out >= 0) {
00197 write_ndx_and_attrs(f_out, ndx, iflags,
00198 fnamecmp_type, buf, len);
00199 }
00200
00201 return iflags;
00202 }
00203
00204 void send_files(struct file_list *flist, int f_out, int f_in)
00205 {
00206 int fd = -1;
00207 struct sum_struct *s;
00208 struct map_struct *mbuf = NULL;
00209 STRUCT_STAT st;
00210 char *fname2, fname[MAXPATHLEN];
00211 char xname[MAXPATHLEN];
00212 uchar fnamecmp_type;
00213 int iflags, xlen;
00214 struct file_struct *file;
00215 int phase = 0, max_phase = protocol_version >= 29 ? 2 : 1;
00216 struct stats initial_stats;
00217 int save_make_backups = make_backups;
00218 int itemizing = am_daemon ? daemon_log_format_has_i
00219 : !am_server && log_format_has_i;
00220 int f_xfer = write_batch < 0 ? batch_fd : f_out;
00221 int i, j;
00222
00223 if (verbose > 2)
00224 rprintf(FINFO, "send_files starting\n");
00225
00226 while (1) {
00227 unsigned int offset;
00228
00229 i = read_int(f_in);
00230 if (i == -1) {
00231 if (++phase > max_phase)
00232 break;
00233 csum_length = SUM_LENGTH;
00234 if (verbose > 2)
00235 rprintf(FINFO, "send_files phase=%d\n", phase);
00236 write_int(f_out, -1);
00237
00238
00239 make_backups = 0;
00240 append_mode = 0;
00241 continue;
00242 }
00243
00244 iflags = read_item_attrs(f_in, f_out, i, &fnamecmp_type,
00245 xname, &xlen);
00246 if (iflags == ITEM_IS_NEW)
00247 continue;
00248
00249 file = flist->files[i];
00250 if (file->dir.root) {
00251
00252 offset = strlcpy(fname, file->dir.root, sizeof fname);
00253 if (!offset || fname[offset-1] != '/')
00254 fname[offset++] = '/';
00255 } else
00256 offset = 0;
00257 fname2 = f_name(file, fname + offset);
00258
00259 if (verbose > 2)
00260 rprintf(FINFO, "send_files(%d, %s)\n", i, fname);
00261
00262 if (!(iflags & ITEM_TRANSFER)) {
00263 maybe_log_item(file, iflags, itemizing, xname);
00264 continue;
00265 }
00266 if (phase == 2) {
00267 rprintf(FERROR,
00268 "got transfer request in phase 2 [%s]\n",
00269 who_am_i());
00270 exit_cleanup(RERR_PROTOCOL);
00271 }
00272
00273 updating_basis_file = inplace && (protocol_version >= 29
00274 ? fnamecmp_type == FNAMECMP_FNAME : !make_backups);
00275
00276 stats.current_file_index = i;
00277 stats.num_transferred_files++;
00278 stats.total_transferred_size += file->length;
00279
00280 if (!do_xfers) {
00281 if (!am_server && log_format)
00282 log_item(file, &stats, iflags, NULL);
00283 write_ndx_and_attrs(f_out, i, iflags, fnamecmp_type,
00284 xname, xlen);
00285 continue;
00286 }
00287
00288 initial_stats = stats;
00289
00290 if (!(s = receive_sums(f_in))) {
00291 io_error |= IOERR_GENERAL;
00292 rprintf(FERROR, "receive_sums failed\n");
00293 return;
00294 }
00295
00296 fd = do_open(fname, O_RDONLY, 0);
00297 if (fd == -1) {
00298 if (errno == ENOENT) {
00299 enum logcode c = am_daemon
00300 && protocol_version < 28 ? FERROR
00301 : FINFO;
00302 io_error |= IOERR_VANISHED;
00303 rprintf(c, "file has vanished: %s\n",
00304 full_fname(fname));
00305 } else {
00306 io_error |= IOERR_GENERAL;
00307 rsyserr(FERROR, errno,
00308 "send_files failed to open %s",
00309 full_fname(fname));
00310 }
00311 free_sums(s);
00312 continue;
00313 }
00314
00315
00316 if (do_fstat(fd, &st) != 0) {
00317 io_error |= IOERR_GENERAL;
00318 rsyserr(FERROR, errno, "fstat failed");
00319 free_sums(s);
00320 close(fd);
00321 return;
00322 }
00323
00324 if (st.st_size) {
00325 int32 read_size = MAX(s->blength * 3, MAX_MAP_SIZE);
00326 mbuf = map_file(fd, st.st_size, read_size, s->blength);
00327 } else
00328 mbuf = NULL;
00329
00330 if (verbose > 2) {
00331 rprintf(FINFO, "send_files mapped %s of size %.0f\n",
00332 fname, (double)st.st_size);
00333 }
00334
00335 write_ndx_and_attrs(f_out, i, iflags, fnamecmp_type,
00336 xname, xlen);
00337 write_sum_head(f_xfer, s);
00338
00339 if (verbose > 2)
00340 rprintf(FINFO, "calling match_sums %s\n", fname);
00341
00342 if (log_before_transfer)
00343 log_item(file, &initial_stats, iflags, NULL);
00344 else if (!am_server && verbose && do_progress)
00345 rprintf(FINFO, "%s\n", fname2);
00346
00347 set_compression(fname);
00348
00349 match_sums(f_xfer, s, mbuf, st.st_size);
00350 if (do_progress)
00351 end_progress(st.st_size);
00352
00353 if (!log_before_transfer)
00354 log_item(file, &initial_stats, iflags, NULL);
00355
00356 if (mbuf) {
00357 j = unmap_file(mbuf);
00358 if (j) {
00359 io_error |= IOERR_GENERAL;
00360 rsyserr(FERROR, j,
00361 "read errors mapping %s",
00362 full_fname(fname));
00363 }
00364 }
00365 close(fd);
00366
00367 free_sums(s);
00368
00369 if (verbose > 2)
00370 rprintf(FINFO, "sender finished %s\n", fname);
00371
00372
00373 file->flags |= FLAG_SENT;
00374 }
00375 make_backups = save_make_backups;
00376
00377 if (verbose > 2)
00378 rprintf(FINFO, "send files finished\n");
00379
00380 match_report();
00381
00382 write_int(f_out, -1);
00383 }