From 61ad9979c89958b36e0d1dc72ae61004c3e32463 Mon Sep 17 00:00:00 2001 From: Sam Leffler Date: Sun, 12 Jun 1983 08:26:48 -0800 Subject: [PATCH] too much to say...let's just say it seems to work now SCCS-vsn: usr.bin/tftp/Makefile 4.5 SCCS-vsn: usr.bin/tftp/main.c 4.6 SCCS-vsn: usr.bin/tftp/tftp.c 4.6 --- usr/src/usr.bin/tftp/Makefile | 2 +- usr/src/usr.bin/tftp/main.c | 105 ++++++++++++++++++----- usr/src/usr.bin/tftp/tftp.c | 157 +++++++++++++++++----------------- 3 files changed, 163 insertions(+), 101 deletions(-) diff --git a/usr/src/usr.bin/tftp/Makefile b/usr/src/usr.bin/tftp/Makefile index b4e32bdfe0..702c796ada 100644 --- a/usr/src/usr.bin/tftp/Makefile +++ b/usr/src/usr.bin/tftp/Makefile @@ -6,7 +6,7 @@ CFLAGS=-O all: ${ALL} tftp: main.o tftp.o - ${CC} main.o tftp.o -o tftp -ljobs + ${CC} main.o tftp.o -o tftp clean: rm -f ${ALL} *.o *.s errs core a.out t.? diff --git a/usr/src/usr.bin/tftp/main.c b/usr/src/usr.bin/tftp/main.c index 1f5769ddf4..002db00419 100644 --- a/usr/src/usr.bin/tftp/main.c +++ b/usr/src/usr.bin/tftp/main.c @@ -1,10 +1,11 @@ -/* main.c 4.5 82/12/25 */ +/* main.c 4.6 83/06/12 */ /* * TFTP User Program -- Command Interface. */ #include #include +#include #include @@ -15,6 +16,8 @@ #include #include +#define TIMEOUT 5 /* secs between rexmt's */ + struct sockaddr_in sin; int f; int trace; @@ -30,7 +33,7 @@ int intr(); struct servent *sp; int quit(), help(), setverbose(), settrace(), status(); -int get(), put(), setpeer(), setmode(); +int get(), put(), setpeer(), setmode(), setrexmt(), settimeout(); #define HELPINDENT (sizeof("connect")) @@ -49,6 +52,8 @@ char shelp[] = "send file"; char rhelp[] = "receive file"; char mhelp[] = "set file transfer mode"; char sthelp[] = "show current status"; +char xhelp[] = "set per-packet retransmission timeout"; +char ihelp[] = "set total retransmission timeout"; struct cmd cmdtab[] = { { "connect", chelp, setpeer }, @@ -59,6 +64,8 @@ struct cmd cmdtab[] = { { "verbose", vhelp, setverbose }, { "trace", thelp, settrace }, { "status", sthelp, status }, + { "rexmt", xhelp, setrexmt }, + { "timeout", ihelp, settimeout }, { "?", hhelp, help }, 0 }; @@ -71,6 +78,9 @@ char *rindex(); main(argc, argv) char *argv[]; { + struct sockaddr_in sin; + int top; + sp = getservbyname("tftp", "udp"); if (sp == 0) { fprintf(stderr, "tftp: udp/tftp: unknown service\n"); @@ -78,18 +88,25 @@ main(argc, argv) } f = socket(AF_INET, SOCK_DGRAM, 0, 0); if (f < 0) { - perror("socket"); + perror("tftp: socket"); exit(3); } + bzero((char *)&sin, sizeof (sin)); + sin.sin_family = AF_INET; + if (bind(f, &sin, sizeof (sin)) < 0) { + perror("tftp: bind"); + exit(1); + } strcpy(mode, "netascii"); + signal(SIGINT, intr); if (argc > 1) { if (setjmp(toplevel) != 0) exit(0); setpeer(argc, argv); } - setjmp(toplevel); + top = setjmp(toplevel) == 0; for (;;) - command(1); + command(top); } char *hostname; @@ -233,12 +250,11 @@ put(argc, argv) printf("No target machine specified.\n"); return; } - sigset(SIGINT, intr); if (argc < 4) { cp = argc == 2 ? tail(targ) : argv[1]; - fd = open(cp); + fd = open(cp, O_RDONLY); if (fd < 0) { - perror(cp); + fprintf(stderr, "tftp: "); perror(cp); return; } sendfile(fd, targ); @@ -248,9 +264,9 @@ put(argc, argv) *cp++ = '/'; for (n = 1; n < argc - 1; n++) { strcpy(cp, tail(argv[n])); - fd = open(argv[n], 0); + fd = open(argv[n], O_RDONLY); if (fd < 0) { - perror(argv[n]); + fprintf(stderr, "tftp: "); perror(argv[n]); continue; } sendfile(fd, targ); @@ -293,7 +309,6 @@ get(argc, argv) getusage(argv[0]); return; } - sigset(SIGINT, intr); for (n = 1; argc == 2 || n < argc - 1; n++) { src = index(argv[n], ':'); if (src == NULL) @@ -316,7 +331,7 @@ get(argc, argv) cp = argc == 3 ? argv[2] : tail(src); fd = creat(cp, 0644); if (fd < 0) { - perror(cp); + fprintf(stderr, "tftp: "); perror(cp); return; } recvfile(fd, src); @@ -327,7 +342,7 @@ get(argc, argv) strcpy(cp, tail(src)); fd = creat(src, 0644); if (fd < 0) { - perror(src); + fprintf(stderr, "tftp: "); perror(src); continue; } recvfile(fd, src); @@ -340,6 +355,58 @@ getusage(s) printf(" %s file file ... file if connected\n", s); } +int rexmtval = TIMEOUT; + +setrexmt(argc, argv) + char *argv[]; +{ + int t; + + if (argc < 2) { + strcpy(line, "Rexmt-timeout "); + printf("(value) "); + gets(&line[strlen(line)]); + makeargv(); + argc = margc; + argv = margv; + } + if (argc != 2) { + printf("usage: %s value\n", argv[0]); + return; + } + t = atoi(argv[1]); + if (t < 0) + printf("%s: bad value\n", t); + else + rexmtval = t; +} + +int maxtimeout = 5 * TIMEOUT; + +settimeout(argc, argv) + char *argv[]; +{ + int t; + + if (argc < 2) { + strcpy(line, "Maximum-timeout "); + printf("(value) "); + gets(&line[strlen(line)]); + makeargv(); + argc = margc; + argv = margv; + } + if (argc != 2) { + printf("usage: %s value\n", argv[0]); + return; + } + t = atoi(argv[1]); + if (t < 0) + printf("%s: bad value\n", t); + else + maxtimeout = t; +} + status(argc, argv) char *argv[]; { @@ -349,10 +416,13 @@ status(argc, argv) printf("Not connected.\n"); printf("Mode: %s Verbose: %s Tracing: %s\n", mode, verbose ? "on" : "off", trace ? "on" : "off"); + printf("Rexmt-interval: %d seconds, Max-timeout: %d seconds\n", + rexmtval, maxtimeout); } intr() { + longjmp(toplevel, -1); } @@ -383,14 +453,12 @@ command(top) if (!top) putchar('\n'); - else - sigset(SIGINT, SIG_DFL); for (;;) { printf("%s> ", prompt); if (gets(line) == 0) - break; + continue; if (line[0] == 0) - break; + continue; makeargv(); c = getcmd(margv[0]); if (c == (struct cmd *)-1) { @@ -402,10 +470,7 @@ command(top) continue; } (*c->handler)(margc, margv); - if (c->handler != help) - break; } - longjmp(toplevel, 1); } struct cmd * diff --git a/usr/src/usr.bin/tftp/tftp.c b/usr/src/usr.bin/tftp/tftp.c index 0131822610..c2bd1ee5c9 100644 --- a/usr/src/usr.bin/tftp/tftp.c +++ b/usr/src/usr.bin/tftp/tftp.c @@ -1,4 +1,4 @@ -/* tftp.c 4.5 83/05/11 */ +/* tftp.c 4.6 83/06/12 */ /* * TFTP User Program -- Protocol Machines @@ -23,17 +23,21 @@ int trace; int verbose; int connected; char buf[BUFSIZ]; +int rexmtval; +int maxtimeout; int timeout; jmp_buf toplevel; +jmp_buf timeoutbuf; timer() { - timeout += TIMEOUT; - if (timeout >= MAXTIMEOUT) { + + timeout += rexmtval; + if (timeout >= maxtimeout) { printf("Transfer timed out.\n"); longjmp(toplevel, -1); } - alarm(TIMEOUT); + longjmp(timeoutbuf, 1); } /* @@ -49,11 +53,11 @@ sendfile(fd, name) time_t start = time(0), delta; int fromlen; - size = makerequest(WRQ, name) - 4; - timeout = 0; - sigset(SIGALRM, timer); + signal(SIGALRM, timer); do { - if (block != 0) { + if (block == 0) + size = makerequest(WRQ, name) - 4; + else { size = read(fd, tp->th_data, SEGSIZE); if (size < 0) { nak(errno + 100); @@ -63,47 +67,42 @@ sendfile(fd, name) tp->th_block = htons((u_short)block); } timeout = 0; - alarm(TIMEOUT); -rexmt: + (void) setjmp(timeoutbuf); if (trace) tpacket("sent", tp, size + 4); n = sendto(f, buf, size + 4, 0, (caddr_t)&sin, sizeof (sin)); if (n != size + 4) { - perror("send"); - break; + perror("tftp: sendto"); + goto abort; } -again: - fromlen = sizeof (from); - n = recvfrom(f, buf, sizeof (buf), 0, (caddr_t)&from, &fromlen); - if (n <= 0) { - if (n == 0) - goto again; - if (errno == EINTR) - goto rexmt; + do { + alarm(rexmtval); + do { + fromlen = sizeof (from); + n = recvfrom(f, buf, sizeof (buf), 0, + (caddr_t)&from, &fromlen); + } while (n <= 0); alarm(0); - perror("receive"); - break; - } - alarm(0); - if (trace) - tpacket("received", tp, n); - /* should verify packet came from server */ -#if vax || pdp11 - tp->th_opcode = ntohs(tp->th_opcode); - tp->th_block = ntohs(tp->th_block); -#endif - if (tp->th_opcode == ERROR) { - printf("Error code %d: %s\n", tp->th_code, - tp->th_msg); - break; - } - if (tp->th_opcode != ACK || block != tp->th_block) - goto again; + if (n < 0) { + perror("tftp: recvfrom"); + goto abort; + } + if (trace) + tpacket("received", tp, n); + /* should verify packet came from server */ + tp->th_opcode = ntohs(tp->th_opcode); + tp->th_block = ntohs(tp->th_block); + if (tp->th_opcode == ERROR) { + printf("Error code %d: %s\n", tp->th_code, + tp->th_msg); + goto abort; + } + } while (tp->th_opcode != ACK && block != tp->th_block); if (block > 0) amount += size; block++; } while (size == SEGSIZE || block == 1); - alarm(0); +abort: (void) close(fd); if (amount > 0) { delta = time(0) - start; @@ -122,53 +121,51 @@ recvfile(fd, name) register int block = 1, n, size, amount = 0; struct sockaddr_in from; time_t start = time(0), delta; - int fromlen; + int fromlen, firsttrip = 1; - size = makerequest(RRQ, name); - timeout = 0; - sigset(SIGALRM, timer); - alarm(TIMEOUT); - goto rexmt; + signal(SIGALRM, timer); do { + if (firsttrip) { + size = makerequest(RRQ, name); + firsttrip = 0; + } else { + tp->th_opcode = htons((u_short)ACK); + tp->th_block = htons((u_short)(block)); + size = 4; + block++; + } timeout = 0; - alarm(TIMEOUT); - tp->th_opcode = htons((u_short)ACK); - tp->th_block = htons((u_short)(block)); - size = 4; - block++; -rexmt: + (void) setjmp(timeoutbuf); if (trace) tpacket("sent", tp, size); - if (sendto(f, buf, size, 0, (caddr_t)&sin, sizeof (sin)) != size) { - perror("send"); - break; - } -again: - n = recvfrom(f, buf, sizeof (buf), 0, (caddr_t)&from, &fromlen); - if (n <= 0) { - if (n == 0) - goto again; - if (errno == EINTR) - goto rexmt; + if (sendto(f, buf, size, 0, (caddr_t)&sin, + sizeof (sin)) != size) { alarm(0); - perror("receive"); - break; - } - alarm(0); - if (trace) - tpacket("received", tp, n); - /* should verify client address */ -#if vax || pdp11 - tp->th_opcode = ntohs(tp->th_opcode); - tp->th_block = ntohs(tp->th_block); -#endif - if (tp->th_opcode == ERROR) { - printf("Error code %d: %s\n", tp->th_code, - tp->th_msg); - break; + perror("tftp: sendto"); + goto abort; } - if (tp->th_opcode != DATA || block != tp->th_block) - goto again; + do { + alarm(rexmtval); + do + n = recvfrom(f, buf, sizeof (buf), 0, + (caddr_t)&from, &fromlen); + while (n <= 0); + alarm(0); + if (n < 0) { + perror("tftp: recvfrom"); + goto abort; + } + if (trace) + tpacket("received", tp, n); + /* should verify client address */ + tp->th_opcode = ntohs(tp->th_opcode); + tp->th_block = ntohs(tp->th_block); + if (tp->th_opcode == ERROR) { + printf("Error code %d: %s\n", tp->th_code, + tp->th_msg); + goto abort; + } + } while (tp->th_opcode != DATA && block != tp->th_block); size = write(fd, tp->th_data, n - 4); if (size < 0) { nak(errno + 100); @@ -176,7 +173,7 @@ again: } amount += size; } while (size == SEGSIZE); - alarm(0); +abort: tp->th_opcode = htons((u_short)ACK); tp->th_block = htons((u_short)block); (void) sendto(f, buf, 4, 0, &sin, sizeof (sin)); -- 2.20.1