package tftpd
tags 536509 + patch
thanks

Now I deliver a fully functional patch to let tftpd __and__ tftp
enjoy the blessing of IPv6 support. For your information it is
worth to point out that the client side is harder to implement
by a magnitude, since the server is inetd-based.

The mailing list debian-ipv6 har been one of utterly silence
since I mentioned this endeouvor, so I had to do all the
research on my own, but here is the outcome.

Best regards
-- 
Mats Erik Andersson, fil. dr
<deb...@gisladisker.se>
diff -Nru netkit-tftp-0.17/debian/changelog netkit-tftp-0.17/debian/changelog
--- netkit-tftp-0.17/debian/changelog	2010-04-17 03:41:02.000000000 +0200
+++ netkit-tftp-0.17/debian/changelog	2010-04-17 02:58:32.000000000 +0200
@@ -1,3 +1,26 @@
+netkit-tftp (0.17-17.1) unstable; urgency=low
+
+  * Non-maintainer upload.
+  * Migrate to source format 3.0 quilt.
+    + Deposit legacy patches in debian/patches/.
+  * Standards 3.8.4, compatibility level 7.
+  * debian/control: Add ${misc:Depends} for both binary packages.
+  * debian/rules: Use dh_strip and dh_prep.
+  * debian/watch: New file.
+  * Augmented patches:
+    + 33_tftp_tftpsubs_c.diff: Missing include.
+    + 10_tftp_manpage.diff: Groff error.
+  * New patches for IPv6-enabled binaries:
+    + Closes: #536509
+    + 50_tftpd_inet6.diff
+    + 55_tftpsubs_inet6.diff
+    + 60_tftp_inet6.diff
+  * debian/tftpd.examples: debian/local/tftpd.xinetd
+  * [lintian] Use the idiom 'set -e' in maintainer scripts.
+  * [lintian] Insert stanza Homepage in control file.
+
+ -- Mats Erik Andersson <mats.anders...@gisladisker.se>  Sat, 17 Apr 2010 02:57:02 +0200
+
 netkit-tftp (0.17-17) unstable; urgency=low
 
   * Require hostname for connection name (Closes: #375365)
diff -Nru netkit-tftp-0.17/debian/compat netkit-tftp-0.17/debian/compat
--- netkit-tftp-0.17/debian/compat	2010-04-17 03:41:02.000000000 +0200
+++ netkit-tftp-0.17/debian/compat	2010-04-17 02:26:15.000000000 +0200
@@ -1 +1 @@
-4
+7
diff -Nru netkit-tftp-0.17/debian/control netkit-tftp-0.17/debian/control
--- netkit-tftp-0.17/debian/control	2010-04-17 03:41:02.000000000 +0200
+++ netkit-tftp-0.17/debian/control	2010-04-17 02:32:47.000000000 +0200
@@ -2,12 +2,13 @@
 Section: net
 Priority: optional
 Maintainer: Alberto Gonzalez Iniesta <a...@inittab.org>
-Standards-Version: 3.8.0.0
-Build-Depends: debhelper (>= 4.0.2)
+Standards-Version: 3.8.4
+Build-Depends: debhelper (>= 7)
+Homepage: http://ftp.uk.linux.org/pub/linux/Networking/netkit/
 
 Package: tftp
 Architecture: any
-Depends: netbase, ${shlibs:Depends}
+Depends: netbase, ${shlibs:Depends}, ${misc:Depends}
 Replaces: netstd
 Description: Trivial file transfer protocol client
  Tftp is the user interface to the Internet TFTP (Trivial File Transfer
@@ -17,7 +18,7 @@
 
 Package: tftpd
 Architecture: any
-Depends: openbsd-inetd | inet-superserver, ${shlibs:Depends}
+Depends: openbsd-inetd | inet-superserver, ${shlibs:Depends}, ${misc:Depends}
 Replaces: netstd
 Description: Trivial file transfer protocol server
  Tftpd is a server which supports the Internet Trivial File Transfer Protocol
diff -Nru netkit-tftp-0.17/debian/local/tftpd.xinetd netkit-tftp-0.17/debian/local/tftpd.xinetd
--- netkit-tftp-0.17/debian/local/tftpd.xinetd	1970-01-01 01:00:00.000000000 +0100
+++ netkit-tftp-0.17/debian/local/tftpd.xinetd	2010-02-06 12:11:28.000000000 +0100
@@ -0,0 +1,13 @@
+service tftp
+{
+	disable = no
+	socket_type = dgram
+	protocol = udp
+	flags = IPv6
+	wait = yes
+	user = nobody
+	server = /usr/sbin/in.tftpd
+	server_args = /srv/tftp
+	log_type = SYSLOG daemon info
+	log_on_success = HOST
+}
diff -Nru netkit-tftp-0.17/debian/patches/05_mrules.diff netkit-tftp-0.17/debian/patches/05_mrules.diff
--- netkit-tftp-0.17/debian/patches/05_mrules.diff	1970-01-01 01:00:00.000000000 +0100
+++ netkit-tftp-0.17/debian/patches/05_mrules.diff	2010-02-05 18:31:18.000000000 +0100
@@ -0,0 +1,14 @@
+X-Comment: Recovered from previous package releases.
+--- netkit-tftp-0.17.orig/MRULES
++++ netkit-tftp-0.17/MRULES
+@@ -1,8 +1,8 @@
+ # Standard compilation rules (don't use make builtins)
+ 
+ %.o: %.c
+-	$(CC) $(CFLAGS) -I../include $< -c
++	$(CC) $(CFLAGS) $< -c
+ 
+ %.o: %.cc
+-	$(CC) $(CFLAGS) -I../include $< -c
++	$(CC) $(CFLAGS) $< -c
+ 
diff -Nru netkit-tftp-0.17/debian/patches/10_tftp_manpage.diff netkit-tftp-0.17/debian/patches/10_tftp_manpage.diff
--- netkit-tftp-0.17/debian/patches/10_tftp_manpage.diff	1970-01-01 01:00:00.000000000 +0100
+++ netkit-tftp-0.17/debian/patches/10_tftp_manpage.diff	2010-02-06 12:07:00.000000000 +0100
@@ -0,0 +1,21 @@
+X-Comment: Recovered from previous package releases.
+--- netkit-tftp-0.17.orig/tftp/tftp.1
++++ netkit-tftp-0.17/tftp/tftp.1
+@@ -60,7 +60,7 @@
+ Once
+ .Nm tftp
+ is running, it issues the prompt
+-.LI tftp>
++\f(CWtftp>\fP
+ and recognizes the following commands:
+ .Pp
+ .Bl -tag -width verbose -compact
+@@ -84,7 +84,7 @@
+ protocol, unlike the
+ .Tn FTP
+ protocol,
+-does not maintain connections betweeen transfers; thus, the
++does not maintain connections between transfers; thus, the
+ .Cm connect
+ command does not actually create a connection,
+ but merely remembers what host is to be used for transfers.
diff -Nru netkit-tftp-0.17/debian/patches/15_tftpd_manpage.diff netkit-tftp-0.17/debian/patches/15_tftpd_manpage.diff
--- netkit-tftp-0.17/debian/patches/15_tftpd_manpage.diff	1970-01-01 01:00:00.000000000 +0100
+++ netkit-tftp-0.17/debian/patches/15_tftpd_manpage.diff	2010-02-05 18:34:03.000000000 +0100
@@ -0,0 +1,32 @@
+Author: Herbert Xu <herb...@debian.org>
+X-Comment: Recovered from previous package releases.
+--- netkit-tftp-0.17.orig/tftpd/tftpd.8
++++ netkit-tftp-0.17/tftpd/tftpd.8
+@@ -42,6 +42,8 @@
+ Trivial File Transfer Protocol server
+ .Sh SYNOPSIS
+ .Nm tftpd
++.Op Fl n
++.Op Fl s
+ .Op Ar directory ...
+ .Sh DESCRIPTION
+ .Nm Tftpd
+@@ -111,6 +113,18 @@
+ can be used to ensure that replies go out from the correct address.
+ These considerations are important, because most tftp clients will
+ reject reply packets that appear to come from an unexpected address.
++.Pp
++The options are:
++.Bl -tag -width Ds
++.It Fl n
++Suppresses negative acknowledgement of requests for nonexistent relative
++filenames.
++.It Fl s
++All absolute filenames are treated as if they were preceded by the first
++directory argument, or
++.Pa /tftpboot
++if there is none.
++.El
+ .Sh SEE ALSO
+ .Xr tftp 1 ,
+ .Xr inetd 8
diff -Nru netkit-tftp-0.17/debian/patches/20_tftp_main_c.diff netkit-tftp-0.17/debian/patches/20_tftp_main_c.diff
--- netkit-tftp-0.17/debian/patches/20_tftp_main_c.diff	1970-01-01 01:00:00.000000000 +0100
+++ netkit-tftp-0.17/debian/patches/20_tftp_main_c.diff	2010-02-05 18:17:16.000000000 +0100
@@ -0,0 +1,68 @@
+Description: Various sanity checks.
+Author: Michael Welle, Alberto Gonzales Iniesta
+Forwarded: no
+X-Comment: Recovered from earlier package releases.
+--- netkit-tftp-0.17.orig/tftp/main.c
++++ netkit-tftp-0.17/tftp/main.c
+@@ -69,7 +69,7 @@
+ #define	TIMEOUT		5		/* secs between rexmt's */
+ 
+ struct sockaddr_in s_inn;
+-int f;
++int f = -1;
+ int trace;
+ int verbose;
+ int rexmtval = TIMEOUT;
+@@ -151,17 +151,11 @@
+ static struct cmd *getcmd(const char *name);
+ static char *tail(char *filename);
+ 
+-int
+-main(int argc, char *argv[])
+-{
++void initsock() {
+ 	struct sockaddr_in s_in;
+-	int top;
+ 
+-	sp = getservbyname("tftp", "udp");
+-	if (sp == 0) {
+-		fprintf(stderr, "tftp: udp/tftp: unknown service\n");
+-		exit(1);
+-	}
++	if (f >= 0)
++		close(f);
+ 	f = socket(AF_INET, SOCK_DGRAM, 0);
+ 	if (f < 0) {
+ 		perror("tftp: socket");
+@@ -173,6 +167,19 @@
+ 		perror("tftp: bind");
+ 		exit(1);
+ 	}
++}
++
++int
++main(int argc, char *argv[])
++{
++	int top;
++
++	sp = getservbyname("tftp", "udp");
++	if (sp == 0) {
++		fprintf(stderr, "tftp: udp/tftp: unknown service\n");
++		exit(1);
++	}
++	initsock();
+ 	strcpy(mode, "netascii");
+ 	mysignal(SIGINT, intr);
+ 	if (argc > 1) {
+@@ -202,7 +209,10 @@
+ 		argc = margc;
+ 		argv = margv;
+ 	}
+-	if (argc > 3) {
++	/* We should have 2 or 3 args now: the cmd and its
++	 * parameters. If not, we bail out here.
++	 */
++	if (argc != 2 && argc != 3) {
+ 		printf("usage: %s host-name [port]\n", argv[0]);
+ 		return;
+ 	}
diff -Nru netkit-tftp-0.17/debian/patches/30_tftp_tftp_c.diff netkit-tftp-0.17/debian/patches/30_tftp_tftp_c.diff
--- netkit-tftp-0.17/debian/patches/30_tftp_tftp_c.diff	1970-01-01 01:00:00.000000000 +0100
+++ netkit-tftp-0.17/debian/patches/30_tftp_tftp_c.diff	2010-02-05 18:36:47.000000000 +0100
@@ -0,0 +1,79 @@
+Description: Various sanity checks.
+Author: Michael Welle, Alberto Gonzales Iniesta
+Forwarded: no
+X-Comment: Recovered from previous package releases.
+--- netkit-tftp-0.17.orig/tftp/tftp.c
++++ netkit-tftp-0.17/tftp/tftp.c
+@@ -174,19 +174,13 @@
+ 				goto abort;
+ 			}
+ 			if (ap->th_opcode == ACK) {
+-				volatile int j = 0;
+-
+ 				if (ap->th_block == block) {
+ 					break;
+ 				}
+ 				/* On an error, try to synchronize
+ 				 * both sides.
+ 				 */
+-				j = synchnet(f);
+-				if (j && trace) {
+-					printf("discarded %d packets\n",
+-							j);
+-				}
++				synchnet(f, trace);
+ 				if (ap->th_block == (block-1)) {
+ 					goto send_data;
+ 				}
+@@ -197,10 +191,14 @@
+ 		}
+ 		else {
+ 			amount += size;
++			if (size != SEGSIZE) {
++				break;
++			}
+ 		}
+ 		block++;
+-	} while (size == SEGSIZE);
++	} while (1);
+ abort:
++	initsock();
+ 	fclose(file);
+ 	stopclock();
+ 	if (amount > 0)
+@@ -278,18 +276,13 @@
+ 				goto abort;
+ 			}
+ 			if (dp->th_opcode == DATA) {
+-				volatile int j = 0;
+-
+ 				if (dp->th_block == block) {
+ 					break;          /* have next packet */
+ 				}
+ 				/* On an error, try to synchronize
+ 				 * both sides.
+ 				 */
+-				j = synchnet(f);
+-				if (j && trace) {
+-					printf("discarded %d packets\n", j);
+-				}
++				synchnet(f, trace);
+ 				if (dp->th_block == (block-1)) {
+ 					goto send_ack;  /* resend ack */
+ 				}
+@@ -303,10 +296,14 @@
+ 		}
+ 		amount += size;
+ 	} while (size == SEGSIZE);
+-abort:                                          /* ok to ack, since user */
++
+ 	ap->th_opcode = htons((u_short)ACK);    /* has seen err msg */
+ 	ap->th_block = htons((u_short)block);
+ 	(void) sendto(f, ackbuf, 4, 0, (struct sockaddr *)&s_inn, sizeof(s_inn));
++
++abort:
++	initsock();
++
+ 	write_behind(file, convert);            /* flush last buffer */
+ 	fclose(file);
+ 	stopclock();
diff -Nru netkit-tftp-0.17/debian/patches/33_tftp_tftpsubs_c.diff netkit-tftp-0.17/debian/patches/33_tftp_tftpsubs_c.diff
--- netkit-tftp-0.17/debian/patches/33_tftp_tftpsubs_c.diff	1970-01-01 01:00:00.000000000 +0100
+++ netkit-tftp-0.17/debian/patches/33_tftp_tftpsubs_c.diff	2010-02-05 18:37:27.000000000 +0100
@@ -0,0 +1,34 @@
+X-Comment: Recovered from previous package releases.
+--- netkit-tftp-0.17.orig/tftp/tftpsubs.c
++++ netkit-tftp-0.17/tftp/tftpsubs.c
+@@ -55,6 +55,7 @@
+ #include <arpa/tftp.h>
+ #include <unistd.h>
+ #include <stdio.h>
++#include <string.h>
+ #include <signal.h>
+ 
+ #ifndef FIONREAD
+@@ -249,8 +250,8 @@
+  * when trace is active).
+  */
+ 
+-int
+-synchnet(int f /* socket to flush */)
++void
++synchnet(int f /* socket to flush */, int trace)
+ {
+ 	int i, j = 0;
+ 	char rbuf[PKTSIZE];
+@@ -265,7 +266,10 @@
+ 			(void) recvfrom(f, rbuf, sizeof (rbuf), 0,
+ 				(struct sockaddr *)&from, &fromlen);
+ 		} else {
+-			return(j);
++			if (j && trace) {
++				printf("discarded %d packets\n", j);
++			}
++			return;
+ 		}
+ 	}
+ }
diff -Nru netkit-tftp-0.17/debian/patches/37_tftp_tftpsubs_h.diff netkit-tftp-0.17/debian/patches/37_tftp_tftpsubs_h.diff
--- netkit-tftp-0.17/debian/patches/37_tftp_tftpsubs_h.diff	1970-01-01 01:00:00.000000000 +0100
+++ netkit-tftp-0.17/debian/patches/37_tftp_tftpsubs_h.diff	2010-02-05 18:37:52.000000000 +0100
@@ -0,0 +1,12 @@
+X-Comment: Recovered from previous package releases.
+--- netkit-tftp-0.17.orig/tftp/tftpsubs.h
++++ netkit-tftp-0.17/tftp/tftpsubs.h
+@@ -1,6 +1,7 @@
+ #define PKTSIZE SEGSIZE+4       /* should be moved to tftp.h */
+ 
+-int synchnet(int);
++void initsock(void);
++void synchnet(int, int);
+ struct tftphdr *r_init(void);
+ struct tftphdr *w_init(void);
+ int readit(FILE *file, struct tftphdr **dpp, int convert);
diff -Nru netkit-tftp-0.17/debian/patches/40_tftpd_tftpd_c.diff netkit-tftp-0.17/debian/patches/40_tftpd_tftpd_c.diff
--- netkit-tftp-0.17/debian/patches/40_tftpd_tftpd_c.diff	1970-01-01 01:00:00.000000000 +0100
+++ netkit-tftp-0.17/debian/patches/40_tftpd_tftpd_c.diff	2010-02-05 18:34:56.000000000 +0100
@@ -0,0 +1,112 @@
+Description: Various sanity checks.
+Author: Herbert Xu, Tomasz Nowiaski, Alberto Gonzales Iniesta
+Forwarded: no
+X-Comment: Recovered from earlier package releases.
+--- netkit-tftp-0.17.orig/tftpd/tftpd.c
++++ netkit-tftp-0.17/tftpd/tftpd.c
+@@ -92,8 +92,11 @@
+ static struct		sockaddr_in from;
+ static socklen_t	fromlen;
+ 
+-#define MAXARG		4
+-static char		*dirs[MAXARG+1];
++static const char	*default_dirs[] = { "/tftpboot", 0 };
++static const char	**dirs = default_dirs;
++
++static int		suppress_naks;
++static int		secure_tftp;
+ 
+ int
+ main(int ac, char **av)
+@@ -105,12 +108,25 @@
+ 	register struct tftphdr *tp;
+ 	register int n = 0;
+ 	int on = 1;
++	int ch;
+ 
+-	ac--; av++;
+-	if (ac==0) dirs[0] = "/tftpboot";  /* default directory */
+-	while (ac-- > 0 && n < MAXARG)
+-		dirs[n++] = *av++;
+ 	openlog("tftpd", LOG_PID, LOG_DAEMON);
++	opterr = 0;
++	while ((ch = getopt(ac, av, "ns")) != EOF) {
++		switch (ch) {
++		case 'n':
++			suppress_naks = 1;
++			break;
++		case 's':
++			secure_tftp = 1;
++			break;
++		default:
++			syslog(LOG_ERR, "unknown option -%c", ch);
++			exit(1);
++		}
++	}
++
++	if (av[optind]) dirs = (const char **) &av[optind];
+ 	if (ioctl(0, FIONBIO, &on) < 0) {
+ 		syslog(LOG_ERR, "ioctl(FIONBIO): %m\n");
+ 		exit(1);
+@@ -279,6 +295,12 @@
+ 	}
+ 	ecode = (*pf->f_validate)(filename, tp->th_opcode);
+ 	if (ecode) {
++		/*
++		 * Avoid storms of naks to a RRQ broadcast for a relative
++		 * bootfile pathname from a diskless Sun.
++		 */
++		if (suppress_naks && *filename != '/' && ecode == ENOTFOUND)
++			exit(0);
+ 		nak(ecode);
+ 		exit(1);
+ 	}
+@@ -310,13 +332,17 @@
+ 	struct stat stbuf;
+ 	int	fd;
+ 	const char *cp;
+-	char **dirp;
++	const char **dirp;
+ 
+ 	syslog(LOG_NOTICE, "tftpd: trying to get file: %s\n", filename);
+ 
+-	if (*filename != '/') {
++	if (*filename != '/' || secure_tftp) {
+ 		syslog(LOG_NOTICE, "tftpd: serving file from %s\n", dirs[0]);
+-		chdir(dirs[0]);
++		/*chdir(dirs[0]);*/
++		if ( chdir(dirs[0]) < 0 )
++			return (EACCESS);
++		while (*filename == '/')
++			filename++;
+ 	} else {
+ 		for (dirp = dirs; *dirp; dirp++)
+ 			if (strncmp(filename, *dirp, strlen(*dirp)) == 0)
+@@ -366,7 +392,8 @@
+ 		if ((stbuf.st_mode & S_IWOTH) == 0)
+ 			return (EACCESS);
+ 	}
+-	fd = open(filename, mode == RRQ ? O_RDONLY : O_WRONLY|O_TRUNC);
++
++	fd = open(filename, mode == RRQ ? O_RDONLY : O_WRONLY|O_TRUNC|O_CREAT, 0600);
+ 	if (fd < 0)
+ 		return (errno + 100);
+ 	file = fdopen(fd, (mode == RRQ)? "r":"w");
+@@ -441,7 +468,7 @@
+ 					break;
+ 				}
+ 				/* Re-synchronize with the other side */
+-				(void) synchnet(peer);
++				(void) synchnet(peer, 0);
+ 				if (ap->th_block == (block -1)) {
+ 					goto send_data;
+ 				}
+@@ -506,7 +533,7 @@
+ 					break;   /* normal */
+ 				}
+ 				/* Re-synchronize with the other side */
+-				(void) synchnet(peer);
++				(void) synchnet(peer, 0);
+ 				if (dp->th_block == (block-1))
+ 					goto send_ack;          /* rexmit */
+ 			}
diff -Nru netkit-tftp-0.17/debian/patches/50_tftpd_inet6.diff netkit-tftp-0.17/debian/patches/50_tftpd_inet6.diff
--- netkit-tftp-0.17/debian/patches/50_tftpd_inet6.diff	1970-01-01 01:00:00.000000000 +0100
+++ netkit-tftp-0.17/debian/patches/50_tftpd_inet6.diff	2010-04-17 02:22:09.000000000 +0200
@@ -0,0 +1,102 @@
+Description: Enable IPv6 sockets for the tftp server.
+ Using the super structure 'struct sockaddr_storage', and adaptive
+ capture of the address family from the incoming socket, the server
+ in.tftpd will be IPv6-enabled.
+X-Depends-on-Previous-Patch: 40_tftpd_tftpd_c.diff
+Author: Mats Erik Andersson <deb...@gisladisker.se>
+Forwarded: no
+Last-Update: 2010-04-17
+--- netkit-tftp-0.17.debian/tftpd/tftpd.c
++++ netkit-tftp-0.17/tftpd/tftpd.c
+@@ -89,7 +89,7 @@
+ 
+ static char		buf[PKTSIZE];
+ static char		ackbuf[PKTSIZE];
+-static struct		sockaddr_in from;
++static struct		sockaddr_storage from;
+ static socklen_t	fromlen;
+ 
+ static const char	*default_dirs[] = { "/tftpboot", 0 };
+@@ -101,7 +101,7 @@
+ int
+ main(int ac, char **av)
+ {
+-	struct sockaddr_in sn;
++	struct sockaddr_storage sn;
+ 	socklen_t snsize;
+ 	int dobind=1;
+ 
+@@ -173,7 +173,7 @@ main(int ac, char **av)
+ 				 */
+ 				k = sizeof(from);
+ 				i = recvfrom(0, buf, sizeof (buf), 0,
+-				    (struct sockaddr *)&from, &k);
++					(struct sockaddr *)&from, &k);
+ 				if (i > 0) {
+ 					n = i;
+ 					fromlen = k;
+@@ -202,7 +202,6 @@ main(int ac, char **av)
+ 			exit(1);
+ 		}
+ 	}
+-	from.sin_family = AF_INET;
+ 	alarm(0);
+ 
+ 	/*
+@@ -213,15 +212,35 @@ main(int ac, char **av)
+ 	 * interface.
+ 	 */
+ 	snsize = sizeof(sn);
+-	if (getsockname(0, (struct sockaddr *)&sn, &snsize)<0 ||
+-	    sn.sin_addr.s_addr == INADDR_ANY) {
++	if ( getsockname(0, (struct sockaddr *)&sn, &snsize) < 0 ) {
+ 		dobind = 0;
+ 	}
+-	sn.sin_port = 0;
++
++	if ( dobind ) {
++	    /* Was the wildcard address contained in the socket? */
++	    if ( ((sn.ss_family == AF_INET) &&
++		    ((struct sockaddr_in *)&sn)->sin_addr.s_addr
++				== INADDR_ANY )
++		|| ((sn.ss_family == AF_INET6) &&
++		    (memcmp( &((struct sockaddr_in6 *)&sn)->sin6_addr,
++				&in6addr_any,
++				sizeof(struct in6_addr)) == 0) )
++		)
++	    {
++		/* Implicit binding suffices for wildcard addresses. */
++		dobind = 0;
++	    }
++	}
++
++	if ( sn.ss_family == AF_INET )
++	    ((struct sockaddr_in *) &sn)->sin_port = 0;
++	else if ( sn.ss_family == AF_INET6 )
++	    ((struct sockaddr_in6 *) &sn)->sin6_port = 0;
+ 
+ 	close(0);
+ 	close(1);
+-	peer = socket(AF_INET, SOCK_DGRAM, 0);
++
++	peer = socket(from.ss_family, SOCK_DGRAM, 0);
+ 	if (peer < 0) {
+ 		syslog(LOG_ERR, "socket: %m\n");
+ 		exit(1);
+@@ -232,10 +251,15 @@ main(int ac, char **av)
+ 		exit(1);
+ 	}
+ 
+-	if (connect(peer, (struct sockaddr *)&from, sizeof(from)) < 0) {
++	if ( connect(peer, (struct sockaddr *)&from,
++			(from.ss_family == AF_INET6)
++				? sizeof(struct sockaddr_in6)
++				: sizeof(struct sockaddr_in))
++			< 0 ) {
+ 		syslog(LOG_ERR, "connect: %m\n");
+ 		exit(1);
+ 	}
++
+ 	tp = (struct tftphdr *)buf;
+ 	tp->th_opcode = ntohs(tp->th_opcode);
+ 	if (tp->th_opcode == RRQ || tp->th_opcode == WRQ)
diff -Nru netkit-tftp-0.17/debian/patches/55_tftpsubs_inet6.diff netkit-tftp-0.17/debian/patches/55_tftpsubs_inet6.diff
--- netkit-tftp-0.17/debian/patches/55_tftpsubs_inet6.diff	1970-01-01 01:00:00.000000000 +0100
+++ netkit-tftp-0.17/debian/patches/55_tftpsubs_inet6.diff	2010-04-17 02:22:25.000000000 +0200
@@ -0,0 +1,30 @@
+Description: Enable IPv6 sockets.
+ Use 'struct sockaddr_storage' to insure that the address structure
+ can accomodate IPv4 as well as IPv6.
+ .
+ Needed for address family independence of the tftp client.
+X-Depends-on-Previous-Patch: 33_tftp_tftpsubs_c.diff
+Author: Mats Erik Andersson <deb...@gisladisker.se>
+Forwarded: no
+Last-Update: 2010-02-17
+--- netkit-tftp-0.17.debian/tftp/tftpsubs.c
++++ netkit-tftp-0.17/tftp/tftpsubs.c
+@@ -255,7 +255,7 @@ synchnet(int f /* socket to flush */, in
+ {
+ 	int i, j = 0;
+ 	char rbuf[PKTSIZE];
+-	struct sockaddr_in from;
++	struct sockaddr_storage from;
+ 	socklen_t fromlen;
+ 
+ 	while (1) {
+--- netkit-tftp-0.17.debian/tftp/tftpsubs.h
++++ netkit-tftp-0.17/tftp/tftpsubs.h
+@@ -1,6 +1,6 @@
+ #define PKTSIZE SEGSIZE+4       /* should be moved to tftp.h */
+ 
+-void initsock(void);
++void initsock(int);
+ void synchnet(int, int);
+ struct tftphdr *r_init(void);
+ struct tftphdr *w_init(void);
diff -Nru netkit-tftp-0.17/debian/patches/60_tftp_inet6.diff netkit-tftp-0.17/debian/patches/60_tftp_inet6.diff
--- netkit-tftp-0.17/debian/patches/60_tftp_inet6.diff	1970-01-01 01:00:00.000000000 +0100
+++ netkit-tftp-0.17/debian/patches/60_tftp_inet6.diff	2010-04-17 02:22:45.000000000 +0200
@@ -0,0 +1,494 @@
+Description: Enable coexisting IPv6 and IPv4 for tftp client.
+ Using the super structure 'struct sockaddr_storage', and adaptive
+ capture of the address family from configured interfaces, the client
+ binary tftp will be IPv6-enabled.
+ .
+ Care has to be taken to let the address family, needed for a
+ specific host connection, trickle down into ever send and recv
+ calls during transportation.
+X-Depends-on-Previous-Patches: 20_tftp_main_c.diff 30_tftp_tftp_c.diff
+ 55_tftpsubs_inet6.diff
+Author: Mats Erik Andersson <deb...@gisladisker.se>
+Forwarded: no
+Last-Update: 2010-04-17
+--- netkit-tftp-0.17.debian/tftp/main.c
++++ netkit-tftp-0.17/tftp/main.c
+@@ -68,7 +68,7 @@
+ 
+ #define	TIMEOUT		5		/* secs between rexmt's */
+ 
+-struct sockaddr_in s_inn;
++struct sockaddr_storage s_inn;
+ int f = -1;
+ int trace;
+ int verbose;
+@@ -79,7 +79,7 @@ void sendfile(int fd, char *name, char *
+ void recvfile(int fd, char *name, char *modestr);
+ 
+ 
+-static int connected;
++static int connected;	/* If non-zero, contains active address family! */
+ static short port;
+ static char mode[32];
+ static char line[200];
+@@ -151,22 +151,63 @@
+ static struct cmd *getcmd(const char *name);
+ static char *tail(char *filename);
+ 
+-void initsock() {
+-	struct sockaddr_in s_in;
++static void
++set_port(struct sockaddr_storage *ss) {
++	switch (ss->ss_family) {
++	  case AF_INET6:
++		((struct sockaddr_in6 *) ss)->sin6_port = port;
++		break;
++	  case AF_INET:
++	  default:
++		((struct sockaddr_in *) ss)->sin_port = port;
++		break;
++	}
++}
++
++void initsock(int af) {
++	struct sockaddr_storage s_in;
++	struct addrinfo hints, *ai, *aiptr;
++
++	memset(&hints, 0, sizeof(hints));
++	hints.ai_flags = AI_V4MAPPED | AI_ADDRCONFIG;
++	hints.ai_family = af;
++	hints.ai_socktype = SOCK_DGRAM;
+ 
++	if ( getaddrinfo(NULL, "tftp", &hints, &aiptr) != 0 ) {
++		perror("tftp: getaddrinfo");
++		exit(1);
++	}
+ 	if (f >= 0)
+ 		close(f);
+-	f = socket(AF_INET, SOCK_DGRAM, 0);
+-	if (f < 0) {
+-		perror("tftp: socket");
+-		exit(3);
++
++	/* At least one valid adress found. */
++	for ( ai=aiptr; ai ; ai=ai->ai_next ) {
++		if ( (f = socket(ai->ai_family, SOCK_DGRAM, 0)) < 0 )
++			/* Failure, next candidate. */
++			continue;
++
++		memset(&s_in, 0, sizeof(s_in));
++		s_in.ss_family = ai->ai_family;
++		if ( bind(f, (struct sockaddr *)&s_in,
++				(s_in.ss_family == AF_INET6)
++					? sizeof(struct sockaddr_in6)
++					: sizeof(struct sockaddr_in))
++			< 0) {
++			/* Could not bind. */
++			close(f);
++			continue;
++		}
++		/* Successfully bound to a socket.
++		 * Now ai != NULL. */
++		break;
+ 	}
+-	memset(&s_in, 0, sizeof(s_in));
+-	s_in.sin_family = AF_INET;
+-	if (bind(f, (struct sockaddr *)&s_in, sizeof (s_in)) < 0) {
+-		perror("tftp: bind");
+-		exit(1);
++
++	if ( ai == NULL ) {
++		/* Could not bind or create the socket. */
++		perror("tftp: socket/bind");
++		exit(3);
+ 	}
++	freeaddrinfo(aiptr);
+ }
+ 
+ int
+@@ -179,7 +220,7 @@ main(int argc, char *argv[])
+ 		fprintf(stderr, "tftp: udp/tftp: unknown service\n");
+ 		exit(1);
+ 	}
+-	initsock();
++	initsock(AF_UNSPEC);
+ 	strcpy(mode, "netascii");
+ 	mysignal(SIGINT, intr);
+ 	if (argc > 1) {
+@@ -197,7 +238,7 @@
+ void
+ setpeer(int argc, char *argv[])
+ {
+-	struct hostent *host;
++	struct addrinfo hints, *aiptr, *ai;
+ 	size_t len;
+ 
+ 	if (argc < 2) {
+@@ -216,25 +257,37 @@ setpeer(int argc, char *argv[])
+ 		printf("usage: %s host-name [port]\n", argv[0]);
+ 		return;
+ 	}
+-	host = gethostbyname(argv[1]);
+-	if (host) {
+-		s_inn.sin_family = host->h_addrtype;
+-		if (host->h_length > (int)sizeof(s_inn.sin_addr)) {
+-			host->h_length = sizeof(s_inn.sin_addr);
+-		}
+-		memcpy(&s_inn.sin_addr, host->h_addr, host->h_length);
+-		strncpy(hostname, host->h_name, sizeof(hostname));
+-		hostname[sizeof(hostname)-1] = 0;
+-	} 
+-	else {
+-		s_inn.sin_family = AF_INET;
+-		if (!inet_aton(argv[1], &s_inn.sin_addr)) {
+-			connected = 0;
+-			printf("%s: unknown host\n", argv[1]);
+-			return;
+-		}
+-		strcpy(hostname, argv[1]);
++
++	memset(&hints, 0, sizeof(hints));
++	hints.ai_flags = AI_ALL | AI_V4MAPPED | AI_ADDRCONFIG | AI_CANONNAME;
++	hints.ai_family = AF_UNSPEC;
++	hints.ai_socktype = SOCK_DGRAM;
++
++	if ( getaddrinfo(argv[1], "tftp", &hints, &aiptr) ) {
++		connected = 0;
++		printf("%s: unknown host\n", argv[1]);
++		return;
+ 	}
++
++	/* Choose first applicable address. */
++	ai = aiptr;
++
++	while ( ai && (ai->ai_family != AF_INET6)
++			&& (ai->ai_family != AF_INET) )
++	  ai = ai->ai_next;
++
++	if ( ai == NULL ) {
++		connected = 0;
++		printf("%s: unknown host\n", argv[1]);
++		freeaddrinfo(aiptr);
++		return;
++	}
++
++	memcpy(&s_inn, ai->ai_addr, ai->ai_addrlen);
++	connected = ai->ai_family;
++	strcpy(hostname, aiptr->ai_canonname);
++	freeaddrinfo(aiptr);
++
+ 	port = sp->s_port;
+ 	if (argc == 3) {
+ 		port = atoi(argv[2]);
+@@ -245,7 +298,8 @@ setpeer(int argc, char *argv[])
+ 		}
+ 		port = htons(port);
+ 	}
+-	connected = 1;
++	/* Test and set socket for the relevant address family. */
++	initsock(connected);
+ }
+ 
+ struct	modes {
+@@ -346,7 +400,8 @@ put(int argc, char *argv[])
+ 	targ = argv[argc - 1];
+ 	if (strchr(argv[argc - 1], ':')) {
+ 		char *cp;
+-		struct hostent *hp;
++		struct addrinfo hints, *aiptr, *ai;
++		int status;
+ 
+ 		for (n = 1; n < argc - 1; n++)
+ 			if (strchr(argv[n], ':')) {
+@@ -356,19 +411,34 @@ put(int argc, char *argv[])
+ 		cp = argv[argc - 1];
+ 		targ = strchr(cp, ':');
+ 		*targ++ = 0;
+-		hp = gethostbyname(cp);
+-		if (hp == NULL) {
++
++		memset(&hints, 0, sizeof(hints));
++		hints.ai_flags = AI_V4MAPPED | AI_ADDRCONFIG | AI_CANONNAME; 
++		hints.ai_family = connected;	//AF_UNSPEC;
++		hints.ai_socktype = SOCK_DGRAM;
++
++		status = getaddrinfo(cp, "tftp", &hints, &aiptr);
++		if ( status != 0 ) {
+ 			fprintf(stderr, "tftp: %s: ", cp);
+ 			herror((char *)NULL);
+ 			return;
+ 		}
+-		if (hp->h_length > (int)sizeof(s_inn.sin_addr)) {
+-			hp->h_length = sizeof(s_inn.sin_addr);
++
++		ai = aiptr;
++		while ( ai && (ai->ai_family != AF_INET)
++				&& (ai->ai_family != AF_INET6) )
++			ai = ai->ai_next;
++		if ( ai == NULL ) {
++			freeaddrinfo(aiptr);
++			fprintf(stderr, "tftp: %s: ", cp);
++			herror((char *)NULL);
++			return;
+ 		}
+-		memcpy(&s_inn.sin_addr, hp->h_addr, hp->h_length);
+-		s_inn.sin_family = hp->h_addrtype;
+-		connected = 1;
+-		strncpy(hostname, hp->h_name, sizeof(hostname));
++
++		memcpy(&s_inn, ai->ai_addr, ai->ai_addrlen);
++		strncpy(hostname, aiptr->ai_canonname, sizeof(hostname));
++		connected = ai->ai_family;
++		freeaddrinfo(aiptr);
+ 		hostname[sizeof(hostname)-1] = 0;
+ 	}
+ 	if (!connected) {
+@@ -386,7 +456,8 @@ put(int argc, char *argv[])
+ 		if (verbose)
+ 			printf("putting %s to %s:%s [%s]\n",
+ 				ccp, hostname, targ, mode);
+-		s_inn.sin_port = port;
++
++		set_port(&s_inn);
+ 		sendfile(fd, targ, mode);
+ 		return;
+ 	}
+@@ -404,7 +475,8 @@ put(int argc, char *argv[])
+ 		if (verbose)
+ 			printf("putting %s to %s:%s [%s]\n",
+ 				argv[n], hostname, targ, mode);
+-		s_inn.sin_port = port;
++
++		set_port(&s_inn);
+ 		sendfile(fd, targ, mode);
+ 	}
+ }
+@@ -453,22 +525,36 @@ get(int argc, char *argv[])
+ 		if (src == NULL)
+ 			src = argv[n];
+ 		else {
+-			struct hostent *hp;
++			struct addrinfo hints, *aiptr, *ai;
+ 
+ 			*src++ = 0;
+-			hp = gethostbyname(argv[n]);
+-			if (hp == NULL) {
++			memset(&hints, 0, sizeof(hints));
++			hints.ai_flags = AI_V4MAPPED | AI_ADDRCONFIG | AI_CANONNAME; 
++			hints.ai_family = connected;	// AF_UNSPEC;
++			hints.ai_socktype = SOCK_DGRAM;
++
++			if ( getaddrinfo(argv[n], "tftp", &hints, &aiptr) ) {
+ 				fprintf(stderr, "tftp: %s: ", argv[n]);
+-				herror(NULL);
++				herror((char *)NULL);
+ 				continue;
+ 			}
+-			if (hp->h_length > (int)sizeof(s_inn.sin_addr)) {
+-				hp->h_length = sizeof(s_inn.sin_addr);
++
++			ai = aiptr;
++			while ( ai && (ai->ai_family != AF_INET)
++					&& (ai->ai_family != AF_INET6) )
++				ai = ai->ai_next;
++			if ( ai == NULL ) {
++				freeaddrinfo(aiptr);
++				fprintf(stderr, "tftp: %s: ", argv[n]);
++				herror((char *)NULL);
++				continue;
+ 			}
+-			memcpy(&s_inn.sin_addr, hp->h_addr, hp->h_length);
+-			s_inn.sin_family = hp->h_addrtype;
+-			connected = 1;
+-			strncpy(hostname, hp->h_name, sizeof(hostname));
++
++			memcpy(&s_inn, ai->ai_addr, ai->ai_addrlen);
++			connected = ai->ai_family;
++			strncpy(hostname, aiptr->ai_canonname,
++					sizeof(hostname));
++			freeaddrinfo(aiptr);
+ 			hostname[sizeof(hostname)-1] = 0;
+ 		}
+ 		if (argc < 4) {
+@@ -481,7 +567,8 @@ get(int argc, char *argv[])
+ 			if (verbose)
+ 				printf("getting from %s:%s to %s [%s]\n",
+ 					hostname, src, cp, mode);
+-			s_inn.sin_port = port;
++
++			set_port(&s_inn);
+ 			recvfile(fd, src, mode);
+ 			break;
+ 		}
+@@ -494,7 +581,8 @@ get(int argc, char *argv[])
+ 		if (verbose)
+ 			printf("getting from %s:%s to %s [%s]\n",
+ 				hostname, src, cp, mode);
+-		s_inn.sin_port = port;
++
++		set_port(&s_inn);
+ 		recvfile(fd, src, mode);
+ 	}
+ }
+--- netkit-tftp-0.17.debian/tftp/tftp.c
++++ netkit-tftp-0.17/tftp/tftp.c
+@@ -61,7 +61,7 @@
+ 
+ #include "../version.h"
+ 
+-extern  struct sockaddr_in s_inn;         /* filled in by main */
++extern  struct sockaddr_storage s_inn;  /* filled in by main */
+ extern  int     f;                      /* the opened socket */
+ extern  int     trace;
+ extern  int     verbose;
+@@ -100,6 +100,31 @@
+ }
+ 
+ /*
++ * Copy port number, hiding dependency on IPv4 and IPv6.
++ */
++static
++void
++copy_port(struct sockaddr_storage *to, struct sockaddr_storage *from)
++{
++	if ( from->ss_family == AF_INET6 ) {
++	  if ( to->ss_family == AF_INET6 )
++	    ((struct sockaddr_in6 *) to)->sin6_port =
++		((struct sockaddr_in6 *) from)->sin6_port;
++	  else
++	    ((struct sockaddr_in *) to)->sin_port =
++		((struct sockaddr_in6 *) from)->sin6_port;
++	}
++	else {
++	  if ( to->ss_family == AF_INET6 )
++	    ((struct sockaddr_in6 *) to)->sin6_port =
++		((struct sockaddr_in *) from)->sin_port;
++	  else
++	    ((struct sockaddr_in *) to)->sin_port =
++		((struct sockaddr_in *) from)->sin_port;
++	}
++}
++
++/*
+  * Send the requested file.
+  */
+ void
+@@ -111,7 +136,7 @@ sendfile(int fd, char *name, char *mode)
+ 	volatile u_int16_t block = 0;
+ 	int n;
+ 	volatile unsigned long amount = 0;
+-	struct sockaddr_in from;
++	struct sockaddr_storage from;
+ 	socklen_t fromlen;
+ 	volatile int convert;            /* true if doing nl->crlf conversion */
+ 	FILE *file;
+@@ -143,8 +168,11 @@ sendfile(int fd, char *name, char *mode)
+ send_data:
+ 		if (trace)
+ 			tpacket("sent", dp, size + 4);
+-		n = sendto(f, dp, size + 4, 0,
+-		    (struct sockaddr *)&s_inn, sizeof(s_inn));
++
++		n = sendto(f, dp, size + 4, 0, (struct sockaddr *)&s_inn,
++				(s_inn.ss_family == AF_INET6)
++					? sizeof(struct sockaddr_in6)
++					: sizeof(struct sockaddr_in));
+ 		if (n != size + 4) {
+ 			perror("tftp: sendto");
+ 			goto abort;
+@@ -162,7 +190,9 @@ send_data:
+ 				perror("tftp: recvfrom");
+ 				goto abort;
+ 			}
+-			s_inn.sin_port = from.sin_port;   /* added */
++
++			copy_port(&s_inn, &from);
++
+ 			if (trace)
+ 				tpacket("received", ap, n);
+ 			/* should verify packet came from server */
+@@ -198,11 +228,11 @@ send_data:
+ 		block++;
+ 	} while (1);
+ abort:
+-	initsock();
+ 	fclose(file);
+ 	stopclock();
+ 	if (amount > 0)
+ 		printstats("Sent", amount);
++	initsock(s_inn.ss_family);	/* Synchronize address family. */
+ }
+ 
+ /*
+@@ -217,7 +247,7 @@ recvfile(int fd, char *name, char *mode)
+ 	volatile u_int16_t block = 1;
+ 	int n; 
+ 	volatile unsigned long amount = 0;
+-	struct sockaddr_in from;
++	struct sockaddr_storage from;
+ 	socklen_t fromlen;
+ 	volatile int firsttrip = 1;
+ 	FILE *file;
+@@ -245,8 +275,13 @@ recvfile(int fd, char *name, char *mode)
+ send_ack:
+ 		if (trace)
+ 			tpacket("sent", ap, size);
+-		if (sendto(f, ackbuf, size, 0, (struct sockaddr *)&s_inn,
+-		    sizeof (s_inn)) != size) {
++
++		n = sendto(f, ackbuf, size, 0, (struct sockaddr *)&s_inn,
++				(s_inn.ss_family == AF_INET6) 
++					? sizeof(struct sockaddr_in6)
++					: sizeof(struct sockaddr_in));
++
++		if ( n != size) {
+ 			alarm(0);
+ 			perror("tftp: sendto");
+ 			goto abort;
+@@ -264,7 +299,9 @@ send_ack:
+ 				perror("tftp: recvfrom");
+ 				goto abort;
+ 			}
+-			s_inn.sin_port = from.sin_port;   /* added */
++
++			copy_port(&s_inn, &from);
++
+ 			if (trace)
+ 				tpacket("received", dp, n);
+ 			/* should verify client address */
+@@ -299,16 +336,18 @@ send_ack:
+ 
+ 	ap->th_opcode = htons((u_short)ACK);    /* has seen err msg */
+ 	ap->th_block = htons((u_short)block);
+-	(void) sendto(f, ackbuf, 4, 0, (struct sockaddr *)&s_inn, sizeof(s_inn));
++	(void) sendto(f, ackbuf, 4, 0, (struct sockaddr *)&s_inn,
++			(s_inn.ss_family == AF_INET6)
++				? sizeof(struct sockaddr_in6)
++				: sizeof(struct sockaddr_in));
+ 
+ abort:
+-	initsock();
+-
+ 	write_behind(file, convert);            /* flush last buffer */
+ 	fclose(file);
+ 	stopclock();
+ 	if (amount > 0)
+ 		printstats("Received", amount);
++	initsock(s_inn.ss_family);	/* Synchronize address family. */
+ }
+ 
+ int
+@@ -369,8 +408,11 @@ nak(int error)
+ 	length = strlen(pe->e_msg) + 4;
+ 	if (trace)
+ 		tpacket("sent", tp, length);
+-	if (sendto(f, ackbuf, length, 0, (struct sockaddr *)&s_inn,
+-	    sizeof (s_inn)) != length)
++	if ( sendto(f, ackbuf, length, 0, (struct sockaddr *)&s_inn,
++			(s_inn.ss_family == AF_INET6)
++				? sizeof(struct sockaddr_in6)
++				: sizeof(struct sockaddr_in))
++			!= length )
+ 		perror("nak");
+ }
+ 
diff -Nru netkit-tftp-0.17/debian/patches/series netkit-tftp-0.17/debian/patches/series
--- netkit-tftp-0.17/debian/patches/series	1970-01-01 01:00:00.000000000 +0100
+++ netkit-tftp-0.17/debian/patches/series	2010-04-17 03:27:15.000000000 +0200
@@ -0,0 +1,11 @@
+05_mrules.diff
+10_tftp_manpage.diff
+15_tftpd_manpage.diff
+20_tftp_main_c.diff
+30_tftp_tftp_c.diff
+33_tftp_tftpsubs_c.diff
+37_tftp_tftpsubs_h.diff
+40_tftpd_tftpd_c.diff
+50_tftpd_inet6.diff
+55_tftpsubs_inet6.diff
+60_tftp_inet6.diff
diff -Nru netkit-tftp-0.17/debian/rules netkit-tftp-0.17/debian/rules
--- netkit-tftp-0.17/debian/rules	2010-04-17 03:41:02.000000000 +0200
+++ netkit-tftp-0.17/debian/rules	2010-04-17 02:55:10.000000000 +0200
@@ -17,7 +17,7 @@
 
 	if [ ! -f MCONFIG ]; then \
 		./configure; \
-		sed -e 's/^CFLAGS=\(.*\)$$/CFLAGS= -g \1/' MCONFIG \
+		sed -e 's/^CFLAGS=\(.*\)$$/CFLAGS= -g \1 -fno-strict-aliasing/' MCONFIG \
 			> MCONFIG.new; \
 		mv MCONFIG.new MCONFIG; \
 	fi
@@ -38,7 +38,7 @@
 install: build
 	dh_testdir
 	dh_testroot
-	dh_clean -k
+	dh_prep
 	dh_installdirs
 
 	$(MAKE) -C tftp install INSTALLROOT=`pwd`/debian/tftp \
@@ -73,6 +73,7 @@
 	dh_fixperms
 	# You may want to make some executables suid here.
 #	dh_makeshlibs
+	dh_strip
 	dh_installdeb
 #	dh_perl
 	dh_shlibdeps
diff -Nru netkit-tftp-0.17/debian/source/format netkit-tftp-0.17/debian/source/format
--- netkit-tftp-0.17/debian/source/format	1970-01-01 01:00:00.000000000 +0100
+++ netkit-tftp-0.17/debian/source/format	2010-04-17 03:41:04.000000000 +0200
@@ -0,0 +1 @@
+3.0 (quilt)
diff -Nru netkit-tftp-0.17/debian/tftpd.examples netkit-tftp-0.17/debian/tftpd.examples
--- netkit-tftp-0.17/debian/tftpd.examples	1970-01-01 01:00:00.000000000 +0100
+++ netkit-tftp-0.17/debian/tftpd.examples	2010-02-09 01:06:31.000000000 +0100
@@ -0,0 +1 @@
+debian/local/tftpd.xinetd
diff -Nru netkit-tftp-0.17/debian/tftpd.postinst netkit-tftp-0.17/debian/tftpd.postinst
--- netkit-tftp-0.17/debian/tftpd.postinst	2010-04-17 03:41:02.000000000 +0200
+++ netkit-tftp-0.17/debian/tftpd.postinst	2010-04-17 02:25:39.000000000 +0200
@@ -1,6 +1,8 @@
-#!/bin/sh -e
+#!/bin/sh
 # $Id: tftpd.postinst,v 1.1 1999/10/26 04:43:01 herbert Exp $
 
+set -e
+
 case "$1" in
 abort-upgrade | abort-deconfigure | abort-remove)
 	update-inetd --enable tftp
diff -Nru netkit-tftp-0.17/debian/tftpd.postrm netkit-tftp-0.17/debian/tftpd.postrm
--- netkit-tftp-0.17/debian/tftpd.postrm	2010-04-17 03:41:02.000000000 +0200
+++ netkit-tftp-0.17/debian/tftpd.postrm	2010-04-17 02:25:39.000000000 +0200
@@ -1,6 +1,8 @@
-#!/bin/sh -e
+#!/bin/sh
 # $Id: tftpd.postrm,v 1.2 2002/12/22 05:17:12 herbert Exp $
 
+set -e
+
 case "$1" in
 abort-install | abort-upgrade | upgrade | failed-upgrade | disappear)
 	;;
diff -Nru netkit-tftp-0.17/debian/watch netkit-tftp-0.17/debian/watch
--- netkit-tftp-0.17/debian/watch	1970-01-01 01:00:00.000000000 +0100
+++ netkit-tftp-0.17/debian/watch	2010-02-04 15:20:43.000000000 +0100
@@ -0,0 +1,2 @@
+version=3
+http://ftp.uk.linux.org/pub/linux/Networking/netkit/netkit-tftp-([.0-9]+)\.tar\.gz	debian	uupdate
diff -Nru netkit-tftp-0.17/MRULES netkit-tftp-0.17/MRULES
--- netkit-tftp-0.17/MRULES	2010-04-17 03:41:02.000000000 +0200
+++ netkit-tftp-0.17/MRULES	2000-07-22 20:59:18.000000000 +0200
@@ -1,8 +1,8 @@
 # Standard compilation rules (don't use make builtins)
 
 %.o: %.c
-	$(CC) $(CFLAGS) $< -c
+	$(CC) $(CFLAGS) -I../include $< -c
 
 %.o: %.cc
-	$(CC) $(CFLAGS) $< -c
+	$(CC) $(CFLAGS) -I../include $< -c
 
diff -Nru netkit-tftp-0.17/tftp/main.c netkit-tftp-0.17/tftp/main.c
--- netkit-tftp-0.17/tftp/main.c	2010-04-17 03:41:02.000000000 +0200
+++ netkit-tftp-0.17/tftp/main.c	2000-07-22 21:06:29.000000000 +0200
@@ -69,7 +69,7 @@
 #define	TIMEOUT		5		/* secs between rexmt's */
 
 struct sockaddr_in s_inn;
-int f = -1;
+int f;
 int trace;
 int verbose;
 int rexmtval = TIMEOUT;
@@ -151,11 +151,17 @@
 static struct cmd *getcmd(const char *name);
 static char *tail(char *filename);
 
-void initsock() {
+int
+main(int argc, char *argv[])
+{
 	struct sockaddr_in s_in;
+	int top;
 
-	if (f >= 0)
-		close(f);
+	sp = getservbyname("tftp", "udp");
+	if (sp == 0) {
+		fprintf(stderr, "tftp: udp/tftp: unknown service\n");
+		exit(1);
+	}
 	f = socket(AF_INET, SOCK_DGRAM, 0);
 	if (f < 0) {
 		perror("tftp: socket");
@@ -167,19 +173,6 @@
 		perror("tftp: bind");
 		exit(1);
 	}
-}
-
-int
-main(int argc, char *argv[])
-{
-	int top;
-
-	sp = getservbyname("tftp", "udp");
-	if (sp == 0) {
-		fprintf(stderr, "tftp: udp/tftp: unknown service\n");
-		exit(1);
-	}
-	initsock();
 	strcpy(mode, "netascii");
 	mysignal(SIGINT, intr);
 	if (argc > 1) {
@@ -209,10 +202,7 @@
 		argc = margc;
 		argv = margv;
 	}
-	/* We should have 2 or 3 args now: the cmd and its
-	 * parameters. If not, we bail out here.
-	 */
-	if (argc != 2 && argc != 3) {
+	if (argc > 3) {
 		printf("usage: %s host-name [port]\n", argv[0]);
 		return;
 	}
diff -Nru netkit-tftp-0.17/tftp/tftp.1 netkit-tftp-0.17/tftp/tftp.1
--- netkit-tftp-0.17/tftp/tftp.1	2010-04-17 03:41:02.000000000 +0200
+++ netkit-tftp-0.17/tftp/tftp.1	2000-07-31 01:57:10.000000000 +0200
@@ -84,7 +84,7 @@
 protocol, unlike the
 .Tn FTP
 protocol,
-does not maintain connections betwen transfers; thus, the
+does not maintain connections betweeen transfers; thus, the
 .Cm connect
 command does not actually create a connection,
 but merely remembers what host is to be used for transfers.
diff -Nru netkit-tftp-0.17/tftp/tftp.c netkit-tftp-0.17/tftp/tftp.c
--- netkit-tftp-0.17/tftp/tftp.c	2010-04-17 03:41:02.000000000 +0200
+++ netkit-tftp-0.17/tftp/tftp.c	2000-07-22 21:06:29.000000000 +0200
@@ -174,13 +174,19 @@
 				goto abort;
 			}
 			if (ap->th_opcode == ACK) {
+				volatile int j = 0;
+
 				if (ap->th_block == block) {
 					break;
 				}
 				/* On an error, try to synchronize
 				 * both sides.
 				 */
-				synchnet(f, trace);
+				j = synchnet(f);
+				if (j && trace) {
+					printf("discarded %d packets\n",
+							j);
+				}
 				if (ap->th_block == (block-1)) {
 					goto send_data;
 				}
@@ -191,14 +197,10 @@
 		}
 		else {
 			amount += size;
-			if (size != SEGSIZE) {
-				break;
-			}
 		}
 		block++;
-	} while (1);
+	} while (size == SEGSIZE);
 abort:
-	initsock();
 	fclose(file);
 	stopclock();
 	if (amount > 0)
@@ -276,13 +278,18 @@
 				goto abort;
 			}
 			if (dp->th_opcode == DATA) {
+				volatile int j = 0;
+
 				if (dp->th_block == block) {
 					break;          /* have next packet */
 				}
 				/* On an error, try to synchronize
 				 * both sides.
 				 */
-				synchnet(f, trace);
+				j = synchnet(f);
+				if (j && trace) {
+					printf("discarded %d packets\n", j);
+				}
 				if (dp->th_block == (block-1)) {
 					goto send_ack;  /* resend ack */
 				}
@@ -296,14 +303,10 @@
 		}
 		amount += size;
 	} while (size == SEGSIZE);
-
+abort:                                          /* ok to ack, since user */
 	ap->th_opcode = htons((u_short)ACK);    /* has seen err msg */
 	ap->th_block = htons((u_short)block);
 	(void) sendto(f, ackbuf, 4, 0, (struct sockaddr *)&s_inn, sizeof(s_inn));
-
-abort:
-	initsock();
-
 	write_behind(file, convert);            /* flush last buffer */
 	fclose(file);
 	stopclock();
diff -Nru netkit-tftp-0.17/tftp/tftpsubs.c netkit-tftp-0.17/tftp/tftpsubs.c
--- netkit-tftp-0.17/tftp/tftpsubs.c	2010-04-17 03:41:02.000000000 +0200
+++ netkit-tftp-0.17/tftp/tftpsubs.c	2000-07-22 21:06:29.000000000 +0200
@@ -249,8 +249,8 @@
  * when trace is active).
  */
 
-void
-synchnet(int f /* socket to flush */, int trace)
+int
+synchnet(int f /* socket to flush */)
 {
 	int i, j = 0;
 	char rbuf[PKTSIZE];
@@ -265,10 +265,7 @@
 			(void) recvfrom(f, rbuf, sizeof (rbuf), 0,
 				(struct sockaddr *)&from, &fromlen);
 		} else {
-			if (j && trace) {
-				printf("discarded %d packets\n", j);
-			}
-			return;
+			return(j);
 		}
 	}
 }
