void start_server(int f_in, int f_out, int argc, char *argv[]) { set_nonblocking(f_in); set_nonblocking(f_out); io_set_sock_fds(f_in, f_out); setup_protocol(f_out, f_in); if (protocol_version >= 23) io_start_multiplex_out(); if (am_sender) { keep_dirlinks = 0; /* Must be disabled on the sender. */ if (need_messages_from_generator) io_start_multiplex_in(); recv_filter_list(f_in); do_server_sender(f_in, f_out, argc, argv); } else { do_server_recv(f_in, f_out, argc, argv); } exit_cleanup(0); }
int start_socket_client(char *host, char *path, int argc, char *argv[]) { int fd, i; char *sargs[MAX_ARGS]; int sargc=0; char line[MAXPATHLEN]; char *p, *user=NULL; extern int remote_version; extern int am_sender; if (*path == '/') { rprintf(FERROR,"ERROR: The remote path must start with a module name\n"); return -1; } p = strchr(host, '@'); if (p) { user = host; host = p+1; *p = 0; } if (!user) user = getenv("USER"); if (!user) user = getenv("LOGNAME"); fd = open_socket_out(host, rsync_port); if (fd == -1) { exit_cleanup(RERR_SOCKETIO); } server_options(sargs,&sargc); sargs[sargc++] = "."; if (path && *path) sargs[sargc++] = path; sargs[sargc] = NULL; io_printf(fd,"@RSYNCD: %d\n", PROTOCOL_VERSION); if (!read_line(fd, line, sizeof(line)-1)) { return -1; } if (sscanf(line,"@RSYNCD: %d", &remote_version) != 1) { return -1; } p = strchr(path,'/'); if (p) *p = 0; io_printf(fd,"%s\n",path); if (p) *p = '/'; while (1) { if (!read_line(fd, line, sizeof(line)-1)) { return -1; } if (strncmp(line,"@RSYNCD: AUTHREQD ",18) == 0) { auth_client(fd, user, line+18); continue; } if (strcmp(line,"@RSYNCD: OK") == 0) break; rprintf(FINFO,"%s\n", line); } for (i=0;i<sargc;i++) { io_printf(fd,"%s\n", sargs[i]); } io_printf(fd,"\n"); if (remote_version > 17 && !am_sender) io_start_multiplex_in(fd); return client_run(fd, fd, -1, argc, argv); }
/* * This is called once the connection has been negotiated. It is used * for rsyncd, remote-shell, and local connections. */ int client_run(int f_in, int f_out, pid_t pid, int argc, char *argv[]) { struct file_list *flist = NULL; int status = 0, status2 = 0; char *local_name = NULL; cleanup_child_pid = pid; if (!read_batch) { set_nonblocking(f_in); set_nonblocking(f_out); } io_set_sock_fds(f_in, f_out); setup_protocol(f_out,f_in); if (protocol_version >= 23 && !read_batch) io_start_multiplex_in(); /* We set our stderr file handle to blocking because ssh might have * set it to non-blocking. This can be particularly troublesome if * stderr is a clone of stdout, because ssh would have set our stdout * to non-blocking at the same time (which can easily cause us to lose * output from our print statements). This kluge shouldn't cause ssh * any problems for how we use it. Note also that we delayed setting * this until after the above protocol setup so that we know for sure * that ssh is done twiddling its file descriptors. */ set_blocking(STDERR_FILENO); if (am_sender) { keep_dirlinks = 0; /* Must be disabled on the sender. */ io_start_buffering_out(); if (!filesfrom_host) set_msg_fd_in(f_in); send_filter_list(f_out); if (filesfrom_host) filesfrom_fd = f_in; if (write_batch && !am_server) start_write_batch(f_out); flist = send_file_list(f_out, argc, argv); set_msg_fd_in(-1); if (verbose > 3) rprintf(FINFO,"file list sent\n"); the_file_list = flist; io_flush(NORMAL_FLUSH); send_files(flist,f_out,f_in); io_flush(FULL_FLUSH); handle_stats(-1); if (protocol_version >= 24) read_final_goodbye(f_in, f_out); if (pid != -1) { if (verbose > 3) rprintf(FINFO,"client_run waiting on %d\n", (int) pid); io_flush(FULL_FLUSH); wait_process(pid, &status); } output_summary(); io_flush(FULL_FLUSH); exit_cleanup(status); } if (need_messages_from_generator && !read_batch) io_start_multiplex_out(); if (argc == 0) list_only |= 1; send_filter_list(read_batch ? -1 : f_out); if (filesfrom_fd >= 0) { io_set_filesfrom_fds(filesfrom_fd, f_out); filesfrom_fd = -1; } if (write_batch && !am_server) start_write_batch(f_in); flist = recv_file_list(f_in); the_file_list = flist; if (flist && flist->count > 0) { local_name = get_local_name(flist, argv[0]); status2 = do_recv(f_in, f_out, flist, local_name); } else { handle_stats(-1); output_summary(); } if (pid != -1) { if (verbose > 3) rprintf(FINFO,"client_run2 waiting on %d\n", (int) pid); io_flush(FULL_FLUSH); wait_process(pid, &status); } return MAX(status, status2); }