eliminate local version of glob (cf ftp)
authorJan-Simon Pendry <pendry@ucbvax.Berkeley.EDU>
Tue, 5 Apr 1994 03:36:06 +0000 (19:36 -0800)
committerJan-Simon Pendry <pendry@ucbvax.Berkeley.EDU>
Tue, 5 Apr 1994 03:36:06 +0000 (19:36 -0800)
clean up yacc grammar.  prettiness police.

SCCS-vsn: libexec/ftpd/Makefile 8.2
SCCS-vsn: libexec/ftpd/popen.c 8.2
SCCS-vsn: libexec/ftpd/ftpd.c 8.2
SCCS-vsn: libexec/ftpd/ftpcmd.y 8.2
SCCS-vsn: libexec/ftpd/extern.h 8.2

usr/src/libexec/ftpd/Makefile
usr/src/libexec/ftpd/extern.h
usr/src/libexec/ftpd/ftpcmd.y
usr/src/libexec/ftpd/ftpd.c
usr/src/libexec/ftpd/popen.c

index 82d701e..75c960e 100644 (file)
@@ -1,10 +1,9 @@
-#      @(#)Makefile    8.1 (Berkeley) %G%
+#      @(#)Makefile    8.2 (Berkeley) %G%
 
 PROG=  ftpd
 
 PROG=  ftpd
-CFLAGS+=-I${.CURDIR}/../../usr.bin/ftp -DSETPROCTITLE
-SRCS=  ftpd.c ftpcmd.c glob.c logwtmp.c popen.c vers.c
+CFLAGS+=-DSETPROCTITLE
+SRCS=  ftpd.c ftpcmd.c logwtmp.c popen.c
 MAN8=  ftpd.0
 CLEANFILES+=ftpcmd.c y.tab.h
 MAN8=  ftpd.0
 CLEANFILES+=ftpcmd.c y.tab.h
-.PATH: ${.CURDIR}/../../usr.bin/ftp
 
 .include <bsd.prog.mk>
 
 .include <bsd.prog.mk>
index 94f74eb..6f0a818 100644 (file)
@@ -4,37 +4,36 @@
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)extern.h    8.1 (Berkeley) %G%
+ *     @(#)extern.h    8.2 (Berkeley) %G%
  */
 
  */
 
-void     blkfree __P((char **));
-char   **copyblk __P((char **));
-void     cwd __P((char *));
-void     delete __P((char *));
-void     dologout __P((int));
-void     fatal __P((char *));
-int      ftpd_pclose __P((FILE *));
-FILE    *ftpd_popen __P((char *, char *));
-char   **ftpglob __P((char *));
-char     *getline __P((char *, int, FILE *));
-void     logwtmp __P((char *, char *, char *));
-void     lreply __P((int, const char *, ...));
-void     makedir __P((char *));
-void     nack __P((char *));
-void     pass __P((char *));
-void     passive __P((void));
-void     perror_reply __P((int, char *));
-void     pwd __P((void));
-void     removedir __P((char *));
-void     renamecmd __P((char *, char *));
-char    *renamefrom __P((char *));
-void     reply __P((int, const char *, ...));
-void     retrieve __P((char *, char *));
-void     send_file_list __P((char *));
-void     setproctitle __P((const char *, ...));
-void     statcmd __P((void));
-void     statfilecmd __P((char *));
-void     store __P((char *, char *, int));
-void     upper __P((char *));
-void     user __P((char *));
-char    *yyerror __P((char *));
+void   blkfree __P((char **));
+char  **copyblk __P((char **));
+void   cwd __P((char *));
+void   delete __P((char *));
+void   dologout __P((int));
+void   fatal __P((char *));
+int    ftpd_pclose __P((FILE *));
+FILE   *ftpd_popen __P((char *, char *));
+char   *getline __P((char *, int, FILE *));
+void   logwtmp __P((char *, char *, char *));
+void   lreply __P((int, const char *, ...));
+void   makedir __P((char *));
+void   nack __P((char *));
+void   pass __P((char *));
+void   passive __P((void));
+void   perror_reply __P((int, char *));
+void   pwd __P((void));
+void   removedir __P((char *));
+void   renamecmd __P((char *, char *));
+char   *renamefrom __P((char *));
+void   reply __P((int, const char *, ...));
+void   retrieve __P((char *, char *));
+void   send_file_list __P((char *));
+void   setproctitle __P((const char *, ...));
+void   statcmd __P((void));
+void   statfilecmd __P((char *));
+void   store __P((char *, char *, int));
+void   upper __P((char *));
+void   user __P((char *));
+void   yyerror __P((char *));
index 3e546d8..437e7c6 100644 (file)
@@ -1,10 +1,10 @@
 /*
 /*
- * Copyright (c) 1985, 1988, 1993
+ * Copyright (c) 1985, 1988, 1993, 1994
  *     The Regents of the University of California.  All rights reserved.
  *
  * %sccs.include.redist.c%
  *
  *     The Regents of the University of California.  All rights reserved.
  *
  * %sccs.include.redist.c%
  *
- *     @(#)ftpcmd.y    8.1 (Berkeley) %G%
+ *     @(#)ftpcmd.y    8.2 (Berkeley) %G%
  */
 
 /*
  */
 
 /*
@@ -15,7 +15,7 @@
 %{
 
 #ifndef lint
 %{
 
 #ifndef lint
-static char sccsid[] = "@(#)ftpcmd.y   8.1 (Berkeley) %G%";
+static char sccsid[] = "@(#)ftpcmd.y   8.2 (Berkeley) %G%";
 #endif /* not lint */
 
 #include <sys/param.h>
 #endif /* not lint */
 
 #include <sys/param.h>
@@ -25,17 +25,19 @@ static char sccsid[] = "@(#)ftpcmd.y        8.1 (Berkeley) %G%";
 #include <netinet/in.h>
 #include <arpa/ftp.h>
 
 #include <netinet/in.h>
 #include <arpa/ftp.h>
 
-#include <signal.h>
-#include <setjmp.h>
-#include <syslog.h>
-#include <time.h>
-#include <pwd.h>
+#include <ctype.h>
 #include <errno.h>
 #include <errno.h>
-#include <unistd.h>
+#include <glob.h>
+#include <pwd.h>
+#include <setjmp.h>
+#include <signal.h>
 #include <stdio.h>
 #include <stdio.h>
-#include <ctype.h>
 #include <stdlib.h>
 #include <string.h>
 #include <stdlib.h>
 #include <string.h>
+#include <syslog.h>
+#include <time.h>
+#include <unistd.h>
+
 #include "extern.h"
 
 extern struct sockaddr_in data_dest;
 #include "extern.h"
 
 extern struct sockaddr_in data_dest;
@@ -51,7 +53,6 @@ extern        int maxtimeout;
 extern  int pdata;
 extern char hostname[], remotehost[];
 extern char proctitle[];
 extern  int pdata;
 extern char hostname[], remotehost[];
 extern char proctitle[];
-extern char *globerr;
 extern int usedefault;
 extern  int transflag;
 extern  char tmpline[];
 extern int usedefault;
 extern  int transflag;
 extern  char tmpline[];
@@ -64,11 +65,16 @@ char        *fromname;
 
 %}
 
 
 %}
 
+%union {
+       int     i;
+       char   *s;
+}
+
 %token
        A       B       C       E       F       I
        L       N       P       R       S       T
 
 %token
        A       B       C       E       F       I
        L       N       P       R       S       T
 
-       SP      CRLF    COMMA   STRING  NUMBER
+       SP      CRLF    COMMA
 
        USER    PASS    ACCT    REIN    QUIT    PORT
        PASV    TYPE    STRU    MODE    RETR    STOR
 
        USER    PASS    ACCT    REIN    QUIT    PORT
        PASV    TYPE    STRU    MODE    RETR    STOR
@@ -82,30 +88,39 @@ char        *fromname;
 
        LEXERR
 
 
        LEXERR
 
+%token <s> STRING
+%token <i> NUMBER
+
+%type  <i> check_login octal_number byte_size
+%type  <i> struct_code mode_code type_code form_code
+%type  <s> pathstring pathname password username
+
 %start cmd_list
 
 %%
 
 %start cmd_list
 
 %%
 
-cmd_list:      /* empty */
-       |       cmd_list cmd
-               = {
+cmd_list
+       : /* empty */
+       | cmd_list cmd
+               {
                        fromname = (char *) 0;
                }
                        fromname = (char *) 0;
                }
-       |       cmd_list rcmd
+       | cmd_list rcmd
        ;
 
        ;
 
-cmd:           USER SP username CRLF
-               = {
-                       user((char *) $3);
-                       free((char *) $3);
+cmd
+       : USER SP username CRLF
+               {
+                       user($3);
+                       free($3);
                }
                }
-       |       PASS SP password CRLF
-               {
-                       pass((char *) $3);
-                       free((char *) $3);
+       | PASS SP password CRLF
+               {
+                       pass($3);
+                       free($3);
                }
                }
-       |       PORT SP host_port CRLF
-               {
+       | PORT SP host_port CRLF
+               {
                        usedefault = 0;
                        if (pdata >= 0) {
                                (void) close(pdata);
                        usedefault = 0;
                        if (pdata >= 0) {
                                (void) close(pdata);
@@ -113,12 +128,12 @@ cmd:              USER SP username CRLF
                        }
                        reply(200, "PORT command successful.");
                }
                        }
                        reply(200, "PORT command successful.");
                }
-       |       PASV CRLF
-               {
+       | PASV CRLF
+               {
                        passive();
                }
                        passive();
                }
-       |       TYPE SP type_code CRLF
-               {
+       | TYPE SP type_code CRLF
+               {
                        switch (cmd_type) {
 
                        case TYPE_A:
                        switch (cmd_type) {
 
                        case TYPE_A:
@@ -152,8 +167,8 @@ cmd:                USER SP username CRLF
 #endif /* NBBY == 8 */
                        }
                }
 #endif /* NBBY == 8 */
                        }
                }
-       |       STRU SP struct_code CRLF
-               {
+       | STRU SP struct_code CRLF
+               {
                        switch ($3) {
 
                        case STRU_F:
                        switch ($3) {
 
                        case STRU_F:
@@ -164,8 +179,8 @@ cmd:                USER SP username CRLF
                                reply(504, "Unimplemented STRU type.");
                        }
                }
                                reply(504, "Unimplemented STRU type.");
                        }
                }