diff -Nru netkit-tftp-0.17/tftp/tftpsubs.h netkit-tftp-0.17/tftp/tftpsubs.h
--- netkit-tftp-0.17/tftp/tftpsubs.h	2010-04-17 03:41:02.000000000 +0200
+++ netkit-tftp-0.17/tftp/tftpsubs.h	2000-07-22 21:06:29.000000000 +0200
@@ -1,7 +1,6 @@
 #define PKTSIZE SEGSIZE+4       /* should be moved to tftp.h */
 
-void initsock(void);
-void synchnet(int, int);
+int synchnet(int);
 struct tftphdr *r_init(void);
 struct tftphdr *w_init(void);
 int readit(FILE *file, struct tftphdr **dpp, int convert);
diff -Nru netkit-tftp-0.17/tftpd/tftpd.8 netkit-tftp-0.17/tftpd/tftpd.8
--- netkit-tftp-0.17/tftpd/tftpd.8	2010-04-17 03:41:02.000000000 +0200
+++ netkit-tftp-0.17/tftpd/tftpd.8	2000-07-31 01:57:10.000000000 +0200
@@ -42,8 +42,6 @@
 Trivial File Transfer Protocol server
 .Sh SYNOPSIS
 .Nm tftpd
-.Op Fl n
-.Op Fl s
 .Op Ar directory ...
 .Sh DESCRIPTION
 .Nm Tftpd
