convert for use with inetd
authorMike Karels <karels@ucbvax.Berkeley.EDU>
Thu, 12 Apr 1984 06:59:37 +0000 (22:59 -0800)
committerMike Karels <karels@ucbvax.Berkeley.EDU>
Thu, 12 Apr 1984 06:59:37 +0000 (22:59 -0800)
SCCS-vsn: libexec/comsat/comsat.c 4.10
SCCS-vsn: libexec/rexecd/rexecd.c 4.11
SCCS-vsn: libexec/rlogind/rlogind.c 4.20
SCCS-vsn: libexec/rshd/rshd.c 4.18
SCCS-vsn: libexec/telnetd/telnetd.c 4.27
SCCS-vsn: libexec/tftpd/tftpd.c 4.12

usr/src/libexec/comsat/comsat.c
usr/src/libexec/rexecd/rexecd.c
usr/src/libexec/rlogind/rlogind.c
usr/src/libexec/rshd/rshd.c
usr/src/libexec/telnetd/telnetd.c
usr/src/libexec/tftpd/tftpd.c

index 9faddb5..139ac1f 100644 (file)
@@ -1,5 +1,5 @@
 #ifndef lint
 #ifndef lint
-static char *sccsid = "@(#)comsat.c    4.10 84/04/11";
+static char sccsid[] = "@(#)comsat.c   4.10 (Berkeley) %G%";
 #endif
 
 #include <sys/types.h>
 #endif
 
 #include <sys/types.h>
@@ -32,55 +32,51 @@ int nutmp;
 int    uf;
 unsigned utmpmtime;                    /* last modification time for utmp */
 int    onalrm();
 int    uf;
 unsigned utmpmtime;                    /* last modification time for utmp */
 int    onalrm();
-struct servent *sp;
+long   lastmsgtime;
 
 
+#define        MAXIDLE 120
 #define NAMLEN (sizeof (uts[0].ut_name) + 1)
 
 main(argc, argv)
 #define NAMLEN (sizeof (uts[0].ut_name) + 1)
 
 main(argc, argv)
-char **argv;
+       int argc;
+       char *argv[];
 {
 {
-       register cc;
+       register int cc;
        char buf[BUFSIZ];
        char buf[BUFSIZ];
-       int s;
-
-       sp = getservbyname("biff", "udp");
-       if (sp == 0) {
-               fprintf(stderr, "comsat: biff/udp: unknown service\n");
-               exit(1);
+       char msgbuf[100];
+       struct sockaddr_in from;
+       int fromlen;
+
+       /* verify proper invocation */
+       fromlen = sizeof (from);
+       if (getsockname(0, &from, &fromlen) < 0) {
+               fprintf(stderr, "%s: ", argv[0]);
+               perror("getsockname");
+               _exit(1);
        }
        }
-       if (!debug)
-       if (fork())
-               exit();
        chdir("/usr/spool/mail");
        chdir("/usr/spool/mail");
-       if((uf = open("/etc/utmp",0)) < 0)
-               perror("/etc/utmp"), exit(1);
-       sleep(10);
+       if ((uf = open("/etc/utmp",0)) < 0) {
+               perror("/etc/utmp");
+               (void) recv(0, msgbuf, sizeof (msgbuf) - 1, 0);
+               exit(1);
+       }
+       lastmsgtime = time(0);
        onalrm();
        signal(SIGALRM, onalrm);
        signal(SIGTTOU, SIG_IGN);
        onalrm();
        signal(SIGALRM, onalrm);
        signal(SIGTTOU, SIG_IGN);
-       s = socket(AF_INET, SOCK_DGRAM, 0, 0);
-       if (s < 0) {
-               perror("socket");
-               exit(1);
-       }
-       sin.sin_port = sp->s_port;
-       if (bind(s, &sin, sizeof (sin), 0) < 0) {
-               perror("bind");
-               exit(1);
-       }
        for (;;) {
        for (;;) {
-               char msgbuf[100];
-               int cc;
-
-               cc = recv(s, msgbuf, sizeof (msgbuf) - 1, 0);
+               cc = recv(0, msgbuf, sizeof (msgbuf) - 1, 0);
                if (cc <= 0) {
                        if (errno != EINTR)
                                sleep(1);
                        errno = 0;
                        continue;
                }
                if (cc <= 0) {
                        if (errno != EINTR)
                                sleep(1);
                        errno = 0;
                        continue;
                }
+               sigblock(1<<SIGALRM);
                msgbuf[cc] = 0;
                msgbuf[cc] = 0;
+               lastmsgtime = time(0);
                mailfor(msgbuf);
                mailfor(msgbuf);
+               sigsetmask(0);
        }
 }
 
        }
 }
 
