
# line 42 "ftpcmd.y"

#ifndef lint
static char sccsid[] = "@(#)ftpcmd.y    5.24 (Berkeley) 2/25/91";
#endif /* not lint */

#include "config.h"
#include <sys/param.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <netinet/in.h>
#include <arpa/ftp.h>
#include <stdio.h>
#include <signal.h>
#include <ctype.h>
#include <pwd.h>
#include <setjmp.h>
#ifdef SYSSYSLOG
#include <sys/syslog.h>
#else
#include <syslog.h>
#endif
#include <time.h>
#include <string.h>
#include <limits.h>
#include "support/ftw.h"
#include "extensions.h"
#include "pathnames.h"

extern  int dolreplies;
extern  char ls_long[50];
extern  char ls_short[50];
extern  struct sockaddr_in data_dest;
extern  int logged_in;
extern  struct passwd *pw;
extern  int anonymous;
extern  int logging;
extern  int log_commands;
extern  int type;
extern  int form;
extern  int debug;
extern  int timeout;
extern  int maxtimeout;
extern  int pdata;
extern  char hostname[], remotehost[];
#ifdef SETPROCTITLE
extern  char proctitle[];
#endif
extern  char *globerr;
extern  int usedefault;
extern  int transflag;
extern  char tmpline[];
extern  int data;
char    **ftpglob();
off_t   restart_point;

extern  char    *strunames[];
extern  char    *typenames[];
extern  char    *modenames[];
extern  char    *formnames[];

static  int cmd_type;
static  int cmd_form;
static  int cmd_bytesz;
char    cbuf[512];
char    *fromname;

static void toolong();


# line 132 "ftpcmd.y"
typedef union  {
    char    *String;
    int     Number;
} YYSTYPE;
# define A 257
# define B 258
# define C 259
# define E 260
# define F 261
# define I 262
# define L 263
# define N 264
# define P 265
# define R 266
# define S 267
# define T 268
# define SP 269
# define CRLF 270
# define COMMA 271
# define STRING 272
# define NUMBER 273
# define USER 274
# define PASS 275
# define ACCT 276
# define REIN 277
# define QUIT 278
# define PORT 279
# define PASV 280
# define TYPE 281
# define STRU 282
# define MODE 283
# define RETR 284
# define STOR 285
# define APPE 286
# define MLFL 287
# define MAIL 288
# define MSND 289
# define MSOM 290
# define MSAM 291
# define MRSQ 292
# define MRCP 293
# define ALLO 294
# define REST 295
# define RNFR 296
# define RNTO 297
# define ABOR 298
# define DELE 299
# define CWD 300
# define LIST 301
# define NLST 302
# define SITE 303
# define STAT 304
# define HELP 305
# define NOOP 306
# define MKD 307
# define RMD 308
# define PWD 309
# define CDUP 310
# define STOU 311
# define SMNT 312
# define SYST 313
# define SIZE 314
# define MDTM 315
# define UMASK 316
# define IDLE 317
# define CHMOD 318
# define GROUP 319
# define GPASS 320
# define NEWER 321
# define MINFO 322
# define INDEX 323
# define EXEC 324
# define ALIAS 325
# define CDPATH 326
# define GROUPS 327
# define LEXERR 328
#define yyclearin yychar = -1
#define yyerrok yyerrflag = 0
extern int yychar;
extern int yyerrflag;
#ifndef YYMAXDEPTH
#define YYMAXDEPTH 150
#endif
YYSTYPE yylval, yyval;
typedef int yytabelem;
# define YYERRCODE 256

# line 862 "ftpcmd.y"


extern jmp_buf errcatch;

#define CMD 0   /* beginning of command */
#define ARGS    1   /* expect miscellaneous arguments */
#define STR1    2   /* expect SP followed by STRING */
#define STR2    3   /* expect STRING */
#define OSTR    4   /* optional SP then STRING */
#define ZSTR1   5   /* SP then optional STRING */
#define ZSTR2   6   /* optional STRING after SP */
#define SITECMD 7   /* SITE command */
#define NSTR    8   /* Number followed by a string */
#define STR3    9   /* expect STRING followed by optional SP then STRING */

struct tab {
    char    *name;
    short   token;
    short   state;
    short   implemented;    /* 1 if command is implemented */
    char    *help;
};

struct tab cmdtab[] = {     /* In order defined in RFC 765 */
    { "USER", USER, STR1, 1,    "<sp> username" },
    { "PASS", PASS, ZSTR1, 1,   "<sp> password" },
    { "ACCT", ACCT, STR1, 0,    "(specify account)" },
    { "SMNT", SMNT, ARGS, 0,    "(structure mount)" },
    { "REIN", REIN, ARGS, 0,    "(reinitialize server state)" },
    { "QUIT", QUIT, ARGS, 1,    "(terminate service)", },
    { "PORT", PORT, ARGS, 1,    "<sp> b0, b1, b2, b3, b4" },
    { "PASV", PASV, ARGS, 1,    "(set server in passive mode)" },
    { "TYPE", TYPE, ARGS, 1,    "<sp> [ A | E | I | L ]" },
    { "STRU", STRU, ARGS, 1,    "(specify file structure)" },
    { "MODE", MODE, ARGS, 1,    "(specify transfer mode)" },
    { "RETR", RETR, STR1, 1,    "<sp> file-name" },
    { "STOR", STOR, STR1, 1,    "<sp> file-name" },
    { "APPE", APPE, STR1, 1,    "<sp> file-name" },
    { "MLFL", MLFL, OSTR, 0,    "(mail file)" },
    { "MAIL", MAIL, OSTR, 0,    "(mail to user)" },
    { "MSND", MSND, OSTR, 0,    "(mail send to terminal)" },
    { "MSOM", MSOM, OSTR, 0,    "(mail send to terminal or mailbox)" },
    { "MSAM", MSAM, OSTR, 0,    "(mail send to terminal and mailbox)" },
    { "MRSQ", MRSQ, OSTR, 0,    "(mail recipient scheme question)" },
    { "MRCP", MRCP, STR1, 0,    "(mail recipient)" },
    { "ALLO", ALLO, ARGS, 1,    "allocate storage (vacuously)" },
    { "REST", REST, ARGS, 1,    "(restart command)" },
    { "RNFR", RNFR, STR1, 1,    "<sp> file-name" },
    { "RNTO", RNTO, STR1, 1,    "<sp> file-name" },
    { "ABOR", ABOR, ARGS, 1,    "(abort operation)" },
    { "DELE", DELE, STR1, 1,    "<sp> file-name" },
    { "CWD",  CWD,  OSTR, 1,    "[ <sp> directory-name ]" },
    { "XCWD", CWD,  OSTR, 1,    "[ <sp> directory-name ]" },
    { "LIST", LIST, OSTR, 1,    "[ <sp> path-name ]" },
    { "NLST", NLST, OSTR, 1,    "[ <sp> path-name ]" },
    { "SITE", SITE, SITECMD, 1, "site-cmd [ <sp> arguments ]" },
    { "SYST", SYST, ARGS, 1,    "(get type of operating system)" },
    { "STAT", STAT, OSTR, 1,    "[ <sp> path-name ]" },
    { "HELP", HELP, OSTR, 1,    "[ <sp> <string> ]" },
    { "NOOP", NOOP, ARGS, 1,    "" },
    { "MKD",  MKD,  STR1, 1,    "<sp> path-name" },
    { "XMKD", MKD,  STR1, 1,    "<sp> path-name" },
    { "RMD",  RMD,  STR1, 1,    "<sp> path-name" },
    { "XRMD", RMD,  STR1, 1,    "<sp> path-name" },
    { "PWD",  PWD,  ARGS, 1,    "(return current directory)" },
    { "XPWD", PWD,  ARGS, 1,    "(return current directory)" },
    { "CDUP", CDUP, ARGS, 1,    "(change to parent directory)" },
    { "XCUP", CDUP, ARGS, 1,    "(change to parent directory)" },
    { "STOU", STOU, STR1, 1,    "<sp> file-name" },
    { "SIZE", SIZE, OSTR, 1,    "<sp> path-name" },
    { "MDTM", MDTM, OSTR, 1,    "<sp> path-name" },
    { NULL,   0,    0,    0,    0 }
};

struct tab sitetab[] = {
    { "UMASK", UMASK, ARGS, 1,  "[ <sp> umask ]" },
    { "IDLE",  IDLE,  ARGS, 1,  "[ <sp> maximum-idle-time ]" },
    { "CHMOD", CHMOD, NSTR, 1,  "<sp> mode <sp> file-name" },
    { "HELP",  HELP,  OSTR, 1,  "[ <sp> <string> ]" },
    { "GROUP", GROUP, STR1, 1,  "<sp> access-group" },
    { "GPASS", GPASS, STR1, 1,  "<sp> access-password" },
    { "NEWER", NEWER, STR3, 1,  "<sp> YYYYMMDDHHMMSS [ <sp> path-name ]" },
    { "MINFO", MINFO, STR3, 1,  "<sp> YYYYMMDDHHMMSS [ <sp> path-name ]" },
    { "INDEX", INDEX, STR1, 1,  "<sp> pattern" },
    { "EXEC",  EXEC,  STR1, 1,  "<sp> command [ <sp> arguments ]" },
    { "ALIAS", ALIAS, OSTR, 1,  "[ <sp> alias ] " },
    { "CDPATH", CDPATH, OSTR, 1,  "[ <sp> ] " },
    { "GROUPS", GROUPS, OSTR, 1,  "[ <sp> ] " },
    { NULL,    0,     0,    0,  0 }
};

struct tab *
lookup(p, cmd)
    register struct tab *p;
    char *cmd;
{

    for (; p->name != NULL; p++)
        if (strcmp(cmd, p->name) == 0)
            return (p);
    return (0);
}

