blob: f63de7f5b770df9adb098a6b8716a2b2205c194e [file] [log] [blame]
Martin Poola0397492000-10-26 07:24:18 +00001/* -*- c-file-style: "linux"; -*-
Wayne Davison4a7319b2003-12-15 01:45:01 +00002
Martin Pool0c5a7922001-03-19 08:19:11 +00003 Copyright (C) 1998-2001 by Andrew Tridgell <tridge@samba.org>
Martin Pool18c71e92001-02-23 01:45:46 +00004 Copyright (C) 2000-2001 by Martin Pool <mbp@samba.org>
Wayne Davison4a7319b2003-12-15 01:45:01 +00005
Andrew Tridgell0b76cd61998-05-09 14:00:55 +00006 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
Wayne Davison4a7319b2003-12-15 01:45:01 +000010
Andrew Tridgell0b76cd61998-05-09 14:00:55 +000011 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
Wayne Davison4a7319b2003-12-15 01:45:01 +000015
Andrew Tridgell0b76cd61998-05-09 14:00:55 +000016 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19*/
20
21/*
Martin Pool3e3dcd62001-02-21 07:18:50 +000022 Logging and utility functions.
Martin Pool0c5a7922001-03-19 08:19:11 +000023 tridge, May 1998
Andrew Tridgell0b76cd61998-05-09 14:00:55 +000024
Martin Pool3e3dcd62001-02-21 07:18:50 +000025 Mapping to human-readable messages added by Martin Pool
26 <mbp@samba.org>, Oct 2000.
Andrew Tridgell0b76cd61998-05-09 14:00:55 +000027 */
28#include "rsync.h"
29
Wayne Davison548abf92004-01-13 04:50:45 +000030extern int am_daemon;
31extern int am_server;
32extern int am_sender;
33extern int quiet;
34extern int module_id;
Wayne Davisona644fc32004-01-15 07:42:19 +000035extern int msg_fd_out;
Wayne Davison548abf92004-01-13 04:50:45 +000036extern char *auth_user;
37extern char *log_format;
38
David Dykstra30e8c8e2002-08-30 23:27:26 +000039static int log_initialised;
David Dykstra45a83542000-10-24 18:50:08 +000040static char *logfname;
Andrew Tridgell4f6325c1998-09-09 05:51:42 +000041static FILE *logfile;
Martin Poolb35d0d82002-04-08 04:10:20 +000042struct stats stats;
Andrew Tridgelle0414f41998-09-09 06:06:08 +000043
Wayne Davison8fcdc442004-05-15 19:31:16 +000044int log_got_error = 0;
Martin Poolaf642a62000-11-10 03:28:15 +000045
46struct {
47 int code;
48 char const *name;
49} const rerr_names[] = {
Wayne Davison4a7319b2003-12-15 01:45:01 +000050 { RERR_SYNTAX , "syntax or usage error" },
51 { RERR_PROTOCOL , "protocol incompatibility" },
52 { RERR_FILESELECT , "errors selecting input/output files, dirs" },
53 { RERR_UNSUPPORTED, "requested action not supported" },
54 { RERR_STARTCLIENT, "error starting client-server protocol" },
55 { RERR_SOCKETIO , "error in socket IO" },
56 { RERR_FILEIO , "error in file IO" },
57 { RERR_STREAMIO , "error in rsync protocol data stream" },
58 { RERR_MESSAGEIO , "errors with program diagnostics" },
59 { RERR_IPC , "error in IPC code" },
60 { RERR_SIGNAL , "received SIGUSR1 or SIGINT" },
61 { RERR_WAITCHILD , "some error returned by waitpid()" },
62 { RERR_MALLOC , "error allocating core memory buffers" },
63 { RERR_PARTIAL , "some files could not be transferred" },
Wayne Davison584ba4e2004-09-05 21:30:00 +000064 { RERR_VANISHED , "some files vanished before they could be transferred" },
Wayne Davison4a7319b2003-12-15 01:45:01 +000065 { RERR_TIMEOUT , "timeout in data send/receive" },
Andrew Tridgell19b27a42001-03-23 01:26:04 +000066 { RERR_CMD_FAILED , "remote shell failed" },
67 { RERR_CMD_KILLED , "remote shell killed" },
68 { RERR_CMD_RUN, "remote command could not be run" },
Wayne Davison4a7319b2003-12-15 01:45:01 +000069 { RERR_CMD_NOTFOUND, "remote command not found" },
70 { 0, NULL }
Martin Poolaf642a62000-11-10 03:28:15 +000071};
72
73
74
75/*
76 * Map from rsync error code to name, or return NULL.
77 */
78static char const *rerr_name(int code)
79{
Wayne Davison4a7319b2003-12-15 01:45:01 +000080 int i;
81 for (i = 0; rerr_names[i].name; i++) {
82 if (rerr_names[i].code == code)
83 return rerr_names[i].name;
84 }
85 return NULL;
Martin Poolaf642a62000-11-10 03:28:15 +000086}
87
88
Andrew Tridgell4f6325c1998-09-09 05:51:42 +000089static void logit(int priority, char *buf)
90{
David Dykstra45a83542000-10-24 18:50:08 +000091 if (logfname) {
David Dykstra15b84e12000-10-25 19:57:42 +000092 if (!logfile)
93 log_open();
Wayne Davison4a7319b2003-12-15 01:45:01 +000094 fprintf(logfile,"%s [%d] %s",
Andrew Tridgellf7632fc1998-11-02 00:52:01 +000095 timestring(time(NULL)), (int)getpid(), buf);
Andrew Tridgell4f6325c1998-09-09 05:51:42 +000096 fflush(logfile);
97 } else {
98 syslog(priority, "%s", buf);
99 }
100}
Andrew Tridgelle42c9451998-05-15 09:26:01 +0000101
David Dykstra45a83542000-10-24 18:50:08 +0000102void log_init(void)
Andrew Tridgell1a016bf1998-05-15 10:34:07 +0000103{
Andrew Tridgell1a016bf1998-05-15 10:34:07 +0000104 int options = LOG_PID;
Andrew Tridgellbcf5b131998-07-02 10:57:20 +0000105 time_t t;
Andrew Tridgell1a016bf1998-05-15 10:34:07 +0000106
Wayne Davison0bb4d172004-06-07 22:51:14 +0000107 if (log_initialised)
108 return;
David Dykstra30e8c8e2002-08-30 23:27:26 +0000109 log_initialised = 1;
Andrew Tridgell1a016bf1998-05-15 10:34:07 +0000110
Andrew Tridgell958f3731998-10-30 11:18:38 +0000111 /* this looks pointless, but it is needed in order for the
Wayne Davison4a7319b2003-12-15 01:45:01 +0000112 * C library on some systems to fetch the timezone info
113 * before the chroot */
Andrew Tridgell958f3731998-10-30 11:18:38 +0000114 t = time(NULL);
115 localtime(&t);
116
117 /* optionally use a log file instead of syslog */
David Dykstra45a83542000-10-24 18:50:08 +0000118 logfname = lp_log_file();
119 if (logfname) {
David Dykstra15b84e12000-10-25 19:57:42 +0000120 if (*logfname) {
121 log_open();
David Dykstra45a83542000-10-24 18:50:08 +0000122 return;
David Dykstra15b84e12000-10-25 19:57:42 +0000123 }
David Dykstra45a83542000-10-24 18:50:08 +0000124 logfname = NULL;
Andrew Tridgell4f6325c1998-09-09 05:51:42 +0000125 }
126
Andrew Tridgell1a016bf1998-05-15 10:34:07 +0000127#ifdef LOG_NDELAY
128 options |= LOG_NDELAY;
129#endif
130
131#ifdef LOG_DAEMON
132 openlog("rsyncd", options, lp_syslog_facility());
133#else
134 openlog("rsyncd", options);
135#endif
136
137#ifndef LOG_NDELAY
Andrew Tridgell4f6325c1998-09-09 05:51:42 +0000138 logit(LOG_INFO,"rsyncd started\n");
Andrew Tridgell1a016bf1998-05-15 10:34:07 +0000139#endif
140}
Andrew Tridgell1a016bf1998-05-15 10:34:07 +0000141
Jos Backus1e34e4b2002-12-24 07:42:04 +0000142void log_open(void)
David Dykstra15b84e12000-10-25 19:57:42 +0000143{
144 if (logfname && !logfile) {
145 extern int orig_umask;
146 int old_umask = umask(022 | orig_umask);
147 logfile = fopen(logfname, "a");
148 umask(old_umask);
149 }
150}
151
Jos Backus1e34e4b2002-12-24 07:42:04 +0000152void log_close(void)
David Dykstra45a83542000-10-24 18:50:08 +0000153{
154 if (logfile) {
155 fclose(logfile);
156 logfile = NULL;
157 }
158}
159
Andrew Tridgell554e0a82000-01-23 07:36:56 +0000160/* this is the underlying (unformatted) rsync debugging function. Call
Wayne Davison4a7319b2003-12-15 01:45:01 +0000161 * it with FINFO, FERROR or FLOG */
Andrew Tridgellff41a592000-01-28 15:29:59 +0000162void rwrite(enum logcode code, char *buf, int len)
Andrew Tridgell554e0a82000-01-23 07:36:56 +0000163{
Wayne Davison8fcdc442004-05-15 19:31:16 +0000164 FILE *f = NULL;
Andrew Tridgell8d9dc9f1998-05-18 08:20:26 +0000165 /* recursion can happen with certain fatal conditions */
Andrew Tridgell8d9dc9f1998-05-18 08:20:26 +0000166
Wayne Davisona644fc32004-01-15 07:42:19 +0000167 if (quiet && code == FINFO)
168 return;
David Dykstrab86f0ce1999-02-09 17:25:35 +0000169
Wayne Davisona644fc32004-01-15 07:42:19 +0000170 if (len < 0)
171 exit_cleanup(RERR_MESSAGEIO);
Andrew Tridgell0b76cd61998-05-09 14:00:55 +0000172
Andrew Tridgellff8b29b1998-05-10 08:24:38 +0000173 buf[len] = 0;
Andrew Tridgell0b76cd61998-05-09 14:00:55 +0000174
Wayne Davison0bb4d172004-06-07 22:51:14 +0000175 if (am_server && msg_fd_out >= 0) {
176 /* Pass the message to our sibling. */
177 send_msg((enum msgcode)code, buf, len);
Andrew Tridgell11a5a3c1998-10-28 03:28:30 +0000178 return;
179 }
180
Wayne Davison0bb4d172004-06-07 22:51:14 +0000181 if (am_daemon) {
182 static int in_block;
183 char msg[2048];
184 int priority = code == FERROR ? LOG_WARNING : LOG_INFO;
185
186 if (in_block)
187 return;
188 in_block = 1;
189 if (!log_initialised)
190 log_init();
191 strlcpy(msg, buf, MIN((int)sizeof msg, len + 1));
192 logit(priority, msg);
193 in_block = 0;
194
195 if (code == FLOG || !am_server)
196 return;
197 } else if (code == FLOG)
198 return;
199
Wayne Davisona644fc32004-01-15 07:42:19 +0000200 if (am_server) {
Wayne Davison0bb4d172004-06-07 22:51:14 +0000201 /* Pass the message to the non-server side. */
202 if (io_multiplex_write((enum msgcode)code, buf, len))
203 return;
204 if (am_daemon) {
205 /* TODO: can we send the error to the user somehow? */
Wayne Davisona644fc32004-01-15 07:42:19 +0000206 return;
207 }
Andrew Tridgell0b76cd61998-05-09 14:00:55 +0000208 }
209
Andrew Tridgellff41a592000-01-28 15:29:59 +0000210 if (code == FERROR) {
Andrew Tridgellff81e802001-03-22 07:36:51 +0000211 log_got_error = 1;
Andrew Tridgellff8b29b1998-05-10 08:24:38 +0000212 f = stderr;
Wayne Davison4a7319b2003-12-15 01:45:01 +0000213 }
Andrew Tridgellff8b29b1998-05-10 08:24:38 +0000214
Wayne Davison0bb4d172004-06-07 22:51:14 +0000215 if (code == FINFO)
216 f = am_server ? stderr : stdout;
Andrew Tridgellff8b29b1998-05-10 08:24:38 +0000217
Wayne Davison0bb4d172004-06-07 22:51:14 +0000218 if (!f)
219 exit_cleanup(RERR_MESSAGEIO);
Andrew Tridgell0b76cd61998-05-09 14:00:55 +0000220
Wayne Davison0bb4d172004-06-07 22:51:14 +0000221 if (fwrite(buf, len, 1, f) != 1)
222 exit_cleanup(RERR_MESSAGEIO);
Andrew Tridgell8d9dc9f1998-05-18 08:20:26 +0000223
Wayne Davison0bb4d172004-06-07 22:51:14 +0000224 if (buf[len-1] == '\r' || buf[len-1] == '\n')
225 fflush(f);
Andrew Tridgell0b76cd61998-05-09 14:00:55 +0000226}
Andrew Tridgell554e0a82000-01-23 07:36:56 +0000227
228
Martin Poola0397492000-10-26 07:24:18 +0000229/* This is the rsync debugging function. Call it with FINFO, FERROR or
230 * FLOG. */
231void rprintf(enum logcode code, const char *format, ...)
Andrew Tridgell554e0a82000-01-23 07:36:56 +0000232{
Wayne Davison4a7319b2003-12-15 01:45:01 +0000233 va_list ap;
Wayne Davison8fcdc442004-05-15 19:31:16 +0000234 char buf[MAXPATHLEN+512];
235 size_t len;
Andrew Tridgell554e0a82000-01-23 07:36:56 +0000236
237 va_start(ap, format);
Andrew Tridgell8950ac02001-05-07 06:59:37 +0000238 len = vsnprintf(buf, sizeof(buf), format, ap);
Andrew Tridgell554e0a82000-01-23 07:36:56 +0000239 va_end(ap);
240
Martin Poolb2f02462001-09-04 03:12:55 +0000241 /* Deal with buffer overruns. Instead of panicking, just
Wayne Davison8fcdc442004-05-15 19:31:16 +0000242 * truncate the resulting string. (Note that configure ensures
243 * that we have a vsnprintf() that doesn't ever return -1.) */
244 if (len > sizeof buf - 1) {
Martin Poolb2f02462001-09-04 03:12:55 +0000245 const char ellipsis[] = "[...]";
246
247 /* Reset length, and zero-terminate the end of our buffer */
248 len = sizeof(buf)-1;
249 buf[len] = '\0';
250
251 /* Copy the ellipsis to the end of the string, but give
252 * us one extra character:
253 *
254 * v--- null byte at buf[sizeof(buf)-1]
255 * abcdefghij0
256 * -> abcd[...]00 <-- now two null bytes at end
257 *
258 * If the input format string has a trailing newline,
259 * we copy it into that extra null; if it doesn't, well,
260 * all we lose is one byte. */
261 strncpy(buf+len-sizeof(ellipsis), ellipsis, sizeof(ellipsis));
262 if (format[strlen(format)-1] == '\n') {
263 buf[len-1] = '\n';
264 }
265 }
Andrew Tridgell554e0a82000-01-23 07:36:56 +0000266
Andrew Tridgellff41a592000-01-28 15:29:59 +0000267 rwrite(code, buf, len);
Andrew Tridgell554e0a82000-01-23 07:36:56 +0000268}
Andrew Tridgell0b76cd61998-05-09 14:00:55 +0000269
Martin Poola0397492000-10-26 07:24:18 +0000270
271/* This is like rprintf, but it also tries to print some
272 * representation of the error code. Normally errcode = errno.
273 *
274 * Unlike rprintf, this always adds a newline and there should not be
275 * one in the format string.
276 *
277 * Note that since strerror might involve dynamically loading a
278 * message catalog we need to call it once before chroot-ing. */
279void rsyserr(enum logcode code, int errcode, const char *format, ...)
280{
Wayne Davison4a7319b2003-12-15 01:45:01 +0000281 va_list ap;
Wayne Davison8fcdc442004-05-15 19:31:16 +0000282 char buf[MAXPATHLEN+512];
283 size_t len;
284
285 strcpy(buf, RSYNC_NAME ": ");
286 len = (sizeof RSYNC_NAME ": ") - 1;
Martin Poola0397492000-10-26 07:24:18 +0000287
288 va_start(ap, format);
Wayne Davison8fcdc442004-05-15 19:31:16 +0000289 len += vsnprintf(buf + len, sizeof buf - len, format, ap);
Martin Poola0397492000-10-26 07:24:18 +0000290 va_end(ap);
291
Wayne Davison8fcdc442004-05-15 19:31:16 +0000292 if (len < sizeof buf) {
293 len += snprintf(buf + len, sizeof buf - len,
294 ": %s (%d)\n", strerror(errcode), errcode);
295 }
296 if (len >= sizeof buf)
Martin Pool59ee7432002-01-23 08:04:54 +0000297 exit_cleanup(RERR_MESSAGEIO);
Martin Poola0397492000-10-26 07:24:18 +0000298
Martin Poola0397492000-10-26 07:24:18 +0000299 rwrite(code, buf, len);
300}
301
302
303
Andrew Tridgellff41a592000-01-28 15:29:59 +0000304void rflush(enum logcode code)
Andrew Tridgell0b76cd61998-05-09 14:00:55 +0000305{
306 FILE *f = NULL;
Andrew Tridgell0b76cd61998-05-09 14:00:55 +0000307
308 if (am_daemon) {
309 return;
310 }
311
Andrew Tridgellff41a592000-01-28 15:29:59 +0000312 if (code == FLOG) {
Andrew Tridgelle08bfe11998-10-30 02:24:47 +0000313 return;
Wayne Davison4a7319b2003-12-15 01:45:01 +0000314 }
Andrew Tridgelle08bfe11998-10-30 02:24:47 +0000315
Andrew Tridgellff41a592000-01-28 15:29:59 +0000316 if (code == FERROR) {
Andrew Tridgell0b76cd61998-05-09 14:00:55 +0000317 f = stderr;
Wayne Davison4a7319b2003-12-15 01:45:01 +0000318 }
Andrew Tridgell0b76cd61998-05-09 14:00:55 +0000319
Andrew Tridgellff41a592000-01-28 15:29:59 +0000320 if (code == FINFO) {
Wayne Davison4a7319b2003-12-15 01:45:01 +0000321 if (am_server)
Andrew Tridgell0b76cd61998-05-09 14:00:55 +0000322 f = stderr;
323 else
324 f = stdout;
Wayne Davison4a7319b2003-12-15 01:45:01 +0000325 }
Andrew Tridgell0b76cd61998-05-09 14:00:55 +0000326
Andrew Tridgell65417571998-11-03 07:08:27 +0000327 if (!f) exit_cleanup(RERR_MESSAGEIO);
Andrew Tridgell0b76cd61998-05-09 14:00:55 +0000328 fflush(f);
329}
330
Andrew Tridgell11a5a3c1998-10-28 03:28:30 +0000331
Andrew Tridgelle08bfe11998-10-30 02:24:47 +0000332
333/* a generic logging routine for send/recv, with parameter
Wayne Davison4a7319b2003-12-15 01:45:01 +0000334 * substitiution */
Andrew Tridgell0f3203c2000-01-29 02:49:03 +0000335static void log_formatted(enum logcode code,
Andrew Tridgellb6062651998-11-03 03:48:47 +0000336 char *format, char *op, struct file_struct *file,
Andrew Tridgell1b7c47c1998-11-02 04:17:56 +0000337 struct stats *initial_stats)
Andrew Tridgelle08bfe11998-10-30 02:24:47 +0000338{
Andrew Tridgelle08bfe11998-10-30 02:24:47 +0000339 char buf[1024];
Andrew Tridgellab7104d1998-11-02 06:40:11 +0000340 char buf2[1024];
Andrew Tridgelle08bfe11998-10-30 02:24:47 +0000341 char *p, *s, *n;
Martin Pool59ee7432002-01-23 08:04:54 +0000342 size_t l;
Andrew Tridgell1b7c47c1998-11-02 04:17:56 +0000343 int64 b;
Andrew Tridgelle08bfe11998-10-30 02:24:47 +0000344
Martin Poolaa126972002-01-24 02:41:38 +0000345 /* We expand % codes one by one in place in buf. We don't
346 * copy in the terminating nul of the inserted strings, but
347 * rather keep going until we reach the nul of the format.
348 * Just to make sure we don't clobber that nul and therefore
349 * accidentally keep going, we zero the buffer now. */
Wayne Davison8fcdc442004-05-15 19:31:16 +0000350 l = strlcpy(buf, format, sizeof buf);
351 if (l < sizeof buf)
352 memset(buf + l, 0, sizeof buf - l);
Andrew Tridgelle08bfe11998-10-30 02:24:47 +0000353
Wayne Davison4a7319b2003-12-15 01:45:01 +0000354 for (s = &buf[0]; s && (p = strchr(s,'%')); ) {
Andrew Tridgelle08bfe11998-10-30 02:24:47 +0000355 n = NULL;
356 s = p + 1;
357
358 switch (p[1]) {
Andrew Tridgellaf77cc61998-11-16 23:50:28 +0000359 case 'h': if (am_daemon) n = client_name(0); break;
360 case 'a': if (am_daemon) n = client_addr(0); break;
Wayne Davison4a7319b2003-12-15 01:45:01 +0000361 case 'l':
362 snprintf(buf2,sizeof(buf2),"%.0f",
363 (double)file->length);
Andrew Tridgelle08bfe11998-10-30 02:24:47 +0000364 n = buf2;
365 break;
Wayne Davison4a7319b2003-12-15 01:45:01 +0000366 case 'p':
367 snprintf(buf2,sizeof(buf2),"%d",
368 (int)getpid());
Andrew Tridgelle08bfe11998-10-30 02:24:47 +0000369 n = buf2;
370 break;
371 case 'o': n = op; break;
Wayne Davison4a7319b2003-12-15 01:45:01 +0000372 case 'f':
Wayne Davison81d2b0e2004-01-20 05:15:14 +0000373 pathjoin(buf2, sizeof buf2,
374 file->basedir ? file->basedir : "",
Andrew Tridgellab7104d1998-11-02 06:40:11 +0000375 f_name(file));
Wayne Davison58b19992004-08-12 18:20:07 +0000376 clean_fname(buf2, 0);
Wayne Davison4a7319b2003-12-15 01:45:01 +0000377 n = buf2;
Andrew Tridgellb6062651998-11-03 03:48:47 +0000378 if (*n == '/') n++;
Andrew Tridgellab7104d1998-11-02 06:40:11 +0000379 break;
Andrew Tridgell97cb8dc1998-10-30 05:53:05 +0000380 case 'm': n = lp_name(module_id); break;
Andrew Tridgellb6062651998-11-03 03:48:47 +0000381 case 't': n = timestring(time(NULL)); break;
Andrew Tridgell97cb8dc1998-10-30 05:53:05 +0000382 case 'P': n = lp_path(module_id); break;
383 case 'u': n = auth_user; break;
Wayne Davison4a7319b2003-12-15 01:45:01 +0000384 case 'b':
Andrew Tridgell1b7c47c1998-11-02 04:17:56 +0000385 if (am_sender) {
Wayne Davison4a7319b2003-12-15 01:45:01 +0000386 b = stats.total_written -
Andrew Tridgell1b7c47c1998-11-02 04:17:56 +0000387 initial_stats->total_written;
388 } else {
Wayne Davison4a7319b2003-12-15 01:45:01 +0000389 b = stats.total_read -
Andrew Tridgell1b7c47c1998-11-02 04:17:56 +0000390 initial_stats->total_read;
391 }
Wayne Davison4a7319b2003-12-15 01:45:01 +0000392 snprintf(buf2,sizeof(buf2),"%.0f", (double)b);
Andrew Tridgell1b7c47c1998-11-02 04:17:56 +0000393 n = buf2;
394 break;
Wayne Davison4a7319b2003-12-15 01:45:01 +0000395 case 'c':
Andrew Tridgell1b7c47c1998-11-02 04:17:56 +0000396 if (!am_sender) {
Wayne Davison4a7319b2003-12-15 01:45:01 +0000397 b = stats.total_written -
Andrew Tridgell1b7c47c1998-11-02 04:17:56 +0000398 initial_stats->total_written;
399 } else {
Wayne Davison4a7319b2003-12-15 01:45:01 +0000400 b = stats.total_read -
Andrew Tridgell1b7c47c1998-11-02 04:17:56 +0000401 initial_stats->total_read;
402 }
Wayne Davison4a7319b2003-12-15 01:45:01 +0000403 snprintf(buf2,sizeof(buf2),"%.0f", (double)b);
Andrew Tridgell1b7c47c1998-11-02 04:17:56 +0000404 n = buf2;
405 break;
Andrew Tridgelle08bfe11998-10-30 02:24:47 +0000406 }
407
Martin Poolaa126972002-01-24 02:41:38 +0000408 /* n is the string to be inserted in place of this %
409 * code; l is its length not including the trailing
410 * NUL */
411 if (!n)
412 continue;
Andrew Tridgelle08bfe11998-10-30 02:24:47 +0000413
414 l = strlen(n);
415
Martin Pool9dd891b2002-01-23 04:57:18 +0000416 if (l + ((int)(s - &buf[0])) >= sizeof(buf)) {
Andrew Tridgelle08bfe11998-10-30 02:24:47 +0000417 rprintf(FERROR,"buffer overflow expanding %%%c - exiting\n",
418 p[0]);
Andrew Tridgell65417571998-11-03 07:08:27 +0000419 exit_cleanup(RERR_MESSAGEIO);
Andrew Tridgelle08bfe11998-10-30 02:24:47 +0000420 }
421
Martin Poolaa126972002-01-24 02:41:38 +0000422 /* Shuffle the rest of the string along to make space for n */
Andrew Tridgelle08bfe11998-10-30 02:24:47 +0000423 if (l != 2) {
Andrew Tridgell34720091998-10-30 02:36:05 +0000424 memmove(s+(l-1), s+1, strlen(s+1)+1);
Andrew Tridgelle08bfe11998-10-30 02:24:47 +0000425 }
Martin Poolaa126972002-01-24 02:41:38 +0000426
427 /* Copy in n but NOT its nul, because the format sting
428 * probably continues after this. */
Andrew Tridgelle08bfe11998-10-30 02:24:47 +0000429 memcpy(p, n, l);
430
Martin Poolaa126972002-01-24 02:41:38 +0000431 /* Skip over inserted string; continue looking */
Andrew Tridgelle08bfe11998-10-30 02:24:47 +0000432 s = p+l;
433 }
434
Andrew Tridgell0f3203c2000-01-29 02:49:03 +0000435 rprintf(code,"%s\n", buf);
Andrew Tridgelle08bfe11998-10-30 02:24:47 +0000436}
437
Andrew Tridgell11a5a3c1998-10-28 03:28:30 +0000438/* log the outgoing transfer of a file */
Andrew Tridgell1b7c47c1998-11-02 04:17:56 +0000439void log_send(struct file_struct *file, struct stats *initial_stats)
Andrew Tridgell11a5a3c1998-10-28 03:28:30 +0000440{
Andrew Tridgell11a5a3c1998-10-28 03:28:30 +0000441 if (lp_transfer_logging(module_id)) {
Andrew Tridgellb6062651998-11-03 03:48:47 +0000442 log_formatted(FLOG, lp_log_format(module_id), "send", file, initial_stats);
443 } else if (log_format && !am_server) {
444 log_formatted(FINFO, log_format, "send", file, initial_stats);
Andrew Tridgell11a5a3c1998-10-28 03:28:30 +0000445 }
446}
447
448/* log the incoming transfer of a file */
Andrew Tridgell1b7c47c1998-11-02 04:17:56 +0000449void log_recv(struct file_struct *file, struct stats *initial_stats)
Andrew Tridgell11a5a3c1998-10-28 03:28:30 +0000450{
Andrew Tridgell11a5a3c1998-10-28 03:28:30 +0000451 if (lp_transfer_logging(module_id)) {
David Dykstra117af101999-01-05 20:08:45 +0000452 log_formatted(FLOG, lp_log_format(module_id), "recv", file, initial_stats);
Andrew Tridgellb6062651998-11-03 03:48:47 +0000453 } else if (log_format && !am_server) {
David Dykstra117af101999-01-05 20:08:45 +0000454 log_formatted(FINFO, log_format, "recv", file, initial_stats);
Andrew Tridgell11a5a3c1998-10-28 03:28:30 +0000455 }
456}
457
Martin Poolaf642a62000-11-10 03:28:15 +0000458
459
460
461/*
462 * Called when the transfer is interrupted for some reason.
463 *
464 * Code is one of the RERR_* codes from errcode.h, or terminating
465 * successfully.
466 */
Andrew Tridgella9766ef1998-11-15 01:21:42 +0000467void log_exit(int code, const char *file, int line)
Andrew Tridgell9b73d1c1998-10-29 11:11:38 +0000468{
469 if (code == 0) {
Andrew Tridgell67ea0d41998-10-29 11:16:51 +0000470 rprintf(FLOG,"wrote %.0f bytes read %.0f bytes total size %.0f\n",
Andrew Tridgell9b73d1c1998-10-29 11:11:38 +0000471 (double)stats.total_written,
472 (double)stats.total_read,
473 (double)stats.total_size);
474 } else {
Wayne Davison4a7319b2003-12-15 01:45:01 +0000475 const char *name;
Martin Poolaf642a62000-11-10 03:28:15 +0000476
Wayne Davison4a7319b2003-12-15 01:45:01 +0000477 name = rerr_name(code);
478 if (!name)
479 name = "unexplained error";
480
Wayne Davison1bca1de2003-12-15 08:06:52 +0000481 /* VANISHED is not an error, only a warning */
482 if (code == RERR_VANISHED) {
483 rprintf(FINFO, "rsync warning: %s (code %d) at %s(%d)\n",
484 name, code, file, line);
485 } else {
486 rprintf(FERROR, "rsync error: %s (code %d) at %s(%d)\n",
487 name, code, file, line);
488 }
Andrew Tridgell9b73d1c1998-10-29 11:11:38 +0000489 }
490}