too much to say...let's just say it seems to work now
authorSam Leffler <sam@ucbvax.Berkeley.EDU>
Sun, 12 Jun 1983 16:26:48 +0000 (08:26 -0800)
committerSam Leffler <sam@ucbvax.Berkeley.EDU>
Sun, 12 Jun 1983 16:26:48 +0000 (08:26 -0800)
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
usr/src/usr.bin/tftp/main.c
usr/src/usr.bin/tftp/tftp.c

index b4e32bd..702c796 100644 (file)
@@ -6,7 +6,7 @@ CFLAGS=-O
 all: ${ALL}
 
 tftp:  main.o tftp.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.?
 
 clean:
        rm -f ${ALL} *.o *.s errs core a.out t.?
index 1f5769d..002db00 100644 (file)
@@ -1,10 +1,11 @@
-/*     main.c  4.5     82/12/25        */
+/*     main.c  4.6     83/06/12        */
 
 /*
  * TFTP User Program -- Command Interface.
  */
 #include <sys/types.h>
 #include <sys/socket.h>
 
 /*
  * TFTP User Program -- Command Interface.
  */
 #include <sys/types.h>
 #include <sys/socket.h>
+#include <sys/file.h>
 
 #include <netinet/in.h>
 
 
 #include <netinet/in.h>
 
@@ -15,6 +16,8 @@
 #include <ctype.h>
 #include <netdb.h>
 
 #include <ctype.h>
 #include <netdb.h>
 
+#define        TIMEOUT         5               /* secs between rexmt's */
+
 struct sockaddr_in sin;
 int    f;
 int    trace;
 struct sockaddr_in sin;
 int    f;
 int    trace;
@@ -30,7 +33,7 @@ int   intr();
 struct servent *sp;
 
 int    quit(), help(), setverbose(), settrace(), status();
 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"))
 
 
 #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   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 },
 
 struct cmd cmdtab[] = {
        { "connect",    chelp,          setpeer },
@@ -59,6 +64,8 @@ struct cmd cmdtab[] = {
        { "verbose",    vhelp,          setverbose },
        { "trace",      thelp,          settrace },
        { "status",     sthelp,         status },
        { "verbose",    vhelp,          setverbose },
        { "trace",      thelp,          settrace },
        { "status",     sthelp,         status },
+       { "rexmt",      xhelp,          setrexmt },
+       { "timeout",    ihelp,          settimeout },
        { "?",          hhelp,          help },
        0
 };
        { "?",          hhelp,          help },
        0
 };
@@ -71,6 +78,9 @@ char  *rindex();
 main(argc, argv)
        char *argv[];
 {
 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");
        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) {
        }
        f = socket(AF_INET, SOCK_DGRAM, 0, 0);
        if (f < 0) {
-               perror("socket");
+               perror("tftp: socket");
                exit(3);
        }
                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");
        strcpy(mode, "netascii");
+       signal(SIGINT, intr);
        if (argc > 1) {
                if (setjmp(toplevel) != 0)
                        exit(0);
                setpeer(argc, argv);
        }
        if (argc > 1) {
                if (setjmp(toplevel) != 0)
                        exit(0);
                setpeer(argc, argv);
        }
-       setjmp(toplevel);
+       top = setjmp(toplevel) == 0;
        for (;;)
        for (;;)
-               command(1);
+               command(top);
 }
 
 char   *hostname;
 }
 
 char   *hostname;
@@ -233,12 +250,11 @@ put(argc, argv)
                printf("No target machine specified.\n");
                return;
        }
                printf("No target machine specified.\n");
                return;
        }
-       sigset(SIGINT, intr);
        if (argc < 4) {
                cp = argc == 2 ? tail(targ) : argv[1];
        if (argc < 4) {
                cp = argc == 2 ? tail(targ) : argv[1];
-               fd = open(cp);
+               fd = open(cp, O_RDONLY);
                if (fd < 0) {
                if (fd < 0) {
-                       perror(cp);
+                       fprintf(stderr, "tftp: "); perror(cp);
                        return;
                }
                sendfile(fd, targ);
                        return;
                }
                sendfile(fd, targ);
@@ -248,9 +264,9 @@ put(argc, argv)
        *cp++ = '/';
        for (n = 1; n < argc - 1; n++) {
                strcpy(cp, tail(argv[n]));
        *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) {
                if (fd < 0) {
-                       perror(argv[n]);
+                       fprintf(stderr, "tftp: "); perror(argv[n]);
                        continue;
                }
                sendfile(fd, targ);
                        continue;
                }
                sendfile(fd, targ);
@@ -293,7 +309,6 @@ get(argc, argv)
                                getusage(argv[0]);
                                return;
                        }
                                getusage(argv[0]);
                                return;
                        }
