diff --git a/CHANGES b/CHANGES index 15874ab..0426417 100644 --- a/CHANGES +++ b/CHANGES @@ -1,5 +1,20 @@ $Id$ +Changes in 0.26: + Fix the configuration process so tftpd doesn't end up + depending on readline, which apparently could happen on some + platforms before. + + Make parallel builds (make -j) work correctly. + + Improve parsing of the "connect" command in the tftp client. + + Add a -V option to both tftp and tftpd to print the version + number on stdout and immediately exit. + + Add a -v option to tftp to start out in verbose mode. + + Changes in 0.25: Fixed Sorcerer's Apprentice bug in both the client and the server. These bugs were inherited from the original BSD code. diff --git a/MCONFIG.in b/MCONFIG.in index d9d5718..5e1d8f1 100644 --- a/MCONFIG.in +++ b/MCONFIG.in @@ -43,8 +43,9 @@ CFLAGS = @CFLAGS@ -I$(SRCROOT) # Link flags LDFLAGS = @LDFLAGS@ -# Libraries -LIBS = @LIBS@ +# Libraries (client and server) +TFTP_LIBS = @TFTP_LIBS@ +TFTPD_LIBS = @TFTPD_LIBS@ # Additional library we need to build LIBOBJS = @LIBOBJS@ diff --git a/Makefile b/Makefile index 4c2369e..df6e0fc 100644 --- a/Makefile +++ b/Makefile @@ -3,10 +3,10 @@ SUB = lib tftp tftpd -%.build: +%.build: MCONFIG acconfig.h version.h $(MAKE) -C $(patsubst %.build, %, $@) -%.install: +%.install: MCONFIG acconfig.h version.h $(MAKE) -C $(patsubst %.install, %, $@) install %.clean: @@ -17,9 +17,13 @@ SUB = lib tftp tftpd all: MCONFIG $(patsubst %, %.build, $(SUB)) +tftp.build: lib.build +tftpd.build: lib.build + install: MCONFIG $(patsubst %, %.install, $(SUB)) clean: $(patsubst %, %.clean, $(SUB)) + rm -f version.h distclean: $(patsubst %, %.distclean, $(SUB)) rm -f MCONFIG config.status config.log acconfig.h *~ \#* @@ -51,3 +55,6 @@ acconfig.h.in: configure.in aclocal.m4 configure: configure.in aclocal.m4 autoconf rm -f MCONFIG config.cache config.log acconfig.h + +version.h: version + echo \#define VERSION \"tftp-hpa `cat version`\" > version.h diff --git a/config.h b/config.h index 7585381..1230971 100644 --- a/config.h +++ b/config.h @@ -78,7 +78,6 @@ #endif #include -#include #include /* If we don't have intmax_t, try creating it */ @@ -172,7 +171,9 @@ typedef unsigned long u_long; #endif #endif -/* Sometimes IPPORT_TFTP isn't defined */ +/* netinet/in.h, and possible missing pieces */ + +#include #ifndef HAVE_IPPORT_TFTP_DEFINITION #ifndef IPPORT_TFTP @@ -180,4 +181,19 @@ typedef unsigned long u_long; #endif #endif +/* arpa/tftp.h, and possible missing pieces */ + +#include + +#ifndef OACK +#define OACK 6 +#endif +#ifndef EOPTNEG +#define EOPTNEG 8 +#endif + +/* tftp-hpa version */ + +#include "version.h" + #endif diff --git a/configure.in b/configure.in index e76decf..2cb2512 100644 --- a/configure.in +++ b/configure.in @@ -73,6 +73,23 @@ AC_CHECK_FUNCS(strtoull) PA_MSGHDR_MSG_CONTROL PA_STRUCT_IN_PKTINFO +AH_TEMPLATE([HAVE_SIGSETJMP], +[Define if we have sigsetjmp, siglongjmp and sigjmp_buf.]) +PA_SIGSETJMP([AC_DEFINE(HAVE_SIGSETJMP)]) + +LIBXTRA=false +AC_SEARCH_LIBS(xmalloc, iberty, , LIBXTRA=true LIBOBJS="$LIBOBJS xmalloc.o") +AC_SEARCH_LIBS(xstrdup, iberty, , LIBXTRA=true LIBOBJS="$LIBOBJS xstrdup.o") +AC_SEARCH_LIBS(bsd_signal, bsd, , LIBXTRA=true LIBOBJS="$LIBOBJS bsdsignal.o") +if $LIBXTRA; then + LIBS="../lib/libxtra.a $LIBS" +fi + +dnl +dnl These libraries apply to the server only +dnl + +common_libs="$LIBS" AH_TEMPLATE([HAVE_IPPORT_TFTP_DEFINITION], [Define if netinet/in.h defines IPPORT_TFTP.]) @@ -85,6 +102,7 @@ PA_WITH_BOOL(tcpwrappers, 1, PA_HAVE_TCPWRAPPERS ],:) + AH_TEMPLATE([WITH_REGEX], [Define if we are compiling with regex filename remapping.]) @@ -101,6 +119,13 @@ PA_WITH_BOOL(remap, 1, ]) ],:) +TFTPD_LIBS="$LIBS" +LIBS="$common_libs" + +dnl +dnl These libraries apply to the client only +dnl + AH_TEMPLATE([WITH_READLINE], [Define if we are compiling with readline command-line editing.]) @@ -119,18 +144,11 @@ PA_WITH_BOOL(readline, 1, fi ],:) -AH_TEMPLATE([HAVE_SIGSETJMP], -[Define if we have sigsetjmp, siglongjmp and sigjmp_buf.]) -PA_SIGSETJMP([AC_DEFINE(HAVE_SIGSETJMP)]) - -LIBXTRA=false -AC_SEARCH_LIBS(xmalloc, iberty, , LIBXTRA=true LIBOBJS="$LIBOBJS xmalloc.o") -AC_SEARCH_LIBS(xstrdup, iberty, , LIBXTRA=true LIBOBJS="$LIBOBJS xstrdup.o") -AC_SEARCH_LIBS(bsd_signal, bsd, , LIBXTRA=true LIBOBJS="$LIBOBJS bsdsignal.o") -if $LIBXTRA; then - LIBS="../lib/libxtra.a $LIBS" -fi +TFTP_LIBS="$LIBS" +LIBS="$common_libs" +AC_SUBST(TFTP_LIBS) +AC_SUBST(TFTPD_LIBS) AC_SUBST(LIBOBJS) AC_SUBST(TFTPDOBJS) diff --git a/tftp/Makefile b/tftp/Makefile index ca91196..8cac750 100644 --- a/tftp/Makefile +++ b/tftp/Makefile @@ -8,7 +8,7 @@ include ../MRULES OBJS = tftp.o main.o tftpsubs.o tftp: $(OBJS) - $(CC) $(LDFLAGS) $^ $(LIBS) -o $@ + $(CC) $(LDFLAGS) $^ $(TFTP_LIBS) -o $@ $(OBJS): tftpsubs.h diff --git a/tftp/main.c b/tftp/main.c index 7ff7d2e..bc88583 100644 --- a/tftp/main.c +++ b/tftp/main.c @@ -81,7 +81,7 @@ static const char *rcsid UNUSED = struct sockaddr_in peeraddr; int f; -short port; +u_short port; int trace; int verbose; int connected; @@ -182,10 +182,37 @@ int main(int argc, char *argv[]) { struct sockaddr_in s_in; + int c; + int pargc; + char **pargv; + + while ((c = getopt(argc, argv, "Vv")) != -1) { + switch (c) { + case 'v': + verbose = 1; + break; + case 'V': + /* Print version to stdout and exit */ + printf("%s\n", VERSION); + exit(0); + default: + fprintf(stderr, "Usage: %s [-v] [host]\n", argv[0]); + exit(EX_USAGE); + } + } + + pargc = argc - (optind-1); + pargv = argv + (optind-1); sp = getservbyname("tftp", "udp"); if (sp == 0) { - fprintf(stderr, "tftp: udp/tftp: unknown service\n"); + /* Use canned values */ + fprintf(stderr, "tftp: tftp/udp: unknown service, faking it...\n"); + sp = xmalloc(sizeof(struct servent)); + sp->s_name = (char *)"tftp"; + sp->s_aliases = NULL; + sp->s_port = htons(IPPORT_TFTP); + sp->s_proto = (char *)"udp"; exit(1); } f = socket(AF_INET, SOCK_DGRAM, 0); @@ -201,10 +228,10 @@ main(int argc, char *argv[]) } strcpy(mode, "netascii"); bsd_signal(SIGINT, intr); - if (argc > 1) { + if (pargc > 1) { if (sigsetjmp(toplevel,1) != 0) exit(0); - setpeer(argc, argv); + setpeer(pargc, pargv); } if (sigsetjmp(toplevel,1) != 0) (void)putchar('\n'); @@ -269,29 +296,40 @@ setpeer(int argc, char *argv[]) printf("usage: %s host-name [port]\n", argv[0]); return; } - if (inet_aton(argv[1], &peeraddr.sin_addr) != 0) { - peeraddr.sin_family = AF_INET; - hostname = xstrdup(argv[1]); - } else { - host = gethostbyname(argv[1]); - if (host == 0) { - connected = 0; - printf("%s: unknown host\n", argv[1]); - return; - } - peeraddr.sin_family = host->h_addrtype; - bcopy(host->h_addr, &peeraddr.sin_addr, host->h_length); - hostname = xstrdup(host->h_name); + + host = gethostbyname(argv[1]); + if (host == 0) { + connected = 0; + printf("%s: unknown host\n", argv[1]); + return; } + peeraddr.sin_family = host->h_addrtype; + bcopy(host->h_addr, &peeraddr.sin_addr, host->h_length); + hostname = xstrdup(host->h_name); + port = sp->s_port; if (argc == 3) { - port = atoi(argv[2]); - if (port < 0) { - printf("%s: bad port number\n", argv[2]); - connected = 0; - return; + struct servent *usp; + usp = getservbyname(argv[2], "udp"); + if ( usp ) { + port = usp->s_port; + } else { + unsigned long myport; + char *ep; + myport = strtoul(argv[2], &ep, 10); + if (*ep || myport > 65535UL) { + printf("%s: bad port number\n", argv[2]); + connected = 0; + return; + } + port = htons((u_short)myport); } - port = htons(port); + } + + if (verbose) { + printf("Connected to %s (%s), port %u\n", + hostname, inet_ntoa(peeraddr.sin_addr), + (unsigned int)ntohs(port)); } connected = 1; } @@ -740,6 +778,8 @@ help(int argc, char *argv[]) { struct cmd *c; + printf("%s\n", VERSION); + if (argc == 1) { printf("Commands may be abbreviated. Commands are:\n\n"); for (c = cmdtab; c->name; c++) diff --git a/tftp/tftp.c b/tftp/tftp.c index 46000d4..017767f 100644 --- a/tftp/tftp.c +++ b/tftp/tftp.c @@ -74,13 +74,6 @@ extern int verbose; extern int rexmtval; extern int maxtimeout; -#ifndef EOPTNEG -#define EOPTNEG 8 -#endif -#ifndef OACK -#define OACK 6 -#endif - #define PKTSIZE SEGSIZE+4 char ackbuf[PKTSIZE]; int timeout; diff --git a/tftpd/Makefile b/tftpd/Makefile index f538c97..014e7fd 100644 --- a/tftpd/Makefile +++ b/tftpd/Makefile @@ -8,7 +8,7 @@ include ../MRULES OBJS = tftpd.o tftpsubs.o recvfrom.o misc.o $(TFTPDOBJS) tftpd: $(OBJS) - $(CC) $(LDFLAGS) $^ $(LIBS) -o $@ + $(CC) $(LDFLAGS) $^ $(TFTPD_LIBS) -o $@ tftpsubs.c: ln -sf ../tftp/tftpsubs.c . diff --git a/tftpd/tftpd.c b/tftpd/tftpd.c index 4f700c9..8640328 100644 --- a/tftpd/tftpd.c +++ b/tftpd/tftpd.c @@ -98,13 +98,6 @@ struct request_info wrap_request; #define TRIES 4 /* Number of attempts to send each packet */ #define TIMEOUT_LIMIT (TRIES*(TRIES+1)/2) -#ifndef OACK -#define OACK 6 -#endif -#ifndef EOPTNEG -#define EOPTNEG 8 -#endif - char *__progname; int peer; int timeout = TIMEOUT; @@ -221,7 +214,7 @@ main(int argc, char **argv) openlog(__progname, LOG_PID|LOG_NDELAY, LOG_DAEMON); - while ((c = getopt(argc, argv, "csvla:u:r:t:m:")) != -1) + while ((c = getopt(argc, argv, "csvVla:u:r:t:m:")) != -1) switch (c) { case 'c': cancreate = 1; @@ -265,6 +258,11 @@ main(int argc, char **argv) case 'v': verbosity++; break; + case 'V': + /* Print version to stdout and exit */ + printf("%s\n", VERSION); + exit(0); + break; default: usage(); break; diff --git a/version b/version new file mode 100644 index 0000000..9922215 --- /dev/null +++ b/version @@ -0,0 +1 @@ +0.26