@@ -89,6 +85,8 @@ onalrm()
        struct stat statbf;
        struct utmp *utp;
 
        struct stat statbf;
        struct utmp *utp;
 
+       if (time(0) - lastmsgtime >= MAXIDLE)
+               exit(1);
        dprintf("alarm\n");
        alarm(15);
        fstat(uf,&statbf);
        dprintf("alarm\n");
        alarm(15);
        fstat(uf,&statbf);
index 1b8f4f1..cc6e64e 100644 (file)
@@ -1,5 +1,5 @@
 #ifndef lint
 #ifndef lint
-static char sccsid[] = "@(#)rexecd.c   4.11 (Berkeley) 84/04/11";
+static char sccsid[] = "@(#)rexecd.c   4.11 (Berkeley) %G%";
 #endif
 
 #include <sys/ioctl.h>
 #endif
 
 #include <sys/ioctl.h>
@@ -16,7 +16,6 @@ static char sccsid[] = "@(#)rexecd.c  4.11 (Berkeley) 84/04/11";
 #include <netdb.h>
 
 extern errno;
 #include <netdb.h>
 
 extern errno;
-struct sockaddr_in sin = { AF_INET };
 struct passwd *getpwnam();
 char   *crypt(), *rindex(), *sprintf();
 /* VARARGS 1 */
 struct passwd *getpwnam();
 char   *crypt(), *rindex(), *sprintf();
 /* VARARGS 1 */
@@ -33,60 +32,16 @@ main(argc, argv)
        int argc;
        char **argv;
 {
        int argc;
        char **argv;
 {
-       int f;
        struct sockaddr_in from;
        struct sockaddr_in from;
-       struct servent *sp;
+       int fromlen;
 
 
-       sp = getservbyname("exec", "tcp");
-       if (sp == 0) {
-               fprintf(stderr, "tcp/exec: unknown service\n");
+       fromlen = sizeof (from);
+       if (getpeername(0, &from, &fromlen) < 0) {
+               fprintf(stderr, "%s: ", argv[0]);
+               perror("getpeername");
                exit(1);
        }
                exit(1);
        }
-       sin.sin_port = sp->s_port;
-#ifndef DEBUG
-       if (fork())
-               exit(0);
-       for (f = 0; f < 10; f++)
-               (void) close(f);
-       (void) open("/", 0);
-       (void) dup2(0, 1);
-       (void) dup2(0, 2);
-       { int t = open("/dev/tty", 2);
-         if (t >= 0) {
-               ioctl(t, TIOCNOTTY, (char *)0);
-               (void) close(t);
-         }
-       }
-#endif
-       argc--, argv++;
-       f = socket(AF_INET, SOCK_STREAM, 0, 0);
-       if (f < 0) {
-               perror("rexecd: socket");
-               exit(1);
-       }
-       if (bind(f, &sin, sizeof (sin), 0) < 0) {
-               perror("rexecd: bind:");
-               exit(1);
-       }
-       signal(SIGCHLD, reapchild);
-       listen(f, 10);
-       for (;;) {
-               int s, len = sizeof (from);
-
-               s = accept(f, &from, &len, 0);
-               if (s < 0) {
-                       if (errno == EINTR)
-                               continue;
-                       perror("rexecd: accept");
-                       sleep(1);
-                       continue;
-               }
-               if (fork() == 0) {
-                       signal(SIGCHLD, SIG_IGN);
-                       doit(s, &from);
-               }
-               (void) close(s);
-       }
+       doit(0, &from);
 }
 
 reapchild()
 }
 
 reapchild()
index 1dbb293..b7611ca 100644 (file)
@@ -1,7 +1,15 @@
 #ifndef lint
 #ifndef lint
