Make sure that whenever log_init() gets called, that a daemon rsync
[rsync/rsync-patches.git] / log-file.diff
CommitLineData
9d32714e
WD
1This patch allows a non-daemon server and a client rsync to log what they
2are doing, similar to how a daemon logs its actions.
3
4--- old/cleanup.c
5+++ new/cleanup.c
6@@ -21,6 +21,7 @@
7
8 #include "rsync.h"
9
10+extern int am_server;
11 extern int io_error;
12 extern int keep_partial;
13 extern int log_got_error;
14@@ -149,7 +150,7 @@ void _exit_cleanup(int code, const char
15 code = RERR_PARTIAL;
16 }
17
18- if (code)
19+ if (code || am_server)
20 log_exit(code, file, line);
21
22 if (verbose > 2) {
23--- old/clientserver.c
24+++ new/clientserver.c
6596b2bd 25@@ -44,10 +44,14 @@ extern int protocol_version;
9d32714e
WD
26 extern int io_timeout;
27 extern int no_detach;
28 extern int default_af_hint;
29+extern int logfile_format_has_i;
30+extern int logfile_format_has_o_or_i;
31 extern mode_t orig_umask;
32 extern char *bind_address;
33 extern char *sockopts;
34 extern char *config_file;
35+extern char *logfile_format;
36+extern char *logfile_name;
37 extern char *files_from;
38 extern char *tmpdir;
39 extern struct chmod_mode_struct *chmod_modes;
6596b2bd 40@@ -55,8 +59,6 @@ extern struct filter_list_struct server_
9d32714e
WD
41
42 char *auth_user;
43 int read_only = 0;
44-int daemon_log_format_has_i = 0;
45-int daemon_log_format_has_o_or_i = 0;
46 int module_id = -1;
47 struct chmod_mode_struct *daemon_chmod_modes;
48
6596b2bd 49@@ -329,11 +331,12 @@ static int rsync_module(int f_in, int f_
9d32714e
WD
50 read_only = 1;
51
9d32714e
WD
52 if (lp_transfer_logging(i)) {
53- if (log_format_has(lp_log_format(i), 'i'))
54- daemon_log_format_has_i = 1;
55- if (daemon_log_format_has_i
56- || log_format_has(lp_log_format(i), 'o'))
57- daemon_log_format_has_o_or_i = 1;
58+ logfile_format = lp_log_format(i);
59+ if (log_format_has(logfile_format, 'i'))
60+ logfile_format_has_i = 1;
61+ if (logfile_format_has_i
62+ || log_format_has(logfile_format, 'o'))
63+ logfile_format_has_o_or_i = 1;
64 }
65
66 am_root = (MY_UID() == 0);
67--- old/flist.c
68+++ new/flist.c
69@@ -95,15 +95,15 @@ static int show_filelist_p(void)
70
71 static void start_filelist_progress(char *kind)
72 {
73- rprintf(FINFO, "%s ... ", kind);
74+ rprintf(FCLIENT, "%s ... ", kind);
75 if (verbose > 1 || do_progress)
76- rprintf(FINFO, "\n");
77+ rprintf(FCLIENT, "\n");
78 rflush(FINFO);
79 }
80
81 static void emit_filelist_progress(int count)
82 {
83- rprintf(FINFO, " %d files...\r", count);
84+ rprintf(FCLIENT, " %d files...\r", count);
85 }
86
87 static void maybe_emit_filelist_progress(int count)
88@@ -295,7 +295,7 @@ void flist_expand(struct file_list *flis
89 flist->malloced);
90
91 if (verbose >= 2 && flist->malloced != FLIST_START) {
92- rprintf(FINFO, "[%s] expand file_list to %.0f bytes, did%s move\n",
93+ rprintf(FCLIENT, "[%s] expand file_list to %.0f bytes, did%s move\n",
94 who_am_i(),
95 (double)sizeof flist->files[0] * flist->malloced,
96 (new_ptr == flist->files) ? " not" : "");
97@@ -1077,6 +1077,7 @@ struct file_list *send_file_list(int f,
98 int64 start_write;
99 int use_ff_fd = 0;
100
101+ rprintf(FLOG, "building file list\n");
102 if (show_filelist_p())
103 start_filelist_progress("building file list");
104
105@@ -1343,6 +1344,7 @@ struct file_list *recv_file_list(int f)
106 unsigned short flags;
107 int64 start_read;
108
109+ rprintf(FLOG, "receiving file list\n");
110 if (show_filelist_p())
111 start_filelist_progress("receiving file list");
112
113--- old/generator.c
114+++ new/generator.c
115@@ -27,7 +27,7 @@ extern int verbose;
116 extern int dry_run;
117 extern int do_xfers;
118 extern int log_format_has_i;
119-extern int daemon_log_format_has_i;
120+extern int logfile_format_has_i;
121 extern int am_root;
122 extern int am_server;
123 extern int am_daemon;
124@@ -663,7 +663,7 @@ static int try_dests_reg(struct file_str
125 } else if (itemizing)
126 itemize(file, ndx, 0, stp, 0, 0, NULL);
127 if (verbose > 1 && maybe_ATTRS_REPORT) {
128- code = daemon_log_format_has_i || dry_run
129+ code = logfile_format_has_i || dry_run
130 ? FCLIENT : FINFO;
131 rprintf(code, "%s is uptodate\n", fname);
132 }
133@@ -686,7 +686,7 @@ static int try_dests_reg(struct file_str
134 if (maybe_ATTRS_REPORT
135 && ((!itemizing && verbose && match_level == 2)
136 || (verbose > 1 && match_level == 3))) {
137- code = daemon_log_format_has_i || dry_run
138+ code = logfile_format_has_i || dry_run
139 ? FCLIENT : FINFO;
140 rprintf(code, "%s%s\n", fname,
141 match_level == 3 ? " is uptodate" : "");
142@@ -742,7 +742,7 @@ static int try_dests_non(struct file_str
143 itemize(file, ndx, 0, &st, changes, 0, lp);
144 }
145 if (verbose > 1 && maybe_ATTRS_REPORT) {
146- code = daemon_log_format_has_i || dry_run
147+ code = logfile_format_has_i || dry_run
148 ? FCLIENT : FINFO;
149 rprintf(code, "%s is uptodate\n", fname);
150 }
151@@ -1304,9 +1304,9 @@ void generate_files(int f_out, struct fi
152 if (protocol_version >= 29) {
153 itemizing = 1;
154 maybe_ATTRS_REPORT = log_format_has_i ? 0 : ATTRS_REPORT;
155- code = daemon_log_format_has_i ? 0 : FLOG;
156+ code = logfile_format_has_i ? 0 : FLOG;
157 } else if (am_daemon) {
158- itemizing = daemon_log_format_has_i && do_xfers;
159+ itemizing = logfile_format_has_i && do_xfers;
160 maybe_ATTRS_REPORT = ATTRS_REPORT;
161 code = itemizing || !do_xfers ? FCLIENT : FINFO;
162 } else if (!am_server) {
163--- old/log.c
164+++ new/log.c
6596b2bd 165@@ -44,18 +44,19 @@ extern int protocol_version;
9d32714e
WD
166 extern int preserve_times;
167 extern int log_format_has_i;
168 extern int log_format_has_o_or_i;
169-extern int daemon_log_format_has_o_or_i;
170+extern int logfile_format_has_o_or_i;
171 extern mode_t orig_umask;
172 extern char *auth_user;
173 extern char *log_format;
174+extern char *logfile_format;
175+extern char *logfile_name;
176 #if defined HAVE_ICONV_OPEN && defined HAVE_ICONV_H
177 extern iconv_t ic_chck;
178 #endif
179
6596b2bd 180 static int log_initialised;
9d32714e
WD
181 static int logfile_was_closed;
182-static char *logfname;
31ce435c
WD
183-static FILE *logfile;
184+static FILE *logfile_fp;
9d32714e
WD
185 struct stats stats;
186
31ce435c
WD
187 int log_got_error = 0;
188@@ -109,10 +110,10 @@ static void logit(int priority, char *bu
189 {
190 if (logfile_was_closed)
191 logfile_reopen();
192- if (logfile) {
193- fprintf(logfile,"%s [%d] %s",
194+ if (logfile_fp) {
195+ fprintf(logfile_fp, "%s [%d] %s",
196 timestring(time(NULL)), (int)getpid(), buf);
197- fflush(logfile);
198+ fflush(logfile_fp);
199 } else {
200 syslog(priority, "%s", buf);
201 }
9d32714e
WD
202@@ -145,14 +146,14 @@ static void syslog_init()
203 static void logfile_open(void)
204 {
205 mode_t old_umask = umask(022 | orig_umask);
206- logfile = fopen(logfname, "a");
31ce435c 207+ logfile_fp = fopen(logfile_name, "a");
9d32714e 208 umask(old_umask);
31ce435c
WD
209- if (!logfile) {
210+ if (!logfile_fp) {
9d32714e
WD
211 int fopen_errno = errno;
212 /* Rsync falls back to using syslog on failure. */
213 syslog_init();
214 rsyserr(FERROR, fopen_errno,
215- "failed to open log-file %s", logfname);
216+ "failed to open log-file %s", logfile_name);
217 rprintf(FINFO, "Ignoring \"log file\" setting.\n");
218 }
219 }
6596b2bd
WD
220@@ -171,9 +172,11 @@ void log_init(void)
221 t = time(NULL);
9d32714e
WD
222 localtime(&t);
223
6596b2bd 224- /* optionally use a log file instead of syslog */
9d32714e
WD
225- logfname = lp_log_file();
226- if (logfname && *logfname)
6596b2bd
WD
227+ /* Optionally use a log file instead of syslog. (Non-daemon
228+ * rsyncs will have already set logfile_name, as needed.) */
229+ if (am_daemon)
230+ logfile_name = lp_log_file();
9d32714e
WD
231+ if (logfile_name && *logfile_name)
232 logfile_open();
233 else
234 syslog_init();
6596b2bd 235@@ -181,10 +184,10 @@ void log_init(void)
31ce435c
WD
236
237 void logfile_close(void)
238 {
239- if (logfile) {
240+ if (logfile_fp) {
241 logfile_was_closed = 1;
242- fclose(logfile);
243- logfile = NULL;
244+ fclose(logfile_fp);
245+ logfile_fp = NULL;
246 }
247 }
248
6596b2bd 249@@ -243,9 +246,9 @@ void rwrite(enum logcode code, char *buf
9d32714e
WD
250
251 if (code == FCLIENT)
252 code = FINFO;
253- else if (am_daemon) {
6596b2bd 254+ else if (am_daemon || logfile_name) {
9d32714e
WD
255 static int in_block;
256- char msg[2048];
257+ char msg[2048], *s;
258 int priority = code == FERROR ? LOG_WARNING : LOG_INFO;
259
260 if (in_block)
6596b2bd 261@@ -254,10 +257,11 @@ void rwrite(enum logcode code, char *buf
9d32714e
WD
262 if (!log_initialised)
263 log_init();
264 strlcpy(msg, buf, MIN((int)sizeof msg, len + 1));
265- logit(priority, msg);
266+ for (s = msg; *s == '\n' && s[1]; s++) {}
267+ logit(priority, s);
268 in_block = 0;
269
270- if (code == FLOG || !am_server)
271+ if (code == FLOG || (am_daemon && !am_server))
272 return;
273 } else if (code == FLOG)
274 return;
6596b2bd 275@@ -403,26 +407,14 @@ void rflush(enum logcode code)
9d32714e
WD
276 {
277 FILE *f = NULL;
278
279- if (am_daemon) {
280+ if (am_daemon || code == FLOG)
281 return;
282- }
283
284- if (code == FLOG) {
285- return;
286- }
287-
288- if (code == FERROR) {
289+ if (code == FERROR || am_server)
290 f = stderr;
291- }
292-
293- if (code == FINFO) {
294- if (am_server)
295- f = stderr;
296- else
297- f = stdout;
298- }
299+ else
300+ f = stdout;
301
302- if (!f) exit_cleanup(RERR_MESSAGEIO);
303 fflush(f);
304 }
305
6596b2bd 306@@ -695,12 +687,12 @@ void log_item(struct file_struct *file,
9d32714e
WD
307 {
308 char *s_or_r = am_sender ? "send" : "recv";
309
310- if (lp_transfer_logging(module_id)) {
311- log_formatted(FLOG, lp_log_format(module_id), s_or_r,
312- file, initial_stats, iflags, hlink);
313- } else if (log_format && !am_server) {
314+ if (log_format && !am_server) {
315 log_formatted(FNAME, log_format, s_or_r,
316 file, initial_stats, iflags, hlink);
317+ } else if (logfile_format) {
318+ log_formatted(FLOG, logfile_format, s_or_r,
319+ file, initial_stats, iflags, hlink);
320 }
321 }
322
6596b2bd 323@@ -712,7 +704,7 @@ void maybe_log_item(struct file_struct *
9d32714e
WD
324 || log_format_has_i > 1 || (verbose > 1 && log_format_has_i));
325 int local_change = iflags & ITEM_LOCAL_CHANGE && significant_flags;
326 if (am_server) {
327- if (am_daemon && !dry_run && see_item)
328+ if (logfile_name && !dry_run && see_item)
329 log_item(file, &stats, iflags, buf);
330 } else if (see_item || local_change || *buf
331 || (S_ISDIR(file->mode) && significant_flags))
6596b2bd 332@@ -740,10 +732,10 @@ void log_delete(char *fname, int mode)
9d32714e
WD
333 ITEM_DELETED, NULL);
334 }
335
336- if (!am_daemon || dry_run || !lp_transfer_logging(module_id))
337+ if (!logfile_name || dry_run || !logfile_format)
338 return;
339
340- fmt = daemon_log_format_has_o_or_i ? lp_log_format(module_id) : "deleting %n";
341+ fmt = logfile_format_has_o_or_i ? logfile_format : "deleting %n";
342 log_formatted(FLOG, fmt, "del.", &file, &stats, ITEM_DELETED, NULL);
343 }
344
345--- old/main.c
346+++ new/main.c
347@@ -168,7 +168,6 @@ static void handle_stats(int f)
348 return;
349
350 if (am_daemon) {
351- log_exit(0, __FILE__, __LINE__);
352 if (f == -1 || !am_sender)
353 return;
354 }
355--- old/options.c
356+++ new/options.c
a56690e2 357@@ -146,6 +146,8 @@ char *basis_dir[MAX_BASIS_DIRS+1];
9d32714e
WD
358 char *config_file = NULL;
359 char *shell_cmd = NULL;
360 char *log_format = NULL;
361+char *logfile_name = NULL;
362+char *logfile_format = NULL;
363 char *password_file = NULL;
364 char *rsync_path = RSYNC_PATH;
365 char *backup_dir = NULL;
a56690e2 366@@ -162,7 +164,9 @@ int verbose = 0;
9d32714e
WD
367 int quiet = 0;
368 int log_before_transfer = 0;
369 int log_format_has_i = 0;
370+int logfile_format_has_i = 0;
371 int log_format_has_o_or_i = 0;
372+int logfile_format_has_o_or_i = 0;
373 int always_checksum = 0;
374 int list_only = 0;
375
a56690e2 376@@ -359,6 +363,7 @@ void usage(enum logcode F)
9d32714e
WD
377 rprintf(F," --progress show progress during transfer\n");
378 rprintf(F," -P same as --partial --progress\n");
379 rprintf(F," -i, --itemize-changes output a change-summary for all updates\n");
380+ rprintf(F," --log-file=FILE output what we're doing to a log file\n");
381 rprintf(F," --log-format=FORMAT output filenames using the specified format\n");
382 rprintf(F," --password-file=FILE read password from FILE\n");
383 rprintf(F," --list-only list the files instead of copying them\n");
a56690e2 384@@ -492,6 +497,7 @@ static struct poptOption long_options[]
9d32714e
WD
385 {"partial-dir", 0, POPT_ARG_STRING, &partial_dir, 0, 0, 0 },
386 {"delay-updates", 0, POPT_ARG_NONE, &delay_updates, 0, 0, 0 },
387 {"prune-empty-dirs",'m', POPT_ARG_NONE, &prune_empty_dirs, 0, 0, 0 },
388+ {"log-file", 0, POPT_ARG_STRING, &logfile_name, 0, 0, 0 },
389 {"log-format", 0, POPT_ARG_STRING, &log_format, 0, 0, 0 },
390 {"itemize-changes", 'i', POPT_ARG_NONE, 0, 'i', 0, 0 },
391 {"bwlimit", 0, POPT_ARG_INT, &bwlimit, 0, 0, 0 },
a56690e2 392@@ -1311,6 +1317,21 @@ int parse_arguments(int *argc, const cha
9d32714e
WD
393 if (log_format_has_i || log_format_has(log_format, 'o'))
394 log_format_has_o_or_i = 1;
395
396+ if (am_daemon)
397+ logfile_name = NULL;
398+ else if (logfile_name) {
399+ if (am_server) {
400+ logfile_format = "%i %n%L";
401+ logfile_format_has_i = logfile_format_has_o_or_i = 1;
402+ } else if (log_format) {
403+ logfile_format = log_format;
404+ logfile_format_has_i = log_format_has_i;
405+ logfile_format_has_o_or_i = log_format_has_o_or_i;
406+ }
407+ log_before_transfer = !am_server;
408+ log_init();
409+ }
410+
411 if (daemon_bwlimit && (!bwlimit || bwlimit > daemon_bwlimit))
412 bwlimit = daemon_bwlimit;
413 if (bwlimit) {
414--- old/progress.c
415+++ new/progress.c
416@@ -103,7 +103,7 @@ static void rprint_progress(OFF_T ofs, O
417 stats.num_files);
418 } else
419 strcpy(eol, "\r");
420- rprintf(FINFO, "%12s %3d%% %7.2f%s %4d:%02d:%02d%s",
421+ rprintf(FCLIENT, "%12s %3d%% %7.2f%s %4d:%02d:%02d%s",
422 human_num(ofs), pct, rate, units,
423 remain_h, remain_m, remain_s, eol);
424 }
425--- old/receiver.c
426+++ new/receiver.c
427@@ -27,7 +27,7 @@ extern int am_server;
428 extern int do_progress;
429 extern int log_before_transfer;
430 extern int log_format_has_i;
431-extern int daemon_log_format_has_i;
432+extern int logfile_format_has_i;
433 extern int csum_length;
434 extern int read_batch;
435 extern int write_batch;
436@@ -341,8 +341,7 @@ int recv_files(int f_in, struct file_lis
437 struct file_struct *file;
438 struct stats initial_stats;
439 int save_make_backups = make_backups;
440- int itemizing = am_daemon ? daemon_log_format_has_i
441- : !am_server && log_format_has_i;
442+ int itemizing = am_server ? logfile_format_has_i : log_format_has_i;
443 int max_phase = protocol_version >= 29 ? 2 : 1;
444 int i, recv_ok;
445
446--- old/rsync.c
447+++ new/rsync.c
448@@ -32,7 +32,7 @@
449
450 extern int verbose;
451 extern int dry_run;
452-extern int daemon_log_format_has_i;
453+extern int logfile_format_has_i;
454 extern int preserve_perms;
455 extern int preserve_executability;
456 extern int preserve_times;
457@@ -218,7 +218,7 @@ int set_file_attrs(char *fname, struct f
458 #endif
459
460 if (verbose > 1 && flags & ATTRS_REPORT) {
461- enum logcode code = daemon_log_format_has_i || dry_run
462+ enum logcode code = logfile_format_has_i || dry_run
463 ? FCLIENT : FINFO;
464 if (updated)
465 rprintf(code, "%s\n", fname);
466--- old/rsync.h
467+++ new/rsync.h
a56690e2 468@@ -158,8 +158,8 @@
9d32714e
WD
469
470
471 /* Log-message categories. Only FERROR and FINFO get sent over the socket.
472- * FLOG and FCLIENT are only used on the daemon side for custom logging,
473- * while FNAME is only used on the client side. */
474+ * FLOG only goes to the log file, not to the client; FCLIENT is the opposite.
475+ * FNAME is a client-side message when outputting a filename on its own. */
476 enum logcode { FERROR=1, FINFO=2, FLOG=3, FCLIENT=4, FNAME=5, FSOCKERR=6 };
477
478 /* Messages types that are sent over the message channel. The logcode
479--- old/rsync.yo
480+++ new/rsync.yo
481@@ -387,6 +387,7 @@ to the detailed description below for a
482 --progress show progress during transfer
483 -P same as --partial --progress
484 -i, --itemize-changes output a change-summary for all updates
485+ --log-file=FILE output what we're doing to a log file
486 --log-format=FORMAT output filenames using the specified format
487 --password-file=FILE read password from FILE
488 --list-only list the files instead of copying them
489@@ -1423,6 +1424,23 @@ the string "*deleting" for each item tha
490 you are talking to a recent enough rsync that it logs deletions instead of
491 outputting them as a verbose message).
492
493+dit(bf(--log-file=FILE)) This option causes rsync to log what it is doing
494+to a file. This is similar to the logging that a daemon does, but can be
495+requested for the client side and/or the server side of a non-daemon
496+transfer. If specified as a client option, transfer logging will in effect
497+if the bf(--log-format) option was either specified or implied (e.g.
498+bf(--verbose) implies a basic log format). If explicitly sent to a server
499+via the bf(--rsync-path) option, transfer logging will always occur using
500+the default bf(--itemize-changes) format.
501+
502+Here's a example command that requests the remote side to log what is
503+happening:
504+
505+verb( rsync -av --rsync-path="path --log-file=/tmp/rlog" src/ dest/)
506+
507+This is very useful if you need to debug why a connection is closing
508+unexpectedly.
509+
510 dit(bf(--log-format=FORMAT)) This allows you to specify exactly what the
511 rsync client outputs to the user on a per-file basis. The format is a text
512 string containing embedded single-character escape sequences prefixed with
513--- old/sender.c
514+++ new/sender.c
515@@ -25,7 +25,7 @@ extern int am_server;
516 extern int am_daemon;
517 extern int log_before_transfer;
518 extern int log_format_has_i;
519-extern int daemon_log_format_has_i;
520+extern int logfile_format_has_i;
521 extern int csum_length;
522 extern int append_mode;
523 extern int io_error;
524@@ -215,8 +215,7 @@ void send_files(struct file_list *flist,
525 int phase = 0, max_phase = protocol_version >= 29 ? 2 : 1;
526 struct stats initial_stats;
527 int save_make_backups = make_backups;
528- int itemizing = am_daemon ? daemon_log_format_has_i
529- : !am_server && log_format_has_i;
530+ int itemizing = am_server ? logfile_format_has_i : log_format_has_i;
531 int f_xfer = write_batch < 0 ? batch_fd : f_out;
532 int i, j;
533