#include <arpa/telnet.h>

/*
 * getline - a hacked up version of fgets to ignore TELNET escape codes.
 */
char *
getline(s, n, iop)
    char *s;
    register FILE *iop;
{
    register c;
    register char *cs;

    cs = s;
/* tmpline may contain saved command from urgent mode interruption */
    for (c = 0; tmpline[c] != '\0' && --n > 0; ++c) {
        *cs++ = tmpline[c];
        if (tmpline[c] == '\n') {
            *cs++ = '\0';
            if (debug)
                syslog(LOG_DEBUG, "command: %s", s);
            tmpline[0] = '\0';
            return(s);
        }
        if (c == 0)
            tmpline[0] = '\0';
    }
    while ((c = getc(iop)) != EOF) {
        c &= 0377;
        if (c == IAC) {
            if ((c = getc(iop)) != EOF) {
            c &= 0377;
            switch (c) {
            case WILL:
            case WONT:
                c = getc(iop);
                printf("%c%c%c", IAC, DONT, 0377&c);
                (void) fflush(stdout);
                continue;
            case DO:
            case DONT:
                c = getc(iop);
                printf("%c%c%c", IAC, WONT, 0377&c);
                (void) fflush(stdout);
                continue;
            case IAC:
                break;
            default:
                continue;   /* ignore command */
            }
            }
        }
        *cs++ = c;
        if (--n <= 0 || c == '\n')
            break;
    }
    if (c == EOF && cs == s)
        return (NULL);
    *cs++ = '\0';
    if (debug)
        syslog(LOG_DEBUG, "command: %s", s);
    return (s);
}

static void
toolong()
{
    time_t now;

    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 %.24s",
            (pw ? pw -> pw_name : "unknown"), timeout, ctime(&now));
    }
    dologout(1);
}

yylex()
{
    static int cpos, state;
    register char *cp, *cp2;
    register struct tab *p;
    int n;
    char c, *copy();

    for (;;) {
        switch (state) {

        case CMD:
            (void) signal(SIGALRM, toolong);
            (void) alarm((unsigned) timeout);
            if (is_shutdown(!logged_in) != 0) {
                reply(221, "Server shutting down.  Goodbye.");
                dologout(0);
            }
#ifdef SETPROCTITLE
            setproctitle("%s: IDLE", proctitle);
#endif
            if (getline(cbuf, sizeof(cbuf)-1, stdin) == NULL) {
                reply(221, "You could at least say goodbye.");
                dologout(0);
            }
            (void) alarm(0);
#ifdef SETPROCTITLE
            if (strncasecmp(cbuf, "PASS", 4) != 0 &&
                strncasecmp(cbuf, "SITE GPASS", 10) != 0)
                setproctitle("%s: %s", proctitle, cbuf);
#endif /* SETPROCTITLE */
            if ((cp = strchr(cbuf, '\r'))) {
                *cp++ = '\n';
                *cp = '\0';
            }
            if ((cp = strpbrk(cbuf, " \n")))
                cpos = cp - cbuf;
            if (cpos == 0)
                cpos = 4;
            c = cbuf[cpos];
            cbuf[cpos] = '\0';
            upper(cbuf);
            p = lookup(cmdtab, cbuf);
            cbuf[cpos] = c;
            if (p != 0) {
                if (p->implemented == 0) {
                    nack(p->name);
                    longjmp(errcatch,0);
                    /* NOTREACHED */
                }
                state = p->state;
                yylval.String = p->name;
                return (p->token);
            }
            break;

        case SITECMD:
            if (cbuf[cpos] == ' ') {
                cpos++;
                return (SP);
            }
            cp = &cbuf[cpos];
            if ((cp2 = strpbrk(cp, " \n")))
                cpos = cp2 - cbuf;
            c = cbuf[cpos];
            cbuf[cpos] = '\0';
            upper(cp);
            p = lookup(sitetab, cp);
            cbuf[cpos] = c;
            if (p != 0) {
                if (p->implemented == 0) {
                    state = CMD;
                    nack(p->name);
                    longjmp(errcatch,0);
                    /* NOTREACHED */
                }
                state = p->state;
                yylval.String = p->name;
                return (p->token);
            }
            state = CMD;
            break;

        case OSTR:
            if (cbuf[cpos] == '\n') {
                state = CMD;
                return (CRLF);
            }
            /* FALLTHROUGH */

        case STR1:
        case ZSTR1:
        dostr1:
            if (cbuf[cpos] == ' ') {
                cpos++;
                state = state == OSTR ? STR2 : ++state;
                return (SP);
            }
            break;

        case ZSTR2:
            if (cbuf[cpos] == '\n') {
                state = CMD;
                return (CRLF);
            }
            /* FALLTHROUGH */

        case STR2:
            cp = &cbuf[cpos];
            n = strlen(cp);
            cpos += n - 1;
            /*
             * Make sure the string is nonempty and \n terminated.
             */
            if (n > 1 && cbuf[cpos] == '\n') {
                cbuf[cpos] = '\0';
                yylval.String = copy(cp);
                cbuf[cpos] = '\n';
                state = ARGS;
                return (STRING);
            }
            break;

        case NSTR:
            if (cbuf[cpos] == ' ') {
                cpos++;
                return (SP);
            }
            if (isdigit(cbuf[cpos])) {
                cp = &cbuf[cpos];
                while (isdigit(cbuf[++cpos]))
                    ;
                c = cbuf[cpos];
                cbuf[cpos] = '\0';
                yylval.Number = atoi(cp);
                cbuf[cpos] = c;
                state = STR1;
                return (NUMBER);
            }
            state = STR1;
            goto dostr1;

        case STR3:
            if (cbuf[cpos] == ' ') {
                cpos++;
                return (SP);
            }

            cp = &cbuf[cpos];
            cp2 = strpbrk(cp, " \n");
            if (cp2 != NULL) {
                c = *cp2;
                *cp2 = '\0';
            }
            n = strlen(cp);
            cpos += n;
            /*
             * Make sure the string is nonempty and SP terminated.
             */
            if ((cp2 - cp) > 1) {
                yylval.String = copy(cp);
                cbuf[cpos] = c;
                state = OSTR;
                return (STRING);
            }
            break;

        case ARGS:
            if (isdigit(cbuf[cpos])) {
                cp = &cbuf[cpos];
                while (isdigit(cbuf[++cpos]))
                    ;
                c = cbuf[cpos];
                cbuf[cpos] = '\0';
                yylval.Number = atoi(cp);
                cbuf[cpos] = c;
                return (NUMBER);
            }
            switch (cbuf[cpos++]) {

            case '\n':
                state = CMD;
                return (CRLF);

            case ' ':
                return (SP);

            case ',':
                return (COMMA);

            case 'A':
            case 'a':
                return (A);

            case 'B':
            case 'b':
                return (B);

            case 'C':
            case 'c':
                return (C);

            case 'E':
            case 'e':
                return (E);

            case 'F':
            case 'f':
                return (F);

            case 'I':
            case 'i':
                return (I);

            case 'L':
            case 'l':
                return (L);

            case 'N':
            case 'n':
                return (N);

            case 'P':
            case 'p':
                return (P);

            case 'R':
            case 'r':
                return (R);

            case 'S':
            case 's':
                return (S);

            case 'T':
            case 't':
                return (T);

            }
            break;

        default:
            fatal("Unknown state in scanner.");
        }
        yyerror((char *)NULL);
        state = CMD;
        longjmp(errcatch,0);
    }
}

upper(s)
    register char *s;
{
    while (*s != '\0') {
        if (islower(*s))
            *s = toupper(*s);
        s++;
    }
}

char *
copy(s)
    char *s;
{
    char *p;

    p = malloc((unsigned) strlen(s) + 1);
    if (p == NULL)
        fatal("Ran out of memory.");
    (void) strcpy(p, s);
    return (p);
}

help(ctab, s)
    struct tab *ctab;
    char *s;
{
    register struct tab *c;
    register int width, NCMDS;
    char *type;

    if (ctab == sitetab)
        type = "SITE ";
    else
        type = "";
    width = 0, NCMDS = 0;
    for (c = ctab; c->name != NULL; c++) {
        int len = strlen(c->name);

        if (len > width)
            width = len;
        NCMDS++;
    }
    width = (width + 8) &~ 7;
    if (s == 0) {
        register int i, j, w;
        int columns, lines;

        lreply(214, "The following %scommands are recognized %s.",
            type, "(* =>'s unimplemented)");
        columns = 76 / width;
        if (columns == 0)
            columns = 1;
        lines = (NCMDS + columns - 1) / columns;
        for (i = 0; i < lines; i++) {
            printf("   ");
            for (j = 0; j < columns; j++) {
                c = ctab + j * lines + i;
                printf("%s%c", c->name,
                    c->implemented ? ' ' : '*');
                if (c + lines >= &ctab[NCMDS])
                    break;
                w = strlen(c->name) + 1;
                while (w < width) {
                    putchar(' ');
                    w++;
                }
            }
            printf("\r\n");
        }
        (void) fflush(stdout);
        reply(214, "Direct comments to ftp-bugs@%s.", hostname);
        return;
    }
    upper(s);
    c = lookup(ctab, s);
    if (c == (struct tab *)NULL) {
        reply(502, "Unknown command %s.", s);
        return;
    }
    if (c->implemented)
        reply(214, "Syntax: %s%s %s", type, c->name, c->help);
    else
        reply(214, "%s%-*s\t%s; unimplemented.", type, width,
            c->name, c->help);
}

