X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/blobdiff_plain/40df65fdb47e025392e2cf5cc3059d627b61ccac..860236bf90087c88e886b6a7bffb83d6df51c1cc:/main.c diff --git a/main.c b/main.c index 5ad21c92..2b207be2 100644 --- a/main.c +++ b/main.c @@ -58,8 +58,7 @@ extern int batch_gen_fd; extern int filesfrom_fd; extern pid_t cleanup_child_pid; extern struct stats stats; -extern char *files_from; -extern char *remote_filesfrom_file; +extern char *filesfrom_host; extern char *partial_dir; extern char *basis_dir[]; extern char *rsync_path; @@ -429,19 +428,25 @@ static char *get_local_name(struct file_list *flist,char *name) } +/* This is only called by the sender. */ static void read_final_goodbye(int f_in, int f_out, int flist_count) { - if (protocol_version < 29) { - read_int(f_in); - return; + int i; + + if (protocol_version < 29) + i = read_int(f_in); + else { + while ((i = read_int(f_in)) == flist_count + && read_shortint(f_in) == ITEM_IS_NEW) { + /* Forward the keep-alive (no-op) to the receiver. */ + write_int(f_out, flist_count); + write_shortint(f_out, ITEM_IS_NEW); + } } - /* Handle any keep-alive messages from --delete-after processing. */ - while (read_int(f_in) == flist_count) { - if (read_shortint(f_in) != ITEM_IS_NEW) - return; /* Complain? */ - write_int(f_out, flist_count); - write_shortint(f_out, ITEM_IS_NEW); + if (i != -1) { + rprintf(FERROR, "Invalid packet from generator at end of run.\n"); + exit_cleanup(RERR_PROTOCOL); } } @@ -564,15 +569,18 @@ static int do_recv(int f_in,int f_out,struct file_list *flist,char *local_name) * that the generator does. */ if (protocol_version >= 29) { kluge_around_eof = -1; - while (read_int(f_in) == flist->count) { - if (read_shortint(f_in) != ITEM_IS_NEW) - break; /* Complain? */ - } + + /* This should only get stopped via a USR2 signal. */ + while (read_int(f_in) == flist->count + && read_shortint(f_in) == ITEM_IS_NEW) {} + + rprintf(FERROR, "Invalid packet from server at end of run.\n"); + exit_cleanup(RERR_PROTOCOL); } - /* Finally, we hang around waiting for our parent to kills - * us with a USR2 signal. We sleep for a short time, as on - * some OSes a signal won't interrupt a sleep! */ + /* Finally, we go to sleep until our parent kills us with a + * USR2 signal. We sleep for a short time, as on some OSes + * a signal won't interrupt a sleep! */ while (1) msleep(20); } @@ -750,10 +758,10 @@ int client_run(int f_in, int f_out, pid_t pid, int argc, char *argv[]) if (am_sender) { keep_dirlinks = 0; /* Must be disabled on the sender. */ io_start_buffering_out(); - if (!remote_filesfrom_file) + if (!filesfrom_host) set_msg_fd_in(f_in); send_filter_list(f_out); - if (remote_filesfrom_file) + if (filesfrom_host) filesfrom_fd = f_in; if (write_batch) @@ -857,49 +865,21 @@ static int start_client(int argc, char *argv[]) if ((rc = copy_argv(argv))) return rc; - /* rsync:// always uses rsync server over direct socket connection */ - if (strncasecmp(URL_PREFIX, argv[0], strlen(URL_PREFIX)) == 0 - && !read_batch) { - char *host, *path; - - host = argv[0] + strlen(URL_PREFIX); - p = strchr(host,'/'); - if (p) { - *p = '\0'; - path = p+1; - } else - path = ""; - if (*host == '[' && (p = strchr(host, ']')) != NULL) { - host++; - *p++ = '\0'; - if (*p != ':') - p = NULL; - } else - p = strchr(host, ':'); - if (p) { - rsync_port = atoi(p+1); - *p = '\0'; - } - return start_socket_client(host, path, argc-1, argv+1); - } - if (!read_batch) { /* for read_batch, NO source is specified */ - p = find_colon(argv[0]); - if (p) { /* source is remote */ - if (remote_filesfrom_file - && remote_filesfrom_file != files_from + 1 - && strncmp(files_from, argv[0], p-argv[0]+1) != 0) { + shell_path = check_for_hostspec(argv[0], &shell_machine, &rsync_port); + if (shell_path) { /* source is remote */ + if (filesfrom_host && *filesfrom_host + && strcmp(filesfrom_host, shell_machine) != 0) { rprintf(FERROR, "--files-from hostname is not the same as the transfer hostname\n"); exit_cleanup(RERR_SYNTAX); } - if (p[1] == ':') { /* double colon */ - *p = 0; + if (rsync_port) { if (!shell_cmd) { - return start_socket_client(argv[0], p+2, + return start_socket_client(shell_machine, + shell_path, argc-1, argv+1); } - p++; daemon_over_rsh = 1; } @@ -909,60 +889,32 @@ static int start_client(int argc, char *argv[]) } am_sender = 0; - *p = 0; - shell_machine = argv[0]; - shell_path = p+1; argv++; - } else { /* source is local */ + } else { /* source is local, check dest arg */ am_sender = 1; - /* rsync:// destination uses rsync server over direct socket */ - if (strncasecmp(URL_PREFIX, argv[argc-1], strlen(URL_PREFIX)) == 0) { - char *host, *path; - - host = argv[argc-1] + strlen(URL_PREFIX); - p = strchr(host,'/'); - if (p) { - *p = '\0'; - path = p+1; - } else - path = ""; - if (*host == '[' && (p = strchr(host, ']')) != NULL) { - host++; - *p++ = '\0'; - if (*p != ':') - p = NULL; - } else - p = strchr(host, ':'); - if (p) { - rsync_port = atoi(p+1); - *p = '\0'; - } - return start_socket_client(host, path, argc-1, argv); - } - - p = find_colon(argv[argc-1]); /* look in dest arg */ - if (p && remote_filesfrom_file - && remote_filesfrom_file != files_from + 1 - && strncmp(files_from, argv[argc-1], p-argv[argc-1]+1) != 0) { + shell_path = check_for_hostspec(argv[argc-1], &shell_machine, &rsync_port); + if (shell_path && filesfrom_host && *filesfrom_host + && strcmp(filesfrom_host, shell_machine) != 0) { rprintf(FERROR, "--files-from hostname is not the same as the transfer hostname\n"); exit_cleanup(RERR_SYNTAX); } - if (!p) { /* no colon found, so src & dest are local */ + if (!shell_path) { /* no hostspec found, so src & dest are local */ local_server = 1; - if (remote_filesfrom_file) { + if (filesfrom_host) { rprintf(FERROR, "--files-from cannot be remote when the transfer is local\n"); exit_cleanup(RERR_SYNTAX); } - } else if (p[1] == ':') { /* double colon */ - *p = 0; + shell_machine = NULL; + shell_path = argv[argc-1]; + } else if (rsync_port) { if (!shell_cmd) { - return start_socket_client(argv[argc-1], p+2, + return start_socket_client(shell_machine, + shell_path, argc-1, argv); } - p++; daemon_over_rsh = 1; } @@ -970,21 +922,12 @@ static int start_client(int argc, char *argv[]) usage(FERROR); exit_cleanup(RERR_SYNTAX); } - - if (local_server) { - shell_machine = NULL; - shell_path = argv[argc-1]; - } else { - *p = 0; - shell_machine = argv[argc-1]; - shell_path = p+1; - } } argc--; } else { /* read_batch */ local_server = 1; shell_path = argv[argc-1]; - if (find_colon(shell_path)) { + if (check_for_hostspec(shell_path, &shell_machine, &rsync_port)) { rprintf(FERROR, "remote destination is not allowed with --read-batch\n"); exit_cleanup(RERR_SYNTAX); }