Subject: tftpd patch...
To: None <current-users@sun-lamp.cs.berkeley.edu>
From: Christos Zoulas <christos@deshaw.com>
List: current-users
Date: 03/01/1994 02:20:41
As promised. the problem was that tftpd would core dump if given no arguments.
I fixed it to use getopt. I also changed 0 to fd, because I had added some
debugging code that allowed me to start it from the command line.


*** tftpd.c.orig	Tue Jan 11 05:33:16 1994
--- tftpd.c	Tue Mar  1 02:17:08 1994
***************
*** 70,75 ****
--- 70,76 ----
  #define	TIMEOUT		5
  
  extern	int errno;
+ extern  char *__progname;
  struct	sockaddr_in s_in = { AF_INET };
  int	peer;
  int	rexmtval = TIMEOUT;
***************
*** 86,127 ****
  
  int	secure = 0;
  
! main(ac, av)
! 	char **av;
  {
  	register struct tftphdr *tp;
  	register int n = 0;
  	int on = 1;
  
- 	ac--; av++;
- 	if (!strcmp(*av, "-s")) {
- 		ac--; av++;
- 		secure = 1;
- 	}
  	openlog("tftpd", LOG_PID, LOG_DAEMON);
! 	while (ac-- > 0) {
  		if (!secure) {
  			if (n >= MAXARG) {
  				syslog(LOG_ERR, "too many directories\n");
  				exit(1);
  			} else
! 				dirs[n++] = *av;
  		}
! 		if (chdir(*av++)) {
! 			syslog(LOG_ERR, "%s: %m\n", av[-1]);
  			exit(1);
  		}
  	}
  	if (secure && chroot(".")) {
  		syslog(LOG_ERR, "chroot: %m\n");
  		exit(1);
  	}
! 	if (ioctl(0, FIONBIO, &on) < 0) {
  		syslog(LOG_ERR, "ioctl(FIONBIO): %m\n");
  		exit(1);
  	}
  	fromlen = sizeof (from);
! 	n = recvfrom(0, buf, sizeof (buf), 0,
  	    (struct sockaddr *)&from, &fromlen);
  	if (n < 0) {
  		syslog(LOG_ERR, "recvfrom: %m\n");
--- 87,147 ----
  
  int	secure = 0;
  
! static void
! usage()
  {
+ 	syslog(LOG_ERR, "Usage: %s [-s] [directory ...]\n", __progname);
+ 	exit(1);
+ }
+ 
+ main(argc, argv)
+ 	int    argc;
+ 	char **argv;
+ {
  	register struct tftphdr *tp;
  	register int n = 0;
  	int on = 1;
+ 	int fd = 0;
+ 	int c;
  
  	openlog("tftpd", LOG_PID, LOG_DAEMON);
! 
! 	while ((c = getopt(argc, argv, "s")) != -1)
! 		switch (c) {
! 		case 's':
! 			secure = 1;
! 			break;
! 
! 		default:
! 			usage();
! 			break;
! 		}
! 
! 	for (; optind != argc; optind++) {
  		if (!secure) {
  			if (n >= MAXARG) {
  				syslog(LOG_ERR, "too many directories\n");
  				exit(1);
  			} else
! 				dirs[n++] = argv[optind];
  		}
! 		if (chdir(argv[optind])) {
! 			syslog(LOG_ERR, "%s: %m\n", argv[optind]);
  			exit(1);
  		}
  	}
+ 
  	if (secure && chroot(".")) {
  		syslog(LOG_ERR, "chroot: %m\n");
  		exit(1);
  	}
! 
! 	if (ioctl(fd, FIONBIO, &on) < 0) {
  		syslog(LOG_ERR, "ioctl(FIONBIO): %m\n");
  		exit(1);
  	}
  	fromlen = sizeof (from);
! 	n = recvfrom(fd, buf, sizeof (buf), 0,
  	    (struct sockaddr *)&from, &fromlen);
  	if (n < 0) {
  		syslog(LOG_ERR, "recvfrom: %m\n");
***************
*** 160,166 ****
  				 * a single request from a single client.
  				 */
  				j = sizeof from;
! 				i = recvfrom(0, buf, sizeof (buf), 0,
  				    (struct sockaddr *)&from, &j);
  				if (i > 0) {
  					n = i;
--- 180,186 ----
  				 * a single request from a single client.
  				 */
  				j = sizeof from;
! 				i = recvfrom(fd, buf, sizeof (buf), 0,
  				    (struct sockaddr *)&from, &j);
  				if (i > 0) {
  					n = i;
***************
*** 179,185 ****
  	}
  	from.sin_family = AF_INET;
  	alarm(0);
! 	close(0);
  	close(1);
  	peer = socket(AF_INET, SOCK_DGRAM, 0);
  	if (peer < 0) {
--- 199,205 ----
  	}
  	from.sin_family = AF_INET;
  	alarm(0);
! 	close(fd);
  	close(1);
  	peer = socket(AF_INET, SOCK_DGRAM, 0);
  	if (peer < 0) {

------------------------------------------------------------------------------