-static char sccsid[] = "@(#)rlogind.c  4.20 84/04/11";
+static char sccsid[] = "@(#)rlogind.c  4.20 (Berkeley) %G%";
 #endif
 
 #endif
 
+/*
+ * remote login server:
+ *     remuser\0
+ *     locuser\0
+ *     terminal type\0
+ *     data
+ */
+
 #include <stdio.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <stdio.h>
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -21,99 +29,25 @@ extern      errno;
 int    reapchild();
 struct passwd *getpwnam();
 char   *crypt(), *rindex(), *index(), *malloc(), *ntoa();
 int    reapchild();
 struct passwd *getpwnam();
 char   *crypt(), *rindex(), *index(), *malloc(), *ntoa();
-struct sockaddr_in sin = { AF_INET };
-/*
- * remote login server:
- *     remuser\0
- *     locuser\0
- *     terminal type\0
- *     data
- */
+
 main(argc, argv)
        int argc;
        char **argv;
 {
 main(argc, argv)
        int argc;
        char **argv;
 {
-       int f, options = 0;
+       int options = 0, fromlen;
        struct sockaddr_in from;
        struct sockaddr_in from;
-       struct servent *sp;
 
 
-       sp = getservbyname("login", "tcp");
-       if (sp == 0) {
-               fprintf(stderr, "rlogind: tcp/rlogin: unknown service\n");
-               exit(1);
+       fromlen = sizeof (from);
+       if (getpeername(0, &from, &fromlen) < 0) {
+               fprintf(stderr, "%s: ", argv[0]);
+               perror("getpeername");
+               _exit(1);
        }
        }
-#ifndef DEBUG
-       if (fork())
-               exit(0);
-       for (f = 0; f < 10; f++)
-               (void) close(f);
-       (void) open("/", 0);
-       (void) dup2(0, 1);
-       (void) dup2(0, 2);
-       { int tt = open("/dev/tty", 2);
-         if (tt > 0) {
-               ioctl(tt, TIOCNOTTY, 0);
-               close(tt);
-         }
-       }
-#endif
-       sin.sin_port = sp->s_port;
-       argc--, argv++;
-       if (argc > 0 && !strcmp(argv[0], "-d")) {
-               options |= SO_DEBUG;
-               argc--, argv++;
-       }
-       if (argc > 0) {
-               int port = atoi(argv[0]);
-
-               if (port < 0) {
-                       fprintf(stderr, "%s: bad port #\n", argv[0]);
-                       exit(1);
-               }
-               sin.sin_port = htons((u_short)port);
-               argv++, argc--;
-       }
-       f = socket(AF_INET, SOCK_STREAM, 0, 0);
-       if (f < 0) {
-               perror("rlogind: socket");
-               exit(1);
-       }
-       if (options & SO_DEBUG)
-               if (setsockopt(f, SOL_SOCKET, SO_DEBUG, 0, 0) < 0)
-                       perror("rlogind: setsockopt (SO_DEBUG)");
-       if (setsockopt(f, SOL_SOCKET, SO_KEEPALIVE, 0, 0) < 0)
-               perror("rlogind: setsockopt (SO_KEEPALIVE)");
-       if (bind(f, &sin, sizeof (sin), 0) < 0) {
-               perror("rlogind: bind");
-               exit(1);
+       if (setsockopt(0, SOL_SOCKET, SO_KEEPALIVE, 0, 0) < 0) {
+               fprintf(stderr, "%s: ", argv[0]);
+               perror("setsockopt (SO_KEEPALIVE)");
        }
        }
-       signal(SIGCHLD, reapchild);
-       listen(f, 10);
-       for (;;) {
-               int s, len = sizeof (from);
-
-               s = accept(f, &from, &len, 0);
-               if (s < 0) {
-                       if (errno == EINTR)
-                               continue;
-                       perror("rlogind: accept");
-                       continue;
-               }
-               if (fork() == 0) {
-                       signal(SIGCHLD, SIG_IGN);
-                       close(f);
-                       doit(s, &from);
-               }
-               close(s);
-       }
-}
-
-reapchild()
-{
-       union wait status;
-
-       while (wait3(&status, WNOHANG, 0) > 0)
-               ;
+       doit(0, &from);
 }
 
 char   locuser[32], remuser[32];
 }
 
 char   locuser[32], remuser[32];