sizecmd(filename)
char *filename;
{
    switch (type) {
    case TYPE_L:
    case TYPE_I: {
        struct stat stbuf;
        if (stat(filename, &stbuf) < 0 ||
            (stbuf.st_mode&S_IFMT) != S_IFREG)
            reply(550, "%s: not a plain file.", filename);
        else
            reply(213, "%lu", stbuf.st_size);
        break;}
    case TYPE_A: {
        FILE *fin;
        register int c;
        register long count;
        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) {
            reply(550, "%s: not a plain file.", filename);
            (void) fclose(fin);
            return;
        }

        count = 0;
        while((c=getc(fin)) != EOF) {
            if (c == '\n')  /* will get expanded to \r\n */
                count++;
            count++;
        }
        (void) fclose(fin);

        reply(213, "%ld", count);
        break;}
    default:
        reply(504, "SIZE not implemented for Type %c.", "?AEIL"[type]);
    }
}

site_exec(cmd)
char *cmd;
{
    char buf[MAXPATHLEN];
    char *sp = (char *) strchr(cmd, ' '), *slash, *t;
    FILE *cmdf, *ftpd_popen();

    if (!acl_cmd_check("exec", 1)) {
	    reply(553, "Permission denied. (exec)");
	    return;
    }

    /* sanitize the command-string */
    
    if (sp == 0)  {
        while ((slash = strchr (cmd, '/')) != 0)
            cmd = slash + 1;
    } else {
        while (sp && (slash = (char *) strchr(cmd, '/')) 
               && (slash < sp))
            cmd = slash+1;
    }
    
    for (t = cmd;  *t && !isspace(*t);  t++) {
        if (isupper(*t)) {
            *t = tolower(*t);
        }
    }

    /* build the command */
    if (strlen(_PATH_EXECPATH) + strlen(cmd) + 1 > sizeof(buf))
        return;
    sprintf(buf, "%s/%s", _PATH_EXECPATH, cmd);

    cmdf = ftpd_popen(buf, "r", 0);
    if (!cmdf) {
        perror_reply(550, cmd);
        if (log_commands)
            syslog(LOG_INFO, "SITE EXEC (FAIL: %m): %s", cmd);
    } else {
        int lines = 0;

        lreply(200, cmd);
        while (fgets(buf, sizeof buf, cmdf)) {
            int len = strlen(buf);

            if (len>0 && buf[len-1]=='\n')
                buf[--len] = '\0';
            lreply(200, buf);
            if (++lines >= 20) {
                lreply(200, "*** Truncated ***");
                break;
            }
        }
        reply(200, " (end of '%s')", cmd);
        if (log_commands)
            syslog(LOG_INFO, "SITE EXEC (lines: %d): %s", lines, cmd);
        ftpd_pclose(cmdf);
    }
}

alias (s)
char *s;
{
    struct aclmember *entry = NULL;

    if (s != (char *)NULL) {
        while (getaclentry("alias", &entry) && ARG0 && ARG1 != NULL)
            if (!strcmp(ARG0, s)) {
                reply (214, "%s is an alias for %s.", ARG0, ARG1);
                return;
            }
        reply (502, "Unknown alias %s.", s);
        return;
    }

    lreply(214, "The following aliases are available.");

    while (getaclentry("alias", &entry) && ARG0 && ARG1 != NULL)
        printf ("   %-8s %s\r\n", ARG0, ARG1);
    (void) fflush (stdout);

    reply(214, "");
}

cdpath ()
{
    struct aclmember *entry = NULL;

    lreply(214, "The cdpath is:");
    while (getaclentry("cdpath", &entry) && ARG0 != NULL)
        printf ("  %s\r\n", ARG0);
    (void) fflush (stdout);
    reply(214, "");
}

void
print_groups()
{
    gid_t  groups[NGROUPS_MAX];
    int    ngroups = 0;

    if ( (ngroups = getgroups(NGROUPS_MAX, groups)) < 0 ) {
        return;
    }

    lreply(214, "Group membership is:");
    ngroups--;

    for (; ngroups >= 0; ngroups--)
        lreply(214, "  %d", groups[ngroups]);

    (void) fflush (stdout);
    reply(214, "");
}
static yytabelem yyexca[] ={
-1, 1,
	0, -1,
	-2, 0,
	};
# define YYNPROD 86
# define YYLAST 391
static yytabelem yyact[]={

    34,   137,   247,   245,   240,   129,   225,   224,   214,   198,
   129,   176,    91,    77,   103,   222,   243,   221,     4,     5,
   220,   219,    33,     6,     7,     8,     9,    10,    12,    13,
    14,    75,    73,   205,   194,   146,   106,   246,    11,    36,
    35,    19,    20,    18,    21,    16,    15,    28,    17,    22,
    23,    24,    25,    26,    27,    29,   111,    30,    31,    32,
   244,   235,   231,   230,   183,   210,   133,   112,   114,   113,
   115,   116,   117,   118,   119,   120,   121,   123,   122,   196,
   195,   168,   167,   160,   159,   156,   155,   142,   141,   105,
   104,    98,    97,    96,    95,    57,    56,   242,   241,   236,
   234,   233,   229,   228,   226,   223,   216,   212,   209,   208,
   207,   206,   193,   192,   191,   190,   189,   188,   187,   186,
   185,   184,   180,   175,   170,   169,   152,   178,   150,   140,
   139,   179,   134,   101,   132,   131,   130,   110,   109,    69,
    68,    65,    58,    54,    51,    40,   232,   227,   211,   204,
   203,   202,   201,   200,   199,   197,   136,   135,   127,   126,
   125,   124,   108,   107,   100,    99,    94,    93,    92,    89,
    90,    71,    63,    53,    44,    43,    42,    41,    88,    39,
    84,    38,    37,    79,    86,    85,    80,    74,    81,    82,
    72,   213,   128,    78,   177,    76,     3,     2,     1,    83,
    87,   102,     0,     0,     0,     0,     0,     0,     0,     0,
     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
     0,     0,     0,     0,     0,     0,   143,   144,   145,     0,
     0,     0,   147,   148,   149,     0,     0,     0,     0,   151,
     0,   153,   154,     0,     0,     0,     0,     0,     0,     0,
     0,     0,     0,     0,    45,     0,     0,     0,   171,   172,
   173,   174,     0,     0,     0,     0,     0,     0,    46,    47,
    48,    49,    50,    52,     0,   138,    55,     0,     0,    59,
    60,    61,    62,     0,    64,     0,    66,    67,     0,     0,
    70,     0,     0,     0,     0,     0,     0,     0,     0,     0,
     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
   182,   181,     0,     0,     0,     0,     0,     0,     0,     0,
     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
     0,   237,     0,     0,     0,   238,   239,   157,   158,     0,
   161,   162,   163,   164,   165,   166,     0,     0,     0,     0,
     0,     0,     0,     0,     0,     0,     0,     0,   218,   215,
   217 };
static yytabelem yypact[]={

 -1000,  -256, -1000, -1000,   -87,   -88,   -90,  -125,   -92,   -93,
   -94,   -95, -1000, -1000, -1000, -1000, -1000,  -126, -1000,   -96,
  -127, -1000,  -174,  -128, -1000, -1000, -1000, -1000,   -97, -1000,
  -129, -1000, -1000,  -130,  -131, -1000,   -98,  -240,  -241,  -260,
 -1000,   -74,   -81,   -89,  -261,  -101,  -102,  -103,  -176,  -178,
  -104, -1000,  -105,  -258, -1000,  -180, -1000,  -236, -1000,  -106,
  -107,  -132,  -133,  -249,  -108, -1000,  -109,  -110, -1000, -1000,
  -111,  -263,  -134, -1000,  -135, -1000,  -136,  -205,  -138,  -112,
  -113, -1000,  -268,  -140, -1000, -1000, -1000,  -141, -1000, -1000,
 -1000,  -182,  -258,  -258,  -258, -1000,  -237, -1000,  -258,  -258,
  -258,  -142, -1000, -1000, -1000,  -258,  -144,  -258,  -258, -1000,
 -1000,  -184, -1000, -1000,  -186, -1000, -1000, -1000, -1000, -1000,
 -1000,  -188,  -145,  -146,  -258,  -258,  -258,  -258,  -147, -1000,
 -1000, -1000, -1000,  -262, -1000,  -137,  -137,  -263, -1000, -1000,
 -1000, -1000,  -202,  -149,  -150,  -151,  -152,  -153,  -154,  -155,
 -1000,  -156, -1000,  -157,  -158, -1000,  -238,  -190,  -114, -1000,
  -264,  -115,  -116,  -117,  -118,  -119,  -120, -1000,  -239, -1000,
 -1000,  -159,  -160,  -161,  -162, -1000,  -206, -1000, -1000, -1000,
 -1000, -1000, -1000,  -121, -1000, -1000, -1000, -1000, -1000, -1000,
 -1000, -1000, -1000, -1000,  -163, -1000,  -265,  -265,  -164,  -240,
  -241,  -251,  -252,  -255,  -257,  -165, -1000, -1000, -1000, -1000,
  -266,  -267, -1000,  -166, -1000,  -122, -1000,  -167,  -168,  -207,
  -123,  -169,  -170, -1000,  -210,  -171, -1000,  -258, -1000, -1000,
 -1000,  -258,  -258, -1000, -1000,  -269, -1000,  -172,  -173,  -254,
  -211, -1000, -1000, -1000,  -270,  -234,  -271, -1000 };
static yytabelem yypgo[]={

     0,   187,   133,   201,   190,   192,   254,   194,   200,   191,
   199,   198,   197,   196,   195,   193 };
static yytabelem yyr1[]={

     0,    11,    11,    11,    12,    12,    12,    12,    12,    12,
    12,    12,    12,    12,    12,    12,    12,    12,    12,    12,
    12,    12,    12,    12,    12,    12,    12,    12,    12,    12,
    12,    12,    12,    12,    12,    12,    12,    12,    12,    12,
    12,    12,    12,    12,    12,    12,    12,    12,    12,    12,
    12,    12,    12,    12,    13,    13,    13,    13,    13,    13,
     4,     1,     1,     5,    14,     7,     7,     7,    15,    15,
    15,    15,    15,    15,    15,    15,    10,    10,    10,     8,
     8,     8,     2,     3,     9,     6 };
