diff -urN netbsd-tftp-20020313.orig/Makefile netbsd-tftp-20020313/Makefile
--- netbsd-tftp-20020313.orig/Makefile	Mon Nov 19 05:20:02 2001
+++ netbsd-tftp-20020313/Makefile	Wed Mar 13 13:28:41 2002
@@ -1,7 +1,30 @@
-#	$NetBSD: Makefile,v 1.7 2001/11/19 03:20:02 itojun Exp $
-#	@(#)Makefile	8.1 (Berkeley) 6/6/93
+CFLAGS = -Wall
 
-PROG=	tftp
-SRCS=	main.c tftp.c tftpsubs.c
+DESTDIR =
+BINDIR  = /usr/bin
+SBINDIR = /usr/sbin
+MANDIR  = /usr/share/man
 
-.include <bsd.prog.mk>
+INSTALL 	= /usr/bin/install -c
+INSTALL_PROGRAM = ${INSTALL}
+INSTALL_DATA    = ${INSTALL} -m 644
+
+all: tftp tftpd
+
+tftp: tftp.o main.o tftpsubs.o strlcpy.o
+
+tftpd: tftpd.o tftpsubs.o strlcpy.o
+
+install: all
+	mkdir -p $(DESTDIR)$(BINDIR) $(DESTDIR)$(SBINDIR) $(DESTDIR)$(MANDIR)/man1 $(DESTDIR)$(MANDIR)/man8
+	$(INSTALL_PROGRAM) tftp $(DESTDIR)$(BINDIR)	
+	$(INSTALL_PROGRAM) tftpd $(DESTDIR)$(SBINDIR)/in.tftpd
+	$(INSTALL_DATA)    tftp.1   $(DESTDIR)$(MANDIR)/man1
+	$(INSTALL_DATA)    tftpd.8   $(DESTDIR)$(MANDIR)/man8/in.tftpd.8	
+	cd $(DESTDIR)$(MANDIR)/man8 && ln -sf in.tftpd.8 tftpd.8
+
+clean:
+	rm -f *.o tftp tftpd
+
+distclean:
+	rm -f *~
diff -urN netbsd-tftp-20020313.orig/README netbsd-tftp-20020313/README
--- netbsd-tftp-20020313.orig/README	Thu Jan  1 02:00:00 1970
+++ netbsd-tftp-20020313/README	Wed Mar 13 13:32:18 2002
@@ -0,0 +1,11 @@
+tftp and tftpd ported from NetBSD CVS to Linux.
+
+This was done because IPv6-aware tftpd server was required to work
+properly with xinetd, and the one from OpenBSD (hpa-tftp) had become bloated
+and diverged from the source tree.
+
+strlcpy.[ch] were taken from OpenSSH source with minor modification
+
+Snapshot up-to-date as of 20020313.
+
+Pekka Savola <pekkas@netcore.fi>
diff -urN netbsd-tftp-20020313.orig/linux.h netbsd-tftp-20020313/linux.h
--- netbsd-tftp-20020313.orig/linux.h	Thu Jan  1 02:00:00 1970
+++ netbsd-tftp-20020313/linux.h	Wed Mar 13 13:22:51 2002
@@ -0,0 +1,28 @@
+/* Some definitions that are missing .. to ease the porting */
+
+#ifndef SA_LEN
+#ifdef __GLIBC__
+#define SA_LEN(x)	(((x)->sa_family == AF_INET6) ? sizeof(struct sockaddr_in6) \
+				: sizeof(struct sockaddr_in))
+#else
+#define SA_LEN(x)	((x)->sa_len)
+#endif
+#endif
+
+#ifndef SS_LEN
+#ifdef __GLIBC__
+#define SS_LEN(x)	SA_LEN((struct sockaddr *)&(x))
+#else
+#define SS_LEN(x)	((x)->ss_len)
+#endif
+#endif
+
+#ifndef UID_MAX
+#define UID_MAX 65535
+#endif
+
+#ifndef GID_MAX
+#define GID_MAX UID_MAX
+#endif
+
+#include "strlcpy.h"
diff -urN netbsd-tftp-20020313.orig/main.c netbsd-tftp-20020313/main.c
--- netbsd-tftp-20020313.orig/main.c	Sat Dec 30 20:00:18 2000
+++ netbsd-tftp-20020313/main.c	Wed Mar 13 12:29:58 2002
@@ -34,6 +34,7 @@
  */
 
 #include <sys/cdefs.h>
