X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/blobdiff_plain/9361f83933042cf3e73ad47a9c3bc00dbc79e8ea..32cbfe7b17ba8ec661fc27fd773909709d100e8a:/io.c diff --git a/io.c b/io.c index e5574025..035362e9 100644 --- a/io.c +++ b/io.c @@ -56,6 +56,7 @@ extern struct stats stats; const char phase_unknown[] = "unknown"; int select_timeout = SELECT_TIMEOUT; +int ignore_timeout = 0; int batch_fd = -1; int batch_gen_fd = -1; @@ -137,7 +138,7 @@ static void check_timeout(void) { time_t t; - if (!io_timeout) + if (!io_timeout || ignore_timeout) return; if (!last_io) { @@ -203,6 +204,10 @@ static void msg_list_add(int code, char *buf, int len) void send_msg(enum msgcode code, char *buf, int len) { + if (msg_fd_out < 0) { + io_multiplex_write(code, buf, len); + return; + } msg_list_add(code, buf, len); msg_list_push(NORMAL_FLUSH); } @@ -244,6 +249,22 @@ static void read_msg_fd(void) read_loop(fd, buf, 4); redo_list_add(IVAL(buf,0)); break; + case MSG_DELETED: + if (len >= (int)sizeof buf || !am_generator) { + rprintf(FERROR, "invalid message %d:%d\n", tag, len); + exit_cleanup(RERR_STREAMIO); + } + read_loop(fd, buf, len); + io_multiplex_write(MSG_DELETED, buf, len); + break; + case MSG_SUCCESS: + if (len != 4 || !am_generator) { + rprintf(FERROR, "invalid message %d:%d\n", tag, len); + exit_cleanup(RERR_STREAMIO); + } + read_loop(fd, buf, len); + io_multiplex_write(MSG_SUCCESS, buf, len); + break; case MSG_INFO: case MSG_ERROR: case MSG_LOG: @@ -614,6 +635,21 @@ void io_end_buffering(void) } +void maybe_send_keepalive(int allowed_lull, int ndx) +{ + if (time(NULL) - last_io >= allowed_lull) { + if (!iobuf_out || !iobuf_out_cnt) { + if (protocol_version < 29) + return; /* there's nothing we can do */ + write_int(sock_f_out, ndx); + write_shortint(sock_f_out, ITEM_IS_NEW); + } + if (iobuf_out) + io_flush(NORMAL_FLUSH); + } +} + + /** * Continue trying to read len bytes - don't return until len has been * read. @@ -640,7 +676,7 @@ static int readfd_unbuffered(int fd, char *buf, size_t len) static size_t remaining; static size_t iobuf_in_ndx; int tag, ret = 0; - char line[1024]; + char line[MAXPATHLEN+1]; if (!iobuf_in || fd != sock_f_in) return read_timeout(fd, buf, len); @@ -677,6 +713,31 @@ static int readfd_unbuffered(int fd, char *buf, size_t len) read_loop(fd, iobuf_in, remaining); iobuf_in_ndx = 0; break; + case MSG_DELETED: + if (remaining >= sizeof line) { + rprintf(FERROR, "invalid multi-message %d:%ld\n", + tag, (long)remaining); + exit_cleanup(RERR_STREAMIO); + } + read_loop(fd, line, remaining); + line[remaining] = '\0'; + /* A directory name was sent with the trailing null */ + if (remaining > 0 && !line[remaining-1]) + log_delete(line, S_IFDIR); + else + log_delete(line, S_IFREG); + remaining = 0; + break; + case MSG_SUCCESS: + if (remaining != 4) { + rprintf(FERROR, "invalid multi-message %d:%ld\n", + tag, (long)remaining); + exit_cleanup(RERR_STREAMIO); + } + read_loop(fd, line, remaining); + successful_send(IVAL(line, 0)); + remaining = 0; + break; case MSG_INFO: case MSG_ERROR: if (remaining >= sizeof line) { @@ -729,7 +790,7 @@ static void readfd(int fd, char *buffer, size_t N) } -unsigned short read_short(int f) +int read_shortint(int f) { uchar b[2]; readfd(f, (char *)b, 2); @@ -969,6 +1030,7 @@ static void writefd_unbuffered(int fd,char *buf,size_t len) * to grab any messages they sent before they died. */ while (fd == sock_f_out && io_multiplexing_in) { io_timeout = select_timeout = 30; + ignore_timeout = 0; readfd_unbuffered(sock_f_in, io_filesfrom_buf, sizeof io_filesfrom_buf); } @@ -1063,7 +1125,7 @@ static void writefd(int fd,char *buf,size_t len) } -void write_short(int f, unsigned short x) +void write_shortint(int f, int x) { uchar b[2]; b[0] = x;