index 4046d14..8683ea7 100644 (file)
@@ -1,7 +1,14 @@
 #ifndef lint
 #ifndef lint
-static char sccsid[] = "@(#)rshd.c     4.18 (Berkeley) 84/04/11";
+static char sccsid[] = "@(#)rshd.c     4.18 (Berkeley) %G%";
 #endif
 
 #endif
 
+/*
+ * remote shell server:
+ *     remuser\0
+ *     locuser\0
+ *     command\0
+ *     data
+ */
 #include <sys/ioctl.h>
 #include <sys/param.h>
 #include <sys/socket.h>
 #include <sys/ioctl.h>
 #include <sys/param.h>
 #include <sys/socket.h>
@@ -16,107 +23,34 @@ static char sccsid[] = "@(#)rshd.c 4.18 (Berkeley) 84/04/11";
 #include <netdb.h>
 
 int    errno;
 #include <netdb.h>
 
 int    errno;
-int    reapchild();
-struct sockaddr_in sin = { AF_INET };
 struct passwd *getpwnam();
 char   *index(), *rindex(), *sprintf();
 struct passwd *getpwnam();
 char   *index(), *rindex(), *sprintf();
-int    options;
 /* VARARGS 1 */
 int    error();
 /* VARARGS 1 */
 int    error();
-/*
- * remote shell server:
- *     remuser\0
- *     locuser\0
- *     command\0
- *     data
- */
+
 main(argc, argv)
        int argc;
        char **argv;
 {
 main(argc, argv)
        int argc;
        char **argv;
 {
-       int f, linger;
+       int linger, fromlen;
        struct sockaddr_in from;
        struct sockaddr_in from;
-       struct servent *sp;
-
-       sp = getservbyname("shell", "tcp");
-       if (sp == 0) {
-               fprintf(stderr, "rshd: tcp/shell: unknown service\n");
-               exit(1);
-       }
-#ifndef DEBUG
-       if (fork())
-               exit(0);
-       for (f = 0; f < 10; f++)
-               (void) close(f);
-       (void) open("/", 0);
-       (void) dup2(0, 1);
-       (void) dup2(0, 2);
-       { int t = open("/dev/tty", 2);
-         if (t >= 0) {
-               ioctl(t, TIOCNOTTY, (char *)0);
-               (void) close(t);
-         }
-       }
-#endif
-       sin.sin_port = sp->s_port;
-       argc--, argv++;
-       if (argc > 0 && !strcmp(argv[0], "-d")) {
-               options |= SO_DEBUG;
-               argc--, argv++;
-       }
-       if (argc > 0) {
-               int port = atoi(argv[0]);
 
 
-               if (port < 0) {
-                       fprintf(stderr, "%s: bad port #\n", argv[0]);
-                       exit(1);
-               }
-               sin.sin_port = htons((u_short)port);
-               argc--, argv++;
+       fromlen = sizeof (from);
+       if (getpeername(0, &from, &fromlen) < 0) {
+               fprintf(stderr, "%s: ", argv[0]);
+               perror("getpeername");
+               _exit(1);
        }
        }
-       f = socket(AF_INET, SOCK_STREAM, 0, 0);
-       if (f < 0) {
-               perror("rshd: socket");
-               exit(1);
+       if (setsockopt(0, SOL_SOCKET, SO_KEEPALIVE, 0, 0) < 0) {
+               fprintf(stderr, "%s: ", argv[0]);
+               perror("setsockopt (SO_KEEPALIVE)");
        }
        }
-       if (options & SO_DEBUG && setsockopt(f, SOL_SOCKET, SO_DEBUG, 0, 0) < 0)
-               perror("rshd: setsockopt (SO_DEBUG)");
-       if (setsockopt(f, SOL_SOCKET, SO_KEEPALIVE, 0, 0) < 0)
-               perror("rshd: setsockopt (SO_KEEPALIVE)");
        linger = 60;                    /* XXX */
        linger = 60;                    /* XXX */
-       if (setsockopt(f, SOL_SOCKET, SO_LINGER, &linger, 0) < 0)
-               perror("rshd: setsockopt (SO_LINGER)");
-       if (bind(f, (caddr_t)&sin, sizeof (sin), 0) < 0) {
-               perror("rshd: bind");
-               exit(1);
-       }
-       signal(SIGCHLD, reapchild);
-       listen(f, 10);
-       for (;;) {
-               int g, len = sizeof (from);
-
-               g = accept(f, &from, &len, 0);
-               if (g < 0) {
-                       if (errno == EINTR)
-                               continue;
-                       perror("rshd: accept");
-                       continue;
-               }
-               if (fork() == 0) {
-                       signal(SIGCHLD, SIG_IGN);
-                       close(f);
-                       doit(g, &from);
-               }
-               close(g);
+       if (setsockopt(0, SOL_SOCKET, SO_LINGER, &linger, sizeof (linger)) < 0) {
+               fprintf(stderr, "%s: ", argv[0]);
+               perror("setsockopt (SO_LINGER)");
        }
        }
-}
-
-reapchild()
-{
-       union wait status;
-
-       while (wait3(&status, WNOHANG, 0) > 0)
-               ;
+       doit(dup(0), &from);
 }
 
 char   username[20] = "USER=";
 }
 
 char   username[20] = "USER=";
@@ -208,8 +142,11 @@ doit(f, fromp)
        }
        endpwent();
        if (chdir(pwd->pw_dir) < 0) {
        }
        endpwent();
        if (chdir(pwd->pw_dir) < 0) {
+               chdir("/");
+#ifdef notdef
                error("No remote directory.\n");
                exit(1);
                error("No remote directory.\n");
                exit(1);
+#endif
        }
        if (ruserok(hp->h_name, pwd->pw_uid == 0, remuser, locuser) < 0) {
                error("Permission denied.\n");
        }
        if (ruserok(hp->h_name, pwd->pw_uid == 0, remuser, locuser) < 0) {
                error("Permission denied.\n");
index 2cc1ca3..d2db5ef 100644 (file)
@@ -1,5 +1,5 @@
 #ifndef lint
 #ifndef lint
-static char sccsid[] = "@(#)telnetd.c  4.27 (Berkeley) 84/04/11";
+static char sccsid[] = "@(#)telnetd.c  4.27 (Berkeley) %G%";
 #endif
 
 /*
 #endif
 
 /*
@@ -41,100 +41,27 @@ int        pcc, ncc;
 
 int    pty, net;
 int    inter;
 
 int    pty, net;
 int    inter;
-int    reapchild();
 extern char **environ;
 extern int errno;
 char   line[] = "/dev/ptyp0";
 
 extern char **environ;
 extern int errno;
 char   line[] = "/dev/ptyp0";
 
-struct sockaddr_in sin = { AF_INET };
-
 main(argc, argv)
        char *argv[];
 {
 main(argc, argv)
        char *argv[];
 {
-       int s, pid, options;
-       struct servent *sp;
-
-       sp = getservbyname("telnet", "tcp");
-       if (sp == 0) {
-               fprintf(stderr, "telnetd: tcp/telnet: unknown service\n");
-               exit(1);
-       }
-       sin.sin_port = sp->s_port;
-       argc--, argv++;
-       if (argc > 0 && !strcmp(*argv, "-d")) {
-               options |= SO_DEBUG;
-               argc--, argv++;
-       }
-       if (argc > 0) {
-               sin.sin_port = atoi(*argv);
-               if (sin.sin_port <= 0) {
-                       fprintf(stderr, "telnetd: %s: bad port #\n", *argv);
-                       exit(1);
-               }
-               sin.sin_port = htons((u_short)sin.sin_port);
+       struct sockaddr_in from;
+       int fromlen;
+
+       fromlen = sizeof (from);
+       if (getpeername(0, &from, &fromlen) < 0) {
+               fprintf(stderr, "%s: ", argv[0]);
+               perror("getpeername");
+               _exit(1);
        }
        }
-#ifndef DEBUG
-       if (fork())
-               exit(0);
-       for (s = 0; s < 10; s++)
-               (void) close(s);
-       (void) open("/", 0);
-       (void) dup2(0, 1);
-       (void) dup2(0, 2);
-       { int tt = open("/dev/tty", 2);
-         if (tt > 0) {
-               ioctl(tt, TIOCNOTTY, 0);
-               close(tt);
-         }
+       if (setsockopt(0, SOL_SOCKET, SO_KEEPALIVE, 0, 0) < 0) {
+               fprintf(stderr, "%s: ", argv[0]);
+               perror("setsockopt (SO_KEEPALIVE)");
        }
        }
-#endif
-again:
-       s = socket(AF_INET, SOCK_STREAM, 0, 0);
-       if (s < 0) {
-               perror("telnetd: socket");;
-               sleep(5);
-               goto again;
-       }
-       if (options & SO_DEBUG)
-               if (setsockopt(s, SOL_SOCKET, SO_DEBUG, 0, 0) < 0)
-                       perror("telnetd: setsockopt (SO_DEBUG)");
-       if (setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, 0, 0) < 0)
-               perror("telnetd: setsockopt (SO_KEEPALIVE)");
-       while (bind(s, (caddr_t)&sin, sizeof (sin), 0) < 0) {
-               perror("telnetd: bind");
-               sleep(5);
-       }
-       signal(SIGCHLD, reapchild);
-       listen(s, 10);
-       for (;;) {
-               struct sockaddr_in from;
-               int s2, fromlen = sizeof (from);
-
-               s2 = accept(s, (caddr_t)&from, &fromlen);
-               if (s2 < 0) {
-                       if (errno == EINTR)
-                               continue;
-                       perror("telnetd: accept");
-                       sleep(1);
-                       continue;
-               }
-               if ((pid = fork()) < 0)
-                       printf("Out of processes\n");
-               else if (pid == 0) {
-                       signal(SIGCHLD, SIG_DFL);
-                       doit(s2, &from);
-               }
-               close(s2);
-       }
-       /*NOTREACHED*/
-}
-
-reapchild()
-{
-       union wait status;
-
-       while (wait3(&status, WNOHANG, 0) > 0)
-               ;
+       doit(0, &from);
 }
 
 char   *envinit[] = { "TERM=network", 0 };
 }
 
 char   *envinit[] = { "TERM=network", 0 };
