If in_exit_cleanup is set, some of our functions return instead of
[rsync/rsync.git] / log.c
diff --git a/log.c b/log.c
index 64e584b..2355214 100644 (file)
--- a/log.c
+++ b/log.c
@@ -37,6 +37,7 @@ extern int msg_fd_out;
 extern int allow_8bit_chars;
 extern int protocol_version;
 extern int preserve_times;
+extern int in_exit_cleanup;
 extern int stdout_format_has_i;
 extern int stdout_format_has_o_or_i;
 extern int logfile_format_has_i;
@@ -49,6 +50,8 @@ extern char *logfile_name;
 #if defined HAVE_ICONV_OPEN && defined HAVE_ICONV_H
 extern iconv_t ic_chck;
 #endif
+extern char curr_dir[];
+extern unsigned int module_dirlen;
 
 static int log_initialised;
 static int logfile_was_closed;
@@ -88,6 +91,13 @@ struct {
        { 0, NULL }
 };
 
+#define EXIT_OR_RETURN(err) \
+       do { \
+               if (in_exit_cleanup) \
+                       return; \
+               exit_cleanup(err); \
+       } while (0)
+
 
 /*
  * Map from rsync error code to name, or return NULL.
@@ -129,7 +139,7 @@ static void syslog_init()
 #endif
 
 #ifdef LOG_DAEMON
-       openlog("rsyncd", options, lp_syslog_facility());
+       openlog("rsyncd", options, lp_syslog_facility(module_id));
 #else
        openlog("rsyncd", options);
 #endif
@@ -154,11 +164,26 @@ static void logfile_open(void)
        }
 }
 
-void log_init(void)
+void log_init(int restart)
 {
-       if (log_initialised)
-               return;
-       log_initialised = 1;
+       if (log_initialised) {
+               if (!restart)
+                       return;
+               if (strcmp(logfile_name, lp_log_file(module_id)) != 0) {
+                       if (logfile_fp) {
+                               fclose(logfile_fp);
+                               logfile_fp = NULL;
+                       } else
+                               closelog();
+                       logfile_name = NULL;
+               } else if (*logfile_name)
+                       return; /* unchanged, non-empty "log file" names */
+               else if (lp_syslog_facility(-1) != lp_syslog_facility(module_id))
+                       closelog();
+               else
+                       return; /* unchanged syslog settings */
+       } else
+               log_initialised = 1;
 
        /* This looks pointless, but it is needed in order for the
         * C library on some systems to fetch the timezone info
@@ -168,7 +193,7 @@ void log_init(void)
        /* Optionally use a log file instead of syslog.  (Non-daemon
         * rsyncs will have already set logfile_name, as needed.) */
        if (am_daemon && !logfile_name)
-               logfile_name = lp_log_file();
+               logfile_name = lp_log_file(module_id);
        if (logfile_name && *logfile_name)
                logfile_open();
        else
@@ -205,13 +230,13 @@ static void filtered_fwrite(FILE *f, const char *buf, int len, int use_isprint)
                  && ((use_isprint && !isprint(*(uchar*)s))
                   || *(uchar*)s < ' '))) {
                        if (s != buf && fwrite(buf, s - buf, 1, f) != 1)
-                               exit_cleanup(RERR_MESSAGEIO);
+                               EXIT_OR_RETURN(RERR_MESSAGEIO);
                        fprintf(f, "\\#%03o", *(uchar*)s);
                        buf = s + 1;
                }
        }
        if (buf != end && fwrite(buf, end - buf, 1, f) != 1)
-               exit_cleanup(RERR_MESSAGEIO);
+               EXIT_OR_RETURN(RERR_MESSAGEIO);
 }
 
 /* this is the underlying (unformatted) rsync debugging function. Call
@@ -223,7 +248,7 @@ void rwrite(enum logcode code, char *buf, int len)
        FILE *f = NULL;
 
        if (len < 0)
-               exit_cleanup(RERR_MESSAGEIO);
+               EXIT_OR_RETURN(RERR_MESSAGEIO);
 
        if (am_server && msg_fd_out >= 0) {
                /* Pass the message to our sibling. */
@@ -245,7 +270,7 @@ void rwrite(enum logcode code, char *buf, int len)
                        return;
                in_block = 1;
                if (!log_initialised)
-                       log_init();
+                       log_init(0);
                strlcpy(msg, buf, MIN((int)sizeof msg, len + 1));
                logit(priority, msg);
                in_block = 0;
@@ -277,7 +302,7 @@ void rwrite(enum logcode code, char *buf, int len)
                f = am_server ? stderr : stdout;
                break;
        default:
-               exit_cleanup(RERR_MESSAGEIO);
+               EXIT_OR_RETURN(RERR_MESSAGEIO);
        }
 
        trailing_CR_or_NL = len && (buf[len-1] == '\n' || buf[len-1] == '\r')
@@ -381,7 +406,7 @@ void rsyserr(enum logcode code, int errcode, const char *format, ...)
                                ": %s (%d)\n", strerror(errcode), errcode);
        }
        if (len >= sizeof buf)
-               exit_cleanup(RERR_MESSAGEIO);
+               EXIT_OR_RETURN(RERR_MESSAGEIO);
 
        rwrite(code, buf, len);
 }
@@ -419,7 +444,7 @@ static void log_formatted(enum logcode code, char *format, char *op,
        total = strlcpy(buf, format, sizeof buf);
        if (total > MAXPATHLEN) {
                rprintf(FERROR, "log-format string is WAY too long!\n");
-               exit_cleanup(RERR_MESSAGEIO);
+               EXIT_OR_RETURN(RERR_MESSAGEIO);
        }
        buf[total++] = '\n';
        buf[total] = '\0';
@@ -498,6 +523,14 @@ static void log_formatted(enum logcode code, char *format, char *op,
                                        strlcpy(n, buf2, MAXPATHLEN);
                                else
                                        n = buf2;
+                       } else if (*n != '/') {
+                               pathjoin(buf2, sizeof buf2,
+                                        curr_dir + module_dirlen, n);
+                               clean_fname(buf2, 0);
+                               if (fmt[1])
+                                       strlcpy(n, buf2, MAXPATHLEN);
+                               else
+                                       n = buf2;
                        } else
                                clean_fname(n, 0);
                        if (*n == '/')