1 This patch allows a non-daemon server and a client rsync to log what they
2 are doing, similar to how a daemon logs its actions.
10 +extern int am_server;
12 extern int keep_partial;
13 extern int log_got_error;
14 @@ -149,7 +150,7 @@ void _exit_cleanup(int code, const char
19 + if (code || am_server)
20 log_exit(code, file, line);
23 --- old/clientserver.c
24 +++ new/clientserver.c
25 @@ -44,11 +44,15 @@ extern int protocol_version;
26 extern int io_timeout;
28 extern int default_af_hint;
29 +extern int logfile_format_has_i;
30 +extern int logfile_format_has_o_or_i;
31 extern int log_initialised;
32 extern mode_t orig_umask;
33 extern char *bind_address;
34 extern char *sockopts;
35 extern char *config_file;
36 +extern char *logfile_format;
37 +extern char *logfile_name;
38 extern char *files_from;
40 extern struct chmod_mode_struct *chmod_modes;
41 @@ -56,8 +60,6 @@ extern struct filter_list_struct server_
45 -int daemon_log_format_has_i = 0;
46 -int daemon_log_format_has_o_or_i = 0;
48 struct chmod_mode_struct *daemon_chmod_modes;
50 @@ -330,11 +332,12 @@ static int rsync_module(int f_in, int f_
53 if (lp_transfer_logging(i)) {
54 - if (log_format_has(lp_log_format(i), 'i'))
55 - daemon_log_format_has_i = 1;
56 - if (daemon_log_format_has_i
57 - || log_format_has(lp_log_format(i), 'o'))
58 - daemon_log_format_has_o_or_i = 1;
59 + logfile_format = lp_log_format(i);
60 + if (log_format_has(logfile_format, 'i'))
61 + logfile_format_has_i = 1;
62 + if (logfile_format_has_i
63 + || log_format_has(logfile_format, 'o'))
64 + logfile_format_has_o_or_i = 1;
67 am_root = (MY_UID() == 0);
68 @@ -395,6 +398,7 @@ static int rsync_module(int f_in, int f_
69 parse_rule(&server_filter_list, p, MATCHFLG_WORD_SPLIT,
70 XFLG_ABS_IF_SLASH | XFLG_OLD_PREFIXES);
72 + logfile_name = lp_log_file();
76 @@ -742,8 +746,10 @@ int start_daemon(int f_in, int f_out)
77 if (!lp_load(config_file, 0))
78 exit_cleanup(RERR_SYNTAX);
80 - if (!log_initialised)
81 + if (!log_initialised) {
82 + logfile_name = lp_log_file();
87 set_socket_options(f_in, "SO_KEEPALIVE");
88 @@ -842,6 +848,7 @@ int daemon_main(void)
89 if (bind_address == NULL && *lp_bind_address())
90 bind_address = lp_bind_address();
92 + logfile_name = lp_log_file();
95 rprintf(FLOG, "rsyncd version %s starting, listening on port %d\n",
98 @@ -95,15 +95,15 @@ static int show_filelist_p(void)
100 static void start_filelist_progress(char *kind)
102 - rprintf(FINFO, "%s ... ", kind);
103 + rprintf(FCLIENT, "%s ... ", kind);
104 if (verbose > 1 || do_progress)
105 - rprintf(FINFO, "\n");
106 + rprintf(FCLIENT, "\n");
110 static void emit_filelist_progress(int count)
112 - rprintf(FINFO, " %d files...\r", count);
113 + rprintf(FCLIENT, " %d files...\r", count);
116 static void maybe_emit_filelist_progress(int count)
117 @@ -295,7 +295,7 @@ void flist_expand(struct file_list *flis
120 if (verbose >= 2 && flist->malloced != FLIST_START) {
121 - rprintf(FINFO, "[%s] expand file_list to %.0f bytes, did%s move\n",
122 + rprintf(FCLIENT, "[%s] expand file_list to %.0f bytes, did%s move\n",
124 (double)sizeof flist->files[0] * flist->malloced,
125 (new_ptr == flist->files) ? " not" : "");
126 @@ -1077,6 +1077,7 @@ struct file_list *send_file_list(int f,
130 + rprintf(FLOG, "building file list\n");
131 if (show_filelist_p())
132 start_filelist_progress("building file list");
134 @@ -1343,6 +1344,7 @@ struct file_list *recv_file_list(int f)
135 unsigned short flags;
138 + rprintf(FLOG, "receiving file list\n");
139 if (show_filelist_p())
140 start_filelist_progress("receiving file list");
144 @@ -27,7 +27,7 @@ extern int verbose;
147 extern int log_format_has_i;
148 -extern int daemon_log_format_has_i;
149 +extern int logfile_format_has_i;
151 extern int am_server;
152 extern int am_daemon;
153 @@ -663,7 +663,7 @@ static int try_dests_reg(struct file_str
154 } else if (itemizing)
155 itemize(file, ndx, 0, stp, 0, 0, NULL);
156 if (verbose > 1 && maybe_ATTRS_REPORT) {
157 - code = daemon_log_format_has_i || dry_run
158 + code = logfile_format_has_i || dry_run
160 rprintf(code, "%s is uptodate\n", fname);
162 @@ -686,7 +686,7 @@ static int try_dests_reg(struct file_str
163 if (maybe_ATTRS_REPORT
164 && ((!itemizing && verbose && match_level == 2)
165 || (verbose > 1 && match_level == 3))) {
166 - code = daemon_log_format_has_i || dry_run
167 + code = logfile_format_has_i || dry_run
169 rprintf(code, "%s%s\n", fname,
170 match_level == 3 ? " is uptodate" : "");
171 @@ -742,7 +742,7 @@ static int try_dests_non(struct file_str
172 itemize(file, ndx, 0, &st, changes, 0, lp);
174 if (verbose > 1 && maybe_ATTRS_REPORT) {
175 - code = daemon_log_format_has_i || dry_run
176 + code = logfile_format_has_i || dry_run
178 rprintf(code, "%s is uptodate\n", fname);
180 @@ -1304,9 +1304,9 @@ void generate_files(int f_out, struct fi
181 if (protocol_version >= 29) {
183 maybe_ATTRS_REPORT = log_format_has_i ? 0 : ATTRS_REPORT;
184 - code = daemon_log_format_has_i ? 0 : FLOG;
185 + code = logfile_format_has_i ? 0 : FLOG;
186 } else if (am_daemon) {
187 - itemizing = daemon_log_format_has_i && do_xfers;
188 + itemizing = logfile_format_has_i && do_xfers;
189 maybe_ATTRS_REPORT = ATTRS_REPORT;
190 code = itemizing || !do_xfers ? FCLIENT : FINFO;
191 } else if (!am_server) {
194 @@ -44,16 +44,17 @@ extern int protocol_version;
195 extern int preserve_times;
196 extern int log_format_has_i;
197 extern int log_format_has_o_or_i;
198 -extern int daemon_log_format_has_o_or_i;
199 +extern int logfile_format_has_o_or_i;
200 extern mode_t orig_umask;
201 extern char *auth_user;
202 extern char *log_format;
203 +extern char *logfile_format;
204 +extern char *logfile_name;
205 #if defined HAVE_ICONV_OPEN && defined HAVE_ICONV_H
206 extern iconv_t ic_chck;
209 static int logfile_was_closed;
210 -static char *logfname;
211 static FILE *logfile;
214 @@ -145,14 +146,14 @@ static void syslog_init()
215 static void logfile_open(void)
217 mode_t old_umask = umask(022 | orig_umask);
218 - logfile = fopen(logfname, "a");
219 + logfile = fopen(logfile_name, "a");
222 int fopen_errno = errno;
223 /* Rsync falls back to using syslog on failure. */
225 rsyserr(FERROR, fopen_errno,
226 - "failed to open log-file %s", logfname);
227 + "failed to open log-file %s", logfile_name);
228 rprintf(FINFO, "Ignoring \"log file\" setting.\n");
231 @@ -171,9 +172,7 @@ void log_init(void)
235 - /* optionally use a log file instead of syslog */
236 - logfname = lp_log_file();
237 - if (logfname && *logfname)
238 + if (logfile_name && *logfile_name)
242 @@ -243,9 +242,9 @@ void rwrite(enum logcode code, char *buf
246 - else if (am_daemon) {
247 + else if (logfile_name) { /* always non-NULL in the daemon */
250 + char msg[2048], *s;
251 int priority = code == FERROR ? LOG_WARNING : LOG_INFO;
254 @@ -254,10 +253,11 @@ void rwrite(enum logcode code, char *buf
255 if (!log_initialised)
257 strlcpy(msg, buf, MIN((int)sizeof msg, len + 1));
258 - logit(priority, msg);
259 + for (s = msg; *s == '\n' && s[1]; s++) {}
260 + logit(priority, s);
263 - if (code == FLOG || !am_server)
264 + if (code == FLOG || (am_daemon && !am_server))
266 } else if (code == FLOG)
268 @@ -403,26 +403,14 @@ void rflush(enum logcode code)
273 + if (am_daemon || code == FLOG)
277 - if (code == FLOG) {
281 - if (code == FERROR) {
282 + if (code == FERROR || am_server)
286 - if (code == FINFO) {
295 - if (!f) exit_cleanup(RERR_MESSAGEIO);
299 @@ -695,12 +683,12 @@ void log_item(struct file_struct *file,
301 char *s_or_r = am_sender ? "send" : "recv";
303 - if (lp_transfer_logging(module_id)) {
304 - log_formatted(FLOG, lp_log_format(module_id), s_or_r,
305 - file, initial_stats, iflags, hlink);
306 - } else if (log_format && !am_server) {
307 + if (log_format && !am_server) {
308 log_formatted(FNAME, log_format, s_or_r,
309 file, initial_stats, iflags, hlink);
310 + } else if (logfile_format) {
311 + log_formatted(FLOG, logfile_format, s_or_r,
312 + file, initial_stats, iflags, hlink);
316 @@ -712,7 +700,7 @@ void maybe_log_item(struct file_struct *
317 || log_format_has_i > 1 || (verbose > 1 && log_format_has_i));
318 int local_change = iflags & ITEM_LOCAL_CHANGE && significant_flags;
320 - if (am_daemon && !dry_run && see_item)
321 + if (logfile_name && !dry_run && see_item)
322 log_item(file, &stats, iflags, buf);
323 } else if (see_item || local_change || *buf
324 || (S_ISDIR(file->mode) && significant_flags))
325 @@ -740,10 +728,10 @@ void log_delete(char *fname, int mode)
329 - if (!am_daemon || dry_run || !lp_transfer_logging(module_id))
330 + if (!logfile_name || dry_run || !logfile_format)
333 - fmt = daemon_log_format_has_o_or_i ? lp_log_format(module_id) : "deleting %n";
334 + fmt = logfile_format_has_o_or_i ? logfile_format : "deleting %n";
335 log_formatted(FLOG, fmt, "del.", &file, &stats, ITEM_DELETED, NULL);
340 @@ -168,7 +168,6 @@ static void handle_stats(int f)
344 - log_exit(0, __FILE__, __LINE__);
345 if (f == -1 || !am_sender)
350 @@ -146,6 +146,8 @@ char *basis_dir[MAX_BASIS_DIRS+1];
351 char *config_file = NULL;
352 char *shell_cmd = NULL;
353 char *log_format = NULL;
354 +char *logfile_name = NULL;
355 +char *logfile_format = NULL;
356 char *password_file = NULL;
357 char *rsync_path = RSYNC_PATH;
358 char *backup_dir = NULL;
359 @@ -162,7 +164,9 @@ int verbose = 0;
361 int log_before_transfer = 0;
362 int log_format_has_i = 0;
363 +int logfile_format_has_i = 0;
364 int log_format_has_o_or_i = 0;
365 +int logfile_format_has_o_or_i = 0;
366 int always_checksum = 0;
369 @@ -359,6 +363,7 @@ void usage(enum logcode F)
370 rprintf(F," --progress show progress during transfer\n");
371 rprintf(F," -P same as --partial --progress\n");
372 rprintf(F," -i, --itemize-changes output a change-summary for all updates\n");
373 + rprintf(F," --log-file=FILE output what we're doing to a log file\n");
374 rprintf(F," --log-format=FORMAT output filenames using the specified format\n");
375 rprintf(F," --password-file=FILE read password from FILE\n");
376 rprintf(F," --list-only list the files instead of copying them\n");
377 @@ -492,6 +497,7 @@ static struct poptOption long_options[]
378 {"partial-dir", 0, POPT_ARG_STRING, &partial_dir, 0, 0, 0 },
379 {"delay-updates", 0, POPT_ARG_NONE, &delay_updates, 0, 0, 0 },
380 {"prune-empty-dirs",'m', POPT_ARG_NONE, &prune_empty_dirs, 0, 0, 0 },
381 + {"log-file", 0, POPT_ARG_STRING, &logfile_name, 0, 0, 0 },
382 {"log-format", 0, POPT_ARG_STRING, &log_format, 0, 0, 0 },
383 {"itemize-changes", 'i', POPT_ARG_NONE, 0, 'i', 0, 0 },
384 {"bwlimit", 0, POPT_ARG_INT, &bwlimit, 0, 0, 0 },
385 @@ -1311,6 +1317,21 @@ int parse_arguments(int *argc, const cha
386 if (log_format_has_i || log_format_has(log_format, 'o'))
387 log_format_has_o_or_i = 1;
390 + logfile_name = NULL;
391 + else if (logfile_name) {
393 + logfile_format = "%i %n%L";
394 + logfile_format_has_i = logfile_format_has_o_or_i = 1;
395 + } else if (log_format) {
396 + logfile_format = log_format;
397 + logfile_format_has_i = log_format_has_i;
398 + logfile_format_has_o_or_i = log_format_has_o_or_i;
400 + log_before_transfer = !am_server;
404 if (daemon_bwlimit && (!bwlimit || bwlimit > daemon_bwlimit))
405 bwlimit = daemon_bwlimit;
409 @@ -103,7 +103,7 @@ static void rprint_progress(OFF_T ofs, O
413 - rprintf(FINFO, "%12s %3d%% %7.2f%s %4d:%02d:%02d%s",
414 + rprintf(FCLIENT, "%12s %3d%% %7.2f%s %4d:%02d:%02d%s",
415 human_num(ofs), pct, rate, units,
416 remain_h, remain_m, remain_s, eol);
420 @@ -27,7 +27,7 @@ extern int am_server;
421 extern int do_progress;
422 extern int log_before_transfer;
423 extern int log_format_has_i;
424 -extern int daemon_log_format_has_i;
425 +extern int logfile_format_has_i;
426 extern int csum_length;
427 extern int read_batch;
428 extern int write_batch;
429 @@ -341,8 +341,7 @@ int recv_files(int f_in, struct file_lis
430 struct file_struct *file;
431 struct stats initial_stats;
432 int save_make_backups = make_backups;
433 - int itemizing = am_daemon ? daemon_log_format_has_i
434 - : !am_server && log_format_has_i;
435 + int itemizing = am_server ? logfile_format_has_i : log_format_has_i;
436 int max_phase = protocol_version >= 29 ? 2 : 1;
445 -extern int daemon_log_format_has_i;
446 +extern int logfile_format_has_i;
447 extern int preserve_perms;
448 extern int preserve_executability;
449 extern int preserve_times;
450 @@ -218,7 +218,7 @@ int set_file_attrs(char *fname, struct f
453 if (verbose > 1 && flags & ATTRS_REPORT) {
454 - enum logcode code = daemon_log_format_has_i || dry_run
455 + enum logcode code = logfile_format_has_i || dry_run
458 rprintf(code, "%s\n", fname);
464 /* Log-message categories. Only FERROR and FINFO get sent over the socket.
465 - * FLOG and FCLIENT are only used on the daemon side for custom logging,
466 - * while FNAME is only used on the client side. */
467 + * FLOG only goes to the log file, not to the client; FCLIENT is the opposite.
468 + * FNAME is a client-side message when outputting a filename on its own. */
469 enum logcode { FERROR=1, FINFO=2, FLOG=3, FCLIENT=4, FNAME=5, FSOCKERR=6 };
471 /* Messages types that are sent over the message channel. The logcode
474 @@ -387,6 +387,7 @@ to the detailed description below for a
475 --progress show progress during transfer
476 -P same as --partial --progress
477 -i, --itemize-changes output a change-summary for all updates
478 + --log-file=FILE output what we're doing to a log file
479 --log-format=FORMAT output filenames using the specified format
480 --password-file=FILE read password from FILE
481 --list-only list the files instead of copying them
482 @@ -1423,6 +1424,23 @@ the string "*deleting" for each item tha
483 you are talking to a recent enough rsync that it logs deletions instead of
484 outputting them as a verbose message).
486 +dit(bf(--log-file=FILE)) This option causes rsync to log what it is doing
487 +to a file. This is similar to the logging that a daemon does, but can be
488 +requested for the client side and/or the server side of a non-daemon
489 +transfer. If specified as a client option, transfer logging will in effect
490 +if the bf(--log-format) option was either specified or implied (e.g.
491 +bf(--verbose) implies a basic log format). If explicitly sent to a server
492 +via the bf(--rsync-path) option, transfer logging will always occur using
493 +the default bf(--itemize-changes) format.
495 +Here's a example command that requests the remote side to log what is
498 +verb( rsync -av --rsync-path="path --log-file=/tmp/rlog" src/ dest/)
500 +This is very useful if you need to debug why a connection is closing
503 dit(bf(--log-format=FORMAT)) This allows you to specify exactly what the
504 rsync client outputs to the user on a per-file basis. The format is a text
505 string containing embedded single-character escape sequences prefixed with
508 @@ -25,7 +25,7 @@ extern int am_server;
509 extern int am_daemon;
510 extern int log_before_transfer;
511 extern int log_format_has_i;
512 -extern int daemon_log_format_has_i;
513 +extern int logfile_format_has_i;
514 extern int csum_length;
515 extern int append_mode;
517 @@ -215,8 +215,7 @@ void send_files(struct file_list *flist,
518 int phase = 0, max_phase = protocol_version >= 29 ? 2 : 1;
519 struct stats initial_stats;
520 int save_make_backups = make_backups;
521 - int itemizing = am_daemon ? daemon_log_format_has_i
522 - : !am_server && log_format_has_i;
523 + int itemizing = am_server ? logfile_format_has_i : log_format_has_i;
524 int f_xfer = write_batch < 0 ? batch_fd : f_out;