関数 | |
int | start_socket_client (char *host, char *path, int argc, char *argv[]) |
Run a client connected to an rsyncd. | |
int | start_inband_exchange (char *user, char *path, int f_in, int f_out, int argc) |
static char * | finish_pre_exec (pid_t pid, int fd, char *request, int argc, char *argv[]) |
static int | read_arg_from_pipe (int fd, char *buf, int limit) |
static int | rsync_module (int f_in, int f_out, int i, char *addr, char *host) |
static void | send_listing (int fd) |
int | start_daemon (int f_in, int f_out) |
int | daemon_main (void) |
変数 | |
int | verbose |
int | quiet |
int | list_only |
int | am_sender |
int | am_server |
int | am_daemon |
int | am_root |
int | rsync_port |
int | kluge_around_eof |
int | daemon_over_rsh |
int | sanitize_paths |
int | filesfrom_fd |
int | remote_protocol |
int | protocol_version |
int | io_timeout |
int | no_detach |
Do not go into the background when run as --daemon. | |
int | default_af_hint |
Network address family. | |
mode_t | orig_umask |
char * | bind_address |
Local address to bind. | |
char * | sockopts |
char * | config_file |
char * | files_from |
char * | tmpdir |
chmod_mode_struct * | chmod_modes |
filter_list_struct | server_filter_list |
char * | auth_user |
int | read_only = 0 |
int | daemon_log_format_has_i = 0 |
int | daemon_log_format_has_o_or_i = 0 |
int | module_id = -1 |
chmod_mode_struct * | daemon_chmod_modes |
unsigned int | module_dirlen = 0 |
static struct sigaction | sigact |
clientserver.c で定義されています。
int start_socket_client | ( | char * | host, | |
char * | path, | |||
int | argc, | |||
char * | argv[] | |||
) |
Run a client connected to an rsyncd.
The alternative to this function for remote-shell connections is do_cmd().
After negotiating which module to use and reading the server's motd, this hands over to client_run(). Telling the server the module will cause it to chroot/setuid/etc.
Instead of doing a transfer, the client may at this stage instead get a listing of remote modules and exit.
clientserver.c の 84 行で定義されています。
参照先 bind_address・client_run()・default_af_hint・FERROR・open_socket_out_wrapped()・rprintf()・rsync_port・set_socket_options()・sockopts・start_inband_exchange().
参照元 start_client().
00085 { 00086 int fd, ret; 00087 char *p, *user = NULL; 00088 00089 /* This is redundant with code in start_inband_exchange(), but this 00090 * short-circuits a problem in the client before we open a socket, 00091 * and the extra check won't hurt. */ 00092 if (*path == '/') { 00093 rprintf(FERROR, 00094 "ERROR: The remote path must start with a module name not a /\n"); 00095 return -1; 00096 } 00097 00098 if ((p = strrchr(host, '@')) != NULL) { 00099 user = host; 00100 host = p+1; 00101 *p = '\0'; 00102 } 00103 00104 fd = open_socket_out_wrapped(host, rsync_port, bind_address, 00105 default_af_hint); 00106 if (fd == -1) 00107 exit_cleanup(RERR_SOCKETIO); 00108 00109 set_socket_options(fd, sockopts); 00110 00111 ret = start_inband_exchange(user, path, fd, fd, argc); 00112 00113 return ret ? ret : client_run(fd, fd, -1, argc, argv); 00114 }
int start_inband_exchange | ( | char * | user, | |
char * | path, | |||
int | f_in, | |||
int | f_out, | |||
int | argc | |||
) |
clientserver.c の 116 行で定義されています。
参照先 am_sender・auth_client()・daemon_over_rsh・FERROR・FINFO・io_printf()・io_start_multiplex_in()・kluge_around_eof・list_only・print_child_argv()・protocol_version・read_line()・remote_protocol・rprintf()・server_options()・verbose.
参照元 start_client()・start_socket_client().
00118 { 00119 int i; 00120 char *sargs[MAX_ARGS]; 00121 int sargc = 0; 00122 char line[BIGPATHBUFLEN]; 00123 char *p; 00124 00125 if (argc == 0 && !am_sender) 00126 list_only |= 1; 00127 00128 if (*path == '/') { 00129 rprintf(FERROR, 00130 "ERROR: The remote path must start with a module name\n"); 00131 return -1; 00132 } 00133 00134 if (!user) 00135 user = getenv("USER"); 00136 if (!user) 00137 user = getenv("LOGNAME"); 00138 00139 io_printf(f_out, "@RSYNCD: %d\n", protocol_version); 00140 00141 if (!read_line(f_in, line, sizeof line - 1)) { 00142 rprintf(FERROR, "rsync: did not see server greeting\n"); 00143 return -1; 00144 } 00145 00146 if (sscanf(line,"@RSYNCD: %d", &remote_protocol) != 1) { 00147 /* note that read_line strips of \n or \r */ 00148 rprintf(FERROR, "rsync: server sent \"%s\" rather than greeting\n", 00149 line); 00150 return -1; 00151 } 00152 if (protocol_version > remote_protocol) 00153 protocol_version = remote_protocol; 00154 00155 if (list_only && protocol_version >= 29) 00156 list_only |= 2; 00157 00158 /* set daemon_over_rsh to false since we need to build the 00159 * true set of args passed through the rsh/ssh connection; 00160 * this is a no-op for direct-socket-connection mode */ 00161 daemon_over_rsh = 0; 00162 server_options(sargs, &sargc); 00163 00164 sargs[sargc++] = "."; 00165 00166 if (path && *path) 00167 sargs[sargc++] = path; 00168 00169 sargs[sargc] = NULL; 00170 00171 if (verbose > 1) 00172 print_child_argv(sargs); 00173 00174 p = strchr(path,'/'); 00175 if (p) *p = 0; 00176 io_printf(f_out, "%s\n", path); 00177 if (p) *p = '/'; 00178 00179 /* Old servers may just drop the connection here, 00180 rather than sending a proper EXIT command. Yuck. */ 00181 kluge_around_eof = list_only && protocol_version < 25 ? 1 : 0; 00182 00183 while (1) { 00184 if (!read_line(f_in, line, sizeof line - 1)) { 00185 rprintf(FERROR, "rsync: didn't get server startup line\n"); 00186 return -1; 00187 } 00188 00189 if (strncmp(line,"@RSYNCD: AUTHREQD ",18) == 0) { 00190 auth_client(f_out, user, line+18); 00191 continue; 00192 } 00193 00194 if (strcmp(line,"@RSYNCD: OK") == 0) 00195 break; 00196 00197 if (strcmp(line,"@RSYNCD: EXIT") == 0) { 00198 /* This is sent by recent versions of the 00199 * server to terminate the listing of modules. 00200 * We don't want to go on and transfer 00201 * anything; just exit. */ 00202 exit(0); 00203 } 00204 00205 if (strncmp(line, "@ERROR", 6) == 0) { 00206 rprintf(FERROR, "%s\n", line); 00207 /* This is always fatal; the server will now 00208 * close the socket. */ 00209 return -1; 00210 } 00211 00212 rprintf(FINFO, "%s\n", line); 00213 } 00214 kluge_around_eof = 0; 00215 00216 for (i = 0; i < sargc; i++) { 00217 io_printf(f_out, "%s\n", sargs[i]); 00218 } 00219 io_printf(f_out, "\n"); 00220 00221 if (protocol_version < 23) { 00222 if (protocol_version == 22 || !am_sender) 00223 io_start_multiplex_in(); 00224 } 00225 00226 return 0; 00227 }
static char* finish_pre_exec | ( | pid_t | pid, | |
int | fd, | |||
char * | request, | |||
int | argc, | |||
char * | argv[] | |||
) | [static] |
clientserver.c の 229 行で定義されています。
参照先 asprintf()・out_of_memory()・wait_process()・write_buf()・write_byte().
参照元 rsync_module().
00231 { 00232 int j, status = -1; 00233 00234 if (request) { 00235 write_buf(fd, request, strlen(request)+1); 00236 for (j = 0; j < argc; j++) 00237 write_buf(fd, argv[j], strlen(argv[j])+1); 00238 } 00239 00240 write_byte(fd, 0); 00241 00242 close(fd); 00243 00244 if (wait_process(pid, &status, 0) < 0 00245 || !WIFEXITED(status) || WEXITSTATUS(status) != 0) { 00246 char *e; 00247 if (asprintf(&e, "pre-xfer exec returned failure (%d)\n", status) < 0) 00248 out_of_memory("finish_pre_exec"); 00249 return e; 00250 } 00251 return NULL; 00252 }
static int read_arg_from_pipe | ( | int | fd, | |
char * | buf, | |||
int | limit | |||
) | [static] |
clientserver.c の 254 行で定義されています。
参照元 rsync_module().
00255 { 00256 char *bp = buf, *eob = buf + limit - 1; 00257 00258 while (1) { 00259 if (read(fd, bp, 1) != 1) 00260 return -1; 00261 if (*bp == '\0') 00262 break; 00263 if (bp < eob) 00264 bp++; 00265 } 00266 *bp = '\0'; 00267 00268 return bp - buf; 00269 }
static int rsync_module | ( | int | f_in, | |
int | f_out, | |||
int | i, | |||
char * | addr, | |||
char * | host | |||
) | [static] |
clientserver.c の 271 行で定義されています。
参照先 allow_access()・am_daemon・am_root・am_sender・am_server・asprintf()・auth_server()・auth_user・buf・chmod_modes・claim_connection()・daemon_chmod_modes・daemon_log_format_has_i・daemon_log_format_has_o_or_i・errno・FERROR・files_from・filesfrom_fd・finish_pre_exec()・FLOG・glob_expand()・io_printf()・io_start_multiplex_out()・io_timeout・log_format_has()・log_init()・lp_name()・lp_path()・lp_use_chroot()・module_dirlen・module_id・msleep()・name・name_to_gid()・name_to_uid()・option_error()・orig_umask・out_of_memory()・parse_arguments()・parse_chmod()・parse_filter_file()・parse_rule()・protocol_version・push_dir()・quiet・read_arg_from_pipe()・read_line()・read_only・rprintf()・rsyserr()・sanitize_paths・server_filter_list・set_blocking()・set_filter_dir()・set_io_timeout()・setup_protocol()・start_server()・strdup()・tmpdir・verbose・wait_process()・write_byte().
参照元 start_daemon().
00272 { 00273 int argc = 0; 00274 int maxargs; 00275 char **argv; 00276 char line[BIGPATHBUFLEN]; 00277 uid_t uid = (uid_t)-2; /* canonically "nobody" */ 00278 gid_t gid = (gid_t)-2; 00279 char *p, *err_msg = NULL; 00280 char *name = lp_name(i); 00281 int use_chroot = lp_use_chroot(i); 00282 int start_glob = 0; 00283 int ret, pre_exec_fd = -1; 00284 pid_t pre_exec_pid = 0; 00285 char *request = NULL; 00286 00287 if (!allow_access(addr, host, lp_hosts_allow(i), lp_hosts_deny(i))) { 00288 rprintf(FLOG, "rsync denied on module %s from %s (%s)\n", 00289 name, host, addr); 00290 if (!lp_list(i)) 00291 io_printf(f_out, "@ERROR: Unknown module '%s'\n", name); 00292 else { 00293 io_printf(f_out, 00294 "@ERROR: access denied to %s from %s (%s)\n", 00295 name, host, addr); 00296 } 00297 return -1; 00298 } 00299 00300 if (am_daemon && am_server) { 00301 rprintf(FLOG, "rsync allowed access on module %s from %s (%s)\n", 00302 name, host, addr); 00303 } 00304 00305 if (!claim_connection(lp_lock_file(i), lp_max_connections(i))) { 00306 if (errno) { 00307 rsyserr(FLOG, errno, "failed to open lock file %s", 00308 lp_lock_file(i)); 00309 io_printf(f_out, "@ERROR: failed to open lock file\n"); 00310 } else { 00311 rprintf(FLOG, "max connections (%d) reached\n", 00312 lp_max_connections(i)); 00313 io_printf(f_out, "@ERROR: max connections (%d) reached -- try again later\n", 00314 lp_max_connections(i)); 00315 } 00316 return -1; 00317 } 00318 00319 auth_user = auth_server(f_in, f_out, i, host, addr, "@RSYNCD: AUTHREQD "); 00320 00321 if (!auth_user) { 00322 io_printf(f_out, "@ERROR: auth failed on module %s\n", name); 00323 return -1; 00324 } 00325 00326 module_id = i; 00327 00328 if (lp_read_only(i)) 00329 read_only = 1; 00330 00331 if (lp_transfer_logging(i)) { 00332 if (log_format_has(lp_log_format(i), 'i')) 00333 daemon_log_format_has_i = 1; 00334 if (daemon_log_format_has_i 00335 || log_format_has(lp_log_format(i), 'o')) 00336 daemon_log_format_has_o_or_i = 1; 00337 } 00338 00339 am_root = (MY_UID() == 0); 00340 00341 if (am_root) { 00342 p = lp_uid(i); 00343 if (!name_to_uid(p, &uid)) { 00344 if (!isdigit(*(unsigned char *)p)) { 00345 rprintf(FLOG, "Invalid uid %s\n", p); 00346 io_printf(f_out, "@ERROR: invalid uid %s\n", p); 00347 return -1; 00348 } 00349 uid = atoi(p); 00350 } 00351 00352 p = lp_gid(i); 00353 if (!name_to_gid(p, &gid)) { 00354 if (!isdigit(*(unsigned char *)p)) { 00355 rprintf(FLOG, "Invalid gid %s\n", p); 00356 io_printf(f_out, "@ERROR: invalid gid %s\n", p); 00357 return -1; 00358 } 00359 gid = atoi(p); 00360 } 00361 } 00362 00363 /* TODO: If we're not root, but the configuration requests 00364 * that we change to some uid other than the current one, then 00365 * log a warning. */ 00366 00367 /* TODO: Perhaps take a list of gids, and make them into the 00368 * supplementary groups. */ 00369 00370 if (use_chroot || (module_dirlen = strlen(lp_path(i))) == 1) { 00371 module_dirlen = 0; 00372 set_filter_dir("/", 1); 00373 } else 00374 set_filter_dir(lp_path(i), module_dirlen); 00375 00376 p = lp_filter(i); 00377 parse_rule(&server_filter_list, p, MATCHFLG_WORD_SPLIT, 00378 XFLG_ABS_IF_SLASH); 00379 00380 p = lp_include_from(i); 00381 parse_filter_file(&server_filter_list, p, MATCHFLG_INCLUDE, 00382 XFLG_ABS_IF_SLASH | XFLG_OLD_PREFIXES | XFLG_FATAL_ERRORS); 00383 00384 p = lp_include(i); 00385 parse_rule(&server_filter_list, p, 00386 MATCHFLG_INCLUDE | MATCHFLG_WORD_SPLIT, 00387 XFLG_ABS_IF_SLASH | XFLG_OLD_PREFIXES); 00388 00389 p = lp_exclude_from(i); 00390 parse_filter_file(&server_filter_list, p, 0, 00391 XFLG_ABS_IF_SLASH | XFLG_OLD_PREFIXES | XFLG_FATAL_ERRORS); 00392 00393 p = lp_exclude(i); 00394 parse_rule(&server_filter_list, p, MATCHFLG_WORD_SPLIT, 00395 XFLG_ABS_IF_SLASH | XFLG_OLD_PREFIXES); 00396 00397 log_init(); 00398 00399 #ifdef HAVE_PUTENV 00400 if (*lp_prexfer_exec(i) || *lp_postxfer_exec(i)) { 00401 char *modname, *modpath, *hostaddr, *hostname, *username; 00402 int status; 00403 if (asprintf(&modname, "RSYNC_MODULE_NAME=%s", name) < 0 00404 || asprintf(&modpath, "RSYNC_MODULE_PATH=%s", lp_path(i)) < 0 00405 || asprintf(&hostaddr, "RSYNC_HOST_ADDR=%s", addr) < 0 00406 || asprintf(&hostname, "RSYNC_HOST_NAME=%s", host) < 0 00407 || asprintf(&username, "RSYNC_USER_NAME=%s", auth_user) < 0) 00408 out_of_memory("rsync_module"); 00409 putenv(modname); 00410 putenv(modpath); 00411 putenv(hostaddr); 00412 putenv(hostname); 00413 putenv(username); 00414 umask(orig_umask); 00415 /* For post-xfer exec, fork a new process to run the rsync 00416 * daemon while this process waits for the exit status and 00417 * runs the indicated command at that point. */ 00418 if (*lp_postxfer_exec(i)) { 00419 pid_t pid = fork(); 00420 if (pid < 0) { 00421 rsyserr(FLOG, errno, "fork failed"); 00422 io_printf(f_out, "@ERROR: fork failed\n"); 00423 return -1; 00424 } 00425 if (pid) { 00426 char *ret1, *ret2; 00427 if (wait_process(pid, &status, 0) < 0) 00428 status = -1; 00429 if (asprintf(&ret1, "RSYNC_RAW_STATUS=%d", status) > 0) 00430 putenv(ret1); 00431 if (WIFEXITED(status)) 00432 status = WEXITSTATUS(status); 00433 else 00434 status = -1; 00435 if (asprintf(&ret2, "RSYNC_EXIT_STATUS=%d", status) > 0) 00436 putenv(ret2); 00437 system(lp_postxfer_exec(i)); 00438 _exit(status); 00439 } 00440 } 00441 /* For pre-xfer exec, fork a child process to run the indicated 00442 * command, though it first waits for the parent process to 00443 * send us the user's request via a pipe. */ 00444 if (*lp_prexfer_exec(i)) { 00445 int fds[2]; 00446 if (pipe(fds) < 0 || (pre_exec_pid = fork()) < 0) { 00447 rsyserr(FLOG, errno, "pre-xfer exec preparation failed"); 00448 io_printf(f_out, "@ERROR: pre-xfer exec preparation failed\n"); 00449 return -1; 00450 } 00451 if (pre_exec_pid == 0) { 00452 char buf[BIGPATHBUFLEN]; 00453 int j, len; 00454 close(fds[1]); 00455 set_blocking(fds[0]); 00456 len = read_arg_from_pipe(fds[0], buf, BIGPATHBUFLEN); 00457 if (len <= 0) 00458 _exit(1); 00459 if (asprintf(&p, "RSYNC_REQUEST=%s", buf) < 0) 00460 out_of_memory("rsync_module"); 00461 putenv(p); 00462 for (j = 0; ; j++) { 00463 len = read_arg_from_pipe(fds[0], buf, 00464 BIGPATHBUFLEN); 00465 if (len <= 0) { 00466 if (!len) 00467 break; 00468 _exit(1); 00469 } 00470 if (asprintf(&p, "RSYNC_ARG%d=%s", j, buf) < 0) 00471 out_of_memory("rsync_module"); 00472 putenv(p); 00473 } 00474 close(fds[0]); 00475 close(STDIN_FILENO); 00476 close(STDOUT_FILENO); 00477 status = system(lp_prexfer_exec(i)); 00478 if (!WIFEXITED(status)) 00479 _exit(1); 00480 _exit(WEXITSTATUS(status)); 00481 } 00482 close(fds[0]); 00483 set_blocking(fds[1]); 00484 pre_exec_fd = fds[1]; 00485 } 00486 umask(0); 00487 } 00488 #endif 00489 00490 if (use_chroot) { 00491 /* 00492 * XXX: The 'use chroot' flag is a fairly reliable 00493 * source of confusion, because it fails under two 00494 * important circumstances: running as non-root, 00495 * running on Win32 (or possibly others). On the 00496 * other hand, if you are running as root, then it 00497 * might be better to always use chroot. 00498 * 00499 * So, perhaps if we can't chroot we should just issue 00500 * a warning, unless a "require chroot" flag is set, 00501 * in which case we fail. 00502 */ 00503 if (chroot(lp_path(i))) { 00504 rsyserr(FLOG, errno, "chroot %s failed", 00505 lp_path(i)); 00506 io_printf(f_out, "@ERROR: chroot failed\n"); 00507 return -1; 00508 } 00509 00510 if (!push_dir("/")) { 00511 rsyserr(FLOG, errno, "chdir %s failed\n", 00512 lp_path(i)); 00513 io_printf(f_out, "@ERROR: chdir failed\n"); 00514 return -1; 00515 } 00516 00517 } else { 00518 if (!push_dir(lp_path(i))) { 00519 rsyserr(FLOG, errno, "chdir %s failed\n", 00520 lp_path(i)); 00521 io_printf(f_out, "@ERROR: chdir failed\n"); 00522 return -1; 00523 } 00524 sanitize_paths = 1; 00525 } 00526 00527 if (am_root) { 00528 /* XXXX: You could argue that if the daemon is started 00529 * by a non-root user and they explicitly specify a 00530 * gid, then we should try to change to that gid -- 00531 * this could be possible if it's already in their 00532 * supplementary groups. */ 00533 00534 /* TODO: Perhaps we need to document that if rsyncd is 00535 * started by somebody other than root it will inherit 00536 * all their supplementary groups. */ 00537 00538 if (setgid(gid)) { 00539 rsyserr(FLOG, errno, "setgid %d failed", (int)gid); 00540 io_printf(f_out, "@ERROR: setgid failed\n"); 00541 return -1; 00542 } 00543 #ifdef HAVE_SETGROUPS 00544 /* Get rid of any supplementary groups this process 00545 * might have inheristed. */ 00546 if (setgroups(1, &gid)) { 00547 rsyserr(FLOG, errno, "setgroups failed"); 00548 io_printf(f_out, "@ERROR: setgroups failed\n"); 00549 return -1; 00550 } 00551 #endif 00552 00553 if (setuid(uid)) { 00554 rsyserr(FLOG, errno, "setuid %d failed", (int)uid); 00555 io_printf(f_out, "@ERROR: setuid failed\n"); 00556 return -1; 00557 } 00558 00559 am_root = (MY_UID() == 0); 00560 } 00561 00562 if (lp_temp_dir(i) && *lp_temp_dir(i)) { 00563 tmpdir = lp_temp_dir(i); 00564 if (strlen(tmpdir) >= MAXPATHLEN - 10) { 00565 rprintf(FLOG, 00566 "the 'temp dir' value for %s is WAY too long -- ignoring.\n", 00567 name); 00568 tmpdir = NULL; 00569 } 00570 } 00571 00572 io_printf(f_out, "@RSYNCD: OK\n"); 00573 00574 maxargs = MAX_ARGS; 00575 if (!(argv = new_array(char *, maxargs))) 00576 out_of_memory("rsync_module"); 00577 argv[argc++] = "rsyncd"; 00578 00579 while (1) { 00580 if (!read_line(f_in, line, sizeof line - 1)) 00581 return -1; 00582 00583 if (!*line) 00584 break; 00585 00586 p = line; 00587 00588 if (argc == maxargs) { 00589 maxargs += MAX_ARGS; 00590 if (!(argv = realloc_array(argv, char *, maxargs))) 00591 out_of_memory("rsync_module"); 00592 } 00593 if (!(argv[argc] = strdup(p))) 00594 out_of_memory("rsync_module"); 00595 00596 switch (start_glob) { 00597 case 0: 00598 argc++; 00599 if (strcmp(line, ".") == 0) 00600 start_glob = 1; 00601 break; 00602 case 1: 00603 if (pre_exec_pid) { 00604 err_msg = finish_pre_exec(pre_exec_pid, 00605 pre_exec_fd, p, 00606 argc, argv); 00607 pre_exec_pid = 0; 00608 } 00609 request = strdup(p); 00610 start_glob = 2; 00611 /* FALL THROUGH */ 00612 default: 00613 if (!err_msg) 00614 glob_expand(name, &argv, &argc, &maxargs); 00615 break; 00616 } 00617 } 00618 00619 if (pre_exec_pid) { 00620 err_msg = finish_pre_exec(pre_exec_pid, pre_exec_fd, request, 00621 argc, argv); 00622 } 00623 00624 verbose = 0; /* future verbosity is controlled by client options */ 00625 ret = parse_arguments(&argc, (const char ***) &argv, 0); 00626 quiet = 0; /* Don't let someone try to be tricky. */ 00627 00628 if (filesfrom_fd == 0) 00629 filesfrom_fd = f_in; 00630 00631 if (request) { 00632 if (*auth_user) { 00633 rprintf(FLOG, "rsync %s %s from %s@%s (%s)\n", 00634 am_sender ? "on" : "to", 00635 request, auth_user, host, addr); 00636 } else { 00637 rprintf(FLOG, "rsync %s %s from %s (%s)\n", 00638 am_sender ? "on" : "to", 00639 request, host, addr); 00640 } 00641 free(request); 00642 } 00643 00644 #ifndef DEBUG 00645 /* don't allow the logs to be flooded too fast */ 00646 if (verbose > lp_max_verbosity(i)) 00647 verbose = lp_max_verbosity(i); 00648 #endif 00649 00650 if (protocol_version < 23 00651 && (protocol_version == 22 || am_sender)) 00652 io_start_multiplex_out(); 00653 else if (!ret || err_msg) { 00654 /* We have to get I/O multiplexing started so that we can 00655 * get the error back to the client. This means getting 00656 * the protocol setup finished first in later versions. */ 00657 setup_protocol(f_out, f_in); 00658 if (!am_sender) { 00659 /* Since we failed in our option parsing, we may not 00660 * have finished parsing that the client sent us a 00661 * --files-from option, so look for it manually. 00662 * Without this, the socket would be in the wrong 00663 * state for the upcoming error message. */ 00664 if (!files_from) { 00665 int i; 00666 for (i = 0; i < argc; i++) { 00667 if (strncmp(argv[i], "--files-from", 12) == 0) { 00668 files_from = ""; 00669 break; 00670 } 00671 } 00672 } 00673 if (files_from) 00674 write_byte(f_out, 0); 00675 } 00676 io_start_multiplex_out(); 00677 } 00678 00679 if (!ret || err_msg) { 00680 if (err_msg) 00681 rprintf(FERROR, err_msg); 00682 else 00683 option_error(); 00684 msleep(400); 00685 exit_cleanup(RERR_UNSUPPORTED); 00686 } 00687 00688 if (lp_timeout(i) && lp_timeout(i) > io_timeout) 00689 set_io_timeout(lp_timeout(i)); 00690 00691 /* If we have some incoming/outgoing chmod changes, append them to 00692 * any user-specified changes (making our changes have priority). 00693 * We also get a pointer to just our changes so that a receiver 00694 * process can use them separately if --perms wasn't specified. */ 00695 if (am_sender) 00696 p = lp_outgoing_chmod(i); 00697 else 00698 p = lp_incoming_chmod(i); 00699 if (*p && !(daemon_chmod_modes = parse_chmod(p, &chmod_modes))) { 00700 rprintf(FLOG, "Invalid \"%sing chmod\" directive: %s\n", 00701 am_sender ? "outgo" : "incom", p); 00702 } 00703 00704 start_server(f_in, f_out, argc, argv); 00705 00706 return 0; 00707 }
static void send_listing | ( | int | fd | ) | [static] |
clientserver.c の 711 行で定義されています。
参照先 io_printf()・lp_name()・lp_numservices()・protocol_version.
参照元 start_daemon().
00712 { 00713 int n = lp_numservices(); 00714 int i; 00715 00716 for (i = 0; i < n; i++) { 00717 if (lp_list(i)) 00718 io_printf(fd, "%-15s\t%s\n", lp_name(i), lp_comment(i)); 00719 } 00720 00721 if (protocol_version >= 25) 00722 io_printf(fd,"@RSYNCD: EXIT\n"); 00723 }
int start_daemon | ( | int | f_in, | |
int | f_out | |||
) |
clientserver.c の 728 行で定義されています。
参照先 am_server・client_addr()・client_name()・config_file・FLOG・io_printf()・io_set_sock_fds()・lp_load()・lp_number()・protocol_version・read_line()・remember_children()・remote_protocol・rprintf()・rsync_module()・send_listing()・set_nonblocking()・set_socket_options()・sigact・sockopts.
参照元 daemon_main()・main().
00729 { 00730 char line[1024]; 00731 char *motd, *addr, *host; 00732 int i; 00733 00734 io_set_sock_fds(f_in, f_out); 00735 00736 /* We must load the config file before calling any function that 00737 * might cause log-file output to occur. This ensures that the 00738 * "log file" param gets honored for the 2 non-forked use-cases 00739 * (when rsync is run by init and run by a remote shell). */ 00740 if (!lp_load(config_file, 0)) 00741 exit_cleanup(RERR_SYNTAX); 00742 00743 addr = client_addr(f_in); 00744 host = client_name(f_in); 00745 rprintf(FLOG, "connect from %s (%s)\n", host, addr); 00746 00747 if (!am_server) { 00748 set_socket_options(f_in, "SO_KEEPALIVE"); 00749 if (sockopts) 00750 set_socket_options(f_in, sockopts); 00751 else 00752 set_socket_options(f_in, lp_socket_options()); 00753 set_nonblocking(f_in); 00754 } 00755 00756 io_printf(f_out, "@RSYNCD: %d\n", protocol_version); 00757 00758 motd = lp_motd_file(); 00759 if (motd && *motd) { 00760 FILE *f = fopen(motd,"r"); 00761 while (f && !feof(f)) { 00762 int len = fread(line, 1, sizeof line - 1, f); 00763 if (len > 0) { 00764 line[len] = 0; 00765 io_printf(f_out, "%s", line); 00766 } 00767 } 00768 if (f) 00769 fclose(f); 00770 io_printf(f_out, "\n"); 00771 } 00772 00773 if (!read_line(f_in, line, sizeof line - 1)) 00774 return -1; 00775 00776 if (sscanf(line,"@RSYNCD: %d", &remote_protocol) != 1) { 00777 io_printf(f_out, "@ERROR: protocol startup error\n"); 00778 return -1; 00779 } 00780 if (protocol_version > remote_protocol) 00781 protocol_version = remote_protocol; 00782 00783 line[0] = 0; 00784 if (!read_line(f_in, line, sizeof line - 1)) 00785 return -1; 00786 00787 if (!*line || strcmp(line, "#list") == 0) { 00788 rprintf(FLOG, "module-list request from %s (%s)\n", 00789 host, addr); 00790 send_listing(f_out); 00791 return -1; 00792 } 00793 00794 if (*line == '#') { 00795 /* it's some sort of command that I don't understand */ 00796 io_printf(f_out, "@ERROR: Unknown command '%s'\n", line); 00797 return -1; 00798 } 00799 00800 if ((i = lp_number(line)) < 0) { 00801 rprintf(FLOG, "unknown module '%s' tried from %s (%s)\n", 00802 line, host, addr); 00803 io_printf(f_out, "@ERROR: Unknown module '%s'\n", line); 00804 return -1; 00805 } 00806 00807 #ifdef HAVE_SIGACTION 00808 sigact.sa_flags = SA_NOCLDSTOP; 00809 #endif 00810 SIGACTION(SIGCHLD, remember_children); 00811 00812 return rsync_module(f_in, f_out, i, addr, host); 00813 }
int daemon_main | ( | void | ) |
clientserver.c の 815 行で定義されています。
参照先 become_daemon()・bind_address・cleanup_set_pid()・config_file・do_open()・errno・FLOG・is_a_socket()・log_init()・lp_load()・no_detach・orig_umask・rprintf()・rsync_port・rsyserr()・snprintf()・start_accept_loop()・start_daemon().
参照元 main().
00816 { 00817 char *pid_file; 00818 00819 if (is_a_socket(STDIN_FILENO)) { 00820 int i; 00821 00822 /* we are running via inetd - close off stdout and 00823 * stderr so that library functions (and getopt) don't 00824 * try to use them. Redirect them to /dev/null */ 00825 for (i = 1; i < 3; i++) { 00826 close(i); 00827 open("/dev/null", O_RDWR); 00828 } 00829 00830 return start_daemon(STDIN_FILENO, STDIN_FILENO); 00831 } 00832 00833 if (!no_detach) 00834 become_daemon(); 00835 00836 if (!lp_load(config_file, 1)) 00837 exit_cleanup(RERR_SYNTAX); 00838 00839 if (rsync_port == 0 && (rsync_port = lp_rsync_port()) == 0) 00840 rsync_port = RSYNC_PORT; 00841 if (bind_address == NULL && *lp_bind_address()) 00842 bind_address = lp_bind_address(); 00843 00844 log_init(); 00845 00846 rprintf(FLOG, "rsyncd version %s starting, listening on port %d\n", 00847 RSYNC_VERSION, rsync_port); 00848 /* TODO: If listening on a particular address, then show that 00849 * address too. In fact, why not just do inet_ntop on the 00850 * local address??? */ 00851 00852 if (((pid_file = lp_pid_file()) != NULL) && (*pid_file != '\0')) { 00853 char pidbuf[16]; 00854 int fd; 00855 pid_t pid = getpid(); 00856 cleanup_set_pid(pid); 00857 if ((fd = do_open(lp_pid_file(), O_WRONLY|O_CREAT|O_TRUNC, 00858 0666 & ~orig_umask)) == -1) { 00859 cleanup_set_pid(0); 00860 rsyserr(FLOG, errno, "failed to create pid file %s", 00861 pid_file); 00862 exit_cleanup(RERR_FILEIO); 00863 } 00864 snprintf(pidbuf, sizeof pidbuf, "%ld\n", (long)pid); 00865 write(fd, pidbuf, strlen(pidbuf)); 00866 close(fd); 00867 } 00868 00869 start_accept_loop(rsync_port, start_daemon); 00870 return -1; 00871 }
int quiet |
int list_only |
int am_sender |
参照元 add_rule()・client_run()・get_rule_prefix()・handle_stats()・local_child()・log_formatted()・log_item()・make_file()・output_flist()・parse_arguments()・recv_filter_list()・rsync_module()・send_filter_list()・send_rules()・server_options()・start_client()・start_inband_exchange()・start_server()・start_write_batch()・who_am_i().
int am_daemon |
int rsync_port |
int kluge_around_eof |
int daemon_over_rsh |
int sanitize_paths |
int remote_protocol |
int protocol_version |
int io_timeout |
int no_detach |
Do not go into the background when run as --daemon.
Good for debugging and required for running as a service on W32, or under Unix process-monitors.
参照元 daemon_main().
int default_af_hint |
mode_t orig_umask |
char* bind_address |
Local address to bind.
As a character string because it's interpreted by the IPv6 layer: should be a numeric IP4 or IP6 address, or a hostname.
参照元 daemon_main()・start_accept_loop()・start_socket_client().
char* sockopts |
char* config_file |
char* files_from |
char* tmpdir |
struct chmod_mode_struct* chmod_modes |
char* auth_user |
int read_only = 0 |
int daemon_log_format_has_i = 0 |
int daemon_log_format_has_o_or_i = 0 |
int module_id = -1 |
struct chmod_mode_struct* daemon_chmod_modes |
unsigned int module_dirlen = 0 |
clientserver.c の 64 行で定義されています。
参照元 add_rule()・parse_rule()・rsync_module()・rule_matches()・set_filter_dir().
struct sigaction sigact [static] |
clientserver.c の 67 行で定義されています。