summaryrefslogtreecommitdiffstats
path: root/usr.bin/yacc/test
diff options
context:
space:
mode:
authorrgrimes <rgrimes@FreeBSD.org>1994-05-27 12:33:43 +0000
committerrgrimes <rgrimes@FreeBSD.org>1994-05-27 12:33:43 +0000
commitf9ab90d9d6d02989a075d0f0074496d5b1045e4b (patch)
treeadd7e996bac5289cdc55e6935750c352505560a9 /usr.bin/yacc/test
parentbe22b15ae2ff8d7fe06b6e14fddf0c5b444a95da (diff)
downloadFreeBSD-src-f9ab90d9d6d02989a075d0f0074496d5b1045e4b.zip
FreeBSD-src-f9ab90d9d6d02989a075d0f0074496d5b1045e4b.tar.gz
BSD 4.4 Lite Usr.bin Sources
Diffstat (limited to 'usr.bin/yacc/test')
-rw-r--r--usr.bin/yacc/test/error.output27
-rw-r--r--usr.bin/yacc/test/error.tab.c275
-rw-r--r--usr.bin/yacc/test/error.tab.h0
-rw-r--r--usr.bin/yacc/test/error.y6
-rw-r--r--usr.bin/yacc/test/ftp.output1625
-rw-r--r--usr.bin/yacc/test/ftp.tab.c1743
-rw-r--r--usr.bin/yacc/test/ftp.tab.h63
-rw-r--r--usr.bin/yacc/test/ftp.y1180
8 files changed, 4919 insertions, 0 deletions
diff --git a/usr.bin/yacc/test/error.output b/usr.bin/yacc/test/error.output
new file mode 100644
index 0000000..0c4db62
--- /dev/null
+++ b/usr.bin/yacc/test/error.output
@@ -0,0 +1,27 @@
+ 0 $accept : S $end
+
+ 1 S : error
+
+state 0
+ $accept : . S $end (0)
+
+ error shift 1
+ . error
+
+ S goto 2
+
+
+state 1
+ S : error . (1)
+
+ . reduce 1
+
+
+state 2
+ $accept : S . $end (0)
+
+ $end accept
+
+
+2 terminals, 2 nonterminals
+2 grammar rules, 3 states
diff --git a/usr.bin/yacc/test/error.tab.c b/usr.bin/yacc/test/error.tab.c
new file mode 100644
index 0000000..ffc6e37
--- /dev/null
+++ b/usr.bin/yacc/test/error.tab.c
@@ -0,0 +1,275 @@
+#ifndef lint
+static char yysccsid[] = "@(#)yaccpar 1.9 (Berkeley) 02/21/93";
+#endif
+#define YYBYACC 1
+#define YYMAJOR 1
+#define YYMINOR 9
+#define yyclearin (yychar=(-1))
+#define yyerrok (yyerrflag=0)
+#define YYRECOVERING (yyerrflag!=0)
+#define YYPREFIX "yy"
+#define YYERRCODE 256
+short yylhs[] = { -1,
+ 0,
+};
+short yylen[] = { 2,
+ 1,
+};
+short yydefred[] = { 0,
+ 1, 0,
+};
+short yydgoto[] = { 2,
+};
+short yysindex[] = { -256,
+ 0, 0,
+};
+short yyrindex[] = { 0,
+ 0, 0,
+};
+short yygindex[] = { 0,
+};
+#define YYTABLESIZE 0
+short yytable[] = { 1,
+};
+short yycheck[] = { 256,
+};
+#define YYFINAL 2
+#ifndef YYDEBUG
+#define YYDEBUG 0
+#endif
+#define YYMAXTOKEN 0
+#if YYDEBUG
+char *yyname[] = {
+"end-of-file",
+};
+char *yyrule[] = {
+"$accept : S",
+"S : error",
+};
+#endif
+#ifndef YYSTYPE
+typedef int YYSTYPE;
+#endif
+#ifdef YYSTACKSIZE
+#undef YYMAXDEPTH
+#define YYMAXDEPTH YYSTACKSIZE
+#else
+#ifdef YYMAXDEPTH
+#define YYSTACKSIZE YYMAXDEPTH
+#else
+#define YYSTACKSIZE 500
+#define YYMAXDEPTH 500
+#endif
+#endif
+int yydebug;
+int yynerrs;
+int yyerrflag;
+int yychar;
+short *yyssp;
+YYSTYPE *yyvsp;
+YYSTYPE yyval;
+YYSTYPE yylval;
+short yyss[YYSTACKSIZE];
+YYSTYPE yyvs[YYSTACKSIZE];
+#define yystacksize YYSTACKSIZE
+#line 4 "error.y"
+main(){printf("yyparse() = %d\n",yyparse());}
+yylex(){return-1;}
+yyerror(s)char*s;{printf("%s\n",s);}
+#line 80 "error.tab.c"
+#define YYABORT goto yyabort
+#define YYREJECT goto yyabort
+#define YYACCEPT goto yyaccept
+#define YYERROR goto yyerrlab
+int
+yyparse()
+{
+ register int yym, yyn, yystate;
+#if YYDEBUG
+ register char *yys;
+ extern char *getenv();
+
+ if (yys = getenv("YYDEBUG"))
+ {
+ yyn = *yys;
+ if (yyn >= '0' && yyn <= '9')
+ yydebug = yyn - '0';
+ }
+#endif
+
+ yynerrs = 0;
+ yyerrflag = 0;
+ yychar = (-1);
+
+ yyssp = yyss;
+ yyvsp = yyvs;
+ *yyssp = yystate = 0;
+
+yyloop:
+ if (yyn = yydefred[yystate]) goto yyreduce;
+ if (yychar < 0)
+ {
+ if ((yychar = yylex()) < 0) yychar = 0;
+#if YYDEBUG
+ if (yydebug)
+ {
+ yys = 0;
+ if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
+ if (!yys) yys = "illegal-symbol";
+ printf("%sdebug: state %d, reading %d (%s)\n",
+ YYPREFIX, yystate, yychar, yys);
+ }
+#endif
+ }
+ if ((yyn = yysindex[yystate]) && (yyn += yychar) >= 0 &&
+ yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
+ {
+#if YYDEBUG
+ if (yydebug)
+ printf("%sdebug: state %d, shifting to state %d\n",
+ YYPREFIX, yystate, yytable[yyn]);
+#endif
+ if (yyssp >= yyss + yystacksize - 1)
+ {
+ goto yyoverflow;
+ }
+ *++yyssp = yystate = yytable[yyn];
+ *++yyvsp = yylval;
+ yychar = (-1);
+ if (yyerrflag > 0) --yyerrflag;
+ goto yyloop;
+ }
+ if ((yyn = yyrindex[yystate]) && (yyn += yychar) >= 0 &&
+ yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
+ {
+ yyn = yytable[yyn];
+ goto yyreduce;
+ }
+ if (yyerrflag) goto yyinrecovery;
+#ifdef lint
+ goto yynewerror;
+#endif
+yynewerror:
+ yyerror("syntax error");
+#ifdef lint
+ goto yyerrlab;
+#endif
+yyerrlab:
+ ++yynerrs;
+yyinrecovery:
+ if (yyerrflag < 3)
+ {
+ yyerrflag = 3;
+ for (;;)
+ {
+ if ((yyn = yysindex[*yyssp]) && (yyn += YYERRCODE) >= 0 &&
+ yyn <= YYTABLESIZE && yycheck[yyn] == YYERRCODE)
+ {
+#if YYDEBUG
+ if (yydebug)
+ printf("%sdebug: state %d, error recovery shifting\
+ to state %d\n", YYPREFIX, *yyssp, yytable[yyn]);
+#endif
+ if (yyssp >= yyss + yystacksize - 1)
+ {
+ goto yyoverflow;
+ }
+ *++yyssp = yystate = yytable[yyn];
+ *++yyvsp = yylval;
+ goto yyloop;
+ }
+ else
+ {
+#if YYDEBUG
+ if (yydebug)
+ printf("%sdebug: error recovery discarding state %d\n",
+ YYPREFIX, *yyssp);
+#endif
+ if (yyssp <= yyss) goto yyabort;
+ --yyssp;
+ --yyvsp;
+ }
+ }
+ }
+ else
+ {
+ if (yychar == 0) goto yyabort;
+#if YYDEBUG
+ if (yydebug)
+ {
+ yys = 0;
+ if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
+ if (!yys) yys = "illegal-symbol";
+ printf("%sdebug: state %d, error recovery discards token %d (%s)\n",
+ YYPREFIX, yystate, yychar, yys);
+ }
+#endif
+ yychar = (-1);
+ goto yyloop;
+ }
+yyreduce:
+#if YYDEBUG
+ if (yydebug)
+ printf("%sdebug: state %d, reducing by rule %d (%s)\n",
+ YYPREFIX, yystate, yyn, yyrule[yyn]);
+#endif
+ yym = yylen[yyn];
+ yyval = yyvsp[1-yym];
+ switch (yyn)
+ {
+ }
+ yyssp -= yym;
+ yystate = *yyssp;
+ yyvsp -= yym;
+ yym = yylhs[yyn];
+ if (yystate == 0 && yym == 0)
+ {
+#if YYDEBUG
+ if (yydebug)
+ printf("%sdebug: after reduction, shifting from state 0 to\
+ state %d\n", YYPREFIX, YYFINAL);
+#endif
+ yystate = YYFINAL;
+ *++yyssp = YYFINAL;
+ *++yyvsp = yyval;
+ if (yychar < 0)
+ {
+ if ((yychar = yylex()) < 0) yychar = 0;
+#if YYDEBUG
+ if (yydebug)
+ {
+ yys = 0;
+ if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
+ if (!yys) yys = "illegal-symbol";
+ printf("%sdebug: state %d, reading %d (%s)\n",
+ YYPREFIX, YYFINAL, yychar, yys);
+ }
+#endif
+ }
+ if (yychar == 0) goto yyaccept;
+ goto yyloop;
+ }
+ if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 &&
+ yyn <= YYTABLESIZE && yycheck[yyn] == yystate)
+ yystate = yytable[yyn];
+ else
+ yystate = yydgoto[yym];
+#if YYDEBUG
+ if (yydebug)
+ printf("%sdebug: after reduction, shifting from state %d \
+to state %d\n", YYPREFIX, *yyssp, yystate);
+#endif
+ if (yyssp >= yyss + yystacksize - 1)
+ {
+ goto yyoverflow;
+ }
+ *++yyssp = yystate;
+ *++yyvsp = yyval;
+ goto yyloop;
+yyoverflow:
+ yyerror("yacc stack overflow");
+yyabort:
+ return (1);
+yyaccept:
+ return (0);
+}
diff --git a/usr.bin/yacc/test/error.tab.h b/usr.bin/yacc/test/error.tab.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/usr.bin/yacc/test/error.tab.h
diff --git a/usr.bin/yacc/test/error.y b/usr.bin/yacc/test/error.y
new file mode 100644
index 0000000..41148ea
--- /dev/null
+++ b/usr.bin/yacc/test/error.y
@@ -0,0 +1,6 @@
+%%
+S: error
+%%
+main(){printf("yyparse() = %d\n",yyparse());}
+yylex(){return-1;}
+yyerror(s)char*s;{printf("%s\n",s);}
diff --git a/usr.bin/yacc/test/ftp.output b/usr.bin/yacc/test/ftp.output
new file mode 100644
index 0000000..f1ab4b2
--- /dev/null
+++ b/usr.bin/yacc/test/ftp.output
@@ -0,0 +1,1625 @@
+ 0 $accept : cmd_list $end
+
+ 1 cmd_list :
+ 2 | cmd_list cmd
+ 3 | cmd_list rcmd
+
+ 4 cmd : USER SP username CRLF
+ 5 | PASS SP password CRLF
+ 6 | PORT SP host_port CRLF
+ 7 | PASV CRLF
+ 8 | TYPE SP type_code CRLF
+ 9 | STRU SP struct_code CRLF
+ 10 | MODE SP mode_code CRLF
+ 11 | ALLO SP NUMBER CRLF
+ 12 | ALLO SP NUMBER SP R SP NUMBER CRLF
+ 13 | RETR check_login SP pathname CRLF
+ 14 | STOR check_login SP pathname CRLF
+ 15 | APPE check_login SP pathname CRLF
+ 16 | NLST check_login CRLF
+ 17 | NLST check_login SP STRING CRLF
+ 18 | LIST check_login CRLF
+ 19 | LIST check_login SP pathname CRLF
+ 20 | STAT check_login SP pathname CRLF
+ 21 | STAT CRLF
+ 22 | DELE check_login SP pathname CRLF
+ 23 | RNTO SP pathname CRLF
+ 24 | ABOR CRLF
+ 25 | CWD check_login CRLF
+ 26 | CWD check_login SP pathname CRLF
+ 27 | HELP CRLF
+ 28 | HELP SP STRING CRLF
+ 29 | NOOP CRLF
+ 30 | MKD check_login SP pathname CRLF
+ 31 | RMD check_login SP pathname CRLF
+ 32 | PWD check_login CRLF
+ 33 | CDUP check_login CRLF
+ 34 | SITE SP HELP CRLF
+ 35 | SITE SP HELP SP STRING CRLF
+ 36 | SITE SP UMASK check_login CRLF
+ 37 | SITE SP UMASK check_login SP octal_number CRLF
+ 38 | SITE SP CHMOD check_login SP octal_number SP pathname CRLF
+ 39 | SITE SP IDLE CRLF
+ 40 | SITE SP IDLE SP NUMBER CRLF
+ 41 | STOU check_login SP pathname CRLF
+ 42 | SYST CRLF
+ 43 | SIZE check_login SP pathname CRLF
+ 44 | MDTM check_login SP pathname CRLF
+ 45 | QUIT CRLF
+ 46 | error CRLF
+
+ 47 rcmd : RNFR check_login SP pathname CRLF
+
+ 48 username : STRING
+
+ 49 password :
+ 50 | STRING
+
+ 51 byte_size : NUMBER
+
+ 52 host_port : NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER
+
+ 53 form_code : N
+ 54 | T
+ 55 | C
+
+ 56 type_code : A
+ 57 | A SP form_code
+ 58 | E
+ 59 | E SP form_code
+ 60 | I
+ 61 | L
+ 62 | L SP byte_size
+ 63 | L byte_size
+
+ 64 struct_code : F
+ 65 | R
+ 66 | P
+
+ 67 mode_code : S
+ 68 | B
+ 69 | C
+
+ 70 pathname : pathstring
+
+ 71 pathstring : STRING
+
+ 72 octal_number : NUMBER
+
+ 73 check_login :
+
+state 0
+ $accept : . cmd_list $end (0)
+ cmd_list : . (1)
+
+ . reduce 1
+
+ cmd_list goto 1
+
+
+state 1
+ $accept : cmd_list . $end (0)
+ cmd_list : cmd_list . cmd (2)
+ cmd_list : cmd_list . rcmd (3)
+
+ $end accept
+ error shift 2
+ USER shift 3
+ PASS shift 4
+ QUIT shift 5
+ PORT shift 6
+ PASV shift 7
+ TYPE shift 8
+ STRU shift 9
+ MODE shift 10
+ RETR shift 11
+ STOR shift 12
+ APPE shift 13
+ ALLO shift 14
+ RNFR shift 15
+ RNTO shift 16
+ ABOR shift 17
+ DELE shift 18
+ CWD shift 19
+ LIST shift 20
+ NLST shift 21
+ SITE shift 22
+ STAT shift 23
+ HELP shift 24
+ NOOP shift 25
+ MKD shift 26
+ RMD shift 27
+ PWD shift 28
+ CDUP shift 29
+ STOU shift 30
+ SYST shift 31
+ SIZE shift 32
+ MDTM shift 33
+ . error
+
+ cmd goto 34
+ rcmd goto 35
+
+
+state 2
+ cmd : error . CRLF (46)
+
+ CRLF shift 36
+ . error
+
+
+state 3
+ cmd : USER . SP username CRLF (4)
+
+ SP shift 37
+ . error
+
+
+state 4
+ cmd : PASS . SP password CRLF (5)
+
+ SP shift 38
+ . error
+
+
+state 5
+ cmd : QUIT . CRLF (45)
+
+ CRLF shift 39
+ . error
+
+
+state 6
+ cmd : PORT . SP host_port CRLF (6)
+
+ SP shift 40
+ . error
+
+
+state 7
+ cmd : PASV . CRLF (7)
+
+ CRLF shift 41
+ . error
+
+
+state 8
+ cmd : TYPE . SP type_code CRLF (8)
+
+ SP shift 42
+ . error
+
+
+state 9
+ cmd : STRU . SP struct_code CRLF (9)
+
+ SP shift 43
+ . error
+
+
+state 10
+ cmd : MODE . SP mode_code CRLF (10)
+
+ SP shift 44
+ . error
+
+
+state 11
+ cmd : RETR . check_login SP pathname CRLF (13)
+ check_login : . (73)
+
+ . reduce 73
+
+ check_login goto 45
+
+
+state 12
+ cmd : STOR . check_login SP pathname CRLF (14)
+ check_login : . (73)
+
+ . reduce 73
+
+ check_login goto 46
+
+
+state 13
+ cmd : APPE . check_login SP pathname CRLF (15)
+ check_login : . (73)
+
+ . reduce 73
+
+ check_login goto 47
+
+
+state 14
+ cmd : ALLO . SP NUMBER CRLF (11)
+ cmd : ALLO . SP NUMBER SP R SP NUMBER CRLF (12)
+
+ SP shift 48
+ . error
+
+
+state 15
+ rcmd : RNFR . check_login SP pathname CRLF (47)
+ check_login : . (73)
+
+ . reduce 73
+
+ check_login goto 49
+
+
+state 16
+ cmd : RNTO . SP pathname CRLF (23)
+
+ SP shift 50
+ . error
+
+
+state 17
+ cmd : ABOR . CRLF (24)
+
+ CRLF shift 51
+ . error
+
+
+state 18
+ cmd : DELE . check_login SP pathname CRLF (22)
+ check_login : . (73)
+
+ . reduce 73
+
+ check_login goto 52
+
+
+state 19
+ cmd : CWD . check_login CRLF (25)
+ cmd : CWD . check_login SP pathname CRLF (26)
+ check_login : . (73)
+
+ . reduce 73
+
+ check_login goto 53
+
+
+state 20
+ cmd : LIST . check_login CRLF (18)
+ cmd : LIST . check_login SP pathname CRLF (19)
+ check_login : . (73)
+
+ . reduce 73
+
+ check_login goto 54
+
+
+state 21
+ cmd : NLST . check_login CRLF (16)
+ cmd : NLST . check_login SP STRING CRLF (17)
+ check_login : . (73)
+
+ . reduce 73
+
+ check_login goto 55
+
+
+state 22
+ cmd : SITE . SP HELP CRLF (34)
+ cmd : SITE . SP HELP SP STRING CRLF (35)
+ cmd : SITE . SP UMASK check_login CRLF (36)
+ cmd : SITE . SP UMASK check_login SP octal_number CRLF (37)
+ cmd : SITE . SP CHMOD check_login SP octal_number SP pathname CRLF (38)
+ cmd : SITE . SP IDLE CRLF (39)
+ cmd : SITE . SP IDLE SP NUMBER CRLF (40)
+
+ SP shift 56
+ . error
+
+
+state 23
+ cmd : STAT . check_login SP pathname CRLF (20)
+ cmd : STAT . CRLF (21)
+ check_login : . (73)
+
+ CRLF shift 57
+ SP reduce 73
+
+ check_login goto 58
+
+
+state 24
+ cmd : HELP . CRLF (27)
+ cmd : HELP . SP STRING CRLF (28)
+
+ SP shift 59
+ CRLF shift 60
+ . error
+
+
+state 25
+ cmd : NOOP . CRLF (29)
+
+ CRLF shift 61
+ . error
+
+
+state 26
+ cmd : MKD . check_login SP pathname CRLF (30)
+ check_login : . (73)
+
+ . reduce 73
+
+ check_login goto 62
+
+
+state 27
+ cmd : RMD . check_login SP pathname CRLF (31)
+ check_login : . (73)
+
+ . reduce 73
+
+ check_login goto 63
+
+
+state 28
+ cmd : PWD . check_login CRLF (32)
+ check_login : . (73)
+
+ . reduce 73
+
+ check_login goto 64
+
+
+state 29
+ cmd : CDUP . check_login CRLF (33)
+ check_login : . (73)
+
+ . reduce 73
+
+ check_login goto 65
+
+
+state 30
+ cmd : STOU . check_login SP pathname CRLF (41)
+ check_login : . (73)
+
+ . reduce 73
+
+ check_login goto 66
+
+
+state 31
+ cmd : SYST . CRLF (42)
+
+ CRLF shift 67
+ . error
+
+
+state 32
+ cmd : SIZE . check_login SP pathname CRLF (43)
+ check_login : . (73)
+
+ . reduce 73
+
+ check_login goto 68
+
+
+state 33
+ cmd : MDTM . check_login SP pathname CRLF (44)
+ check_login : . (73)
+
+ . reduce 73
+
+ check_login goto 69
+
+
+state 34
+ cmd_list : cmd_list cmd . (2)
+
+ . reduce 2
+
+
+state 35
+ cmd_list : cmd_list rcmd . (3)
+
+ . reduce 3
+
+
+state 36
+ cmd : error CRLF . (46)
+
+ . reduce 46
+
+
+state 37
+ cmd : USER SP . username CRLF (4)
+
+ STRING shift 70
+ . error
+
+ username goto 71
+
+
+state 38
+ cmd : PASS SP . password CRLF (5)
+ password : . (49)
+
+ STRING shift 72
+ CRLF reduce 49
+
+ password goto 73
+
+
+state 39
+ cmd : QUIT CRLF . (45)
+
+ . reduce 45
+
+
+state 40
+ cmd : PORT SP . host_port CRLF (6)
+
+ NUMBER shift 74
+ . error
+
+ host_port goto 75
+
+
+state 41
+ cmd : PASV CRLF . (7)
+
+ . reduce 7
+
+
+state 42
+ cmd : TYPE SP . type_code CRLF (8)
+
+ A shift 76
+ E shift 77
+ I shift 78
+ L shift 79
+ . error
+
+ type_code goto 80
+
+
+state 43
+ cmd : STRU SP . struct_code CRLF (9)
+
+ F shift 81
+ P shift 82
+ R shift 83
+ . error
+
+ struct_code goto 84
+
+
+state 44
+ cmd : MODE SP . mode_code CRLF (10)
+
+ B shift 85
+ C shift 86
+ S shift 87
+ . error
+
+ mode_code goto 88
+
+
+state 45
+ cmd : RETR check_login . SP pathname CRLF (13)
+
+ SP shift 89
+ . error
+
+
+state 46
+ cmd : STOR check_login . SP pathname CRLF (14)
+
+ SP shift 90
+ . error
+
+
+state 47
+ cmd : APPE check_login . SP pathname CRLF (15)
+
+ SP shift 91
+ . error
+
+
+state 48
+ cmd : ALLO SP . NUMBER CRLF (11)
+ cmd : ALLO SP . NUMBER SP R SP NUMBER CRLF (12)
+
+ NUMBER shift 92
+ . error
+
+
+state 49
+ rcmd : RNFR check_login . SP pathname CRLF (47)
+
+ SP shift 93
+ . error
+
+
+state 50
+ cmd : RNTO SP . pathname CRLF (23)
+
+ STRING shift 94
+ . error
+
+ pathname goto 95
+ pathstring goto 96
+
+
+state 51
+ cmd : ABOR CRLF . (24)
+
+ . reduce 24
+
+
+state 52
+ cmd : DELE check_login . SP pathname CRLF (22)
+
+ SP shift 97
+ . error
+
+
+state 53
+ cmd : CWD check_login . CRLF (25)
+ cmd : CWD check_login . SP pathname CRLF (26)
+
+ SP shift 98
+ CRLF shift 99
+ . error
+
+
+state 54
+ cmd : LIST check_login . CRLF (18)
+ cmd : LIST check_login . SP pathname CRLF (19)
+
+ SP shift 100
+ CRLF shift 101
+ . error
+
+
+state 55
+ cmd : NLST check_login . CRLF (16)
+ cmd : NLST check_login . SP STRING CRLF (17)
+
+ SP shift 102
+ CRLF shift 103
+ . error
+
+
+state 56
+ cmd : SITE SP . HELP CRLF (34)
+ cmd : SITE SP . HELP SP STRING CRLF (35)
+ cmd : SITE SP . UMASK check_login CRLF (36)
+ cmd : SITE SP . UMASK check_login SP octal_number CRLF (37)
+ cmd : SITE SP . CHMOD check_login SP octal_number SP pathname CRLF (38)
+ cmd : SITE SP . IDLE CRLF (39)
+ cmd : SITE SP . IDLE SP NUMBER CRLF (40)
+
+ HELP shift 104
+ UMASK shift 105
+ IDLE shift 106
+ CHMOD shift 107
+ . error
+
+
+state 57
+ cmd : STAT CRLF . (21)
+
+ . reduce 21
+
+
+state 58
+ cmd : STAT check_login . SP pathname CRLF (20)
+
+ SP shift 108
+ . error
+
+
+state 59
+ cmd : HELP SP . STRING CRLF (28)
+
+ STRING shift 109
+ . error
+
+
+state 60
+ cmd : HELP CRLF . (27)
+
+ . reduce 27
+
+
+state 61
+ cmd : NOOP CRLF . (29)
+
+ . reduce 29
+
+
+state 62
+ cmd : MKD check_login . SP pathname CRLF (30)
+
+ SP shift 110
+ . error
+
+
+state 63
+ cmd : RMD check_login . SP pathname CRLF (31)
+
+ SP shift 111
+ . error
+
+
+state 64
+ cmd : PWD check_login . CRLF (32)
+
+ CRLF shift 112
+ . error
+
+
+state 65
+ cmd : CDUP check_login . CRLF (33)
+
+ CRLF shift 113
+ . error
+
+
+state 66
+ cmd : STOU check_login . SP pathname CRLF (41)
+
+ SP shift 114
+ . error
+
+
+state 67
+ cmd : SYST CRLF . (42)
+
+ . reduce 42
+
+
+state 68
+ cmd : SIZE check_login . SP pathname CRLF (43)
+
+ SP shift 115
+ . error
+
+
+state 69
+ cmd : MDTM check_login . SP pathname CRLF (44)
+
+ SP shift 116
+ . error
+
+
+state 70
+ username : STRING . (48)
+
+ . reduce 48
+
+
+state 71
+ cmd : USER SP username . CRLF (4)
+
+ CRLF shift 117
+ . error
+
+
+state 72
+ password : STRING . (50)
+
+ . reduce 50
+
+
+state 73
+ cmd : PASS SP password . CRLF (5)
+
+ CRLF shift 118
+ . error
+
+
+state 74
+ host_port : NUMBER . COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER (52)
+
+ COMMA shift 119
+ . error
+
+
+state 75
+ cmd : PORT SP host_port . CRLF (6)
+
+ CRLF shift 120
+ . error
+
+
+state 76
+ type_code : A . (56)
+ type_code : A . SP form_code (57)
+
+ SP shift 121
+ CRLF reduce 56
+
+
+state 77
+ type_code : E . (58)
+ type_code : E . SP form_code (59)
+
+ SP shift 122
+ CRLF reduce 58
+
+
+state 78
+ type_code : I . (60)
+
+ . reduce 60
+
+
+state 79
+ type_code : L . (61)
+ type_code : L . SP byte_size (62)
+ type_code : L . byte_size (63)
+
+ SP shift 123
+ NUMBER shift 124
+ CRLF reduce 61
+
+ byte_size goto 125
+
+
+state 80
+ cmd : TYPE SP type_code . CRLF (8)
+
+ CRLF shift 126
+ . error
+
+
+state 81
+ struct_code : F . (64)
+
+ . reduce 64
+
+
+state 82
+ struct_code : P . (66)
+
+ . reduce 66
+
+
+state 83
+ struct_code : R . (65)
+
+ . reduce 65
+
+
+state 84
+ cmd : STRU SP struct_code . CRLF (9)
+
+ CRLF shift 127
+ . error
+
+
+state 85
+ mode_code : B . (68)
+
+ . reduce 68
+
+
+state 86
+ mode_code : C . (69)
+
+ . reduce 69
+
+
+state 87
+ mode_code : S . (67)
+
+ . reduce 67
+
+
+state 88
+ cmd : MODE SP mode_code . CRLF (10)
+
+ CRLF shift 128
+ . error
+
+
+state 89
+ cmd : RETR check_login SP . pathname CRLF (13)
+
+ STRING shift 94
+ . error
+
+ pathname goto 129
+ pathstring goto 96
+
+
+state 90
+ cmd : STOR check_login SP . pathname CRLF (14)
+
+ STRING shift 94
+ . error
+
+ pathname goto 130
+ pathstring goto 96
+
+
+state 91
+ cmd : APPE check_login SP . pathname CRLF (15)
+
+ STRING shift 94
+ . error
+
+ pathname goto 131
+ pathstring goto 96
+
+
+state 92
+ cmd : ALLO SP NUMBER . CRLF (11)
+ cmd : ALLO SP NUMBER . SP R SP NUMBER CRLF (12)
+
+ SP shift 132
+ CRLF shift 133
+ . error
+
+
+state 93
+ rcmd : RNFR check_login SP . pathname CRLF (47)
+
+ STRING shift 94
+ . error
+
+ pathname goto 134
+ pathstring goto 96
+
+
+state 94
+ pathstring : STRING . (71)
+
+ . reduce 71
+
+
+state 95
+ cmd : RNTO SP pathname . CRLF (23)
+
+ CRLF shift 135
+ . error
+
+
+state 96
+ pathname : pathstring . (70)
+
+ . reduce 70
+
+
+state 97
+ cmd : DELE check_login SP . pathname CRLF (22)
+
+ STRING shift 94
+ . error
+
+ pathname goto 136
+ pathstring goto 96
+
+
+state 98
+ cmd : CWD check_login SP . pathname CRLF (26)
+
+ STRING shift 94
+ . error
+
+ pathname goto 137
+ pathstring goto 96
+
+
+state 99
+ cmd : CWD check_login CRLF . (25)
+
+ . reduce 25
+
+
+state 100
+ cmd : LIST check_login SP . pathname CRLF (19)
+
+ STRING shift 94
+ . error
+
+ pathname goto 138
+ pathstring goto 96
+
+
+state 101
+ cmd : LIST check_login CRLF . (18)
+
+ . reduce 18
+
+
+state 102
+ cmd : NLST check_login SP . STRING CRLF (17)
+
+ STRING shift 139
+ . error
+
+
+state 103
+ cmd : NLST check_login CRLF . (16)
+
+ . reduce 16
+
+
+state 104
+ cmd : SITE SP HELP . CRLF (34)
+ cmd : SITE SP HELP . SP STRING CRLF (35)
+
+ SP shift 140
+ CRLF shift 141
+ . error
+
+
+state 105
+ cmd : SITE SP UMASK . check_login CRLF (36)
+ cmd : SITE SP UMASK . check_login SP octal_number CRLF (37)
+ check_login : . (73)
+
+ . reduce 73
+
+ check_login goto 142
+
+
+state 106
+ cmd : SITE SP IDLE . CRLF (39)
+ cmd : SITE SP IDLE . SP NUMBER CRLF (40)
+
+ SP shift 143
+ CRLF shift 144
+ . error
+
+
+state 107
+ cmd : SITE SP CHMOD . check_login SP octal_number SP pathname CRLF (38)
+ check_login : . (73)
+
+ . reduce 73
+
+ check_login goto 145
+
+
+state 108
+ cmd : STAT check_login SP . pathname CRLF (20)
+
+ STRING shift 94
+ . error
+
+ pathname goto 146
+ pathstring goto 96
+
+
+state 109
+ cmd : HELP SP STRING . CRLF (28)
+
+ CRLF shift 147
+ . error
+
+
+state 110
+ cmd : MKD check_login SP . pathname CRLF (30)
+
+ STRING shift 94
+ . error
+
+ pathname goto 148
+ pathstring goto 96
+
+
+state 111
+ cmd : RMD check_login SP . pathname CRLF (31)
+
+ STRING shift 94
+ . error
+
+ pathname goto 149
+ pathstring goto 96
+
+
+state 112
+ cmd : PWD check_login CRLF . (32)
+
+ . reduce 32
+
+
+state 113
+ cmd : CDUP check_login CRLF . (33)
+
+ . reduce 33
+
+
+state 114
+ cmd : STOU check_login SP . pathname CRLF (41)
+
+ STRING shift 94
+ . error
+
+ pathname goto 150
+ pathstring goto 96
+
+
+state 115
+ cmd : SIZE check_login SP . pathname CRLF (43)
+
+ STRING shift 94
+ . error
+
+ pathname goto 151
+ pathstring goto 96
+
+
+state 116
+ cmd : MDTM check_login SP . pathname CRLF (44)
+
+ STRING shift 94
+ . error
+
+ pathname goto 152
+ pathstring goto 96
+
+
+state 117
+ cmd : USER SP username CRLF . (4)
+
+ . reduce 4
+
+
+state 118
+ cmd : PASS SP password CRLF . (5)
+
+ . reduce 5
+
+
+state 119
+ host_port : NUMBER COMMA . NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER (52)
+
+ NUMBER shift 153
+ . error
+
+
+state 120
+ cmd : PORT SP host_port CRLF . (6)
+
+ . reduce 6
+
+
+state 121
+ type_code : A SP . form_code (57)
+
+ C shift 154
+ N shift 155
+ T shift 156
+ . error
+
+ form_code goto 157
+
+
+state 122
+ type_code : E SP . form_code (59)
+
+ C shift 154
+ N shift 155
+ T shift 156
+ . error
+
+ form_code goto 158
+
+
+state 123
+ type_code : L SP . byte_size (62)
+
+ NUMBER shift 124
+ . error
+
+ byte_size goto 159
+
+
+state 124
+ byte_size : NUMBER . (51)
+
+ . reduce 51
+
+
+state 125
+ type_code : L byte_size . (63)
+
+ . reduce 63
+
+
+state 126
+ cmd : TYPE SP type_code CRLF . (8)
+
+ . reduce 8
+
+
+state 127
+ cmd : STRU SP struct_code CRLF . (9)
+
+ . reduce 9
+
+
+state 128
+ cmd : MODE SP mode_code CRLF . (10)
+
+ . reduce 10
+
+
+state 129
+ cmd : RETR check_login SP pathname . CRLF (13)
+
+ CRLF shift 160
+ . error
+
+
+state 130
+ cmd : STOR check_login SP pathname . CRLF (14)
+
+ CRLF shift 161
+ . error
+
+
+state 131
+ cmd : APPE check_login SP pathname . CRLF (15)
+
+ CRLF shift 162
+ . error
+
+
+state 132
+ cmd : ALLO SP NUMBER SP . R SP NUMBER CRLF (12)
+
+ R shift 163
+ . error
+
+
+state 133
+ cmd : ALLO SP NUMBER CRLF . (11)
+
+ . reduce 11
+
+
+state 134
+ rcmd : RNFR check_login SP pathname . CRLF (47)
+
+ CRLF shift 164
+ . error
+
+
+state 135
+ cmd : RNTO SP pathname CRLF . (23)
+
+ . reduce 23
+
+
+state 136
+ cmd : DELE check_login SP pathname . CRLF (22)
+
+ CRLF shift 165
+ . error
+
+
+state 137
+ cmd : CWD check_login SP pathname . CRLF (26)
+
+ CRLF shift 166
+ . error
+
+
+state 138
+ cmd : LIST check_login SP pathname . CRLF (19)
+
+ CRLF shift 167
+ . error
+
+
+state 139
+ cmd : NLST check_login SP STRING . CRLF (17)
+
+ CRLF shift 168
+ . error
+
+
+state 140
+ cmd : SITE SP HELP SP . STRING CRLF (35)
+
+ STRING shift 169
+ . error
+
+
+state 141
+ cmd : SITE SP HELP CRLF . (34)
+
+ . reduce 34
+
+
+state 142
+ cmd : SITE SP UMASK check_login . CRLF (36)
+ cmd : SITE SP UMASK check_login . SP octal_number CRLF (37)
+
+ SP shift 170
+ CRLF shift 171
+ . error
+
+
+state 143
+ cmd : SITE SP IDLE SP . NUMBER CRLF (40)
+
+ NUMBER shift 172
+ . error
+
+
+state 144
+ cmd : SITE SP IDLE CRLF . (39)
+
+ . reduce 39
+
+
+state 145
+ cmd : SITE SP CHMOD check_login . SP octal_number SP pathname CRLF (38)
+
+ SP shift 173
+ . error
+
+
+state 146
+ cmd : STAT check_login SP pathname . CRLF (20)
+
+ CRLF shift 174
+ . error
+
+
+state 147
+ cmd : HELP SP STRING CRLF . (28)
+
+ . reduce 28
+
+
+state 148
+ cmd : MKD check_login SP pathname . CRLF (30)
+
+ CRLF shift 175
+ . error
+
+
+state 149
+ cmd : RMD check_login SP pathname . CRLF (31)
+
+ CRLF shift 176
+ . error
+
+
+state 150
+ cmd : STOU check_login SP pathname . CRLF (41)
+
+ CRLF shift 177
+ . error
+
+
+state 151
+ cmd : SIZE check_login SP pathname . CRLF (43)
+
+ CRLF shift 178
+ . error
+
+
+state 152
+ cmd : MDTM check_login SP pathname . CRLF (44)
+
+ CRLF shift 179
+ . error
+
+
+state 153
+ host_port : NUMBER COMMA NUMBER . COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER (52)
+
+ COMMA shift 180
+ . error
+
+
+state 154
+ form_code : C . (55)
+
+ . reduce 55
+
+
+state 155
+ form_code : N . (53)
+
+ . reduce 53
+
+
+state 156
+ form_code : T . (54)
+
+ . reduce 54
+
+
+state 157
+ type_code : A SP form_code . (57)
+
+ . reduce 57
+
+
+state 158
+ type_code : E SP form_code . (59)
+
+ . reduce 59
+
+
+state 159
+ type_code : L SP byte_size . (62)
+
+ . reduce 62
+
+
+state 160
+ cmd : RETR check_login SP pathname CRLF . (13)
+
+ . reduce 13
+
+
+state 161
+ cmd : STOR check_login SP pathname CRLF . (14)
+
+ . reduce 14
+
+
+state 162
+ cmd : APPE check_login SP pathname CRLF . (15)
+
+ . reduce 15
+
+
+state 163
+ cmd : ALLO SP NUMBER SP R . SP NUMBER CRLF (12)
+
+ SP shift 181
+ . error
+
+
+state 164
+ rcmd : RNFR check_login SP pathname CRLF . (47)
+
+ . reduce 47
+
+
+state 165
+ cmd : DELE check_login SP pathname CRLF . (22)
+
+ . reduce 22
+
+
+state 166
+ cmd : CWD check_login SP pathname CRLF . (26)
+
+ . reduce 26
+
+
+state 167
+ cmd : LIST check_login SP pathname CRLF . (19)
+
+ . reduce 19
+
+
+state 168
+ cmd : NLST check_login SP STRING CRLF . (17)
+
+ . reduce 17
+
+
+state 169
+ cmd : SITE SP HELP SP STRING . CRLF (35)
+
+ CRLF shift 182
+ . error
+
+
+state 170
+ cmd : SITE SP UMASK check_login SP . octal_number CRLF (37)
+
+ NUMBER shift 183
+ . error
+
+ octal_number goto 184
+
+
+state 171
+ cmd : SITE SP UMASK check_login CRLF . (36)
+
+ . reduce 36
+
+
+state 172
+ cmd : SITE SP IDLE SP NUMBER . CRLF (40)
+
+ CRLF shift 185
+ . error
+
+
+state 173
+ cmd : SITE SP CHMOD check_login SP . octal_number SP pathname CRLF (38)
+
+ NUMBER shift 183
+ . error
+
+ octal_number goto 186
+
+
+state 174
+ cmd : STAT check_login SP pathname CRLF . (20)
+
+ . reduce 20
+
+
+state 175
+ cmd : MKD check_login SP pathname CRLF . (30)
+
+ . reduce 30
+
+
+state 176
+ cmd : RMD check_login SP pathname CRLF . (31)
+
+ . reduce 31
+
+
+state 177
+ cmd : STOU check_login SP pathname CRLF . (41)
+
+ . reduce 41
+
+
+state 178
+ cmd : SIZE check_login SP pathname CRLF . (43)
+
+ . reduce 43
+
+
+state 179
+ cmd : MDTM check_login SP pathname CRLF . (44)
+
+ . reduce 44
+
+
+state 180
+ host_port : NUMBER COMMA NUMBER COMMA . NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER (52)
+
+ NUMBER shift 187
+ . error
+
+
+state 181
+ cmd : ALLO SP NUMBER SP R SP . NUMBER CRLF (12)
+
+ NUMBER shift 188
+ . error
+
+
+state 182
+ cmd : SITE SP HELP SP STRING CRLF . (35)
+
+ . reduce 35
+
+
+state 183
+ octal_number : NUMBER . (72)
+
+ . reduce 72
+
+
+state 184
+ cmd : SITE SP UMASK check_login SP octal_number . CRLF (37)
+
+ CRLF shift 189
+ . error
+
+
+state 185
+ cmd : SITE SP IDLE SP NUMBER CRLF . (40)
+
+ . reduce 40
+
+
+state 186
+ cmd : SITE SP CHMOD check_login SP octal_number . SP pathname CRLF (38)
+
+ SP shift 190
+ . error
+
+
+state 187
+ host_port : NUMBER COMMA NUMBER COMMA NUMBER . COMMA NUMBER COMMA NUMBER COMMA NUMBER (52)
+
+ COMMA shift 191
+ . error
+
+
+state 188
+ cmd : ALLO SP NUMBER SP R SP NUMBER . CRLF (12)
+
+ CRLF shift 192
+ . error
+
+
+state 189
+ cmd : SITE SP UMASK check_login SP octal_number CRLF . (37)
+
+ . reduce 37
+
+
+state 190
+ cmd : SITE SP CHMOD check_login SP octal_number SP . pathname CRLF (38)
+
+ STRING shift 94
+ . error
+
+ pathname goto 193
+ pathstring goto 96
+
+
+state 191
+ host_port : NUMBER COMMA NUMBER COMMA NUMBER COMMA . NUMBER COMMA NUMBER COMMA NUMBER (52)
+
+ NUMBER shift 194
+ . error
+
+
+state 192
+ cmd : ALLO SP NUMBER SP R SP NUMBER CRLF . (12)
+
+ . reduce 12
+
+
+state 193
+ cmd : SITE SP CHMOD check_login SP octal_number SP pathname . CRLF (38)
+
+ CRLF shift 195
+ . error
+
+
+state 194
+ host_port : NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER . COMMA NUMBER COMMA NUMBER (52)
+
+ COMMA shift 196
+ . error
+
+
+state 195
+ cmd : SITE SP CHMOD check_login SP octal_number SP pathname CRLF . (38)
+
+ . reduce 38
+
+
+state 196
+ host_port : NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA . NUMBER COMMA NUMBER (52)
+
+ NUMBER shift 197
+ . error
+
+
+state 197
+ host_port : NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER . COMMA NUMBER (52)
+
+ COMMA shift 198
+ . error
+
+
+state 198
+ host_port : NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA . NUMBER (52)
+
+ NUMBER shift 199
+ . error
+
+
+state 199
+ host_port : NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER . (52)
+
+ . reduce 52
+
+
+65 terminals, 16 nonterminals
+74 grammar rules, 200 states
diff --git a/usr.bin/yacc/test/ftp.tab.c b/usr.bin/yacc/test/ftp.tab.c
new file mode 100644
index 0000000..c9794ed
--- /dev/null
+++ b/usr.bin/yacc/test/ftp.tab.c
@@ -0,0 +1,1743 @@
+#ifndef lint
+static char yysccsid[] = "@(#)yaccpar 1.9 (Berkeley) 02/21/93";
+#endif
+#define YYBYACC 1
+#define YYMAJOR 1
+#define YYMINOR 9
+#define yyclearin (yychar=(-1))
+#define yyerrok (yyerrflag=0)
+#define YYRECOVERING (yyerrflag!=0)
+#define YYPREFIX "yy"
+#line 26 "ftp.y"
+
+#ifndef lint
+static char sccsid[] = "@(#)ftpcmd.y 5.20.1.1 (Berkeley) 3/2/89";
+#endif /* not lint */
+
+#include <sys/param.h>
+#include <sys/socket.h>
+
+#include <netinet/in.h>
+
+#include <arpa/ftp.h>
+
+#include <stdio.h>
+#include <signal.h>
+#include <ctype.h>
+#include <pwd.h>
+#include <setjmp.h>
+#include <syslog.h>
+#include <sys/stat.h>
+#include <time.h>
+
+extern struct sockaddr_in data_dest;
+extern int logged_in;
+extern struct passwd *pw;
+extern int guest;
+extern int logging;
+extern int type;
+extern int form;
+extern int debug;
+extern int timeout;
+extern int maxtimeout;
+extern int pdata;
+extern char hostname[], remotehost[];
+extern char proctitle[];
+extern char *globerr;
+extern int usedefault;
+extern int transflag;
+extern char tmpline[];
+char **glob();
+
+static int cmd_type;
+static int cmd_form;
+static int cmd_bytesz;
+char cbuf[512];
+char *fromname;
+
+char *index();
+#line 60 "ftp.tab.c"
+#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 LEXERR 319
+#define YYERRCODE 256
+short yylhs[] = { -1,
+ 0, 0, 0, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 2, 3, 4, 4,
+ 12, 5, 13, 13, 13, 6, 6, 6, 6, 6,
+ 6, 6, 6, 7, 7, 7, 8, 8, 8, 10,
+ 14, 11, 9,
+};
+short yylen[] = { 2,
+ 0, 2, 2, 4, 4, 4, 2, 4, 4, 4,
+ 4, 8, 5, 5, 5, 3, 5, 3, 5, 5,
+ 2, 5, 4, 2, 3, 5, 2, 4, 2, 5,
+ 5, 3, 3, 4, 6, 5, 7, 9, 4, 6,
+ 5, 2, 5, 5, 2, 2, 5, 1, 0, 1,
+ 1, 11, 1, 1, 1, 1, 3, 1, 3, 1,
+ 1, 3, 2, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 0,
+};
+short yydefred[] = { 1,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 73, 73, 73, 0, 73, 0, 0, 73, 73, 73,
+ 73, 0, 0, 0, 0, 73, 73, 73, 73, 73,
+ 0, 73, 73, 2, 3, 46, 0, 0, 45, 0,
+ 7, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 24, 0, 0, 0, 0, 0, 21, 0, 0, 27,
+ 29, 0, 0, 0, 0, 0, 42, 0, 0, 48,
+ 0, 50, 0, 0, 0, 0, 0, 60, 0, 0,
+ 64, 66, 65, 0, 68, 69, 67, 0, 0, 0,
+ 0, 0, 0, 71, 0, 70, 0, 0, 25, 0,
+ 18, 0, 16, 0, 73, 0, 73, 0, 0, 0,
+ 0, 32, 33, 0, 0, 0, 4, 5, 0, 6,
+ 0, 0, 0, 51, 63, 8, 9, 10, 0, 0,
+ 0, 0, 11, 0, 23, 0, 0, 0, 0, 0,
+ 34, 0, 0, 39, 0, 0, 28, 0, 0, 0,
+ 0, 0, 0, 55, 53, 54, 57, 59, 62, 13,
+ 14, 15, 0, 47, 22, 26, 19, 17, 0, 0,
+ 36, 0, 0, 20, 30, 31, 41, 43, 44, 0,
+ 0, 35, 72, 0, 40, 0, 0, 0, 37, 0,
+ 0, 12, 0, 0, 38, 0, 0, 0, 52,
+};
+short yydgoto[] = { 1,
+ 34, 35, 71, 73, 75, 80, 84, 88, 45, 95,
+ 184, 125, 157, 96,
+};
+short yysindex[] = { 0,
+ -224, -247, -239, -236, -232, -222, -204, -200, -181, -177,
+ 0, 0, 0, -166, 0, -161, -199, 0, 0, 0,
+ 0, -160, -159, -264, -158, 0, 0, 0, 0, 0,
+ -157, 0, 0, 0, 0, 0, -167, -162, 0, -156,
+ 0, -250, -198, -165, -155, -154, -153, -151, -150, -152,
+ 0, -145, -252, -229, -217, -302, 0, -144, -146, 0,
+ 0, -142, -141, -140, -139, -137, 0, -136, -135, 0,
+ -134, 0, -133, -132, -130, -131, -128, 0, -249, -127,
+ 0, 0, 0, -126, 0, 0, 0, -125, -152, -152,
+ -152, -205, -152, 0, -124, 0, -152, -152, 0, -152,
+ 0, -143, 0, -173, 0, -171, 0, -152, -123, -152,
+ -152, 0, 0, -152, -152, -152, 0, 0, -138, 0,
+ -164, -164, -122, 0, 0, 0, 0, 0, -121, -120,
+ -118, -148, 0, -117, 0, -116, -115, -114, -113, -112,
+ 0, -163, -111, 0, -110, -109, 0, -107, -106, -105,
+ -104, -103, -129, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, -101, 0, 0, 0, 0, 0, -100, -102,
+ 0, -98, -102, 0, 0, 0, 0, 0, 0, -99,
+ -97, 0, 0, -95, 0, -96, -94, -92, 0, -152,
+ -93, 0, -91, -90, 0, -88, -87, -86, 0,
+};
+short yyrindex[] = { 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, -83, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, -82, 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, -81, -80, 0, -158, 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, 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, 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, 0, 0, 0,
+};
+short yygindex[] = { 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 16, -89,
+ -25, 35, 47, 0,
+};
+#define YYTABLESIZE 190
+short yytable[] = { 129,
+ 130, 131, 104, 134, 59, 60, 76, 136, 137, 77,
+ 138, 78, 79, 105, 106, 107, 98, 99, 146, 123,
+ 148, 149, 36, 124, 150, 151, 152, 46, 47, 37,
+ 49, 2, 38, 52, 53, 54, 55, 39, 58, 100,
+ 101, 62, 63, 64, 65, 66, 40, 68, 69, 3,
+ 4, 102, 103, 5, 6, 7, 8, 9, 10, 11,
+ 12, 13, 81, 132, 133, 41, 82, 83, 42, 14,
+ 51, 15, 16, 17, 18, 19, 20, 21, 22, 23,
+ 24, 25, 26, 27, 28, 29, 30, 43, 31, 32,
+ 33, 44, 85, 86, 154, 140, 141, 143, 144, 155,
+ 193, 87, 48, 156, 70, 170, 171, 50, 56, 72,
+ 57, 61, 67, 89, 90, 91, 74, 163, 93, 94,
+ 142, 92, 145, 97, 108, 109, 110, 111, 139, 112,
+ 113, 114, 115, 116, 153, 117, 118, 121, 119, 120,
+ 122, 180, 126, 127, 128, 135, 147, 186, 160, 161,
+ 124, 162, 164, 165, 166, 167, 168, 159, 173, 169,
+ 174, 172, 175, 176, 177, 178, 179, 181, 158, 182,
+ 183, 185, 190, 187, 189, 188, 191, 192, 195, 194,
+ 196, 0, 0, 198, 197, 73, 199, 49, 56, 58,
+};
+short yycheck[] = { 89,
+ 90, 91, 305, 93, 269, 270, 257, 97, 98, 260,
+ 100, 262, 263, 316, 317, 318, 269, 270, 108, 269,
+ 110, 111, 270, 273, 114, 115, 116, 12, 13, 269,
+ 15, 256, 269, 18, 19, 20, 21, 270, 23, 269,
+ 270, 26, 27, 28, 29, 30, 269, 32, 33, 274,
+ 275, 269, 270, 278, 279, 280, 281, 282, 283, 284,
+ 285, 286, 261, 269, 270, 270, 265, 266, 269, 294,
+ 270, 296, 297, 298, 299, 300, 301, 302, 303, 304,
+ 305, 306, 307, 308, 309, 310, 311, 269, 313, 314,
+ 315, 269, 258, 259, 259, 269, 270, 269, 270, 264,
+ 190, 267, 269, 268, 272, 269, 270, 269, 269, 272,
+ 270, 270, 270, 269, 269, 269, 273, 266, 269, 272,
+ 105, 273, 107, 269, 269, 272, 269, 269, 272, 270,
+ 270, 269, 269, 269, 273, 270, 270, 269, 271, 270,
+ 269, 271, 270, 270, 270, 270, 270, 173, 270, 270,
+ 273, 270, 270, 270, 270, 270, 270, 123, 269, 272,
+ 270, 273, 270, 270, 270, 270, 270, 269, 122, 270,
+ 273, 270, 269, 273, 270, 273, 271, 270, 270, 273,
+ 271, -1, -1, 271, 273, 269, 273, 270, 270, 270,
+};
+#define YYFINAL 1
+#ifndef YYDEBUG
+#define YYDEBUG 0
+#endif
+#define YYMAXTOKEN 319
+#if YYDEBUG
+char *yyname[] = {
+"end-of-file",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,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,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,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,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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"A","B","C","E","F","I","L","N",
+"P","R","S","T","SP","CRLF","COMMA","STRING","NUMBER","USER","PASS","ACCT",
+"REIN","QUIT","PORT","PASV","TYPE","STRU","MODE","RETR","STOR","APPE","MLFL",
+"MAIL","MSND","MSOM","MSAM","MRSQ","MRCP","ALLO","REST","RNFR","RNTO","ABOR",
+"DELE","CWD","LIST","NLST","SITE","STAT","HELP","NOOP","MKD","RMD","PWD","CDUP",
+"STOU","SMNT","SYST","SIZE","MDTM","UMASK","IDLE","CHMOD","LEXERR",
+};
+char *yyrule[] = {
+"$accept : cmd_list",
+"cmd_list :",
+"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 : 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",
+"username : STRING",
+"password :",
+"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 :",
+};
+#endif
+#ifndef YYSTYPE
+typedef int YYSTYPE;
+#endif
+#ifdef YYSTACKSIZE
+#undef YYMAXDEPTH
+#define YYMAXDEPTH YYSTACKSIZE
+#else
+#ifdef YYMAXDEPTH
+#define YYSTACKSIZE YYMAXDEPTH
+#else
+#define YYSTACKSIZE 500
+#define YYMAXDEPTH 500
+#endif
+#endif
+int yydebug;
+int yynerrs;
+int yyerrflag;
+int yychar;
+short *yyssp;
+YYSTYPE *yyvsp;
+YYSTYPE yyval;
+YYSTYPE yylval;
+short yyss[YYSTACKSIZE];
+YYSTYPE yyvs[YYSTACKSIZE];
+#define yystacksize YYSTACKSIZE
+#line 658 "ftp.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 */
+
+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, 0, "(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> ]" },
+ { 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 int
+toolong()
+{
+ time_t now;
+ extern char *ctime();
+ extern time_t time();
+
+ 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));
+ }
+ dologout(1);
+}
+
+yylex()
+{
+ static int cpos, state;
+ register char *cp, *cp2;
+ register struct tab *p;
+ int n;
+ char c, *strpbrk();
+ char *copy();
+
+ for (;;) {
+ switch (state) {
+
+ case CMD:
+ (void) signal(SIGALRM, toolong);
+ (void) alarm((unsigned) timeout);
+ 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) != NULL)
+ setproctitle("%s: %s", proctitle, cbuf);
+#endif /* SETPROCTITLE */
+ if ((cp = index(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;
+ *(char **)&yylval = 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;
+ *(char **)&yylval = 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';
+ *(char **)&yylval = 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 = atoi(cp);
+ cbuf[cpos] = c;
+ state = STR1;
+ return (NUMBER);
+ }
+ state = STR1;
+ goto dostr1;
+
+ case ARGS:
+ if (isdigit(cbuf[cpos])) {
+ cp = &cbuf[cpos];
+ while (isdigit(cbuf[++cpos]))
+ ;
+ c = cbuf[cpos];
+ cbuf[cpos] = '\0';
+ yylval = 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 *) 0);
+ 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;
+ extern char *malloc(), *strcpy();
+
+ 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 *)0) {
+ 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, 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]);
+ }
+}
+#line 908 "ftp.tab.c"
+#define YYABORT goto yyabort
+#define YYREJECT goto yyabort
+#define YYACCEPT goto yyaccept
+#define YYERROR goto yyerrlab
+int
+yyparse()
+{
+ register int yym, yyn, yystate;
+#if YYDEBUG
+ register char *yys;
+ extern char *getenv();
+
+ if (yys = getenv("YYDEBUG"))
+ {
+ yyn = *yys;
+ if (yyn >= '0' && yyn <= '9')
+ yydebug = yyn - '0';
+ }
+#endif
+
+ yynerrs = 0;
+ yyerrflag = 0;
+ yychar = (-1);
+
+ yyssp = yyss;
+ yyvsp = yyvs;
+ *yyssp = yystate = 0;
+
+yyloop:
+ if (yyn = yydefred[yystate]) goto yyreduce;
+ if (yychar < 0)
+ {
+ if ((yychar = yylex()) < 0) yychar = 0;
+#if YYDEBUG
+ if (yydebug)
+ {
+ yys = 0;
+ if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
+ if (!yys) yys = "illegal-symbol";
+ printf("%sdebug: state %d, reading %d (%s)\n",
+ YYPREFIX, yystate, yychar, yys);
+ }
+#endif
+ }
+ if ((yyn = yysindex[yystate]) && (yyn += yychar) >= 0 &&
+ yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
+ {
+#if YYDEBUG
+ if (yydebug)
+ printf("%sdebug: state %d, shifting to state %d\n",
+ YYPREFIX, yystate, yytable[yyn]);
+#endif
+ if (yyssp >= yyss + yystacksize - 1)
+ {
+ goto yyoverflow;
+ }
+ *++yyssp = yystate = yytable[yyn];
+ *++yyvsp = yylval;
+ yychar = (-1);
+ if (yyerrflag > 0) --yyerrflag;
+ goto yyloop;
+ }
+ if ((yyn = yyrindex[yystate]) && (yyn += yychar) >= 0 &&
+ yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
+ {
+ yyn = yytable[yyn];
+ goto yyreduce;
+ }
+ if (yyerrflag) goto yyinrecovery;
+#ifdef lint
+ goto yynewerror;
+#endif
+yynewerror:
+ yyerror("syntax error");
+#ifdef lint
+ goto yyerrlab;
+#endif
+yyerrlab:
+ ++yynerrs;
+yyinrecovery:
+ if (yyerrflag < 3)
+ {
+ yyerrflag = 3;
+ for (;;)
+ {
+ if ((yyn = yysindex[*yyssp]) && (yyn += YYERRCODE) >= 0 &&
+ yyn <= YYTABLESIZE && yycheck[yyn] == YYERRCODE)
+ {
+#if YYDEBUG
+ if (yydebug)
+ printf("%sdebug: state %d, error recovery shifting\
+ to state %d\n", YYPREFIX, *yyssp, yytable[yyn]);
+#endif
+ if (yyssp >= yyss + yystacksize - 1)
+ {
+ goto yyoverflow;
+ }
+ *++yyssp = yystate = yytable[yyn];
+ *++yyvsp = yylval;
+ goto yyloop;
+ }
+ else
+ {
+#if YYDEBUG
+ if (yydebug)
+ printf("%sdebug: error recovery discarding state %d\n",
+ YYPREFIX, *yyssp);
+#endif
+ if (yyssp <= yyss) goto yyabort;
+ --yyssp;
+ --yyvsp;
+ }
+ }
+ }
+ else
+ {
+ if (yychar == 0) goto yyabort;
+#if YYDEBUG
+ if (yydebug)
+ {
+ yys = 0;
+ if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
+ if (!yys) yys = "illegal-symbol";
+ printf("%sdebug: state %d, error recovery discards token %d (%s)\n",
+ YYPREFIX, yystate, yychar, yys);
+ }
+#endif
+ yychar = (-1);
+ goto yyloop;
+ }
+yyreduce:
+#if YYDEBUG
+ if (yydebug)
+ printf("%sdebug: state %d, reducing by rule %d (%s)\n",
+ YYPREFIX, yystate, yyn, yyrule[yyn]);
+#endif
+ yym = yylen[yyn];
+ yyval = yyvsp[1-yym];
+ switch (yyn)
+ {
+case 2:
+#line 99 "ftp.y"
+ {
+ fromname = (char *) 0;
+ }
+break;
+case 4:
+#line 106 "ftp.y"
+ {
+ user((char *) yyvsp[-1]);
+ free((char *) yyvsp[-1]);
+ }
+break;
+case 5:
+#line 111 "ftp.y"
+ {
+ pass((char *) yyvsp[-1]);
+ free((char *) yyvsp[-1]);
+ }
+break;
+case 6:
+#line 116 "ftp.y"
+ {
+ usedefault = 0;
+ if (pdata >= 0) {
+ (void) close(pdata);
+ pdata = -1;
+ }
+ reply(200, "PORT command successful.");
+ }
+break;
+case 7:
+#line 125 "ftp.y"
+ {
+ passive();
+ }
+break;
+case 8:
+#line 129 "ftp.y"
+ {
+ 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 */
+ }
+ }
+break;
+case 9:
+#line 164 "ftp.y"
+ {
+ switch (yyvsp[-1]) {
+
+ case STRU_F:
+ reply(200, "STRU F ok.");
+ break;
+
+ default:
+ reply(504, "Unimplemented STRU type.");
+ }
+ }
+break;
+case 10:
+#line 176 "ftp.y"
+ {
+ switch (yyvsp[-1]) {
+
+ case MODE_S:
+ reply(200, "MODE S ok.");
+ break;
+
+ default:
+ reply(502, "Unimplemented MODE type.");
+ }
+ }
+break;
+case 11:
+#line 188 "ftp.y"
+ {
+ reply(202, "ALLO command ignored.");
+ }
+break;
+case 12:
+#line 192 "ftp.y"
+ {
+ reply(202, "ALLO command ignored.");
+ }
+break;
+case 13:
+#line 196 "ftp.y"
+ {
+ if (yyvsp[-3] && yyvsp[-1] != NULL)
+ retrieve((char *) 0, (char *) yyvsp[-1]);
+ if (yyvsp[-1] != NULL)
+ free((char *) yyvsp[-1]);
+ }
+break;
+case 14:
+#line 203 "ftp.y"
+ {
+ if (yyvsp[-3] && yyvsp[-1] != NULL)
+ store((char *) yyvsp[-1], "w", 0);
+ if (yyvsp[-1] != NULL)
+ free((char *) yyvsp[-1]);
+ }
+break;
+case 15:
+#line 210 "ftp.y"
+ {
+ if (yyvsp[-3] && yyvsp[-1] != NULL)
+ store((char *) yyvsp[-1], "a", 0);
+ if (yyvsp[-1] != NULL)
+ free((char *) yyvsp[-1]);
+ }
+break;
+case 16:
+#line 217 "ftp.y"
+ {
+ if (yyvsp[-1])
+ send_file_list(".");
+ }
+break;
+case 17:
+#line 222 "ftp.y"
+ {
+ if (yyvsp[-3] && yyvsp[-1] != NULL)
+ send_file_list((char *) yyvsp[-1]);
+ if (yyvsp[-1] != NULL)
+ free((char *) yyvsp[-1]);
+ }
+break;
+case 18:
+#line 229 "ftp.y"
+ {
+ if (yyvsp[-1])
+ retrieve("/bin/ls -lgA", "");
+ }
+break;
+case 19:
+#line 234 "ftp.y"
+ {
+ if (yyvsp[-3] && yyvsp[-1] != NULL)
+ retrieve("/bin/ls -lgA %s", (char *) yyvsp[-1]);
+ if (yyvsp[-1] != NULL)
+ free((char *) yyvsp[-1]);
+ }
+break;
+case 20:
+#line 241 "ftp.y"
+ {
+ if (yyvsp[-3] && yyvsp[-1] != NULL)
+ statfilecmd((char *) yyvsp[-1]);
+ if (yyvsp[-1] != NULL)
+ free((char *) yyvsp[-1]);
+ }
+break;
+case 21:
+#line 248 "ftp.y"
+ {
+ statcmd();
+ }
+break;
+case 22:
+#line 252 "ftp.y"
+ {
+ if (yyvsp[-3] && yyvsp[-1] != NULL)
+ delete((char *) yyvsp[-1]);
+ if (yyvsp[-1] != NULL)
+ free((char *) yyvsp[-1]);
+ }
+break;
+case 23:
+#line 259 "ftp.y"
+ {
+ if (fromname) {
+ renamecmd(fromname, (char *) yyvsp[-1]);
+ free(fromname);
+ fromname = (char *) 0;
+ } else {
+ reply(503, "Bad sequence of commands.");
+ }
+ free((char *) yyvsp[-1]);
+ }
+break;
+case 24:
+#line 270 "ftp.y"
+ {
+ reply(225, "ABOR command successful.");
+ }
+break;
+case 25:
+#line 274 "ftp.y"
+ {
+ if (yyvsp[-1])
+ cwd(pw->pw_dir);
+ }
+break;
+case 26:
+#line 279 "ftp.y"
+ {
+ if (yyvsp[-3] && yyvsp[-1] != NULL)
+ cwd((char *) yyvsp[-1]);
+ if (yyvsp[-1] != NULL)
+ free((char *) yyvsp[-1]);
+ }
+break;
+case 27:
+#line 286 "ftp.y"
+ {
+ help(cmdtab, (char *) 0);
+ }
+break;
+case 28:
+#line 290 "ftp.y"
+ {
+ register char *cp = (char *)yyvsp[-1];
+
+ if (strncasecmp(cp, "SITE", 4) == 0) {
+ cp = (char *)yyvsp[-1] + 4;
+ if (*cp == ' ')
+ cp++;
+ if (*cp)
+ help(sitetab, cp);
+ else
+ help(sitetab, (char *) 0);
+ } else
+ help(cmdtab, (char *) yyvsp[-1]);
+ }
+break;
+case 29:
+#line 305 "ftp.y"
+ {
+ reply(200, "NOOP command successful.");
+ }
+break;
+case 30:
+#line 309 "ftp.y"
+ {
+ if (yyvsp[-3] && yyvsp[-1] != NULL)
+ makedir((char *) yyvsp[-1]);
+ if (yyvsp[-1] != NULL)
+ free((char *) yyvsp[-1]);
+ }
+break;
+case 31:
+#line 316 "ftp.y"
+ {
+ if (yyvsp[-3] && yyvsp[-1] != NULL)
+ removedir((char *) yyvsp[-1]);
+ if (yyvsp[-1] != NULL)
+ free((char *) yyvsp[-1]);
+ }
+break;
+case 32:
+#line 323 "ftp.y"
+ {
+ if (yyvsp[-1])
+ pwd();
+ }
+break;
+case 33:
+#line 328 "ftp.y"
+ {
+ if (yyvsp[-1])
+ cwd("..");
+ }
+break;
+case 34:
+#line 333 "ftp.y"
+ {
+ help(sitetab, (char *) 0);
+ }
+break;
+case 35:
+#line 337 "ftp.y"
+ {
+ help(sitetab, (char *) yyvsp[-1]);
+ }
+break;
+case 36:
+#line 341 "ftp.y"
+ {
+ int oldmask;
+
+ if (yyvsp[-1]) {
+ oldmask = umask(0);
+ (void) umask(oldmask);
+ reply(200, "Current UMASK is %03o", oldmask);
+ }
+ }
+break;
+case 37:
+#line 351 "ftp.y"
+ {
+ int oldmask;
+
+ if (yyvsp[-3]) {
+ if ((yyvsp[-1] == -1) || (yyvsp[-1] > 0777)) {
+ reply(501, "Bad UMASK value");
+ } else {
+ oldmask = umask(yyvsp[-1]);
+ reply(200,
+ "UMASK set to %03o (was %03o)",
+ yyvsp[-1], oldmask);
+ }
+ }
+ }
+break;
+case 38:
+#line 366 "ftp.y"
+ {
+ if (yyvsp[-5] && (yyvsp[-1] != NULL)) {
+ if (yyvsp[-3] > 0777)
+ reply(501,
+ "CHMOD: Mode value must be between 0 and 0777");
+ else if (chmod((char *) yyvsp[-1], yyvsp[-3]) < 0)
+ perror_reply(550, (char *) yyvsp[-1]);
+ else
+ reply(200, "CHMOD command successful.");
+ }
+ if (yyvsp[-1] != NULL)
+ free((char *) yyvsp[-1]);
+ }
+break;
+case 39:
+#line 380 "ftp.y"
+ {
+ reply(200,
+ "Current IDLE time limit is %d seconds; max %d",
+ timeout, maxtimeout);
+ }
+break;
+case 40:
+#line 386 "ftp.y"
+ {
+ if (yyvsp[-1] < 30 || yyvsp[-1] > maxtimeout) {
+ reply(501,
+ "Maximum IDLE time must be between 30 and %d seconds",
+ maxtimeout);
+ } else {
+ timeout = yyvsp[-1];
+ (void) alarm((unsigned) timeout);
+ reply(200,
+ "Maximum IDLE time set to %d seconds",
+ timeout);
+ }
+ }
+break;
+case 41:
+#line 400 "ftp.y"
+ {
+ if (yyvsp[-3] && yyvsp[-1] != NULL)
+ store((char *) yyvsp[-1], "w", 1);
+ if (yyvsp[-1] != NULL)
+ free((char *) yyvsp[-1]);
+ }
+break;
+case 42:
+#line 407 "ftp.y"
+ {
+#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 */
+ }
+break;
+case 43:
+#line 428 "ftp.y"
+ {
+ if (yyvsp[-3] && yyvsp[-1] != NULL)
+ sizecmd((char *) yyvsp[-1]);
+ if (yyvsp[-1] != NULL)
+ free((char *) yyvsp[-1]);
+ }
+break;
+case 44:
+#line 445 "ftp.y"
+ {
+ if (yyvsp[-3] && yyvsp[-1] != NULL) {
+ struct stat stbuf;
+ if (stat((char *) yyvsp[-1], &stbuf) < 0)
+ perror_reply(550, "%s", (char *) yyvsp[-1]);
+ else if ((stbuf.st_mode&S_IFMT) != S_IFREG) {
+ reply(550, "%s: not a plain file.",
+ (char *) yyvsp[-1]);
+ } 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);
+ }
+ }
+ if (yyvsp[-1] != NULL)
+ free((char *) yyvsp[-1]);
+ }
+break;
+case 45:
+#line 467 "ftp.y"
+ {
+ reply(221, "Goodbye.");
+ dologout(0);
+ }
+break;
+case 46:
+#line 472 "ftp.y"
+ {
+ yyerrok;
+ }
+break;
+case 47:
+#line 477 "ftp.y"
+ {
+ char *renamefrom();
+
+ if (yyvsp[-3] && yyvsp[-1]) {
+ fromname = renamefrom((char *) yyvsp[-1]);
+ if (fromname == (char *) 0 && yyvsp[-1]) {
+ free((char *) yyvsp[-1]);
+ }
+ }
+ }
+break;
+case 49:
+#line 493 "ftp.y"
+ {
+ *(char **)&(yyval) = "";
+ }
+break;
+case 52:
+#line 504 "ftp.y"
+ {
+ register char *a, *p;
+
+ a = (char *)&data_dest.sin_addr;
+ a[0] = yyvsp[-10]; a[1] = yyvsp[-8]; a[2] = yyvsp[-6]; a[3] = yyvsp[-4];
+ p = (char *)&data_dest.sin_port;
+ p[0] = yyvsp[-2]; p[1] = yyvsp[0];
+ data_dest.sin_family = AF_INET;
+ }
+break;
+case 53:
+#line 516 "ftp.y"
+ {
+ yyval = FORM_N;
+ }
+break;
+case 54:
+#line 520 "ftp.y"
+ {
+ yyval = FORM_T;
+ }
+break;
+case 55:
+#line 524 "ftp.y"
+ {
+ yyval = FORM_C;
+ }
+break;
+case 56:
+#line 530 "ftp.y"
+ {
+ cmd_type = TYPE_A;
+ cmd_form = FORM_N;
+ }
+break;
+case 57:
+#line 535 "ftp.y"
+ {
+ cmd_type = TYPE_A;
+ cmd_form = yyvsp[0];
+ }
+break;
+case 58:
+#line 540 "ftp.y"
+ {
+ cmd_type = TYPE_E;
+ cmd_form = FORM_N;
+ }
+break;
+case 59:
+#line 545 "ftp.y"
+ {
+ cmd_type = TYPE_E;
+ cmd_form = yyvsp[0];
+ }
+break;
+case 60:
+#line 550 "ftp.y"
+ {
+ cmd_type = TYPE_I;
+ }
+break;
+case 61:
+#line 554 "ftp.y"
+ {
+ cmd_type = TYPE_L;
+ cmd_bytesz = NBBY;
+ }
+break;
+case 62:
+#line 559 "ftp.y"
+ {
+ cmd_type = TYPE_L;
+ cmd_bytesz = yyvsp[0];
+ }
+break;
+case 63:
+#line 565 "ftp.y"
+ {
+ cmd_type = TYPE_L;
+ cmd_bytesz = yyvsp[0];
+ }
+break;
+case 64:
+#line 572 "ftp.y"
+ {
+ yyval = STRU_F;
+ }
+break;
+case 65:
+#line 576 "ftp.y"
+ {
+ yyval = STRU_R;
+ }
+break;
+case 66:
+#line 580 "ftp.y"
+ {
+ yyval = STRU_P;
+ }
+break;
+case 67:
+#line 586 "ftp.y"
+ {
+ yyval = MODE_S;
+ }
+break;
+case 68:
+#line 590 "ftp.y"
+ {
+ yyval = MODE_B;
+ }
+break;
+case 69:
+#line 594 "ftp.y"
+ {
+ yyval = MODE_C;
+ }
+break;
+case 70:
+#line 600 "ftp.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 && yyvsp[0] && strncmp((char *) yyvsp[0], "~", 1) == 0) {
+ *(char **)&(yyval) = *glob((char *) yyvsp[0]);
+ if (globerr != NULL) {
+ reply(550, globerr);
+ yyval = NULL;
+ }
+ free((char *) yyvsp[0]);
+ } else
+ yyval = yyvsp[0];
+ }
+break;
+case 72:
+#line 622 "ftp.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 = yyvsp[0];
+ multby = 1;
+ ret = 0;
+ while (dec) {
+ digit = dec%10;
+ if (digit > 7) {
+ ret = -1;
+ break;
+ }
+ ret += digit * multby;
+ multby *= 8;
+ dec /= 10;
+ }
+ yyval = ret;
+ }
+break;
+case 73:
+#line 647 "ftp.y"
+ {
+ if (logged_in)
+ yyval = 1;
+ else {
+ reply(530, "Please login with USER and PASS.");
+ yyval = 0;
+ }
+ }
+break;
+#line 1688 "ftp.tab.c"
+ }
+ yyssp -= yym;
+ yystate = *yyssp;
+ yyvsp -= yym;
+ yym = yylhs[yyn];
+ if (yystate == 0 && yym == 0)
+ {
+#if YYDEBUG
+ if (yydebug)
+ printf("%sdebug: after reduction, shifting from state 0 to\
+ state %d\n", YYPREFIX, YYFINAL);
+#endif
+ yystate = YYFINAL;
+ *++yyssp = YYFINAL;
+ *++yyvsp = yyval;
+ if (yychar < 0)
+ {
+ if ((yychar = yylex()) < 0) yychar = 0;
+#if YYDEBUG
+ if (yydebug)
+ {
+ yys = 0;
+ if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
+ if (!yys) yys = "illegal-symbol";
+ printf("%sdebug: state %d, reading %d (%s)\n",
+ YYPREFIX, YYFINAL, yychar, yys);
+ }
+#endif
+ }
+ if (yychar == 0) goto yyaccept;
+ goto yyloop;
+ }
+ if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 &&
+ yyn <= YYTABLESIZE && yycheck[yyn] == yystate)
+ yystate = yytable[yyn];
+ else
+ yystate = yydgoto[yym];
+#if YYDEBUG
+ if (yydebug)
+ printf("%sdebug: after reduction, shifting from state %d \
+to state %d\n", YYPREFIX, *yyssp, yystate);
+#endif
+ if (yyssp >= yyss + yystacksize - 1)
+ {
+ goto yyoverflow;
+ }
+ *++yyssp = yystate;
+ *++yyvsp = yyval;
+ goto yyloop;
+yyoverflow:
+ yyerror("yacc stack overflow");
+yyabort:
+ return (1);
+yyaccept:
+ return (0);
+}
diff --git a/usr.bin/yacc/test/ftp.tab.h b/usr.bin/yacc/test/ftp.tab.h
new file mode 100644
index 0000000..24f0791
--- /dev/null
+++ b/usr.bin/yacc/test/ftp.tab.h
@@ -0,0 +1,63 @@
+#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 LEXERR 319
diff --git a/usr.bin/yacc/test/ftp.y b/usr.bin/yacc/test/ftp.y
new file mode 100644
index 0000000..a9ee9cd
--- /dev/null
+++ b/usr.bin/yacc/test/ftp.y
@@ -0,0 +1,1180 @@
+/*
+ * Copyright (c) 1985, 1988 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.
+ *
+ * @(#)ftpcmd.y 5.20.1.1 (Berkeley) 3/2/89
+ */
+
+/*
+ * Grammar for FTP commands.
+ * See RFC 959.
+ */
+
+%{
+
+#ifndef lint
+static char sccsid[] = "@(#)ftpcmd.y 5.20.1.1 (Berkeley) 3/2/89";
+#endif /* not lint */
+
+#include <sys/param.h>
+#include <sys/socket.h>
+
+#include <netinet/in.h>
+
+#include <arpa/ftp.h>
+
+#include <stdio.h>
+#include <signal.h>
+#include <ctype.h>
+#include <pwd.h>
+#include <setjmp.h>
+#include <syslog.h>
+#include <sys/stat.h>
+#include <time.h>
+
+extern struct sockaddr_in data_dest;
+extern int logged_in;
+extern struct passwd *pw;
+extern int guest;
+extern int logging;
+extern int type;
+extern int form;
+extern int debug;
+extern int timeout;
+extern int maxtimeout;
+extern int pdata;
+extern char hostname[], remotehost[];
+extern char proctitle[];
+extern char *globerr;
+extern int usedefault;
+extern int transflag;
+extern char tmpline[];
+char **glob();
+
+static int cmd_type;
+static int cmd_form;
+static int cmd_bytesz;
+char cbuf[512];
+char *fromname;
+
+char *index();
+%}
+
+%token
+ A B C E F I
+ L N P R S T
+
+ SP CRLF COMMA STRING NUMBER
+
+ USER PASS ACCT REIN QUIT PORT
+ PASV TYPE STRU MODE RETR STOR
+ APPE MLFL MAIL MSND MSOM MSAM
+ MRSQ MRCP ALLO REST RNFR RNTO
+ ABOR DELE CWD LIST NLST SITE
+ STAT HELP NOOP MKD RMD PWD
+ CDUP STOU SMNT SYST SIZE MDTM
+
+ UMASK IDLE CHMOD
+
+ LEXERR
+
+%start cmd_list
+
+%%
+
+cmd_list: /* empty */
+ | cmd_list cmd
+ = {
+ fromname = (char *) 0;
+ }
+ | cmd_list rcmd
+ ;
+
+cmd: USER SP username CRLF
+ = {
+ user((char *) $3);
+ free((char *) $3);
+ }
+ | PASS SP password CRLF
+ = {
+ pass((char *) $3);
+ free((char *) $3);
+ }
+ | PORT SP host_port CRLF
+ = {
+ usedefault = 0;
+ if (pdata >= 0) {
+ (void) close(pdata);
+ pdata = -1;
+ }
+ reply(200, "PORT command successful.");
+ }
+ | PASV CRLF
+ = {
+ passive();
+ }
+ | TYPE SP type_code CRLF
+ = {
+ 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 */
+ }
+ }
+ | STRU SP struct_code CRLF
+ = {
+ switch ($3) {
+
+ case STRU_F:
+ reply(200, "STRU F ok.");
+ break;
+
+ default:
+ reply(504, "Unimplemented STRU type.");
+ }
+ }
+ | MODE SP mode_code CRLF
+ = {
+ switch ($3) {
+
+ case MODE_S:
+ reply(200, "MODE S ok.");
+ break;
+
+ default:
+ reply(502, "Unimplemented MODE type.");
+ }
+ }
+ | ALLO SP NUMBER CRLF
+ = {
+ reply(202, "ALLO command ignored.");
+ }
+ | ALLO SP NUMBER SP R SP NUMBER CRLF
+ = {
+ reply(202, "ALLO command ignored.");
+ }
+ | RETR check_login SP pathname CRLF
+ = {
+ if ($2 && $4 != NULL)
+ retrieve((char *) 0, (char *) $4);
+ if ($4 != NULL)
+ free((char *) $4);
+ }
+ | STOR check_login SP pathname CRLF
+ = {
+ if ($2 && $4 != NULL)
+ store((char *) $4, "w", 0);
+ if ($4 != NULL)
+ free((char *) $4);
+ }
+ | APPE check_login SP pathname CRLF
+ = {
+ if ($2 && $4 != NULL)
+ store((char *) $4, "a", 0);
+ if ($4 != NULL)
+ free((char *) $4);
+ }
+ | NLST check_login CRLF
+ = {
+ if ($2)
+ send_file_list(".");
+ }
+ | NLST check_login SP STRING CRLF
+ = {
+ if ($2 && $4 != NULL)
+ send_file_list((char *) $4);
+ if ($4 != NULL)
+ free((char *) $4);
+ }
+ | LIST check_login CRLF
+ = {
+ if ($2)
+ retrieve("/bin/ls -lgA", "");
+ }
+ | LIST check_login SP pathname CRLF
+ = {
+ if ($2 && $4 != NULL)
+ retrieve("/bin/ls -lgA %s", (char *) $4);
+ if ($4 != NULL)
+ free((char *) $4);
+ }
+ | STAT check_login SP pathname CRLF
+ = {
+ if ($2 && $4 != NULL)
+ statfilecmd((char *) $4);
+ if ($4 != NULL)
+ free((char *) $4);
+ }
+ | STAT CRLF
+ = {
+ statcmd();
+ }
+ | DELE check_login SP pathname CRLF
+ = {
+ if ($2 && $4 != NULL)
+ delete((char *) $4);
+ if ($4 != NULL)
+ free((char *) $4);
+ }
+ | RNTO SP pathname CRLF
+ = {
+ if (fromname) {
+ renamecmd(fromname, (char *) $3);
+ free(fromname);
+ fromname = (char *) 0;
+ } else {
+ reply(503, "Bad sequence of commands.");
+ }
+ free((char *) $3);
+ }
+ | ABOR CRLF
+ = {
+ reply(225, "ABOR command successful.");
+ }
+ | CWD check_login CRLF
+ = {
+ if ($2)
+ cwd(pw->pw_dir);
+ }
+ | CWD check_login SP pathname CRLF
+ = {
+ if ($2 && $4 != NULL)
+ cwd((char *) $4);
+ if ($4 != NULL)
+ free((char *) $4);
+ }
+ | HELP CRLF
+ = {
+ help(cmdtab, (char *) 0);
+ }
+ | HELP SP STRING CRLF
+ = {
+ register char *cp = (char *)$3;
+
+ if (strncasecmp(cp, "SITE", 4) == 0) {
+ cp = (char *)$3 + 4;
+ if (*cp == ' ')
+ cp++;
+ if (*cp)
+ help(sitetab, cp);
+ else
+ help(sitetab, (char *) 0);
+ } else
+ help(cmdtab, (char *) $3);
+ }
+ | NOOP CRLF
+ = {
+ reply(200, "NOOP command successful.");
+ }
+ | MKD check_login SP pathname CRLF
+ = {
+ if ($2 && $4 != NULL)
+ makedir((char *) $4);
+ if ($4 != NULL)
+ free((char *) $4);
+ }
+ | RMD check_login SP pathname CRLF
+ = {
+ if ($2 && $4 != NULL)
+ removedir((char *) $4);
+ if ($4 != NULL)
+ free((char *) $4);
+ }
+ | PWD check_login CRLF
+ = {
+ if ($2)
+ pwd();
+ }
+ | CDUP check_login CRLF
+ = {
+ if ($2)
+ cwd("..");
+ }
+ | SITE SP HELP CRLF
+ = {
+ help(sitetab, (char *) 0);
+ }
+ | SITE SP HELP SP STRING CRLF
+ = {
+ help(sitetab, (char *) $5);
+ }
+ | SITE SP UMASK check_login CRLF
+ = {
+ int oldmask;
+
+ if ($4) {
+ oldmask = umask(0);
+ (void) umask(oldmask);
+ reply(200, "Current UMASK is %03o", oldmask);
+ }
+ }
+ | SITE SP UMASK check_login SP octal_number CRLF
+ = {
+ int oldmask;
+
+ if ($4) {
+ if (($6 == -1) || ($6 > 0777)) {
+ reply(501, "Bad UMASK value");
+ } else {
+ oldmask = umask($6);
+ reply(200,
+ "UMASK set to %03o (was %03o)",
+ $6, oldmask);
+ }
+ }
+ }
+ | 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");
+ else if (chmod((char *) $8, $6) < 0)
+ perror_reply(550, (char *) $8);
+ else
+ reply(200, "CHMOD command successful.");
+ }
+ if ($8 != NULL)
+ free((char *) $8);
+ }
+ | SITE SP IDLE CRLF
+ = {
+ reply(200,
+ "Current IDLE time limit is %d seconds; max %d",
+ timeout, maxtimeout);
+ }
+ | SITE SP IDLE SP NUMBER CRLF
+ = {
+ if ($5 < 30 || $5 > maxtimeout) {
+ reply(501,
+ "Maximum IDLE time must be between 30 and %d seconds",
+ maxtimeout);
+ } else {
+ timeout = $5;
+ (void) alarm((unsigned) timeout);
+ reply(200,
+ "Maximum IDLE time set to %d seconds",
+ timeout);
+ }
+ }
+ | STOU check_login SP pathname CRLF
+ = {
+ if ($2 && $4 != NULL)
+ store((char *) $4, "w", 1);
+ if ($4 != NULL)
+ free((char *) $4);
+ }
+ | SYST CRLF
+ = {
+#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 */
+ }
+
+ /*
+ * SIZE is not in RFC959, but Postel has blessed it and
+ * it will be in the updated RFC.
+ *
+ * Return size of file in a format suitable for
+ * using with RESTART (we just count bytes).
+ */
+ | SIZE check_login SP pathname CRLF
+ = {
+ if ($2 && $4 != NULL)
+ sizecmd((char *) $4);
+ if ($4 != NULL)
+ free((char *) $4);
+ }
+
+ /*
+ * MDTM is not in RFC959, but Postel has blessed it and
+ * it will be in the updated RFC.
+ *
+ * Return modification time of file as an ISO 3307
+ * style time. E.g. YYYYMMDDHHMMSS or YYYYMMDDHHMMSS.xxx
+ * where xxx is the fractional second (of any precision,
+ * not necessarily 3 digits)
+ */
+ | MDTM check_login SP pathname CRLF
+ = {
+ 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);
+ } 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);
+ }
+ }
+ if ($4 != NULL)
+ free((char *) $4);
+ }
+ | QUIT CRLF
+ = {
+ reply(221, "Goodbye.");
+ dologout(0);
+ }
+ | error CRLF
+ = {
+ yyerrok;
+ }
+ ;
+rcmd: RNFR check_login SP pathname CRLF
+ = {
+ char *renamefrom();
+
+ if ($2 && $4) {
+ fromname = renamefrom((char *) $4);
+ if (fromname == (char *) 0 && $4) {
+ free((char *) $4);
+ }
+ }
+ }
+ ;
+
+username: STRING
+ ;
+
+password: /* empty */
+ = {
+ *(char **)&($$) = "";
+ }
+ | STRING
+ ;
+
+byte_size: NUMBER
+ ;
+
+host_port: NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA
+ NUMBER COMMA NUMBER
+ = {
+ register char *a, *p;
+
+ a = (char *)&data_dest.sin_addr;
+ a[0] = $1; a[1] = $3; a[2] = $5; a[3] = $7;
+ p = (char *)&data_dest.sin_port;
+ p[0] = $9; p[1] = $11;
+ data_dest.sin_family = AF_INET;
+ }
+ ;
+
+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;
+ }
+ ;
+
+struct_code: F
+ = {
+ $$ = STRU_F;
+ }
+ | R
+ = {
+ $$ = STRU_R;
+ }
+ | P
+ = {
+ $$ = STRU_P;
+ }
+ ;
+
+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;
+ }
+ ;
+
+pathstring: STRING
+ ;
+
+octal_number: NUMBER
+ = {
+ 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 = $1;
+ multby = 1;
+ ret = 0;
+ while (dec) {
+ digit = dec%10;
+ if (digit > 7) {
+ ret = -1;
+ break;
+ }
+ ret += digit * multby;
+ multby *= 8;
+ dec /= 10;
+ }
+ $$ = ret;
+ }
+ ;
+
+check_login: /* empty */
+ = {
+ if (logged_in)
+ $$ = 1;
+ else {
+ reply(530, "Please login with USER and PASS.");
+ $$ = 0;
+ }
+ }
+ ;
+
+%%
+
+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 */
+
+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, 0, "(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> ]" },
+ { 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 int
+toolong()
+{
+ time_t now;
+ extern char *ctime();
+ extern time_t time();
+
+ 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));
+ }
+ dologout(1);
+}
+
+yylex()
+{
+ static int cpos, state;
+ register char *cp, *cp2;
+ register struct tab *p;
+ int n;
+ char c, *strpbrk();
+ char *copy();
+
+ for (;;) {
+ switch (state) {
+
+ case CMD:
+ (void) signal(SIGALRM, toolong);
+ (void) alarm((unsigned) timeout);
+ 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) != NULL)
+ setproctitle("%s: %s", proctitle, cbuf);
+#endif /* SETPROCTITLE */
+ if ((cp = index(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;
+ *(char **)&yylval = 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;
+ *(char **)&yylval = 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';
+ *(char **)&yylval = 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 = atoi(cp);
+ cbuf[cpos] = c;
+ state = STR1;
+ return (NUMBER);
+ }
+ state = STR1;
+ goto dostr1;
+
+ case ARGS:
+ if (isdigit(cbuf[cpos])) {
+ cp = &cbuf[cpos];
+ while (isdigit(cbuf[++cpos]))
+ ;
+ c = cbuf[cpos];
+ cbuf[cpos] = '\0';
+ yylval = 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 *) 0);
+ 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;
+ extern char *malloc(), *strcpy();
+
+ 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 *)0) {
+ 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, 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]);
+ }
+}
OpenPOWER on IntegriCloud