+#if 0
 #ifndef lint
 __COPYRIGHT("@(#) Copyright (c) 1983, 1993\n\
 	The Regents of the University of California.  All rights reserved.\n");
@@ -43,6 +44,7 @@
 __RCSID("$NetBSD: main.c,v 1.14 2000/12/30 18:00:18 itojun Exp $");
 #endif
 #endif /* not lint */
+#endif
 
 /* Many bug fixes are from Jim Guyton <guyton@rand-unix> */
 
@@ -70,6 +72,8 @@
 
 #include "extern.h"
 
+#include "linux.h"
+
 #define	TIMEOUT		5		/* secs between rexmt's */
 #define	LBUFLEN		200		/* size of input buffer */
 
@@ -104,7 +108,7 @@
 void	intr __P((int));
 struct cmd *getcmd __P((char *));
 
-static __dead void command __P((void));
+static void command __P((void));
 
 static void getusage __P((char *));
 static void makeargv __P((void));
@@ -211,8 +215,8 @@
 
 		memset(&ss, 0, sizeof(ss));
 		ss.ss_family = res->ai_family;
-		ss.ss_len = res->ai_addrlen;
-		if (bind(f, (struct sockaddr *)&ss, ss.ss_len) < 0) {
+		/* ss.ss_len = res->ai_addrlen; */
+		if (bind(f, (struct sockaddr *)&ss, SS_LEN(ss)) < 0) {
 			cause = "bind";
 			close(f);
 			f = -1;
@@ -607,7 +611,7 @@
 /*
  * Command parser.
  */
-static __dead void
+static void
 command()
 {
 	struct cmd *c;
diff -urN netbsd-tftp-20020313.orig/strlcpy.c netbsd-tftp-20020313/strlcpy.c
--- netbsd-tftp-20020313.orig/strlcpy.c	Thu Jan  1 02:00:00 1970
+++ netbsd-tftp-20020313/strlcpy.c	Wed Mar 13 12:18:32 2002
@@ -0,0 +1,74 @@
+/*	$OpenBSD: strlcpy.c,v 1.5 2001/05/13 15:40:16 deraadt Exp $	*/
+
+/*
+ * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef HAVE_STRLCPY
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char *rcsid = "$OpenBSD: strlcpy.c,v 1.5 2001/05/13 15:40:16 deraadt Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <string.h>
+#include "strlcpy.h"
+
+/*
+ * Copy src to string dst of size siz.  At most siz-1 characters
+ * will be copied.  Always NUL terminates (unless siz == 0).
+ * Returns strlen(src); if retval >= siz, truncation occurred.
+ */
+size_t
+strlcpy(dst, src, siz)
+	char *dst;
+	const char *src;
+	size_t siz;
+{
+	register char *d = dst;
+	register const char *s = src;
+	register size_t n = siz;
+
+	/* Copy as many bytes as will fit */
+	if (n != 0 && --n != 0) {
+		do {
+			if ((*d++ = *s++) == 0)
+				break;
+		} while (--n != 0);
+	}
+
+	/* Not enough room in dst, add NUL and traverse rest of src */
+	if (n == 0) {
+		if (siz != 0)
+			*d = '\0';		/* NUL-terminate dst */
+		while (*s++)
+			;
+	}
+
+	return(s - src - 1);	/* count does not include NUL */
+}
+
+#endif /* !HAVE_STRLCPY */
diff -urN netbsd-tftp-20020313.orig/strlcpy.h netbsd-tftp-20020313/strlcpy.h
--- netbsd-tftp-20020313.orig/strlcpy.h	Thu Jan  1 02:00:00 1970
+++ netbsd-tftp-20020313/strlcpy.h	Wed Mar 13 12:19:04 2002
@@ -0,0 +1,11 @@
+/* $Id: strlcpy.h,v 1.2 2001/02/09 01:55:36 djm Exp $ */
+
+#ifndef _BSD_STRLCPY_H
+#define _BSD_STRLCPY_H
+
+#ifndef HAVE_STRLCPY
+#include <sys/types.h>
+size_t strlcpy(char *dst, const char *src, size_t siz);
+#endif /* !HAVE_STRLCPY */
+
+#endif /* _BSD_STRLCPY_H */
diff -urN netbsd-tftp-20020313.orig/tftp.c netbsd-tftp-20020313/tftp.c
--- netbsd-tftp-20020313.orig/tftp.c	Sat Dec 30 20:00:18 2000
+++ netbsd-tftp-20020313/tftp.c	Wed Mar 13 12:29:31 2002
@@ -34,6 +34,7 @@
  */
 
 #include <sys/cdefs.h>
+#if 0
 #ifndef lint
 #if 0
 static char sccsid[] = "@(#)tftp.c	8.1 (Berkeley) 6/6/93";
@@ -41,6 +42,7 @@
 __RCSID("$NetBSD: tftp.c,v 1.15 2000/12/30 18:00:18 itojun Exp $");
 #endif
 #endif /* not lint */
+#endif
 
 /* Many bug fixes are from Jim Guyton <guyton@rand-unix> */
 
@@ -67,6 +69,8 @@
 #include "extern.h"
 #include "tftpsubs.h"
 
+#include "linux.h"
+
 extern  struct sockaddr_storage peeraddr; /* filled in by main */
 extern  int     f;			/* the opened socket */
 extern  int     trace;
@@ -117,7 +121,7 @@
 	convert = !strcmp(mode, "netascii");
 	block = 0;
 	amount = 0;
-	memcpy(&peer, &peeraddr, peeraddr.ss_len);
+	memcpy(&peer, &peeraddr, SS_LEN(peeraddr));
 	memset(&serv, 0, sizeof(serv));
 
 	signal(SIGALRM, timer);
@@ -140,7 +144,7 @@
 		if (trace)
 			tpacket("sent", dp, size + 4);
 		n = sendto(f, dp, size + 4, 0,
-		    (struct sockaddr *)&peer, peer.ss_len);
+		    (struct sockaddr *)&peer, SS_LEN(peer));
 		if (n != size + 4) {
 			warn("sendto");
 			goto abort;
@@ -236,7 +240,7 @@
 	block = 1;
 	firsttrip = 1;
 	amount = 0;
-	memcpy(&peer, &peeraddr, peeraddr.ss_len);
+	memcpy(&peer, &peeraddr, SS_LEN(peeraddr));
 	memset(&serv, 0, sizeof(serv));
 
 	signal(SIGALRM, timer);
@@ -256,7 +260,7 @@
 		if (trace)
 			tpacket("sent", ap, size);
 		if (sendto(f, ackbuf, size, 0, (struct sockaddr *)&peer,
-		    peer.ss_len) != size) {
+		    SS_LEN(peer)) != size) {
 			alarm(0);
 			warn("sendto");
 			goto abort;
@@ -322,7 +326,7 @@
 	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 *)&peer,
-	    peer.ss_len);
+	    SS_LEN(peer));
 	write_behind(file, convert);		/* flush last buffer */
 	fclose(file);
 	stopclock();
