From le@univie.ac.at  Sun Aug  3 13:05:00 2003
Return-Path: <le@univie.ac.at>
Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125])
	by hub.freebsd.org (Postfix) with ESMTP id 8BB2637B401
	for <FreeBSD-gnats-submit@freebsd.org>; Sun,  3 Aug 2003 13:05:00 -0700 (PDT)
Received: from mailbox.univie.ac.at (mailbox.univie.ac.at [131.130.1.27])
	by mx1.FreeBSD.org (Postfix) with ESMTP id 1F51243F75
	for <FreeBSD-gnats-submit@freebsd.org>; Sun,  3 Aug 2003 13:04:59 -0700 (PDT)
	(envelope-from le@univie.ac.at)
Received: from korben.in.tern (adslle.cc.univie.ac.at [131.130.102.11])
	by mailbox.univie.ac.at (8.12.2/8.12.2) with ESMTP id h73K4eMP035448
	for <FreeBSD-gnats-submit@freebsd.org>; Sun, 3 Aug 2003 22:04:48 +0200
Received: from korben.in.tern (korben.in.tern [127.0.0.1])
	by korben.in.tern (8.12.9/8.12.9) with ESMTP id h73K4bPE014106
	for <FreeBSD-gnats-submit@freebsd.org>; Sun, 3 Aug 2003 22:04:37 +0200 (CEST)
	(envelope-from le@korben.in.tern)
Received: (from le@localhost)
	by korben.in.tern (8.12.9/8.12.9/Submit) id h73K4aIC014105;
	Sun, 3 Aug 2003 22:04:36 +0200 (CEST)
	(envelope-from le)
Message-Id: <200308032004.h73K4aIC014105@korben.in.tern>
Date: Sun, 3 Aug 2003 22:04:36 +0200 (CEST)
From: Lukas Ertl <l.ertl@univie.ac.at>
Reply-To: Lukas Ertl <l.ertl@univie.ac.at>
To: FreeBSD-gnats-submit@freebsd.org
Cc:
Subject: [PATCH] add wu-ftpd style xferlog format to libexec/ftpd
X-Send-Pr-Version: 3.113
X-GNATS-Notify:

>Number:         55215
>Category:       bin
>Synopsis:       [PATCH] add wu-ftpd style xferlog format to libexec/ftpd
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    le
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Sun Aug 03 13:10:12 PDT 2003
>Closed-Date:    Sat Nov 26 16:32:45 GMT 2005
>Last-Modified:  Sat Nov 26 16:32:45 GMT 2005
>Originator:     Lukas Ertl
>Release:        FreeBSD 5.1-CURRENT i386
>Organization:
Vienna University Computer Center
>Environment:
System: FreeBSD korben 5.1-CURRENT FreeBSD 5.1-CURRENT #22: Sun Aug 3 14:25:10 CEST 2003 le@korben:/usr/obj/usr/src/sys/KORBEN i386


	
>Description:

The -S option to ftpd lets the daemon log all anonymous file transfers
to /var/log/ftpd, but in a somewhat antiquated format.  The attached
patch adds an option -x, which changes this output format to wu-ftpd
style "xferlog" format, which can be processed by analysis tools
like webalizer et. al.

>How-To-Repeat:
	
>Fix:

	

--- ftpd.diff begins here ---
Index: libexec/ftpd/ftpd.8
===================================================================
RCS file: /usr/local/bsdcvs/src/libexec/ftpd/ftpd.8,v
retrieving revision 1.64
diff -u -u -r1.64 ftpd.8
--- libexec/ftpd/ftpd.8	8 Jun 2003 12:39:17 -0000	1.64
+++ libexec/ftpd/ftpd.8	3 Aug 2003 19:59:19 -0000
@@ -40,7 +40,7 @@
 .Nd Internet File Transfer Protocol server
 .Sh SYNOPSIS
 .Nm
-.Op Fl 46ADdEhMmOoRrSUvW
+.Op Fl 46ADdEhMmOoRrSUvWx
 .Op Fl l Op Fl l
 .Op Fl a Ar address
 .Op Fl P Ar port
@@ -210,6 +210,13 @@
 .It Fl W
 Do not log FTP sessions to
 .Pa /var/log/wtmp .
+.It Fl x
+Like
+.Fl S ,
+but the output has wu-ftpd style
+.Dq xferlog
+format, which can be processed with logfile analysis programs like
+.Pa ports/www/webalizer .
 .El
 .Pp
 The file
