main.c

ソースコードを見る。


データ構造

struct  pid_status

関数

static void show_malloc_stats (void)
 If our C library can get malloc statistics, then show them to FINFO
pid_t wait_process (pid_t pid, int *status_ptr, int flags)
static void wait_process_with_flush (pid_t pid, int *exit_code_ptr)
static void handle_stats (int f)
static void output_summary (void)
static pid_t do_cmd (char *cmd, char *machine, char *user, char *path, int *f_in, int *f_out)
static char * get_local_name (struct file_list *flist, char *dest_path)
static void read_final_goodbye (int f_in, int f_out)
static void do_server_sender (int f_in, int f_out, int argc, char *argv[])
static int do_recv (int f_in, int f_out, struct file_list *flist, char *local_name)
static void do_server_recv (int f_in, int f_out, int argc, char *argv[])
int child_main (int argc, char *argv[])
void start_server (int f_in, int f_out, int argc, char *argv[])
int client_run (int f_in, int f_out, pid_t pid, int argc, char *argv[])
static int copy_argv (char *argv[])
static int start_client (int argc, char *argv[])
 Start a client for either type of remote connection.
static RETSIGTYPE sigusr1_handler (UNUSED(int val))
static RETSIGTYPE sigusr2_handler (UNUSED(int val))
RETSIGTYPE remember_children (UNUSED(int val))
const char * get_panic_action (void)
 This routine catches signals and tries to send them to gdb.
static RETSIGTYPE rsync_panic_handler (UNUSED(int whatsig))
 Handle a fatal signal by launching a debugger, controlled by $RSYNC_PANIC_ACTION.
int main (int argc, char *argv[])

変数

int verbose
int dry_run
int list_only
int am_root
int am_server
int am_sender
int am_generator
int am_daemon
int blocking_io
int remove_sent_files
int daemon_over_rsh
int need_messages_from_generator
int kluge_around_eof
int do_stats
int log_got_error
int module_id
int copy_links
int copy_dirlinks
int keep_dirlinks
int preserve_hard_links
int protocol_version
int recurse
int relative_paths
int rsync_port
int whole_file
 If 1, send the whole file as literal data rather than trying to create an incremental diff.
int read_batch
int write_batch
int batch_fd
int batch_gen_fd
int filesfrom_fd
pid_t cleanup_child_pid
stats stats
char * filesfrom_host
char * rsync_path
char * shell_cmd
char * batch_name
int local_server = 0
mode_t orig_umask = 0
file_listthe_file_list
static struct sigaction sigact
pid_status pid_stat_table [MAXCHILDPROCS]
static time_t starttime
static time_t endtime
static int64 total_read
static int64 total_written

関数

static void show_malloc_stats ( void   )  [static]

If our C library can get malloc statistics, then show them to FINFO

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

参照先 am_daemonam_serverFINFOrprintf()who_am_i().

参照元 handle_stats().

00264 {
00265 #ifdef HAVE_MALLINFO
00266         struct mallinfo mi;
00267 
00268         mi = mallinfo();
00269 
00270         rprintf(FINFO, "\n" RSYNC_NAME "[%d] (%s%s%s) heap statistics:\n",
00271                 getpid(), am_server ? "server " : "",
00272                 am_daemon ? "daemon " : "", who_am_i());
00273         rprintf(FINFO, "  arena:     %10ld   (bytes from sbrk)\n",
00274                 (long)mi.arena);
00275         rprintf(FINFO, "  ordblks:   %10ld   (chunks not in use)\n",
00276                 (long)mi.ordblks);
00277         rprintf(FINFO, "  smblks:    %10ld\n",
00278                 (long)mi.smblks);
00279         rprintf(FINFO, "  hblks:     %10ld   (chunks from mmap)\n",
00280                 (long)mi.hblks);
00281         rprintf(FINFO, "  hblkhd:    %10ld   (bytes from mmap)\n",
00282                 (long)mi.hblkhd);
00283         rprintf(FINFO, "  allmem:    %10ld   (bytes from sbrk + mmap)\n",
00284                 (long)mi.arena + mi.hblkhd);
00285         rprintf(FINFO, "  usmblks:   %10ld\n",
00286                 (long)mi.usmblks);
00287         rprintf(FINFO, "  fsmblks:   %10ld\n",
00288                 (long)mi.fsmblks);
00289         rprintf(FINFO, "  uordblks:  %10ld   (bytes used)\n",
00290                 (long)mi.uordblks);
00291         rprintf(FINFO, "  fordblks:  %10ld   (bytes free)\n",
00292                 (long)mi.fordblks);
00293         rprintf(FINFO, "  keepcost:  %10ld   (bytes in releasable chunk)\n",
00294                 (long)mi.keepcost);
00295 #endif /* HAVE_MALLINFO */
00296 }

pid_t wait_process ( pid_t  pid,
int *  status_ptr,
int  flags 
)

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

参照先 errnopid_status::pidpid_stat_tablewaitpid().

参照元 _exit_cleanup()finish_pre_exec()rsync_module()wait_process_with_flush().

00094 {
00095         pid_t waited_pid = waitpid(pid, status_ptr, flags);
00096 
00097         if (waited_pid == -1 && errno == ECHILD) {
00098                 /* Status of requested child no longer available:  check to
00099                  * see if it was processed by remember_children(). */
00100                 int cnt;
00101                 for (cnt = 0; cnt < MAXCHILDPROCS; cnt++) {
00102                         if (pid == pid_stat_table[cnt].pid) {
00103                                 *status_ptr = pid_stat_table[cnt].status;
00104                                 pid_stat_table[cnt].pid = 0;
00105                                 return pid;
00106                         }
00107                 }
00108         }
00109 
00110         return waited_pid;
00111 }

static void wait_process_with_flush ( pid_t  pid,
int *  exit_code_ptr 
) [static]

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

参照先 errnoFERRORio_flush()msleep()rsyserr()wait_process().

参照元 client_run()do_recv().

00115 {
00116         pid_t waited_pid;
00117         int status;
00118 
00119         while ((waited_pid = wait_process(pid, &status, WNOHANG)) == 0) {
00120                 msleep(20);
00121                 io_flush(FULL_FLUSH);
00122         }
00123 
00124         /* TODO: If the child exited on a signal, then log an
00125          * appropriate error message.  Perhaps we should also accept a
00126          * message describing the purpose of the child.  Also indicate
00127          * this to the caller so that they know something went wrong. */
00128         if (waited_pid < 0) {
00129                 rsyserr(FERROR, errno, "waitpid");
00130                 *exit_code_ptr = RERR_WAITCHILD;
00131         } else if (!WIFEXITED(status)) {
00132 #ifdef WCOREDUMP
00133                 if (WCOREDUMP(status))
00134                         *exit_code_ptr = RERR_CRASHED;
00135                 else
00136 #endif
00137                 if (WIFSIGNALED(status))
00138                         *exit_code_ptr = RERR_TERMINATED;
00139                 else
00140                         *exit_code_ptr = RERR_WAITCHILD;
00141         } else
00142                 *exit_code_ptr = WEXITSTATUS(status);
00143 }

