--- /dev/null
+# Copyright (C) 2006 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+# $Id$
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=atftp
+PKG_VERSION:=0.7
+PKG_RELEASE:=1
+PKG_MD5SUM:=3b27365772d918050b2251d98a9c7c82
+
+PKG_SOURCE_URL:=ftp://ftp.mamalinux.com/pub/atftp/
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_CAT:=zcat
+
+PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
+PKG_INSTALL_DIR:=$(PKG_BUILD_DIR)/ipkg-install
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/atftp
+ SECTION:=net
+ CATEGORY:=Network
+ DEPENDS:=+libreadline +libpcre
+ MENU:=1
+ TITLE:=TFTP client
+ DESCRIPTION:=TFTP client
+ URL:=ftp://ftp.mamalinux.com/pub/atftp/
+endef
+
+define Package/atftpd
+ SECTION:=net
+ CATEGORY:=Network
+ DEPENDS:=atftp +libreadline +libpcre
+ TITLE:=TFTP server
+ DESCRIPTION:=TFTP server
+ URL:=ftp://ftp.mamalinux.com/pub/atftp/
+endef
+
+define Package/atftpd/postinst
+#!/bin/sh
+grep -q '^tftp[[:space:]]*69/tcp' ${IPKG_INSTROOT}/etc/services 2>/dev/null
+if [ $? -ne 0 ]; then
+ echo "tftp 69/tcp" >>${IPKG_INSTROOT}/etc/services
+ echo "tftp 69/udp" >>${IPKG_INSTROOT}/etc/services
+ echo "tftp-mcast 1758/tcp" >>${IPKG_INSTROOT}/etc/services
+ echo "tftp-mcast 1758/udp" >>${IPKG_INSTROOT}/etc/services
+fi
+endef
+
+define Build/Configure
+$(call Build/Configure/Default)
+endef
+
+define Build/Compile
+ rm -rf $(PKG_INSTALL_DIR)
+ mkdir -p $(PKG_INSTALL_DIR)
+ $(MAKE) -C $(PKG_BUILD_DIR) \
+ $(TARGET_CONFIGURE_OPTS) \
+ CFLAGS="$(TARGET_CFLAGS) -Wall -D_REENTRANT" \
+ DESTDIR=$(PKG_INSTALL_DIR) \
+ all install
+endef
+
+define Package/atftp/install
+ install -m0755 -d $(1)/usr/sbin
+ $(CP) $(PKG_BUILD_DIR)/$(PKG_NAME) $(1)/usr/sbin
+endef
+
+define Package/atftpd/install
+ install -m0755 -d $(1)/usr/sbin
+ $(CP) $(PKG_BUILD_DIR)/$(PKG_NAME) $(1)/usr/sbin/
+endef
+
+$(eval $(call BuildPackage,atftp))
+$(eval $(call BuildPackage,atftpd))
--- /dev/null
+diff -urN atftp.old/tftp.c atftp.dev/tftp.c
+--- atftp.old/tftp.c 2004-03-16 00:55:56.000000000 +0100
++++ atftp.dev/tftp.c 2006-03-22 10:18:54.000000000 +0100
+@@ -409,7 +409,7 @@
+ int set_peer(int argc, char **argv)
+ {
+ struct hostent *host; /* for host name lookup */
+- struct servent *sp; /* server entry for tftp service */
++ int port = htons(69);
+
+ /* sanity check */
+ if ((argc < 2) || (argc > 3))
+@@ -418,13 +418,6 @@
+ return ERR;
+ }
+
+- /* get the server entry */
+- sp = getservbyname("tftp", "udp");
+- if (sp == 0) {
+- fprintf(stderr, "tftp: udp/tftp, unknown service.\n");
+- return ERR;
+- }
+-
+ /* look up the host */
+ host = gethostbyname(argv[1]);
+ /* if valid, update s_inn structure */
+@@ -437,7 +430,7 @@
+ Strncpy(data.hostname, host->h_name,
+ sizeof(data.hostname));
+ data.hostname[sizeof(data.hostname)-1] = 0;
+- data.sa_peer.sin_port = sp->s_port;
++ data.sa_peer.sin_port = port;
+ }
+ else
+ {
+@@ -448,17 +441,17 @@
+ /* get the server port */
+ if (argc == 3)
+ {
+- sp->s_port = htons(atoi(argv[2]));
+- if (sp->s_port < 0)
++ port = htons(atoi(argv[2]));
++ if (port < 0)
+ {
+ fprintf(stderr, "%s: bad port number.\n", argv[2]);
+ data.connected = 0;
+ return ERR;
+ }
+- data.sa_peer.sin_port = sp->s_port;
++ data.sa_peer.sin_port = port;
+ }
+ /* copy port number to data structure */
+- data.port = ntohs(sp->s_port);
++ data.port = ntohs(port);
+
+ data.connected = 1;
+ return OK;
+diff -urN atftp.old/tftpd.c atftp.dev/tftpd.c
+--- atftp.old/tftpd.c 2004-02-27 03:05:26.000000000 +0100
++++ atftp.dev/tftpd.c 2006-03-22 10:23:20.000000000 +0100
+@@ -230,14 +230,8 @@
+
+ /* find the port */
+ if (tftpd_port == 0)
+- {
+- if ((serv = getservbyname("tftp", "udp")) == NULL)
+- {
+- logger(LOG_ERR, "atftpd: udp/tftp, unknown service");
+- exit(1);
+- }
+- tftpd_port = ntohs(serv->s_port);
+- }
++ tftpd_port = htons(69);
++
+ /* initialise sockaddr_in structure */
+ memset(&sa, 0, sizeof(sa));
+ sa.sin_family = AF_INET;
--- /dev/null
+diff -urN atftp.old/tftp.c atftp.dev/tftp.c
+--- atftp.old/tftp.c 2006-03-25 16:41:49.000000000 +0100
++++ atftp.dev/tftp.c 2006-03-25 18:10:04.000000000 +0100
+@@ -967,6 +967,7 @@
+ { "tftp-timeout", 1, NULL, 'T'},
+ { "mode", 1, NULL, 'M'},
+ { "option", 1, NULL, 'O'},
++ { "retry", 1, NULL, 'R'},
+ #if 1
+ { "timeout", 1, NULL, 't'},
+ { "blksize", 1, NULL, 'b'},
+@@ -986,11 +987,16 @@
+ };
+
+ /* Support old argument until 0.8 */
+- while ((c = getopt_long(argc, argv, /*"gpl:r:Vh"*/ "gpl:r:Vht:b:sm",
++ while ((c = getopt_long(argc, argv, /*"gpl:r:Vh"*/ "gpl:r:Vht:b:smR:",
+ options, &option_index)) != EOF)
+ {
+ switch (c)
+ {
++ case 'R':
++ snprintf(string, sizeof(string), "option retry %s", optarg);
++ make_arg(string, &ac, &av);
++ process_cmd(ac, av);
++ break;
+ case 'g':
+ interactive = 0;
+ if ((action == PUT) || (action == MGET))
+diff -urN atftp.old/tftp_def.c atftp.dev/tftp_def.c
+--- atftp.old/tftp_def.c 2004-02-13 04:16:09.000000000 +0100
++++ atftp.dev/tftp_def.c 2006-03-25 18:10:04.000000000 +0100
+@@ -37,6 +37,7 @@
+ { "timeout", "5", 0, 1 }, /* 2348, 2349, 2090. */
+ { "blksize", "512", 0, 1 }, /* This is the default option */
+ { "multicast", "", 0, 1 }, /* structure */
++ { "retry", "5", 0, 1 },
+ { "", "", 0, 0}
+ };
+
+diff -urN atftp.old/tftp_def.h atftp.dev/tftp_def.h
+--- atftp.old/tftp_def.h 2004-02-13 04:16:09.000000000 +0100
++++ atftp.dev/tftp_def.h 2006-03-25 17:19:15.000000000 +0100
+@@ -40,7 +40,8 @@
+ #define OPT_TIMEOUT 3
+ #define OPT_BLKSIZE 4
+ #define OPT_MULTICAST 5
+-#define OPT_NUMBER 7
++#define OPT_RETRY 6
++#define OPT_NUMBER 8
+
+ #define OPT_SIZE 12
+ #define VAL_SIZE MAXLEN
+diff -urN atftp.old/tftp_file.c atftp.dev/tftp_file.c
+--- atftp.old/tftp_file.c 2004-02-13 04:16:09.000000000 +0100
++++ atftp.dev/tftp_file.c 2006-03-25 18:10:04.000000000 +0100
+@@ -123,6 +123,7 @@
+ struct tftphdr *tftphdr = (struct tftphdr *)data->data_buffer;
+ FILE *fp = NULL; /* the local file pointer */
+ int number_of_timeout = 0;
++ int num_retry = atoi(data->tftp_options[OPT_RETRY].value);
+ int convert = 0; /* if true, do netascii convertion */
+
+ int oacks = 0; /* count OACK for improved error checking */
+@@ -141,7 +142,7 @@
+
+ int prev_block_number = 0; /* needed to support netascii convertion */
+ int temp = 0;
+-
++
+ data->file_size = 0;
+ tftp_cancel = 0;
+ from.sin_addr.s_addr = 0;
+@@ -288,7 +289,7 @@
+ case GET_TIMEOUT:
+ number_of_timeout++;
+ fprintf(stderr, "timeout: retrying...\n");
+- if (number_of_timeout > NB_OF_RETRY)
++ if ((num_retry > 0) && (number_of_timeout > num_retry))
+ state = S_ABORT;
+ else
+ state = timeout_state;
+@@ -325,7 +326,7 @@
+ number_of_timeout++;
+ fprintf(stderr, "tftp: packet discard <%s:%d>.\n",
+ inet_ntoa(from.sin_addr), ntohs(from.sin_port));
+- if (number_of_timeout > NB_OF_RETRY)
++ if ((num_retry > 0) && (number_of_timeout > num_retry))
+ state = S_ABORT;
+ break;
+ case ERR:
+@@ -614,6 +615,7 @@
+ struct tftphdr *tftphdr = (struct tftphdr *)data->data_buffer;
+ FILE *fp; /* the local file pointer */
+ int number_of_timeout = 0;
++ int num_retry = atoi(data->tftp_options[OPT_RETRY].value);
+ struct stat file_stat;
+ int convert = 0; /* if true, do netascii convertion */
+ char string[MAXLEN];
+@@ -751,7 +753,7 @@
+ case GET_TIMEOUT:
+ number_of_timeout++;
+ fprintf(stderr, "timeout: retrying...\n");
+- if (number_of_timeout > NB_OF_RETRY)
++ if ((num_retry > 0) && (number_of_timeout > num_retry))
+ state = S_ABORT;
+ else
+ state = timeout_state;
+@@ -797,7 +799,7 @@
+ number_of_timeout++;
+ fprintf(stderr, "tftp: packet discard <%s:%d>.\n",
+ inet_ntoa(from.sin_addr), ntohs(from.sin_port));
+- if (number_of_timeout > NB_OF_RETRY)
++ if ((num_retry > 0) && (number_of_timeout > num_retry))
+ state = S_ABORT;
+ break;
+ case ERR: