From e08bfe1248d9640e77544fe7df50573c6e8843b3 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 30 Oct 1998 02:24:47 +0000 Subject: [PATCH] added "log format" option to allow admins to choose the format for rsyncd log file entries --- loadparm.c | 4 +++ log.c | 72 ++++++++++++++++++++++++++++++++++++++++++++------ rsync.h | 10 +++++++ rsyncd.conf.yo | 18 +++++++++++++ 4 files changed, 96 insertions(+), 8 deletions(-) diff --git a/loadparm.c b/loadparm.c index aeb29804..150c618c 100644 --- a/loadparm.c +++ b/loadparm.c @@ -129,6 +129,7 @@ typedef struct char *secrets_file; char *exclude; char *exclude_from; + char *log_format; } service; @@ -150,6 +151,7 @@ static service sDefault = NULL, /* secrets file */ NULL, /* exclude */ NULL, /* exclude from */ + "%o %h [%a] %f %l", /* log format */ }; @@ -255,6 +257,7 @@ static struct parm_struct parm_table[] = {"exclude", P_STRING, P_LOCAL, &sDefault.exclude, NULL, 0}, {"exclude from", P_STRING, P_LOCAL, &sDefault.exclude_from,NULL, 0}, {"transfer logging", P_BOOL, P_LOCAL, &sDefault.transfer_logging,NULL,0}, + {"log format", P_STRING, P_LOCAL, &sDefault.log_format, NULL, 0}, {NULL, P_BOOL, P_NONE, NULL, NULL, 0} }; @@ -326,6 +329,7 @@ FN_LOCAL_STRING(lp_auth_users, auth_users) FN_LOCAL_STRING(lp_secrets_file, secrets_file) FN_LOCAL_STRING(lp_exclude, exclude) FN_LOCAL_STRING(lp_exclude_from, exclude_from) +FN_LOCAL_STRING(lp_log_format, log_format) /* local prototypes */ static int strwicmp( char *psz1, char *psz2 ); diff --git a/log.c b/log.c index 21b5c1c2..a4f06f16 100644 --- a/log.c +++ b/log.c @@ -97,8 +97,8 @@ void log_open(void) } -/* this is the rsync debugging function. Call it with FINFO or FERROR */ -void rprintf(int fd, const char *format, ...) +/* this is the rsync debugging function. Call it with FINFO, FERROR or FLOG */ + void rprintf(int fd, const char *format, ...) { va_list ap; char buf[1024]; @@ -171,6 +171,10 @@ void rflush(int fd) return; } + if (fd == FLOG) { + return; + } + if (fd == FERROR) { f = stderr; } @@ -188,14 +192,68 @@ void rflush(int fd) } + +/* a generic logging routine for send/recv, with parameter + substitiution */ +static void log_formatted(char *op, struct file_struct *file) +{ + extern int module_id; + char buf[1024]; + char *p, *s, *n; + char buf2[100]; + int l; + + strlcpy(buf, lp_log_format(module_id), sizeof(buf)-1); + + for (s=&buf[0]; + s && (p=strchr(s,'%')); ) { + n = NULL; + s = p + 1; + + switch (p[1]) { + case 'h': n = client_name(0); break; + case 'a': n = client_addr(0); break; + case 'l': + slprintf(buf2,sizeof(buf2)-1,"%.0f", + (double)file->length); + n = buf2; + break; + case 'p': + slprintf(buf2,sizeof(buf2)-1,"%d", + (int)getpid()); + n = buf2; + break; + case 'o': n = op; break; + case 'f': n = f_name(file); break; + } + + if (!n) continue; + + l = strlen(n); + + if ((l-1) + ((int)(s - &buf[0])) > sizeof(buf)) { + rprintf(FERROR,"buffer overflow expanding %%%c - exiting\n", + p[0]); + exit_cleanup(1); + } + + if (l != 2) { + memmove(s+(l-1), s+1, strlen(s+1)); + } + memcpy(p, n, l); + + s = p+l; + } + + rprintf(FLOG,"%s\n", buf); +} + /* log the outgoing transfer of a file */ void log_send(struct file_struct *file) { extern int module_id; if (lp_transfer_logging(module_id)) { - rprintf(FLOG,"Sending %s [%s] %.0f %s\n", - client_name(0), client_addr(0), - (double)file->length, f_name(file)); + log_formatted("send", file); } } @@ -204,9 +262,7 @@ void log_recv(struct file_struct *file) { extern int module_id; if (lp_transfer_logging(module_id)) { - rprintf(FLOG,"Receiving %s [%s] %.0f %s\n", - client_name(0), client_addr(0), - (double)file->length, f_name(file)); + log_formatted("recv", file); } } diff --git a/rsync.h b/rsync.h index c7b43bdd..11af1f33 100644 --- a/rsync.h +++ b/rsync.h @@ -456,3 +456,13 @@ extern int errno; #ifndef ACCESSPERMS #define ACCESSPERMS 0777 #endif + +/* handler for null strings in printf format */ +#define NS(s) ((s)?(s):"") + +/* use magic gcc attributes to catch format errors */ + void rprintf(int , const char *, ...) +#ifdef __GNUC__ + __attribute__ ((format (printf, 2, 3))) +#endif +; diff --git a/rsyncd.conf.yo b/rsyncd.conf.yo index 69be457e..f326f0a9 100644 --- a/rsyncd.conf.yo +++ b/rsyncd.conf.yo @@ -112,6 +112,24 @@ logging of downloads and uploads in a format somewhat similar to that used by ftp daemons. If you want to customise the log formats look at log_send, log_recv and log_transfer in log.c +dit(bf(log format)) The "log format" option allows you to specify the +format used for logging file transfers when transfer logging is +enabled. The format is a text string containing embedded single +character escape sequences prefixed with a percent (%) character. + +The prefixes that are understood are: + +itemize( + it() %h for the remote host name + it() %a for the remote IP address + it() %l for the length of the file in bytes + it() %p for the process id of this rsync session + it() %o for the operation, which is either "send" or "recv" + it() %f for the filename +) + +The default log format is "%o %h [%a] %f %l" + dit(bf(socket options)) This option can provide endless fun for people who like to tune their systems to the utmost degree. You can set all sorts of socket options which may make transfers faster (or -- 2.34.1