index e6e28dc..3de71d5 100644 (file)
@@ -1,5 +1,5 @@
 #ifndef lint
 #ifndef lint
-static char sccsid[] = "@(#)tftpd.c    4.12 (Berkeley) %G%";
+static char sccsid[] = "@(#)tftpd.c    4.12 (Berkeley) %G%";
 #endif
 
 /*
 #endif
 
 /*
@@ -26,78 +26,58 @@ static char sccsid[] = "@(#)tftpd.c 4.12 (Berkeley) %G%";
 
 extern int errno;
 struct sockaddr_in sin = { AF_INET };
 
 extern int errno;
 struct sockaddr_in sin = { AF_INET };
-int    f;
+int    peer;
 int    rexmtval = TIMEOUT;
 int    maxtimeout = 5*TIMEOUT;
 char   buf[BUFSIZ];
 int    rexmtval = TIMEOUT;
 int    maxtimeout = 5*TIMEOUT;
 char   buf[BUFSIZ];
-int    reapchild();
+struct sockaddr_in from;
+int    fromlen;
 
 
-main(argc, argv)
-       char *argv[];
+main()
 {
 {
-       struct sockaddr_in from;
        register struct tftphdr *tp;
        register int n;
        register struct tftphdr *tp;
        register int n;
-       struct servent *sp;
 
 
-       sp = getservbyname("tftp", "udp");
-       if (sp == 0) {
-               fprintf(stderr, "tftpd: udp/tftp: unknown service\n");
+       alarm(10);
+       fromlen = sizeof (from);
+       n = recvfrom(0, buf, sizeof (buf), 0,
+           (caddr_t)&from, &fromlen);
+       if (n < 0) {
+               perror("tftpd: recvfrom");
                exit(1);
        }
                exit(1);
        }
-       sin.sin_port = sp->s_port;
-#ifndef DEBUG
+       from.sin_family = AF_INET;
+       alarm(0);
+#ifdef do_it_right_and_use_a_new_port
        if (fork())
                exit(0);
        if (fork())
                exit(0);
-       for (f = 0; f < 10; f++)
-               (void) close(f);
-       (void) open("/", 0);
-       (void) dup2(0, 1);
-       (void) dup2(0, 2);
-       { int t = open("/dev/tty", 2);
-         if (t >= 0) {
-               ioctl(t, TIOCNOTTY, (char *)0);
-               (void) close(t);
-         }
+       close(0);
+       close(1);
+       peer = socket(AF_INET, SOCK_DGRAM, 0);
+       if (peer < 0) {
+               perror("tftpd: socket");
+               exit(1);
+       }
+       if (bind(peer, (caddr_t)&sin, sizeof (sin)) < 0) {
+               perror("tftpd: bind");
+               exit(1);
        }
        }
+#else
+       /*
+        * The current 4.2 tftp client neglects to switch its destination
+        * port after the first ACK.
+        */
+       peer = 0;
 #endif
 #endif