Index: libexec/ftpd/ftpd.c
===================================================================
RCS file: /usr/local/bsdcvs/src/libexec/ftpd/ftpd.c,v
retrieving revision 1.145
diff -u -u -r1.145 ftpd.c
--- libexec/ftpd/ftpd.c	9 Jul 2003 12:46:24 -0000	1.145
+++ libexec/ftpd/ftpd.c	3 Aug 2003 15:42:50 -0000
@@ -131,6 +131,7 @@
 int	dochroot;
 int	dowtmp = 1;
 int	stats;
+int	xferlogstats;
 int	statfd = -1;
 int	type;
 int	form;
@@ -301,7 +302,7 @@
 
 
 	while ((ch = getopt(argc, argv,
-	                    "46a:AdDEhlmMoOp:P:rRSt:T:u:UvW")) != -1) {
+	                    "46a:AdDEhlmMoOp:P:rRSt:T:u:UvWx")) != -1) {
 		switch (ch) {
 		case '4':
 			enable_v4 = 1;
@@ -412,6 +413,11 @@
 			dowtmp = 0;
 			break;
 
+		case 'x':
+			stats++;
+			xferlogstats++;
+			break;
+
 		default:
 			warnx("unknown flag -%c ignored", optopt);
 			break;
@@ -3133,10 +3139,19 @@
 
 	if (statfd >= 0 && getwd(path) != NULL) {
 		time(&now);
-		snprintf(buf, sizeof(buf), "%.20s!%s!%s!%s/%s!%qd!%ld\n",
-			ctime(&now)+4, ident, remotehost,
-			path, name, (long long)size,
-			(long)(now - start + (now == start)));
+		if (xferlogstats > 0) {
+			snprintf(buf, sizeof(buf),
+				"%.24s %ld %s %qd %s/%s %s _ o a %s ftp 1 * %s\n",
+				ctime(&now), (long)(now - start + (now == start)),
+				remotehost, (long long)byte_count, path, name,
+				type == TYPE_A ? "a" : "b", ident,
+				byte_count == size ? "c" : "i");
+		} else {
+			snprintf(buf, sizeof(buf), "%.20s!%s!%s!%s/%s!%qd!%ld\n",
+				ctime(&now)+4, ident, remotehost,
+				path, name, (long long)size,
+				(long)(now - start + (now == start)));
+		}
 		write(statfd, buf, strlen(buf));
 	}
 }
--- ftpd.diff ends here ---


>Release-Note:
>Audit-Trail:
Responsible-Changed-From-To: freebsd-bugs->le 
Responsible-Changed-By: le 
Responsible-Changed-When: Mon Feb 2 14:27:29 PST 2004 
Responsible-Changed-Why:  
Take my own PR. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=55215 

From: Nick Leuta <skynick@stu.lipetsk.ru>
To: freebsd-gnats-submit@FreeBSD.org, l.ertl@univie.ac.at
Cc:  
Subject: Re: bin/55215: [PATCH] add wu-ftpd style xferlog format to libexec/ftpd
Date: Fri, 6 Feb 2004 13:34:40 +0300

 There is more powerful way - to log _all_ file transfers, not only anonymous
 ones. Next patch enables the wu-ftpd style xferlog for both syslog and
 /var/log/ftpd, and also implements an optional extension, which allows to
 identify restarted transfers in both directions and appends in case of
 incoming transfers.
 
 diff -urN ftpd.ORI/ftpd.8 ftpd/ftpd.8
 --- ftpd.ORI/ftpd.8	Sun Sep 14 20:42:46 2003
 +++ ftpd/ftpd.8	Fri Feb  6 01:43:58 2004
 @@ -40,14 +40,16 @@
  .Nd Internet File Transfer Protocol server
  .Sh SYNOPSIS
  .Nm
 -.Op Fl 46ADdEhMmOoRrSUvW
 +.Op Fl 46ADdEhMmOoRrUuvW
  .Op Fl l Op Fl l
  .Op Fl a Ar address
  .Op Fl P Ar port
  .Op Fl p Ar file
 +.Op Fl S Ar logtype
  .Op Fl T Ar maxtimeout
  .Op Fl t Ar timeout
  .Op Fl u Ar umask
 +.Op Fl X Ar logtype
  .Sh DESCRIPTION
  The
  .Nm
 @@ -111,10 +113,13 @@
  If this option is specified twice, the retrieve (get), store (put), append,
  delete, make directory, remove directory and rename operations and
  their filename arguments are also logged.
 -By default,
 -.Xr syslogd 8
 -logs these to
 -.Pa /var/log/xferlog .
 +.Pp
 +The format, in which the information about the retrieve (get), store (put) and
 +append operations will be logged, may be changed to the wu-ftpd style
 +.Xr xferlog 5
 +one with help of
 +.Fl X
 +option.
  .It Fl M
  Prevent anonymous users from creating directories.
  .It Fl m
 @@ -160,9 +165,27 @@
  .It Fl S
  With this option set,
  .Nm
 -logs all anonymous file downloads to the file
 +logs all file transfers to the file
  .Pa /var/log/ftpd
 -when this file exists.
 +when this file exists. This file name may be overridden in the virtual hosting
 +configuration file. The possible values of
 +.Ar logtype
 +are:
 +.Bl -tag -width wu-orig
 +.It Cm anon
 +Server logs only anonymous file downloads in its own
 +.Xr xferlog 5
 +format.
 +.It Cm wu-orig
 +Log all file transfers in the original wu-ftpd
 +.Xr xferlog 5
 +format.
 +.It Cm wu-ext
 +Log all file transfers in the extended wu-ftpd style
 +.Xr xferlog 5
 +format. In this case the information about restarted downloads and about
 +appends will also be available.
 +.El
  .It Fl T
  A client may also request a different timeout period;
  the maximum period allowed may be set to
 @@ -204,6 +227,27 @@
  .It Fl W
  Do not log FTP sessions to
  .Pa /var/log/wtmp .
 +.It Fl X
 +Log all file transfers to the syslog in the wu-ftpd style
 +.Xr xferlog 5
 +format. File transfers will be logged regardless of the logging state which is
 +set by
 +.Fl l
 +option, but if
 +.Fl l
 +option is specified twice, the information about the retrieve (get), store
 +(put) and append operations will be logged in this format.
 +.Pp
 +The possible values of
 +.Ar logtype
 +are:
 +.Bl -tag -width wu-orig
 +.It Cm wu-orig
 +Log all file transfers in the original wu-ftpd format.
 +.It Cm wu-ext
 +Log all file transfers in the extended wu-ftpd style format. In this case the
 +information about restarted downloads and about appends will also be available.
 +.El
  .El
  .Pp
  The file
 @@ -528,9 +572,7 @@
  .It Pa /var/run/nologin
  Displayed and access refused.
  .It Pa /var/log/ftpd
 -Log file for anonymous transfers.
 -.It Pa /var/log/xferlog
 -Default place for session logs.
 +Log file for all file transfers.
  .El
  .Sh SEE ALSO
  .Xr ftp 1 ,
 @@ -539,7 +581,9 @@
  .Xr getusershell 3 ,
  .Xr ftpchroot 5 ,
  .Xr login.conf 5 ,
 +.Xr xferlog 5 ,
  .Xr inetd 8 ,
 +.Xr pam 8 ,
  .Xr syslogd 8
  .Sh BUGS
  The server must run as the super-user
 diff -urN ftpd.ORI/ftpd.c ftpd/ftpd.c
 --- ftpd.ORI/ftpd.c	Mon Jan 19 00:29:33 2004
 +++ ftpd/ftpd.c	Fri Feb  6 01:58:22 2004
 @@ -186,6 +186,14 @@
  static char opieprompt[OPIE_CHALLENGE_MAX+1];
  static int pwok;
  
 +/*
 + * wu-ftpd style xferlog
 + */
 +#define XFERLOG_ORIG	1 /* use original format */
 +#define XFERLOG_EXT	2 /* use extended format */
 +int	xferlog_stat = 0; /* xferlog format for stat file */
 +int	xferlog_syslog = 0; /* xferlog format for syslog */
 +
  char	*pid_file = NULL;
  
  /*
 @@ -255,7 +263,9 @@
  		 sgetpwnam(char *);
  static char	*sgetsave(char *);
  static void	 reapchild(int);
 -static void      logxfer(char *, off_t, time_t);
 +static void      logxfer(char *, char *, off_t, time_t, time_t, int, int);
 +static void      logxfer_anon(char *, off_t, time_t, time_t);
 +static void      logxfer_wuftpd(char *, char *, off_t, time_t, time_t, int, int);
  static char	*doublequote(char *);
  static int	*socksetup(int, char *, const char *);
  
 @@ -300,7 +310,7 @@
  
  
  	while ((ch = getopt(argc, argv,
 -	                    "46a:AdDEhlmMoOp:P:rRSt:T:u:UvW")) != -1) {
 +	                    "46a:AdDEhlmMoOp:P:rRS:t:T:u:UvWX:")) != -1) {
  		switch (ch) {
  		case '4':
  			family = (family == AF_INET6) ? AF_UNSPEC : AF_INET;
 @@ -371,7 +381,19 @@
  			break;
  
  		case 'S':
 -			stats++;
 +			if (strcmp(optarg, "anon") == 0 ) {
 +			    stats = 1;
 +			    break;
 +			}
 +			if (strcmp(optarg, "wu-orig") == 0 ) {
 +			    xferlog_stat = XFERLOG_ORIG;
 +			    break;
 +			}
 +			if (strcmp(optarg, "wu-ext") == 0 ) {
 +			    xferlog_stat = XFERLOG_EXT;
 +			    break;
 +			}
 +			warnx("bad value for -S");
  			break;
  
  		case 't':
 @@ -409,6 +431,18 @@
  			dowtmp = 0;
  			break;
  
 +		case 'X':
 +			if (strcmp(optarg, "wu-orig") == 0 ) {
 +			    xferlog_syslog = XFERLOG_ORIG;
 +			    break;
 +			}
 +			if (strcmp(optarg, "wu-ext") == 0 ) {
 +			    xferlog_syslog = XFERLOG_EXT;
 +			    break;
 +			}
 +			warnx("bad value for -X");
 +			break;
 +
  		default:
  			warnx("unknown flag -%c ignored", optopt);
  			break;
 @@ -1451,13 +1485,16 @@
  		    (struct sockaddr *)&his_addr);
  	logged_in = 1;
  
 -	if (guest && stats && statfd < 0)
 +	if ((stats || xferlog_stat) && statfd < 0)
  #ifdef VIRTUAL_HOSTING
  		if ((statfd = open(thishost->statfile, O_WRONLY|O_APPEND)) < 0)
  #else
  		if ((statfd = open(_PATH_FTPDSTATFILE, O_WRONLY|O_APPEND)) < 0)
  #endif
 +		{
  			stats = 0;
 +			xferlog_stat = 0;
 +		}
  
  	dochroot =
  		checkuser(_PATH_FTPCHROOT, pw->pw_name, 1, &residue)
 @@ -1624,7 +1661,8 @@
  	FILE *fin, *dout;
  	struct stat st;
  	int (*closefunc)(FILE *);
 -	time_t start;
 +	time_t time_start, time_end;
 +	int send_err = -1;
  
  	if (cmd == 0) {
  		fin = fopen(name, "r"), closefunc = fclose;
 @@ -1681,20 +1719,26 @@
  			goto done;
  		}
  	}
 +
  	dout = dataconn(name, st.st_size, "w");
 -	if (dout == NULL)
 +	if (dout == NULL) {
 +		time(&time_start);
 +		time_end = time_start;
  		goto done;
 -	time(&start);
 -	send_data(fin, dout, st.st_blksize, st.st_size,
 +	}
 +	time(&time_start);
 +	send_err = send_data(fin, dout, st.st_blksize, st.st_size,
  		  restart_point == 0 && cmd == 0 && S_ISREG(st.st_mode));
 -	if (cmd == 0 && guest && stats)
 -		logxfer(name, st.st_size, start);
 +	time(&time_end);
  	(void) fclose(dout);
 +
  	data = -1;
  	pdata = -1;
  done:
 -	if (cmd == 0)
 -		LOGBYTES("get", name, byte_count);
 +	if (cmd == 0) {
 +		logxfer("get", name, st.st_size, time_start, time_end, 1,
 +		    send_err);
 +	}
  	(*closefunc)(fin);
  }
  
 @@ -1703,7 +1747,10 @@
  {
  	int fd;
  	FILE *fout, *din;
 +	struct stat st;
  	int (*closefunc)(FILE *);
 +	time_t time_start, time_end;
 +	int rec_err = -1;
  
  	if (*mode == 'a') {		/* APPE */
  		if (unique) {
 @@ -1770,10 +1817,19 @@
  			goto done;
  		}
  	}
 +
  	din = dataconn(name, (off_t)-1, "r");
 -	if (din == NULL)
 +	if (din == NULL) {
 +		time(&time_start);
 +		time_end = time_start;
  		goto done;
 -	if (receive_data(din, fout) == 0) {
 +	}
 +
 +	time(&time_start);
 +	rec_err = receive_data(din, fout);
 +	time(&time_end);
 +
 +	if (rec_err == 0) {
  		if (unique)
  			reply(226, "Transfer complete (unique file name:%s).",
  			    name);
 @@ -1781,10 +1837,18 @@
  			reply(226, "Transfer complete.");
  	}
  	(void) fclose(din);
 +
  	data = -1;
  	pdata = -1;
  done:
 -	LOGBYTES(*mode == 'a' ? "append" : "put", name, byte_count);
 +	if (fstat(fileno(fout), &st) < 0) {
 +		/* Unexpected error */
 +		syslog(LOG_ERR, "Can't fstat() the receiving file: %s%s",
 +		    (*(name) == '/') ? "" : curdir(), name);
 +		st.st_size = 0;
 +	}
 +	logxfer(*mode == 'a' ? "append" : "put", name, st.st_size, time_start,
 +	    time_end, 0, rec_err);
  	(*closefunc)(fout);
  	return;
  err:
 @@ -3105,20 +3169,146 @@
  }
  #endif /* OLD_SETPROCTITLE */
  
 +/*
 + * Log the transfer information.
 + * arguments:
 + *	cmd  - the name of the ftp(1) operation.
 + *	name - the name of the file.
 + *	size - the size of the file (not the size of the transfer!).
 + *	time_start, time_end - the values of times (according to time(3)) of
 + *		the begin and the end of transfer, respectively.
 + *	outgoing_flag - is not 0 in case of outgoing transfer.
 + *	err_flag - is not 0 if errors occurred during the transfer.
 + * return:
 + *	none.
 + */
  static void
 -logxfer(char *name, off_t size, time_t start)
 +logxfer(char *cmd, char *name, off_t size, time_t time_start, time_t time_end,
 +	int outgoing_flag, int err_flag)
 +{
 +	/* this information will be logged in wu-ftpd style format */
 +	if (!xferlog_syslog)
 +		LOGBYTES(cmd, name, byte_count);
 +
 +	/* don't use it if wu-ftpd style xferlog is enabled */
 +	if (!xferlog_stat && guest && stats && outgoing_flag)
 +		logxfer_anon(name, size, time_start, time_end);
 +
 +	/* use wu-ftpd style xferlog if allowed */
 +	if (xferlog_stat || xferlog_syslog)
 +		logxfer_wuftpd(cmd, name, size, time_start, time_end,
 +		outgoing_flag, err_flag);
 +}
 +
 +/*
 + * Log anonymous file downloads.
 + * arguments:
 + *	name - the name of the file.
 + *	size - the size of the file (not the size of the transfer!).
 + *	time_start, time_end - the values of times (according to time(3)) of
 + *		the begin and the end of transfer, respectively.
 + * return:
 + *	none.
 + */
 +static void
 +logxfer_anon(char *name, off_t size, time_t time_start, time_t time_end)
  {
  	char buf[1024];
 -	char path[MAXPATHLEN + 1];
 -	time_t now;
 +	char path[MAXPATHLEN+1+1];	/* path + '/' + '\0' */
  
 -	if (statfd >= 0 && getwd(path) != NULL) {
 -		time(&now);
 +	if (statfd >= 0 && getcwd(path, sizeof(path)-2) != NULL) {
  		snprintf(buf, sizeof(buf), "%.20s!%s!%s!%s/%s!%qd!%ld\n",
 -			ctime(&now)+4, ident, remotehost,
 +			ctime(&time_end)+4, ident, remotehost,
  			path, name, (long long)size,
 -			(long)(now - start + (now == start)));
 +			(long)(time_end-time_start + (time_end==time_start)));
  		write(statfd, buf, strlen(buf));
 +	}
 +}
 +
 +/*
 + * Log the transfer information in the wu-ftpd style format.
 + * arguments:
 + *	cmd  - the name of the ftp(1) operation.
 + *	name - the name of the file.
 + *	size - the size of the file (not the size of the transfer!).
 + *	time_start, time_end - the values of times (according to time(3)) of
 + *		the begin and the end of transfer, respectively.
 + *	outgoing_flag - is not 0 in case of outgoing transfer.
 + *	err_flag - is not 0 if errors occurred during the transfer.
 + * return:
 + *	none.
 + * notes:
 + *	In case of an incoming transfer (outgoing_flag == 0) the "size" must
 + *	be the size of the file AFTER the completion of the transfer.
 + */
 +static void
 +logxfer_wuftpd(char *cmd, char *name, off_t size, time_t time_start,
 +	    time_t time_end, int outgoing_flag, int err_flag)
 +{
 +	char msg[MAXPATHLEN+1 + MAXHOSTNAMELEN + BUFSIZ +1];
 +	/* (path+'/') + remotehost + (numbers/flags/etc) + '\0' */
 +	char msg_app[BUFSIZ]; /* extended fields of the xferlog */
 +	size_t msglen;
 +	time_t xfertime = time_end - time_start + (time_end == time_start);
 +	time_t curtime = time(NULL);
 +
 +	snprintf(msg, sizeof(msg), "%.24s %ld %s %qd %s%s %c %s %c %c %s ftp %d %s %c",
 +		/* current-time in the form "DDD MMM dd hh:mm:ss YYYY" */
 +		ctime(&curtime),
 +		/* transfer-time (seconds) */
 +		(long)xfertime,
 +		/* remote-host */
 +		remotehost,
 +		/* byte-count (bytes) */
 +		(long long)byte_count,
 +		/* filename */
 +		(*(name) == '/') ? "" : curdir(), name,
 +		/* transfer-type (ascii/binary: [a|b]) */
 +		(type == TYPE_A) ? 'a' : 'b',
 +		/* special-action-flag (gzip/gunzip/tar/none: [C|U|T|_]) */
 +		"_",
 +		/* direction (incoming/outgoing: [i|o]) */
 +		outgoing_flag ? 'o' : 'i',
 +		/* access-mode (anonymous/guest/real user: [a|g|r]) */
 +		guest ? 'a' : dochroot ? 'g' : 'r',
 +		/* username (ident string/login name) */
 +		guest ? ident : curname,
 +		/* authentication-method (none/RFC931: [0|1]) */
 +		0,
 +		/* authentication-user-id; '*' if it isn't available */
 +		"*",
 +		/* completion-status (complete/incomplete: [c|i]) */
 +		 err_flag ? 'i' : 'c'
 +	);
 +
 +	if (xferlog_stat == XFERLOG_EXT || xferlog_syslog == XFERLOG_EXT) {
 +		snprintf(msg_app, sizeof(msg_app), " %qd %qd",
 +		/* restart-point (bytes), file-size (bytes) */
 +		(long long)restart_point, (long long)size);
 +	}
 +
 +	if (xferlog_syslog)
 +		syslog(LOG_INFO, "xferlog (%s): %s%s",
 +		    /* The extended format or... */
 +		    xferlog_syslog == XFERLOG_EXT ? cmd :
 +		    /* ...the original wu-ftpd one */
 +		    (outgoing_flag ? "send" : "recv"),
 +		    /* Skip date/time */
 +		    msg + 25,
 +		    /* Append extended fields */
 +		    xferlog_syslog == XFERLOG_EXT ? msg_app : "");
 +
 +	if (statfd >= 0 && xferlog_stat) {
 +		/* Append '\n' and extended fields */
 +		msglen = strlen(msg);
 +		snprintf(msg + msglen, sizeof(msg) - msglen, "%s\n",
 +		    (xferlog_stat == XFERLOG_EXT) ? msg_app: "");
 +
 +		/* Ensure that msg always ends with '\n' */
 +		if (strlen(msg) == sizeof(msg) - 1)
 +			msg[sizeof(msg) - 2] = '\n';
 +
 +		write(statfd, msg, strlen(msg));
  	}
  }
  
 diff -urN ftpd.ORI/xferlog.5 ftpd/xferlog.5
 --- ftpd.ORI/xferlog.5	Thu Jan  1 03:00:00 1970
 +++ ftpd/xferlog.5	Fri Feb  6 01:58:47 2004
 @@ -0,0 +1,281 @@
 +.\" Copyright (c) 2004 Nick Leuta
 +.\" All rights reserved.
 +.\"
 +.\" Redistribution and use in source and binary forms, with or without
 +.\" modification, are permitted provided that the following conditions
 +.\" are met:
 +.\" 1. Redistributions of source code must retain the above copyright
 +.\"    notice, this list of conditions and the following disclaimer.
 +.\" 2. Redistributions in binary form must reproduce the above copyright
 +.\"    notice, this list of conditions and the following disclaimer in the
 +.\"    documentation and/or other materials provided with the distribution.
 +.\" 3. The name of the author may not be used to endorse or promote products
 +.\"    derived from this software without specific prior written permission. 
 +.\"
 +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 +.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 +.\" SUCH DAMAGE.
 +.\"
 +.Dd January 4, 2004
 +.Dt XFERLOG 5
 +.Os
 +.Sh NAME
 +.Nm xferlog
 +.Nd the format that is used to log an information about file transfers
 +.Sh DESCRIPTION
 +The
 +.Xr ftpd 8
 +utility can log an information about file transfers to the file or to the
 +syslog using LOG_FTP facility. The file transfer information may be logged in
 +several formats.
 +.Pp
 +The default name of the file to which all file transfers are logged is
 +.Pa /var/log/ftpd .
 +The name and the location of this file may be changed by the virtual hosting
 +configuration in the
 +.Pa /etc/ftphosts
 +file. In case of the wu-ftpd style logging format the most common alternative
 +for the file name is
 +.Pa /var/log/xferlog .
 +.Pp
 +The
 +.Xr ftpd 8
 +utility supports next logging formats:
 +.Bl -tag -width wu-orig
 +.It wu-orig
 +The original
 +.Sq xferlog
 +format of wu-ftpd server.
 +.It wu-ext
 +The extended wu-ftpd style
 +.Sq xferlog
 +format.
 +.It anon
 +The format for logging anonymous file downloads.
 +.El
 +.Pp
 +Each file transfer is represented by a single line. In case of
 +.Dq wu-orig
 +and
 +.Dq wu-ext
 +formats each line contains a number of fields separated by whitespace. The
 +.Dq wu-orig
 +format uses next set of fields:
 +.Pp
 +.Ic current-time transfer-time remote-host byte-count filename transfer-type special-action-flag direction access-mode username service-name authentication-method authenticated-user-id completion-status
 +.Pp
 +The
 +.Dq wu-ext
 +format extends that set of fields by the new ones:
 +.Pp
 +.Ic current-time transfer-time remote-host byte-count filename transfer-type special-action-flag direction access-mode username service-name authentication-method authenticated-user-id completion-status restart-point file-size
 +.Pp
 +When logging to the syslog, the
 +.Sq current-time
 +field is replaced by the next structure:
 +.Pp
 +.Ic SYSLOG-PREFIX xferlog (CMDTYPE):
 +.Pp
 +The variable fields of this structure are:
 +.Bl -tag -width SYSLOG-PREFIX
 +.It SYSLOG-PREFIX
 +A string that prepends to every syslog message and contains the current time,
 +the local host name, the ident (the
 +.Dq ftpd
 +keyword for the
 +.Xr ftpd 8
 +utility) and the process id. See also
 +.Xr syslogd 8
 +and
 +.Xr syslog.conf 5 .
 +.It CMDTYPE
 +The keyword that describes the type of FTP command depending to the direction
 +of the transfer. In case of the
 +.Dq wu-orig
 +format it is one of
 +.Dq send
 +or
 +.Dq recv ,
 +depending to the outgoing or incoming direction of the transfer. In case of
 +the
 +.Dq wu-ext
 +format, it is one of
 +.Dq get ,
 +.Dq put
 +or
 +.Dq append
 +keywords, those correspond to the retrieve, store and append operations,
 +respectively.
 +.El
 +.Pp
 +This is a description of all fields of both wu-ftpd style formats:
 +.Bl -tag -width transfer-time
 +.It current-time
 +The current local time in the form "DDD MMM dd hh:mm:ss YYYY", where DDD is the
 +day of the week, MMM is the month, dd is the day of the month, hh is the hour,
 +mm is the minutes, ss is the seconds, and YYYY is the year.
 +.It transfer-time
 +The total time of the transfer in seconds.
 +.It remote-host
 +The remote host name.
 +.It byte-count
 +The amount of transferred bytes.
 +.It filename
 +The name of the transferred file.
 +.It transfer-type
 +The single character that indicates the type of the transfer. The set of
 +possible values is:
 +.Bl -tag -width abc
 +.It a
 +An ascii transfer.
 +.It b
 +A binary transfer.
 +.El
 +.It special-action-flag
 +.Bl -tag -width abc
 +One or more single character flags indicating any special action taken. The set
 +of possible values is:
 +.It _
 +No action was taken
 +.It C
 +The file was compressed (not used).
 +.It U
 +The file was uncompressed (not used).
 +.It T
 +The file was tar'ed (not used).
 +.El
 +.It direction
 +The direction of the transfer. The set of possible values is:
 +.Bl -tag -width abc
 +.It o
 +The outgoing transfer.
 +.It i
 +The incoming transfer.
 +.El
 +.It access-mode
 +The method by which the user is logged in. The set of possible values is:
 +.Bl -tag -width a_(anonymous)
 +.It a (anonymous)
 +The anonymous guest user.
 +.It g (guest)
 +The real but chrooted user (this capability is guided by
 +.Xr ftpchroot 5
 +file).
 +.It r (real)
 +The real user.
 +.El
 +.It username
 +The user's login name in case of the real user, or the user's identification
 +string in case of the anonymous user (by convention it is an email address of
 +the user).
 +.It service-name
 +The name of the service being invoked. The
 +.Xr ftpd 8
 +utility uses the
 +.Dq ftp
 +keyword.
 +.It authentication-method
 +The used method of the authentication. The set of possible values is:
 +.Bl -tag -width abc
 +.It 0
 +None.
 +.It 1
 +RFC931 Authentication (not used).
 +.El
 +.It authenticated-user-id
 +The user id returned by the authentication method. The
 +.Sq *
 +symbol is used if an authenticated user id is not available.
 +.It completion-status
 +The single character that indicates the status of the transfer. The set of
 +possible values is:
 +.Bl -tag -width abc
 +.It c
 +A complete transfer.
 +.It i
 +An incomplete transfer.
 +.El
 +.It restart-point
 +The restart point of the transfer in bytes.
 +.It file-size
 +In case of the outgoing transfer it is the original size of the file in bytes.
 +In case of the incoming transfer it is the size in bytes of the file after the
 +completion of the transfer.
 +.El
 +.Pp
 +The usage of
 +.Dq restart-point
 +and
 +.Dq file-size
 +fields allows to identify restarted transfers in both directions (the
 +.Dq restart-point
 +field contains non-zero value) and appends in case of incoming transfers (the
 +.Dq byte-count
 +contains the value that is lesser then the one of the
 +.Dq file-size
 +filed).
 +.Pp
 +The
 +.Dq anon
 +format is used only for logging to the file and is supported for the backward
 +compatibility with old versions of
 +.Xr ftpd 8 .
 +In case of this format each line contains a number of fields separated by the
 +`!' symbol:
 +.Bl -tag -width transfer-time
 +.It current-time
 +The current local time in the form "MMM dd hh:mm:ss YYYY", where MMM is the
 +month, dd is the day of the month, hh is the hour, mm is the minutes, ss is the
 +seconds, and YYYY is the year.
 +.It ident
 +The user's identification string; by convention it is an email address of the
 +user.
 +.It remote-host
 +The remote host name.
 +.It filename
 +The name of the transferred file.
 +.It byte-count
 +The amount of transferred bytes.
 +.It transfer-time
 +The total time of the transfer, in seconds.
 +.El
 +.Sh FILES
 +.Bl -tag -width ".Pa /var/log/xferlog" -compact
 +.It Pa /var/log/ftpd
 +Log file for all file transfers.
 +.It Pa /var/log/xferlog
 +The alternative name of the log file for file transfers. It is commonly used
 +in case of wu-ftpd style format of logging.
 +.It Pa /etc/ftpchroot
 +List of normal users who should be chroot'd.
 +.It Pa /etc/ftphosts
 +Virtual hosting configuration file.
 +.El
 +.Sh SEE ALSO
 +.Xr ftpchroot 5 ,
 +.Xr syslog.conf 5 ,
 +.Xr ftpd 8 ,
 +.Xr syslogd 8
 +.Sh HISTORY
 +The
 +.Dq wu-orig
 +format appeared in wu-ftpd server. The names of the fields in the wu-ftpd style
 +formats described in this document are mainly based on ones from the wu-ftpd
 +documentation. The names "wuftpd" and "wu-ftpd" are trademarks of the WU-FTPD
 +Development Group and the Washington University at Saint Louis.
 +.Pp
 +The
 +.Dq anon
 +format appeared in FreeBSD 2.0.5.
 +.Pp
 +The
 +.Dq wu-ext
 +format appeared in BSDftpd-ssl 1.0.1.
State-Changed-From-To: open->closed 
State-Changed-By: le 
State-Changed-When: Sat Nov 26 16:32:29 GMT 2005 
State-Changed-Why:  
It seems nobody is really interested in this kind of feature. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=55215 
>Unformatted:
