- switched on multiplexing for all connections, not just daemon
authorAndrew Tridgell <tridge@samba.org>
Fri, 28 Jan 2000 15:29:59 +0000 (15:29 +0000)
committerAndrew Tridgell <tridge@samba.org>
Fri, 28 Jan 2000 15:29:59 +0000 (15:29 +0000)
  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
io.c
log.c
main.c
rsync.h
test.sh

index 8cf7bab..2cd2c40 100644 (file)
@@ -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 6f3854e..aefd3ef 100644 (file)
--- 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 788225f..8619e4d 100644 (file)
--- 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 80839de..2a5597e 100644 (file)
--- 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 9e7775c..3c5b7dc 100644 (file)
--- 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):"<NULL>")
 
 /* 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 792bb67..1e9e24e 100755 (executable)
--- 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