@@ -402,7 +406,7 @@
 	msglen = &tp->th_msg[length + 1] - ackbuf;
 	if (trace)
 		tpacket("sent", tp, (int)msglen);
-	if (sendto(f, ackbuf, msglen, 0, peer, peer->sa_len) != length)
+	if (sendto(f, ackbuf, msglen, 0, peer, SA_LEN(peer)) != length)
 		warn("nak");
 }
 
@@ -504,9 +508,9 @@
 {
 	char a[NI_MAXSERV], b[NI_MAXSERV];
 
-	if (getnameinfo(sa, sa->sa_len, NULL, 0, a, sizeof(a), NI_NUMERICSERV))
+	if (getnameinfo(sa, SA_LEN(sa), NULL, 0, a, sizeof(a), NI_NUMERICSERV))
 		return 0;
-	if (getnameinfo(sb, sb->sa_len, NULL, 0, b, sizeof(b), NI_NUMERICSERV))
+	if (getnameinfo(sb, SA_LEN(sb), NULL, 0, b, sizeof(b), NI_NUMERICSERV))
 		return 0;
 	if (strcmp(a, b) != 0)
 		return 0;
diff -urN netbsd-tftp-20020313.orig/tftpd.c netbsd-tftp-20020313/tftpd.c
--- netbsd-tftp-20020313.orig/tftpd.c	Tue Oct  9 21:46:18 2001
+++ netbsd-tftp-20020313/tftpd.c	Wed Mar 13 13:17:13 2002
@@ -34,6 +34,7 @@
  */
 
 #include <sys/cdefs.h>
+#if 0
 #ifndef lint
 __COPYRIGHT("@(#) Copyright (c) 1983, 1993\n\
 	The Regents of the University of California.  All rights reserved.\n");
@@ -43,6 +44,7 @@
 __RCSID("$NetBSD: tftpd.c,v 1.24 2001/10/09 18:46:18 christos Exp $");
 #endif
 #endif /* not lint */
+#endif
 
 /*
  * Trivial file transfer protocol server.
@@ -76,6 +78,8 @@
 #include <syslog.h>
 #include <unistd.h>
 
+#include "linux.h"
+
 #include "tftpsubs.h"
 
 #define	DEFAULTUSER	"nobody"
@@ -142,8 +146,7 @@
 {
 
 	syslog(LOG_ERR,
-    "Usage: %s [-dln] [-u user] [-g group] [-s directory] [directory ...]",
-		    getprogname());
+    "Usage: tftpd [-dln] [-u user] [-g group] [-s directory] [directory ...]");
 	exit(1);
 }
 
@@ -368,7 +371,7 @@
 	} else {
 		memset(&me, 0, sizeof(me));
 		me.ss_family = from.ss_family;
-		me.ss_len = from.ss_len;
+		/* me.ss_len = from.ss_len; */
 	}
 
 	alarm(0);