-       signal(SIGCHLD, reapchild);
-       for (;;) {
-               int fromlen;
-
-               f = socket(AF_INET, SOCK_DGRAM, 0);
-               if (f < 0) {
-                       perror("tftpd: socket");
-                       sleep(5);
-                       continue;
-               }
-               if (setsockopt(f, SOL_SOCKET, SO_REUSEADDR, 0, 0) < 0)
-                       perror("tftpd: setsockopt (SO_REUSEADDR)");
-               sleep(1);                       /* let child do connect */
-               while (bind(f, (caddr_t)&sin, sizeof (sin), 0) < 0) {
-                       perror("tftpd: bind");
-                       sleep(5);
-               }
-               do {
-                       fromlen = sizeof (from);
-                       n = recvfrom(f, buf, sizeof (buf), 0,
-                           (caddr_t)&from, &fromlen);
-               } while (n <= 0);
-               tp = (struct tftphdr *)buf;
-               tp->th_opcode = ntohs(tp->th_opcode);
-               if (tp->th_opcode == RRQ || tp->th_opcode == WRQ)
-                       if (fork() == 0)
-                               tftp(&from, tp, n);
-               (void) close(f);
+       if (connect(peer, (caddr_t)&from, sizeof(from)) < 0) {
+               perror("tftpd: connect");
+               exit(1);
        }
        }
-}
-
-reapchild()
-{
-       union wait status;
-
-       while (wait3(&status, WNOHANG, 0) > 0)
-               ;
+       tp = (struct tftphdr *)buf;
+       tp->th_opcode = ntohs(tp->th_opcode);
+       if (tp->th_opcode == RRQ || tp->th_opcode == WRQ)
+               tftp(tp, n);
+       exit(1);
 }
 
 int    validate_access();
 }
 
 int    validate_access();
@@ -117,13 +97,10 @@ struct formats {
        { 0 }
 };
 
        { 0 }
 };
 
-int    fd;                     /* file being transferred */
-
 /*
  * Handle initial connection protocol.
  */
 /*
  * Handle initial connection protocol.
  */
