retry data connection (SO_REUSEADDR isn't enough); show directories
authorMike Karels <karels@ucbvax.Berkeley.EDU>
Fri, 21 Apr 1989 01:31:10 +0000 (17:31 -0800)
committerMike Karels <karels@ucbvax.Berkeley.EDU>
Fri, 21 Apr 1989 01:31:10 +0000 (17:31 -0800)
in NLST unless globbing (a botch, but too incompatible otherwise); bostic's
pathname changes

SCCS-vsn: libexec/ftpd/ftpd.c 5.28

usr/src/libexec/ftpd/ftpd.c

index 4f44818..0549b7e 100644 (file)
@@ -22,7 +22,7 @@ char copyright[] =
 #endif /* not lint */
 
 #ifndef lint
 #endif /* not lint */
 
 #ifndef lint
-static char sccsid[] = "@(#)ftpd.c     5.27.1.1        (Berkeley) %G%";
+static char sccsid[] = "@(#)ftpd.c     5.28    (Berkeley) %G%";
 #endif /* not lint */
 
 /*
 #endif /* not lint */
 
 /*
@@ -53,14 +53,13 @@ static char sccsid[] = "@(#)ftpd.c  5.27.1.1        (Berkeley) %G%";
 #include <strings.h>
 #include <syslog.h>
 #include <varargs.h>
 #include <strings.h>
 #include <syslog.h>
 #include <varargs.h>
+#include "pathnames.h"
 
 /*
  * File containing login names
  * NOT to be used on this machine.
  * Commonly used to disallow uucp.
  */
 
 /*
  * File containing login names
  * NOT to be used on this machine.
  * Commonly used to disallow uucp.
  */
-#define        FTPUSERS        "/etc/ftpusers"
-
 extern int errno;
 extern char *sys_errlist[];
 extern int sys_nerr;
 extern int errno;
 extern char *sys_errlist[];
 extern int sys_nerr;
@@ -206,7 +205,7 @@ main(argc, argv, envp)
 nextopt:
                argc--, argv++;
        }
 nextopt:
                argc--, argv++;
        }
-       (void) freopen("/dev/null", "w", stderr);
+       (void) freopen(_PATH_DEVNULL, "w", stderr);
        (void) signal(SIGPIPE, lostconn);
        (void) signal(SIGCHLD, SIG_IGN);
        if ((int)signal(SIGURG, myoob) < 0)
        (void) signal(SIGPIPE, lostconn);
        (void) signal(SIGCHLD, SIG_IGN);
        if ((int)signal(SIGURG, myoob) < 0)
@@ -313,8 +312,8 @@ int askpasswd;                      /* had user command, ask for passwd */
  * If account doesn't exist, ask for passwd anyway.
  * Otherwise, check user requesting login privileges.
  * Disallow anyone who does not have a standard
  * If account doesn't exist, ask for passwd anyway.
  * Otherwise, check user requesting login privileges.
  * Disallow anyone who does not have a standard
- * shell returned by getusershell() (/etc/shells).
- * Disallow anyone mentioned in the file FTPUSERS
+ * shell as returned by getusershell().
+ * Disallow anyone mentioned in the file _PATH_FTPUSERS
  * to allow people such as root and uucp to be avoided.
  */
 user(name)
  * to allow people such as root and uucp to be avoided.
  */
 user(name)
@@ -345,7 +344,7 @@ user(name)
        }
        if (pw = sgetpwnam(name)) {
                if ((shell = pw->pw_shell) == NULL || *shell == 0)
        }
        if (pw = sgetpwnam(name)) {
                if ((shell = pw->pw_shell) == NULL || *shell == 0)
-                       shell = "/bin/sh";
+                       shell = _PATH_BSHELL;
                while ((cp = getusershell()) != NULL)
                        if (strcmp(cp, shell) == 0)
                                break;
                while ((cp = getusershell()) != NULL)
                        if (strcmp(cp, shell) == 0)
                                break;
@@ -359,7 +358,7 @@ user(name)
                        pw = (struct passwd *) NULL;
                        return;
                }
                        pw = (struct passwd *) NULL;
                        return;
                }