-       |       MODE SP mode_code CRLF
-               {
+       | MODE SP mode_code CRLF
+               {
                        switch ($3) {
 
                        case MODE_S:
                        switch ($3) {
 
                        case MODE_S:
@@ -176,114 +191,114 @@ cmd:            USER SP username CRLF
                                reply(502, "Unimplemented MODE type.");
                        }
                }
                                reply(502, "Unimplemented MODE type.");
                        }
                }
-       |       ALLO SP NUMBER CRLF
-               {
+       | ALLO SP NUMBER CRLF
+               {
                        reply(202, "ALLO command ignored.");
                }
                        reply(202, "ALLO command ignored.");
                }
-       |       ALLO SP NUMBER SP R SP NUMBER CRLF
-               {
+       | ALLO SP NUMBER SP R SP NUMBER CRLF
+               {
                        reply(202, "ALLO command ignored.");
                }
                        reply(202, "ALLO command ignored.");
                }
-       |       RETR check_login SP pathname CRLF
-               {
+       | RETR check_login SP pathname CRLF
+               {
                        if ($2 && $4 != NULL)
                        if ($2 && $4 != NULL)
-                               retrieve((char *) 0, (char *) $4);
+                               retrieve((char *) 0, $4);
                        if ($4 != NULL)
                        if ($4 != NULL)
-                               free((char *) $4);
+                               free($4);
                }
                }
-       |       STOR check_login SP pathname CRLF
-               {
+       | STOR check_login SP pathname CRLF
+               {
                        if ($2 && $4 != NULL)
                        if ($2 && $4 != NULL)
-                               store((char *) $4, "w", 0);
+                               store($4, "w", 0);
                        if ($4 != NULL)
                        if ($4 != NULL)
-                               free((char *) $4);
+                               free($4);
                }
                }
-       |       APPE check_login SP pathname CRLF
-               {
+       | APPE check_login SP pathname CRLF
+               {
                        if ($2 && $4 != NULL)
                        if ($2 && $4 != NULL)
-                               store((char *) $4, "a", 0);
+                               store($4, "a", 0);
                        if ($4 != NULL)
                        if ($4 != NULL)
-                               free((char *) $4);
+                               free($4);
                }
                }
-       |       NLST check_login CRLF
-               {
+       | NLST check_login CRLF
+               {
                        if ($2)
                                send_file_list(".");
                }
                        if ($2)
                                send_file_list(".");
                }
-       |       NLST check_login SP STRING CRLF
-               {
+       | NLST check_login SP STRING CRLF
+               {
                        if ($2 && $4 != NULL)
                        if ($2 && $4 != NULL)
-                               send_file_list((char *) $4);
+                               send_file_list($4);
                        if ($4 != NULL)
                        if ($4 != NULL)
-                               free((char *) $4);
+                               free($4);
                }
                }
-       |       LIST check_login CRLF
-               {
+       | LIST check_login CRLF
+               {
                        if ($2)
                                retrieve("/bin/ls -lgA", "");
                }
                        if ($2)
                                retrieve("/bin/ls -lgA", "");
                }
-       |       LIST check_login SP pathname CRLF
-               {
+       | LIST check_login SP pathname CRLF
+               {
                        if ($2 && $4 != NULL)
                        if ($2 && $4 != NULL)
-                               retrieve("/bin/ls -lgA %s", (char *) $4);
+                               retrieve("/bin/ls -lgA %s", $4);
                        if ($4 != NULL)
                        if ($4 != NULL)
-                               free((char *) $4);
+                               free($4);
                }
                }
-       |       STAT check_login SP pathname CRLF
-               {
+       | STAT check_login SP pathname CRLF
+               {
                        if ($2 && $4 != NULL)
                        if ($2 && $4 != NULL)
-                               statfilecmd((char *) $4);
+                               statfilecmd($4);
                        if ($4 != NULL)
                        if ($4 != NULL)
-                               free((char *) $4);
+                               free($4);
                }
                }
-       |       STAT CRLF
-               {
+       | STAT CRLF
+               {
                        statcmd();
                }
                        statcmd();
                }
-       |       DELE check_login SP pathname CRLF
-               {
+       | DELE check_login SP pathname CRLF
+               {
                        if ($2 && $4 != NULL)
                        if ($2 && $4 != NULL)
-                               delete((char *) $4);
+                               delete($4);
                        if ($4 != NULL)
                        if ($4 != NULL)
-                               free((char *) $4);
+                               free($4);
                }
                }
-       |       RNTO SP pathname CRLF
-               {
+       | RNTO SP pathname CRLF
+               {
                        if (fromname) {
                        if (fromname) {
-                               renamecmd(fromname, (char *) $3);
+                               renamecmd(fromname, $3);
                                free(fromname);
                                fromname = (char *) 0;
                        } else {
                                reply(503, "Bad sequence of commands.");
                        }
                                free(fromname);
                                fromname = (char *) 0;
                        } else {
                                reply(503, "Bad sequence of commands.");
                        }
-                       free((char *) $3);
+                       free($3);
                }
                }
-       |       ABOR CRLF
-               {
+       | ABOR CRLF
+               {
                        reply(225, "ABOR command successful.");
                }
                        reply(225, "ABOR command successful.");
                }
-       |       CWD check_login CRLF
-               {
+       | CWD check_login CRLF
+               {
                        if ($2)
                                cwd(pw->pw_dir);
                }
                        if ($2)
                                cwd(pw->pw_dir);
                }
-       |       CWD check_login SP pathname CRLF
-               {
+       | CWD check_login SP pathname CRLF
+               {
                        if ($2 && $4 != NULL)
                        if ($2 && $4 != NULL)
-                               cwd((char *) $4);
+                               cwd($4);
                        if ($4 != NULL)
                        if ($4 != NULL)
-                               free((char *) $4);
+                               free($4);
                }
                }
-       |       HELP CRLF
-               {
+       | HELP CRLF
+               {
                        help(cmdtab, (char *) 0);
                }
                        help(cmdtab, (char *) 0);
                }
-       |       HELP SP STRING CRLF
-               {
-                       register char *cp = (char *)$3;
+       | HELP SP STRING CRLF
+               {
+                       char *cp = $3;
 
                        if (strncasecmp(cp, "SITE", 4) == 0) {
 
                        if (strncasecmp(cp, "SITE", 4) == 0) {
-                               cp = (char *)$3 + 4;
+                               cp = $3 + 4;
                                if (*cp == ' ')
                                        cp++;
                                if (*cp)
                                if (*cp == ' ')
                                        cp++;
                                if (*cp)
@@ -291,46 +306,46 @@ cmd:              USER SP username CRLF
                                else
                                        help(sitetab, (char *) 0);
                        } else
                                else
                                        help(sitetab, (char *) 0);
                        } else
-                               help(cmdtab, (char *) $3);
+                               help(cmdtab, $3);
                }
                }
-       |       NOOP CRLF
-               {
+       | NOOP CRLF
+               {
                        reply(200, "NOOP command successful.");
                }
                        reply(200, "NOOP command successful.");
                }
-       |       MKD check_login SP pathname CRLF
-               {
+       | MKD check_login SP pathname CRLF
+               {
                        if ($2 && $4 != NULL)
                        if ($2 && $4 != NULL)
-                               makedir((char *) $4);
+                               makedir($4);
                        if ($4 != NULL)
                        if ($4 != NULL)
-                               free((char *) $4);
+                               free($4);
                }
                }
-       |       RMD check_login SP pathname CRLF
-               {
+       | RMD check_login SP pathname CRLF
+               {
                        if ($2 && $4 != NULL)
                        if ($2 && $4 != NULL)
-                               removedir((char *) $4);
+                               removedir($4);
                        if ($4 != NULL)
                        if ($4 != NULL)
-                               free((char *) $4);
+                               free($4);
                }
                }
-       |       PWD check_login CRLF
-               {
+       | PWD check_login CRLF
+               {
                        if ($2)
                                pwd();
                }
                        if ($2)
                                pwd();
                }
-       |       CDUP check_login CRLF
-               {
+       | CDUP check_login CRLF
+               {
                        if ($2)
                                cwd("..");
                }
                        if ($2)
                                cwd("..");
                }
-       |       SITE SP HELP CRLF
-               {
+       | SITE SP HELP CRLF
+               {
                        help(sitetab, (char *) 0);
                }
                        help(sitetab, (char *) 0);
                }
-       |       SITE SP HELP SP STRING CRLF
-               {
-                       help(sitetab, (char *) $5);
+       | SITE SP HELP SP STRING CRLF
+               {
+                       help(sitetab, $5);
                }
                }
-       |       SITE SP UMASK check_login CRLF
-               {
+       | SITE SP UMASK check_login CRLF
+               {
                        int oldmask;
 
                        if ($4) {
                        int oldmask;
 
                        if ($4) {
@@ -339,8 +354,8 @@ cmd:                USER SP username CRLF
                                reply(200, "Current UMASK is %03o", oldmask);
                        }
                }
                                reply(200, "Current UMASK is %03o", oldmask);
                        }
                }
-       |       SITE SP UMASK check_login SP octal_number CRLF
-               {
+       | SITE SP UMASK check_login SP octal_number CRLF
+               {
                        int oldmask;
 
                        if ($4) {
                        int oldmask;
 
                        if ($4) {
@@ -354,28 +369,28 @@ cmd:              USER SP username CRLF
                                }
                        }
                }
                                }
                        }
                }
-       |       SITE SP CHMOD check_login SP octal_number SP pathname CRLF
-               {
+       | SITE SP CHMOD check_login SP octal_number SP pathname CRLF
+               {
                        if ($4 && ($8 != NULL)) {
                                if ($6 > 0777)
                                        reply(501,
                                "CHMOD: Mode value must be between 0 and 0777");
                        if ($4 && ($8 != NULL)) {
                                if ($6 > 0777)
                                        reply(501,
                                "CHMOD: Mode value must be between 0 and 0777");
-                               else if (chmod((char *) $8, $6) < 0)
-                                       perror_reply(550, (char *) $8);
+                               else if (chmod($8, $6) < 0)
+                                       perror_reply(550, $8);
                                else
                                        reply(200, "CHMOD command successful.");
                        }
                        if ($8 != NULL)
                                else
                                        reply(200, "CHMOD command successful.");
                        }
                        if ($8 != NULL)
-                               free((char *) $8);
+                               free($8);
                }
                }