static yytabelem yyr2[]={

     0,     0,     5,     4,     9,     9,     9,     5,     9,     9,
     9,     9,    17,    11,    11,    11,     7,    11,     7,    11,
    11,     5,    11,     9,     5,     7,    11,     5,     9,     5,
    11,    11,     7,     7,     9,    13,    11,    15,    19,     9,
    13,    15,    15,    15,    19,    19,    15,    15,    11,     5,
    11,    11,     5,     5,    11,     9,     9,    13,     9,     9,
     2,     1,     2,     2,    23,     3,     3,     3,     3,     7,
     3,     7,     3,     3,     7,     5,     3,     3,     3,     3,
     3,     3,     3,     2,     3,     1 };
static yytabelem yychk[]={

 -1000,   -11,   -12,   -13,   274,   275,   279,   280,   281,   282,
   283,   294,   284,   285,   286,   302,   301,   304,   299,   297,
   298,   300,   305,   306,   307,   308,   309,   310,   303,   311,
   313,   314,   315,   278,   256,   296,   295,   269,   269,   269,
   270,   269,   269,   269,   269,    -6,    -6,    -6,    -6,    -6,
    -6,   270,    -6,   269,   270,    -6,   270,   269,   270,    -6,
    -6,    -6,    -6,   269,    -6,   270,    -6,    -6,   270,   270,
    -6,   269,    -4,   272,    -1,   272,   -14,   273,   -15,   257,
   260,   262,   263,   -10,   261,   266,   265,    -8,   267,   258,
   259,   273,   269,   269,   269,   270,   269,   270,   269,   269,
   269,    -2,    -3,   272,   270,   269,   272,   269,   269,   270,
   270,   305,   316,   318,   317,   319,   320,   321,   322,   323,
   324,   325,   327,   326,   269,   269,   269,   269,    -5,   273,
   270,   270,   270,   271,   270,   269,   269,   269,    -5,   270,
   270,   270,   269,    -2,    -2,    -2,   272,    -2,    -2,    -2,
   270,    -2,   270,    -2,    -2,   270,   269,    -6,    -6,   270,
   269,    -6,    -6,    -6,    -6,    -6,    -6,   270,   269,   270,
   270,    -2,    -2,    -2,    -2,   270,   273,    -7,   264,   268,
   259,    -7,    -5,   266,   270,   270,   270,   270,   270,   270,
   270,   270,   270,   270,   272,   270,   269,   269,   273,   269,
   269,   269,   269,   269,   269,   272,   270,   270,   270,   270,
   271,   269,   270,    -9,   273,    -9,   270,    -4,    -1,   272,
   272,   272,   272,   270,   273,   273,   270,   269,   270,   270,
   270,   269,   269,   270,   270,   271,   270,    -2,    -2,    -2,
   273,   270,   270,   270,   271,   273,   271,   273 };
static yytabelem yydef[]={

     1,    -2,     2,     3,     0,     0,     0,     0,     0,     0,
     0,     0,    85,    85,    85,    85,    85,    85,    85,     0,
     0,    85,     0,     0,    85,    85,    85,    85,     0,    85,
     0,    85,    85,     0,     0,    85,     0,     0,    61,     0,
     7,     0,     0,     0,     0,     0,     0,     0,     0,     0,
     0,    21,     0,     0,    24,     0,    27,     0,    29,     0,
     0,     0,     0,     0,     0,    49,     0,     0,    52,    53,
     0,     0,     0,    60,     0,    62,     0,     0,     0,    68,
    70,    72,    73,     0,    76,    77,    78,     0,    79,    80,
    81,     0,     0,     0,     0,    16,     0,    18,     0,     0,
     0,     0,    82,    83,    25,     0,     0,     0,     0,    32,
    33,     0,    85,    85,     0,    85,    85,    85,    85,    85,
    85,     0,     0,     0,     0,     0,     0,     0,     0,    63,
     4,     5,     6,     0,     8,     0,     0,     0,    75,     9,
    10,    11,     0,     0,     0,     0,     0,     0,     0,     0,
    23,     0,    28,     0,     0,    34,     0,     0,     0,    39,
     0,     0,     0,     0,     0,     0,     0,    56,     0,    58,
    59,     0,     0,     0,     0,    55,     0,    69,    65,    66,
    67,    71,    74,     0,    13,    14,    15,    17,    19,    20,
    22,    26,    30,    31,     0,    36,     0,     0,     0,     0,
    61,     0,     0,     0,     0,     0,    48,    50,    51,    54,
     0,     0,    35,     0,    84,     0,    40,     0,     0,     0,
     0,     0,     0,    57,     0,     0,    37,     0,    41,    42,
    43,     0,     0,    46,    47,     0,    12,     0,     0,     0,
     0,    38,    44,    45,     0,     0,     0,    64 };
typedef struct { char *t_name; int t_val; } yytoktype;
#ifndef YYDEBUG
#	define YYDEBUG	0	/* don't allow debugging */
#endif

#if YYDEBUG

yytoktype yytoks[] =
{
	"A",	257,
	"B",	258,
	"C",	259,
	"E",	260,
	"F",	261,
	"I",	262,
	"L",	263,
	"N",	264,
	"P",	265,
	"R",	266,
	"S",	267,
	"T",	268,
	"SP",	269,
	"CRLF",	270,
	"COMMA",	271,
	"STRING",	272,
	"NUMBER",	273,
	"USER",	274,
	"PASS",	275,
	"ACCT",	276,
	"REIN",	277,
	"QUIT",	278,
	"PORT",	279,
	"PASV",	280,
	"TYPE",	281,
	"STRU",	282,
	"MODE",	283,
	"RETR",	284,
	"STOR",	285,
	"APPE",	286,
	"MLFL",	287,
	"MAIL",	288,
	"MSND",	289,
	"MSOM",	290,
	"MSAM",	291,
	"MRSQ",	292,
	"MRCP",	293,
	"ALLO",	294,
	"REST",	295,
	"RNFR",	296,
	"RNTO",	297,
	"ABOR",	298,
	"DELE",	299,
	"CWD",	300,
	"LIST",	301,
	"NLST",	302,
	"SITE",	303,
	"STAT",	304,
	"HELP",	305,
	"NOOP",	306,
	"MKD",	307,
	"RMD",	308,
	"PWD",	309,
	"CDUP",	310,
	"STOU",	311,
	"SMNT",	312,
	"SYST",	313,
	"SIZE",	314,
	"MDTM",	315,
	"UMASK",	316,
	"IDLE",	317,
	"CHMOD",	318,
	"GROUP",	319,
	"GPASS",	320,
	"NEWER",	321,
	"MINFO",	322,
	"INDEX",	323,
	"EXEC",	324,
	"ALIAS",	325,
	"CDPATH",	326,
	"GROUPS",	327,
	"LEXERR",	328,
	"-unknown-",	-1	/* ends search */
};

char * yyreds[] =
{
	"-no such reduction-",
      "cmd_list : /* empty */",
      "cmd_list : cmd_list cmd",
      "cmd_list : cmd_list rcmd",
      "cmd : USER SP username CRLF",
      "cmd : PASS SP password CRLF",
      "cmd : PORT SP host_port CRLF",
      "cmd : PASV CRLF",
      "cmd : TYPE SP type_code CRLF",
      "cmd : STRU SP struct_code CRLF",
      "cmd : MODE SP mode_code CRLF",
      "cmd : ALLO SP NUMBER CRLF",
      "cmd : ALLO SP NUMBER SP R SP NUMBER CRLF",
      "cmd : RETR check_login SP pathname CRLF",
      "cmd : STOR check_login SP pathname CRLF",
      "cmd : APPE check_login SP pathname CRLF",
      "cmd : NLST check_login CRLF",
      "cmd : NLST check_login SP STRING CRLF",
      "cmd : LIST check_login CRLF",
      "cmd : LIST check_login SP pathname CRLF",
      "cmd : STAT check_login SP pathname CRLF",
      "cmd : STAT CRLF",
      "cmd : DELE check_login SP pathname CRLF",
      "cmd : RNTO SP pathname CRLF",
      "cmd : ABOR CRLF",
      "cmd : CWD check_login CRLF",
      "cmd : CWD check_login SP pathname CRLF",
      "cmd : HELP CRLF",
      "cmd : HELP SP STRING CRLF",
      "cmd : NOOP CRLF",
      "cmd : MKD check_login SP pathname CRLF",
      "cmd : RMD check_login SP pathname CRLF",
      "cmd : PWD check_login CRLF",
      "cmd : CDUP check_login CRLF",
      "cmd : SITE SP HELP CRLF",
      "cmd : SITE SP HELP SP STRING CRLF",
      "cmd : SITE SP UMASK check_login CRLF",
      "cmd : SITE SP UMASK check_login SP octal_number CRLF",
      "cmd : SITE SP CHMOD check_login SP octal_number SP pathname CRLF",
      "cmd : SITE SP IDLE CRLF",
      "cmd : SITE SP IDLE SP NUMBER CRLF",
      "cmd : SITE SP GROUP check_login SP username CRLF",
      "cmd : SITE SP GPASS check_login SP password CRLF",
      "cmd : SITE SP NEWER check_login SP STRING CRLF",
      "cmd : SITE SP NEWER check_login SP STRING SP pathname CRLF",
      "cmd : SITE SP MINFO check_login SP STRING SP pathname CRLF",
      "cmd : SITE SP INDEX check_login SP STRING CRLF",
      "cmd : SITE SP EXEC check_login SP STRING CRLF",
      "cmd : STOU check_login SP pathname CRLF",
      "cmd : SYST CRLF",
      "cmd : SIZE check_login SP pathname CRLF",
      "cmd : MDTM check_login SP pathname CRLF",
      "cmd : QUIT CRLF",
      "cmd : error CRLF",
      "rcmd : RNFR check_login SP pathname CRLF",
      "rcmd : REST SP byte_size CRLF",
      "rcmd : SITE SP ALIAS CRLF",
      "rcmd : SITE SP ALIAS SP STRING CRLF",
      "rcmd : SITE SP GROUPS CRLF",
      "rcmd : SITE SP CDPATH CRLF",
      "username : STRING",
      "password : /* empty */",
      "password : STRING",
      "byte_size : NUMBER",
      "host_port : NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER",
      "form_code : N",
      "form_code : T",
      "form_code : C",
      "type_code : A",
      "type_code : A SP form_code",
      "type_code : E",
      "type_code : E SP form_code",
      "type_code : I",
      "type_code : L",
      "type_code : L SP byte_size",
      "type_code : L byte_size",
      "struct_code : F",
      "struct_code : R",
      "struct_code : P",
      "mode_code : S",
      "mode_code : B",
      "mode_code : C",
      "pathname : pathstring",
      "pathstring : STRING",
      "octal_number : NUMBER",
      "check_login : /* empty */",
};
#endif /* YYDEBUG */
/*
 * (c) Copyright 1990, OPEN SOFTWARE FOUNDATION, INC.
 * ALL RIGHTS RESERVED
 */