static void handle_stats ( int  f  )  [static]

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

参照先 am_daemonam_generatoram_senderam_serverbatch_fddo_statsendtimestats::flist_buildtimestats::flist_xfertimelog_exit()protocol_versionread_longint()show_flist_stats()show_malloc_stats()statsstats::total_readtotal_readstats::total_sizestats::total_writtentotal_writtenverbosewrite_batchwrite_longint().

参照元 client_run()do_recv()do_server_sender().

00154 {
00155         endtime = time(NULL);
00156 
00157         /* Cache two stats because the read/write code can change it. */
00158         total_read = stats.total_read;
00159         total_written = stats.total_written;
00160 
00161         if (do_stats && verbose > 1) {
00162                 /* These come out from every process */
00163                 show_malloc_stats();
00164                 show_flist_stats();
00165         }
00166 
00167         if (am_generator)
00168                 return;
00169 
00170         if (am_daemon) {
00171                 log_exit(0, __FILE__, __LINE__);
00172                 if (f == -1 || !am_sender)
00173                         return;
00174         }
00175 
00176         if (am_server) {
00177                 if (am_sender) {
00178                         write_longint(f, total_read);
00179                         write_longint(f, total_written);
00180                         write_longint(f, stats.total_size);
00181                         if (protocol_version >= 29) {
00182                                 write_longint(f, stats.flist_buildtime);
00183                                 write_longint(f, stats.flist_xfertime);
00184                         }
00185                 }
00186                 return;
00187         }
00188 
00189         /* this is the client */
00190 
00191         if (f < 0 && !am_sender) /* e.g. when we got an empty file list. */
00192                 ; 
00193         else if (!am_sender) {
00194                 /* Read the first two in opposite order because the meaning of
00195                  * read/write swaps when switching from sender to receiver. */
00196                 total_written = read_longint(f);
00197                 total_read = read_longint(f);
00198                 stats.total_size = read_longint(f);
00199                 if (protocol_version >= 29) {
00200                         stats.flist_buildtime = read_longint(f);
00201                         stats.flist_xfertime = read_longint(f);
00202                 }
00203         } else if (write_batch) {
00204                 /* The --read-batch process is going to be a client
00205                  * receiver, so we need to give it the stats. */
00206                 write_longint(batch_fd, total_read);
00207                 write_longint(batch_fd, total_written);
00208                 write_longint(batch_fd, stats.total_size);
00209                 if (protocol_version >= 29) {
00210                         write_longint(batch_fd, stats.flist_buildtime);
00211                         write_longint(batch_fd, stats.flist_xfertime);
00212                 }
00213         }
00214 }

static void output_summary ( void   )  [static]

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

参照先 do_statsendtimeFINFOstats::flist_buildtimestats::flist_sizestats::flist_xfertimehuman_dnum()human_num()stats::literal_datastats::matched_datastats::num_filesstats::num_transferred_filesrprintf()starttimestatstotal_readstats::total_sizestats::total_transferred_sizetotal_writtenverbose.

参照元 client_run()sigusr2_handler().

00217 {
00218         if (do_stats) {
00219                 rprintf(FINFO,"\nNumber of files: %d\n", stats.num_files);
00220                 rprintf(FINFO,"Number of files transferred: %d\n",
00221                         stats.num_transferred_files);
00222                 rprintf(FINFO,"Total file size: %s bytes\n",
00223                         human_num(stats.total_size));
00224                 rprintf(FINFO,"Total transferred file size: %s bytes\n",
00225                         human_num(stats.total_transferred_size));
00226                 rprintf(FINFO,"Literal data: %s bytes\n",
00227                         human_num(stats.literal_data));
00228                 rprintf(FINFO,"Matched data: %s bytes\n",
00229                         human_num(stats.matched_data));
00230                 rprintf(FINFO,"File list size: %d\n", stats.flist_size);
00231                 if (stats.flist_buildtime) {
00232                         rprintf(FINFO,
00233                                 "File list generation time: %.3f seconds\n",
00234                                 (double)stats.flist_buildtime / 1000);
00235                         rprintf(FINFO,
00236                                 "File list transfer time: %.3f seconds\n",
00237                                 (double)stats.flist_xfertime / 1000);
00238                 }
00239                 rprintf(FINFO,"Total bytes sent: %s\n",
00240                         human_num(total_written));
00241                 rprintf(FINFO,"Total bytes received: %s\n",
00242                         human_num(total_read));
00243         }
00244 
00245         if (verbose || do_stats) {
00246                 rprintf(FINFO,
00247                         "\nsent %s bytes  received %s bytes  %s bytes/sec\n",
00248                         human_num(total_written), human_num(total_read),
00249                         human_dnum((total_written + total_read)/(0.5 + (endtime - starttime)), 2));
00250                 rprintf(FINFO, "total size is %s  speedup is %.2f\n",
00251                         human_num(stats.total_size),
00252                         (double)stats.total_size / (total_written+total_read));
00253         }
00254 
00255         fflush(stdout);
00256         fflush(stderr);
00257 }

static pid_t do_cmd ( char *  cmd,
char *  machine,
char *  user,
char *  path,
int *  f_in,
int *  f_out 
) [static]

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

参照先 batch_fdbatch_gen_fdblocking_iochild_main()daemon_over_rsherrnofd_pair()FERRORFINFOlocal_child()local_serverout_of_memory()piped_child()read_batchrprintf()rsync_pathrsyserr()server_options()strdup()verbosewhole_filewrite_batch.

参照元 start_client().