-               if ((fd = fopen(FTPUSERS, "r")) != NULL) {
+               if ((fd = fopen(_PATH_FTPUSERS, "r")) != NULL) {
                    while (fgets(line, sizeof (line), fd) != NULL) {
                        if ((cp = index(line, '\n')) != NULL)
                                *cp = '\0';
                    while (fgets(line, sizeof (line), fd) != NULL) {
                        if ((cp = index(line, '\n')) != NULL)
                                *cp = '\0';
@@ -570,7 +569,7 @@ FILE *
 getdatasock(mode)
        char *mode;
 {
 getdatasock(mode)
        char *mode;
 {
-       int s, on = 1;
+       int s, on = 1, tries;
 
        if (data >= 0)
                return (fdopen(data, mode));
 
        if (data >= 0)
                return (fdopen(data, mode));
@@ -578,13 +577,20 @@ getdatasock(mode)
        if (s < 0)
                return (NULL);
        (void) seteuid((uid_t)0);
        if (s < 0)
                return (NULL);
        (void) seteuid((uid_t)0);
-       if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *) &on, sizeof (on)) < 0)
+       if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR,
+           (char *) &on, sizeof (on)) < 0)
                goto bad;
        /* anchor socket to avoid multi-homing problems */
        data_source.sin_family = AF_INET;
        data_source.sin_addr = ctrl_addr.sin_addr;
                goto bad;
        /* anchor socket to avoid multi-homing problems */
        data_source.sin_family = AF_INET;
        data_source.sin_addr = ctrl_addr.sin_addr;
-       if (bind(s, (struct sockaddr *)&data_source, sizeof (data_source)) < 0)
-               goto bad;
+       for (tries = 1; ; tries++) {
+               if (bind(s, (struct sockaddr *)&data_source,
+                   sizeof (data_source)) >= 0)
+                       break;
+               if (errno != EADDRINUSE || tries > 10)
+                       goto bad;
+               sleep(tries);
+       }
        (void) seteuid((uid_t)pw->pw_uid);
        return (fdopen(s, mode));
 bad:
        (void) seteuid((uid_t)pw->pw_uid);
        return (fdopen(s, mode));
 bad:
@@ -1221,6 +1227,7 @@ send_file_list(whichfiles)
        struct direct *dir;
        FILE *dout = NULL;
        register char **dirlist, *dirname;
        struct direct *dir;
        FILE *dout = NULL;
        register char **dirlist, *dirname;
+       int simple = 0;
        char *strpbrk();
 
        if (strpbrk(whichfiles, "~{[*?") != NULL) {
        char *strpbrk();
 
        if (strpbrk(whichfiles, "~{[*?") != NULL) {
@@ -1239,6 +1246,7 @@ send_file_list(whichfiles)
        } else {
                onefile[0] = whichfiles;
                dirlist = onefile;
        } else {
                onefile[0] = whichfiles;
                dirlist = onefile;
+               simple = 1;
        }
 
        if (setjmp(urgcatch)) {
        }
 
        if (setjmp(urgcatch)) {
@@ -1268,7 +1276,7 @@ send_file_list(whichfiles)
 
                if ((st.st_mode&S_IFMT) == S_IFREG) {
                        if (dout == NULL) {
 
                if ((st.st_mode&S_IFMT) == S_IFREG) {
                        if (dout == NULL) {
-                               dout = dataconn(whichfiles, (off_t)-1, "w");
+                               dout = dataconn("file list", (off_t)-1, "w");
                                if (dout == NULL)
                                        return;
                                transflag++;
                                if (dout == NULL)
                                        return;
                                transflag++;
@@ -1297,10 +1305,10 @@ send_file_list(whichfiles)
                         * We have to do a stat to insure it's
                         * not a directory or special file.
                         */
                         * We have to do a stat to insure it's
                         * not a directory or special file.
                         */
-                       if (stat(nbuf, &st) == 0 &&
-                           (st.st_mode&S_IFMT) == S_IFREG) {
+                       if (simple || (stat(nbuf, &st) == 0 &&
+                           (st.st_mode&S_IFMT) == S_IFREG)) {
                                if (dout == NULL) {
                                if (dout == NULL) {
-                                       dout = dataconn(whichfiles, (off_t)-1,
+                                       dout = dataconn("file list", (off_t)-1,
                                                "w");
                                        if (dout == NULL)
                                                return;
                                                "w");
                                        if (dout == NULL)
                                                return;