version 1.1.1.1, 2012/02/17 15:09:30
|
version 1.1.1.4, 2021/03/17 00:32:36
|
Line 3
|
Line 3
|
* |
* |
* Copyright (C) 1998-2001 Andrew Tridgell <tridge@samba.org> |
* Copyright (C) 1998-2001 Andrew Tridgell <tridge@samba.org> |
* Copyright (C) 2000-2001 Martin Pool <mbp@samba.org> |
* Copyright (C) 2000-2001 Martin Pool <mbp@samba.org> |
* Copyright (C) 2003-2009 Wayne Davison | * Copyright (C) 2003-2020 Wayne Davison |
* |
* |
* This program is free software; you can redistribute it and/or modify |
* 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 |
* it under the terms of the GNU General Public License as published by |
Line 20
|
Line 20
|
*/ |
*/ |
|
|
#include "rsync.h" |
#include "rsync.h" |
#include "ifuncs.h" | #include "itypes.h" |
| #include "inums.h" |
|
|
extern int verbose; |
|
extern int dry_run; |
extern int dry_run; |
extern int am_daemon; |
extern int am_daemon; |
extern int am_server; |
extern int am_server; |
Line 31 extern int am_generator;
|
Line 31 extern int am_generator;
|
extern int local_server; |
extern int local_server; |
extern int quiet; |
extern int quiet; |
extern int module_id; |
extern int module_id; |
extern int msg_fd_out; |
|
extern int allow_8bit_chars; |
extern int allow_8bit_chars; |
extern int protocol_version; |
extern int protocol_version; |
|
extern int always_checksum; |
extern int preserve_times; |
extern int preserve_times; |
extern int progress_is_active; | extern int msgs2stderr; |
| extern int xfersum_type; |
| extern int checksum_type; |
extern int stdout_format_has_i; |
extern int stdout_format_has_i; |
extern int stdout_format_has_o_or_i; |
extern int stdout_format_has_o_or_i; |
extern int logfile_format_has_i; |
extern int logfile_format_has_i; |
extern int logfile_format_has_o_or_i; |
extern int logfile_format_has_o_or_i; |
extern int receiver_symlink_times; |
extern int receiver_symlink_times; |
|
extern int64 total_data_written; |
|
extern int64 total_data_read; |
extern mode_t orig_umask; |
extern mode_t orig_umask; |
extern char *auth_user; |
extern char *auth_user; |
extern char *stdout_format; |
extern char *stdout_format; |
Line 55 extern iconv_t ic_recv;
|
Line 59 extern iconv_t ic_recv;
|
extern char curr_dir[MAXPATHLEN]; |
extern char curr_dir[MAXPATHLEN]; |
extern char *full_module_path; |
extern char *full_module_path; |
extern unsigned int module_dirlen; |
extern unsigned int module_dirlen; |
|
extern char sender_file_sum[MAX_DIGEST_LEN]; |
|
extern const char undetermined_hostname[]; |
|
|
static int log_initialised; |
static int log_initialised; |
static int logfile_was_closed; |
static int logfile_was_closed; |
Line 62 static FILE *logfile_fp;
|
Line 68 static FILE *logfile_fp;
|
struct stats stats; |
struct stats stats; |
|
|
int got_xfer_error = 0; |
int got_xfer_error = 0; |
|
int output_needs_newline = 0; |
|
int send_msgs_to_gen = 0; |
|
|
|
static int64 initial_data_written; |
|
static int64 initial_data_read; |
|
|
struct { |
struct { |
int code; | int code; |
char const *name; | char const *name; |
} const rerr_names[] = { |
} const rerr_names[] = { |
{ RERR_SYNTAX , "syntax or usage error" }, |
{ RERR_SYNTAX , "syntax or usage error" }, |
{ RERR_PROTOCOL , "protocol incompatibility" }, |
{ RERR_PROTOCOL , "protocol incompatibility" }, |
Line 81 struct {
|
Line 92 struct {
|
{ RERR_TERMINATED , "sibling process terminated abnormally" }, |
{ RERR_TERMINATED , "sibling process terminated abnormally" }, |
{ RERR_SIGNAL1 , "received SIGUSR1" }, |
{ RERR_SIGNAL1 , "received SIGUSR1" }, |
{ RERR_SIGNAL , "received SIGINT, SIGTERM, or SIGHUP" }, |
{ RERR_SIGNAL , "received SIGINT, SIGTERM, or SIGHUP" }, |
|
{ RERR_WECRASHED , "rsync caught a CRASH-causing signal" }, |
{ RERR_WAITCHILD , "waitpid() failed" }, |
{ RERR_WAITCHILD , "waitpid() failed" }, |
{ RERR_MALLOC , "error allocating core memory buffers" }, |
{ RERR_MALLOC , "error allocating core memory buffers" }, |
{ RERR_PARTIAL , "some files/attrs were not transferred (see previous errors)" }, |
{ RERR_PARTIAL , "some files/attrs were not transferred (see previous errors)" }, |
{ RERR_VANISHED , "some files vanished before they could be transferred" }, |
{ RERR_VANISHED , "some files vanished before they could be transferred" }, |
|
{ RERR_DEL_LIMIT , "the --max-delete limit stopped deletions" }, |
{ RERR_TIMEOUT , "timeout in data send/receive" }, |
{ RERR_TIMEOUT , "timeout in data send/receive" }, |
{ RERR_CONTIMEOUT , "timeout waiting for daemon connection" }, |
{ RERR_CONTIMEOUT , "timeout waiting for daemon connection" }, |
{ RERR_CMD_FAILED , "remote shell failed" }, |
{ RERR_CMD_FAILED , "remote shell failed" }, |
{ RERR_CMD_KILLED , "remote shell killed" }, |
{ RERR_CMD_KILLED , "remote shell killed" }, |
{ RERR_CMD_RUN , "remote command could not be run" }, |
{ RERR_CMD_RUN , "remote command could not be run" }, |
{ RERR_CMD_NOTFOUND,"remote command not found" }, |
{ RERR_CMD_NOTFOUND,"remote command not found" }, |
{ RERR_DEL_LIMIT , "the --max-delete limit stopped deletions" }, |
|
{ 0, NULL } |
{ 0, NULL } |
}; |
}; |
|
|
Line 113 static void logit(int priority, const char *buf)
|
Line 125 static void logit(int priority, const char *buf)
|
if (logfile_was_closed) |
if (logfile_was_closed) |
logfile_reopen(); |
logfile_reopen(); |
if (logfile_fp) { |
if (logfile_fp) { |
fprintf(logfile_fp, "%s [%d] %s", | fprintf(logfile_fp, "%s [%d] %s", timestring(time(NULL)), (int)getpid(), buf); |
timestring(time(NULL)), (int)getpid(), buf); | |
fflush(logfile_fp); |
fflush(logfile_fp); |
} else { |
} else { |
syslog(priority, "%s", buf); |
syslog(priority, "%s", buf); |
Line 123 static void logit(int priority, const char *buf)
|
Line 134 static void logit(int priority, const char *buf)
|
|
|
static void syslog_init() |
static void syslog_init() |
{ |
{ |
static int been_here = 0; |
|
int options = LOG_PID; |
int options = LOG_PID; |
|
|
if (been_here) |
|
return; |
|
been_here = 1; |
|
|
|
#ifdef LOG_NDELAY |
#ifdef LOG_NDELAY |
options |= LOG_NDELAY; |
options |= LOG_NDELAY; |
#endif |
#endif |
|
|
#ifdef LOG_DAEMON |
#ifdef LOG_DAEMON |
openlog("rsyncd", options, lp_syslog_facility(module_id)); | openlog(lp_syslog_tag(module_id), options, lp_syslog_facility(module_id)); |
#else |
#else |
openlog("rsyncd", options); | openlog(lp_syslog_tag(module_id), options); |
#endif |
#endif |
|
|
#ifndef LOG_NDELAY |
#ifndef LOG_NDELAY |
Line 157 static void logfile_open(void)
|
Line 163 static void logfile_open(void)
|
rsyserr(FERROR, fopen_errno, |
rsyserr(FERROR, fopen_errno, |
"failed to open log-file %s", logfile_name); |
"failed to open log-file %s", logfile_name); |
rprintf(FINFO, "Ignoring \"log file\" setting.\n"); |
rprintf(FINFO, "Ignoring \"log file\" setting.\n"); |
|
logfile_name = ""; |
} |
} |
} |
} |
|
|
void log_init(int restart) |
void log_init(int restart) |
{ |
{ |
if (log_initialised) { |
if (log_initialised) { |
if (!restart) | if (!restart) /* Note: a restart only happens with am_daemon */ |
return; |
return; |
|
assert(logfile_name); /* all am_daemon procs got at least an empty string */ |
if (strcmp(logfile_name, lp_log_file(module_id)) != 0) { |
if (strcmp(logfile_name, lp_log_file(module_id)) != 0) { |
if (logfile_fp) { |
if (logfile_fp) { |
fclose(logfile_fp); |
fclose(logfile_fp); |
Line 174 void log_init(int restart)
|
Line 182 void log_init(int restart)
|
logfile_name = NULL; |
logfile_name = NULL; |
} else if (*logfile_name) |
} else if (*logfile_name) |
return; /* unchanged, non-empty "log file" names */ |
return; /* unchanged, non-empty "log file" names */ |
else if (lp_syslog_facility(-1) != lp_syslog_facility(module_id)) | else if (lp_syslog_facility(-1) != lp_syslog_facility(module_id) |
| || strcmp(lp_syslog_tag(-1), lp_syslog_tag(module_id)) != 0) |
closelog(); |
closelog(); |
else |
else |
return; /* unchanged syslog settings */ |
return; /* unchanged syslog settings */ |
Line 196 void log_init(int restart)
|
Line 205 void log_init(int restart)
|
syslog_init(); |
syslog_init(); |
} |
} |
|
|
|
/* Note that this close & reopen idiom intentionally ignores syslog logging. */ |
void logfile_close(void) |
void logfile_close(void) |
{ |
{ |
if (logfile_fp) { |
if (logfile_fp) { |
Line 213 void logfile_reopen(void)
|
Line 223 void logfile_reopen(void)
|
} |
} |
} |
} |
|
|
static void filtered_fwrite(FILE *f, const char *buf, int len, int use_isprint) | static void filtered_fwrite(FILE *f, const char *in_buf, int in_len, int use_isprint, char end_char) |
{ |
{ |
const char *s, *end = buf + len; | char outbuf[1024], *ob = outbuf; |
for (s = buf; s < end; s++) { | const char *end = in_buf + in_len; |
if ((s < end - 4 | while (in_buf < end) { |
&& *s == '\\' && s[1] == '#' | if (ob - outbuf >= (int)sizeof outbuf - 10) { |
&& isDigit(s + 2) | if (fwrite(outbuf, ob - outbuf, 1, f) != 1) |
&& isDigit(s + 3) | |
&& isDigit(s + 4)) | |
|| (*s != '\t' | |
&& ((use_isprint && !isPrint(s)) | |
|| *(uchar*)s < ' '))) { | |
if (s != buf && fwrite(buf, s - buf, 1, f) != 1) | |
exit_cleanup(RERR_MESSAGEIO); |
exit_cleanup(RERR_MESSAGEIO); |
fprintf(f, "\\#%03o", *(uchar*)s); | ob = outbuf; |
buf = s + 1; | |
} |
} |
|
if ((in_buf < end - 4 && *in_buf == '\\' && in_buf[1] == '#' |
|
&& isDigit(in_buf + 2) && isDigit(in_buf + 3) && isDigit(in_buf + 4)) |
|
|| (*in_buf != '\t' && ((use_isprint && !isPrint(in_buf)) || *(uchar*)in_buf < ' '))) |
|
ob += snprintf(ob, 6, "\\#%03o", *(uchar*)in_buf++); |
|
else |
|
*ob++ = *in_buf++; |
} |
} |
if (buf != end && fwrite(buf, end - buf, 1, f) != 1) | if (end_char) /* The "- 10" above means that there is always room for one more char here. */ |
| *ob++ = end_char; |
| if (ob != outbuf && fwrite(outbuf, ob - outbuf, 1, f) != 1) |
exit_cleanup(RERR_MESSAGEIO); |
exit_cleanup(RERR_MESSAGEIO); |
} |
} |
|
|
Line 240 static void filtered_fwrite(FILE *f, const char *buf,
|
Line 251 static void filtered_fwrite(FILE *f, const char *buf,
|
* can happen with certain fatal conditions. */ |
* can happen with certain fatal conditions. */ |
void rwrite(enum logcode code, const char *buf, int len, int is_utf8) |
void rwrite(enum logcode code, const char *buf, int len, int is_utf8) |
{ |
{ |
int trailing_CR_or_NL; | char trailing_CR_or_NL; |
FILE *f = NULL; | FILE *f = msgs2stderr == 1 ? stderr : stdout; |
#ifdef ICONV_OPTION |
#ifdef ICONV_OPTION |
iconv_t ic = is_utf8 && ic_recv != (iconv_t)-1 ? ic_recv : ic_chck; |
iconv_t ic = is_utf8 && ic_recv != (iconv_t)-1 ? ic_recv : ic_chck; |
#else |
#else |
Line 253 void rwrite(enum logcode code, const char *buf, int le
|
Line 264 void rwrite(enum logcode code, const char *buf, int le
|
if (len < 0) |
if (len < 0) |
exit_cleanup(RERR_MESSAGEIO); |
exit_cleanup(RERR_MESSAGEIO); |
|
|
if (am_server && msg_fd_out >= 0) { | if (msgs2stderr == 1) { |
| /* A normal daemon can get msgs2stderr set if the socket is busted, so we |
| * change the message destination into an FLOG message in order to try to |
| * get some info about an abnormal-exit into the log file. An rsh daemon |
| * can have this set via user request, so we'll leave the code alone so |
| * that the msg gets logged and then sent to stderr after that. */ |
| if (am_daemon > 0 && code != FCLIENT) |
| code = FLOG; |
| } else if (send_msgs_to_gen) { |
assert(!is_utf8); |
assert(!is_utf8); |
/* Pass the message to our sibling in native charset. */ |
/* Pass the message to our sibling in native charset. */ |
send_msg((enum msgcode)code, buf, len, 0); |
send_msg((enum msgcode)code, buf, len, 0); |
Line 288 void rwrite(enum logcode code, const char *buf, int le
|
Line 307 void rwrite(enum logcode code, const char *buf, int le
|
} else if (code == FLOG) |
} else if (code == FLOG) |
return; |
return; |
|
|
if (quiet && code == FINFO) | switch (code) { |
return; | case FERROR_XFER: |
| got_xfer_error = 1; |
| /* FALL THROUGH */ |
| case FERROR: |
| case FWARNING: |
| f = stderr; |
| break; |
| case FINFO: |
| if (quiet) |
| return; |
| break; |
| /*case FLOG:*/ |
| /*case FCLIENT:*/ |
| /*case FERROR_UTF8:*/ |
| /*case FERROR_SOCKET:*/ |
| default: |
| fprintf(stderr, "Bad logcode in rwrite(): %d [%s]\n", (int)code, who_am_i()); |
| exit_cleanup(RERR_MESSAGEIO); |
| } |
|
|
if (am_server) { | if (am_server && msgs2stderr != 1 && (msgs2stderr != 2 || f != stderr)) { |
enum msgcode msg = (enum msgcode)code; |
enum msgcode msg = (enum msgcode)code; |
if (protocol_version < 30) { |
if (protocol_version < 30) { |
if (msg == MSG_ERROR) |
if (msg == MSG_ERROR) |
Line 302 void rwrite(enum logcode code, const char *buf, int le
|
Line 339 void rwrite(enum logcode code, const char *buf, int le
|
/* Pass the message to the non-server side. */ |
/* Pass the message to the non-server side. */ |
if (send_msg(msg, buf, len, !is_utf8)) |
if (send_msg(msg, buf, len, !is_utf8)) |
return; |
return; |
if (am_daemon) { | if (am_daemon > 0) { |
/* TODO: can we send the error to the user somehow? */ |
/* TODO: can we send the error to the user somehow? */ |
return; |
return; |
} |
} |
} |
|
|
|
switch (code) { |
|
case FERROR_XFER: |
|
got_xfer_error = 1; |
|
/* FALL THROUGH */ |
|
case FERROR: |
|
case FWARNING: |
|
f = stderr; |
f = stderr; |
break; |
|
case FINFO: |
|
f = am_server ? stderr : stdout; |
|
break; |
|
default: |
|
exit_cleanup(RERR_MESSAGEIO); |
|
} |
} |
|
|
if (progress_is_active && !am_server) { | if (output_needs_newline) { |
fputc('\n', f); |
fputc('\n', f); |
progress_is_active = 0; | output_needs_newline = 0; |
} |
} |
|
|
trailing_CR_or_NL = len && (buf[len-1] == '\n' || buf[len-1] == '\r') | trailing_CR_or_NL = len && (buf[len-1] == '\n' || buf[len-1] == '\r') ? buf[--len] : '\0'; |
? buf[--len] : 0; | |
|
|
|
if (len && buf[0] == '\r') { |
|
fputc('\r', f); |
|
buf++; |
|
len--; |
|
} |
|
|
#ifdef ICONV_CONST |
#ifdef ICONV_CONST |
if (ic != (iconv_t)-1) { |
if (ic != (iconv_t)-1) { |
xbuf outbuf, inbuf; |
xbuf outbuf, inbuf; |
Line 338 void rwrite(enum logcode code, const char *buf, int le
|
Line 366 void rwrite(enum logcode code, const char *buf, int le
|
int ierrno; |
int ierrno; |
|
|
INIT_CONST_XBUF(outbuf, convbuf); |
INIT_CONST_XBUF(outbuf, convbuf); |
INIT_XBUF(inbuf, (char*)buf, len, -1); | INIT_XBUF(inbuf, (char*)buf, len, (size_t)-1); |
|
|
while (inbuf.len) { |
while (inbuf.len) { |
iconvbufs(ic, &inbuf, &outbuf, 0); | iconvbufs(ic, &inbuf, &outbuf, inbuf.pos ? 0 : ICB_INIT); |
ierrno = errno; |
ierrno = errno; |
if (outbuf.len) { |
if (outbuf.len) { |
filtered_fwrite(f, convbuf, outbuf.len, 0); | char trailing = inbuf.len ? '\0' : trailing_CR_or_NL; |
| filtered_fwrite(f, convbuf, outbuf.len, 0, trailing); |
| if (trailing) { |
| trailing_CR_or_NL = '\0'; |
| fflush(f); |
| } |
outbuf.len = 0; |
outbuf.len = 0; |
} |
} |
if (!ierrno || ierrno == E2BIG) | /* Log one byte of illegal/incomplete sequence and continue with |
continue; | * the next character. Check that the buffer is non-empty for the |
fprintf(f, "\\#%03o", CVAL(inbuf.buf, inbuf.pos++)); | * sake of robustness. */ |
inbuf.len--; | if ((ierrno == EILSEQ || ierrno == EINVAL) && inbuf.len) { |
| fprintf(f, "\\#%03o", CVAL(inbuf.buf, inbuf.pos++)); |
| inbuf.len--; |
| } |
} |
} |
|
|
|
if (trailing_CR_or_NL) { |
|
fputc(trailing_CR_or_NL, f); |
|
fflush(f); |
|
} |
} else |
} else |
#endif |
#endif |
filtered_fwrite(f, buf, len, !allow_8bit_chars); | { |
| filtered_fwrite(f, buf, len, !allow_8bit_chars, trailing_CR_or_NL); |
if (trailing_CR_or_NL) { | if (trailing_CR_or_NL) |
fputc(trailing_CR_or_NL, f); | fflush(f); |
fflush(f); | |
} |
} |
} |
} |
|
|
Line 417 void rsyserr(enum logcode code, int errcode, const cha
|
Line 457 void rsyserr(enum logcode code, int errcode, const cha
|
char buf[BIGPATHBUFLEN]; |
char buf[BIGPATHBUFLEN]; |
size_t len; |
size_t len; |
|
|
strlcpy(buf, RSYNC_NAME ": ", sizeof buf); | len = snprintf(buf, sizeof buf, RSYNC_NAME ": [%s] ", who_am_i()); |
len = (sizeof RSYNC_NAME ": ") - 1; | |
|
|
va_start(ap, format); |
va_start(ap, format); |
len += vsnprintf(buf + len, sizeof buf - len, format, ap); |
len += vsnprintf(buf + len, sizeof buf - len, format, ap); |
Line 436 void rsyserr(enum logcode code, int errcode, const cha
|
Line 475 void rsyserr(enum logcode code, int errcode, const cha
|
|
|
void rflush(enum logcode code) |
void rflush(enum logcode code) |
{ |
{ |
FILE *f = NULL; | FILE *f; |
|
|
if (am_daemon || code == FLOG) |
if (am_daemon || code == FLOG) |
return; |
return; |
|
|
if (code == FINFO && !am_server) | if (!am_server && (code == FINFO || code == FCLIENT)) |
f = stdout; |
f = stdout; |
else |
else |
f = stderr; |
f = stderr; |
Line 449 void rflush(enum logcode code)
|
Line 488 void rflush(enum logcode code)
|
fflush(f); |
fflush(f); |
} |
} |
|
|
|
void remember_initial_stats(void) |
|
{ |
|
initial_data_read = total_data_read; |
|
initial_data_written = total_data_written; |
|
} |
|
|
/* A generic logging routine for send/recv, with parameter substitiution. */ |
/* A generic logging routine for send/recv, with parameter substitiution. */ |
static void log_formatted(enum logcode code, const char *format, const char *op, |
static void log_formatted(enum logcode code, const char *format, const char *op, |
struct file_struct *file, const char *fname, | struct file_struct *file, const char *fname, int iflags, |
struct stats *initial_stats, int iflags, | |
const char *hlink) |
const char *hlink) |
{ |
{ |
char buf[MAXPATHLEN+1024], buf2[MAXPATHLEN], fmt[32]; |
char buf[MAXPATHLEN+1024], buf2[MAXPATHLEN], fmt[32]; |
Line 475 static void log_formatted(enum logcode code, const cha
|
Line 519 static void log_formatted(enum logcode code, const cha
|
buf[total] = '\0'; |
buf[total] = '\0'; |
|
|
for (p = buf; (p = strchr(p, '%')) != NULL; ) { |
for (p = buf; (p = strchr(p, '%')) != NULL; ) { |
|
int humanize = 0; |
s = p++; |
s = p++; |
c = fmt + 1; |
c = fmt + 1; |
|
while (*p == '\'') { |
|
humanize++; |
|
p++; |
|
} |
if (*p == '-') |
if (*p == '-') |
*c++ = *p++; |
*c++ = *p++; |
while (isDigit(p) && c - fmt < (int)(sizeof fmt) - 8) |
while (isDigit(p) && c - fmt < (int)(sizeof fmt) - 8) |
*c++ = *p++; |
*c++ = *p++; |
|
while (*p == '\'') { |
|
humanize++; |
|
p++; |
|
} |
if (!*p) |
if (!*p) |
break; |
break; |
*c = '\0'; |
*c = '\0'; |
n = NULL; |
n = NULL; |
|
|
|
/* Note for %h and %a: it doesn't matter what fd we pass to |
|
* client_{name,addr} because rsync_module will already have |
|
* forced the answer to be cached (assuming, of course, for %h |
|
* that lp_reverse_lookup(module_id) is true). */ |
switch (*p) { |
switch (*p) { |
case 'h': |
case 'h': |
if (am_daemon) | if (am_daemon) { |
n = client_name(0); | n = lp_reverse_lookup(module_id) |
| ? client_name(0) : undetermined_hostname; |
| } |
break; |
break; |
case 'a': |
case 'a': |
if (am_daemon) |
if (am_daemon) |
n = client_addr(0); |
n = client_addr(0); |
break; |
break; |
case 'l': |
case 'l': |
strlcat(fmt, ".0f", sizeof fmt); | strlcat(fmt, "s", sizeof fmt); |
snprintf(buf2, sizeof buf2, fmt, |
snprintf(buf2, sizeof buf2, fmt, |
(double)F_LENGTH(file)); | do_big_num(F_LENGTH(file), humanize, NULL)); |
n = buf2; |
n = buf2; |
break; |
break; |
case 'U': |
case 'U': |
Line 518 static void log_formatted(enum logcode code, const cha
|
Line 577 static void log_formatted(enum logcode code, const cha
|
} |
} |
break; |
break; |
case 'p': |
case 'p': |
strlcat(fmt, "ld", sizeof fmt); | strlcat(fmt, "d", sizeof fmt); |
snprintf(buf2, sizeof buf2, fmt, | snprintf(buf2, sizeof buf2, fmt, (int)getpid()); |
(long)getpid()); | |
n = buf2; |
n = buf2; |
break; |
break; |
case 'M': |
case 'M': |
Line 607 static void log_formatted(enum logcode code, const cha
|
Line 665 static void log_formatted(enum logcode code, const cha
|
n = auth_user; |
n = auth_user; |
break; |
break; |
case 'b': |
case 'b': |
if (am_sender) { | case 'c': |
b = stats.total_written - | if (!(iflags & ITEM_TRANSFER)) |
initial_stats->total_written; | b = 0; |
} else { | else if ((!!am_sender) ^ (*p == 'c')) |
b = stats.total_read - | b = total_data_written - initial_data_written; |
initial_stats->total_read; | else |
} | b = total_data_read - initial_data_read; |
strlcat(fmt, ".0f", sizeof fmt); | strlcat(fmt, "s", sizeof fmt); |
snprintf(buf2, sizeof buf2, fmt, (double)b); | snprintf(buf2, sizeof buf2, fmt, |
| do_big_num(b, humanize, NULL)); |
n = buf2; |
n = buf2; |
break; |
break; |
case 'c': | case 'C': |
if (!am_sender) { | n = NULL; |
b = stats.total_written - | if (S_ISREG(file->mode)) { |
initial_stats->total_written; | if (always_checksum) |
} else { | n = sum_as_hex(checksum_type, F_SUM(file), 1); |
b = stats.total_read - | else if (iflags & ITEM_TRANSFER) |
initial_stats->total_read; | n = sum_as_hex(xfersum_type, sender_file_sum, 0); |
} |
} |
strlcat(fmt, ".0f", sizeof fmt); | if (!n) { |
snprintf(buf2, sizeof buf2, fmt, (double)b); | int sum_len = csum_len_for_type(always_checksum ? checksum_type : xfersum_type, |
n = buf2; | always_checksum); |
| memset(buf2, ' ', sum_len*2); |
| buf2[sum_len*2] = '\0'; |
| n = buf2; |
| } |
break; |
break; |
case 'i': |
case 'i': |
if (iflags & ITEM_DELETED) { |
if (iflags & ITEM_DELETED) { |
Line 637 static void log_formatted(enum logcode code, const cha
|
Line 700 static void log_formatted(enum logcode code, const cha
|
} |
} |
n = c = buf2 + MAXPATHLEN - 32; |
n = c = buf2 + MAXPATHLEN - 32; |
c[0] = iflags & ITEM_LOCAL_CHANGE |
c[0] = iflags & ITEM_LOCAL_CHANGE |
? iflags & ITEM_XNAME_FOLLOWS ? 'h' : 'c' | ? iflags & ITEM_XNAME_FOLLOWS ? 'h' : 'c' |
: !(iflags & ITEM_TRANSFER) ? '.' |
: !(iflags & ITEM_TRANSFER) ? '.' |
: !local_server && *op == 's' ? '<' : '>'; |
: !local_server && *op == 's' ? '<' : '>'; |
if (S_ISLNK(file->mode)) { |
if (S_ISLNK(file->mode)) { |
Line 658 static void log_formatted(enum logcode code, const cha
|
Line 721 static void log_formatted(enum logcode code, const cha
|
c[5] = !(iflags & ITEM_REPORT_PERMS) ? '.' : 'p'; |
c[5] = !(iflags & ITEM_REPORT_PERMS) ? '.' : 'p'; |
c[6] = !(iflags & ITEM_REPORT_OWNER) ? '.' : 'o'; |
c[6] = !(iflags & ITEM_REPORT_OWNER) ? '.' : 'o'; |
c[7] = !(iflags & ITEM_REPORT_GROUP) ? '.' : 'g'; |
c[7] = !(iflags & ITEM_REPORT_GROUP) ? '.' : 'g'; |
c[8] = !(iflags & ITEM_REPORT_ATIME) ? '.' : 'u'; | c[8] = !(iflags & (ITEM_REPORT_ATIME|ITEM_REPORT_CRTIME)) ? '.' |
| : BITS_SET(iflags, ITEM_REPORT_ATIME|ITEM_REPORT_CRTIME) ? 'b' |
| : iflags & ITEM_REPORT_ATIME ? 'u' : 'n'; |
c[9] = !(iflags & ITEM_REPORT_ACL) ? '.' : 'a'; |
c[9] = !(iflags & ITEM_REPORT_ACL) ? '.' : 'a'; |
c[10] = !(iflags & ITEM_REPORT_XATTR) ? '.' : 'x'; |
c[10] = !(iflags & ITEM_REPORT_XATTR) ? '.' : 'x'; |
c[11] = '\0'; | c[11] = !(iflags & ITEM_REPORT_FFLAGS) ? '.' : 'f'; |
| c[12] = '\0'; |
|
|
if (iflags & (ITEM_IS_NEW|ITEM_MISSING_DATA)) { |
if (iflags & (ITEM_IS_NEW|ITEM_MISSING_DATA)) { |
char ch = iflags & ITEM_IS_NEW ? '+' : '?'; |
char ch = iflags & ITEM_IS_NEW ? '+' : '?'; |
Line 728 int log_format_has(const char *format, char esc)
|
Line 794 int log_format_has(const char *format, char esc)
|
return 0; |
return 0; |
|
|
for (p = format; (p = strchr(p, '%')) != NULL; ) { |
for (p = format; (p = strchr(p, '%')) != NULL; ) { |
if (*++p == '-') | for (p++; *p == '\''; p++) {} /*SHARED ITERATOR*/ |
| if (*p == '-') |
p++; |
p++; |
while (isDigit(p)) |
while (isDigit(p)) |
p++; |
p++; |
|
while (*p == '\'') p++; |
if (!*p) |
if (!*p) |
break; |
break; |
if (*p == esc) |
if (*p == esc) |
Line 743 int log_format_has(const char *format, char esc)
|
Line 811 int log_format_has(const char *format, char esc)
|
/* Log the transfer of a file. If the code is FCLIENT, the output just goes |
/* Log the transfer of a file. If the code is FCLIENT, the output just goes |
* to stdout. If it is FLOG, it just goes to the log file. Otherwise we |
* to stdout. If it is FLOG, it just goes to the log file. Otherwise we |
* output to both. */ |
* output to both. */ |
void log_item(enum logcode code, struct file_struct *file, | void log_item(enum logcode code, struct file_struct *file, int iflags, const char *hlink) |
struct stats *initial_stats, int iflags, const char *hlink) | |
{ |
{ |
const char *s_or_r = am_sender ? "send" : "recv"; |
const char *s_or_r = am_sender ? "send" : "recv"; |
|
|
if (code != FLOG && stdout_format && !am_server) { | if (code != FLOG && stdout_format && !am_server) |
log_formatted(FCLIENT, stdout_format, s_or_r, | log_formatted(FCLIENT, stdout_format, s_or_r, file, NULL, iflags, hlink); |
file, NULL, initial_stats, iflags, hlink); | if (code != FCLIENT && logfile_format && *logfile_format) |
} | log_formatted(FLOG, logfile_format, s_or_r, file, NULL, iflags, hlink); |
if (code != FCLIENT && logfile_format && *logfile_format) { | |
log_formatted(FLOG, logfile_format, s_or_r, | |
file, NULL, initial_stats, iflags, hlink); | |
} | |
} |
} |
|
|
void maybe_log_item(struct file_struct *file, int iflags, int itemizing, | void maybe_log_item(struct file_struct *file, int iflags, int itemizing, const char *buf) |
const char *buf) | |
{ |
{ |
int significant_flags = iflags & SIGNIFICANT_ITEM_FLAGS; |
int significant_flags = iflags & SIGNIFICANT_ITEM_FLAGS; |
int see_item = itemizing && (significant_flags || *buf |
int see_item = itemizing && (significant_flags || *buf |
|| stdout_format_has_i > 1 || (verbose > 1 && stdout_format_has_i)); | || stdout_format_has_i > 1 || (INFO_GTE(NAME, 2) && stdout_format_has_i)); |
int local_change = iflags & ITEM_LOCAL_CHANGE && significant_flags; |
int local_change = iflags & ITEM_LOCAL_CHANGE && significant_flags; |
if (am_server) { |
if (am_server) { |
if (logfile_name && !dry_run && see_item |
if (logfile_name && !dry_run && see_item |
&& (significant_flags || logfile_format_has_i)) |
&& (significant_flags || logfile_format_has_i)) |
log_item(FLOG, file, &stats, iflags, buf); | log_item(FLOG, file, iflags, buf); |
} else if (see_item || local_change || *buf |
} else if (see_item || local_change || *buf |
|| (S_ISDIR(file->mode) && significant_flags)) { |
|| (S_ISDIR(file->mode) && significant_flags)) { |
enum logcode code = significant_flags || logfile_format_has_i ? FINFO : FCLIENT; |
enum logcode code = significant_flags || logfile_format_has_i ? FINFO : FCLIENT; |
log_item(code, file, &stats, iflags, buf); | log_item(code, file, iflags, buf); |
} |
} |
} |
} |
|
|
Line 781 void log_delete(const char *fname, int mode)
|
Line 843 void log_delete(const char *fname, int mode)
|
static struct { |
static struct { |
union file_extras ex[4]; /* just in case... */ |
union file_extras ex[4]; /* just in case... */ |
struct file_struct file; |
struct file_struct file; |
} x; | } x; /* Zero-initialized due to static declaration. */ |
int len = strlen(fname); |
int len = strlen(fname); |
const char *fmt; |
const char *fmt; |
|
|
x.file.mode = mode; |
x.file.mode = mode; |
|
|
if (!verbose && !stdout_format) | if (am_server && protocol_version >= 29 && len < MAXPATHLEN) { |
; | |
else if (am_server && protocol_version >= 29 && len < MAXPATHLEN) { | |
if (S_ISDIR(mode)) |
if (S_ISDIR(mode)) |
len++; /* directories include trailing null */ |
len++; /* directories include trailing null */ |
send_msg(MSG_DELETED, fname, len, am_generator); |
send_msg(MSG_DELETED, fname, len, am_generator); |
} else { | } else if (!INFO_GTE(DEL, 1) && !stdout_format) |
| ; |
| else { |
fmt = stdout_format_has_o_or_i ? stdout_format : "deleting %n"; |
fmt = stdout_format_has_o_or_i ? stdout_format : "deleting %n"; |
log_formatted(FCLIENT, fmt, "del.", &x.file, fname, &stats, | log_formatted(FCLIENT, fmt, "del.", &x.file, fname, ITEM_DELETED, NULL); |
ITEM_DELETED, NULL); | |
} |
} |
|
|
if (!logfile_name || dry_run || !logfile_format) |
if (!logfile_name || dry_run || !logfile_format) |
return; |
return; |
|
|
fmt = logfile_format_has_o_or_i ? logfile_format : "deleting %n"; |
fmt = logfile_format_has_o_or_i ? logfile_format : "deleting %n"; |
log_formatted(FLOG, fmt, "del.", &x.file, fname, &stats, ITEM_DELETED, NULL); | log_formatted(FLOG, fmt, "del.", &x.file, fname, ITEM_DELETED, NULL); |
} |
} |
|
|
/* |
/* |
Line 814 void log_delete(const char *fname, int mode)
|
Line 875 void log_delete(const char *fname, int mode)
|
*/ |
*/ |
void log_exit(int code, const char *file, int line) |
void log_exit(int code, const char *file, int line) |
{ |
{ |
if (code == 0) { | /* The receiving side's stats are split between 2 procs until the |
rprintf(FLOG,"sent %.0f bytes received %.0f bytes total size %.0f\n", | * end of the run, so only the sender can output non-final info. */ |
(double)stats.total_written, | if (code == 0 || am_sender) { |
(double)stats.total_read, | rprintf(FLOG,"sent %s bytes received %s bytes total size %s\n", |
(double)stats.total_size); | big_num(stats.total_written), |
} else if (am_server != 2) { | big_num(stats.total_read), |
| big_num(stats.total_size)); |
| } |
| if (code != 0 && am_server != 2) { |
const char *name; |
const char *name; |
|
|
name = rerr_name(code); |
name = rerr_name(code); |
Line 829 void log_exit(int code, const char *file, int line)
|
Line 893 void log_exit(int code, const char *file, int line)
|
/* VANISHED is not an error, only a warning */ |
/* VANISHED is not an error, only a warning */ |
if (code == RERR_VANISHED) { |
if (code == RERR_VANISHED) { |
rprintf(FWARNING, "rsync warning: %s (code %d) at %s(%d) [%s=%s]\n", |
rprintf(FWARNING, "rsync warning: %s (code %d) at %s(%d) [%s=%s]\n", |
name, code, file, line, who_am_i(), RSYNC_VERSION); | name, code, src_file(file), line, who_am_i(), rsync_version()); |
} else { |
} else { |
rprintf(FERROR, "rsync error: %s (code %d) at %s(%d) [%s=%s]\n", |
rprintf(FERROR, "rsync error: %s (code %d) at %s(%d) [%s=%s]\n", |
name, code, file, line, who_am_i(), RSYNC_VERSION); | name, code, src_file(file), line, who_am_i(), rsync_version()); |
} |
} |
} |
} |
} |
} |