-tftp(client, tp, size)
-       struct sockaddr_in *client;
+tftp(tp, size)
        struct tftphdr *tp;
        int size;
 {
        struct tftphdr *tp;
        int size;
 {
@@ -132,10 +109,6 @@ tftp(client, tp, size)
        register struct formats *pf;
        char *filename, *mode;
 
        register struct formats *pf;
        char *filename, *mode;
 
-       if (connect(f, (caddr_t)client, sizeof (*client), 0) < 0) {
-               perror("connect");
-               exit(1);
-       }
        filename = cp = tp->th_stuff;
 again:
        while (cp < buf + size) {
        filename = cp = tp->th_stuff;
 again:
        while (cp < buf + size) {
@@ -162,7 +135,7 @@ again:
                nak(EBADOP);
                exit(1);
        }
                nak(EBADOP);
                exit(1);
        }
-       ecode = (*pf->f_validate)(filename, client, tp->th_opcode);
+       ecode = (*pf->f_validate)(filename, tp->th_opcode);
        if (ecode) {
                nak(ecode);
                exit(1);
        if (ecode) {
                nak(ecode);
                exit(1);
@@ -174,6 +147,8 @@ again:
        exit(0);
 }
 
        exit(0);
 }
 
+int    fd;
+
 /*
  * Validate file access.  Since we
  * have no uid or gid, for now require
 /*
  * Validate file access.  Since we
  * have no uid or gid, for now require
@@ -182,9 +157,8 @@ again:
  * Note also, full path name must be
  * given as we have no login directory.
  */
  * Note also, full path name must be
  * given as we have no login directory.
  */
-validate_access(file, client, mode)
+validate_access(file, mode)
        char *file;
        char *file;
-       struct sockaddr_in *client;
        int mode;
 {
        struct stat stbuf;
        int mode;
 {
        struct stat stbuf;
@@ -233,33 +207,31 @@ sendfile(pf)
                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);
-                       goto abort;
+                       return;
                }
                tp->th_opcode = htons((u_short)DATA);
                tp->th_block = htons((u_short)block);
                timeout = 0;
                (void) setjmp(timeoutbuf);
                }
                tp->th_opcode = htons((u_short)DATA);
                tp->th_block = htons((u_short)block);
                timeout = 0;
                (void) setjmp(timeoutbuf);
-               if (write(f, buf, size + 4) != size + 4) {
-                       perror("tftpd: write");
-                       goto abort;
+               if (send(peer, buf, size + 4, 0) != size + 4) {
+                       perror("tftpd: send");
+                       return;
                }
                do {
                        alarm(rexmtval);
                }
                do {
                        alarm(rexmtval);
-                       n = read(f, buf, sizeof (buf));
+                       n = recv(peer, buf, sizeof (buf), 0);
                        alarm(0);
                        if (n < 0) {
                        alarm(0);
                        if (n < 0) {
-                               perror("tftpd: read");
-                               goto abort;
+                               perror("tftpd: recv");
+                               return;
                        }
                        tp->th_opcode = ntohs((u_short)tp->th_opcode);
                        tp->th_block = ntohs((u_short)tp->th_block);
                        if (tp->th_opcode == ERROR)
                        }
                        tp->th_opcode = ntohs((u_short)tp->th_opcode);
                        tp->th_block = ntohs((u_short)tp->th_block);
                        if (tp->th_opcode == ERROR)
-                               goto abort;
+                               return;
                } while (tp->th_opcode != ACK || tp->th_block != block);
                block++;
        } while (size == SEGSIZE);
                } while (tp->th_opcode != ACK || tp->th_block != block);
                block++;
        } while (size == SEGSIZE);
-abort:
-       (void) close(fd);
 }
 
 /*
 }
 
 /*
@@ -279,16 +251,16 @@ recvfile(pf)
                tp->th_block = htons((u_short)block);
                block++;
                (void) setjmp(timeoutbuf);
                tp->th_block = htons((u_short)block);
                block++;
                (void) setjmp(timeoutbuf);
-               if (write(f, buf, 4) != 4) {
-                       perror("tftpd: write");
+               if (send(peer, buf, 4, 0) != 4) {
+                       perror("tftpd: send");
                        goto abort;
                }
                do {
                        alarm(rexmtval);
                        goto abort;
                }
                do {
                        alarm(rexmtval);
-                       n = read(f, buf, sizeof (buf));
+                       n = recv(peer, buf, sizeof (buf), 0);
                        alarm(0);
                        if (n < 0) {
                        alarm(0);
                        if (n < 0) {
-                               perror("tftpd: read");
+                               perror("tftpd: recv");
                                goto abort;
                        }
                        tp->th_opcode = ntohs((u_short)tp->th_opcode);
                                goto abort;
                        }
                        tp->th_opcode = ntohs((u_short)tp->th_opcode);
@@ -305,8 +277,7 @@ recvfile(pf)
 abort:
        tp->th_opcode = htons((u_short)ACK);
        tp->th_block = htons((u_short)(block));
 abort:
        tp->th_opcode = htons((u_short)ACK);
        tp->th_block = htons((u_short)(block));
-       (void) write(f, buf, 4);
-       (void) close(fd);
+       (void) send(peer, buf, 4, 0);
 }
 
 struct errmsg {
 }
 
 struct errmsg {
@@ -350,6 +321,7 @@ nak(error)
        length = strlen(pe->e_msg);
        tp->th_msg[length] = '\0';
        length += 5;
        length = strlen(pe->e_msg);
        tp->th_msg[length] = '\0';
        length += 5;
-       if (write(f, buf, length) != length)
+       if (send(peer, buf, length, 0) != length)
                perror("nak");
                perror("nak");
+       exit(1);
 }
 }