sender.c

The sender gets checksums from the generator, calculates deltas, and transmits them to the receiver. [詳細]

ソースコードを見る。


関数

static struct sum_structreceive_sums (int f)
 Receive the checksums for a buffer
void successful_send (int ndx)
static void write_ndx_and_attrs (int f_out, int ndx, int iflags, uchar fnamecmp_type, char *buf, int len)
int read_item_attrs (int f_in, int f_out, int ndx, uchar *type_ptr, char *buf, int *len_ptr)
void send_files (struct file_list *flist, int f_out, int f_in)

変数

int verbose
int do_xfers
int am_server
int am_daemon
int log_before_transfer
int log_format_has_i
int daemon_log_format_has_i
int csum_length
int append_mode
int io_error
int allowed_lull
int protocol_version
int remove_sent_files
int updating_basis_file
int make_backups
int do_progress
int inplace
int batch_fd
int write_batch
stats stats
file_listthe_file_list
char * log_format

説明

The sender gets checksums from the generator, calculates deltas, and transmits them to the receiver.

The sender process runs on the machine holding the source files.

sender.c で定義されています。


関数

static struct sum_struct* receive_sums ( int  f  )  [static]

Receive the checksums for a buffer

sender.c57 行で定義されています。

参照先 allowed_lullappend_modesum_struct::blengthsum_struct::countFINFOsum_buf::flagssum_struct::flengthsum_buf::lenmaybe_send_keepalive()sum_buf::offsetout_of_memory()read_buf()read_int()read_sum_head()sum_struct::remainderrprintf()sum_struct::s2lengthsum_buf::sum1sum_buf::sum2sum_struct::sumsverbose.

参照元 send_files().

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 }

void successful_send ( int  ndx  ) 

sender.c118 行で定義されています。

参照先 file_list::countfile_struct::dirdo_unlink()f_name()file_list::filesFINFOfile_struct::flagsfile_struct::moderemove_sent_filesfile_struct::rootrprintf()stringjoin()the_file_listverbose.

参照元 readfd_unbuffered().

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         /* The generator might tell us about symlinks we didn't send. */
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 }

static void write_ndx_and_attrs ( int  f_out,
int  ndx,
int  iflags,
uchar  fnamecmp_type,
char *  buf,
int  len 
) [static]

sender.c141 行で定義されています。

参照先 protocol_versionwrite_byte()write_int()write_shortint()write_vstring().

参照元 read_item_attrs()send_files().

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 }

int read_item_attrs ( int  f_in,
int  f_out,
int  ndx,
uchar *  type_ptr,
char *  buf,
int *  len_ptr 
)

sender.c155 行で定義されています。

参照先 file_list::countFERRORfile_list::filesfile_struct::modeprotocol_versionread_byte()read_shortint()read_vstring()rprintf()the_file_listwho_am_i()write_ndx_and_attrs().

参照元 recv_files()send_files().

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         /* Handle the new keep-alive (no-op) packet. */
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 }

void send_files ( struct file_list flist,
int  f_out,
int  f_in 
)

sender.c204 行で定義されています。

参照先 am_daemonam_serverappend_modebatch_fdsum_struct::blengthcsum_lengthstats::current_file_indexdaemon_log_format_has_ifile_struct::dirdo_fstat()do_open()do_progressdo_xfersend_progress()errnof_name()FERRORfile_list::filesFINFOfree_sums()full_fname()inplaceio_errorfile_struct::lengthlog_before_transferlog_formatlog_format_has_ilog_item()make_backupsmap_file()match_report()match_sums()maybe_log_item()stats::num_transferred_filesphaseprotocol_versionread_int()read_item_attrs()receive_sums()file_struct::rootrprintf()rsyserr()set_compression()statsstrlcpy()stats::total_transferred_sizeunmap_file()updating_basis_fileverbosewho_am_i()write_batchwrite_int()write_ndx_and_attrs()write_sum_head().

参照元 client_run()do_server_sender().

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                         /* For inplace: redo phase turns off the backup
00238                          * flag so that we do a regular inplace send. */
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) /* no-op packet */
00247                         continue;
00248 
00249                 file = flist->files[i];
00250                 if (file->dir.root) {
00251                         /* N.B. We're sure that this fits, so offset is OK. */
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) { /* log the transfer */
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                 /* map the local file */
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                 /* Flag that we actually sent this entry. */
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 }


変数

int verbose

options.c163 行で定義されています。

int do_xfers

options.c61 行で定義されています。

int am_server

options.c75 行で定義されています。

int am_daemon

options.c94 行で定義されています。

int log_before_transfer

options.c165 行で定義されています。

参照元 recv_files()send_files().

int log_format_has_i

options.c166 行で定義されています。

int daemon_log_format_has_i

clientserver.c58 行で定義されています。

参照元 generate_files()recv_files()rsync_module()send_files()set_file_attrs()try_dests_non()try_dests_reg().

int csum_length

checksum.c22 行で定義されています。

参照元 generate_files()read_sum_head()recv_files()send_files()sum_sizes_sqroot().

int append_mode

options.c42 行で定義されています。

int io_error

flist.c72 行で定義されています。

int allowed_lull

options.c85 行で定義されています。

int protocol_version

mdfour.c209 行で定義されています。

int remove_sent_files

options.c68 行で定義されています。

int updating_basis_file

match.c27 行で定義されています。

参照元 hash_search()send_files().

int make_backups

options.c30 行で定義されています。

int do_progress

options.c97 行で定義されています。

int inplace

options.c116 行で定義されています。

int batch_fd

io.c63 行で定義されています。

参照元 do_cmd()handle_stats()main()readfd()send_files()start_write_batch()writefd().

int write_batch

options.c138 行で定義されています。

struct stats stats

log.c59 行で定義されています。

struct file_list* the_file_list

main.c66 行で定義されています。

char* log_format

options.c150 行で定義されています。


rsyncに対してSat Dec 5 19:45:45 2009に生成されました。  doxygen 1.4.7