X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/blobdiff_plain/ff41a59f58614ff4e57b4c97b586dcd46e43cc5c..a039749b4c21e3439dc06fcdd5355828f1f95463:/log.c diff --git a/log.c b/log.c index 8619e4d6..8928a386 100644 --- a/log.c +++ b/log.c @@ -1,5 +1,6 @@ -/* - Copyright (C) Andrew Tridgell 1998 +/* -*- c-file-style: "linux"; -*- + + Copyright (C) 1998-2000 by Andrew Tridgell This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -23,12 +24,15 @@ */ #include "rsync.h" +static char *logfname; static FILE *logfile; static int log_error_fd = -1; static void logit(int priority, char *buf) { - if (logfile) { + if (logfname) { + if (!logfile) + log_open(); fprintf(logfile,"%s [%d] %s", timestring(time(NULL)), (int)getpid(), buf); fflush(logfile); @@ -37,12 +41,11 @@ static void logit(int priority, char *buf) } } -void log_open(void) +void log_init(void) { static int initialised; int options = LOG_PID; time_t t; - char *logf; if (initialised) return; initialised = 1; @@ -54,13 +57,13 @@ void log_open(void) localtime(&t); /* optionally use a log file instead of syslog */ - logf = lp_log_file(); - if (logf && *logf) { - extern int orig_umask; - int old_umask = umask(022 | orig_umask); - logfile = fopen(logf, "a"); - umask(old_umask); - return; + logfname = lp_log_file(); + if (logfname) { + if (*logfname) { + log_open(); + return; + } + logfname = NULL; } #ifdef LOG_NDELAY @@ -78,6 +81,24 @@ void log_open(void) #endif } +void log_open() +{ + if (logfname && !logfile) { + extern int orig_umask; + int old_umask = umask(022 | orig_umask); + logfile = fopen(logfname, "a"); + umask(old_umask); + } +} + +void log_close() +{ + if (logfile) { + fclose(logfile); + logfile = NULL; + } +} + /* setup the error file descriptor - used when we are a server that is receiving files */ void set_error_fd(int fd) @@ -91,10 +112,11 @@ void rwrite(enum logcode code, char *buf, int len) { FILE *f=NULL; extern int am_daemon; + extern int am_server; extern int quiet; /* recursion can happen with certain fatal conditions */ - if (quiet != 0 && code == FINFO) return; + if (quiet && code == FINFO) return; if (len < 0) exit_cleanup(RERR_MESSAGEIO); @@ -105,7 +127,15 @@ void rwrite(enum logcode code, char *buf, int len) return; } - if (io_error_write(log_error_fd, code, buf, strlen(buf))) return; + /* first try to pass it off the our sibling */ + if (am_server && io_error_write(log_error_fd, code, buf, len)) { + return; + } + + /* 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; @@ -116,10 +146,8 @@ void rwrite(enum logcode code, char *buf, int len) depth++; - log_open(); - if (!io_multiplex_write(code, buf, strlen(buf))) { - logit(priority, buf); - } + log_init(); + logit(priority, buf); depth--; return; @@ -130,7 +158,6 @@ void rwrite(enum logcode code, char *buf, int len) } if (code == FINFO) { - extern int am_server; if (am_server) f = stderr; else @@ -145,8 +172,9 @@ void rwrite(enum logcode code, char *buf, int len) } -/* this is the rsync debugging function. Call it with FINFO, FERROR or FLOG */ - void rprintf(enum logcode code, const char *format, ...) +/* This is the rsync debugging function. Call it with FINFO, FERROR or + * FLOG. */ +void rprintf(enum logcode code, const char *format, ...) { va_list ap; char buf[1024]; @@ -161,6 +189,45 @@ void rwrite(enum logcode code, char *buf, int len) rwrite(code, buf, len); } + +/* This is like rprintf, but it also tries to print some + * representation of the error code. Normally errcode = errno. + * + * Unlike rprintf, this always adds a newline and there should not be + * one in the format string. + * + * Note that since strerror might involve dynamically loading a + * message catalog we need to call it once before chroot-ing. */ +void rsyserr(enum logcode code, int errcode, const char *format, ...) +{ + va_list ap; + char buf[1024]; + int len, sys_len; + char *sysmsg; + + va_start(ap, format); + len = vslprintf(buf, sizeof(buf), format, ap); + va_end(ap); + + if (len > sizeof(buf)-1) exit_cleanup(RERR_MESSAGEIO); + + sysmsg = strerror(errcode); + sys_len = strlen(sysmsg); + if (len + 3 + sys_len > sizeof(buf) - 1) + exit_cleanup(RERR_MESSAGEIO); + + strcpy(buf + len, ": "); + len += 2; + strcpy(buf + len, sysmsg); + len += sys_len; + strcpy(buf + len, "\n"); + len++; + + rwrite(code, buf, len); +} + + + void rflush(enum logcode code) { FILE *f = NULL; @@ -194,7 +261,7 @@ void rflush(enum logcode code) /* a generic logging routine for send/recv, with parameter substitiution */ -static void log_formatted(int fd, +static void log_formatted(enum logcode code, char *format, char *op, struct file_struct *file, struct stats *initial_stats) { @@ -284,7 +351,7 @@ static void log_formatted(int fd, s = p+l; } - rprintf(fd,"%s\n", buf); + rprintf(code,"%s\n", buf); } /* log the outgoing transfer of a file */