00302 {
00303         int i, argc = 0;
00304         char *args[MAX_ARGS];
00305         pid_t ret;
00306         char *dir = NULL;
00307         int dash_l_set = 0;
00308 
00309         if (!read_batch && !local_server) {
00310                 char *t, *f, in_quote = '\0';
00311                 char *rsh_env = getenv(RSYNC_RSH_ENV);
00312                 if (!cmd)
00313                         cmd = rsh_env;
00314                 if (!cmd)
00315                         cmd = RSYNC_RSH;
00316                 cmd = strdup(cmd);
00317                 if (!cmd)
00318                         goto oom;
00319 
00320                 for (t = f = cmd; *f; f++) {
00321                         if (*f == ' ')
00322                                 continue;
00323                         /* Comparison leaves rooms for server_options(). */
00324                         if (argc >= MAX_ARGS - MAX_SERVER_ARGS) {
00325                                 rprintf(FERROR, "internal: args[] overflowed in do_cmd()\n");
00326                                 exit_cleanup(RERR_SYNTAX);
00327                         }
00328                         args[argc++] = t;
00329                         while (*f != ' ' || in_quote) {
00330                                 if (!*f) {
00331                                         if (in_quote) {
00332                                                 rprintf(FERROR,
00333                                                     "Missing trailing-%c in remote-shell command.\n",
00334                                                     in_quote);
00335                                                 exit_cleanup(RERR_SYNTAX);
00336                                         }
00337                                         f--;
00338                                         break;
00339                                 }
00340                                 if (*f == '\'' || *f == '"') {
00341                                         if (!in_quote) {
00342                                                 in_quote = *f++;
00343                                                 continue;
00344                                         }
00345                                         if (*f == in_quote && *++f != in_quote) {
00346                                                 in_quote = '\0';
00347                                                 continue;
00348                                         }
00349                                 }
00350                                 *t++ = *f++;
00351                         }
00352                         *t++ = '\0';
00353                 }
00354 
00355                 /* check to see if we've already been given '-l user' in
00356                  * the remote-shell command */
00357                 for (i = 0; i < argc-1; i++) {
00358                         if (!strcmp(args[i], "-l") && args[i+1][0] != '-')
00359                                 dash_l_set = 1;
00360                 }
00361 
00362 #ifdef HAVE_REMSH
00363                 /* remsh (on HPUX) takes the arguments the other way around */
00364                 args[argc++] = machine;
00365                 if (user && !(daemon_over_rsh && dash_l_set)) {
00366                         args[argc++] = "-l";
00367                         args[argc++] = user;
00368                 }
00369 #else
00370                 if (user && !(daemon_over_rsh && dash_l_set)) {
00371                         args[argc++] = "-l";
00372                         args[argc++] = user;
00373                 }
00374                 args[argc++] = machine;
00375 #endif
00376 
00377                 args[argc++] = rsync_path;
00378 
00379                 if (blocking_io < 0) {
00380                         char *cp;
00381                         if ((cp = strrchr(cmd, '/')) != NULL)
00382                                 cp++;
00383                         else
00384                                 cp = cmd;
00385                         if (strcmp(cp, "rsh") == 0 || strcmp(cp, "remsh") == 0)
00386                                 blocking_io = 1;
00387                 }
00388 
00389                 server_options(args,&argc);
00390 
00391                 if (argc >= MAX_ARGS - 2) {
00392                         rprintf(FERROR, "internal: args[] overflowed in do_cmd()\n");
00393                         exit_cleanup(RERR_SYNTAX);
00394                 }
00395         }
00396 
00397         args[argc++] = ".";
00398 
00399         if (!daemon_over_rsh && path && *path)
00400                 args[argc++] = path;
00401 
00402         args[argc] = NULL;
00403 
00404         if (verbose > 3) {
00405                 for (i = 0; i < argc; i++)
00406                         rprintf(FINFO, "cmd[%d]=%s ", i, args[i]);
00407                 rprintf(FINFO, "\n");
00408         }
00409 
00410         if (read_batch) {
00411                 int from_gen_pipe[2];
00412                 if (fd_pair(from_gen_pipe) < 0) {
00413                         rsyserr(FERROR, errno, "pipe");
00414                         exit_cleanup(RERR_IPC);
00415                 }
00416                 batch_gen_fd = from_gen_pipe[0];
00417                 *f_out = from_gen_pipe[1];
00418                 *f_in = batch_fd;
00419                 ret = -1; /* no child pid */
00420         } else if (local_server) {
00421                 /* If the user didn't request --[no-]whole-file, force
00422                  * it on, but only if we're not batch processing. */
00423                 if (whole_file < 0 && !write_batch)
00424                         whole_file = 1;
00425                 ret = local_child(argc, args, f_in, f_out, child_main);
00426         } else
00427                 ret = piped_child(args,f_in,f_out);
00428 
00429         if (dir)
00430                 free(dir);
00431 
00432         return ret;
00433 
00434   oom:
00435         out_of_memory("do_cmd");
00436         return 0; /* not reached */
00437 }

static char* get_local_name ( struct file_list flist,
char *  dest_path 
) [static]

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

参照先 file_list::countdo_stat()dry_runerrnoFERRORfile_list::filesFINFOfull_fname()list_onlymkdir_defmode()file_struct::modepush_dir()rprintf()rsyserr()verbose.

参照元 client_run()do_server_recv().

00452 {
00453         STRUCT_STAT st;
00454         char *cp;
00455 
00456         if (verbose > 2) {
00457                 rprintf(FINFO, "get_local_name count=%d %s\n",
00458                         flist->count, NS(dest_path));
00459         }
00460 
00461         if (!dest_path || list_only)
00462                 return NULL;
00463 
00464         /* If the destination path refers to an existing directory, enter
00465          * it and use mode 1.  If there is something other than a directory
00466          * at the destination path, we must be transferring one file
00467          * (anything at the destination will be overwritten). */
00468         if (do_stat(dest_path, &st) == 0) {
00469                 if (S_ISDIR(st.st_mode)) {
00470                         if (!push_dir(dest_path)) {
00471                                 rsyserr(FERROR, errno, "push_dir#1 %s failed",
00472                                         full_fname(dest_path));
00473                                 exit_cleanup(RERR_FILESELECT);
00474                         }
00475                         return NULL;
00476                 }
00477                 if (flist->count > 1) {
00478                         rprintf(FERROR,
00479                                 "ERROR: destination must be a directory when"
00480                                 " copying more than 1 file\n");
00481                         exit_cleanup(RERR_FILESELECT);
00482                 }
00483                 /* Caution: flist->count could be 0! */
00484                 if (flist->count == 1 && S_ISDIR(flist->files[0]->mode)) {
00485                         rprintf(FERROR,
00486                                 "ERROR: cannot overwrite non-directory"
00487                                 " with a directory\n");
00488                         exit_cleanup(RERR_FILESELECT);
00489                 }
00490         } else if (errno != ENOENT) {
00491                 rsyserr(FERROR, errno, "cannot stat destination %s",
00492                         full_fname(dest_path));
00493                 exit_cleanup(RERR_FILESELECT);
00494         }
00495 
00496         cp = strrchr(dest_path, '/');
00497 
00498         /* If the destination path ends in a slash or we are transferring
00499          * multiple files, create a directory at the destination path,
00500          * enter the new directory, and use mode 1. */
00501         if (flist->count > 1 || (cp && !cp[1])) {
00502                 /* Lop off the final slash (if any). */
00503                 if (cp && !cp[1])
00504                         *cp = '\0';
00505 
00506                 if (mkdir_defmode(dest_path) != 0) {
00507                         rsyserr(FERROR, errno, "mkdir %s failed",
00508                                 full_fname(dest_path));
00509                         exit_cleanup(RERR_FILEIO);
00510                 }
00511 
00512                 if (verbose)
00513                         rprintf(FINFO, "created directory %s\n", dest_path);
00514 
00515                 if (dry_run) {
00516                         /* Indicate that the destination directory doesn't
00517                          * really exist and return mode 1. */
00518                         dry_run++;
00519                         return NULL;
00520                 }
00521 
00522                 if (!push_dir(dest_path)) {
00523                         rsyserr(FERROR, errno, "push_dir#2 %s failed",
00524                                 full_fname(dest_path));
00525                         exit_cleanup(RERR_FILESELECT);
00526                 }
00527 
00528                 return NULL;
00529         }
00530 
00531         /* Otherwise, we are writing a single file, possibly on top of an
00532          * existing non-directory.  Change to the item's parent directory
00533          * (if it has a path component), return the basename of the
00534          * destination file as the local name, and use mode 2. */
00535         if (!cp)
00536                 return dest_path;
00537 
00538         if (cp == dest_path)
00539                 dest_path = "/";
00540 
00541         *cp = '\0';
00542         if (!push_dir(dest_path)) {
00543                 rsyserr(FERROR, errno, "push_dir#3 %s failed",
00544                         full_fname(dest_path));
00545                 exit_cleanup(RERR_FILESELECT);
00546         }
00547         *cp = '/';
00548 
00549         return cp + 1;
00550 }