-       sigset(SIGINT, intr);
        for (n = 1; argc == 2 || n < argc - 1; n++) {
                src = index(argv[n], ':');
                if (src == NULL)
        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) {
                        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);
                                return;
                        }
                        recvfile(fd, src);
@@ -327,7 +342,7 @@ get(argc, argv)
                strcpy(cp, tail(src));
                fd = creat(src, 0644);
                if (fd < 0) {
                strcpy(cp, tail(src));
                fd = creat(src, 0644);
                if (fd < 0) {
-                       perror(src);
+                       fprintf(stderr, "tftp: "); perror(src);
                        continue;
                }
                recvfile(fd, src);
                        continue;
                }
                recvfile(fd, src);
@@ -340,6 +355,58 @@ getusage(s)
        printf("       %s file file ... file if connected\n", 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[];
 {
 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("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()
 {
 }
 
 intr()
 {
+
        longjmp(toplevel, -1);
 }
 
        longjmp(toplevel, -1);
 }
 
@@ -383,14 +453,12 @@ command(top)
 
        if (!top)
                putchar('\n');
 
        if (!top)
                putchar('\n');
-       else
-               sigset(SIGINT, SIG_DFL);
        for (;;) {
                printf("%s> ", prompt);
                if (gets(line) == 0)
        for (;;) {
                printf("%s> ", prompt);
                if (gets(line) == 0)
-                       break;
+                       continue;
                if (line[0] == 0)
                if (line[0] == 0)
-                       break;
+                       continue;
                makeargv();
                c = getcmd(margv[0]);
                if (c == (struct cmd *)-1) {
                makeargv();
                c = getcmd(margv[0]);
                if (c == (struct cmd *)-1) {
@@ -402,10 +470,7 @@ command(top)
                        continue;
                }
                (*c->handler)(margc, margv);
                        continue;
                }
                (*c->handler)(margc, margv);
-               if (c->handler != help)
-                       break;
        }
        }
-       longjmp(toplevel, 1);
 }
 
 struct cmd *
 }
 
 struct cmd *
index 0131822..c2bd1ee 100644 (file)
@@ -1,4 +1,4 @@
-/*     tftp.c  4.5     83/05/11        */
+/*     tftp.c  4.6     83/06/12        */
 
 /*
  * TFTP User Program -- Protocol Machines
 
 /*
  * TFTP User Program -- Protocol Machines
@@ -23,17 +23,21 @@ int trace;
 int    verbose;
 int    connected;
 char   buf[BUFSIZ];
 int    verbose;
 int    connected;
 char   buf[BUFSIZ];
+int    rexmtval;
+int    maxtimeout;
 int    timeout;
 jmp_buf        toplevel;
 int    timeout;
 jmp_buf        toplevel;
+jmp_buf        timeoutbuf;
 
 timer()
 {
 
 timer()
 {
-       timeout += TIMEOUT;
-       if (timeout >= MAXTIMEOUT) {
+
+       timeout += rexmtval;
+       if (timeout >= maxtimeout) {
                printf("Transfer timed out.\n");
                longjmp(toplevel, -1);
        }
                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;
 
        time_t start = time(0), delta;
        int fromlen;
 
-       size = makerequest(WRQ, name) - 4;
-       timeout = 0;
-       sigset(SIGALRM, timer);
+       signal(SIGALRM, timer);
        do {
        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);
                        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;
                        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) {
                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);
                        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);
                if (block > 0)
                        amount += size;
                block++;
        } while (size == SEGSIZE || block == 1);
-       alarm(0);
+abort:
        (void) close(fd);
        if (amount > 0) {
                delta = time(0) - start;
        (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;
        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 {
        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;
                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 (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);
                        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);
                size = write(fd, tp->th_data, n - 4);
                if (size < 0) {
                        nak(errno + 100);
@@ -176,7 +173,7 @@ again:
                }
                amount += size;
        } while (size == SEGSIZE);
                }
                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));
        tp->th_opcode = htons((u_short)ACK);
        tp->th_block = htons((u_short)block);
        (void) sendto(f, buf, 4, 0, &sin, sizeof (sin));