@@ -113,18 +111,6 @@
 can be used to ensure that replies go out from the correct address.
 These considerations are important, because most tftp clients will
 reject reply packets that appear to come from an unexpected address.
-.Pp
-The options are:
-.Bl -tag -width Ds
-.It Fl n
-Suppresses negative acknowledgement of requests for nonexistent relative
-filenames.
-.It Fl s
-All absolute filenames are treated as if they were preceded by the first
-directory argument, or
-.Pa /tftpboot
-if there is none.
-.El
 .Sh SEE ALSO
 .Xr tftp 1 ,
 .Xr inetd 8
diff -Nru netkit-tftp-0.17/tftpd/tftpd.c netkit-tftp-0.17/tftpd/tftpd.c
--- netkit-tftp-0.17/tftpd/tftpd.c	2010-04-17 03:41:02.000000000 +0200
+++ netkit-tftp-0.17/tftpd/tftpd.c	2000-07-29 20:37:21.000000000 +0200
@@ -92,11 +92,8 @@
 static struct		sockaddr_in from;
 static socklen_t	fromlen;
 
-static const char	*default_dirs[] = { "/tftpboot", 0 };
-static const char	**dirs = default_dirs;
-
-static int		suppress_naks;
-static int		secure_tftp;
+#define MAXARG		4
+static char		*dirs[MAXARG+1];
 
 int
 main(int ac, char **av)
