eliminate local version of glob (cf ftp)
[unix-history] / usr / src / libexec / ftpd / ftpcmd.y
index bcf761b..437e7c6 100644 (file)
@@ -1,20 +1,10 @@
 /*
 /*
- * Copyright (c) 1985, 1988 Regents of the University of California.
- * All rights reserved.
+ * Copyright (c) 1985, 1988, 1993, 1994
+ *     The Regents of the University of California.  All rights reserved.
  *
  *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by the University of California, Berkeley.  The name of the
- * University may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ * %sccs.include.redist.c%
  *
  *
- *     @(#)ftpcmd.y    5.22 (Berkeley) %G%
+ *     @(#)ftpcmd.y    8.2 (Berkeley) %G%
  */
 
 /*
  */
 
 /*
 %{
 
 #ifndef lint
 %{
 
 #ifndef lint
-static char sccsid[] = "@(#)ftpcmd.y   5.22 (Berkeley) %G%";
+static char sccsid[] = "@(#)ftpcmd.y   8.2 (Berkeley) %G%";
 #endif /* not lint */
 
 #include <sys/param.h>
 #include <sys/socket.h>
 #endif /* not lint */
 
 #include <sys/param.h>
 #include <sys/socket.h>
+#include <sys/stat.h>
 
 #include <netinet/in.h>
 
 #include <netinet/in.h>
-
 #include <arpa/ftp.h>
 
 #include <arpa/ftp.h>
 
-#include <stdio.h>
-#include <signal.h>
 #include <ctype.h>
 #include <ctype.h>
+#include <errno.h>
+#include <glob.h>
 #include <pwd.h>
 #include <setjmp.h>
 #include <pwd.h>
 #include <setjmp.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
 #include <syslog.h>
 #include <syslog.h>
-#include <sys/stat.h>
 #include <time.h>
 #include <time.h>
+#include <unistd.h>
+
+#include "extern.h"
 
 extern struct sockaddr_in data_dest;
 extern int logged_in;
 
 extern struct sockaddr_in data_dest;
 extern int logged_in;
@@ -57,11 +53,9 @@ 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[];
-char   **glob();
 
 static int cmd_type;
 static int cmd_form;
 
 static int cmd_type;
 static int cmd_form;
@@ -69,14 +63,18 @@ static      int cmd_bytesz;
 char   cbuf[512];
 char   *fromname;
 
 char   cbuf[512];
 char   *fromname;
 
-char   *index();
 %}
 
 %}
 
+%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
@@ -90,30 +88,39 @@ char        *index();
 
        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);
@@ -121,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:
@@ -160,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:
@@ -172,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:
@@ -184,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
-               {
-                       if ($2 && $4 != NULL) 
-                               send_file_list((char *) $4);
+       | NLST check_login SP STRING CRLF
+               {
+                       if ($2 && $4 != NULL)
+                               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)
@@ -299,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) {
@@ -347,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) {
@@ -362,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",
@@ -396,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",
@@ -424,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);
                }
 
                /*
                }
 
                /*
@@ -441,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)
-                                       perror_reply(550, "%s", (char *) $4);
-                               else if ((stbuf.st_mode&S_IFMT) != S_IFREG) {
-                                       reply(550, "%s: not a plain file.",
-                                               (char *) $4);
+                               if (stat($4, &stbuf) < 0)
+                                       reply(550, "%s: %s",
+                                           $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 *gmtime();
+                                       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",
@@ -461,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;
@@ -512,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 **)&($$) = *glob((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;
+                       }
                }
                }
-       }
        ;
 
 %%
        ;
 
 %%
@@ -735,9 +761,17 @@ struct tab sitetab[] = {
        { NULL,   0,    0,    0,        0 }
 };
 
        { NULL,   0,    0,    0,        0 }
 };
 
-struct tab *
+static char    *copy __P((char *));
+static void     help __P((struct tab *, char *));
+static struct tab *
+                lookup __P((struct tab *, char *));
+static void     sizecmd __P((char *));
+static void     toolong __P((int));
+static int      yylex __P((void));
+
+static struct tab *
 lookup(p, cmd)
 lookup(p, cmd)
-       register struct tab *p;
+       struct tab *p;
        char *cmd;
 {
 
        char *cmd;
 {
 
@@ -755,9 +789,10 @@ lookup(p, cmd)
 char *
 getline(s, n, iop)
        char *s;
 char *
 getline(s, n, iop)
        char *s;
-       register FILE *iop;
+       int n;
+       FILE *iop;
 {
 {
-       register c;
+       int c;
        register char *cs;
 
        cs = s;
        register char *cs;
 
        cs = s;
@@ -806,37 +841,48 @@ getline(s, n, iop)
        if (c == EOF && cs == s)
                return (NULL);
        *cs++ = '\0';
        if (c == EOF && cs == s)
                return (NULL);
        *cs++ = '\0';
-       if (debug)
-               syslog(LOG_DEBUG, "command: %s", s);
+       if (debug) {
+               if (!guest && strncasecmp("pass ", s, 5) == 0) {
+                       /* Don't syslog passwords */
+                       syslog(LOG_DEBUG, "command: %.5s ???", s);
+               } else {
+                       register char *cp;
+                       register int len;
+
+                       /* Don't syslog trailing CR-LF */
+                       len = strlen(s);
+                       cp = s + len - 1;
+                       while (cp >= s && (*cp == '\n' || *cp == '\r')) {
+                               --cp;
+                               --len;
+                       }
+                       syslog(LOG_DEBUG, "command: %.*s", len, s);
+               }
+       }
        return (s);
 }
 
        return (s);
 }
 