static void read_final_goodbye ( int  f_in,
int  f_out 
) [static]

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

参照先 file_list::countFERRORprotocol_versionread_int()read_shortint()rprintf()the_file_listwho_am_i()write_int()write_shortint().

参照元 client_run()do_server_sender().

00555 {
00556         int i;
00557 
00558         if (protocol_version < 29)
00559                 i = read_int(f_in);
00560         else {
00561                 while ((i = read_int(f_in)) == the_file_list->count
00562                     && read_shortint(f_in) == ITEM_IS_NEW) {
00563                         /* Forward the keep-alive (no-op) to the receiver. */
00564                         write_int(f_out, the_file_list->count);
00565                         write_shortint(f_out, ITEM_IS_NEW);
00566                 }
00567         }
00568 
00569         if (i != -1) {
00570                 rprintf(FERROR, "Invalid packet at end of run (%d) [%s]\n",
00571                         i, who_am_i());
00572                 exit_cleanup(RERR_PROTOCOL);
00573         }
00574 }

static void do_server_sender ( int  f_in,
int  f_out,
int  argc,
char *  argv[] 
) [static]

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

参照先 am_daemonfile_list::counterrnoFERRORFINFOfull_fname()handle_stats()io_flush()io_start_buffering_in()io_start_buffering_out()list_onlymodule_idprotocol_versionpush_dir()read_final_goodbye()recurserelative_pathsremove_sent_filesrprintf()rsyserr()send_file_list()send_files()the_file_listverbose.

参照元 start_server().

00578 {
00579         struct file_list *flist;
00580         char *dir = argv[0];
00581 
00582         if (verbose > 2) {
00583                 rprintf(FINFO, "server_sender starting pid=%ld\n",
00584                         (long)getpid());
00585         }
00586 
00587         if (am_daemon && lp_write_only(module_id)) {
00588                 rprintf(FERROR, "ERROR: module is write only\n");
00589                 exit_cleanup(RERR_SYNTAX);
00590                 return;
00591         }
00592         if (am_daemon && lp_read_only(module_id) && remove_sent_files) {
00593                 rprintf(FERROR,
00594                     "ERROR: --remove-sent-files cannot be used with a read-only module\n");
00595                 exit_cleanup(RERR_SYNTAX);
00596                 return;
00597         }
00598 
00599         if (!relative_paths && !push_dir(dir)) {
00600                 rsyserr(FERROR, errno, "push_dir#3 %s failed",
00601                         full_fname(dir));
00602                 exit_cleanup(RERR_FILESELECT);
00603         }
00604         argc--;
00605         argv++;
00606 
00607         if (argc == 0 && (recurse || list_only)) {
00608                 argc = 1;
00609                 argv--;
00610                 argv[0] = ".";
00611         }
00612 
00613         flist = send_file_list(f_out,argc,argv);
00614         if (!flist || flist->count == 0) {
00615                 exit_cleanup(0);
00616         }
00617         the_file_list = flist;
00618 
00619         io_start_buffering_in();
00620         io_start_buffering_out();
00621 
00622         send_files(flist,f_out,f_in);
00623         io_flush(FULL_FLUSH);
00624         handle_stats(f_out);
00625         if (protocol_version >= 24)
00626                 read_final_goodbye(f_in, f_out);
00627         io_flush(FULL_FLUSH);
00628         exit_cleanup(0);
00629 }

static int do_recv ( int  f_in,
int  f_out,
struct file_list flist,
char *  local_name 
) [static]

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

参照先 am_generatoram_serverclose_multiplexing_in()close_multiplexing_out()copy_dirlinkscopy_linksfile_list::countdo_fork()errnofd_pair()FERRORgenerate_files()handle_stats()init_hard_links()io_flush()io_start_buffering_out()kluge_around_eofMSG_DONEmsleep()preserve_hard_linksprotocol_versionread_int()read_shortint()recv_files()rprintf()rsyserr()send_msg()set_msg_fd_in()set_msg_fd_out()stop_write_batch()wait_process_with_flush()who_am_i()write_batchwrite_int().

参照元 client_run()do_server_recv().

