From ff41a59f58614ff4e57b4c97b586dcd46e43cc5c Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 28 Jan 2000 15:29:59 +0000 Subject: [PATCH] - switched on multiplexing for all connections, not just daemon connections (this fixes the stderr/stdout problem). Upped protocol version for backward compat - use multiplexing on error fd - upped minimal protocol version - got rid of some ugly code in the write buffering --- clientserver.c | 4 +-- io.c | 73 ++++++++++++++++++++++++++++++++++---------------- log.c | 30 ++++++++++----------- main.c | 8 ++++++ rsync.h | 11 ++++---- test.sh | 2 +- 6 files changed, 81 insertions(+), 47 deletions(-) diff --git a/clientserver.c b/clientserver.c index 8cf7baba..2cd2c40a 100644 --- a/clientserver.c +++ b/clientserver.c @@ -101,7 +101,7 @@ int start_socket_client(char *host, char *path, int argc, char *argv[]) } io_printf(fd,"\n"); - if (remote_version >= 22 || (remote_version > 17 && !am_sender)) + if (remote_version == 22 || (remote_version > 17 && !am_sender)) io_start_multiplex_in(fd); return client_run(fd, fd, -1, argc, argv); @@ -316,7 +316,7 @@ static int rsync_module(int fd, int i) argp = argv + optind; optind = 0; - if (remote_version >= 22 || (remote_version > 17 && am_sender)) + if (remote_version == 22 || (remote_version > 17 && am_sender)) io_start_multiplex_out(fd); if (read_only) { diff --git a/io.c b/io.c index 6f3854e3..aefd3ef4 100644 --- a/io.c +++ b/io.c @@ -40,6 +40,8 @@ extern struct stats stats; static int buffer_f_in = -1; static int io_error_fd = -1; +static void read_loop(int fd, char *buf, int len); + void setup_readbuffer(int f_in) { buffer_f_in = f_in; @@ -71,17 +73,29 @@ void io_set_error_fd(int fd) io_error_fd = fd; } -/* read some data from the error fd and write it to FERROR */ +/* read some data from the error fd and write it to the write log code */ static void read_error_fd(void) { char buf[200]; int n; int fd = io_error_fd; + int tag, len; + io_error_fd = -1; - n = read(fd, buf, sizeof(buf)-1); - if (n > 0) { - rwrite(FERROR, buf, n); + read_loop(fd, buf, 4); + tag = IVAL(buf, 0); + + len = tag & 0xFFFFFF; + tag = tag >> 24; + tag -= MPLEX_BASE; + + while (len) { + n = len; + if (n > (sizeof(buf)-1)) n = sizeof(buf)-1; + read_loop(fd, buf, n); + rwrite((enum logcode)tag, buf, n); + len -= n; } io_error_fd = fd; @@ -181,7 +195,6 @@ static void read_loop(int fd, char *buf, int len) static int read_unbuffered(int fd, char *buf, int len) { static int remaining; - char ibuf[4]; int tag, ret=0; char line[1024]; @@ -197,8 +210,8 @@ static int read_unbuffered(int fd, char *buf, int len) continue; } - read_loop(fd, ibuf, 4); - tag = IVAL(ibuf, 0); + read_loop(fd, line, 4); + tag = IVAL(line, 0); remaining = tag & 0xFFFFFF; tag = tag >> 24; @@ -221,7 +234,7 @@ static int read_unbuffered(int fd, char *buf, int len) read_loop(fd, line, remaining); line[remaining] = 0; - rprintf(tag,"%s", line); + rprintf((enum logcode)tag,"%s", line); remaining = 0; } @@ -382,22 +395,41 @@ void io_start_buffering(int fd) { if (io_buffer) return; multiplex_out_fd = fd; - io_buffer = (char *)malloc(IO_BUFFER_SIZE+4); + io_buffer = (char *)malloc(IO_BUFFER_SIZE); if (!io_buffer) out_of_memory("writefd"); io_buffer_count = 0; +} + +/* write an message to a multiplexed stream. If this fails then rsync + exits */ +static void mplex_write(int fd, enum logcode code, char *buf, int len) +{ + char buffer[4096]; + int n = len; - /* leave room for the multiplex header in case it's needed */ - io_buffer += 4; + SIVAL(buffer, 0, ((MPLEX_BASE + (int)code)<<24) + len); + + if (n > (sizeof(buf)-4)) { + n = sizeof(buf)-4; + } + + memcpy(&buffer[4], buf, n); + writefd_unbuffered(fd, buffer, n+4); + + len -= n; + buf += n; + + writefd_unbuffered(fd, buf, len); } + void io_flush(void) { int fd = multiplex_out_fd; if (!io_buffer_count || no_flush) return; if (io_multiplexing_out) { - SIVAL(io_buffer-4, 0, (MPLEX_BASE<<24) + io_buffer_count); - writefd_unbuffered(fd, io_buffer-4, io_buffer_count+4); + mplex_write(fd, 0, io_buffer, io_buffer_count); } else { writefd_unbuffered(fd, io_buffer, io_buffer_count); } @@ -408,7 +440,7 @@ void io_end_buffering(int fd) { io_flush(); if (!io_multiplexing_out) { - free(io_buffer-4); + free(io_buffer); io_buffer = NULL; } } @@ -539,26 +571,21 @@ void io_start_multiplex_in(int fd) } /* write an message to the multiplexed error stream */ -int io_multiplex_write(int f, char *buf, int len) +int io_multiplex_write(enum logcode code, char *buf, int len) { if (!io_multiplexing_out) return 0; io_flush(); - - SIVAL(io_buffer-4, 0, ((MPLEX_BASE + f)<<24) + len); - memcpy(io_buffer, buf, len); - stats.total_written += (len+4); - - writefd_unbuffered(multiplex_out_fd, io_buffer-4, len+4); + mplex_write(multiplex_out_fd, code, buf, len); return 1; } /* write a message to the special error fd */ -int io_error_write(int f, char *buf, int len) +int io_error_write(int f, enum logcode code, char *buf, int len) { if (f == -1) return 0; - writefd_unbuffered(f, buf, len); + mplex_write(f, code, buf, len); return 1; } diff --git a/log.c b/log.c index 788225f5..8619e4d6 100644 --- a/log.c +++ b/log.c @@ -87,37 +87,37 @@ void set_error_fd(int fd) /* this is the underlying (unformatted) rsync debugging function. Call it with FINFO, FERROR or FLOG */ -void rwrite(int fd, char *buf, int len) +void rwrite(enum logcode code, char *buf, int len) { FILE *f=NULL; extern int am_daemon; extern int quiet; /* recursion can happen with certain fatal conditions */ - if (quiet != 0 && fd == FINFO) return; + if (quiet != 0 && code == FINFO) return; if (len < 0) exit_cleanup(RERR_MESSAGEIO); buf[len] = 0; - if (fd == FLOG) { + if (code == FLOG) { if (am_daemon) logit(LOG_INFO, buf); return; } + if (io_error_write(log_error_fd, code, buf, strlen(buf))) return; + if (am_daemon) { static int depth; int priority = LOG_INFO; - if (fd == FERROR) priority = LOG_WARNING; + if (code == FERROR) priority = LOG_WARNING; if (depth) return; depth++; log_open(); - - if (!io_error_write(log_error_fd, buf, strlen(buf)) && - !io_multiplex_write(fd, buf, strlen(buf))) { + if (!io_multiplex_write(code, buf, strlen(buf))) { logit(priority, buf); } @@ -125,11 +125,11 @@ void rwrite(int fd, char *buf, int len) return; } - if (fd == FERROR) { + if (code == FERROR) { f = stderr; } - if (fd == FINFO) { + if (code == FINFO) { extern int am_server; if (am_server) f = stderr; @@ -146,7 +146,7 @@ void rwrite(int fd, char *buf, int len) /* this is the rsync debugging function. Call it with FINFO, FERROR or FLOG */ - void rprintf(int fd, const char *format, ...) + void rprintf(enum logcode code, const char *format, ...) { va_list ap; char buf[1024]; @@ -158,10 +158,10 @@ void rwrite(int fd, char *buf, int len) if (len > sizeof(buf)-1) exit_cleanup(RERR_MESSAGEIO); - rwrite(fd, buf, len); + rwrite(code, buf, len); } -void rflush(int fd) +void rflush(enum logcode code) { FILE *f = NULL; extern int am_daemon; @@ -170,15 +170,15 @@ void rflush(int fd) return; } - if (fd == FLOG) { + if (code == FLOG) { return; } - if (fd == FERROR) { + if (code == FERROR) { f = stderr; } - if (fd == FINFO) { + if (code == FINFO) { extern int am_server; if (am_server) f = stderr; diff --git a/main.c b/main.c index 80839de3..2a5597e4 100644 --- a/main.c +++ b/main.c @@ -391,6 +391,10 @@ void start_server(int f_in, int f_out, int argc, char *argv[]) { extern int cvs_exclude; extern int am_sender; + extern int remote_version; + + if (remote_version >= 23) + io_start_multiplex_out(f_out); setup_protocol(f_out, f_in); @@ -412,6 +416,10 @@ int client_run(int f_in, int f_out, int pid, int argc, char *argv[]) char *local_name = NULL; extern int am_sender; extern int list_only; + extern int remote_version; + + if (remote_version >= 23) + io_start_multiplex_in(f_in); setup_protocol(f_out,f_in); diff --git a/rsync.h b/rsync.h index 9e7775c7..3c5b7dc7 100644 --- a/rsync.h +++ b/rsync.h @@ -47,8 +47,8 @@ #define SAME_TIME (1<<7) /* update this if you make incompatible changes */ -#define PROTOCOL_VERSION 22 -#define MIN_PROTOCOL_VERSION 11 +#define PROTOCOL_VERSION 23 +#define MIN_PROTOCOL_VERSION 15 #define MAX_PROTOCOL_VERSION 30 #define RSYNC_PORT 873 @@ -62,9 +62,8 @@ #define MAX_ARGS 1000 #define MPLEX_BASE 7 -#define FERROR 1 -#define FINFO 2 -#define FLOG 3 + +enum logcode {FERROR=1, FINFO=2, FLOG=3}; #include "errcode.h" @@ -477,7 +476,7 @@ extern int errno; #define NS(s) ((s)?(s):"") /* use magic gcc attributes to catch format errors */ - void rprintf(int , const char *, ...) + void rprintf(enum logcode , const char *, ...) #ifdef __GNUC__ __attribute__ ((format (printf, 2, 3))) #endif diff --git a/test.sh b/test.sh index 792bb677..1e9e24e2 100755 --- a/test.sh +++ b/test.sh @@ -160,7 +160,7 @@ fi rm -rf ${TO} mkdir -p ${FROM}2/dir/subdir cp -a ${FROM}/dir/subdir/subsubdir ${FROM}2/dir/subdir -cp ${FROM}/dir/* ${FROM}2/dir 2>/dev/null +cp -a ${FROM}/dir/* ${FROM}2/dir 2>/dev/null runtest "excludes" 'checkit "rsync -vv -Hlrt --delete --include /dir/ --include /dir/\* --include /dir/\*/subsubdir --include /dir/\*/subsubdir/\*\* --exclude \*\* ${FROM}/dir ${TO}" ${FROM}2/ ${TO}' rm -r ${FROM}2 -- 2.34.1