-       |       SITE SP IDLE CRLF
-               {
+       | SITE SP IDLE CRLF
+               {
                        reply(200,
                            "Current IDLE time limit is %d seconds; max %d",
                                timeout, maxtimeout);
                }
                        reply(200,
                            "Current IDLE time limit is %d seconds; max %d",
                                timeout, maxtimeout);
                }
-       |       SITE SP IDLE SP NUMBER CRLF
-               {
+       | SITE SP IDLE SP NUMBER CRLF
+               {
                        if ($5 < 30 || $5 > maxtimeout) {
                                reply(501,
                        "Maximum IDLE time must be between 30 and %d seconds",
                        if ($5 < 30 || $5 > maxtimeout) {
                                reply(501,
                        "Maximum IDLE time must be between 30 and %d seconds",
@@ -388,15 +403,15 @@ cmd:              USER SP username CRLF
                                    timeout);
                        }
                }
                                    timeout);
                        }
                }
-       |       STOU check_login SP pathname CRLF
-               {
+       | STOU check_login SP pathname CRLF
+               {
                        if ($2 && $4 != NULL)
                        if ($2 && $4 != NULL)
-                               store((char *) $4, "w", 1);
+                               store($4, "w", 1);
                        if ($4 != NULL)
                        if ($4 != NULL)
-                               free((char *) $4);
+                               free($4);
                }
                }