00633 {
00634         int pid;
00635         int exit_code = 0;
00636         int error_pipe[2];
00637 
00638         /* The receiving side mustn't obey this, or an existing symlink that
00639          * points to an identical file won't be replaced by the referent. */
00640         copy_links = copy_dirlinks = 0;
00641 
00642         if (preserve_hard_links)
00643                 init_hard_links();
00644 
00645         if (fd_pair(error_pipe) < 0) {
00646                 rsyserr(FERROR, errno, "pipe failed in do_recv");
00647                 exit_cleanup(RERR_IPC);
00648         }
00649 
00650         io_flush(NORMAL_FLUSH);
00651 
00652         if ((pid = do_fork()) == -1) {
00653                 rsyserr(FERROR, errno, "fork failed in do_recv");
00654                 exit_cleanup(RERR_IPC);
00655         }
00656 
00657         if (pid == 0) {
00658                 close(error_pipe[0]);
00659                 if (f_in != f_out)
00660                         close(f_out);
00661 
00662                 /* we can't let two processes write to the socket at one time */
00663                 close_multiplexing_out();
00664 
00665                 /* set place to send errors */
00666                 set_msg_fd_out(error_pipe[1]);
00667 
00668                 recv_files(f_in, flist, local_name);
00669                 io_flush(FULL_FLUSH);
00670                 handle_stats(f_in);
00671 
00672                 send_msg(MSG_DONE, "", 0);
00673                 io_flush(FULL_FLUSH);
00674 
00675                 /* Handle any keep-alive packets from the post-processing work
00676                  * that the generator does. */
00677                 if (protocol_version >= 29) {
00678                         kluge_around_eof = -1;
00679 
00680                         /* This should only get stopped via a USR2 signal. */
00681                         while (read_int(f_in) == flist->count
00682                             && read_shortint(f_in) == ITEM_IS_NEW) {}
00683 
00684                         rprintf(FERROR, "Invalid packet at end of run [%s]\n",
00685                                 who_am_i());
00686                         exit_cleanup(RERR_PROTOCOL);
00687                 }
00688 
00689                 /* Finally, we go to sleep until our parent kills us with a
00690                  * USR2 signal.  We sleep for a short time, as on some OSes
00691                  * a signal won't interrupt a sleep! */
00692                 while (1)
00693                         msleep(20);
00694         }
00695 
00696         am_generator = 1;
00697         close_multiplexing_in();
00698         if (write_batch && !am_server)
00699                 stop_write_batch();
00700 
00701         close(error_pipe[1]);
00702         if (f_in != f_out)
00703                 close(f_in);
00704 
00705         io_start_buffering_out();
00706 
00707         set_msg_fd_in(error_pipe[0]);
00708 
00709         generate_files(f_out, flist, local_name);
00710 
00711         handle_stats(-1);
00712         io_flush(FULL_FLUSH);
00713         if (protocol_version >= 24) {
00714                 /* send a final goodbye message */
00715                 write_int(f_out, -1);
00716         }
00717         io_flush(FULL_FLUSH);
00718 
00719         set_msg_fd_in(-1);
00720         kill(pid, SIGUSR2);
00721         wait_process_with_flush(pid, &exit_code);
00722         return exit_code;
00723 }

static void do_server_recv ( int  f_in,
int  f_out,
int  argc,
char *  argv[] 
) [static]

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

参照先 am_daemondo_recv()errnoFERRORfilesfrom_fdFINFOfull_fname()get_local_name()io_set_filesfrom_fds()io_start_buffering_in()module_idpush_dir()recv_file_list()recv_filter_list()rprintf()rsyserr()the_file_listverbose.

参照元 start_server().

00727 {
00728         int exit_code;
00729         struct file_list *flist;
00730         char *local_name = NULL;
00731         char *dir = NULL;
00732         int save_verbose = verbose;
00733 
00734         if (filesfrom_fd >= 0) {
00735                 /* We can't mix messages with files-from data on the socket,
00736                  * so temporarily turn off verbose messages. */
00737                 verbose = 0;
00738         }
00739 
00740         if (verbose > 2) {
00741                 rprintf(FINFO, "server_recv(%d) starting pid=%ld\n",
00742                         argc, (long)getpid());
00743         }
00744 
00745         if (am_daemon && lp_read_only(module_id)) {
00746                 rprintf(FERROR,"ERROR: module is read only\n");
00747                 exit_cleanup(RERR_SYNTAX);
00748                 return;
00749         }
00750 
00751         if (argc > 0) {
00752                 dir = argv[0];
00753                 argc--;
00754                 argv++;
00755                 if (!am_daemon && !push_dir(dir)) {
00756                         rsyserr(FERROR, errno, "push_dir#4 %s failed",
00757                                 full_fname(dir));
00758                         exit_cleanup(RERR_FILESELECT);
00759                 }
00760         }
00761 
00762         io_start_buffering_in();
00763         recv_filter_list(f_in);
00764 
00765         if (filesfrom_fd >= 0) {
00766                 /* We need to send the files-from names to the sender at the
00767                  * same time that we receive the file-list from them, so we
00768                  * need the IO routines to automatically write out the names
00769                  * onto our f_out socket as we read the file-list.  This
00770                  * avoids both deadlock and extra delays/buffers. */
00771                 io_set_filesfrom_fds(filesfrom_fd, f_out);
00772                 filesfrom_fd = -1;
00773         }
00774 
00775         flist = recv_file_list(f_in);
00776         verbose = save_verbose;
00777         if (!flist) {
00778                 rprintf(FERROR,"server_recv: recv_file_list error\n");
00779                 exit_cleanup(RERR_FILESELECT);
00780         }
00781         the_file_list = flist;
00782 
00783         if (argc > 0)
00784                 local_name = get_local_name(flist,argv[0]);
00785 
00786         exit_code = do_recv(f_in,f_out,flist,local_name);
00787         exit_cleanup(exit_code);
00788 }

int child_main ( int  argc,
char *  argv[] 
)

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

参照先 start_server().

参照元 do_cmd()local_child().

00792 {
00793         start_server(STDIN_FILENO, STDOUT_FILENO, argc, argv);
00794         return 0;
00795 }

void start_server ( int  f_in,
int  f_out,
int  argc,
char *  argv[] 
)

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

参照先 am_senderdo_server_recv()do_server_sender()io_set_sock_fds()io_start_multiplex_in()io_start_multiplex_out()keep_dirlinksneed_messages_from_generatorprotocol_versionrecv_filter_list()set_nonblocking()setup_iconv()setup_protocol().

参照元 child_main()main()rsync_module().

00799 {
00800         set_nonblocking(f_in);
00801         set_nonblocking(f_out);
00802 
00803         io_set_sock_fds(f_in, f_out);
00804         setup_protocol(f_out, f_in);
00805 #if defined HAVE_ICONV_OPEN && defined HAVE_ICONV_H
00806         setup_iconv();
00807 #endif
00808 
00809         if (protocol_version >= 23)
00810                 io_start_multiplex_out();
00811 
00812         if (am_sender) {
00813                 keep_dirlinks = 0; /* Must be disabled on the sender. */
00814                 if (need_messages_from_generator)
00815                         io_start_multiplex_in();
00816 
00817                 recv_filter_list(f_in);
00818                 do_server_sender(f_in, f_out, argc, argv);
00819         } else {
00820                 do_server_recv(f_in, f_out, argc, argv);
00821         }
00822         exit_cleanup(0);
00823 }

int client_run ( int  f_in,
int  f_out,
pid_t  pid,
int  argc,
char *  argv[] 
)

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

参照先 am_senderam_servercleanup_child_pidfile_list::countdo_recv()filesfrom_fdfilesfrom_hostFINFOget_local_name()handle_stats()io_flush()io_set_filesfrom_fds()io_set_sock_fds()io_start_buffering_out()io_start_multiplex_in()io_start_multiplex_out()keep_dirlinkslist_onlyneed_messages_from_generatoroutput_summary()protocol_versionread_batchread_final_goodbye()recv_file_list()rprintf()send_file_list()send_files()send_filter_list()set_blocking()set_msg_fd_in()set_nonblocking()setup_iconv()setup_protocol()start_write_batch()the_file_listverbosewait_process_with_flush()write_batch.

参照元 start_client()start_socket_client().