/*
 * OSF/1 Release 1.0
 */
/* @(#)yaccpar	1.3  com/cmd/lang/yacc,3.1, 9/7/89 18:46:37 */
/*
** Skeleton parser driver for yacc output
*/

/*
** yacc user known macros and defines
*/
#ifdef YYSPLIT
#   define YYERROR	return(-2)
#else
#   define YYERROR	goto yyerrlab
#endif

#define YYACCEPT	return(0)
#define YYABORT		return(1)
#define YYBACKUP( newtoken, newvalue )\
{\
	if ( yychar >= 0 || ( yyr2[ yytmp ] >> 1 ) != 1 )\
	{\
		yyerror( "syntax error - cannot backup" );\
		goto yyerrlab;\
	}\
	yychar = newtoken;\
	yystate = *yyps;\
	yylval = newvalue;\
	goto yynewstate;\
}
#define YYRECOVERING()	(!!yyerrflag)
#ifndef YYDEBUG
#	define YYDEBUG	1	/* make debugging available */
#endif

/*
** user known globals
*/
int yydebug;			/* set to 1 to get debugging */

/*
** driver internal defines
*/
#define YYFLAG		(-1000)

#ifdef YYSPLIT
#   define YYSCODE { \
			extern int (*yyf[])(); \
			register int yyret; \
			if (yyf[yytmp]) \
			    if ((yyret=(*yyf[yytmp])()) == -2) \
				    goto yyerrlab; \
				else if (yyret>=0) return(yyret); \
		   }
#endif

/*
** global variables used by the parser
*/
YYSTYPE yyv[ YYMAXDEPTH ];	/* value stack */
int yys[ YYMAXDEPTH ];		/* state stack */

YYSTYPE *yypv;			/* top of value stack */
YYSTYPE *yypvt;			/* top of value stack for $vars */
int *yyps;			/* top of state stack */

int yystate;			/* current state */
int yytmp;			/* extra var (lasts between blocks) */

int yynerrs;			/* number of errors */
int yyerrflag;			/* error recovery flag */
int yychar;			/* current input token number */