-       |       SYST CRLF
-               {
+       | SYST CRLF
+               {
 #ifdef unix
 #ifdef BSD
                        reply(215, "UNIX Type: L%d Version: BSD-%d",
 #ifdef unix
 #ifdef BSD
                        reply(215, "UNIX Type: L%d Version: BSD-%d",
@@ -416,12 +431,12 @@ cmd:              USER SP username CRLF
                 * Return size of file in a format suitable for
                 * using with RESTART (we just count bytes).
                 */
                 * Return size of file in a format suitable for
                 * using with RESTART (we just count bytes).
                 */
-       |       SIZE check_login SP pathname CRLF
-               {
+       | SIZE check_login SP pathname CRLF
+               {
                        if ($2 && $4 != NULL)
                        if ($2 && $4 != NULL)
-                               sizecmd((char *) $4);
+                               sizecmd($4);
                        if ($4 != NULL)
                        if ($4 != NULL)
-                               free((char *) $4);
+                               free($4);
                }
 
                /*
                }
 
                /*
@@ -433,18 +448,17 @@ cmd:              USER SP username CRLF
                 * where xxx is the fractional second (of any precision,
                 * not necessarily 3 digits)
                 */
                 * where xxx is the fractional second (of any precision,
                 * not necessarily 3 digits)
                 */
-       |       MDTM check_login SP pathname CRLF
-               {
+       | MDTM check_login SP pathname CRLF
+               {
                        if ($2 && $4 != NULL) {
                                struct stat stbuf;
                        if ($2 && $4 != NULL) {
                                struct stat stbuf;
-                               if (stat((char *) $4, &stbuf) < 0)
+                               if (stat($4, &stbuf) < 0)
                                        reply(550, "%s: %s",
                                        reply(550, "%s: %s",
-                                           (char *)$4, strerror(errno));
-                               else if ((stbuf.st_mode&S_IFMT) != S_IFREG) {
-                                       reply(550, "%s: not a plain file.",
-                                               (char *) $4);
+                                           $4, strerror(errno));
+                               else if (!S_ISREG(stbuf.st_mode)) {
+                                       reply(550, "%s: not a plain file.", $4);
                                } else {
                                } else {
-                                       register struct tm *t;
+                                       struct tm *t;
                                        t = gmtime(&stbuf.st_mtime);
                                        reply(213,
                                            "19%02d%02d%02d%02d%02d%02d",
                                        t = gmtime(&stbuf.st_mtime);
                                        reply(213,
                                            "19%02d%02d%02d%02d%02d%02d",
@@ -453,48 +467,53 @@ cmd:              USER SP username CRLF
                                }
                        }
                        if ($4 != NULL)
                                }
                        }
                        if ($4 != NULL)
-                               free((char *) $4);
+                               free($4);
                }
                }
-       |       QUIT CRLF
-               {
+       | QUIT CRLF
+               {
                        reply(221, "Goodbye.");
                        dologout(0);
                }
                        reply(221, "Goodbye.");
                        dologout(0);
                }
-       |       error CRLF
-               {
+       | error CRLF
+               {
                        yyerrok;
                }
        ;
                        yyerrok;
                }
        ;
-rcmd:          RNFR check_login SP pathname CRLF
-               = {
+rcmd
+       : RNFR check_login SP pathname CRLF
+               {
                        char *renamefrom();
 
                        if ($2 && $4) {
                        char *renamefrom();
 
                        if ($2 && $4) {
-                               fromname = renamefrom((char *) $4);
+                               fromname = renamefrom($4);
                                if (fromname == (char *) 0 && $4) {
                                if (fromname == (char *) 0 && $4) {
-                                       free((char *) $4);
+                                       free($4);
                                }
                        }
                }
        ;
 
                                }
                        }
                }
        ;
 
-username:      STRING
+username
+       : STRING
        ;
 
        ;
 
-password:      /* empty */
-               = {
-                       *(char **)&($$) = (char *)calloc(1, sizeof(char));
+password
+       : /* empty */
+               {
+                       $$ = (char *)calloc(1, sizeof(char));
                }
                }
-       |       STRING
+       | STRING
        ;
 
        ;
 
-byte_size:     NUMBER
+byte_size
+       : NUMBER
        ;
 
        ;
 
-host_port:     NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA
+host_port
+       : NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA
                NUMBER COMMA NUMBER
                NUMBER COMMA NUMBER
-               {
-                       register char *a, *p;
+               {
+                       char *a, *p;
 
                        a = (char *)&data_dest.sin_addr;
                        a[0] = $1; a[1] = $3; a[2] = $5; a[3] = $7;
 
                        a = (char *)&data_dest.sin_addr;
                        a[0] = $1; a[1] = $3; a[2] = $5; a[3] = $7;
@@ -504,146 +523,161 @@ host_port:      NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA
                }
        ;
 
                }
        ;
 
-form_code:     N
-       = {
-               $$ = FORM_N;
-       }
-       |       T
-       = {
-               $$ = FORM_T;
-       }
-       |       C
-       = {
-               $$ = FORM_C;
-       }
+form_code
+       : N
+               {
+                       $$ = FORM_N;
+               }
+       | T
+               {
+                       $$ = FORM_T;
+               }
+       | C
+               {
+                       $$ = FORM_C;
+               }
        ;
 
        ;
 
-type_code:     A
-       = {
-               cmd_type = TYPE_A;
-               cmd_form = FORM_N;
-       }
-       |       A SP form_code
-       = {
-               cmd_type = TYPE_A;
-               cmd_form = $3;
-       }
-       |       E
-       = {
-               cmd_type = TYPE_E;
-               cmd_form = FORM_N;
-       }
-       |       E SP form_code
-       = {
-               cmd_type = TYPE_E;
-               cmd_form = $3;
-       }
-       |       I
-       = {
-               cmd_type = TYPE_I;
-       }
-       |       L
-       = {
-               cmd_type = TYPE_L;
-               cmd_bytesz = NBBY;
-       }
-       |       L SP byte_size
-       = {
-               cmd_type = TYPE_L;
-               cmd_bytesz = $3;
-       }
-       /* this is for a bug in the BBN ftp */
-       |       L byte_size
-       = {
-               cmd_type = TYPE_L;
-               cmd_bytesz = $2;
-       }
+type_code
+       : A
+               {
+                       cmd_type = TYPE_A;
+                       cmd_form = FORM_N;
+               }
+       | A SP form_code
+               {
+                       cmd_type = TYPE_A;
+                       cmd_form = $3;
+               }
+       | E
+               {
+                       cmd_type = TYPE_E;
+                       cmd_form = FORM_N;
+               }
+       | E SP form_code
+               {
+                       cmd_type = TYPE_E;
+                       cmd_form = $3;
+               }
+       | I
+               {
+                       cmd_type = TYPE_I;
+               }
+       | L
+               {
+                       cmd_type = TYPE_L;
+                       cmd_bytesz = NBBY;
+               }
+       | L SP byte_size
+               {
+                       cmd_type = TYPE_L;
+                       cmd_bytesz = $3;
+               }
+               /* this is for a bug in the BBN ftp */
+       | L byte_size
+               {
+                       cmd_type = TYPE_L;
+                       cmd_bytesz = $2;
+               }
        ;
 
        ;
 
-struct_code:   F
-       = {
-               $$ = STRU_F;
-       }
-       |       R
-       = {
-               $$ = STRU_R;
-       }
-       |       P
-       = {
-               $$ = STRU_P;
-       }
+struct_code
+       : F
+               {
+                       $$ = STRU_F;
+               }
+       | R
+               {
+                       $$ = STRU_R;
+               }
+       | P
+               {
+                       $$ = STRU_P;
+               }
        ;
 
        ;
 
-mode_code:     S
-       = {
-               $$ = MODE_S;
-       }
-       |       B
-       = {
-               $$ = MODE_B;
-       }
-       |       C
-       = {
-               $$ = MODE_C;
-       }
+mode_code
+       : S
+               {
+                       $$ = MODE_S;
+               }
+       | B
+               {
+                       $$ = MODE_B;
+               }
+       | C
+               {
+                       $$ = MODE_C;
+               }
        ;
 
        ;
 
-pathname:      pathstring
-       = {
-               /*
-                * Problem: this production is used for all pathname
-                * processing, but only gives a 550 error reply.
-                * This is a valid reply in some cases but not in others.
-                */
-               if (logged_in && $1 && strncmp((char *) $1, "~", 1) == 0) {
-                       *(char **)&($$) = *ftpglob((char *) $1);
-                       if (globerr != NULL) {
-                               reply(550, globerr);
-                               $$ = NULL;
-                       }
-                       free((char *) $1);
-               } else
-                       $$ = $1;
-       }
+pathname
+       : pathstring
+               {
+                       /*
+                        * Problem: this production is used for all pathname
+                        * processing, but only gives a 550 error reply.
+                        * This is a valid reply in some cases but not in others.
+                        */
+                       if (logged_in && $1 && *$1 == '~') {
+                               glob_t gl;
+                               int flags = GLOB_BRACE|GLOB_QUOTE|GLOB_TILDE;
+
+                               memset(&gl, 0, sizeof(gl));
+                               if (glob($1, flags, NULL, &gl)) {
+                                       reply(550, "not found");
+                                       $$ = NULL;
+                               } else {
+                                       $$ = strdup(gl.gl_pathv[0]);
+                               }
+                               globfree(&gl);
+                               free($1);
+                       } else
+                               $$ = $1;
+               }
        ;
 
        ;
 
-pathstring:    STRING
+pathstring
+       : STRING
        ;
 
        ;
 
-octal_number:  NUMBER
-       = {
-               register int ret, dec, multby, digit;
+octal_number
+       : NUMBER
+               {
+                       int ret, dec, multby, digit;
 
 
-               /*
-                * Convert a number that was read as decimal number
-                * to what it would be if it had been read as octal.
-                */
-               dec = $1;
-               multby = 1;
-               ret = 0;
-               while (dec) {
-                       digit = dec%10;
-                       if (digit > 7) {
-                               ret = -1;
-                               break;
+                       /*
+                        * Convert a number that was read as decimal number
+                        * to what it would be if it had been read as octal.
+                        */
+                       dec = $1;
+                       multby = 1;
+                       ret = 0;
+                       while (dec) {
+                               digit = dec%10;
+                               if (digit > 7) {
+                                       ret = -1;
+                                       break;
+                               }
+                               ret += digit * multby;
+                               multby *= 8;
+                               dec /= 10;
                        }
                        }
-                       ret += digit * multby;
-                       multby *= 8;
-                       dec /= 10;
+                       $$ = ret;
                }
                }
-               $$ = ret;
-       }
        ;
 
        ;
 
-check_login:   /* empty */
-       = {
-               if (logged_in)
-                       $$ = 1;
-               else {
-                       reply(530, "Please login with USER and PASS.");
-                       $$ = 0;
+
+check_login
+       : /* empty */
+               {
+                       if (logged_in)
+                               $$ = 1;
+                       else {
+                               reply(530, "Please login with USER and PASS.");
+                               $$ = 0;
+                       }
                }
                }
-       }
        ;
 
 %%
        ;
 
 %%
@@ -737,7 +771,7 @@ static int   yylex __P((void));
 
 static struct tab *
 lookup(p, cmd)
 
 static struct tab *
 lookup(p, cmd)
-       register struct tab *p;
+       struct tab *p;
        char *cmd;
 {
 
        char *cmd;
 {
 
@@ -756,9 +790,9 @@ char *
 getline(s, n, iop)
        char *s;
        int n;
 getline(s, n, iop)
        char *s;
        int n;
-       register FILE *iop;
+       FILE *iop;
 {
 {
-       register c;
+       int c;
        register char *cs;
 
        cs = s;
        register char *cs;
 
        cs = s;
@@ -845,8 +879,8 @@ static int
 yylex()
 {
        static int cpos, state;
 yylex()
 {
        static int cpos, state;
-       register char *cp, *cp2;
-       register struct tab *p;
+       char *cp, *cp2;
+       struct tab *p;
        int n;
        char c;
 
        int n;
        char c;
 
@@ -885,7 +919,7 @@ yylex()
                                        /* NOTREACHED */
                                }
                                state = p->state;
                                        /* NOTREACHED */
                                }
                                state = p->state;
-                               *(char **)&yylval = p->name;
+                               yylval.s = p->name;
                                return (p->token);
                        }
                        break;
                                return (p->token);
                        }
                        break;
@@ -911,7 +945,7 @@ yylex()
                                        /* NOTREACHED */
                                }
                                state = p->state;
                                        /* NOTREACHED */
                                }
                                state = p->state;
-                               *(char **)&yylval = p->name;
+                               yylval.s = p->name;
                                return (p->token);
                        }
                        state = CMD;
                                return (p->token);
                        }
                        state = CMD;
@@ -950,7 +984,7 @@ yylex()
                         */
                        if (n > 1 && cbuf[cpos] == '\n') {
                                cbuf[cpos] = '\0';
                         */
                        if (n > 1 && cbuf[cpos] == '\n') {
                                cbuf[cpos] = '\0';
-                               *(char **)&yylval = copy(cp);
+                               yylval.s = copy(cp);
                                cbuf[cpos] = '\n';
                                state = ARGS;
                                return (STRING);
                                cbuf[cpos] = '\n';
                                state = ARGS;
                                return (STRING);
@@ -968,7 +1002,7 @@ yylex()
                                        ;
                                c = cbuf[cpos];
                                cbuf[cpos] = '\0';
                                        ;
                                c = cbuf[cpos];
                                cbuf[cpos] = '\0';
-                               yylval = atoi(cp);
+                               yylval.i = atoi(cp);
                                cbuf[cpos] = c;
                                state = STR1;
                                return (NUMBER);
                                cbuf[cpos] = c;
                                state = STR1;
                                return (NUMBER);
@@ -983,7 +1017,7 @@ yylex()
                                        ;
                                c = cbuf[cpos];
                                cbuf[cpos] = '\0';
                                        ;
                                c = cbuf[cpos];
                                cbuf[cpos] = '\0';
-                               yylval = atoi(cp);
+                               yylval.i = atoi(cp);
                                cbuf[cpos] = c;
                                return (NUMBER);
                        }
                                cbuf[cpos] = c;
                                return (NUMBER);
                        }
@@ -1061,7 +1095,7 @@ yylex()
 
 void
 upper(s)
 
 void
 upper(s)
-       register char *s;
+       char *s;
 {
        while (*s != '\0') {
                if (islower(*s))
 {
        while (*s != '\0') {
                if (islower(*s))
@@ -1088,8 +1122,8 @@ help(ctab, s)
        struct tab *ctab;
        char *s;
 {
        struct tab *ctab;
        char *s;
 {
-       register struct tab *c;
-       register int width, NCMDS;
+       struct tab *c;
+       int width, NCMDS;
        char *type;
 
        if (ctab == sitetab)
        char *type;
 
        if (ctab == sitetab)
@@ -1106,7 +1140,7 @@ help(ctab, s)
        }
        width = (width + 8) &~ 7;
        if (s == 0) {
        }
        width = (width + 8) &~ 7;
        if (s == 0) {
-               register int i, j, w;
+               int i, j, w;
                int columns, lines;
 
                lreply(214, "The following %scommands are recognized %s.",
                int columns, lines;
 
                lreply(214, "The following %scommands are recognized %s.",
@@ -1156,24 +1190,22 @@ sizecmd(filename)
        case TYPE_L:
        case TYPE_I: {
                struct stat stbuf;
        case TYPE_L:
        case TYPE_I: {
                struct stat stbuf;
-               if (stat(filename, &stbuf) < 0 ||
-                   (stbuf.st_mode&S_IFMT) != S_IFREG)
+               if (stat(filename, &stbuf) < 0 || !S_ISREG(stbuf.st_mode))
                        reply(550, "%s: not a plain file.", filename);
                else
                        reply(550, "%s: not a plain file.", filename);
                else
-                       reply(213, "%lu", stbuf.st_size);
-               break;}
+                       reply(213, "%qu", stbuf.st_size);
+               break; }
        case TYPE_A: {
                FILE *fin;
        case TYPE_A: {
                FILE *fin;
-               register int c;
-               register long count;
+               int c;
+               off_t count;
                struct stat stbuf;
                fin = fopen(filename, "r");
                if (fin == NULL) {
                        perror_reply(550, filename);
                        return;
                }
                struct stat stbuf;
                fin = fopen(filename, "r");
                if (fin == NULL) {
                        perror_reply(550, filename);
                        return;
                }
-               if (fstat(fileno(fin), &stbuf) < 0 ||
-                   (stbuf.st_mode&S_IFMT) != S_IFREG) {
+               if (fstat(fileno(fin), &stbuf) < 0 || !S_ISREG(stbuf.st_mode)) {
                        reply(550, "%s: not a plain file.", filename);
                        (void) fclose(fin);
                        return;
                        reply(550, "%s: not a plain file.", filename);
                        (void) fclose(fin);
                        return;
@@ -1187,8 +1219,8 @@ sizecmd(filename)
                }
                (void) fclose(fin);
 
                }
                (void) fclose(fin);
 
-               reply(213, "%ld", count);
-               break;}
+               reply(213, "%qd", count);
+               break; }
        default:
                reply(504, "SIZE not implemented for Type %c.", "?AEIL"[type]);
        }
        default:
                reply(504, "SIZE not implemented for Type %c.", "?AEIL"[type]);
        }
index 7aaec85..09dc72d 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 1985, 1988, 1990, 1992, 1993
+ * Copyright (c) 1985, 1988, 1990, 1992, 1993, 1994
  *     The Regents of the University of California.  All rights reserved.
  *
  * %sccs.include.redist.c%
  *     The Regents of the University of California.  All rights reserved.
  *
  * %sccs.include.redist.c%
@@ -7,12 +7,12 @@
 
 #ifndef lint
 static char copyright[] =
 
 #ifndef lint
 static char copyright[] =
-"@(#) Copyright (c) 1985, 1988, 1990, 1992, 1993\n\
+"@(#) Copyright (c) 1985, 1988, 1990, 1992, 1993, 1994\n\
        The Regents of the University of California.  All rights reserved.\n";
 #endif /* not lint */
 
 #ifndef lint
        The Regents of the University of California.  All rights reserved.\n";
 #endif /* not lint */
 
 #ifndef lint
-static char sccsid[] = "@(#)ftpd.c     8.1 (Berkeley) %G%";
+static char sccsid[] = "@(#)ftpd.c     8.2 (Berkeley) %G%";
 #endif /* not lint */
 
 /*
 #endif /* not lint */
 
 /*
@@ -33,20 +33,24 @@ static char sccsid[] = "@(#)ftpd.c  8.1 (Berkeley) %G%";
 #include <arpa/inet.h>
 #include <arpa/telnet.h>
 
 #include <arpa/inet.h>
 #include <arpa/telnet.h>
 
-#include <signal.h>
+#include <ctype.h>
 #include <dirent.h>
 #include <dirent.h>
+#include <err.h>
+#include <errno.h>
 #include <fcntl.h>
 #include <fcntl.h>
-#include <time.h>
+#include <glob.h>
+#include <limits.h>
+#include <netdb.h>
 #include <pwd.h>
 #include <setjmp.h>
 #include <pwd.h>
 #include <setjmp.h>
-#include <netdb.h>
-#include <errno.h>
-#include <syslog.h>
-#include <unistd.h>
+#include <signal.h>
 #include <stdio.h>
 #include <stdio.h>
-#include <ctype.h>
 #include <stdlib.h>
 #include <string.h>
 #include <stdlib.h>
 #include <string.h>
+#include <syslog.h>
+#include <time.h>
+#include <unistd.h>
+
 #include "pathnames.h"
 #include "extern.h"
 
 #include "pathnames.h"
 #include "extern.h"
 
@@ -56,8 +60,9 @@ static char sccsid[] = "@(#)ftpd.c    8.1 (Berkeley) %G%";
 #include <varargs.h>
 #endif
 
 #include <varargs.h>
 #endif
 
+static char version[] = "Version 6.00";
+
 extern off_t restart_point;
 extern off_t restart_point;
-extern char *home;             /* pointer to home directory for glob */
 extern char cbuf[];
 
 struct sockaddr_in ctrl_addr;
 extern char cbuf[];
 
 struct sockaddr_in ctrl_addr;
@@ -81,7 +86,7 @@ int   stru;                   /* avoid C keyword */
 int    mode;
 int    usedefault = 1;         /* for data transfers */
 int    pdata = -1;             /* for passive mode */
 int    mode;
 int    usedefault = 1;         /* for data transfers */
 int    pdata = -1;             /* for passive mode */
-int    transflag;
+sig_atomic_t transflag;
 off_t  file_size;
 off_t  byte_count;
 #if !defined(CMASK) || CMASK == 0
 off_t  file_size;
 off_t  byte_count;
 #if !defined(CMASK) || CMASK == 0
@@ -107,11 +112,9 @@ int        swaitint = SWAITINT;
 #ifdef SETPROCTITLE
 char   **Argv = NULL;          /* pointer to argument vector */
 char   *LastArgv = NULL;       /* end of argv */
 #ifdef SETPROCTITLE
 char   **Argv = NULL;          /* pointer to argument vector */
 char   *LastArgv = NULL;       /* end of argv */
-char   proctitle[BUFSIZ];      /* initial part of title */
+char   proctitle[LINE_MAX];    /* initial part of title */
 #endif /* SETPROCTITLE */
 
 #endif /* SETPROCTITLE */
 
-#define MAXLINE         256
-
 #define LOGCMD(cmd, file) \
        if (logging > 1) \
            syslog(LOG_INFO,"%s %s%s", cmd, \
 #define LOGCMD(cmd, file) \
        if (logging > 1) \
            syslog(LOG_INFO,"%s %s%s", cmd, \
@@ -166,8 +169,8 @@ main(argc, argv, envp)
        char *argv[];
        char **envp;
 {
        char *argv[];
        char **envp;
 {
-       int addrlen, on = 1, tos;
-       char *cp, line[MAXLINE];
+       int addrlen, ch, on = 1, tos;
+       char *cp, line[LINE_MAX];
        FILE *fd;
 
        /*
        FILE *fd;
 
        /*
@@ -175,12 +178,12 @@ main(argc, argv, envp)
         * necessary for anonymous ftp's that chroot and can't do it later.
         */
        openlog("ftpd", LOG_PID | LOG_NDELAY, LOG_FTP);
         * necessary for anonymous ftp's that chroot and can't do it later.
         */
        openlog("ftpd", LOG_PID | LOG_NDELAY, LOG_FTP);
-       addrlen = sizeof (his_addr);
+       addrlen = sizeof(his_addr);
        if (getpeername(0, (struct sockaddr *)&his_addr, &addrlen) < 0) {
                syslog(LOG_ERR, "getpeername (%s): %m",argv[0]);
                exit(1);
        }
        if (getpeername(0, (struct sockaddr *)&his_addr, &addrlen) < 0) {
                syslog(LOG_ERR, "getpeername (%s): %m",argv[0]);
                exit(1);
        }
-       addrlen = sizeof (ctrl_addr);
+       addrlen = sizeof(ctrl_addr);
        if (getsockname(0, (struct sockaddr *)&ctrl_addr, &addrlen) < 0) {
                syslog(LOG_ERR, "getsockname (%s): %m",argv[0]);
                exit(1);
        if (getsockname(0, (struct sockaddr *)&ctrl_addr, &addrlen) < 0) {
                syslog(LOG_ERR, "getsockname (%s): %m",argv[0]);
                exit(1);
@@ -202,14 +205,8 @@ main(argc, argv, envp)
        LastArgv = envp[-1] + strlen(envp[-1]);
 #endif /* SETPROCTITLE */
 
        LastArgv = envp[-1] + strlen(envp[-1]);
 #endif /* SETPROCTITLE */
 
-       argc--, argv++;
-       while (argc > 0 && *argv[0] == '-') {
-               for (cp = &argv[0][1]; *cp; cp++) switch (*cp) {
-
-               case 'v':
-                       debug = 1;
-                       break;
-
+       while ((ch = getopt(argc, argv, "dlt:T:u:v")) != EOF) {
+               switch (ch) {
                case 'd':
                        debug = 1;
                        break;
                case 'd':
                        debug = 1;
                        break;
@@ -219,37 +216,37 @@ main(argc, argv, envp)
                        break;
 
                case 't':
                        break;
 
                case 't':
-                       timeout = atoi(++cp);
+                       timeout = atoi(optarg);
                        if (maxtimeout < timeout)
                                maxtimeout = timeout;
                        if (maxtimeout < timeout)
                                maxtimeout = timeout;
-                       goto nextopt;
+                       break;
 
                case 'T':
 
                case 'T':
-                       maxtimeout = atoi(++cp);
+                       maxtimeout = atoi(optarg);
                        if (timeout > maxtimeout)
                                timeout = maxtimeout;
                        if (timeout > maxtimeout)
                                timeout = maxtimeout;
-                       goto nextopt;
+                       break;
 
                case 'u':
                    {
 
                case 'u':
                    {
-                       int val = 0;
+                       long val = 0;
 
 
-                       while (*++cp && *cp >= '0' && *cp <= '9')
-                               val = val*8 + *cp - '0';
-                       if (*cp)
-                               fprintf(stderr, "ftpd: Bad value for -u\n");
+                       val = strtol(optarg, &optarg, 8);
+                       if (*optarg != '\0' || val < 0)
+                               warnx("bad value for -u");
                        else
                                defumask = val;
                        else
                                defumask = val;
-                       goto nextopt;
+                       break;
                    }
 
                    }
 
+               case 'v':
+                       debug = 1;
+                       break;
+
                default:
                default:
-                       fprintf(stderr, "ftpd: Unknown flag -%c ignored.\n",
-                            *cp);
+                       warnx("unknown flag -%c ignored", optopt);
                        break;
                }
                        break;
                }
-nextopt:
-               argc--, argv++;
        }
        (void) freopen(_PATH_DEVNULL, "w", stderr);
        (void) signal(SIGPIPE, lostconn);
        }
        (void) freopen(_PATH_DEVNULL, "w", stderr);
        (void) signal(SIGPIPE, lostconn);
@@ -280,7 +277,7 @@ nextopt:
 
        /* If logins are disabled, print out the message. */
        if ((fd = fopen(_PATH_NOLOGIN,"r")) != NULL) {
 
        /* If logins are disabled, print out the message. */
        if ((fd = fopen(_PATH_NOLOGIN,"r")) != NULL) {
-               while (fgets(line, sizeof (line), fd) != NULL) {
+               while (fgets(line, sizeof(line), fd) != NULL) {
                        if ((cp = strchr(line, '\n')) != NULL)
                                *cp = '\0';
                        lreply(530, "%s", line);
                        if ((cp = strchr(line, '\n')) != NULL)
                                *cp = '\0';
                        lreply(530, "%s", line);
@@ -291,7 +288,7 @@ nextopt:
                exit(0);
        }
        if ((fd = fopen(_PATH_FTPWELCOME, "r")) != NULL) {
                exit(0);
        }
        if ((fd = fopen(_PATH_FTPWELCOME, "r")) != NULL) {
-               while (fgets(line, sizeof (line), fd) != NULL) {
+               while (fgets(line, sizeof(line), fd) != NULL) {
                        if ((cp = strchr(line, '\n')) != NULL)
                                *cp = '\0';
                        lreply(220, "%s", line);
                        if ((cp = strchr(line, '\n')) != NULL)
                                *cp = '\0';
                        lreply(220, "%s", line);
@@ -300,7 +297,7 @@ nextopt:
                (void) fclose(fd);
                /* reply(220,) must follow */
        }
                (void) fclose(fd);
                /* reply(220,) must follow */
        }
-       (void) gethostname(hostname, sizeof (hostname));
+       (void) gethostname(hostname, sizeof(hostname));
        reply(220, "%s FTP server (%s) ready.", hostname, version);
        (void) setjmp(errcatch);
        for (;;)
        reply(220, "%s FTP server (%s) ready.", hostname, version);
        (void) setjmp(errcatch);
        for (;;)
@@ -312,6 +309,7 @@ static void
 lostconn(signo)
        int signo;
 {
 lostconn(signo)
        int signo;
 {
+
        if (debug)
                syslog(LOG_DEBUG, "lost connection");
        dologout(-1);
        if (debug)
                syslog(LOG_DEBUG, "lost connection");
        dologout(-1);
@@ -347,8 +345,7 @@ sgetpwnam(name)
        char *name;
 {
        static struct passwd save;
        char *name;
 {
        static struct passwd save;
-       register struct passwd *p;
-       char *sgetsave();
+       struct passwd *p;
 
        if ((p = getpwnam(name)) == NULL)
                return (p);
 
        if ((p = getpwnam(name)) == NULL)
                return (p);
@@ -387,8 +384,7 @@ void
 user(name)
        char *name;
 {
 user(name)
        char *name;
 {
-       register char *cp;
-       char *shell;
+       char *cp, *shell;
 
        if (logged_in) {
                if (guest) {
 
        if (logged_in) {
                if (guest) {
@@ -451,10 +447,9 @@ static int
 checkuser(name)
        char *name;
 {
 checkuser(name)
        char *name;
 {
-       register FILE *fd;
-       register char *p;
-       char line[BUFSIZ];
+       FILE *fd;
        int found = 0;
        int found = 0;
+       char *p, line[BUFSIZ];
 
        if ((fd = fopen(_PATH_FTPUSERS, "r")) != NULL) {
                while (fgets(line, sizeof(line), fd) != NULL)
 
        if ((fd = fopen(_PATH_FTPUSERS, "r")) != NULL) {
                while (fgets(line, sizeof(line), fd) != NULL)
@@ -492,7 +487,7 @@ void
 pass(passwd)
        char *passwd;
 {
 pass(passwd)
        char *passwd;
 {
-       char *xpasswd, *salt;
+       char *salt, *xpasswd;
        FILE *fd;
 
        if (logged_in || askpasswd == 0) {
        FILE *fd;
 
        if (logged_in || askpasswd == 0) {
@@ -563,9 +558,9 @@ pass(passwd)
         * N.B. reply(230,) must follow the message.
         */
        if ((fd = fopen(_PATH_FTPLOGINMESG, "r")) != NULL) {
         * N.B. reply(230,) must follow the message.
         */
        if ((fd = fopen(_PATH_FTPLOGINMESG, "r")) != NULL) {
-               char *cp, line[MAXLINE];
+               char *cp, line[LINE_MAX];
 
 
-               while (fgets(line, sizeof (line), fd) != NULL) {
+               while (fgets(line, sizeof(line), fd) != NULL) {
                        if ((cp = strchr(line, '\n')) != NULL)
                                *cp = '\0';
                        lreply(230, "%s", line);
                        if ((cp = strchr(line, '\n')) != NULL)
                                *cp = '\0';
                        lreply(230, "%s", line);
@@ -576,7 +571,8 @@ pass(passwd)
        if (guest) {
                reply(230, "Guest login ok, access restrictions apply.");
 #ifdef SETPROCTITLE
        if (guest) {
                reply(230, "Guest login ok, access restrictions apply.");
 #ifdef SETPROCTITLE
-               sprintf(proctitle, "%s: anonymous/%.*s", remotehost,
+               snprintf(proctitle, sizeof(proctitle),
+                   "%s: anonymous/%.*s", remotehost,
                    sizeof(proctitle) - sizeof(remotehost) -
                    sizeof(": anonymous/"), passwd);
                setproctitle(proctitle);
                    sizeof(proctitle) - sizeof(remotehost) -
                    sizeof(": anonymous/"), passwd);
                setproctitle(proctitle);
@@ -584,17 +580,16 @@ pass(passwd)
                if (logging)
                        syslog(LOG_INFO, "ANONYMOUS FTP LOGIN FROM %s, %s",
                            remotehost, passwd);
                if (logging)
                        syslog(LOG_INFO, "ANONYMOUS FTP LOGIN FROM %s, %s",
                            remotehost, passwd);
-               home = "/";             /* guest home dir for globbing */
        } else {
                reply(230, "User %s logged in.", pw->pw_name);
 #ifdef SETPROCTITLE
        } else {
                reply(230, "User %s logged in.", pw->pw_name);
 #ifdef SETPROCTITLE
-               sprintf(proctitle, "%s: %s", remotehost, pw->pw_name);
+               snprintf(proctitle, sizeof(proctitle),
+                   "%s: %s", remotehost, pw->pw_name);
                setproctitle(proctitle);
 #endif /* SETPROCTITLE */
                if (logging)
                        syslog(LOG_INFO, "FTP LOGIN FROM %s as %s",
                            remotehost, pw->pw_name);
                setproctitle(proctitle);
 #endif /* SETPROCTITLE */
                if (logging)
                        syslog(LOG_INFO, "FTP LOGIN FROM %s as %s",
                            remotehost, pw->pw_name);
-               home = pw->pw_dir;      /* home dir for globbing */
        }
        (void) umask(defumask);
        return;
        }
        (void) umask(defumask);
        return;
@@ -609,7 +604,7 @@ retrieve(cmd, name)
 {
        FILE *fin, *dout;
        struct stat st;
 {
        FILE *fin, *dout;
        struct stat st;
-       int (*closefunc)();
+       int (*closefunc) __P((FILE *));
 
        if (cmd == 0) {
                fin = fopen(name, "r"), closefunc = fclose;
 
        if (cmd == 0) {
                fin = fopen(name, "r"), closefunc = fclose;
@@ -632,8 +627,7 @@ retrieve(cmd, name)
                return;
        }
        byte_count = -1;
                return;
        }
        byte_count = -1;
-       if (cmd == 0 &&
-           (fstat(fileno(fin), &st) < 0 || (st.st_mode&S_IFMT) != S_IFREG)) {
+       if (cmd == 0 && (fstat(fileno(fin), &st) < 0 || !S_ISREG(st.st_mode))) {
                reply(550, "%s: not a plain file.", name);
                goto done;
        }
                reply(550, "%s: not a plain file.", name);
                goto done;
        }
@@ -657,7 +651,7 @@ store(name, mode, unique)
 {
        FILE *fout, *din;
        struct stat st;
 {
        FILE *fout, *din;
        struct stat st;
-       int (*closefunc)();
+       int (*closefunc) __P((FILE *));
 
        if (unique && stat(name, &st) == 0 &&
            (name = gunique(name)) == NULL) {
 
        if (unique && stat(name, &st) == 0 &&
            (name = gunique(name)) == NULL) {
@@ -694,8 +688,7 @@ static FILE *
 getdatasock(mode)
        char *mode;
 {
 getdatasock(mode)
        char *mode;
 {
-       int s, on = 1, tries;
-       int t;
+       int on = 1, s, t, tries;
 
        if (data >= 0)
                return (fdopen(data, mode));
 
        if (data >= 0)
                return (fdopen(data, mode));
@@ -704,14 +697,14 @@ getdatasock(mode)
        if (s < 0)
                goto bad;
        if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR,
        if (s < 0)
                goto bad;
        if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR,
-           (char *) &on, sizeof (on)) < 0)
+           (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;
        for (tries = 1; ; tries++) {
                if (bind(s, (struct sockaddr *)&data_source,
                goto bad;
        /* anchor socket to avoid multi-homing problems */
        data_source.sin_family = AF_INET;
        data_source.sin_addr = ctrl_addr.sin_addr;
        for (tries = 1; ; tries++) {
                if (bind(s, (struct sockaddr *)&data_source,
-                   sizeof (data_source)) >= 0)
+                   sizeof(data_source)) >= 0)
                        break;
                if (errno != EADDRINUSE || tries > 10)
                        goto bad;
                        break;
                if (errno != EADDRINUSE || tries > 10)
                        goto bad;
@@ -746,7 +739,7 @@ dataconn(name, size, mode)
        file_size = size;
        byte_count = 0;
        if (size != (off_t) -1)
        file_size = size;
        byte_count = 0;
        if (size != (off_t) -1)
-               (void) sprintf (sizebuf, " (%qd bytes)", size);
+               (void) sprintf(sizebuf, " (%qd bytes)", size);
        else
                (void) strcpy(sizebuf, "");
        if (pdata >= 0) {
        else
                (void) strcpy(sizebuf, "");
        if (pdata >= 0) {
@@ -758,7 +751,7 @@ dataconn(name, size, mode)
                        reply(425, "Can't open data connection.");
                        (void) close(pdata);
                        pdata = -1;
                        reply(425, "Can't open data connection.");
                        (void) close(pdata);
                        pdata = -1;
-                       return(NULL);
+                       return (NULL);
                }
                (void) close(pdata);
                pdata = s;
                }
                (void) close(pdata);
                pdata = s;
@@ -769,7 +762,7 @@ dataconn(name, size, mode)
 #endif
                reply(150, "Opening %s mode data connection for '%s'%s.",
                     type == TYPE_A ? "ASCII" : "BINARY", name, sizebuf);
 #endif
                reply(150, "Opening %s mode data connection for '%s'%s.",
                     type == TYPE_A ? "ASCII" : "BINARY", name, sizebuf);
-               return(fdopen(pdata, mode));
+               return (fdopen(pdata, mode));
        }
        if (data >= 0) {
                reply(125, "Using existing data connection for '%s'%s.",
        }
        if (data >= 0) {
                reply(125, "Using existing data connection for '%s'%s.",
@@ -789,7 +782,7 @@ dataconn(name, size, mode)
        }
        data = fileno(file);
        while (connect(data, (struct sockaddr *)&data_dest,
        }
        data = fileno(file);
        while (connect(data, (struct sockaddr *)&data_dest,
-           sizeof (data_dest)) < 0) {
+           sizeof(data_dest)) < 0) {
                if (errno == EADDRINUSE && retry < swaitmax) {
                        sleep((unsigned) swaitint);
                        retry += swaitint;
                if (errno == EADDRINUSE && retry < swaitmax) {
                        sleep((unsigned) swaitint);
                        retry += swaitint;
@@ -816,9 +809,8 @@ send_data(instr, outstr, blksize)
        FILE *instr, *outstr;
        off_t blksize;
 {
        FILE *instr, *outstr;
        off_t blksize;
 {
-       register int c, cnt;
-       register char *buf;
-       int netfd, filefd;
+       int c, cnt, filefd, netfd;
+       char *buf;
 
        transflag++;
        if (setjmp(urgcatch)) {
 
        transflag++;
        if (setjmp(urgcatch)) {
@@ -893,7 +885,7 @@ static int
 receive_data(instr, outstr)
        FILE *instr, *outstr;
 {
 receive_data(instr, outstr)
        FILE *instr, *outstr;
 {
-       register int c;
+       int c;
        int cnt, bare_lfs = 0;
        char buf[BUFSIZ];
 
        int cnt, bare_lfs = 0;
        char buf[BUFSIZ];
 
@@ -906,7 +898,7 @@ receive_data(instr, outstr)
 
        case TYPE_I:
        case TYPE_L:
 
        case TYPE_I:
        case TYPE_L:
-               while ((cnt = read(fileno(instr), buf, sizeof buf)) > 0) {
+               while ((cnt = read(fileno(instr), buf, sizeof(buf))) > 0) {
                        if (write(fileno(outstr), buf, cnt) != cnt)
                                goto file_err;
                        byte_count += cnt;
                        if (write(fileno(outstr), buf, cnt) != cnt)
                                goto file_err;
                        byte_count += cnt;
@@ -970,9 +962,9 @@ void
 statfilecmd(filename)
        char *filename;
 {
 statfilecmd(filename)
        char *filename;
 {
-       char line[BUFSIZ];
        FILE *fin;
        int c;
        FILE *fin;
        int c;
+       char line[LINE_MAX];
 
        (void)snprintf(line, sizeof(line), "/bin/ls -lgA %s", filename);
        fin = ftpd_popen(line, "r");
 
        (void)snprintf(line, sizeof(line), "/bin/ls -lgA %s", filename);
        fin = ftpd_popen(line, "r");
@@ -1055,6 +1047,7 @@ void
 fatal(s)
        char *s;
 {
 fatal(s)
        char *s;
 {
+
        reply(451, "Error in server: %s\n", s);
        reply(221, "Closing connection due to server error.");
        dologout(0);
        reply(451, "Error in server: %s\n", s);
        reply(221, "Closing connection due to server error.");
        dologout(0);
@@ -1117,6 +1110,7 @@ static void
 ack(s)
        char *s;
 {
 ack(s)
        char *s;
 {
+
        reply(250, "%s command successful.", s);
 }
 
        reply(250, "%s command successful.", s);
 }
 
@@ -1124,11 +1118,12 @@ void
 nack(s)
        char *s;
 {
 nack(s)
        char *s;
 {
+
        reply(502, "%s command not implemented.", s);
 }
 
 /* ARGSUSED */
        reply(502, "%s command not implemented.", s);
 }
 
 /* ARGSUSED */
-char *
+void
 yyerror(s)
        char *s;
 {
 yyerror(s)
        char *s;
 {
@@ -1169,6 +1164,7 @@ void
 cwd(path)
        char *path;
 {
 cwd(path)
        char *path;
 {
+
        if (chdir(path) < 0)
                perror_reply(550, path);
        else
        if (chdir(path) < 0)
                perror_reply(550, path);
        else
@@ -1179,6 +1175,7 @@ void
 makedir(name)
        char *name;
 {
 makedir(name)
        char *name;
 {
+
        LOGCMD("mkdir", name);
        if (mkdir(name, 0777) < 0)
                perror_reply(550, name);
        LOGCMD("mkdir", name);
        if (mkdir(name, 0777) < 0)
                perror_reply(550, name);
@@ -1190,6 +1187,7 @@ void
 removedir(name)
        char *name;
 {
 removedir(name)
        char *name;
 {
+
        LOGCMD("rmdir", name);
        if (rmdir(name) < 0)
                perror_reply(550, name);
        LOGCMD("rmdir", name);
        if (rmdir(name) < 0)
                perror_reply(550, name);
@@ -1226,6 +1224,7 @@ void
 renamecmd(from, to)
        char *from, *to;
 {
 renamecmd(from, to)
        char *from, *to;
 {
+
        LOGCMD2("rename", from, to);
        if (rename(from, to) < 0)
                perror_reply(550, "rename");
        LOGCMD2("rename", from, to);
        if (rename(from, to) < 0)
                perror_reply(550, "rename");
@@ -1238,15 +1237,15 @@ dolog(sin)
        struct sockaddr_in *sin;
 {
        struct hostent *hp = gethostbyaddr((char *)&sin->sin_addr,
        struct sockaddr_in *sin;
 {
        struct hostent *hp = gethostbyaddr((char *)&sin->sin_addr,
-               sizeof (struct in_addr), AF_INET);
+               sizeof(struct in_addr), AF_INET);
 
        if (hp)
 
        if (hp)
-               (void) strncpy(remotehost, hp->h_name, sizeof (remotehost));
+               (void) strncpy(remotehost, hp->h_name, sizeof(remotehost));
        else
                (void) strncpy(remotehost, inet_ntoa(sin->sin_addr),
        else
                (void) strncpy(remotehost, inet_ntoa(sin->sin_addr),
-                   sizeof (remotehost));
+                   sizeof(remotehost));
 #ifdef SETPROCTITLE
 #ifdef SETPROCTITLE
-       sprintf(proctitle, "%s: connected", remotehost);
+       snprintf(proctitle, sizeof(proctitle), "%s: connected", remotehost);
        setproctitle(proctitle);
 #endif /* SETPROCTITLE */
 
        setproctitle(proctitle);
 #endif /* SETPROCTITLE */
 
@@ -1262,6 +1261,7 @@ void
 dologout(status)
        int status;
 {
 dologout(status)
        int status;
 {
+
        if (logged_in) {
                (void) seteuid((uid_t)0);
                logwtmp(ttyline, "", "");
        if (logged_in) {
                (void) seteuid((uid_t)0);
                logwtmp(ttyline, "", "");
@@ -1310,7 +1310,7 @@ void
 passive()
 {
        int len;
 passive()
 {
        int len;
-       register char *p, *a;
+       char *p, *a;
 
        pdata = socket(AF_INET, SOCK_STREAM, 0);
        if (pdata < 0) {
 
        pdata = socket(AF_INET, SOCK_STREAM, 0);
        if (pdata < 0) {
@@ -1365,7 +1365,7 @@ gunique(local)
                *cp = '\0';
        if (stat(cp ? local : ".", &st) < 0) {
                perror_reply(553, cp ? local : ".");
                *cp = '\0';
        if (stat(cp ? local : ".", &st) < 0) {
                perror_reply(553, cp ? local : ".");
-               return((char *) 0);
+               return ((char *) 0);
        }
        if (cp)
                *cp = '/';
        }
        if (cp)
                *cp = '/';
@@ -1375,10 +1375,10 @@ gunique(local)
        for (count = 1; count < 100; count++) {
                (void)sprintf(cp, "%d", count);
                if (stat(new, &st) < 0)
        for (count = 1; count < 100; count++) {
                (void)sprintf(cp, "%d", count);
                if (stat(new, &st) < 0)
-                       return(new);
+                       return (new);
        }
        reply(452, "Unique file name cannot be created.");
        }
        reply(452, "Unique file name cannot be created.");
-       return(NULL);
+       return (NULL);
 }
 
 /*
 }
 
 /*
@@ -1389,6 +1389,7 @@ perror_reply(code, string)
        int code;
        char *string;
 {
        int code;
        char *string;
 {
+
        reply(code, "%s: %s.", string, strerror(errno));
 }
 
        reply(code, "%s: %s.", string, strerror(errno));
 }
 
@@ -1398,38 +1399,40 @@ static char *onefile[] = {
 };
 
 void
 };
 
 void
-send_file_list(whichfiles)
-       char *whichfiles;
+send_file_list(whichf)
+       char *whichf;
 {
        struct stat st;
        DIR *dirp = NULL;
        struct dirent *dir;
        FILE *dout = NULL;
 {
        struct stat st;
        DIR *dirp = NULL;
        struct dirent *dir;
        FILE *dout = NULL;
-       register char **dirlist, *dirname;
+       char **dirlist, *dirname;
        int simple = 0;
        int simple = 0;
+       int freeglob = 0;
+       glob_t gl;
 
 
-       if (strpbrk(whichfiles, "~{[*?") != NULL) {
-               extern char *globerr;
+       if (strpbrk(whichf, "~{[*?") != NULL) {
 
 
-               globerr = NULL;
-               dirlist = ftpglob(whichfiles);
-               if (globerr != NULL) {
-                       reply(550, globerr);
-                       return;
-               } else if (dirlist == NULL) {
+               memset(&gl, 0, sizeof(gl));
+               freeglob = 1;
+               if (glob(whichf, GLOB_BRACE|GLOB_QUOTE|GLOB_TILDE, 0, &gl)) {
+                       reply(550, "not found");
+                       goto out;
+               } else if (gl.gl_pathc == 0) {
                        errno = ENOENT;
                        errno = ENOENT;
-                       perror_reply(550, whichfiles);
-                       return;
+                       perror_reply(550, whichf);
+                       goto out;
                }
                }
+               dirlist = gl.gl_pathv;
        } else {
        } else {
-               onefile[0] = whichfiles;
+               onefile[0] = whichf;
                dirlist = onefile;
                simple = 1;
        }
 
        if (setjmp(urgcatch)) {
                transflag = 0;
                dirlist = onefile;
                simple = 1;
        }
 
        if (setjmp(urgcatch)) {
                transflag = 0;
-               return;
+               goto out;
        }
        while (dirname = *dirlist++) {
                if (stat(dirname, &st) < 0) {
        }
        while (dirname = *dirlist++) {
                if (stat(dirname, &st) < 0) {
@@ -1440,30 +1443,30 @@ send_file_list(whichfiles)
                        if (dirname[0] == '-' && *dirlist == NULL &&
                            transflag == 0) {
                                retrieve("/bin/ls %s", dirname);
                        if (dirname[0] == '-' && *dirlist == NULL &&
                            transflag == 0) {
                                retrieve("/bin/ls %s", dirname);
-                               return;
+                               goto out;
                        }
                        }
-                       perror_reply(550, whichfiles);
+                       perror_reply(550, whichf);
                        if (dout != NULL) {
                                (void) fclose(dout);
                                transflag = 0;
                                data = -1;
                                pdata = -1;
                        }
                        if (dout != NULL) {
                                (void) fclose(dout);
                                transflag = 0;
                                data = -1;
                                pdata = -1;
                        }
-                       return;
+                       goto out;
                }
 
                }
 
-               if ((st.st_mode&S_IFMT) == S_IFREG) {
+               if (S_ISREG(st.st_mode)) {
                        if (dout == NULL) {
                                dout = dataconn("file list", (off_t)-1, "w");
                                if (dout == NULL)
                        if (dout == NULL) {
                                dout = dataconn("file list", (off_t)-1, "w");
                                if (dout == NULL)
-                                       return;
+                                       goto out;
                                transflag++;
                        }
                        fprintf(dout, "%s%s\n", dirname,
                                type == TYPE_A ? "\r" : "");
                        byte_count += strlen(dirname) + 1;
                        continue;
                                transflag++;
                        }
                        fprintf(dout, "%s%s\n", dirname,
                                type == TYPE_A ? "\r" : "");
                        byte_count += strlen(dirname) + 1;
                        continue;
-               } else if ((st.st_mode&S_IFMT) != S_IFDIR)
+               } else if (!S_ISDIR(st.st_mode))
                        continue;
 
                if ((dirp = opendir(dirname)) == NULL)
                        continue;
 
                if ((dirp = opendir(dirname)) == NULL)
@@ -1485,12 +1488,12 @@ send_file_list(whichfiles)
                         * not a directory or special file.
                         */
                        if (simple || (stat(nbuf, &st) == 0 &&
                         * not a directory or special file.
                         */
                        if (simple || (stat(nbuf, &st) == 0 &&
-                           (st.st_mode&S_IFMT) == S_IFREG)) {
+                           S_ISREG(st.st_mode))) {
                                if (dout == NULL) {
                                        dout = dataconn("file list", (off_t)-1,
                                                "w");
                                        if (dout == NULL)
                                if (dout == NULL) {
                                        dout = dataconn("file list", (off_t)-1,
                                                "w");
                                        if (dout == NULL)
-                                               return;
+                                               goto out;
                                        transflag++;
                                }
                                if (nbuf[0] == '.' && nbuf[1] == '/')
                                        transflag++;
                                }
                                if (nbuf[0] == '.' && nbuf[1] == '/')
@@ -1517,6 +1520,11 @@ send_file_list(whichfiles)
                (void) fclose(dout);
        data = -1;
        pdata = -1;
                (void) fclose(dout);
        data = -1;
        pdata = -1;
+out:
+       if (freeglob) {
+               freeglob = 0;
+               globfree(&gl);
+       }
 }
 
 #ifdef SETPROCTITLE
 }
 
 #ifdef SETPROCTITLE
@@ -1534,10 +1542,11 @@ setproctitle(fmt, va_alist)
         va_dcl
 #endif
 {
         va_dcl
 #endif
 {
-       register char *p, *bp, ch;
-       register int i;
+       int i;
        va_list ap;
        va_list ap;
-       char buf[BUFSIZ];
+       char *p, *bp, ch;
+       char buf[LINE_MAX];
+
 #if __STDC__
        va_start(ap, fmt);
 #else
 #if __STDC__
        va_start(ap, fmt);
 #else
index 3fec3b6..1f5a0bc 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 1988, 1993
+ * Copyright (c) 1988, 1993, 1994
  *     The Regents of the University of California.  All rights reserved.
  *
  * This code is derived from software written by Ken Arnold and
  *     The Regents of the University of California.  All rights reserved.
  *
  * This code is derived from software written by Ken Arnold and
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)popen.c    8.1 (Berkeley) %G%";
+static char sccsid[] = "@(#)popen.c    8.2 (Berkeley) %G%";
 #endif /* not lint */
 
 #include <sys/types.h>
 #include <sys/wait.h>
 
 #endif /* not lint */
 
 #include <sys/types.h>
 #include <sys/wait.h>
 
+#include <errno.h>
+#include <glob.h>
 #include <signal.h>
 #include <signal.h>
-#include <unistd.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <unistd.h>
+
 #include "extern.h"
 
 /*
 #include "extern.h"
 
 /*
- * Special version of popen which avoids call to shell.  This insures noone
+ * Special version of popen which avoids call to shell.  This ensures noone
  * may create a pipe to a hidden program as a side effect of a list or dir
  * command.
  */
  * may create a pipe to a hidden program as a side effect of a list or dir
  * command.
  */
@@ -35,23 +38,23 @@ FILE *
 ftpd_popen(program, type)
        char *program, *type;
 {
 ftpd_popen(program, type)
        char *program, *type;
 {
-       register char *cp;
+       char *cp;
        FILE *iop;
        int argc, gargc, pdes[2], pid;
        FILE *iop;
        int argc, gargc, pdes[2], pid;
-       char **pop, *argv[100], *gargv[1000], *vv[2];
+       char **pop, *argv[100], *gargv[1000];
 
        if (*type != 'r' && *type != 'w' || type[1])
 
        if (*type != 'r' && *type != 'w' || type[1])
-               return(NULL);
+               return (NULL);
 
        if (!pids) {
                if ((fds = getdtablesize()) <= 0)
 
        if (!pids) {
                if ((fds = getdtablesize()) <= 0)
-                       return(NULL);
+                       return (NULL);
                if ((pids = (int *)malloc((u_int)(fds * sizeof(int)))) == NULL)
                if ((pids = (int *)malloc((u_int)(fds * sizeof(int)))) == NULL)
-                       return(NULL);
+                       return (NULL);
                memset(pids, 0, fds * sizeof(int));
        }
        if (pipe(pdes) < 0)
                memset(pids, 0, fds * sizeof(int));
        }
        if (pipe(pdes) < 0)
-               return(NULL);
+               return (NULL);
 
        /* break up string into pieces */
        for (argc = 0, cp = program;; cp = NULL)
 
        /* break up string into pieces */
        for (argc = 0, cp = program;; cp = NULL)
@@ -61,14 +64,16 @@ ftpd_popen(program, type)
        /* glob each piece */
        gargv[0] = argv[0];
        for (gargc = argc = 1; argv[argc]; argc++) {
        /* glob each piece */
        gargv[0] = argv[0];
        for (gargc = argc = 1; argv[argc]; argc++) {
-               if (!(pop = ftpglob(argv[argc]))) {     /* globbing failed */
-                       vv[0] = argv[argc];
-                       vv[1] = NULL;
-                       pop = copyblk(vv);
-               }
-               argv[argc] = (char *)pop;               /* save to free later */
-               while (*pop && gargc < 1000)
-                       gargv[gargc++] = *pop++;
+               glob_t gl;
+               int flags = GLOB_BRACE|GLOB_QUOTE|GLOB_TILDE;
+
+               memset(&gl, 0, sizeof(gl));
+               if (glob(argv[argc], flags, NULL, &gl))
+                       gargv[gargc++] = strdup(argv[argc]);
+               else
+                       for (pop = gl.gl_pathv; *pop; pop++)
+                               gargv[gargc++] = strdup(*pop);
+               globfree(&gl);
        }
        gargv[gargc] = NULL;
 
        }
        gargv[gargc] = NULL;
 
@@ -81,15 +86,15 @@ ftpd_popen(program, type)
                /* NOTREACHED */
        case 0:                         /* child */
                if (*type == 'r') {
                /* NOTREACHED */
        case 0:                         /* child */
                if (*type == 'r') {
-                       if (pdes[1] != 1) {
-                               dup2(pdes[1], 1);
-                               dup2(pdes[1], 2);       /* stderr, too! */
+                       if (pdes[1] != STDOUT_FILENO) {
+                               dup2(pdes[1], STDOUT_FILENO);
                                (void)close(pdes[1]);
                        }
                                (void)close(pdes[1]);
                        }
+                       dup2(STDOUT_FILENO, STDERR_FILENO); /* stderr too! */
                        (void)close(pdes[0]);
                } else {
                        (void)close(pdes[0]);
                } else {
-                       if (pdes[0] != 0) {
-                               dup2(pdes[0], 0);
+                       if (pdes[0] != STDIN_FILENO) {
+                               dup2(pdes[0], STDIN_FILENO);
                                (void)close(pdes[0]);
                        }
                        (void)close(pdes[1]);
                                (void)close(pdes[0]);
                        }
                        (void)close(pdes[1]);
@@ -107,32 +112,34 @@ ftpd_popen(program, type)
        }
        pids[fileno(iop)] = pid;
 
        }
        pids[fileno(iop)] = pid;
 
-pfree: for (argc = 1; argv[argc] != NULL; argc++) {
-               blkfree((char **)argv[argc]);
-               free((char *)argv[argc]);
-       }
-       return(iop);
+pfree: for (argc = 1; gargv[argc] != NULL; argc++)
+               free(gargv[argc]);
+
+       return (iop);
 }
 
 int
 ftpd_pclose(iop)
        FILE *iop;
 {
 }
 
 int
 ftpd_pclose(iop)
        FILE *iop;
 {
-       register int fdes;
-       int omask;
-       union wait stat_loc;
-       int pid;
+       int fdes, omask, status;
+       pid_t pid;
 
        /*
         * pclose returns -1 if stream is not associated with a
         * `popened' command, or, if already `pclosed'.
         */
        if (pids == 0 || pids[fdes = fileno(iop)] == 0)
 
        /*
         * pclose returns -1 if stream is not associated with a
         * `popened' command, or, if already `pclosed'.
         */
        if (pids == 0 || pids[fdes = fileno(iop)] == 0)
-               return(-1);
+               return (-1);
        (void)fclose(iop);
        omask = sigblock(sigmask(SIGINT)|sigmask(SIGQUIT)|sigmask(SIGHUP));
        (void)fclose(iop);
        omask = sigblock(sigmask(SIGINT)|sigmask(SIGQUIT)|sigmask(SIGHUP));
-       while ((pid = wait((int *)&stat_loc)) != pids[fdes] && pid != -1);
+       while ((pid = waitpid(pids[fdes], &status, 0)) < 0 && errno == EINTR)
+               continue;
        (void)sigsetmask(omask);
        pids[fdes] = 0;
        (void)sigsetmask(omask);
        pids[fdes] = 0;
-       return(pid == -1 ? -1 : stat_loc.w_status);
+       if (pid < 0)
+               return (pid);
+       if (WIFEXITED(status))
+               return (WEXITSTATUS(status));
+       return (1);
 }
 }