00831 {
00832         struct file_list *flist = NULL;
00833         int exit_code = 0, exit_code2 = 0;
00834         char *local_name = NULL;
00835 
00836         cleanup_child_pid = pid;
00837         if (!read_batch) {
00838                 set_nonblocking(f_in);
00839                 set_nonblocking(f_out);
00840         }
00841 
00842         io_set_sock_fds(f_in, f_out);
00843         setup_protocol(f_out,f_in);
00844 #if defined HAVE_ICONV_OPEN && defined HAVE_ICONV_H
00845         setup_iconv();
00846 #endif
00847 
00848         if (protocol_version >= 23 && !read_batch)
00849                 io_start_multiplex_in();
00850 
00851         /* We set our stderr file handle to blocking because ssh might have
00852          * set it to non-blocking.  This can be particularly troublesome if
00853          * stderr is a clone of stdout, because ssh would have set our stdout
00854          * to non-blocking at the same time (which can easily cause us to lose
00855          * output from our print statements).  This kluge shouldn't cause ssh
00856          * any problems for how we use it.  Note also that we delayed setting
00857          * this until after the above protocol setup so that we know for sure
00858          * that ssh is done twiddling its file descriptors.  */
00859         set_blocking(STDERR_FILENO);
00860 
00861         if (am_sender) {
00862                 keep_dirlinks = 0; /* Must be disabled on the sender. */
00863                 io_start_buffering_out();
00864                 if (!filesfrom_host)
00865                         set_msg_fd_in(f_in);
00866                 send_filter_list(f_out);
00867                 if (filesfrom_host)
00868                         filesfrom_fd = f_in;
00869 
00870                 if (write_batch && !am_server)
00871                         start_write_batch(f_out);
00872                 flist = send_file_list(f_out, argc, argv);
00873                 set_msg_fd_in(-1);
00874                 if (verbose > 3)
00875                         rprintf(FINFO,"file list sent\n");
00876                 the_file_list = flist;
00877 
00878                 io_flush(NORMAL_FLUSH);
00879                 send_files(flist,f_out,f_in);
00880                 io_flush(FULL_FLUSH);
00881                 handle_stats(-1);
00882                 if (protocol_version >= 24)
00883                         read_final_goodbye(f_in, f_out);
00884                 if (pid != -1) {
00885                         if (verbose > 3)
00886                                 rprintf(FINFO,"client_run waiting on %d\n", (int) pid);
00887                         io_flush(FULL_FLUSH);
00888                         wait_process_with_flush(pid, &exit_code);
00889                 }
00890                 output_summary();
00891                 io_flush(FULL_FLUSH);
00892                 exit_cleanup(exit_code);
00893         }
00894 
00895         if (need_messages_from_generator && !read_batch)
00896                 io_start_multiplex_out();
00897 
00898         if (argc == 0)
00899                 list_only |= 1;
00900 
00901         send_filter_list(read_batch ? -1 : f_out);
00902 
00903         if (filesfrom_fd >= 0) {
00904                 io_set_filesfrom_fds(filesfrom_fd, f_out);
00905                 filesfrom_fd = -1;
00906         }
00907 
00908         if (write_batch && !am_server)
00909                 start_write_batch(f_in);
00910         flist = recv_file_list(f_in);
00911         the_file_list = flist;
00912 
00913         if (flist && flist->count > 0) {
00914                 local_name = get_local_name(flist, argv[0]);
00915 
00916                 exit_code2 = do_recv(f_in, f_out, flist, local_name);
00917         } else {
00918                 handle_stats(-1);
00919                 output_summary();
00920         }
00921 
00922         if (pid != -1) {
00923                 if (verbose > 3)
00924                         rprintf(FINFO,"client_run2 waiting on %d\n", (int) pid);
00925                 io_flush(FULL_FLUSH);
00926                 wait_process_with_flush(pid, &exit_code);
00927         }
00928 
00929         return MAX(exit_code, exit_code2);
00930 }

static int copy_argv ( char *  argv[]  )  [static]

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

参照先 FERRORrprintf()strdup().

参照元 start_client().

00933 {
00934         int i;
00935 
00936         for (i = 0; argv[i]; i++) {
00937                 if (!(argv[i] = strdup(argv[i]))) {
00938                         rprintf (FERROR, "out of memory at %s(%d)\n",
00939                                  __FILE__, __LINE__);
00940                         return RERR_MALLOC;
00941                 }
00942         }
00943 
00944         return 0;
00945 }

static int start_client ( int  argc,
char *  argv[] 
) [static]

Start a client for either type of remote connection.

Work out whether the arguments request a remote shell or rsyncd connection, and call the appropriate connection function, then run_client.

Calls either start_socket_client (for sockets) or do_cmd and client_run (for ssh).

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

参照先 am_sendercheck_for_hostspec()client_run()copy_argv()daemon_over_rshdo_cmd()FERRORfilesfrom_hostFINFOlist_onlylocal_serverread_batchrprintf()rsync_portshell_cmdstart_inband_exchange()start_socket_client()usage()verbose.

参照元 main().

