extern int msg_fd_out;
extern int protocol_version;
extern int preserve_times;
+extern int log_format_has_i;
extern int log_format_has_o_or_i;
extern int daemon_log_format_has_o_or_i;
extern char *auth_user;
extern char *log_format;
static int log_initialised;
+static int logfile_was_closed;
static char *logfname;
static FILE *logfile;
struct stats stats;
{ RERR_STREAMIO , "error in rsync protocol data stream" },
{ RERR_MESSAGEIO , "errors with program diagnostics" },
{ RERR_IPC , "error in IPC code" },
- { RERR_SIGNAL , "received SIGUSR1 or SIGINT" },
- { RERR_WAITCHILD , "some error returned by waitpid()" },
+ { RERR_CRASHED , "sibling process crashed" },
+ { RERR_TERMINATED , "sibling process terminated abnormally" },
+ { RERR_SIGNAL1 , "received SIGUSR1" },
+ { RERR_SIGNAL , "received SIGINT, SIGTERM, or SIGHUP" },
+ { RERR_WAITCHILD , "waitpid() failed" },
{ RERR_MALLOC , "error allocating core memory buffers" },
{ RERR_PARTIAL , "some files could not be transferred" },
{ RERR_VANISHED , "some files vanished before they could be transferred" },
static void logit(int priority, char *buf)
{
- if (logfname) {
- if (!logfile) {
- log_open();
- if (!logfname) {
- logit(priority, buf);
- return;
- }
- }
+ if (logfile_was_closed)
+ logfile_reopen();
+ if (logfile) {
fprintf(logfile,"%s [%d] %s",
timestring(time(NULL)), (int)getpid(), buf);
fflush(logfile);
#endif
}
+static void logfile_open(void)
+{
+ extern int orig_umask;
+ int old_umask = umask(022 | orig_umask);
+ logfile = fopen(logfname, "a");
+ umask(old_umask);
+ if (!logfile) {
+ int fopen_errno = errno;
+ /* Rsync falls back to using syslog on failure. */
+ syslog_init();
+ rsyserr(FERROR, fopen_errno,
+ "failed to open log-file %s", logfname);
+ rprintf(FINFO, "Ignoring \"log file\" setting.\n");
+ }
+}
+
void log_init(void)
{
time_t t;
/* optionally use a log file instead of syslog */
logfname = lp_log_file();
- if (logfname) {
- if (*logfname) {
- log_open();
- return;
- }
- logfname = NULL;
- }
-
- syslog_init();
+ if (logfname && *logfname)
+ logfile_open();
+ else
+ syslog_init();
}
-void log_open(void)
+void logfile_close(void)
{
- if (logfname && !logfile) {
- extern int orig_umask;
- int old_umask = umask(022 | orig_umask);
- logfile = fopen(logfname, "a");
- umask(old_umask);
- if (!logfile) {
- char *had_logfname = logfname;
- int open_errno = errno;
- /* Rsync falls back to using syslog on failure. */
- logfname = NULL;
- syslog_init();
- rsyserr(FERROR, open_errno,
- "failed to open log-file %s", had_logfname);
- rprintf(FINFO, "Ignoring \"log file\" setting.\n");
- }
+ if (logfile) {
+ logfile_was_closed = 1;
+ fclose(logfile);
+ logfile = NULL;
}
}
-void log_close(void)
+void logfile_reopen(void)
{
- if (logfile) {
- fclose(logfile);
- logfile = NULL;
+ if (logfile_was_closed) {
+ logfile_was_closed = 0;
+ logfile_open();
}
}
void rprintf(enum logcode code, const char *format, ...)
{
va_list ap;
- char buf[MAXPATHLEN+512];
+ char buf[BIGPATHBUFLEN];
size_t len;
va_start(ap, format);
* truncate the resulting string. (Note that configure ensures
* that we have a vsnprintf() that doesn't ever return -1.) */
if (len > sizeof buf - 1) {
- const char ellipsis[] = "[...]";
+ static const char ellipsis[] = "[...]";
/* Reset length, and zero-terminate the end of our buffer */
len = sizeof buf - 1;
* If the input format string has a trailing newline,
* we copy it into that extra null; if it doesn't, well,
* all we lose is one byte. */
- strncpy(buf+len-sizeof ellipsis, ellipsis, sizeof ellipsis);
+ memcpy(buf+len-sizeof ellipsis, ellipsis, sizeof ellipsis);
if (format[strlen(format)-1] == '\n') {
buf[len-1] = '\n';
}
void rsyserr(enum logcode code, int errcode, const char *format, ...)
{
va_list ap;
- char buf[MAXPATHLEN+512];
+ char buf[BIGPATHBUFLEN];
size_t len;
strcpy(buf, RSYNC_NAME ": ");
n = NULL;
switch (*p) {
- case 'h': if (am_daemon) n = client_name(0); break;
- case 'a': if (am_daemon) n = client_addr(0); break;
+ case 'h':
+ if (am_daemon)
+ n = client_name(0);
+ break;
+ case 'a':
+ if (am_daemon)
+ n = client_addr(0);
+ break;
case 'l':
strlcat(fmt, ".0f", sizeof fmt);
snprintf(buf2, sizeof buf2, fmt,
(long)getpid());
n = buf2;
break;
- case 'o': n = op; break;
+ case 'o':
+ n = op;
+ break;
case 'f':
n = safe_fname(f_name(file));
if (am_sender && file->dir.root) {
snprintf(buf2 + 4, sizeof buf2 - 4, fmt, n);
n = buf2;
break;
- case 'm': n = lp_name(module_id); break;
- case 't': n = timestring(time(NULL)); break;
- case 'P': n = lp_path(module_id); break;
- case 'u': n = auth_user; break;
+ case 'm':
+ n = lp_name(module_id);
+ break;
+ case 't':
+ n = timestring(time(NULL));
+ break;
+ case 'P':
+ n = lp_path(module_id);
+ break;
+ case 'u':
+ n = auth_user;
+ break;
case 'b':
if (am_sender) {
b = stats.total_written -
int i;
for (i = 2; n[i]; i++)
n[i] = ch;
- } else if (!(iflags & (ITEM_TRANSFER|ITEM_LOCAL_CHANGE))) {
+ } else if (n[0] == '.' || n[0] == 'h'
+ || (n[0] == 'c' && n[1] == 'f')) {
int i;
for (i = 2; n[i]; i++) {
if (n[i] != '.')
void maybe_log_item(struct file_struct *file, int iflags, int itemizing,
char *buf)
{
- int see_item = itemizing && (iflags || verbose > 1);
+ int significant_flags = iflags & SIGNIFICANT_ITEM_FLAGS;
+ int see_item = itemizing && (significant_flags || *buf
+ || (verbose > 1 && log_format_has_i));
+ int local_change = iflags & ITEM_LOCAL_CHANGE && significant_flags;
if (am_server) {
if (am_daemon && !dry_run && see_item)
log_item(file, &stats, iflags, buf);
- } else if (see_item || iflags & ITEM_LOCAL_CHANGE || *buf
- || (S_ISDIR(file->mode) && iflags & SIGNIFICANT_ITEM_FLAGS))
+ } else if (see_item || local_change || *buf
+ || (S_ISDIR(file->mode) && significant_flags))
log_item(file, &stats, iflags, buf);
}