-static int
-toolong()
+static void
+toolong(signo)
+       int signo;
 {
 {
-       time_t now;
-       extern char *ctime();
-       extern time_t time();
 
        reply(421,
 
        reply(421,
-         "Timeout (%d seconds): closing control connection.", timeout);
-       (void) time(&now);
-       if (logging) {
-               syslog(LOG_INFO,
-                       "User %s timed out after %d seconds at %s",
-                       (pw ? pw -> pw_name : "unknown"), timeout, ctime(&now));
-       }
+           "Timeout (%d seconds): closing control connection.", timeout);
+       if (logging)
+               syslog(LOG_INFO, "User %s timed out after %d seconds",
+                   (pw ? pw -> pw_name : "unknown"), timeout);
        dologout(1);
 }
 
        dologout(1);
 }
 
+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;
        int n;
-       char c, *strpbrk();
-       char *copy();
+       char c;
 
        for (;;) {
                switch (state) {
 
        for (;;) {
                switch (state) {
@@ -853,7 +899,7 @@ yylex()
                        if (strncasecmp(cbuf, "PASS", 4) != NULL)
                                setproctitle("%s: %s", proctitle, cbuf);
 #endif /* SETPROCTITLE */
                        if (strncasecmp(cbuf, "PASS", 4) != NULL)
                                setproctitle("%s: %s", proctitle, cbuf);
 #endif /* SETPROCTITLE */
-                       if ((cp = index(cbuf, '\r'))) {
+                       if ((cp = strchr(cbuf, '\r'))) {
                                *cp++ = '\n';
                                *cp = '\0';
                        }
                                *cp++ = '\n';
                                *cp = '\0';
                        }
@@ -873,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;
@@ -899,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;
@@ -938,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);
@@ -956,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);
@@ -971,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);
                        }
@@ -1047,8 +1093,9 @@ yylex()
        }
 }
 
        }
 }
 
+void
 upper(s)
 upper(s)
-       register char *s;
+       char *s;
 {
        while (*s != '\0') {
                if (islower(*s))
 {
        while (*s != '\0') {
                if (islower(*s))
@@ -1057,12 +1104,11 @@ upper(s)
        }
 }
 
        }
 }
 
-char *
+static char *
 copy(s)
        char *s;
 {
        char *p;
 copy(s)
        char *s;
 {
        char *p;
-       extern char *malloc(), *strcpy();
 
        p = malloc((unsigned) strlen(s) + 1);
        if (p == NULL)
 
        p = malloc((unsigned) strlen(s) + 1);
        if (p == NULL)
@@ -1071,12 +1117,13 @@ copy(s)
        return (p);
 }
 
        return (p);
 }
 
+static void
 help(ctab, s)
        struct tab *ctab;
        char *s;
 {
 help(ctab, 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)
@@ -1093,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.",
@@ -1135,31 +1182,30 @@ help(ctab, s)
                    c->name, c->help);
 }
 
                    c->name, c->help);
 }
 
+static void
 sizecmd(filename)
 sizecmd(filename)
-char *filename;
+       char *filename;
 {
        switch (type) {
        case TYPE_L:
        case TYPE_I: {
                struct stat stbuf;
 {
        switch (type) {
        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;
@@ -1173,8 +1219,8 @@ char *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]);
        }