00957 {
00958         char *p;
00959         char *shell_machine = NULL;
00960         char *shell_path = NULL;
00961         char *shell_user = NULL;
00962         int ret;
00963         pid_t pid;
00964         int f_in,f_out;
00965         int rc;
00966 
00967         /* Don't clobber argv[] so that ps(1) can still show the right
00968          * command line. */
00969         if ((rc = copy_argv(argv)))
00970                 return rc;
00971 
00972         if (!read_batch) { /* for read_batch, NO source is specified */
00973                 shell_path = check_for_hostspec(argv[0], &shell_machine, &rsync_port);
00974                 if (shell_path) { /* source is remote */
00975                         char *dummy1;
00976                         int dummy2;
00977                         if (--argc
00978                          && check_for_hostspec(argv[argc], &dummy1, &dummy2)) {
00979                                 rprintf(FERROR,
00980                                         "The source and destination cannot both be remote.\n");
00981                                 exit_cleanup(RERR_SYNTAX);
00982                         }
00983                         argv++;
00984                         if (filesfrom_host && *filesfrom_host
00985                             && strcmp(filesfrom_host, shell_machine) != 0) {
00986                                 rprintf(FERROR,
00987                                         "--files-from hostname is not the same as the transfer hostname\n");
00988                                 exit_cleanup(RERR_SYNTAX);
00989                         }
00990                         if (rsync_port) {
00991                                 if (!shell_cmd) {
00992                                         return start_socket_client(shell_machine,
00993                                                                    shell_path,
00994                                                                    argc, argv);
00995                                 }
00996                                 daemon_over_rsh = 1;
00997                         }
00998 
00999                         am_sender = 0;
01000                 } else { /* source is local, check dest arg */
01001                         am_sender = 1;
01002 
01003                         if (argc > 1)
01004                                 p = argv[--argc];
01005                         else {
01006                                 p = ".";
01007                                 list_only = 1;
01008                         }
01009 
01010                         shell_path = check_for_hostspec(p, &shell_machine, &rsync_port);
01011                         if (shell_path && filesfrom_host && *filesfrom_host
01012                             && strcmp(filesfrom_host, shell_machine) != 0) {
01013                                 rprintf(FERROR,
01014                                         "--files-from hostname is not the same as the transfer hostname\n");
01015                                 exit_cleanup(RERR_SYNTAX);
01016                         }
01017                         if (!shell_path) { /* no hostspec found, so src & dest are local */
01018                                 local_server = 1;
01019                                 if (filesfrom_host) {
01020                                         rprintf(FERROR,
01021                                                 "--files-from cannot be remote when the transfer is local\n");
01022                                         exit_cleanup(RERR_SYNTAX);
01023                                 }
01024                                 shell_machine = NULL;
01025                                 shell_path = p;
01026                         } else if (rsync_port) {
01027                                 if (!shell_cmd) {
01028                                         return start_socket_client(shell_machine,
01029                                                                    shell_path,
01030                                                                    argc, argv);
01031                                 }
01032                                 daemon_over_rsh = 1;
01033                         }
01034                 }
01035         } else {  /* read_batch */
01036                 local_server = 1;
01037                 shell_path = argv[argc-1];
01038                 if (check_for_hostspec(shell_path, &shell_machine, &rsync_port)) {
01039                         rprintf(FERROR, "remote destination is not allowed with --read-batch\n");
01040                         exit_cleanup(RERR_SYNTAX);
01041                 }
01042         }
01043 
01044         if (shell_machine) {
01045                 p = strrchr(shell_machine,'@');
01046                 if (p) {
01047                         *p = 0;
01048                         shell_user = shell_machine;
01049                         shell_machine = p+1;
01050                 }
01051         }
01052 
01053         if (verbose > 3) {
01054                 rprintf(FINFO,"cmd=%s machine=%s user=%s path=%s\n",
01055                         shell_cmd ? shell_cmd : "",
01056                         shell_machine ? shell_machine : "",
01057                         shell_user ? shell_user : "",
01058                         shell_path ? shell_path : "");
01059         }
01060 
01061         /* for remote source, only single dest arg can remain ... */
01062         if (!am_sender && argc > 1) {
01063                 usage(FERROR);
01064                 exit_cleanup(RERR_SYNTAX);
01065         }
01066 
01067         /* ... or no dest at all */
01068         if (!am_sender && argc == 0)
01069                 list_only |= 1;
01070 
01071         pid = do_cmd(shell_cmd,shell_machine,shell_user,shell_path,
01072                      &f_in,&f_out);
01073 
01074         /* if we're running an rsync server on the remote host over a
01075          * remote shell command, we need to do the RSYNCD protocol first */
01076         if (daemon_over_rsh) {
01077                 int tmpret;
01078                 tmpret = start_inband_exchange(shell_user, shell_path,
01079                                                f_in, f_out, argc);
01080                 if (tmpret < 0)
01081                         return tmpret;
01082         }
01083 
01084         ret = client_run(f_in, f_out, pid, argc, argv);
01085 
01086         fflush(stdout);
01087         fflush(stderr);
01088 
01089         return ret;
01090 }

static RETSIGTYPE sigusr1_handler ( UNUSED(int val)   )  [static]

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

参照元 main().

01094 {
01095         exit_cleanup(RERR_SIGNAL1);
01096 }

static RETSIGTYPE sigusr2_handler ( UNUSED(int val)   )  [static]

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

参照先 am_serverclose_all()log_got_erroroutput_summary().

参照元 main().

01099 {
01100         if (!am_server)
01101                 output_summary();
01102         close_all();
01103         if (log_got_error)
01104                 _exit(RERR_PARTIAL);
01105         _exit(0);
01106 }

RETSIGTYPE remember_children ( UNUSED(int val)   ) 

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

参照先 pid_stat_tablepid_status::statuswaitpid().

参照元 main()start_daemon().

01109 {
01110 #ifdef WNOHANG
01111         int cnt, status;
01112         pid_t pid;
01113         /* An empty waitpid() loop was put here by Tridge and we could never
01114          * get him to explain why he put it in, so rather than taking it
01115          * out we're instead saving the child exit statuses for later use.
01116          * The waitpid() loop presumably eliminates all possibility of leaving
01117          * zombie children, maybe that's why he did it. */
01118         while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
01119                 /* save the child's exit status */
01120                 for (cnt = 0; cnt < MAXCHILDPROCS; cnt++) {
01121                         if (pid_stat_table[cnt].pid == 0) {
01122                                 pid_stat_table[cnt].pid = pid;
01123                                 pid_stat_table[cnt].status = status;
01124                                 break;
01125                         }
01126                 }
01127         }
01128 #endif
01129 #ifndef HAVE_SIGACTION
01130         signal(SIGCHLD, remember_children);
01131 #endif
01132 }

const char* get_panic_action ( void   ) 

This routine catches signals and tries to send them to gdb.

Because it's called from inside a signal handler it ought not to use too many library routines.

TODO:
Perhaps use "screen -X" instead/as well, to help people debugging without easy access to X. Perhaps use an environment variable, or just call a script?
TODO:
The /proc/ magic probably only works on Linux (and Solaris?) Can we be more portable?

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

参照元 print_rsync_version()rsync_panic_handler().

01150 {
01151         const char *cmd_fmt = getenv("RSYNC_PANIC_ACTION");
01152 
01153         if (cmd_fmt)
01154                 return cmd_fmt;
01155         else
01156                 return "xterm -display :0 -T Panic -n Panic "
01157                         "-e gdb /proc/%d/exe %d";
01158 }

static RETSIGTYPE rsync_panic_handler ( UNUSED(int whatsig)   )  [static]

Handle a fatal signal by launching a debugger, controlled by $RSYNC_PANIC_ACTION.

This signal handler is only installed if we were configured with --enable-maintainer-mode. Perhaps it should always be on and we should just look at the environment variable, but I'm a bit leery of a signal sending us into a busy loop.

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

参照先 get_panic_action()sprintf().

参照元 main().

01170 {
01171         char cmd_buf[300];
01172         int ret;
01173 
01174         sprintf(cmd_buf, get_panic_action(),
01175                 getpid(), getpid());
01176 
01177         /* Unless we failed to execute gdb, we allow the process to
01178          * continue.  I'm not sure if that's right. */
01179         ret = system(cmd_buf);
01180         if (ret)
01181                 _exit(ret);
01182 }

int main ( int  argc,
char *  argv[] 
)

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

参照先 am_daemonam_rootam_serverbatch_fdbatch_namedaemon_main()do_open()dry_runerrnoFERRORfull_fname()init_flist()option_error()orig_umaskparse_arguments()push_dir()read_batchread_stream_flags()remember_children()rsync_panic_handler()rsyserr()set_nonblocking()sig_int()sigactsigusr1_handler()sigusr2_handler()start_client()start_daemon()start_server()starttimestatsusage()write_batchwrite_batch_shell_file().