@@ -108,25 +105,12 @@
 	register struct tftphdr *tp;
 	register int n = 0;
 	int on = 1;
-	int ch;
 
+	ac--; av++;
+	if (ac==0) dirs[0] = "/tftpboot";  /* default directory */
+	while (ac-- > 0 && n < MAXARG)
+		dirs[n++] = *av++;
 	openlog("tftpd", LOG_PID, LOG_DAEMON);
-	opterr = 0;
-	while ((ch = getopt(ac, av, "ns")) != EOF) {
-		switch (ch) {
-		case 'n':
-			suppress_naks = 1;
-			break;
-		case 's':
-			secure_tftp = 1;
-			break;
-		default:
-			syslog(LOG_ERR, "unknown option -%c", ch);
-			exit(1);
-		}
-	}
-
-	if (av[optind]) dirs = (const char **) &av[optind];
 	if (ioctl(0, FIONBIO, &on) < 0) {
 		syslog(LOG_ERR, "ioctl(FIONBIO): %m\n");
 		exit(1);
@@ -295,12 +279,6 @@
 	}
 	ecode = (*pf->f_validate)(filename, tp->th_opcode);
 	if (ecode) {
-		/*
-		 * Avoid storms of naks to a RRQ broadcast for a relative
-		 * bootfile pathname from a diskless Sun.
-		 */
-		if (suppress_naks && *filename != '/' && ecode == ENOTFOUND)
-			exit(0);
 		nak(ecode);
 		exit(1);
 	}