@@ -379,11 +382,11 @@
 		syslog(LOG_ERR, "socket: %m");
 		exit(1);
 	}
-	if (bind(peer, (struct sockaddr *)&me, me.ss_len) < 0) {
+	if (bind(peer, (struct sockaddr *)&me, SS_LEN(me)) < 0) {
 		syslog(LOG_ERR, "bind: %m");
 		exit(1);
 	}
-	if (connect(peer, (struct sockaddr *)&from, from.ss_len) < 0) {
+	if (connect(peer, (struct sockaddr *)&from, SS_LEN(from)) < 0) {
 		syslog(LOG_ERR, "connect: %m");
 		exit(1);
 	}
@@ -855,7 +858,7 @@
 {
 	static char hbuf[MAXHOSTNAMELEN];
 
-	if (getnameinfo(fromp, fromp->sa_len, hbuf, sizeof(hbuf), NULL, 0, 0))
+	if (getnameinfo(fromp, SA_LEN(fromp), hbuf, sizeof(hbuf), NULL, 0, 0))
 		strlcpy(hbuf, "?", sizeof(hbuf));
 	return (hbuf);
 }
diff -urN netbsd-tftp-20020313.orig/tftpsubs.c netbsd-tftp-20020313/tftpsubs.c
--- netbsd-tftp-20020313.orig/tftpsubs.c	Mon Jul 12 23:19:21 1999
+++ netbsd-tftp-20020313/tftpsubs.c	Wed Mar 13 12:16:56 2002
@@ -34,6 +34,7 @@
  */
 
 #include <sys/cdefs.h>
+#if 0
 #ifndef lint
 #if 0
 static char sccsid[] = "@(#)tftpsubs.c	8.1 (Berkeley) 6/6/93";
@@ -41,6 +42,7 @@
 __RCSID("$NetBSD: tftpsubs.c,v 1.6 1999/07/12 20:19:21 itojun Exp $");
 #endif
 #endif /* not lint */
+#endif
 
 /* Simple minded read-ahead/write-behind subroutines for tftp user and
    server.  Written originally with multiple buffers in mind, but current