01187 {
01188         int ret;
01189         int orig_argc = argc;
01190         char **orig_argv = argv;
01191 #ifdef HAVE_SIGACTION
01192 # ifdef HAVE_SIGPROCMASK
01193         sigset_t sigmask;
01194 
01195         sigemptyset(&sigmask);
01196 # endif
01197         sigact.sa_flags = SA_NOCLDSTOP;
01198 #endif
01199         SIGACTMASK(SIGUSR1, sigusr1_handler);
01200         SIGACTMASK(SIGUSR2, sigusr2_handler);
01201         SIGACTMASK(SIGCHLD, remember_children);
01202 #ifdef MAINTAINER_MODE
01203         SIGACTMASK(SIGSEGV, rsync_panic_handler);
01204         SIGACTMASK(SIGFPE, rsync_panic_handler);
01205         SIGACTMASK(SIGABRT, rsync_panic_handler);
01206         SIGACTMASK(SIGBUS, rsync_panic_handler);
01207 #endif
01208 
01209         starttime = time(NULL);
01210         am_root = (MY_UID() == 0);
01211 
01212         memset(&stats, 0, sizeof(stats));
01213 
01214         if (argc < 2) {
01215                 usage(FERROR);
01216                 exit_cleanup(RERR_SYNTAX);
01217         }
01218 
01219         /* we set a 0 umask so that correct file permissions can be
01220          * carried across */
01221         orig_umask = umask(0);
01222 
01223 #if defined CONFIG_LOCALE && defined HAVE_SETLOCALE
01224         setlocale(LC_CTYPE, "");
01225 #endif
01226 
01227         if (!parse_arguments(&argc, (const char ***) &argv, 1)) {
01228                 /* FIXME: We ought to call the same error-handling
01229                  * code here, rather than relying on getopt. */
01230                 option_error();
01231                 exit_cleanup(RERR_SYNTAX);
01232         }
01233 
01234         SIGACTMASK(SIGINT, sig_int);
01235         SIGACTMASK(SIGHUP, sig_int);
01236         SIGACTMASK(SIGTERM, sig_int);
01237 #if defined HAVE_SIGACTION && HAVE_SIGPROCMASK
01238         sigprocmask(SIG_UNBLOCK, &sigmask, NULL);
01239 #endif
01240 
01241         /* Ignore SIGPIPE; we consistently check error codes and will
01242          * see the EPIPE. */
01243         SIGACTION(SIGPIPE, SIG_IGN);
01244 #ifdef SIGXFSZ
01245         SIGACTION(SIGXFSZ, SIG_IGN);
01246 #endif
01247 
01248         /* Initialize push_dir here because on some old systems getcwd
01249          * (implemented by forking "pwd" and reading its output) doesn't
01250          * work when there are other child processes.  Also, on all systems
01251          * that implement getcwd that way "pwd" can't be found after chroot. */
01252         push_dir(NULL);
01253 
01254         init_flist();
01255 
01256         if ((write_batch || read_batch) && !am_server) {
01257                 if (write_batch)
01258                         write_batch_shell_file(orig_argc, orig_argv, argc);
01259 
01260                 if (read_batch && strcmp(batch_name, "-") == 0)
01261                         batch_fd = STDIN_FILENO;
01262                 else {
01263                         batch_fd = do_open(batch_name,
01264                                    write_batch ? O_WRONLY | O_CREAT | O_TRUNC
01265                                    : O_RDONLY, S_IRUSR | S_IWUSR);
01266                 }
01267                 if (batch_fd < 0) {
01268                         rsyserr(FERROR, errno, "Batch file %s open error",
01269                                 full_fname(batch_name));
01270                         exit_cleanup(RERR_FILEIO);
01271                 }
01272                 if (read_batch)
01273                         read_stream_flags(batch_fd);
01274         }
01275         if (write_batch < 0)
01276                 dry_run = 1;
01277 
01278         if (am_daemon && !am_server)
01279                 return daemon_main();
01280 
01281         if (argc < 1) {
01282                 usage(FERROR);
01283                 exit_cleanup(RERR_SYNTAX);
01284         }
01285 
01286         if (am_server) {
01287                 set_nonblocking(STDIN_FILENO);
01288                 set_nonblocking(STDOUT_FILENO);
01289                 if (am_daemon)
01290                         return start_daemon(STDIN_FILENO, STDOUT_FILENO);
01291                 start_server(STDIN_FILENO, STDOUT_FILENO, argc, argv);
01292         }
01293 
01294         ret = start_client(argc, argv);
01295         if (ret == -1)
01296                 exit_cleanup(RERR_STARTCLIENT);
01297         else
01298                 exit_cleanup(ret);
01299 
01300         return ret;
01301 }


変数

int verbose

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

int dry_run

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

int list_only

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

int am_root

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

int am_server

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

int am_sender

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

int am_generator

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

int am_daemon

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

int blocking_io

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

参照元 do_cmd()piped_child()server_options().

int remove_sent_files

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

int daemon_over_rsh

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

int need_messages_from_generator

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

参照元 client_run()parse_arguments()start_server().

int kluge_around_eof

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

int do_stats

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

参照元 handle_stats()output_summary().

int log_got_error

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

int module_id

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

int copy_links

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

int copy_dirlinks

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

int keep_dirlinks

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

int preserve_hard_links

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

int protocol_version

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

int recurse

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

int relative_paths

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

int rsync_port

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

int whole_file

If 1, send the whole file as literal data rather than trying to create an incremental diff.

If -1, then look at whether we're local or remote and go by that.

参照:
disable_deltas_p()

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

int read_batch

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

int write_batch

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

参照元 client_run()do_cmd()do_recv()handle_stats()main()parse_arguments()recv_files()send_files()server_options().

int batch_fd

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

int batch_gen_fd

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

int filesfrom_fd

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

pid_t cleanup_child_pid

cleanup.c83 行で定義されています。

参照元 _exit_cleanup()client_run().

struct stats stats

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

char* filesfrom_host

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

char* rsync_path

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

参照元 do_cmd().

char* shell_cmd

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

参照元 start_client().

char* batch_name

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

int local_server = 0

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

mode_t orig_umask = 0

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

struct file_list* the_file_list

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

struct sigaction sigact [static]

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

struct pid_status pid_stat_table[MAXCHILDPROCS]

参照元 remember_children()wait_process().

time_t starttime [static]

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

参照元 main()output_summary().

time_t endtime [static]

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

参照元 handle_stats()output_summary().

int64 total_read [static]

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

参照元 handle_stats()output_summary().

int64 total_written [static]

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

参照元 full_write()handle_stats()output_summary()sleep_for_bwlimit().


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