@@ -332,17 +310,13 @@
 	struct stat stbuf;
 	int	fd;
 	const char *cp;
-	const char **dirp;
+	char **dirp;
 
 	syslog(LOG_NOTICE, "tftpd: trying to get file: %s\n", filename);
 
-	if (*filename != '/' || secure_tftp) {
+	if (*filename != '/') {
 		syslog(LOG_NOTICE, "tftpd: serving file from %s\n", dirs[0]);
-		/*chdir(dirs[0]);*/
-		if ( chdir(dirs[0]) < 0 )
-			return (EACCESS);
-		while (*filename == '/')
-			filename++;
+		chdir(dirs[0]);
 	} else {
 		for (dirp = dirs; *dirp; dirp++)
 			if (strncmp(filename, *dirp, strlen(*dirp)) == 0)
@@ -392,8 +366,7 @@
 		if ((stbuf.st_mode & S_IWOTH) == 0)
 			return (EACCESS);
 	}
-
-	fd = open(filename, mode == RRQ ? O_RDONLY : O_WRONLY|O_TRUNC|O_CREAT, 0600);
+	fd = open(filename, mode == RRQ ? O_RDONLY : O_WRONLY|O_TRUNC);
 	if (fd < 0)
 		return (errno + 100);
 	file = fdopen(fd, (mode == RRQ)? "r":"w");
@@ -468,7 +441,7 @@
 					break;
 				}
 				/* Re-synchronize with the other side */
-				(void) synchnet(peer, 0);
+				(void) synchnet(peer);
 				if (ap->th_block == (block -1)) {
 					goto send_data;
 				}
@@ -533,7 +506,7 @@
 					break;   /* normal */
 				}
 				/* Re-synchronize with the other side */
-				(void) synchnet(peer, 0);
+				(void) synchnet(peer);
 				if (dp->th_block == (block-1))
 					goto send_ack;          /* rexmit */
 			}

Attachment: signature.asc
Description: Digital signature

Reply via email to