/*
** yyparse - return 0 if worked, 1 if syntax error not recovered from
*/
int
yyparse()
{
	/*
	** Initialize externals - yyparse may be called more than once
	*/
	yypv = &yyv[-1];
	yyps = &yys[-1];
	yystate = 0;
	yytmp = 0;
	yynerrs = 0;
	yyerrflag = 0;
	yychar = -1;

	goto yystack;
	{
		register YYSTYPE *yy_pv;	/* top of value stack */
		register int *yy_ps;		/* top of state stack */
		register int yy_state;		/* current state */
		register int  yy_n;		/* internal state number info */

		/*
		** get globals into registers.
		** branch to here only if YYBACKUP was called.
		*/
	yynewstate:
		yy_pv = yypv;
		yy_ps = yyps;
		yy_state = yystate;
		goto yy_newstate;

		/*
		** get globals into registers.
		** either we just started, or we just finished a reduction
		*/
	yystack:
		yy_pv = yypv;
		yy_ps = yyps;
		yy_state = yystate;

		/*
		** top of for (;;) loop while no reductions done
		*/
	yy_stack:
		/*
		** put a state and value onto the stacks
		*/
#if YYDEBUG
		/*
		** if debugging, look up token value in list of value vs.
		** name pairs.  0 and negative (-1) are special values.
		** Note: linear search is used since time is not a real
		** consideration while debugging.
		*/
		if ( yydebug )
		{
			register int yy_i;

			printf( "State %d, token ", yy_state );
			if ( yychar == 0 )
				printf( "end-of-file\n" );
			else if ( yychar < 0 )
				printf( "-none-\n" );
			else
			{
				for ( yy_i = 0; yytoks[yy_i].t_val >= 0;
					yy_i++ )
				{
					if ( yytoks[yy_i].t_val == yychar )
						break;
				}
				printf( "%s\n", yytoks[yy_i].t_name );
			}
		}
#endif /* YYDEBUG */
		if ( ++yy_ps >= &yys[ YYMAXDEPTH ] )	/* room on stack? */
		{
			yyerror( "yacc stack overflow" );
			YYABORT;
		}
		*yy_ps = yy_state;
		*++yy_pv = yyval;

		/*
		** we have a new state - find out what to do
		*/
	yy_newstate:
		if ( ( yy_n = yypact[ yy_state ] ) <= YYFLAG )
			goto yydefault;		/* simple state */
#if YYDEBUG
		/*
		** if debugging, need to mark whether new token grabbed
		*/
		yytmp = yychar < 0;
#endif
		if ( ( yychar < 0 ) && ( ( yychar = yylex() ) < 0 ) )
			yychar = 0;		/* reached EOF */
#if YYDEBUG
		if ( yydebug && yytmp )
		{
			register int yy_i;

			printf( "Received token " );
			if ( yychar == 0 )
				printf( "end-of-file\n" );
			else if ( yychar < 0 )
				printf( "-none-\n" );
			else
			{
				for ( yy_i = 0; yytoks[yy_i].t_val >= 0;
					yy_i++ )
				{
					if ( yytoks[yy_i].t_val == yychar )
						break;
				}
				printf( "%s\n", yytoks[yy_i].t_name );
			}
		}
#endif /* YYDEBUG */
		if ( ( ( yy_n += yychar ) < 0 ) || ( yy_n >= YYLAST ) )
			goto yydefault;
		if ( yychk[ yy_n = yyact[ yy_n ] ] == yychar )	/*valid shift*/
		{
			yychar = -1;
			yyval = yylval;
			yy_state = yy_n;
			if ( yyerrflag > 0 )
				yyerrflag--;
			goto yy_stack;
		}

	yydefault:
		if ( ( yy_n = yydef[ yy_state ] ) == -2 )
		{
#if YYDEBUG
			yytmp = yychar < 0;
#endif
			if ( ( yychar < 0 ) && ( ( yychar = yylex() ) < 0 ) )
				yychar = 0;		/* reached EOF */
#if YYDEBUG
			if ( yydebug && yytmp )
			{
				register int yy_i;

				printf( "Received token " );
				if ( yychar == 0 )
					printf( "end-of-file\n" );
				else if ( yychar < 0 )
					printf( "-none-\n" );
				else
				{
					for ( yy_i = 0;
						yytoks[yy_i].t_val >= 0;
						yy_i++ )
					{
						if ( yytoks[yy_i].t_val
							== yychar )
						{
							break;
						}
					}
					printf( "%s\n", yytoks[yy_i].t_name );
				}
			}
#endif /* YYDEBUG */
			/*
			** look through exception table
			*/
			{
				register int *yyxi = yyexca;

				while ( ( *yyxi != -1 ) ||
					( yyxi[1] != yy_state ) )
				{
					yyxi += 2;
				}
				while ( ( *(yyxi += 2) >= 0 ) &&
					( *yyxi != yychar ) )
					;
				if ( ( yy_n = yyxi[1] ) < 0 )
					YYACCEPT;
			}
		}

		/*
		** check for syntax error
		*/
		if ( yy_n == 0 )	/* have an error */
		{
			/* no worry about speed here! */
			switch ( yyerrflag )
			{
			case 0:		/* new error */
				yyerror( "syntax error" );
				goto skip_init;
			yyerrlab:
				/*
				** get globals into registers.
				** we have a user generated syntax type error
				*/
				yy_pv = yypv;
				yy_ps = yyps;
				yy_state = yystate;
				yynerrs++;
			skip_init:
			case 1:
			case 2:		/* incompletely recovered error */
					/* try again... */
				yyerrflag = 3;
				/*
				** find state where "error" is a legal
				** shift action
				*/
				while ( yy_ps >= yys )
				{
					yy_n = yypact[ *yy_ps ] + YYERRCODE;
					if ( yy_n >= 0 && yy_n < YYLAST &&
						yychk[yyact[yy_n]] == YYERRCODE)					{
						/*
						** simulate shift of "error"
						*/
						yy_state = yyact[ yy_n ];
						goto yy_stack;
					}
					/*
					** current state has no shift on
					** "error", pop stack
					*/
#if YYDEBUG
#	define _POP_ "Error recovery pops state %d, uncovers state %d\n"
					if ( yydebug )
						printf( _POP_, *yy_ps,
							yy_ps[-1] );
#	undef _POP_
#endif
					yy_ps--;
					yy_pv--;
				}
				/*
				** there is no state on stack with "error" as
				** a valid shift.  give up.
				*/
				YYABORT;
			case 3:		/* no shift yet; eat a token */
#if YYDEBUG
				/*
				** if debugging, look up token in list of
				** pairs.  0 and negative shouldn't occur,
				** but since timing doesn't matter when
				** debugging, it doesn't hurt to leave the
				** tests here.
				*/
				if ( yydebug )
				{
					register int yy_i;

					printf( "Error recovery discards " );
					if ( yychar == 0 )
						printf( "token end-of-file\n" );
					else if ( yychar < 0 )
						printf( "token -none-\n" );
					else
					{
						for ( yy_i = 0;
							yytoks[yy_i].t_val >= 0;
							yy_i++ )
						{
							if ( yytoks[yy_i].t_val
								== yychar )
							{
								break;
							}
						}
						printf( "token %s\n",
							yytoks[yy_i].t_name );
					}
				}
#endif /* YYDEBUG */
				if ( yychar == 0 )	/* reached EOF. quit */
					YYABORT;
				yychar = -1;
				goto yy_newstate;
			}
		}/* end if ( yy_n == 0 ) */
		/*
		** reduction by production yy_n
		** put stack tops, etc. so things right after switch
		*/
#if YYDEBUG
		/*
		** if debugging, print the string that is the user's
		** specification of the reduction which is just about
		** to be done.
		*/
		if ( yydebug )
			printf( "Reduce by (%d) \"%s\"\n",
				yy_n, yyreds[ yy_n ] );
#endif
		yytmp = yy_n;			/* value to switch over */
		yypvt = yy_pv;			/* $vars top of value stack */
		/*
		** Look in goto table for next state
		** Sorry about using yy_state here as temporary
		** register variable, but why not, if it works...
		** If yyr2[ yy_n ] doesn't have the low order bit
		** set, then there is no action to be done for
		** this reduction.  So, no saving & unsaving of
		** registers done.  The only difference between the
		** code just after the if and the body of the if is
		** the goto yy_stack in the body.  This way the test
		** can be made before the choice of what to do is needed.
		*/
		{
			/* length of production doubled with extra bit */
			register int yy_len = yyr2[ yy_n ];

			if ( !( yy_len & 01 ) )
			{
				yy_len >>= 1;
				yyval = ( yy_pv -= yy_len )[1];	/* $$ = $1 */
				yy_state = yypgo[ yy_n = yyr1[ yy_n ] ] +
					*( yy_ps -= yy_len ) + 1;
				if ( yy_state >= YYLAST ||
					yychk[ yy_state =
					yyact[ yy_state ] ] != -yy_n )
				{
					yy_state = yyact[ yypgo[ yy_n ] ];
				}
				goto yy_stack;
			}
			yy_len >>= 1;
			yyval = ( yy_pv -= yy_len )[1];	/* $$ = $1 */
			yy_state = yypgo[ yy_n = yyr1[ yy_n ] ] +
				*( yy_ps -= yy_len ) + 1;
			if ( yy_state >= YYLAST ||
				yychk[ yy_state = yyact[ yy_state ] ] != -yy_n )
			{
				yy_state = yyact[ yypgo[ yy_n ] ];
			}
		}
					/* save until reenter driver code */
		yystate = yy_state;
		yyps = yy_ps;
		yypv = yy_pv;
	}
	/*
	** code supplied by user is placed in this switch
	*/

		switch(yytmp){

case 2:
# line 147 "ftpcmd.y"
 {
            fromname = 0;
            restart_point = 0;
        } /*NOTREACHED*/ break;
case 4:
# line 155 "ftpcmd.y"
 {
            user(yypvt[-1].String);
            if (log_commands) syslog(LOG_INFO, "USER %s", yypvt[-1].String);
            free(yypvt[-1].String);
        } /*NOTREACHED*/ break;
case 5:
# line 161 "ftpcmd.y"
 {
            if (log_commands)
                if (anonymous)
                    syslog(LOG_INFO, "PASS %s", yypvt[-1].String);
                else
                    syslog(LOG_INFO, "PASS password");

            pass(yypvt[-1].String);
            free(yypvt[-1].String);
        } /*NOTREACHED*/ break;
case 6:
# line 172 "ftpcmd.y"
 {
            if (log_commands) syslog(LOG_INFO, "PORT");
            usedefault = 0;
            if (pdata >= 0) {
                (void) close(pdata);
                pdata = -1;
            }
            reply(200, "PORT command successful.");
        } /*NOTREACHED*/ break;
case 7:
# line 182 "ftpcmd.y"
 {
            if (log_commands) syslog(LOG_INFO, "PASV");
            passive();
        } /*NOTREACHED*/ break;
case 8:
# line 187 "ftpcmd.y"
 {
            if (log_commands) syslog(LOG_INFO, "TYPE %s", typenames[cmd_type]);
            switch (cmd_type) {

            case TYPE_A:
                if (cmd_form == FORM_N) {
                    reply(200, "Type set to A.");
                    type = cmd_type;
                    form = cmd_form;
                } else
                    reply(504, "Form must be N.");
                break;

            case TYPE_E:
                reply(504, "Type E not implemented.");
                break;

            case TYPE_I:
                reply(200, "Type set to I.");
                type = cmd_type;
                break;

            case TYPE_L:
#if NBBY == 8
                if (cmd_bytesz == 8) {
                    reply(200,
                        "Type set to L (byte size 8).");
                    type = cmd_type;
                } else
                    reply(504, "Byte size must be 8.");
#else /* NBBY == 8 */
                UNIMPLEMENTED for NBBY != 8
#endif /* NBBY == 8 */
            }
        } /*NOTREACHED*/ break;
case 9:
# line 223 "ftpcmd.y"
 {
            if (log_commands) syslog(LOG_INFO, "STRU %s", strunames[yypvt[-1].Number]);
            switch (yypvt[-1].Number) {

            case STRU_F:
                reply(200, "STRU F ok.");
                break;

            default:
                reply(504, "Unimplemented STRU type.");
            }
        } /*NOTREACHED*/ break;
case 10:
# line 236 "ftpcmd.y"
 {
            if (log_commands) syslog(LOG_INFO, "MODE %s", modenames[yypvt[-1].Number]);
            switch (yypvt[-1].Number) {

            case MODE_S:
                reply(200, "MODE S ok.");
                break;

            default:
                reply(502, "Unimplemented MODE type.");
            }
        } /*NOTREACHED*/ break;
case 11:
# line 249 "ftpcmd.y"
 {
            if (log_commands) syslog(LOG_INFO, "ALLO %d", yypvt[-1].Number);
            reply(202, "ALLO command ignored.");
        } /*NOTREACHED*/ break;
case 12:
# line 254 "ftpcmd.y"
 {
            if (log_commands) syslog(LOG_INFO, "ALLO %d R %d", yypvt[-5].Number, yypvt[-1].Number);
            reply(202, "ALLO command ignored.");
        } /*NOTREACHED*/ break;
case 13:
# line 259 "ftpcmd.y"
 {
            if (log_commands) syslog(LOG_INFO, "RETR %s", yypvt[-1].String);
            if (yypvt[-3].Number && yypvt[-1].String != NULL)
                retrieve((char *) NULL, yypvt[-1].String);
            if (yypvt[-1].String != NULL)
                free(yypvt[-1].String);
        } /*NOTREACHED*/ break;
case 14:
# line 267 "ftpcmd.y"
 {
            if (log_commands) syslog(LOG_INFO, "STOR %s", yypvt[-1].String);
            if (yypvt[-3].Number && yypvt[-1].String != NULL)
                store(yypvt[-1].String, "w", 0);
            if (yypvt[-1].String != NULL)
                free(yypvt[-1].String);
        } /*NOTREACHED*/ break;
case 15:
# line 275 "ftpcmd.y"
 {
            if (log_commands) syslog(LOG_INFO, "APPE %s", yypvt[-1].String);
            if (yypvt[-3].Number && yypvt[-1].String != NULL)
                store(yypvt[-1].String, "a", 0);
            if (yypvt[-1].String != NULL)
                free(yypvt[-1].String);
        } /*NOTREACHED*/ break;
case 16:
# line 283 "ftpcmd.y"
 {
            if (log_commands) syslog(LOG_INFO, "NLST");
            if (yypvt[-1].Number)
                send_file_list(".");
        } /*NOTREACHED*/ break;
case 17:
# line 289 "ftpcmd.y"
 {
            if (log_commands) syslog(LOG_INFO, "NLST %s", yypvt[-1].String);
            if (yypvt[-3].Number && yypvt[-1].String) {
                send_file_list(yypvt[-1].String);
                free(yypvt[-1].String);
            }
        } /*NOTREACHED*/ break;
case 18:
# line 297 "ftpcmd.y"
 {
            if (log_commands) syslog(LOG_INFO, "LIST");
            if (yypvt[-1].Number)
        if (anonymous && dolreplies)
                retrieve(ls_long, "");
            else
                retrieve(ls_short, "");
        } /*NOTREACHED*/ break;
case 19:
# line 306 "ftpcmd.y"
 {
            if (log_commands) syslog(LOG_INFO, "LIST %s", yypvt[-1].String);
            if (yypvt[-3].Number && yypvt[-1].String != NULL)
        if (anonymous && dolreplies)
                retrieve(ls_long, yypvt[-1].String);
            else
                retrieve(ls_short, yypvt[-1].String);
            if (yypvt[-1].String != NULL)
                free(yypvt[-1].String);
        } /*NOTREACHED*/ break;
case 20:
# line 317 "ftpcmd.y"
 {
            if (log_commands) syslog(LOG_INFO, "STAT %s", yypvt[-1].String);
            if (yypvt[-3].Number && yypvt[-1].String != NULL)
                statfilecmd(yypvt[-1].String);
            if (yypvt[-1].String != NULL)
                free(yypvt[-1].String);
        } /*NOTREACHED*/ break;
case 21:
# line 325 "ftpcmd.y"
 {
            if (log_commands) syslog(LOG_INFO, "STAT");
            statcmd();
        } /*NOTREACHED*/ break;
case 22:
# line 330 "ftpcmd.y"
 {
            if (log_commands) syslog(LOG_INFO, "DELE %s", yypvt[-1].String);
            if (yypvt[-3].Number && yypvt[-1].String != NULL)
                delete(yypvt[-1].String);
            if (yypvt[-1].String != NULL)
                free(yypvt[-1].String);
        } /*NOTREACHED*/ break;
case 23:
# line 338 "ftpcmd.y"
 {
            if (log_commands) syslog(LOG_INFO, "RNTO %s", yypvt[-1].String);
            if (fromname) {
                renamecmd(fromname, yypvt[-1].String);
                free(fromname);
                fromname = (char *) NULL;
            } else {
                reply(503, "Bad sequence of commands.");
            }
            free(yypvt[-1].String);
        } /*NOTREACHED*/ break;
case 24:
# line 350 "ftpcmd.y"
 {
            if (log_commands) syslog(LOG_INFO, "ABOR");
            reply(225, "ABOR command successful.");
        } /*NOTREACHED*/ break;
case 25:
# line 355 "ftpcmd.y"
 {
            if (log_commands) syslog(LOG_INFO, "CWD");
            if (yypvt[-1].Number)
                cwd(pw->pw_dir);
        } /*NOTREACHED*/ break;
case 26:
# line 361 "ftpcmd.y"
 {
            if (log_commands) syslog(LOG_INFO, "CWD %s", yypvt[-1].String);
            if (yypvt[-3].Number && yypvt[-1].String != NULL)
                cwd(yypvt[-1].String);
            if (yypvt[-1].String != NULL)
                free(yypvt[-1].String);
        } /*NOTREACHED*/ break;
case 27:
# line 369 "ftpcmd.y"
 {
            if (log_commands) syslog(LOG_INFO, "HELP");
            help(cmdtab, (char *) NULL);
        } /*NOTREACHED*/ break;
case 28:
# line 374 "ftpcmd.y"
 {
            register char *cp = (char *)yypvt[-1].String;

            if (log_commands) syslog(LOG_INFO, "HELP %s", yypvt[-1].String);
            if (strncasecmp(cp, "SITE", 4) == 0) {
                cp = (char *)yypvt[-1].String + 4;
                if (*cp == ' ')
                    cp++;
                if (*cp)
                    help(sitetab, cp);
                else
                    help(sitetab, (char *) NULL);
            } else
                help(cmdtab, yypvt[-1].String);
        } /*NOTREACHED*/ break;
case 29:
# line 390 "ftpcmd.y"
 {
            if (log_commands) syslog(LOG_INFO, "NOOP");
            reply(200, "NOOP command successful.");
        } /*NOTREACHED*/ break;
case 30:
# line 395 "ftpcmd.y"
 {
            if (log_commands) syslog(LOG_INFO, "MKD %s", yypvt[-1].String);
            if (yypvt[-3].Number && yypvt[-1].String != NULL)
                makedir(yypvt[-1].String);
            if (yypvt[-1].String != NULL)
                free(yypvt[-1].String);
        } /*NOTREACHED*/ break;
case 31:
# line 403 "ftpcmd.y"
 {
            if (log_commands) syslog(LOG_INFO, "RMD %s", yypvt[-1].String);
            if (yypvt[-3].Number && yypvt[-1].String != NULL)
                removedir(yypvt[-1].String);
            if (yypvt[-1].String != NULL)
                free(yypvt[-1].String);
        } /*NOTREACHED*/ break;
case 32:
# line 411 "ftpcmd.y"
 {
            if (log_commands) syslog(LOG_INFO, "PWD");
            if (yypvt[-1].Number)
                pwd();
        } /*NOTREACHED*/ break;
case 33:
# line 417 "ftpcmd.y"
 {
            if (log_commands) syslog(LOG_INFO, "CDUP");
            if (yypvt[-1].Number)
                cwd("..");
        } /*NOTREACHED*/ break;
case 34:
# line 423 "ftpcmd.y"
 {
            if (log_commands) syslog(LOG_INFO, "SITE HELP");
            help(sitetab, (char *) NULL);
        } /*NOTREACHED*/ break;
case 35:
# line 428 "ftpcmd.y"
 {
            if (log_commands) syslog(LOG_INFO, "SITE HELP %s", yypvt[-1].String);
            help(sitetab, yypvt[-1].String);
        } /*NOTREACHED*/ break;
case 36:
# line 433 "ftpcmd.y"
 {
            mode_t oldmask;

            if (log_commands) syslog(LOG_INFO, "SITE UMASK");
            if (yypvt[-1].Number) {
                oldmask = umask(0);
                (void) umask(oldmask);
                reply(200, "Current UMASK is %03o", oldmask);
            }
        } /*NOTREACHED*/ break;
case 37:
# line 444 "ftpcmd.y"
 {
            mode_t oldmask;
            struct aclmember *entry = NULL;
            int ok = 1;

            if (log_commands) syslog(LOG_INFO, "SITE UMASK %d", yypvt[-1].Number);
            if (yypvt[-3].Number) {
                /* check for umask permission */
                while (getaclentry("umask", &entry) && ARG0 && ARG1 != NULL) {
                    if (type_match(ARG1)) 
                        if (*ARG0 == 'n')  ok = 0;
                }
                if (ok) {
                    if ((yypvt[-1].Number == -1) || (yypvt[-1].Number > 0777)) {
                        reply(501, "Bad UMASK value");
                    } else {
                        oldmask = umask((mode_t)yypvt[-1].Number);
                        reply(200, "UMASK set to %03o (was %03o)", yypvt[-1].Number, oldmask);
                    }
                } else 
                    reply(553, "Permission denied. (umask)");
            }
        } /*NOTREACHED*/ break;
case 38:
# line 468 "ftpcmd.y"
 {
            struct aclmember *entry = NULL;
            int ok = 1;

            if (log_commands) syslog(LOG_INFO, "SITE CHMOD %d %s", yypvt[-3].Number, yypvt[-1].String);
            if (yypvt[-5].Number && yypvt[-3].Number && yypvt[-1].String) {
                /* check for chmod permission */
                while (getaclentry("chmod", &entry) && ARG0 && ARG1 != NULL) {
                    if (type_match(ARG1)) 
                        if (*ARG0 == 'n')  ok = 0;
                }
                if (ok) {
                    if (yypvt[-3].Number > 0777)
                        reply(501, 
                            "CHMOD: Mode value must be between 0 and 0777");
                    else if (chmod(yypvt[-1].String, (mode_t) yypvt[-3].Number) < 0)
                        perror_reply(550, yypvt[-1].String);
                    else
                        reply(200, "CHMOD command successful.");
                    free(yypvt[-1].String);
                } else
                    reply(553, "Permission denied. (chmod)");
            }
        } /*NOTREACHED*/ break;
case 39:
# line 493 "ftpcmd.y"
 {
            if (log_commands) syslog(LOG_INFO, "SITE IDLE");
            reply(200,
                "Current IDLE time limit is %d seconds; max %d",
                timeout, maxtimeout);
        } /*NOTREACHED*/ break;
case 40:
# line 500 "ftpcmd.y"
 {
            if (log_commands) syslog(LOG_INFO, "SITE IDLE %d", yypvt[-1].Number);
            if (yypvt[-1].Number < 30 || yypvt[-1].Number > maxtimeout) {
                reply(501,
            "Maximum IDLE time must be between 30 and %d seconds",
                    maxtimeout);
            } else {
                timeout = yypvt[-1].Number;
                (void) alarm((unsigned) timeout);
                reply(200, "Maximum IDLE time set to %d seconds", timeout);
            }
        } /*NOTREACHED*/ break;
case 41:
# line 513 "ftpcmd.y"
 {
#ifndef NO_PRIVATE
            if (log_commands) syslog(LOG_INFO, "SITE GROUP %s", yypvt[-1].String);
            if (yypvt[-3].Number && yypvt[-1].String) priv_group(yypvt[-1].String);
            free(yypvt[-1].String);
#endif /* !NO_PRIVATE */
        } /*NOTREACHED*/ break;
case 42:
# line 521 "ftpcmd.y"
 {
#ifndef NO_PRIVATE
            if (log_commands) syslog(LOG_INFO, "SITE GPASS password");
            if (yypvt[-3].Number && yypvt[-1].String) priv_gpass(yypvt[-1].String);
            free(yypvt[-1].String);
#endif /* !NO_PRIVATE */
        } /*NOTREACHED*/ break;
case 43:
# line 529 "ftpcmd.y"
 {
            if (yypvt[-3].Number && yypvt[-1].String) newer(yypvt[-1].String, ".", 0);
            free(yypvt[-1].String);
        } /*NOTREACHED*/ break;
case 44:
# line 534 "ftpcmd.y"
 {
            if (yypvt[-5].Number && yypvt[-3].String && yypvt[-1].String) newer(yypvt[-3].String, yypvt[-1].String, 0);
            free(yypvt[-3].String);
            free(yypvt[-1].String);
        } /*NOTREACHED*/ break;
case 45:
# line 540 "ftpcmd.y"
 {
            if (yypvt[-5].Number && yypvt[-3].String && yypvt[-1].String) newer(yypvt[-3].String, yypvt[-1].String, 1);
            free(yypvt[-3].String);
            free(yypvt[-1].String);
        } /*NOTREACHED*/ break;
case 46:
# line 546 "ftpcmd.y"
 {
            /* this is just for backward compatibility since we
             * thought of INDEX before we thought of EXEC
             */
            if (yypvt[-3].Number != 0 && yypvt[-1].String != NULL) {
                char buf[MAXPATHLEN];
                if (strlen(yypvt[-1].String) + 7 <= sizeof(buf)) {
                    sprintf(buf, "index %s", (char*)yypvt[-1].String);
                    (void) site_exec(buf);
                }
            }
        } /*NOTREACHED*/ break;
case 47:
# line 559 "ftpcmd.y"
 {
            if (yypvt[-3].Number != 0 && yypvt[-1].String != NULL) {
                (void) site_exec((char*)yypvt[-1].String);
            }
        } /*NOTREACHED*/ break;
case 48:
# line 565 "ftpcmd.y"
 {
            if (log_commands) syslog(LOG_INFO, "STOU %s", yypvt[-1].String);
            if (yypvt[-3].Number && yypvt[-1].String) {
                store(yypvt[-1].String, "w", 1);
                free(yypvt[-1].String);
            }
        } /*NOTREACHED*/ break;
case 49:
# line 573 "ftpcmd.y"
 {
            if (log_commands) syslog(LOG_INFO, "SYST");
#ifdef unix
#ifdef BSD
            reply(215, "UNIX Type: L%d Version: BSD-%d",
                NBBY, BSD);
#else  /* BSD */
            reply(215, "UNIX Type: L%d", NBBY);
#endif /* BSD */
#else  /* unix */
            reply(215, "UNKNOWN Type: L%d", NBBY);
#endif /* unix */
        } /*NOTREACHED*/ break;
case 50:
# line 595 "ftpcmd.y"
 {
            if (log_commands) syslog(LOG_INFO, "SIZE %s", yypvt[-1].String);
            if (yypvt[-3].Number && yypvt[-1].String) {
                sizecmd(yypvt[-1].String);
                free(yypvt[-1].String);
            }
        } /*NOTREACHED*/ break;
case 51:
# line 613 "ftpcmd.y"
 {
            if (log_commands) syslog(LOG_INFO, "MDTM %s", yypvt[-1].String);
            if (yypvt[-3].Number && yypvt[-1].String) {
                struct stat stbuf;

                if (stat(yypvt[-1].String, &stbuf) < 0)
                    perror_reply(550, yypvt[-1].String);
                else if ((stbuf.st_mode&S_IFMT) != S_IFREG) {
                    reply(550, "%s: not a plain file.",
                        yypvt[-1].String);
                } else {
                    register struct tm *t;
                    struct tm *gmtime();
                    t = gmtime(&stbuf.st_mtime);
                    reply(213,
                        "19%02d%02d%02d%02d%02d%02d",
                        t->tm_year, t->tm_mon+1, t->tm_mday,
                        t->tm_hour, t->tm_min, t->tm_sec);
                }
                free(yypvt[-1].String);
            }
        } /*NOTREACHED*/ break;
case 52:
# line 636 "ftpcmd.y"
 {
            if (log_commands) syslog(LOG_INFO, "QUIT");
            reply(221, "Goodbye.");
            dologout(0);
        } /*NOTREACHED*/ break;
case 53:
# line 642 "ftpcmd.y"
 {
            yyerrok;
        } /*NOTREACHED*/ break;
case 54:
# line 647 "ftpcmd.y"
 {
            char *renamefrom();

            if (log_commands) syslog(LOG_INFO, "RNFR %s", yypvt[-1].String);
            restart_point = (off_t) 0;
            if (yypvt[-3].Number && yypvt[-1].String) {
                fromname = renamefrom(yypvt[-1].String);
                if (fromname == 0 && yypvt[-1].String) {
                    free(yypvt[-1].String);
                }
            }
        } /*NOTREACHED*/ break;
case 55:
# line 660 "ftpcmd.y"
 {
            long atol();

            fromname = 0;
            restart_point = yypvt[-1].Number;
            if (log_commands) syslog(LOG_INFO, "REST %d", restart_point);
            reply(350, "Restarting at %ld. %s", restart_point,
                "Send STORE or RETRIEVE to initiate transfer.");
        } /*NOTREACHED*/ break;
case 56:
# line 671 "ftpcmd.y"
 {
           if (log_commands) syslog(LOG_INFO, "SITE ALIAS");
           alias ((char *)NULL);
        } /*NOTREACHED*/ break;
case 57:
# line 676 "ftpcmd.y"
 {
           if (log_commands) syslog(LOG_INFO, "SITE ALIAS %s", yypvt[-1].String);
           alias (yypvt[-1].String);
        } /*NOTREACHED*/ break;
case 58:
# line 681 "ftpcmd.y"
 {
           if (log_commands) syslog(LOG_INFO, "SITE GROUPS");
           print_groups () ;
        } /*NOTREACHED*/ break;
case 59:
# line 686 "ftpcmd.y"
 {
           if (log_commands) syslog(LOG_INFO, "SITE CDPATH");
           cdpath () ;
        } /*NOTREACHED*/ break;
case 61:
# line 696 "ftpcmd.y"
 {
            yyval.String = malloc(1);
            yyval.String[0] = '\0';
        } /*NOTREACHED*/ break;
case 64:
# line 708 "ftpcmd.y"
 {
            register char *a, *p;

            a = (char *)&data_dest.sin_addr;
            a[0] = yypvt[-10].Number; a[1] = yypvt[-8].Number; a[2] = yypvt[-6].Number; a[3] = yypvt[-4].Number;
            p = (char *)&data_dest.sin_port;
            p[0] = yypvt[-2].Number; p[1] = yypvt[-0].Number;
            data_dest.sin_family = AF_INET;
        } /*NOTREACHED*/ break;
case 65:
# line 720 "ftpcmd.y"
 {
        yyval.Number = FORM_N;
    } /*NOTREACHED*/ break;
case 66:
# line 724 "ftpcmd.y"
 {
        yyval.Number = FORM_T;
    } /*NOTREACHED*/ break;
case 67:
# line 728 "ftpcmd.y"
 {
        yyval.Number = FORM_C;
    } /*NOTREACHED*/ break;
case 68:
# line 734 "ftpcmd.y"
 {
        cmd_type = TYPE_A;
        cmd_form = FORM_N;
    } /*NOTREACHED*/ break;
case 69:
# line 739 "ftpcmd.y"
 {
        cmd_type = TYPE_A;
        cmd_form = yypvt[-0].Number;
    } /*NOTREACHED*/ break;
case 70:
# line 744 "ftpcmd.y"
 {
        cmd_type = TYPE_E;
        cmd_form = FORM_N;
    } /*NOTREACHED*/ break;
case 71:
# line 749 "ftpcmd.y"
 {
        cmd_type = TYPE_E;
        cmd_form = yypvt[-0].Number;
    } /*NOTREACHED*/ break;
case 72:
# line 754 "ftpcmd.y"
 {
        cmd_type = TYPE_I;
    } /*NOTREACHED*/ break;
case 73:
# line 758 "ftpcmd.y"
 {
        cmd_type = TYPE_L;
        cmd_bytesz = NBBY;
    } /*NOTREACHED*/ break;
case 74:
# line 763 "ftpcmd.y"
 {
        cmd_type = TYPE_L;
        cmd_bytesz = yypvt[-0].Number;
    } /*NOTREACHED*/ break;
case 75:
# line 769 "ftpcmd.y"
 {
        cmd_type = TYPE_L;
        cmd_bytesz = yypvt[-0].Number;
    } /*NOTREACHED*/ break;
case 76:
# line 776 "ftpcmd.y"
 {
        yyval.Number = STRU_F;
    } /*NOTREACHED*/ break;
case 77:
# line 780 "ftpcmd.y"
 {
        yyval.Number = STRU_R;
    } /*NOTREACHED*/ break;
case 78:
# line 784 "ftpcmd.y"
 {
        yyval.Number = STRU_P;
    } /*NOTREACHED*/ break;
case 79:
# line 790 "ftpcmd.y"
 {
        yyval.Number = MODE_S;
    } /*NOTREACHED*/ break;
case 80:
# line 794 "ftpcmd.y"
 {
        yyval.Number = MODE_B;
    } /*NOTREACHED*/ break;
case 81:
# line 798 "ftpcmd.y"
 {
        yyval.Number = MODE_C;
    } /*NOTREACHED*/ break;
case 82:
# line 804 "ftpcmd.y"
 {
        /*
         * 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 && yypvt[-0].String && strncmp(yypvt[-0].String, "~", 1) == 0) {
            yyval.String = *ftpglob(yypvt[-0].String);
            if (globerr) {
                reply(550, globerr);
                yyval.String = NULL;
            }
            free(yypvt[-0].String);
        } else
            yyval.String = yypvt[-0].String;
    } /*NOTREACHED*/ break;
case 84:
# line 826 "ftpcmd.y"
 {
        register 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 = yypvt[-0].Number;
        multby = 1;
        ret = 0;
        while (dec) {
            digit = dec%10;
            if (digit > 7) {
                ret = -1;
                break;
            }
            ret += digit * multby;
            multby *= 8;
            dec /= 10;
        }
        yyval.Number = ret;
    } /*NOTREACHED*/ break;
case 85:
# line 851 "ftpcmd.y"
 {
        if (logged_in)
            yyval.Number = 1;
        else {
            if (log_commands) syslog(LOG_INFO, "cmd failure - not logged in");
            reply(530, "Please login with USER and PASS.");
            yyval.Number = 0;
        }
    } /*NOTREACHED*/ break;
}


	goto yystack;		/* reset registers in driver code */
}
