>>>>> "John" == John L Allen <Allen> writes: John> But I do agree it would be nice if the man page documented John> them. Or, better still, if rsync itself simply told you what they meant ;-)
--- log.c.orig Sat Jan 29 06:35:03 2000 +++ log.c Wed Oct 18 14:01:26 2000 @@ -25,6 +25,29 @@ static FILE *logfile; static int log_error_fd = -1; +static const struct errdesc { int c; const char *s; const char *d; } errcodes[] = { + { RERR_SYNTAX, "RERR_SYNTAX", "syntax or usage error" }, + { RERR_PROTOCOL, "RERR_PROTOCOL", "protocol incompatibility" }, + { RERR_FILESELECT, "RERR_FILESELECT", "errors selecting input/output files, dirs" +}, + { RERR_UNSUPPORTED, "RERR_UNSUPPORTED", "requested action not supported" }, + { RERR_SOCKETIO, "RERR_SOCKETIO", "error in socket IO" }, + { RERR_FILEIO, "RERR_FILEIO", "error in file IO" }, + { RERR_STREAMIO, "RERR_STREAMIO", "error in rsync protocol data stream" }, + { RERR_MESSAGEIO, "RERR_MESSAGEIO", "errors with program diagnostics" }, + { RERR_IPC, "RERR_IPC", "error in IPC code" }, + { RERR_SIGNAL, "RERR_SIGNAL", "status returned when sent SIGUSR1, SIGINT" +}, + { RERR_WAITCHILD, "RERR_WAITCHILD", "some error returned by waitpid()" }, + { RERR_MALLOC, "RERR_MALLOC", "error allocating core memory buffers" }, + { RERR_TIMEOUT, "RERR_TIMEOUT", "timeout in data send/receive" }, +}; + +static const struct errdesc *geterrdesc(int code) +{ + int i; + for ( i = 0; i < sizeof(errcodes)/sizeof(*errcodes); ++i ) + if ( code == errcodes[i].c ) break; + return ( i < sizeof(errcodes)/sizeof(*errcodes) ? &errcodes[i] : NULL ); +} static void logit(int priority, char *buf) { @@ -324,12 +347,16 @@ /* called when the transfer is interrupted for some reason */ void log_exit(int code, const char *file, int line) { + const struct errdesc *pd = NULL; if (code == 0) { extern struct stats stats; rprintf(FLOG,"wrote %.0f bytes read %.0f bytes total size %.0f\n", (double)stats.total_written, (double)stats.total_read, (double)stats.total_size); + } else if ( (pd = geterrdesc(code)) != NULL ) { + rprintf(FLOG,"transfer interrupted - %s (code %d, %s) at %s(%d)\n", + pd->d, code, pd->s, file, line); } else { rprintf(FLOG,"transfer interrupted (code %d) at %s(%d)\n", code, file, line); @@ -349,4 +376,3 @@ rprintf(FINFO,"%s\n", fname); } -
In concert with that, I'd also tried to ensure that all error messages always get logged somewhere (i.e. never just get lost, as could currently happen for certain server errors if the sibling is unreachable). I refactored the logging code to try to make it more clear where the messages were to be routed. In the process, it is possible that I may have unknowingly/inadvertently violated some design intentions (e.g. I seem to remember Dave Dykstra mentioning that certain server errors were not logged to the client for security reasons - I may have busted that, sorry). Anyway, here is the patch (which is totally separate from the first one: you can safely opt-in to the first and opt-out from this one).
--- log.c.orig Tue Oct 24 12:11:06 2000 +++ log.c Tue Oct 24 12:45:12 2000 @@ -51,6 +51,7 @@ static void logit(int priority, char *buf) { + log_open(); if (logfile) { fprintf(logfile,"%s [%d] %s", timestring(time(NULL)), (int)getpid(), buf); @@ -113,10 +114,13 @@ void rwrite(enum logcode code, char *buf, int len) { FILE *f=NULL; + int need_remote = 0; + int need_local = 1; extern int am_daemon; extern int am_server; extern int quiet; /* recursion can happen with certain fatal conditions */ + static int depth = 0; if (quiet && code == FINFO) return; @@ -124,53 +128,78 @@ buf[len] = 0; - if (code == FLOG) { - if (am_daemon) logit(LOG_INFO, buf); - return; - } + ++depth; - /* first try to pass it off the our sibling */ - if (am_server && io_error_write(log_error_fd, code, buf, len)) { - return; - } + switch ( code ) { + + case FINFO: + f = ( am_server ? stderr : stdout ); + need_remote = ( am_server ? 1 : 0 ); + need_local = 1; + break; + + case FLOG: + f = NULL; + need_remote = 0; + need_local = ( am_daemon ? 1 : 0 ); + break; + + case FERROR: + f = stderr; + need_remote = ( am_server ? 1 : 0 ); + need_local = 1; + break; + + default: + f = stderr; + need_remote = ( am_server ? 1 : 0 ); + need_local = 1; + break; - /* then try to pass it to the other end */ - if (am_server && io_multiplex_write(code, buf, len)) { - return; } - if (am_daemon) { - static int depth; - int priority = LOG_INFO; - if (code == FERROR) priority = LOG_WARNING; + if ( need_local ) { - if (depth) return; + if ( am_daemon ) { - depth++; + int priority = ( code == FERROR ? LOG_WARNING : LOG_INFO ); - log_open(); logit(priority, buf); - depth--; - return; + } else { + + if (!f) exit_cleanup(RERR_MESSAGEIO); + + if (fwrite(buf, len, 1, f) != 1) exit_cleanup(RERR_MESSAGEIO); + + if (buf[len-1] == '\r' || buf[len-1] == '\n') fflush(f); + } - if (code == FERROR) { - f = stderr; } - if (code == FINFO) { - if (am_server) - f = stderr; - else - f = stdout; + if ( need_remote ) { + + if ( depth <= 1 ) { + + int ok = 0; + + /* first try to pass it off to our sibling */ + if ( ! ok ) + ok = io_error_write(log_error_fd, code, buf, len); + + /* then try to pass it to the other end */ + if ( ! ok ) + ok = io_multiplex_write(code, buf, len); + } - if (!f) exit_cleanup(RERR_MESSAGEIO); + } - if (fwrite(buf, len, 1, f) != 1) exit_cleanup(RERR_MESSAGEIO); + --depth; + + return; - if (buf[len-1] == '\r' || buf[len-1] == '\n') fflush(f); }
Regards, Neil -- Neil Schellenberger | Voice : (613) 599-2300 ext. 8445 Orchestream | Fax : (613) 599-2330 350 Terry Fox Drive | E-Mail: [EMAIL PROTECTED] Kanata ON, Canada, K2K 2W5 | URL : http://www.orchestream.com/