xref: /freebsd/libexec/ftpd/ftpd.c (revision 77a0943ded95b9e6438f7db70c4a28e4d93946d4)
1 /*
2  * Copyright (c) 1985, 1988, 1990, 1992, 1993, 1994
3  *	The Regents of the University of California.  All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. All advertising materials mentioning features or use of this software
14  *    must display the following acknowledgement:
15  *	This product includes software developed by the University of
16  *	California, Berkeley and its contributors.
17  * 4. Neither the name of the University nor the names of its contributors
18  *    may be used to endorse or promote products derived from this software
19  *    without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  */
33 
34 #if 0
35 #ifndef lint
36 static char copyright[] =
37 "@(#) Copyright (c) 1985, 1988, 1990, 1992, 1993, 1994\n\
38 	The Regents of the University of California.  All rights reserved.\n";
39 #endif /* not lint */
40 #endif
41 
42 #ifndef lint
43 #if 0
44 static char sccsid[] = "@(#)ftpd.c	8.4 (Berkeley) 4/16/94";
45 #endif
46 static const char rcsid[] =
47   "$FreeBSD$";
48 #endif /* not lint */
49 
50 /*
51  * FTP server.
52  */
53 #include <sys/param.h>
54 #include <sys/ioctl.h>
55 #include <sys/mman.h>
56 #include <sys/socket.h>
57 #include <sys/stat.h>
58 #include <sys/time.h>
59 #include <sys/wait.h>
60 
61 #include <netinet/in.h>
62 #include <netinet/in_systm.h>
63 #include <netinet/ip.h>
64 #include <netinet/tcp.h>
65 
66 #define	FTP_NAMES
67 #include <arpa/ftp.h>
68 #include <arpa/inet.h>
69 #include <arpa/telnet.h>
70 
71 #include <ctype.h>
72 #include <dirent.h>
73 #include <err.h>
74 #include <errno.h>
75 #include <fcntl.h>
76 #include <glob.h>
77 #include <limits.h>
78 #include <netdb.h>
79 #include <pwd.h>
80 #include <grp.h>
81 #include <setjmp.h>
82 #include <signal.h>
83 #include <stdio.h>
84 #include <stdlib.h>
85 #include <string.h>
86 #include <syslog.h>
87 #include <time.h>
88 #include <unistd.h>
89 #include <libutil.h>
90 #ifdef	LOGIN_CAP
91 #include <login_cap.h>
92 #endif
93 
94 #ifdef	SKEY
95 #include <skey.h>
96 #endif
97 
98 #if !defined(NOPAM)
99 #include <security/pam_appl.h>
100 #endif
101 
102 #include "pathnames.h"
103 #include "extern.h"
104 
105 #if __STDC__
106 #include <stdarg.h>
107 #else
108 #include <varargs.h>
109 #endif
110 
111 static char version[] = "Version 6.00LS";
112 #undef main
113 
114 /* wrapper for KAME-special getnameinfo() */
115 #ifndef NI_WITHSCOPEID
116 #define	NI_WITHSCOPEID	0
117 #endif
118 
119 extern	off_t restart_point;
120 extern	char cbuf[];
121 
122 union sockunion server_addr;
123 union sockunion ctrl_addr;
124 union sockunion data_source;
125 union sockunion data_dest;
126 union sockunion his_addr;
127 union sockunion pasv_addr;
128 
129 int	daemon_mode;
130 int	data;
131 jmp_buf	errcatch, urgcatch;
132 int	logged_in;
133 struct	passwd *pw;
134 int	debug;
135 int	timeout = 900;    /* timeout after 15 minutes of inactivity */
136 int	maxtimeout = 7200;/* don't allow idle time to be set beyond 2 hours */
137 int	logging;
138 int	restricted_data_ports = 1;
139 int	paranoid = 1;	  /* be extra careful about security */
140 int	anon_only = 0;    /* Only anonymous ftp allowed */
141 int	guest;
142 int	dochroot;
143 int	stats;
144 int	statfd = -1;
145 int	type;
146 int	form;
147 int	stru;			/* avoid C keyword */
148 int	mode;
149 int	usedefault = 1;		/* for data transfers */
150 int	pdata = -1;		/* for passive mode */
151 sig_atomic_t transflag;
152 off_t	file_size;
153 off_t	byte_count;
154 #if !defined(CMASK) || CMASK == 0
155 #undef CMASK
156 #define CMASK 027
157 #endif
158 int	defumask = CMASK;		/* default umask value */
159 char	tmpline[7];
160 char	*hostname;
161 #ifdef VIRTUAL_HOSTING
162 char	*ftpuser;
163 
164 int	epsvall = 0;
165 
166 static struct ftphost {
167 	struct ftphost	*next;
168 	struct addrinfo *hostinfo;
169 	char		*hostname;
170 	char		*anonuser;
171 	char		*statfile;
172 	char		*welcome;
173 	char		*loginmsg;
174 } *thishost, *firsthost;
175 
176 #endif
177 char	remotehost[MAXHOSTNAMELEN];
178 char	*ident = NULL;
179 
180 static char ttyline[20];
181 char	*tty = ttyline;		/* for klogin */
182 
183 #if !defined(NOPAM)
184 static int	auth_pam __P((struct passwd**, const char*));
185 #endif
186 
187 char	*pid_file = NULL;
188 
189 /*
190  * Timeout intervals for retrying connections
191  * to hosts that don't accept PORT cmds.  This
192  * is a kludge, but given the problems with TCP...
193  */
194 #define	SWAITMAX	90	/* wait at most 90 seconds */
195 #define	SWAITINT	5	/* interval between retries */
196 
197 int	swaitmax = SWAITMAX;
198 int	swaitint = SWAITINT;
199 
200 #ifdef SETPROCTITLE
201 #ifdef OLD_SETPROCTITLE
202 char	**Argv = NULL;		/* pointer to argument vector */
203 char	*LastArgv = NULL;	/* end of argv */
204 #endif /* OLD_SETPROCTITLE */
205 char	proctitle[LINE_MAX];	/* initial part of title */
206 #endif /* SETPROCTITLE */
207 
208 #ifdef SKEY
209 int	pwok = 0;
210 #endif
211 
212 #define LOGCMD(cmd, file) \
213 	if (logging > 1) \
214 	    syslog(LOG_INFO,"%s %s%s", cmd, \
215 		*(file) == '/' ? "" : curdir(), file);
216 #define LOGCMD2(cmd, file1, file2) \
217 	 if (logging > 1) \
218 	    syslog(LOG_INFO,"%s %s%s %s%s", cmd, \
219 		*(file1) == '/' ? "" : curdir(), file1, \
220 		*(file2) == '/' ? "" : curdir(), file2);
221 #define LOGBYTES(cmd, file, cnt) \
222 	if (logging > 1) { \
223 		if (cnt == (off_t)-1) \
224 		    syslog(LOG_INFO,"%s %s%s", cmd, \
225 			*(file) == '/' ? "" : curdir(), file); \
226 		else \
227 		    syslog(LOG_INFO, "%s %s%s = %qd bytes", \
228 			cmd, (*(file) == '/') ? "" : curdir(), file, cnt); \
229 	}
230 
231 #ifdef VIRTUAL_HOSTING
232 static void	 inithosts __P((void));
233 static void	selecthost __P((union sockunion *));
234 #endif
235 static void	 ack __P((char *));
236 static void	 myoob __P((int));
237 static int	 checkuser __P((char *, char *, int));
238 static FILE	*dataconn __P((char *, off_t, char *));
239 static void	 dolog __P((struct sockaddr *));
240 static char	*curdir __P((void));
241 static void	 end_login __P((void));
242 static FILE	*getdatasock __P((char *));
243 static char	*gunique __P((char *));
244 static void	 lostconn __P((int));
245 static int	 receive_data __P((FILE *, FILE *));
246 static void	 send_data __P((FILE *, FILE *, off_t, off_t, int));
247 static struct passwd *
248 		 sgetpwnam __P((char *));
249 static char	*sgetsave __P((char *));
250 static void	 reapchild __P((int));
251 static void      logxfer __P((char *, long, long));
252 
253 static char *
254 curdir()
255 {
256 	static char path[MAXPATHLEN+1+1];	/* path + '/' + '\0' */
257 
258 	if (getcwd(path, sizeof(path)-2) == NULL)
259 		return ("");
260 	if (path[1] != '\0')		/* special case for root dir. */
261 		strcat(path, "/");
262 	/* For guest account, skip / since it's chrooted */
263 	return (guest ? path+1 : path);
264 }
265 
266 int
267 main(argc, argv, envp)
268 	int argc;
269 	char *argv[];
270 	char **envp;
271 {
272 	int addrlen, ch, on = 1, tos;
273 	char *cp, line[LINE_MAX];
274 	FILE *fd;
275 	int error;
276 	char	*bindname = NULL;
277 	int	family = AF_UNSPEC;
278 	int	enable_v4 = 0;
279 
280 	tzset();		/* in case no timezone database in ~ftp */
281 
282 #ifdef OLD_SETPROCTITLE
283 	/*
284 	 *  Save start and extent of argv for setproctitle.
285 	 */
286 	Argv = argv;
287 	while (*envp)
288 		envp++;
289 	LastArgv = envp[-1] + strlen(envp[-1]);
290 #endif /* OLD_SETPROCTITLE */
291 
292 
293 	while ((ch = getopt(argc, argv, "AdlDSURt:T:u:va:p:46")) != -1) {
294 		switch (ch) {
295 		case 'D':
296 			daemon_mode++;
297 			break;
298 
299 		case 'd':
300 			debug++;
301 			break;
302 
303 		case 'l':
304 			logging++;	/* > 1 == extra logging */
305 			break;
306 
307 		case 'R':
308 			paranoid = 0;
309 			break;
310 
311 		case 'S':
312 			stats++;
313 			break;
314 
315 		case 'T':
316 			maxtimeout = atoi(optarg);
317 			if (timeout > maxtimeout)
318 				timeout = maxtimeout;
319 			break;
320 
321 		case 't':
322 			timeout = atoi(optarg);
323 			if (maxtimeout < timeout)
324 				maxtimeout = timeout;
325 			break;
326 
327 		case 'U':
328 			restricted_data_ports = 0;
329 			break;
330 
331 		case 'a':
332 			bindname = optarg;
333 			break;
334 
335 		case 'p':
336 			pid_file = optarg;
337 			break;
338 
339 		case 'u':
340 		    {
341 			long val = 0;
342 
343 			val = strtol(optarg, &optarg, 8);
344 			if (*optarg != '\0' || val < 0)
345 				warnx("bad value for -u");
346 			else
347 				defumask = val;
348 			break;
349 		    }
350 		case 'A':
351 			anon_only = 1;
352 			break;
353 
354 		case 'v':
355 			debug = 1;
356 			break;
357 
358 		case '4':
359 			enable_v4 = 1;
360 			if (family == AF_UNSPEC)
361 				family = AF_INET;
362 			break;
363 
364 		case '6':
365 			family = AF_INET6;
366 			break;
367 
368 		default:
369 			warnx("unknown flag -%c ignored", optopt);
370 			break;
371 		}
372 	}
373 
374 #ifdef VIRTUAL_HOSTING
375 	inithosts();
376 #endif
377 	(void) freopen(_PATH_DEVNULL, "w", stderr);
378 
379 	/*
380 	 * LOG_NDELAY sets up the logging connection immediately,
381 	 * necessary for anonymous ftp's that chroot and can't do it later.
382 	 */
383 	openlog("ftpd", LOG_PID | LOG_NDELAY, LOG_FTP);
384 
385 	if (daemon_mode) {
386 		int ctl_sock, fd;
387 		struct addrinfo hints, *res;
388 
389 		/*
390 		 * Detach from parent.
391 		 */
392 		if (daemon(1, 1) < 0) {
393 			syslog(LOG_ERR, "failed to become a daemon");
394 			exit(1);
395 		}
396 		(void) signal(SIGCHLD, reapchild);
397 		/* init bind_sa */
398 		memset(&hints, 0, sizeof(hints));
399 
400 		hints.ai_family = family == AF_UNSPEC ? AF_INET : family;
401 		hints.ai_socktype = SOCK_STREAM;
402 		hints.ai_protocol = 0;
403 		hints.ai_flags = AI_PASSIVE;
404 		error = getaddrinfo(bindname, "ftp", &hints, &res);
405 		if (error) {
406 			if (family == AF_UNSPEC) {
407 				hints.ai_family = AF_UNSPEC;
408 				error = getaddrinfo(bindname, "ftp", &hints,
409 						    &res);
410 			}
411 		}
412 		if (error) {
413 			syslog(LOG_ERR, "%s", gai_strerror(error));
414 			if (error == EAI_SYSTEM)
415 				syslog(LOG_ERR, "%s", strerror(errno));
416 			exit(1);
417 		}
418 		if (res->ai_addr == NULL) {
419 			syslog(LOG_ERR, "-a %s: getaddrinfo failed", hostname);
420 			exit(1);
421 		} else
422 			family = res->ai_addr->sa_family;
423 		/*
424 		 * Open a socket, bind it to the FTP port, and start
425 		 * listening.
426 		 */
427 		ctl_sock = socket(family, SOCK_STREAM, 0);
428 		if (ctl_sock < 0) {
429 			syslog(LOG_ERR, "control socket: %m");
430 			exit(1);
431 		}
432 		if (setsockopt(ctl_sock, SOL_SOCKET, SO_REUSEADDR,
433 		    (char *)&on, sizeof(on)) < 0)
434 			syslog(LOG_ERR, "control setsockopt: %m");
435 #ifdef IPV6_BINDV6ONLY
436 		if (family == AF_INET6 && enable_v4 == 0) {
437 			if (setsockopt(ctl_sock, IPPROTO_IPV6, IPV6_BINDV6ONLY,
438 				       (char *)&on, sizeof (on)) < 0)
439 				syslog(LOG_ERR,
440 				       "control setsockopt(IPV6_BINDV6ONLY): %m");
441 		}
442 #endif /* IPV6_BINDV6ONLY */
443 		memcpy(&server_addr, res->ai_addr, res->ai_addr->sa_len);
444 		if (bind(ctl_sock, (struct sockaddr *)&server_addr,
445 			 server_addr.su_len) < 0) {
446 			syslog(LOG_ERR, "control bind: %m");
447 			exit(1);
448 		}
449 		if (listen(ctl_sock, 32) < 0) {
450 			syslog(LOG_ERR, "control listen: %m");
451 			exit(1);
452 		}
453 		/*
454 		 * Atomically write process ID
455 		 */
456 		if (pid_file)
457 		{
458 			int fd;
459 			char buf[20];
460 
461 			fd = open(pid_file, O_CREAT | O_WRONLY | O_TRUNC
462 				| O_NONBLOCK | O_EXLOCK, 0644);
463 			if (fd < 0) {
464 				if (errno == EAGAIN)
465 					errx(1, "%s: file locked", pid_file);
466 				else
467 					err(1, "%s", pid_file);
468 			}
469 			snprintf(buf, sizeof(buf),
470 				"%lu\n", (unsigned long) getpid());
471 			if (write(fd, buf, strlen(buf)) < 0)
472 				err(1, "%s: write", pid_file);
473 			/* Leave the pid file open and locked */
474 		}
475 		/*
476 		 * Loop forever accepting connection requests and forking off
477 		 * children to handle them.
478 		 */
479 		while (1) {
480 			addrlen = server_addr.su_len;
481 			fd = accept(ctl_sock, (struct sockaddr *)&his_addr, &addrlen);
482 			if (fork() == 0) {
483 				/* child */
484 				(void) dup2(fd, 0);
485 				(void) dup2(fd, 1);
486 				close(ctl_sock);
487 				break;
488 			}
489 			close(fd);
490 		}
491 	} else {
492 		addrlen = sizeof(his_addr);
493 		if (getpeername(0, (struct sockaddr *)&his_addr, &addrlen) < 0) {
494 			syslog(LOG_ERR, "getpeername (%s): %m",argv[0]);
495 			exit(1);
496 		}
497 	}
498 
499 	(void) signal(SIGCHLD, SIG_IGN);
500 	(void) signal(SIGPIPE, lostconn);
501 	if (signal(SIGURG, myoob) == SIG_ERR)
502 		syslog(LOG_ERR, "signal: %m");
503 
504 	addrlen = sizeof(ctrl_addr);
505 	if (getsockname(0, (struct sockaddr *)&ctrl_addr, &addrlen) < 0) {
506 		syslog(LOG_ERR, "getsockname (%s): %m",argv[0]);
507 		exit(1);
508 	}
509 #ifdef VIRTUAL_HOSTING
510 	/* select our identity from virtual host table */
511 	selecthost(&ctrl_addr);
512 #endif
513 #ifdef IP_TOS
514 	if (ctrl_addr.su_family == AF_INET)
515       {
516 	tos = IPTOS_LOWDELAY;
517 	if (setsockopt(0, IPPROTO_IP, IP_TOS, (char *)&tos, sizeof(int)) < 0)
518 		syslog(LOG_WARNING, "setsockopt (IP_TOS): %m");
519       }
520 #endif
521 	/*
522 	 * Disable Nagle on the control channel so that we don't have to wait
523 	 * for peer's ACK before issuing our next reply.
524 	 */
525 	if (setsockopt(0, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on)) < 0)
526 		syslog(LOG_WARNING, "control setsockopt TCP_NODELAY: %m");
527 
528 	data_source.su_port = htons(ntohs(ctrl_addr.su_port) - 1);
529 
530 	/* set this here so klogin can use it... */
531 	(void)snprintf(ttyline, sizeof(ttyline), "ftp%d", getpid());
532 
533 	/* Try to handle urgent data inline */
534 #ifdef SO_OOBINLINE
535 	if (setsockopt(0, SOL_SOCKET, SO_OOBINLINE, (char *)&on, sizeof(on)) < 0)
536 		syslog(LOG_ERR, "setsockopt: %m");
537 #endif
538 
539 #ifdef	F_SETOWN
540 	if (fcntl(fileno(stdin), F_SETOWN, getpid()) == -1)
541 		syslog(LOG_ERR, "fcntl F_SETOWN: %m");
542 #endif
543 	dolog((struct sockaddr *)&his_addr);
544 	/*
545 	 * Set up default state
546 	 */
547 	data = -1;
548 	type = TYPE_A;
549 	form = FORM_N;
550 	stru = STRU_F;
551 	mode = MODE_S;
552 	tmpline[0] = '\0';
553 
554 	/* If logins are disabled, print out the message. */
555 	if ((fd = fopen(_PATH_NOLOGIN,"r")) != NULL) {
556 		while (fgets(line, sizeof(line), fd) != NULL) {
557 			if ((cp = strchr(line, '\n')) != NULL)
558 				*cp = '\0';
559 			lreply(530, "%s", line);
560 		}
561 		(void) fflush(stdout);
562 		(void) fclose(fd);
563 		reply(530, "System not available.");
564 		exit(0);
565 	}
566 #ifdef VIRTUAL_HOSTING
567 	if ((fd = fopen(thishost->welcome, "r")) != NULL) {
568 #else
569 	if ((fd = fopen(_PATH_FTPWELCOME, "r")) != NULL) {
570 #endif
571 		while (fgets(line, sizeof(line), fd) != NULL) {
572 			if ((cp = strchr(line, '\n')) != NULL)
573 				*cp = '\0';
574 			lreply(220, "%s", line);
575 		}
576 		(void) fflush(stdout);
577 		(void) fclose(fd);
578 		/* reply(220,) must follow */
579 	}
580 #ifndef VIRTUAL_HOSTING
581 	if ((hostname = malloc(MAXHOSTNAMELEN)) == NULL)
582 		fatal("Ran out of memory.");
583 	(void) gethostname(hostname, MAXHOSTNAMELEN - 1);
584 	hostname[MAXHOSTNAMELEN - 1] = '\0';
585 #endif
586 	reply(220, "%s FTP server (%s) ready.", hostname, version);
587 	(void) setjmp(errcatch);
588 	for (;;)
589 		(void) yyparse();
590 	/* NOTREACHED */
591 }
592 
593 static void
594 lostconn(signo)
595 	int signo;
596 {
597 
598 	if (debug)
599 		syslog(LOG_DEBUG, "lost connection");
600 	dologout(1);
601 }
602 
603 #ifdef VIRTUAL_HOSTING
604 /*
605  * read in virtual host tables (if they exist)
606  */
607 
608 static void
609 inithosts()
610 {
611 	FILE *fp;
612 	char *cp;
613 	struct ftphost *hrp, *lhrp;
614 	char line[1024];
615 	struct addrinfo hints, *res, *ai;
616 
617 	/*
618 	 * Fill in the default host information
619 	 */
620 	if (gethostname(line, sizeof(line)) < 0)
621 		line[0] = '\0';
622 	if ((hrp = malloc(sizeof(struct ftphost))) == NULL ||
623 	    (hrp->hostname = strdup(line)) == NULL)
624 		fatal("Ran out of memory.");
625 	hrp->hostinfo = NULL;
626 
627 	memset(&hints, 0, sizeof(hints));
628 	hints.ai_flags = AI_CANONNAME;
629 	hints.ai_family = AF_UNSPEC;
630 	getaddrinfo(hrp->hostname, NULL, &hints, &res);
631 	if (res)
632 		hrp->hostinfo = res;
633 	hrp->statfile = _PATH_FTPDSTATFILE;
634 	hrp->welcome  = _PATH_FTPWELCOME;
635 	hrp->loginmsg = _PATH_FTPLOGINMESG;
636 	hrp->anonuser = "ftp";
637 	hrp->next = NULL;
638 	thishost = firsthost = lhrp = hrp;
639 	if ((fp = fopen(_PATH_FTPHOSTS, "r")) != NULL) {
640 		int addrsize, error, gothost;
641 		void *addr;
642 		struct hostent *hp;
643 
644 		while (fgets(line, sizeof(line), fp) != NULL) {
645 			int	i, hp_error;
646 
647 			if ((cp = strchr(line, '\n')) == NULL) {
648 				/* ignore long lines */
649 				while (fgets(line, sizeof(line), fp) != NULL &&
650 					strchr(line, '\n') == NULL)
651 					;
652 				continue;
653 			}
654 			*cp = '\0';
655 			cp = strtok(line, " \t");
656 			/* skip comments and empty lines */
657 			if (cp == NULL || line[0] == '#')
658 				continue;
659 
660 			hints.ai_flags = 0;
661 			hints.ai_family = AF_UNSPEC;
662 			hints.ai_flags = AI_PASSIVE;
663 			error = getaddrinfo(cp, NULL, &hints, &res);
664 			if (error != NULL)
665 				continue;
666 			for (ai = res; ai != NULL && ai->ai_addr != NULL;
667 			     ai = ai->ai_next) {
668 
669 			gothost = 0;
670 			for (hrp = firsthost; hrp != NULL; hrp = hrp->next) {
671 				struct addrinfo *hi;
672 
673 				for (hi = hrp->hostinfo; hi != NULL;
674 				     hi = hi->ai_next)
675 					if (hi->ai_addrlen == ai->ai_addrlen &&
676 					    memcmp(hi->ai_addr,
677 						   ai->ai_addr,
678 						   ai->ai_addr->sa_len) == 0) {
679 						gothost++;
680 						break;
681 				}
682 				if (gothost)
683 					break;
684 			}
685 			if (hrp == NULL) {
686 				if ((hrp = malloc(sizeof(struct ftphost))) == NULL)
687 					continue;
688 				/* defaults */
689 				hrp->statfile = _PATH_FTPDSTATFILE;
690 				hrp->welcome  = _PATH_FTPWELCOME;
691 				hrp->loginmsg = _PATH_FTPLOGINMESG;
692 				hrp->anonuser = "ftp";
693 				hrp->next     = NULL;
694 				lhrp->next = hrp;
695 				lhrp = hrp;
696 			}
697 			hrp->hostinfo = res;
698 
699 			/*
700 			 * determine hostname to use.
701 			 * force defined name if there is a valid alias
702 			 * otherwise fallback to primary hostname
703 			 */
704 			/* XXX: getaddrinfo() can't do alias check */
705 			switch(hrp->hostinfo->ai_family) {
706 			case AF_INET:
707 				addr = &((struct sockaddr_in *)&hrp->hostinfo->ai_addr)->sin_addr;
708 				addrsize = sizeof(struct sockaddr_in);
709 				break;
710 			case AF_INET6:
711 				addr = &((struct sockaddr_in6 *)&hrp->hostinfo->ai_addr)->sin6_addr;
712 				addrsize = sizeof(struct sockaddr_in6);
713 				break;
714 			default:
715 				/* should not reach here */
716 				if (hrp->hostinfo != NULL)
717 					freeaddrinfo(hrp->hostinfo);
718 				free(hrp);
719 				continue;
720 				/* NOTREACHED */
721 			}
722 			if ((hp = getipnodebyaddr((char*)addr, addrsize,
723 						  hrp->hostinfo->ai_family,
724 						  &hp_error)) != NULL) {
725 				if (strcmp(cp, hp->h_name) != 0) {
726 					if (hp->h_aliases == NULL)
727 						cp = hp->h_name;
728 					else {
729 						i = 0;
730 						while (hp->h_aliases[i] &&
731 						       strcmp(cp, hp->h_aliases[i]) != 0)
732 							++i;
733 						if (hp->h_aliases[i] == NULL)
734 							cp = hp->h_name;
735 					}
736 				}
737 			}
738 			hrp->hostname = strdup(cp);
739 			freehostent(hp);
740 			/* ok, now we now peel off the rest */
741 			i = 0;
742 			while (i < 4 && (cp = strtok(NULL, " \t")) != NULL) {
743 				if (*cp != '-' && (cp = strdup(cp)) != NULL) {
744 					switch (i) {
745 					case 0:	/* anon user permissions */
746 						hrp->anonuser = cp;
747 						break;
748 					case 1: /* statistics file */
749 						hrp->statfile = cp;
750 						break;
751 					case 2: /* welcome message */
752 						hrp->welcome  = cp;
753 						break;
754 					case 3: /* login message */
755 						hrp->loginmsg = cp;
756 						break;
757 					}
758 				}
759 				++i;
760 			}
761 			/* XXX: re-initialization for getaddrinfo() loop */
762 			cp = strtok(line, " \t");
763 		      }
764 		}
765 		(void) fclose(fp);
766 	}
767 }
768 
769 static void
770 selecthost(su)
771 	union sockunion *su;
772 {
773 	struct ftphost	*hrp;
774 	u_int16_t port;
775 #ifdef INET6
776 	struct in6_addr *mapped_in6 = NULL;
777 #endif
778 	struct addrinfo *hi;
779 
780 #ifdef INET6
781 	/*
782 	 * XXX IPv4 mapped IPv6 addr consideraton,
783 	 * specified in rfc2373.
784 	 */
785 	if (su->su_family == AF_INET6 &&
786 	    IN6_IS_ADDR_V4MAPPED(&su->su_sin6.sin6_addr))
787 		mapped_in6 = &su->su_sin6.sin6_addr;
788 #endif
789 
790 	hrp = thishost = firsthost;	/* default */
791 	port = su->su_port;
792 	su->su_port = 0;
793 	while (hrp != NULL) {
794 	    for (hi = hrp->hostinfo; hi != NULL; hi = hi->ai_next) {
795 		if (memcmp(su, hi->ai_addr, hi->ai_addrlen) == 0) {
796 			thishost = hrp;
797 			break;
798 		}
799 #ifdef INET6
800 		/* XXX IPv4 mapped IPv6 addr consideraton */
801 		if (hi->ai_addr->sa_family == AF_INET && mapped_in6 != NULL &&
802 		    (memcmp(&mapped_in6->s6_addr[12],
803 			    &((struct sockaddr_in *)hi->ai_addr)->sin_addr,
804 			    sizeof(struct in_addr)) == 0)) {
805 			thishost = hrp;
806 			break;
807 		}
808 #endif
809 	    }
810 	    hrp = hrp->next;
811 	}
812 	su->su_port = port;
813 	/* setup static variables as appropriate */
814 	hostname = thishost->hostname;
815 	ftpuser = thishost->anonuser;
816 }
817 #endif
818 
819 /*
820  * Helper function for sgetpwnam().
821  */
822 static char *
823 sgetsave(s)
824 	char *s;
825 {
826 	char *new = malloc((unsigned) strlen(s) + 1);
827 
828 	if (new == NULL) {
829 		perror_reply(421, "Local resource failure: malloc");
830 		dologout(1);
831 		/* NOTREACHED */
832 	}
833 	(void) strcpy(new, s);
834 	return (new);
835 }
836 
837 /*
838  * Save the result of a getpwnam.  Used for USER command, since
839  * the data returned must not be clobbered by any other command
840  * (e.g., globbing).
841  */
842 static struct passwd *
843 sgetpwnam(name)
844 	char *name;
845 {
846 	static struct passwd save;
847 	struct passwd *p;
848 
849 	if ((p = getpwnam(name)) == NULL)
850 		return (p);
851 	if (save.pw_name) {
852 		free(save.pw_name);
853 		free(save.pw_passwd);
854 		free(save.pw_gecos);
855 		free(save.pw_dir);
856 		free(save.pw_shell);
857 	}
858 	save = *p;
859 	save.pw_name = sgetsave(p->pw_name);
860 	save.pw_passwd = sgetsave(p->pw_passwd);
861 	save.pw_gecos = sgetsave(p->pw_gecos);
862 	save.pw_dir = sgetsave(p->pw_dir);
863 	save.pw_shell = sgetsave(p->pw_shell);
864 	return (&save);
865 }
866 
867 static int login_attempts;	/* number of failed login attempts */
868 static int askpasswd;		/* had user command, ask for passwd */
869 static char curname[MAXLOGNAME];	/* current USER name */
870 
871 /*
872  * USER command.
873  * Sets global passwd pointer pw if named account exists and is acceptable;
874  * sets askpasswd if a PASS command is expected.  If logged in previously,
875  * need to reset state.  If name is "ftp" or "anonymous", the name is not in
876  * _PATH_FTPUSERS, and ftp account exists, set guest and pw, then just return.
877  * If account doesn't exist, ask for passwd anyway.  Otherwise, check user
878  * requesting login privileges.  Disallow anyone who does not have a standard
879  * shell as returned by getusershell().  Disallow anyone mentioned in the file
880  * _PATH_FTPUSERS to allow people such as root and uucp to be avoided.
881  */
882 void
883 user(name)
884 	char *name;
885 {
886 	char *cp, *shell;
887 
888 	if (logged_in) {
889 		if (guest) {
890 			reply(530, "Can't change user from guest login.");
891 			return;
892 		} else if (dochroot) {
893 			reply(530, "Can't change user from chroot user.");
894 			return;
895 		}
896 		end_login();
897 	}
898 
899 	guest = 0;
900 	if (strcmp(name, "ftp") == 0 || strcmp(name, "anonymous") == 0) {
901 		if (checkuser(_PATH_FTPUSERS, "ftp", 0) ||
902 		    checkuser(_PATH_FTPUSERS, "anonymous", 0))
903 			reply(530, "User %s access denied.", name);
904 #ifdef VIRTUAL_HOSTING
905 		else if ((pw = sgetpwnam(thishost->anonuser)) != NULL) {
906 #else
907 		else if ((pw = sgetpwnam("ftp")) != NULL) {
908 #endif
909 			guest = 1;
910 			askpasswd = 1;
911 			reply(331,
912 			"Guest login ok, send your email address as password.");
913 		} else
914 			reply(530, "User %s unknown.", name);
915 		if (!askpasswd && logging)
916 			syslog(LOG_NOTICE,
917 			    "ANONYMOUS FTP LOGIN REFUSED FROM %s", remotehost);
918 		return;
919 	}
920 	if (anon_only != 0) {
921 		reply(530, "Sorry, only anonymous ftp allowed.");
922 		return;
923 	}
924 
925 	if ((pw = sgetpwnam(name))) {
926 		if ((shell = pw->pw_shell) == NULL || *shell == 0)
927 			shell = _PATH_BSHELL;
928 		while ((cp = getusershell()) != NULL)
929 			if (strcmp(cp, shell) == 0)
930 				break;
931 		endusershell();
932 
933 		if (cp == NULL || checkuser(_PATH_FTPUSERS, name, 1)) {
934 			reply(530, "User %s access denied.", name);
935 			if (logging)
936 				syslog(LOG_NOTICE,
937 				    "FTP LOGIN REFUSED FROM %s, %s",
938 				    remotehost, name);
939 			pw = (struct passwd *) NULL;
940 			return;
941 		}
942 	}
943 	if (logging)
944 		strncpy(curname, name, sizeof(curname)-1);
945 #ifdef SKEY
946 	pwok = skeyaccess(name, NULL, remotehost, remotehost);
947 	reply(331, "%s", skey_challenge(name, pw, pwok));
948 #else
949 	reply(331, "Password required for %s.", name);
950 #endif
951 	askpasswd = 1;
952 	/*
953 	 * Delay before reading passwd after first failed
954 	 * attempt to slow down passwd-guessing programs.
955 	 */
956 	if (login_attempts)
957 		sleep((unsigned) login_attempts);
958 }
959 
960 /*
961  * Check if a user is in the file "fname"
962  */
963 static int
964 checkuser(fname, name, pwset)
965 	char *fname;
966 	char *name;
967 	int pwset;
968 {
969 	FILE *fd;
970 	int found = 0;
971 	char *p, line[BUFSIZ];
972 
973 	if ((fd = fopen(fname, "r")) != NULL) {
974 		while (!found && fgets(line, sizeof(line), fd) != NULL)
975 			if ((p = strchr(line, '\n')) != NULL) {
976 				*p = '\0';
977 				if (line[0] == '#')
978 					continue;
979 				/*
980 				 * if first chr is '@', check group membership
981 				 */
982 				if (line[0] == '@') {
983 					int i = 0;
984 					struct group *grp;
985 
986 					if ((grp = getgrnam(line+1)) == NULL)
987 						continue;
988 					/*
989 					 * Check user's default group
990 					 */
991 					if (pwset && grp->gr_gid == pw->pw_gid)
992 						found = 1;
993 					/*
994 					 * Check supplementary groups
995 					 */
996 					while (!found && grp->gr_mem[i])
997 						found = strcmp(name,
998 							grp->gr_mem[i++])
999 							== 0;
1000 				}
1001 				/*
1002 				 * Otherwise, just check for username match
1003 				 */
1004 				else
1005 					found = strcmp(line, name) == 0;
1006 			}
1007 		(void) fclose(fd);
1008 	}
1009 	return (found);
1010 }
1011 
1012 /*
1013  * Terminate login as previous user, if any, resetting state;
1014  * used when USER command is given or login fails.
1015  */
1016 static void
1017 end_login()
1018 {
1019 
1020 	(void) seteuid((uid_t)0);
1021 	if (logged_in)
1022 		ftpd_logwtmp(ttyline, "", "");
1023 	pw = NULL;
1024 #ifdef	LOGIN_CAP
1025 	setusercontext(NULL, getpwuid(0), (uid_t)0,
1026 		       LOGIN_SETPRIORITY|LOGIN_SETRESOURCES|LOGIN_SETUMASK);
1027 #endif
1028 	logged_in = 0;
1029 	guest = 0;
1030 	dochroot = 0;
1031 }
1032 
1033 #if !defined(NOPAM)
1034 
1035 /*
1036  * the following code is stolen from imap-uw PAM authentication module and
1037  * login.c
1038  */
1039 #define COPY_STRING(s) (s ? strdup(s) : NULL)
1040 
1041 struct cred_t {
1042 	const char *uname;		/* user name */
1043 	const char *pass;		/* password */
1044 };
1045 typedef struct cred_t cred_t;
1046 
1047 static int
1048 auth_conv(int num_msg, const struct pam_message **msg,
1049 	  struct pam_response **resp, void *appdata)
1050 {
1051 	int i;
1052 	cred_t *cred = (cred_t *) appdata;
1053 	struct pam_response *reply =
1054 			malloc(sizeof(struct pam_response) * num_msg);
1055 
1056 	for (i = 0; i < num_msg; i++) {
1057 		switch (msg[i]->msg_style) {
1058 		case PAM_PROMPT_ECHO_ON:	/* assume want user name */
1059 			reply[i].resp_retcode = PAM_SUCCESS;
1060 			reply[i].resp = COPY_STRING(cred->uname);
1061 			/* PAM frees resp. */
1062 			break;
1063 		case PAM_PROMPT_ECHO_OFF:	/* assume want password */
1064 			reply[i].resp_retcode = PAM_SUCCESS;
1065 			reply[i].resp = COPY_STRING(cred->pass);
1066 			/* PAM frees resp. */
1067 			break;
1068 		case PAM_TEXT_INFO:
1069 		case PAM_ERROR_MSG:
1070 			reply[i].resp_retcode = PAM_SUCCESS;
1071 			reply[i].resp = NULL;
1072 			break;
1073 		default:			/* unknown message style */
1074 			free(reply);
1075 			return PAM_CONV_ERR;
1076 		}
1077 	}
1078 
1079 	*resp = reply;
1080 	return PAM_SUCCESS;
1081 }
1082 
1083 /*
1084  * Attempt to authenticate the user using PAM.  Returns 0 if the user is
1085  * authenticated, or 1 if not authenticated.  If some sort of PAM system
1086  * error occurs (e.g., the "/etc/pam.conf" file is missing) then this
1087  * function returns -1.  This can be used as an indication that we should
1088  * fall back to a different authentication mechanism.
1089  */
1090 static int
1091 auth_pam(struct passwd **ppw, const char *pass)
1092 {
1093 	pam_handle_t *pamh = NULL;
1094 	const char *tmpl_user;
1095 	const void *item;
1096 	int rval;
1097 	int e;
1098 	cred_t auth_cred = { (*ppw)->pw_name, pass };
1099 	struct pam_conv conv = { &auth_conv, &auth_cred };
1100 
1101 	e = pam_start("ftpd", (*ppw)->pw_name, &conv, &pamh);
1102 	if (e != PAM_SUCCESS) {
1103 		syslog(LOG_ERR, "pam_start: %s", pam_strerror(pamh, e));
1104 		return -1;
1105 	}
1106 
1107 	e = pam_set_item(pamh, PAM_RHOST, remotehost);
1108 	if (e != PAM_SUCCESS) {
1109 		syslog(LOG_ERR, "pam_set_item(PAM_RHOST): %s",
1110 			pam_strerror(pamh, e));
1111 		return -1;
1112 	}
1113 
1114 	e = pam_authenticate(pamh, 0);
1115 	switch (e) {
1116 	case PAM_SUCCESS:
1117 		/*
1118 		 * With PAM we support the concept of a "template"
1119 		 * user.  The user enters a login name which is
1120 		 * authenticated by PAM, usually via a remote service
1121 		 * such as RADIUS or TACACS+.  If authentication
1122 		 * succeeds, a different but related "template" name
1123 		 * is used for setting the credentials, shell, and
1124 		 * home directory.  The name the user enters need only
1125 		 * exist on the remote authentication server, but the
1126 		 * template name must be present in the local password
1127 		 * database.
1128 		 *
1129 		 * This is supported by two various mechanisms in the
1130 		 * individual modules.  However, from the application's
1131 		 * point of view, the template user is always passed
1132 		 * back as a changed value of the PAM_USER item.
1133 		 */
1134 		if ((e = pam_get_item(pamh, PAM_USER, &item)) ==
1135 		    PAM_SUCCESS) {
1136 			tmpl_user = (const char *) item;
1137 			if (strcmp((*ppw)->pw_name, tmpl_user) != 0)
1138 				*ppw = getpwnam(tmpl_user);
1139 		} else
1140 			syslog(LOG_ERR, "Couldn't get PAM_USER: %s",
1141 			    pam_strerror(pamh, e));
1142 		rval = 0;
1143 		break;
1144 
1145 	case PAM_AUTH_ERR:
1146 	case PAM_USER_UNKNOWN:
1147 	case PAM_MAXTRIES:
1148 		rval = 1;
1149 		break;
1150 
1151 	default:
1152 		syslog(LOG_ERR, "auth_pam: %s", pam_strerror(pamh, e));
1153 		rval = -1;
1154 		break;
1155 	}
1156 
1157 	if ((e = pam_end(pamh, e)) != PAM_SUCCESS) {
1158 		syslog(LOG_ERR, "pam_end: %s", pam_strerror(pamh, e));
1159 		rval = -1;
1160 	}
1161 	return rval;
1162 }
1163 
1164 #endif /* !defined(NOPAM) */
1165 
1166 void
1167 pass(passwd)
1168 	char *passwd;
1169 {
1170 	int rval;
1171 	FILE *fd;
1172 #ifdef	LOGIN_CAP
1173 	login_cap_t *lc = NULL;
1174 #endif
1175 
1176 	if (logged_in || askpasswd == 0) {
1177 		reply(503, "Login with USER first.");
1178 		return;
1179 	}
1180 	askpasswd = 0;
1181 	if (!guest) {		/* "ftp" is only account allowed no password */
1182 		if (pw == NULL) {
1183 			rval = 1;	/* failure below */
1184 			goto skip;
1185 		}
1186 #if !defined(NOPAM)
1187 		rval = auth_pam(&pw, passwd);
1188 		if (rval >= 0)
1189 			goto skip;
1190 #endif
1191 #ifdef SKEY
1192 		if (pwok)
1193 			rval = strcmp(pw->pw_passwd,
1194 			    crypt(passwd, pw->pw_passwd));
1195 		if (rval)
1196 			rval = strcmp(pw->pw_passwd,
1197 			    skey_crypt(passwd, pw->pw_passwd, pw, pwok));
1198 #else
1199 		rval = strcmp(pw->pw_passwd, crypt(passwd, pw->pw_passwd));
1200 #endif
1201 		/* The strcmp does not catch null passwords! */
1202 		if (*pw->pw_passwd == '\0' ||
1203 		    (pw->pw_expire && time(NULL) >= pw->pw_expire))
1204 			rval = 1;	/* failure */
1205 skip:
1206 		/*
1207 		 * If rval == 1, the user failed the authentication check
1208 		 * above.  If rval == 0, either PAM or local authentication
1209 		 * succeeded.
1210 		 */
1211 		if (rval) {
1212 			reply(530, "Login incorrect.");
1213 			if (logging)
1214 				syslog(LOG_NOTICE,
1215 				    "FTP LOGIN FAILED FROM %s, %s",
1216 				    remotehost, curname);
1217 			pw = NULL;
1218 			if (login_attempts++ >= 5) {
1219 				syslog(LOG_NOTICE,
1220 				    "repeated login failures from %s",
1221 				    remotehost);
1222 				exit(0);
1223 			}
1224 			return;
1225 		}
1226 	}
1227 #ifdef SKEY
1228 	pwok = 0;
1229 #endif
1230 	login_attempts = 0;		/* this time successful */
1231 	if (setegid((gid_t)pw->pw_gid) < 0) {
1232 		reply(550, "Can't set gid.");
1233 		return;
1234 	}
1235 	/* May be overridden by login.conf */
1236 	(void) umask(defumask);
1237 #ifdef	LOGIN_CAP
1238 	if ((lc = login_getpwclass(pw)) != NULL) {
1239 		char	remote_ip[MAXHOSTNAMELEN];
1240 
1241 		getnameinfo((struct sockaddr *)&his_addr, his_addr.su_len,
1242 			remote_ip, sizeof(remote_ip) - 1, NULL, 0,
1243 			NI_NUMERICHOST|NI_WITHSCOPEID);
1244 		remote_ip[sizeof(remote_ip) - 1] = 0;
1245 		if (!auth_hostok(lc, remotehost, remote_ip)) {
1246 			syslog(LOG_INFO|LOG_AUTH,
1247 			    "FTP LOGIN FAILED (HOST) as %s: permission denied.",
1248 			    pw->pw_name);
1249 			reply(530, "Permission denied.\n");
1250 			pw = NULL;
1251 			return;
1252 		}
1253 		if (!auth_timeok(lc, time(NULL))) {
1254 			reply(530, "Login not available right now.\n");
1255 			pw = NULL;
1256 			return;
1257 		}
1258 	}
1259 	setusercontext(lc, pw, (uid_t)0,
1260 		LOGIN_SETLOGIN|LOGIN_SETGROUP|LOGIN_SETPRIORITY|
1261 		LOGIN_SETRESOURCES|LOGIN_SETUMASK);
1262 #else
1263 	setlogin(pw->pw_name);
1264 	(void) initgroups(pw->pw_name, pw->pw_gid);
1265 #endif
1266 
1267 	/* open wtmp before chroot */
1268 	ftpd_logwtmp(ttyline, pw->pw_name, remotehost);
1269 	logged_in = 1;
1270 
1271 	if (guest && stats && statfd < 0)
1272 #ifdef VIRTUAL_HOSTING
1273 		if ((statfd = open(thishost->statfile, O_WRONLY|O_APPEND)) < 0)
1274 #else
1275 		if ((statfd = open(_PATH_FTPDSTATFILE, O_WRONLY|O_APPEND)) < 0)
1276 #endif
1277 			stats = 0;
1278 
1279 	dochroot =
1280 #ifdef	LOGIN_CAP	/* Allow login.conf configuration as well */
1281 		login_getcapbool(lc, "ftp-chroot", 0) ||
1282 #endif
1283 		checkuser(_PATH_FTPCHROOT, pw->pw_name, 1);
1284 	if (guest) {
1285 		/*
1286 		 * We MUST do a chdir() after the chroot. Otherwise
1287 		 * the old current directory will be accessible as "."
1288 		 * outside the new root!
1289 		 */
1290 		if (chroot(pw->pw_dir) < 0 || chdir("/") < 0) {
1291 			reply(550, "Can't set guest privileges.");
1292 			goto bad;
1293 		}
1294 	} else if (dochroot) {
1295 		if (chroot(pw->pw_dir) < 0 || chdir("/") < 0) {
1296 			reply(550, "Can't change root.");
1297 			goto bad;
1298 		}
1299 	} else if (chdir(pw->pw_dir) < 0) {
1300 		if (chdir("/") < 0) {
1301 			reply(530, "User %s: can't change directory to %s.",
1302 			    pw->pw_name, pw->pw_dir);
1303 			goto bad;
1304 		} else
1305 			lreply(230, "No directory! Logging in with home=/");
1306 	}
1307 	if (seteuid((uid_t)pw->pw_uid) < 0) {
1308 		reply(550, "Can't set uid.");
1309 		goto bad;
1310 	}
1311 
1312 	/*
1313 	 * Display a login message, if it exists.
1314 	 * N.B. reply(230,) must follow the message.
1315 	 */
1316 #ifdef VIRTUAL_HOSTING
1317 	if ((fd = fopen(thishost->loginmsg, "r")) != NULL) {
1318 #else
1319 	if ((fd = fopen(_PATH_FTPLOGINMESG, "r")) != NULL) {
1320 #endif
1321 		char *cp, line[LINE_MAX];
1322 
1323 		while (fgets(line, sizeof(line), fd) != NULL) {
1324 			if ((cp = strchr(line, '\n')) != NULL)
1325 				*cp = '\0';
1326 			lreply(230, "%s", line);
1327 		}
1328 		(void) fflush(stdout);
1329 		(void) fclose(fd);
1330 	}
1331 	if (guest) {
1332 		if (ident != NULL)
1333 			free(ident);
1334 		ident = strdup(passwd);
1335 		if (ident == NULL)
1336 			fatal("Ran out of memory.");
1337 
1338 		reply(230, "Guest login ok, access restrictions apply.");
1339 #ifdef SETPROCTITLE
1340 #ifdef VIRTUAL_HOSTING
1341 		if (thishost != firsthost)
1342 			snprintf(proctitle, sizeof(proctitle),
1343 				 "%s: anonymous(%s)/%.*s", remotehost, hostname,
1344 				 (int)(sizeof(proctitle) - sizeof(remotehost) -
1345 				 sizeof(": anonymous/")), passwd);
1346 		else
1347 #endif
1348 			snprintf(proctitle, sizeof(proctitle),
1349 				 "%s: anonymous/%.*s", remotehost,
1350 				 (int)(sizeof(proctitle) - sizeof(remotehost) -
1351 				 sizeof(": anonymous/")), passwd);
1352 		setproctitle("%s", proctitle);
1353 #endif /* SETPROCTITLE */
1354 		if (logging)
1355 			syslog(LOG_INFO, "ANONYMOUS FTP LOGIN FROM %s, %s",
1356 			    remotehost, passwd);
1357 	} else {
1358 	    if (dochroot)
1359 		reply(230, "User %s logged in, access restrictions apply.",
1360 			pw->pw_name);
1361 	    else
1362 		reply(230, "User %s logged in.", pw->pw_name);
1363 
1364 #ifdef SETPROCTITLE
1365 		snprintf(proctitle, sizeof(proctitle),
1366 			 "%s: %s", remotehost, pw->pw_name);
1367 		setproctitle("%s", proctitle);
1368 #endif /* SETPROCTITLE */
1369 		if (logging)
1370 			syslog(LOG_INFO, "FTP LOGIN FROM %s as %s",
1371 			    remotehost, pw->pw_name);
1372 	}
1373 #ifdef	LOGIN_CAP
1374 	login_close(lc);
1375 #endif
1376 	return;
1377 bad:
1378 	/* Forget all about it... */
1379 #ifdef	LOGIN_CAP
1380 	login_close(lc);
1381 #endif
1382 	end_login();
1383 }
1384 
1385 void
1386 retrieve(cmd, name)
1387 	char *cmd, *name;
1388 {
1389 	FILE *fin, *dout;
1390 	struct stat st;
1391 	int (*closefunc) __P((FILE *));
1392 	time_t start;
1393 
1394 	if (cmd == 0) {
1395 		fin = fopen(name, "r"), closefunc = fclose;
1396 		st.st_size = 0;
1397 	} else {
1398 		char line[BUFSIZ];
1399 
1400 		(void) snprintf(line, sizeof(line), cmd, name), name = line;
1401 		fin = ftpd_popen(line, "r"), closefunc = ftpd_pclose;
1402 		st.st_size = -1;
1403 		st.st_blksize = BUFSIZ;
1404 	}
1405 	if (fin == NULL) {
1406 		if (errno != 0) {
1407 			perror_reply(550, name);
1408 			if (cmd == 0) {
1409 				LOGCMD("get", name);
1410 			}
1411 		}
1412 		return;
1413 	}
1414 	byte_count = -1;
1415 	if (cmd == 0 && (fstat(fileno(fin), &st) < 0 || !S_ISREG(st.st_mode))) {
1416 		reply(550, "%s: not a plain file.", name);
1417 		goto done;
1418 	}
1419 	if (restart_point) {
1420 		if (type == TYPE_A) {
1421 			off_t i, n;
1422 			int c;
1423 
1424 			n = restart_point;
1425 			i = 0;
1426 			while (i++ < n) {
1427 				if ((c=getc(fin)) == EOF) {
1428 					perror_reply(550, name);
1429 					goto done;
1430 				}
1431 				if (c == '\n')
1432 					i++;
1433 			}
1434 		} else if (lseek(fileno(fin), restart_point, L_SET) < 0) {
1435 			perror_reply(550, name);
1436 			goto done;
1437 		}
1438 	}
1439 	dout = dataconn(name, st.st_size, "w");
1440 	if (dout == NULL)
1441 		goto done;
1442 	time(&start);
1443 	send_data(fin, dout, st.st_blksize, st.st_size,
1444 		  restart_point == 0 && cmd == 0 && S_ISREG(st.st_mode));
1445 	if (cmd == 0 && guest && stats)
1446 		logxfer(name, st.st_size, start);
1447 	(void) fclose(dout);
1448 	data = -1;
1449 	pdata = -1;
1450 done:
1451 	if (cmd == 0)
1452 		LOGBYTES("get", name, byte_count);
1453 	(*closefunc)(fin);
1454 }
1455 
1456 void
1457 store(name, mode, unique)
1458 	char *name, *mode;
1459 	int unique;
1460 {
1461 	FILE *fout, *din;
1462 	struct stat st;
1463 	int (*closefunc) __P((FILE *));
1464 
1465 	if ((unique || guest) && stat(name, &st) == 0 &&
1466 	    (name = gunique(name)) == NULL) {
1467 		LOGCMD(*mode == 'w' ? "put" : "append", name);
1468 		return;
1469 	}
1470 
1471 	if (restart_point)
1472 		mode = "r+";
1473 	fout = fopen(name, mode);
1474 	closefunc = fclose;
1475 	if (fout == NULL) {
1476 		perror_reply(553, name);
1477 		LOGCMD(*mode == 'w' ? "put" : "append", name);
1478 		return;
1479 	}
1480 	byte_count = -1;
1481 	if (restart_point) {
1482 		if (type == TYPE_A) {
1483 			off_t i, n;
1484 			int c;
1485 
1486 			n = restart_point;
1487 			i = 0;
1488 			while (i++ < n) {
1489 				if ((c=getc(fout)) == EOF) {
1490 					perror_reply(550, name);
1491 					goto done;
1492 				}
1493 				if (c == '\n')
1494 					i++;
1495 			}
1496 			/*
1497 			 * We must do this seek to "current" position
1498 			 * because we are changing from reading to
1499 			 * writing.
1500 			 */
1501 			if (fseek(fout, 0L, L_INCR) < 0) {
1502 				perror_reply(550, name);
1503 				goto done;
1504 			}
1505 		} else if (lseek(fileno(fout), restart_point, L_SET) < 0) {
1506 			perror_reply(550, name);
1507 			goto done;
1508 		}
1509 	}
1510 	din = dataconn(name, (off_t)-1, "r");
1511 	if (din == NULL)
1512 		goto done;
1513 	if (receive_data(din, fout) == 0) {
1514 		if (unique)
1515 			reply(226, "Transfer complete (unique file name:%s).",
1516 			    name);
1517 		else
1518 			reply(226, "Transfer complete.");
1519 	}
1520 	(void) fclose(din);
1521 	data = -1;
1522 	pdata = -1;
1523 done:
1524 	LOGBYTES(*mode == 'w' ? "put" : "append", name, byte_count);
1525 	(*closefunc)(fout);
1526 }
1527 
1528 static FILE *
1529 getdatasock(mode)
1530 	char *mode;
1531 {
1532 	int on = 1, s, t, tries;
1533 
1534 	if (data >= 0)
1535 		return (fdopen(data, mode));
1536 	(void) seteuid((uid_t)0);
1537 
1538 	s = socket(data_dest.su_family, SOCK_STREAM, 0);
1539 	if (s < 0)
1540 		goto bad;
1541 	if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR,
1542 	    (char *) &on, sizeof(on)) < 0)
1543 		goto bad;
1544 	/* anchor socket to avoid multi-homing problems */
1545 	data_source = ctrl_addr;
1546 	data_source.su_port = htons(20); /* ftp-data port */
1547 	for (tries = 1; ; tries++) {
1548 		if (bind(s, (struct sockaddr *)&data_source,
1549 		    data_source.su_len) >= 0)
1550 			break;
1551 		if (errno != EADDRINUSE || tries > 10)
1552 			goto bad;
1553 		sleep(tries);
1554 	}
1555 	(void) seteuid((uid_t)pw->pw_uid);
1556 #ifdef IP_TOS
1557 	if (data_source.su_family == AF_INET)
1558       {
1559 	on = IPTOS_THROUGHPUT;
1560 	if (setsockopt(s, IPPROTO_IP, IP_TOS, (char *)&on, sizeof(int)) < 0)
1561 		syslog(LOG_WARNING, "setsockopt (IP_TOS): %m");
1562       }
1563 #endif
1564 #ifdef TCP_NOPUSH
1565 	/*
1566 	 * Turn off push flag to keep sender TCP from sending short packets
1567 	 * at the boundaries of each write().  Should probably do a SO_SNDBUF
1568 	 * to set the send buffer size as well, but that may not be desirable
1569 	 * in heavy-load situations.
1570 	 */
1571 	on = 1;
1572 	if (setsockopt(s, IPPROTO_TCP, TCP_NOPUSH, (char *)&on, sizeof on) < 0)
1573 		syslog(LOG_WARNING, "setsockopt (TCP_NOPUSH): %m");
1574 #endif
1575 #ifdef SO_SNDBUF
1576 	on = 65536;
1577 	if (setsockopt(s, SOL_SOCKET, SO_SNDBUF, (char *)&on, sizeof on) < 0)
1578 		syslog(LOG_WARNING, "setsockopt (SO_SNDBUF): %m");
1579 #endif
1580 
1581 	return (fdopen(s, mode));
1582 bad:
1583 	/* Return the real value of errno (close may change it) */
1584 	t = errno;
1585 	(void) seteuid((uid_t)pw->pw_uid);
1586 	(void) close(s);
1587 	errno = t;
1588 	return (NULL);
1589 }
1590 
1591 static FILE *
1592 dataconn(name, size, mode)
1593 	char *name;
1594 	off_t size;
1595 	char *mode;
1596 {
1597 	char sizebuf[32];
1598 	FILE *file;
1599 	int retry = 0, tos;
1600 
1601 	file_size = size;
1602 	byte_count = 0;
1603 	if (size != (off_t) -1)
1604 		(void) snprintf(sizebuf, sizeof(sizebuf), " (%qd bytes)", size);
1605 	else
1606 		*sizebuf = '\0';
1607 	if (pdata >= 0) {
1608 		union sockunion from;
1609 		int s, fromlen = ctrl_addr.su_len;
1610 		struct timeval timeout;
1611 		fd_set set;
1612 
1613 		FD_ZERO(&set);
1614 		FD_SET(pdata, &set);
1615 
1616 		timeout.tv_usec = 0;
1617 		timeout.tv_sec = 120;
1618 
1619 		if (select(pdata+1, &set, (fd_set *) 0, (fd_set *) 0, &timeout) == 0 ||
1620 		    (s = accept(pdata, (struct sockaddr *) &from, &fromlen)) < 0) {
1621 			reply(425, "Can't open data connection.");
1622 			(void) close(pdata);
1623 			pdata = -1;
1624 			return (NULL);
1625 		}
1626 		(void) close(pdata);
1627 		pdata = s;
1628 #ifdef IP_TOS
1629 		if (from.su_family == AF_INET)
1630 	      {
1631 		tos = IPTOS_THROUGHPUT;
1632 		(void) setsockopt(s, IPPROTO_IP, IP_TOS, (char *)&tos,
1633 		    sizeof(int));
1634 	      }
1635 #endif
1636 		reply(150, "Opening %s mode data connection for '%s'%s.",
1637 		     type == TYPE_A ? "ASCII" : "BINARY", name, sizebuf);
1638 		return (fdopen(pdata, mode));
1639 	}
1640 	if (data >= 0) {
1641 		reply(125, "Using existing data connection for '%s'%s.",
1642 		    name, sizebuf);
1643 		usedefault = 1;
1644 		return (fdopen(data, mode));
1645 	}
1646 	if (usedefault)
1647 		data_dest = his_addr;
1648 	usedefault = 1;
1649 	file = getdatasock(mode);
1650 	if (file == NULL) {
1651 		char hostbuf[BUFSIZ], portbuf[BUFSIZ];
1652 		getnameinfo((struct sockaddr *)&data_source,
1653 			data_source.su_len, hostbuf, sizeof(hostbuf) - 1,
1654 			portbuf, sizeof(portbuf),
1655 			NI_NUMERICHOST|NI_NUMERICSERV|NI_WITHSCOPEID);
1656 		reply(425, "Can't create data socket (%s,%s): %s.",
1657 			hostbuf, portbuf, strerror(errno));
1658 		return (NULL);
1659 	}
1660 	data = fileno(file);
1661 	while (connect(data, (struct sockaddr *)&data_dest,
1662 	    data_dest.su_len) < 0) {
1663 		if (errno == EADDRINUSE && retry < swaitmax) {
1664 			sleep((unsigned) swaitint);
1665 			retry += swaitint;
1666 			continue;
1667 		}
1668 		perror_reply(425, "Can't build data connection");
1669 		(void) fclose(file);
1670 		data = -1;
1671 		return (NULL);
1672 	}
1673 	reply(150, "Opening %s mode data connection for '%s'%s.",
1674 	     type == TYPE_A ? "ASCII" : "BINARY", name, sizebuf);
1675 	return (file);
1676 }
1677 
1678 /*
1679  * Tranfer the contents of "instr" to "outstr" peer using the appropriate
1680  * encapsulation of the data subject to Mode, Structure, and Type.
1681  *
1682  * NB: Form isn't handled.
1683  */
1684 static void
1685 send_data(instr, outstr, blksize, filesize, isreg)
1686 	FILE *instr, *outstr;
1687 	off_t blksize;
1688 	off_t filesize;
1689 	int isreg;
1690 {
1691 	int c, cnt, filefd, netfd;
1692 	char *buf, *bp;
1693 	size_t len;
1694 
1695 	transflag++;
1696 	if (setjmp(urgcatch)) {
1697 		transflag = 0;
1698 		return;
1699 	}
1700 	switch (type) {
1701 
1702 	case TYPE_A:
1703 		while ((c = getc(instr)) != EOF) {
1704 			byte_count++;
1705 			if (c == '\n') {
1706 				if (ferror(outstr))
1707 					goto data_err;
1708 				(void) putc('\r', outstr);
1709 			}
1710 			(void) putc(c, outstr);
1711 		}
1712 		fflush(outstr);
1713 		transflag = 0;
1714 		if (ferror(instr))
1715 			goto file_err;
1716 		if (ferror(outstr))
1717 			goto data_err;
1718 		reply(226, "Transfer complete.");
1719 		return;
1720 
1721 	case TYPE_I:
1722 	case TYPE_L:
1723 		/*
1724 		 * isreg is only set if we are not doing restart and we
1725 		 * are sending a regular file
1726 		 */
1727 		netfd = fileno(outstr);
1728 		filefd = fileno(instr);
1729 
1730 		if (isreg && filesize < (off_t)16 * 1024 * 1024) {
1731 			buf = mmap(0, filesize, PROT_READ, MAP_SHARED, filefd,
1732 				   (off_t)0);
1733 			if (buf == MAP_FAILED) {
1734 				syslog(LOG_WARNING, "mmap(%lu): %m",
1735 				       (unsigned long)filesize);
1736 				goto oldway;
1737 			}
1738 			bp = buf;
1739 			len = filesize;
1740 			do {
1741 				cnt = write(netfd, bp, len);
1742 				len -= cnt;
1743 				bp += cnt;
1744 				if (cnt > 0) byte_count += cnt;
1745 			} while(cnt > 0 && len > 0);
1746 
1747 			transflag = 0;
1748 			munmap(buf, (size_t)filesize);
1749 			if (cnt < 0)
1750 				goto data_err;
1751 			reply(226, "Transfer complete.");
1752 			return;
1753 		}
1754 
1755 oldway:
1756 		if ((buf = malloc((u_int)blksize)) == NULL) {
1757 			transflag = 0;
1758 			perror_reply(451, "Local resource failure: malloc");
1759 			return;
1760 		}
1761 
1762 		while ((cnt = read(filefd, buf, (u_int)blksize)) > 0 &&
1763 		    write(netfd, buf, cnt) == cnt)
1764 			byte_count += cnt;
1765 		transflag = 0;
1766 		(void)free(buf);
1767 		if (cnt != 0) {
1768 			if (cnt < 0)
1769 				goto file_err;
1770 			goto data_err;
1771 		}
1772 		reply(226, "Transfer complete.");
1773 		return;
1774 	default:
1775 		transflag = 0;
1776 		reply(550, "Unimplemented TYPE %d in send_data", type);
1777 		return;
1778 	}
1779 
1780 data_err:
1781 	transflag = 0;
1782 	perror_reply(426, "Data connection");
1783 	return;
1784 
1785 file_err:
1786 	transflag = 0;
1787 	perror_reply(551, "Error on input file");
1788 }
1789 
1790 /*
1791  * Transfer data from peer to "outstr" using the appropriate encapulation of
1792  * the data subject to Mode, Structure, and Type.
1793  *
1794  * N.B.: Form isn't handled.
1795  */
1796 static int
1797 receive_data(instr, outstr)
1798 	FILE *instr, *outstr;
1799 {
1800 	int c;
1801 	int cnt, bare_lfs;
1802 	char buf[BUFSIZ];
1803 
1804 	transflag++;
1805 	if (setjmp(urgcatch)) {
1806 		transflag = 0;
1807 		return (-1);
1808 	}
1809 
1810 	bare_lfs = 0;
1811 
1812 	switch (type) {
1813 
1814 	case TYPE_I:
1815 	case TYPE_L:
1816 		while ((cnt = read(fileno(instr), buf, sizeof(buf))) > 0) {
1817 			if (write(fileno(outstr), buf, cnt) != cnt)
1818 				goto file_err;
1819 			byte_count += cnt;
1820 		}
1821 		if (cnt < 0)
1822 			goto data_err;
1823 		transflag = 0;
1824 		return (0);
1825 
1826 	case TYPE_E:
1827 		reply(553, "TYPE E not implemented.");
1828 		transflag = 0;
1829 		return (-1);
1830 
1831 	case TYPE_A:
1832 		while ((c = getc(instr)) != EOF) {
1833 			byte_count++;
1834 			if (c == '\n')
1835 				bare_lfs++;
1836 			while (c == '\r') {
1837 				if (ferror(outstr))
1838 					goto data_err;
1839 				if ((c = getc(instr)) != '\n') {
1840 					(void) putc ('\r', outstr);
1841 					if (c == '\0' || c == EOF)
1842 						goto contin2;
1843 				}
1844 			}
1845 			(void) putc(c, outstr);
1846 	contin2:	;
1847 		}
1848 		fflush(outstr);
1849 		if (ferror(instr))
1850 			goto data_err;
1851 		if (ferror(outstr))
1852 			goto file_err;
1853 		transflag = 0;
1854 		if (bare_lfs) {
1855 			lreply(226,
1856 		"WARNING! %d bare linefeeds received in ASCII mode",
1857 			    bare_lfs);
1858 		(void)printf("   File may not have transferred correctly.\r\n");
1859 		}
1860 		return (0);
1861 	default:
1862 		reply(550, "Unimplemented TYPE %d in receive_data", type);
1863 		transflag = 0;
1864 		return (-1);
1865 	}
1866 
1867 data_err:
1868 	transflag = 0;
1869 	perror_reply(426, "Data Connection");
1870 	return (-1);
1871 
1872 file_err:
1873 	transflag = 0;
1874 	perror_reply(452, "Error writing file");
1875 	return (-1);
1876 }
1877 
1878 void
1879 statfilecmd(filename)
1880 	char *filename;
1881 {
1882 	FILE *fin;
1883 	int c;
1884 	char line[LINE_MAX];
1885 
1886 	(void)snprintf(line, sizeof(line), _PATH_LS " -lgA %s", filename);
1887 	fin = ftpd_popen(line, "r");
1888 	lreply(211, "status of %s:", filename);
1889 	while ((c = getc(fin)) != EOF) {
1890 		if (c == '\n') {
1891 			if (ferror(stdout)){
1892 				perror_reply(421, "control connection");
1893 				(void) ftpd_pclose(fin);
1894 				dologout(1);
1895 				/* NOTREACHED */
1896 			}
1897 			if (ferror(fin)) {
1898 				perror_reply(551, filename);
1899 				(void) ftpd_pclose(fin);
1900 				return;
1901 			}
1902 			(void) putc('\r', stdout);
1903 		}
1904 		(void) putc(c, stdout);
1905 	}
1906 	(void) ftpd_pclose(fin);
1907 	reply(211, "End of Status");
1908 }
1909 
1910 void
1911 statcmd()
1912 {
1913 	union sockunion *su;
1914 	u_char *a, *p;
1915 	char hname[INET6_ADDRSTRLEN];
1916 	int ispassive;
1917 
1918 	lreply(211, "%s FTP server status:", hostname, version);
1919 	printf("     %s\r\n", version);
1920 	printf("     Connected to %s", remotehost);
1921 	if (!getnameinfo((struct sockaddr *)&his_addr, his_addr.su_len,
1922 			 hname, sizeof(hname) - 1, NULL, 0,
1923 			 NI_NUMERICHOST|NI_WITHSCOPEID)) {
1924 		if (strcmp(hname, remotehost) != 0)
1925 			printf(" (%s)", hname);
1926 	}
1927 	printf("\r\n");
1928 	if (logged_in) {
1929 		if (guest)
1930 			printf("     Logged in anonymously\r\n");
1931 		else
1932 			printf("     Logged in as %s\r\n", pw->pw_name);
1933 	} else if (askpasswd)
1934 		printf("     Waiting for password\r\n");
1935 	else
1936 		printf("     Waiting for user name\r\n");
1937 	printf("     TYPE: %s", typenames[type]);
1938 	if (type == TYPE_A || type == TYPE_E)
1939 		printf(", FORM: %s", formnames[form]);
1940 	if (type == TYPE_L)
1941 #if NBBY == 8
1942 		printf(" %d", NBBY);
1943 #else
1944 		printf(" %d", bytesize);	/* need definition! */
1945 #endif
1946 	printf("; STRUcture: %s; transfer MODE: %s\r\n",
1947 	    strunames[stru], modenames[mode]);
1948 	if (data != -1)
1949 		printf("     Data connection open\r\n");
1950 	else if (pdata != -1) {
1951 		ispassive = 1;
1952 		su = &pasv_addr;
1953 		goto printaddr;
1954 	} else if (usedefault == 0) {
1955 		ispassive = 0;
1956 		su = &data_dest;
1957 printaddr:
1958 #define UC(b) (((int) b) & 0xff)
1959 		if (epsvall) {
1960 			printf("     EPSV only mode (EPSV ALL)\r\n");
1961 			goto epsvonly;
1962 		}
1963 
1964 		/* PORT/PASV */
1965 		if (su->su_family == AF_INET) {
1966 			a = (u_char *) &su->su_sin.sin_addr;
1967 			p = (u_char *) &su->su_sin.sin_port;
1968 			printf("     %s (%d,%d,%d,%d,%d,%d)\r\n",
1969 				ispassive ? "PASV" : "PORT",
1970 				UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]),
1971 				UC(p[0]), UC(p[1]));
1972 		}
1973 
1974 		/* LPRT/LPSV */
1975 	    {
1976 		int alen, af, i;
1977 
1978 		switch (su->su_family) {
1979 		case AF_INET:
1980 			a = (u_char *) &su->su_sin.sin_addr;
1981 			p = (u_char *) &su->su_sin.sin_port;
1982 			alen = sizeof(su->su_sin.sin_addr);
1983 			af = 4;
1984 			break;
1985 		case AF_INET6:
1986 			a = (u_char *) &su->su_sin6.sin6_addr;
1987 			p = (u_char *) &su->su_sin6.sin6_port;
1988 			alen = sizeof(su->su_sin6.sin6_addr);
1989 			af = 6;
1990 			break;
1991 		default:
1992 			af = 0;
1993 			break;
1994 		}
1995 		if (af) {
1996 			printf("     %s (%d,%d,", ispassive ? "LPSV" : "LPRT",
1997 				af, alen);
1998 			for (i = 0; i < alen; i++)
1999 				printf("%d,", UC(a[i]));
2000 			printf("%d,%d,%d)\r\n", 2, UC(p[0]), UC(p[1]));
2001 		}
2002 	    }
2003 
2004 epsvonly:;
2005 		/* EPRT/EPSV */
2006 	    {
2007 		int af;
2008 
2009 		switch (su->su_family) {
2010 		case AF_INET:
2011 			af = 1;
2012 			break;
2013 		case AF_INET6:
2014 			af = 2;
2015 			break;
2016 		default:
2017 			af = 0;
2018 			break;
2019 		}
2020 		if (af) {
2021 			if (!getnameinfo((struct sockaddr *)su, su->su_len,
2022 					hname, sizeof(hname) - 1, NULL, 0,
2023 					NI_NUMERICHOST)) {
2024 				printf("     %s |%d|%s|%d|\r\n",
2025 					ispassive ? "EPSV" : "EPRT",
2026 					af, hname, htons(su->su_port));
2027 			}
2028 		}
2029 	    }
2030 #undef UC
2031 	} else
2032 		printf("     No data connection\r\n");
2033 	reply(211, "End of status");
2034 }
2035 
2036 void
2037 fatal(s)
2038 	char *s;
2039 {
2040 
2041 	reply(451, "Error in server: %s\n", s);
2042 	reply(221, "Closing connection due to server error.");
2043 	dologout(0);
2044 	/* NOTREACHED */
2045 }
2046 
2047 void
2048 #if __STDC__
2049 reply(int n, const char *fmt, ...)
2050 #else
2051 reply(n, fmt, va_alist)
2052 	int n;
2053 	char *fmt;
2054         va_dcl
2055 #endif
2056 {
2057 	va_list ap;
2058 #if __STDC__
2059 	va_start(ap, fmt);
2060 #else
2061 	va_start(ap);
2062 #endif
2063 	(void)printf("%d ", n);
2064 	(void)vprintf(fmt, ap);
2065 	(void)printf("\r\n");
2066 	(void)fflush(stdout);
2067 	if (debug) {
2068 		syslog(LOG_DEBUG, "<--- %d ", n);
2069 		vsyslog(LOG_DEBUG, fmt, ap);
2070 	}
2071 }
2072 
2073 void
2074 #if __STDC__
2075 lreply(int n, const char *fmt, ...)
2076 #else
2077 lreply(n, fmt, va_alist)
2078 	int n;
2079 	char *fmt;
2080         va_dcl
2081 #endif
2082 {
2083 	va_list ap;
2084 #if __STDC__
2085 	va_start(ap, fmt);
2086 #else
2087 	va_start(ap);
2088 #endif
2089 	(void)printf("%d- ", n);
2090 	(void)vprintf(fmt, ap);
2091 	(void)printf("\r\n");
2092 	(void)fflush(stdout);
2093 	if (debug) {
2094 		syslog(LOG_DEBUG, "<--- %d- ", n);
2095 		vsyslog(LOG_DEBUG, fmt, ap);
2096 	}
2097 }
2098 
2099 static void
2100 ack(s)
2101 	char *s;
2102 {
2103 
2104 	reply(250, "%s command successful.", s);
2105 }
2106 
2107 void
2108 nack(s)
2109 	char *s;
2110 {
2111 
2112 	reply(502, "%s command not implemented.", s);
2113 }
2114 
2115 /* ARGSUSED */
2116 void
2117 yyerror(s)
2118 	char *s;
2119 {
2120 	char *cp;
2121 
2122 	if ((cp = strchr(cbuf,'\n')))
2123 		*cp = '\0';
2124 	reply(500, "'%s': command not understood.", cbuf);
2125 }
2126 
2127 void
2128 delete(name)
2129 	char *name;
2130 {
2131 	struct stat st;
2132 
2133 	LOGCMD("delete", name);
2134 	if (stat(name, &st) < 0) {
2135 		perror_reply(550, name);
2136 		return;
2137 	}
2138 	if ((st.st_mode&S_IFMT) == S_IFDIR) {
2139 		if (rmdir(name) < 0) {
2140 			perror_reply(550, name);
2141 			return;
2142 		}
2143 		goto done;
2144 	}
2145 	if (unlink(name) < 0) {
2146 		perror_reply(550, name);
2147 		return;
2148 	}
2149 done:
2150 	ack("DELE");
2151 }
2152 
2153 void
2154 cwd(path)
2155 	char *path;
2156 {
2157 
2158 	if (chdir(path) < 0)
2159 		perror_reply(550, path);
2160 	else
2161 		ack("CWD");
2162 }
2163 
2164 void
2165 makedir(name)
2166 	char *name;
2167 {
2168 
2169 	LOGCMD("mkdir", name);
2170 	if (mkdir(name, 0777) < 0)
2171 		perror_reply(550, name);
2172 	else
2173 		reply(257, "MKD command successful.");
2174 }
2175 
2176 void
2177 removedir(name)
2178 	char *name;
2179 {
2180 
2181 	LOGCMD("rmdir", name);
2182 	if (rmdir(name) < 0)
2183 		perror_reply(550, name);
2184 	else
2185 		ack("RMD");
2186 }
2187 
2188 void
2189 pwd()
2190 {
2191 	char path[MAXPATHLEN + 1];
2192 
2193 	if (getwd(path) == (char *)NULL)
2194 		reply(550, "%s.", path);
2195 	else
2196 		reply(257, "\"%s\" is current directory.", path);
2197 }
2198 
2199 char *
2200 renamefrom(name)
2201 	char *name;
2202 {
2203 	struct stat st;
2204 
2205 	if (stat(name, &st) < 0) {
2206 		perror_reply(550, name);
2207 		return ((char *)0);
2208 	}
2209 	reply(350, "File exists, ready for destination name");
2210 	return (name);
2211 }
2212 
2213 void
2214 renamecmd(from, to)
2215 	char *from, *to;
2216 {
2217 	struct stat st;
2218 
2219 	LOGCMD2("rename", from, to);
2220 
2221 	if (guest && (stat(to, &st) == 0)) {
2222 		reply(550, "%s: permission denied", to);
2223 		return;
2224 	}
2225 
2226 	if (rename(from, to) < 0)
2227 		perror_reply(550, "rename");
2228 	else
2229 		ack("RNTO");
2230 }
2231 
2232 static void
2233 dolog(who)
2234 	struct sockaddr *who;
2235 {
2236 	int error;
2237 
2238 	realhostname_sa(remotehost, sizeof(remotehost) - 1, who, who->sa_len);
2239 
2240 #ifdef SETPROCTITLE
2241 #ifdef VIRTUAL_HOSTING
2242 	if (thishost != firsthost)
2243 		snprintf(proctitle, sizeof(proctitle), "%s: connected (to %s)",
2244 			 remotehost, hostname);
2245 	else
2246 #endif
2247 		snprintf(proctitle, sizeof(proctitle), "%s: connected",
2248 			 remotehost);
2249 	setproctitle("%s", proctitle);
2250 #endif /* SETPROCTITLE */
2251 
2252 	if (logging) {
2253 #ifdef VIRTUAL_HOSTING
2254 		if (thishost != firsthost)
2255 			syslog(LOG_INFO, "connection from %s (to %s)",
2256 			       remotehost, hostname);
2257 		else
2258 #endif
2259 		{
2260 			char	who_name[MAXHOSTNAMELEN];
2261 
2262 			error = getnameinfo(who, who->sa_len,
2263 					    who_name, sizeof(who_name) - 1,
2264 					    NULL, 0,
2265 					    NI_NUMERICHOST|NI_WITHSCOPEID);
2266 			syslog(LOG_INFO, "connection from %s (%s)", remotehost,
2267 			       error == 0 ? who_name : "");
2268 		}
2269 	}
2270 }
2271 
2272 /*
2273  * Record logout in wtmp file
2274  * and exit with supplied status.
2275  */
2276 void
2277 dologout(status)
2278 	int status;
2279 {
2280 	/*
2281 	 * Prevent reception of SIGURG from resulting in a resumption
2282 	 * back to the main program loop.
2283 	 */
2284 	transflag = 0;
2285 
2286 	if (logged_in) {
2287 		(void) seteuid((uid_t)0);
2288 		ftpd_logwtmp(ttyline, "", "");
2289 	}
2290 	/* beware of flushing buffers after a SIGPIPE */
2291 	_exit(status);
2292 }
2293 
2294 static void
2295 myoob(signo)
2296 	int signo;
2297 {
2298 	char *cp;
2299 
2300 	/* only process if transfer occurring */
2301 	if (!transflag)
2302 		return;
2303 	cp = tmpline;
2304 	if (getline(cp, 7, stdin) == NULL) {
2305 		reply(221, "You could at least say goodbye.");
2306 		dologout(0);
2307 	}
2308 	upper(cp);
2309 	if (strcmp(cp, "ABOR\r\n") == 0) {
2310 		tmpline[0] = '\0';
2311 		reply(426, "Transfer aborted. Data connection closed.");
2312 		reply(226, "Abort successful");
2313 		longjmp(urgcatch, 1);
2314 	}
2315 	if (strcmp(cp, "STAT\r\n") == 0) {
2316 		tmpline[0] = '\0';
2317 		if (file_size != (off_t) -1)
2318 			reply(213, "Status: %qd of %qd bytes transferred",
2319 			    byte_count, file_size);
2320 		else
2321 			reply(213, "Status: %qd bytes transferred", byte_count);
2322 	}
2323 }
2324 
2325 /*
2326  * Note: a response of 425 is not mentioned as a possible response to
2327  *	the PASV command in RFC959. However, it has been blessed as
2328  *	a legitimate response by Jon Postel in a telephone conversation
2329  *	with Rick Adams on 25 Jan 89.
2330  */
2331 void
2332 passive()
2333 {
2334 	int len;
2335 	char *p, *a;
2336 
2337 	if (pdata >= 0)		/* close old port if one set */
2338 		close(pdata);
2339 
2340 	pdata = socket(ctrl_addr.su_family, SOCK_STREAM, 0);
2341 	if (pdata < 0) {
2342 		perror_reply(425, "Can't open passive connection");
2343 		return;
2344 	}
2345 
2346 	(void) seteuid((uid_t)0);
2347 
2348 #ifdef IP_PORTRANGE
2349 	if (ctrl_addr.su_family == AF_INET) {
2350 	    int on = restricted_data_ports ? IP_PORTRANGE_HIGH
2351 					   : IP_PORTRANGE_DEFAULT;
2352 
2353 	    if (setsockopt(pdata, IPPROTO_IP, IP_PORTRANGE,
2354 			    (char *)&on, sizeof(on)) < 0)
2355 		    goto pasv_error;
2356 	}
2357 #endif
2358 #ifdef IPV6_PORTRANGE
2359 	if (ctrl_addr.su_family == AF_INET6) {
2360 	    int on = restricted_data_ports ? IPV6_PORTRANGE_HIGH
2361 					   : IPV6_PORTRANGE_DEFAULT;
2362 
2363 	    if (setsockopt(pdata, IPPROTO_IPV6, IPV6_PORTRANGE,
2364 			    (char *)&on, sizeof(on)) < 0)
2365 		    goto pasv_error;
2366 	}
2367 #endif
2368 
2369 	pasv_addr = ctrl_addr;
2370 	pasv_addr.su_port = 0;
2371 	if (bind(pdata, (struct sockaddr *)&pasv_addr, pasv_addr.su_len) < 0)
2372 		goto pasv_error;
2373 
2374 	(void) seteuid((uid_t)pw->pw_uid);
2375 
2376 	len = sizeof(pasv_addr);
2377 	if (getsockname(pdata, (struct sockaddr *) &pasv_addr, &len) < 0)
2378 		goto pasv_error;
2379 	if (listen(pdata, 1) < 0)
2380 		goto pasv_error;
2381 	if (pasv_addr.su_family == AF_INET)
2382 		a = (char *) &pasv_addr.su_sin.sin_addr;
2383 	else if (pasv_addr.su_family == AF_INET6 &&
2384 		 IN6_IS_ADDR_V4MAPPED(&pasv_addr.su_sin6.sin6_addr))
2385 		a = (char *) &pasv_addr.su_sin6.sin6_addr.s6_addr[12];
2386 	else
2387 		goto pasv_error;
2388 
2389 	p = (char *) &pasv_addr.su_port;
2390 
2391 #define UC(b) (((int) b) & 0xff)
2392 
2393 	reply(227, "Entering Passive Mode (%d,%d,%d,%d,%d,%d)", UC(a[0]),
2394 		UC(a[1]), UC(a[2]), UC(a[3]), UC(p[0]), UC(p[1]));
2395 	return;
2396 
2397 pasv_error:
2398 	(void) seteuid((uid_t)pw->pw_uid);
2399 	(void) close(pdata);
2400 	pdata = -1;
2401 	perror_reply(425, "Can't open passive connection");
2402 	return;
2403 }
2404 
2405 /*
2406  * Long Passive defined in RFC 1639.
2407  *     228 Entering Long Passive Mode
2408  *         (af, hal, h1, h2, h3,..., pal, p1, p2...)
2409  */
2410 
2411 void
2412 long_passive(cmd, pf)
2413 	char *cmd;
2414 	int pf;
2415 {
2416 	int len;
2417 	char *p, *a;
2418 
2419 	if (pdata >= 0)		/* close old port if one set */
2420 		close(pdata);
2421 
2422 	if (pf != PF_UNSPEC) {
2423 		if (ctrl_addr.su_family != pf) {
2424 			switch (ctrl_addr.su_family) {
2425 			case AF_INET:
2426 				pf = 1;
2427 				break;
2428 			case AF_INET6:
2429 				pf = 2;
2430 				break;
2431 			default:
2432 				pf = 0;
2433 				break;
2434 			}
2435 			/*
2436 			 * XXX
2437 			 * only EPRT/EPSV ready clients will understand this
2438 			 */
2439 			if (strcmp(cmd, "EPSV") == 0 && pf) {
2440 				reply(522, "Network protocol mismatch, "
2441 					"use (%d)", pf);
2442 			} else
2443 				reply(501, "Network protocol mismatch"); /*XXX*/
2444 
2445 			return;
2446 		}
2447 	}
2448 
2449 	pdata = socket(ctrl_addr.su_family, SOCK_STREAM, 0);
2450 	if (pdata < 0) {
2451 		perror_reply(425, "Can't open passive connection");
2452 		return;
2453 	}
2454 
2455 	(void) seteuid((uid_t)0);
2456 
2457 	pasv_addr = ctrl_addr;
2458 	pasv_addr.su_port = 0;
2459 	len = pasv_addr.su_len;
2460 
2461 #ifdef IP_PORTRANGE
2462 	if (ctrl_addr.su_family == AF_INET) {
2463 	    int on = restricted_data_ports ? IP_PORTRANGE_HIGH
2464 					   : IP_PORTRANGE_DEFAULT;
2465 
2466 	    if (setsockopt(pdata, IPPROTO_IP, IP_PORTRANGE,
2467 			    (char *)&on, sizeof(on)) < 0)
2468 		    goto pasv_error;
2469 	}
2470 #endif
2471 #ifdef IPV6_PORTRANGE
2472 	if (ctrl_addr.su_family == AF_INET6) {
2473 	    int on = restricted_data_ports ? IPV6_PORTRANGE_HIGH
2474 					   : IPV6_PORTRANGE_DEFAULT;
2475 
2476 	    if (setsockopt(pdata, IPPROTO_IPV6, IPV6_PORTRANGE,
2477 			    (char *)&on, sizeof(on)) < 0)
2478 		    goto pasv_error;
2479 	}
2480 #endif
2481 
2482 	if (bind(pdata, (struct sockaddr *)&pasv_addr, len) < 0)
2483 		goto pasv_error;
2484 
2485 	(void) seteuid((uid_t)pw->pw_uid);
2486 
2487 	if (getsockname(pdata, (struct sockaddr *) &pasv_addr, &len) < 0)
2488 		goto pasv_error;
2489 	if (listen(pdata, 1) < 0)
2490 		goto pasv_error;
2491 
2492 #define UC(b) (((int) b) & 0xff)
2493 
2494 	if (strcmp(cmd, "LPSV") == 0) {
2495 		p = (char *)&pasv_addr.su_port;
2496 		switch (pasv_addr.su_family) {
2497 		case AF_INET:
2498 			a = (char *) &pasv_addr.su_sin.sin_addr;
2499 		v4_reply:
2500 			reply(228,
2501 "Entering Long Passive Mode (%d,%d,%d,%d,%d,%d,%d,%d,%d)",
2502 			      4, 4, UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]),
2503 			      2, UC(p[0]), UC(p[1]));
2504 			return;
2505 		case AF_INET6:
2506 			if (IN6_IS_ADDR_V4MAPPED(&pasv_addr.su_sin6.sin6_addr)) {
2507 				a = (char *) &pasv_addr.su_sin6.sin6_addr.s6_addr[12];
2508 				goto v4_reply;
2509 			}
2510 			a = (char *) &pasv_addr.su_sin6.sin6_addr;
2511 			reply(228,
2512 "Entering Long Passive Mode "
2513 "(%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d)",
2514 			      6, 16, UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]),
2515 			      UC(a[4]), UC(a[5]), UC(a[6]), UC(a[7]),
2516 			      UC(a[8]), UC(a[9]), UC(a[10]), UC(a[11]),
2517 			      UC(a[12]), UC(a[13]), UC(a[14]), UC(a[15]),
2518 			      2, UC(p[0]), UC(p[1]));
2519 			return;
2520 		}
2521 	} else if (strcmp(cmd, "EPSV") == 0) {
2522 		switch (pasv_addr.su_family) {
2523 		case AF_INET:
2524 		case AF_INET6:
2525 			reply(229, "Entering Extended Passive Mode (|||%d|)",
2526 				ntohs(pasv_addr.su_port));
2527 			return;
2528 		}
2529 	} else {
2530 		/* more proper error code? */
2531 	}
2532 
2533 pasv_error:
2534 	(void) seteuid((uid_t)pw->pw_uid);
2535 	(void) close(pdata);
2536 	pdata = -1;
2537 	perror_reply(425, "Can't open passive connection");
2538 	return;
2539 }
2540 
2541 /*
2542  * Generate unique name for file with basename "local".
2543  * The file named "local" is already known to exist.
2544  * Generates failure reply on error.
2545  */
2546 static char *
2547 gunique(local)
2548 	char *local;
2549 {
2550 	static char new[MAXPATHLEN];
2551 	struct stat st;
2552 	int count;
2553 	char *cp;
2554 
2555 	cp = strrchr(local, '/');
2556 	if (cp)
2557 		*cp = '\0';
2558 	if (stat(cp ? local : ".", &st) < 0) {
2559 		perror_reply(553, cp ? local : ".");
2560 		return ((char *) 0);
2561 	}
2562 	if (cp)
2563 		*cp = '/';
2564 	/* -4 is for the .nn<null> we put on the end below */
2565 	(void) snprintf(new, sizeof(new) - 4, "%s", local);
2566 	cp = new + strlen(new);
2567 	*cp++ = '.';
2568 	for (count = 1; count < 100; count++) {
2569 		(void)sprintf(cp, "%d", count);
2570 		if (stat(new, &st) < 0)
2571 			return (new);
2572 	}
2573 	reply(452, "Unique file name cannot be created.");
2574 	return (NULL);
2575 }
2576 
2577 /*
2578  * Format and send reply containing system error number.
2579  */
2580 void
2581 perror_reply(code, string)
2582 	int code;
2583 	char *string;
2584 {
2585 
2586 	reply(code, "%s: %s.", string, strerror(errno));
2587 }
2588 
2589 static char *onefile[] = {
2590 	"",
2591 	0
2592 };
2593 
2594 void
2595 send_file_list(whichf)
2596 	char *whichf;
2597 {
2598 	struct stat st;
2599 	DIR *dirp = NULL;
2600 	struct dirent *dir;
2601 	FILE *dout = NULL;
2602 	char **dirlist, *dirname;
2603 	int simple = 0;
2604 	int freeglob = 0;
2605 	glob_t gl;
2606 
2607 	if (strpbrk(whichf, "~{[*?") != NULL) {
2608 		int flags = GLOB_BRACE|GLOB_NOCHECK|GLOB_QUOTE|GLOB_TILDE;
2609 
2610 		memset(&gl, 0, sizeof(gl));
2611 		freeglob = 1;
2612 		if (glob(whichf, flags, 0, &gl)) {
2613 			reply(550, "not found");
2614 			goto out;
2615 		} else if (gl.gl_pathc == 0) {
2616 			errno = ENOENT;
2617 			perror_reply(550, whichf);
2618 			goto out;
2619 		}
2620 		dirlist = gl.gl_pathv;
2621 	} else {
2622 		onefile[0] = whichf;
2623 		dirlist = onefile;
2624 		simple = 1;
2625 	}
2626 
2627 	if (setjmp(urgcatch)) {
2628 		transflag = 0;
2629 		goto out;
2630 	}
2631 	while ((dirname = *dirlist++)) {
2632 		if (stat(dirname, &st) < 0) {
2633 			/*
2634 			 * If user typed "ls -l", etc, and the client
2635 			 * used NLST, do what the user meant.
2636 			 */
2637 			if (dirname[0] == '-' && *dirlist == NULL &&
2638 			    transflag == 0) {
2639 				retrieve(_PATH_LS " %s", dirname);
2640 				goto out;
2641 			}
2642 			perror_reply(550, whichf);
2643 			if (dout != NULL) {
2644 				(void) fclose(dout);
2645 				transflag = 0;
2646 				data = -1;
2647 				pdata = -1;
2648 			}
2649 			goto out;
2650 		}
2651 
2652 		if (S_ISREG(st.st_mode)) {
2653 			if (dout == NULL) {
2654 				dout = dataconn("file list", (off_t)-1, "w");
2655 				if (dout == NULL)
2656 					goto out;
2657 				transflag++;
2658 			}
2659 			fprintf(dout, "%s%s\n", dirname,
2660 				type == TYPE_A ? "\r" : "");
2661 			byte_count += strlen(dirname) + 1;
2662 			continue;
2663 		} else if (!S_ISDIR(st.st_mode))
2664 			continue;
2665 
2666 		if ((dirp = opendir(dirname)) == NULL)
2667 			continue;
2668 
2669 		while ((dir = readdir(dirp)) != NULL) {
2670 			char nbuf[MAXPATHLEN];
2671 
2672 			if (dir->d_name[0] == '.' && dir->d_namlen == 1)
2673 				continue;
2674 			if (dir->d_name[0] == '.' && dir->d_name[1] == '.' &&
2675 			    dir->d_namlen == 2)
2676 				continue;
2677 
2678 			snprintf(nbuf, sizeof(nbuf),
2679 				"%s/%s", dirname, dir->d_name);
2680 
2681 			/*
2682 			 * We have to do a stat to insure it's
2683 			 * not a directory or special file.
2684 			 */
2685 			if (simple || (stat(nbuf, &st) == 0 &&
2686 			    S_ISREG(st.st_mode))) {
2687 				if (dout == NULL) {
2688 					dout = dataconn("file list", (off_t)-1,
2689 						"w");
2690 					if (dout == NULL)
2691 						goto out;
2692 					transflag++;
2693 				}
2694 				if (nbuf[0] == '.' && nbuf[1] == '/')
2695 					fprintf(dout, "%s%s\n", &nbuf[2],
2696 						type == TYPE_A ? "\r" : "");
2697 				else
2698 					fprintf(dout, "%s%s\n", nbuf,
2699 						type == TYPE_A ? "\r" : "");
2700 				byte_count += strlen(nbuf) + 1;
2701 			}
2702 		}
2703 		(void) closedir(dirp);
2704 	}
2705 
2706 	if (dout == NULL)
2707 		reply(550, "No files found.");
2708 	else if (ferror(dout) != 0)
2709 		perror_reply(550, "Data connection");
2710 	else
2711 		reply(226, "Transfer complete.");
2712 
2713 	transflag = 0;
2714 	if (dout != NULL)
2715 		(void) fclose(dout);
2716 	data = -1;
2717 	pdata = -1;
2718 out:
2719 	if (freeglob) {
2720 		freeglob = 0;
2721 		globfree(&gl);
2722 	}
2723 }
2724 
2725 void
2726 reapchild(signo)
2727 	int signo;
2728 {
2729 	while (wait3(NULL, WNOHANG, NULL) > 0);
2730 }
2731 
2732 #ifdef OLD_SETPROCTITLE
2733 /*
2734  * Clobber argv so ps will show what we're doing.  (Stolen from sendmail.)
2735  * Warning, since this is usually started from inetd.conf, it often doesn't
2736  * have much of an environment or arglist to overwrite.
2737  */
2738 void
2739 #if __STDC__
2740 setproctitle(const char *fmt, ...)
2741 #else
2742 setproctitle(fmt, va_alist)
2743 	char *fmt;
2744         va_dcl
2745 #endif
2746 {
2747 	int i;
2748 	va_list ap;
2749 	char *p, *bp, ch;
2750 	char buf[LINE_MAX];
2751 
2752 #if __STDC__
2753 	va_start(ap, fmt);
2754 #else
2755 	va_start(ap);
2756 #endif
2757 	(void)vsnprintf(buf, sizeof(buf), fmt, ap);
2758 
2759 	/* make ps print our process name */
2760 	p = Argv[0];
2761 	*p++ = '-';
2762 
2763 	i = strlen(buf);
2764 	if (i > LastArgv - p - 2) {
2765 		i = LastArgv - p - 2;
2766 		buf[i] = '\0';
2767 	}
2768 	bp = buf;
2769 	while (ch = *bp++)
2770 		if (ch != '\n' && ch != '\r')
2771 			*p++ = ch;
2772 	while (p < LastArgv)
2773 		*p++ = ' ';
2774 }
2775 #endif /* OLD_SETPROCTITLE */
2776 
2777 static void
2778 logxfer(name, size, start)
2779 	char *name;
2780 	long size;
2781 	long start;
2782 {
2783 	char buf[1024];
2784 	char path[MAXPATHLEN + 1];
2785 	time_t now;
2786 
2787 	if (statfd >= 0 && getwd(path) != NULL) {
2788 		time(&now);
2789 		snprintf(buf, sizeof(buf), "%.20s!%s!%s!%s/%s!%ld!%ld\n",
2790 			ctime(&now)+4, ident, remotehost,
2791 			path, name, size, now - start + (now == start));
2792 		write(statfd, buf, strlen(buf));
2793 	}
2794 }
2795