xref: /original-bsd/usr.bin/yacc/test/ftp.tab.c (revision 1d5f76bd)
1 #ifndef lint
2 static char yysccsid[] = "@(#)yaccpar	1.9 (Berkeley) 02/21/93";
3 #endif
4 #define YYBYACC 1
5 #define YYMAJOR 1
6 #define YYMINOR 9
7 #define yyclearin (yychar=(-1))
8 #define yyerrok (yyerrflag=0)
9 #define YYRECOVERING (yyerrflag!=0)
10 #define YYPREFIX "yy"
11 #line 26 "ftp.y"
12 
13 #ifndef lint
14 static char sccsid[] = "@(#)ftpcmd.y	5.20.1.1 (Berkeley) 3/2/89";
15 #endif /* not lint */
16 
17 #include <sys/param.h>
18 #include <sys/socket.h>
19 
20 #include <netinet/in.h>
21 
22 #include <arpa/ftp.h>
23 
24 #include <stdio.h>
25 #include <signal.h>
26 #include <ctype.h>
27 #include <pwd.h>
28 #include <setjmp.h>
29 #include <syslog.h>
30 #include <sys/stat.h>
31 #include <time.h>
32 
33 extern	struct sockaddr_in data_dest;
34 extern	int logged_in;
35 extern	struct passwd *pw;
36 extern	int guest;
37 extern	int logging;
38 extern	int type;
39 extern	int form;
40 extern	int debug;
41 extern	int timeout;
42 extern	int maxtimeout;
43 extern  int pdata;
44 extern	char hostname[], remotehost[];
45 extern	char proctitle[];
46 extern	char *globerr;
47 extern	int usedefault;
48 extern  int transflag;
49 extern  char tmpline[];
50 char	**glob();
51 
52 static	int cmd_type;
53 static	int cmd_form;
54 static	int cmd_bytesz;
55 char	cbuf[512];
56 char	*fromname;
57 
58 char	*index();
59 #line 60 "ftp.tab.c"
60 #define A 257
61 #define B 258
62 #define C 259
63 #define E 260
64 #define F 261
65 #define I 262
66 #define L 263
67 #define N 264
68 #define P 265
69 #define R 266
70 #define S 267
71 #define T 268
72 #define SP 269
73 #define CRLF 270
74 #define COMMA 271
75 #define STRING 272
76 #define NUMBER 273
77 #define USER 274
78 #define PASS 275
79 #define ACCT 276
80 #define REIN 277
81 #define QUIT 278
82 #define PORT 279
83 #define PASV 280
84 #define TYPE 281
85 #define STRU 282
86 #define MODE 283
87 #define RETR 284
88 #define STOR 285
89 #define APPE 286
90 #define MLFL 287
91 #define MAIL 288
92 #define MSND 289
93 #define MSOM 290
94 #define MSAM 291
95 #define MRSQ 292
96 #define MRCP 293
97 #define ALLO 294
98 #define REST 295
99 #define RNFR 296
100 #define RNTO 297
101 #define ABOR 298
102 #define DELE 299
103 #define CWD 300
104 #define LIST 301
105 #define NLST 302
106 #define SITE 303
107 #define STAT 304
108 #define HELP 305
109 #define NOOP 306
110 #define MKD 307
111 #define RMD 308
112 #define PWD 309
113 #define CDUP 310
114 #define STOU 311
115 #define SMNT 312
116 #define SYST 313
117 #define SIZE 314
118 #define MDTM 315
119 #define UMASK 316
120 #define IDLE 317
121 #define CHMOD 318
122 #define LEXERR 319
123 #define YYERRCODE 256
124 short yylhs[] = {                                        -1,
125     0,    0,    0,    1,    1,    1,    1,    1,    1,    1,
126     1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
127     1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
128     1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
129     1,    1,    1,    1,    1,    1,    2,    3,    4,    4,
130    12,    5,   13,   13,   13,    6,    6,    6,    6,    6,
131     6,    6,    6,    7,    7,    7,    8,    8,    8,   10,
132    14,   11,    9,
133 };
134 short yylen[] = {                                         2,
135     0,    2,    2,    4,    4,    4,    2,    4,    4,    4,
136     4,    8,    5,    5,    5,    3,    5,    3,    5,    5,
137     2,    5,    4,    2,    3,    5,    2,    4,    2,    5,
138     5,    3,    3,    4,    6,    5,    7,    9,    4,    6,
139     5,    2,    5,    5,    2,    2,    5,    1,    0,    1,
140     1,   11,    1,    1,    1,    1,    3,    1,    3,    1,
141     1,    3,    2,    1,    1,    1,    1,    1,    1,    1,
142     1,    1,    0,
143 };
144 short yydefred[] = {                                      1,
145     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
146    73,   73,   73,    0,   73,    0,    0,   73,   73,   73,
147    73,    0,    0,    0,    0,   73,   73,   73,   73,   73,
148     0,   73,   73,    2,    3,   46,    0,    0,   45,    0,
149     7,    0,    0,    0,    0,    0,    0,    0,    0,    0,
150    24,    0,    0,    0,    0,    0,   21,    0,    0,   27,
151    29,    0,    0,    0,    0,    0,   42,    0,    0,   48,
152     0,   50,    0,    0,    0,    0,    0,   60,    0,    0,
153    64,   66,   65,    0,   68,   69,   67,    0,    0,    0,
154     0,    0,    0,   71,    0,   70,    0,    0,   25,    0,
155    18,    0,   16,    0,   73,    0,   73,    0,    0,    0,
156     0,   32,   33,    0,    0,    0,    4,    5,    0,    6,
157     0,    0,    0,   51,   63,    8,    9,   10,    0,    0,
158     0,    0,   11,    0,   23,    0,    0,    0,    0,    0,
159    34,    0,    0,   39,    0,    0,   28,    0,    0,    0,
160     0,    0,    0,   55,   53,   54,   57,   59,   62,   13,
161    14,   15,    0,   47,   22,   26,   19,   17,    0,    0,
162    36,    0,    0,   20,   30,   31,   41,   43,   44,    0,
163     0,   35,   72,    0,   40,    0,    0,    0,   37,    0,
164     0,   12,    0,    0,   38,    0,    0,    0,   52,
165 };
166 short yydgoto[] = {                                       1,
167    34,   35,   71,   73,   75,   80,   84,   88,   45,   95,
168   184,  125,  157,   96,
169 };
170 short yysindex[] = {                                      0,
171  -224, -247, -239, -236, -232, -222, -204, -200, -181, -177,
172     0,    0,    0, -166,    0, -161, -199,    0,    0,    0,
173     0, -160, -159, -264, -158,    0,    0,    0,    0,    0,
174  -157,    0,    0,    0,    0,    0, -167, -162,    0, -156,
175     0, -250, -198, -165, -155, -154, -153, -151, -150, -152,
176     0, -145, -252, -229, -217, -302,    0, -144, -146,    0,
177     0, -142, -141, -140, -139, -137,    0, -136, -135,    0,
178  -134,    0, -133, -132, -130, -131, -128,    0, -249, -127,
179     0,    0,    0, -126,    0,    0,    0, -125, -152, -152,
180  -152, -205, -152,    0, -124,    0, -152, -152,    0, -152,
181     0, -143,    0, -173,    0, -171,    0, -152, -123, -152,
182  -152,    0,    0, -152, -152, -152,    0,    0, -138,    0,
183  -164, -164, -122,    0,    0,    0,    0,    0, -121, -120,
184  -118, -148,    0, -117,    0, -116, -115, -114, -113, -112,
185     0, -163, -111,    0, -110, -109,    0, -107, -106, -105,
186  -104, -103, -129,    0,    0,    0,    0,    0,    0,    0,
187     0,    0, -101,    0,    0,    0,    0,    0, -100, -102,
188     0,  -98, -102,    0,    0,    0,    0,    0,    0,  -99,
189   -97,    0,    0,  -95,    0,  -96,  -94,  -92,    0, -152,
190   -93,    0,  -91,  -90,    0,  -88,  -87,  -86,    0,
191 };
192 short yyrindex[] = {                                      0,
193     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
194     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
195     0,    0,  -83,    0,    0,    0,    0,    0,    0,    0,
196     0,    0,    0,    0,    0,    0,    0,  -82,    0,    0,
197     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
198     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
199     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
200     0,    0,    0,    0,    0,  -81,  -80,    0, -158,    0,
201     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
202     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
203     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
204     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
205     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
206     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
207     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
208     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
209     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
210     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
211     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
212     0,    0,    0,    0,    0,    0,    0,    0,    0,
213 };
214 short yygindex[] = {                                      0,
215     0,    0,    0,    0,    0,    0,    0,    0,   16,  -89,
216   -25,   35,   47,    0,
217 };
218 #define YYTABLESIZE 190
219 short yytable[] = {                                     129,
220   130,  131,  104,  134,   59,   60,   76,  136,  137,   77,
221   138,   78,   79,  105,  106,  107,   98,   99,  146,  123,
222   148,  149,   36,  124,  150,  151,  152,   46,   47,   37,
223    49,    2,   38,   52,   53,   54,   55,   39,   58,  100,
224   101,   62,   63,   64,   65,   66,   40,   68,   69,    3,
225     4,  102,  103,    5,    6,    7,    8,    9,   10,   11,
226    12,   13,   81,  132,  133,   41,   82,   83,   42,   14,
227    51,   15,   16,   17,   18,   19,   20,   21,   22,   23,
228    24,   25,   26,   27,   28,   29,   30,   43,   31,   32,
229    33,   44,   85,   86,  154,  140,  141,  143,  144,  155,
230   193,   87,   48,  156,   70,  170,  171,   50,   56,   72,
231    57,   61,   67,   89,   90,   91,   74,  163,   93,   94,
232   142,   92,  145,   97,  108,  109,  110,  111,  139,  112,
233   113,  114,  115,  116,  153,  117,  118,  121,  119,  120,
234   122,  180,  126,  127,  128,  135,  147,  186,  160,  161,
235   124,  162,  164,  165,  166,  167,  168,  159,  173,  169,
236   174,  172,  175,  176,  177,  178,  179,  181,  158,  182,
237   183,  185,  190,  187,  189,  188,  191,  192,  195,  194,
238   196,    0,    0,  198,  197,   73,  199,   49,   56,   58,
239 };
240 short yycheck[] = {                                      89,
241    90,   91,  305,   93,  269,  270,  257,   97,   98,  260,
242   100,  262,  263,  316,  317,  318,  269,  270,  108,  269,
243   110,  111,  270,  273,  114,  115,  116,   12,   13,  269,
244    15,  256,  269,   18,   19,   20,   21,  270,   23,  269,
245   270,   26,   27,   28,   29,   30,  269,   32,   33,  274,
246   275,  269,  270,  278,  279,  280,  281,  282,  283,  284,
247   285,  286,  261,  269,  270,  270,  265,  266,  269,  294,
248   270,  296,  297,  298,  299,  300,  301,  302,  303,  304,
249   305,  306,  307,  308,  309,  310,  311,  269,  313,  314,
250   315,  269,  258,  259,  259,  269,  270,  269,  270,  264,
251   190,  267,  269,  268,  272,  269,  270,  269,  269,  272,
252   270,  270,  270,  269,  269,  269,  273,  266,  269,  272,
253   105,  273,  107,  269,  269,  272,  269,  269,  272,  270,
254   270,  269,  269,  269,  273,  270,  270,  269,  271,  270,
255   269,  271,  270,  270,  270,  270,  270,  173,  270,  270,
256   273,  270,  270,  270,  270,  270,  270,  123,  269,  272,
257   270,  273,  270,  270,  270,  270,  270,  269,  122,  270,
258   273,  270,  269,  273,  270,  273,  271,  270,  270,  273,
259   271,   -1,   -1,  271,  273,  269,  273,  270,  270,  270,
260 };
261 #define YYFINAL 1
262 #ifndef YYDEBUG
263 #define YYDEBUG 0
264 #endif
265 #define YYMAXTOKEN 319
266 #if YYDEBUG
267 char *yyname[] = {
268 "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,
269 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
270 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
271 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
272 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
273 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
274 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",
275 "P","R","S","T","SP","CRLF","COMMA","STRING","NUMBER","USER","PASS","ACCT",
276 "REIN","QUIT","PORT","PASV","TYPE","STRU","MODE","RETR","STOR","APPE","MLFL",
277 "MAIL","MSND","MSOM","MSAM","MRSQ","MRCP","ALLO","REST","RNFR","RNTO","ABOR",
278 "DELE","CWD","LIST","NLST","SITE","STAT","HELP","NOOP","MKD","RMD","PWD","CDUP",
279 "STOU","SMNT","SYST","SIZE","MDTM","UMASK","IDLE","CHMOD","LEXERR",
280 };
281 char *yyrule[] = {
282 "$accept : cmd_list",
283 "cmd_list :",
284 "cmd_list : cmd_list cmd",
285 "cmd_list : cmd_list rcmd",
286 "cmd : USER SP username CRLF",
287 "cmd : PASS SP password CRLF",
288 "cmd : PORT SP host_port CRLF",
289 "cmd : PASV CRLF",
290 "cmd : TYPE SP type_code CRLF",
291 "cmd : STRU SP struct_code CRLF",
292 "cmd : MODE SP mode_code CRLF",
293 "cmd : ALLO SP NUMBER CRLF",
294 "cmd : ALLO SP NUMBER SP R SP NUMBER CRLF",
295 "cmd : RETR check_login SP pathname CRLF",
296 "cmd : STOR check_login SP pathname CRLF",
297 "cmd : APPE check_login SP pathname CRLF",
298 "cmd : NLST check_login CRLF",
299 "cmd : NLST check_login SP STRING CRLF",
300 "cmd : LIST check_login CRLF",
301 "cmd : LIST check_login SP pathname CRLF",
302 "cmd : STAT check_login SP pathname CRLF",
303 "cmd : STAT CRLF",
304 "cmd : DELE check_login SP pathname CRLF",
305 "cmd : RNTO SP pathname CRLF",
306 "cmd : ABOR CRLF",
307 "cmd : CWD check_login CRLF",
308 "cmd : CWD check_login SP pathname CRLF",
309 "cmd : HELP CRLF",
310 "cmd : HELP SP STRING CRLF",
311 "cmd : NOOP CRLF",
312 "cmd : MKD check_login SP pathname CRLF",
313 "cmd : RMD check_login SP pathname CRLF",
314 "cmd : PWD check_login CRLF",
315 "cmd : CDUP check_login CRLF",
316 "cmd : SITE SP HELP CRLF",
317 "cmd : SITE SP HELP SP STRING CRLF",
318 "cmd : SITE SP UMASK check_login CRLF",
319 "cmd : SITE SP UMASK check_login SP octal_number CRLF",
320 "cmd : SITE SP CHMOD check_login SP octal_number SP pathname CRLF",
321 "cmd : SITE SP IDLE CRLF",
322 "cmd : SITE SP IDLE SP NUMBER CRLF",
323 "cmd : STOU check_login SP pathname CRLF",
324 "cmd : SYST CRLF",
325 "cmd : SIZE check_login SP pathname CRLF",
326 "cmd : MDTM check_login SP pathname CRLF",
327 "cmd : QUIT CRLF",
328 "cmd : error CRLF",
329 "rcmd : RNFR check_login SP pathname CRLF",
330 "username : STRING",
331 "password :",
332 "password : STRING",
333 "byte_size : NUMBER",
334 "host_port : NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER",
335 "form_code : N",
336 "form_code : T",
337 "form_code : C",
338 "type_code : A",
339 "type_code : A SP form_code",
340 "type_code : E",
341 "type_code : E SP form_code",
342 "type_code : I",
343 "type_code : L",
344 "type_code : L SP byte_size",
345 "type_code : L byte_size",
346 "struct_code : F",
347 "struct_code : R",
348 "struct_code : P",
349 "mode_code : S",
350 "mode_code : B",
351 "mode_code : C",
352 "pathname : pathstring",
353 "pathstring : STRING",
354 "octal_number : NUMBER",
355 "check_login :",
356 };
357 #endif
358 #ifndef YYSTYPE
359 typedef int YYSTYPE;
360 #endif
361 #ifdef YYSTACKSIZE
362 #undef YYMAXDEPTH
363 #define YYMAXDEPTH YYSTACKSIZE
364 #else
365 #ifdef YYMAXDEPTH
366 #define YYSTACKSIZE YYMAXDEPTH
367 #else
368 #define YYSTACKSIZE 500
369 #define YYMAXDEPTH 500
370 #endif
371 #endif
372 int yydebug;
373 int yynerrs;
374 int yyerrflag;
375 int yychar;
376 short *yyssp;
377 YYSTYPE *yyvsp;
378 YYSTYPE yyval;
379 YYSTYPE yylval;
380 short yyss[YYSTACKSIZE];
381 YYSTYPE yyvs[YYSTACKSIZE];
382 #define yystacksize YYSTACKSIZE
383 #line 658 "ftp.y"
384 
385 extern jmp_buf errcatch;
386 
387 #define	CMD	0	/* beginning of command */
388 #define	ARGS	1	/* expect miscellaneous arguments */
389 #define	STR1	2	/* expect SP followed by STRING */
390 #define	STR2	3	/* expect STRING */
391 #define	OSTR	4	/* optional SP then STRING */
392 #define	ZSTR1	5	/* SP then optional STRING */
393 #define	ZSTR2	6	/* optional STRING after SP */
394 #define	SITECMD	7	/* SITE command */
395 #define	NSTR	8	/* Number followed by a string */
396 
397 struct tab {
398 	char	*name;
399 	short	token;
400 	short	state;
401 	short	implemented;	/* 1 if command is implemented */
402 	char	*help;
403 };
404 
405 struct tab cmdtab[] = {		/* In order defined in RFC 765 */
406 	{ "USER", USER, STR1, 1,	"<sp> username" },
407 	{ "PASS", PASS, ZSTR1, 1,	"<sp> password" },
408 	{ "ACCT", ACCT, STR1, 0,	"(specify account)" },
409 	{ "SMNT", SMNT, ARGS, 0,	"(structure mount)" },
410 	{ "REIN", REIN, ARGS, 0,	"(reinitialize server state)" },
411 	{ "QUIT", QUIT, ARGS, 1,	"(terminate service)", },
412 	{ "PORT", PORT, ARGS, 1,	"<sp> b0, b1, b2, b3, b4" },
413 	{ "PASV", PASV, ARGS, 1,	"(set server in passive mode)" },
414 	{ "TYPE", TYPE, ARGS, 1,	"<sp> [ A | E | I | L ]" },
415 	{ "STRU", STRU, ARGS, 1,	"(specify file structure)" },
416 	{ "MODE", MODE, ARGS, 1,	"(specify transfer mode)" },
417 	{ "RETR", RETR, STR1, 1,	"<sp> file-name" },
418 	{ "STOR", STOR, STR1, 1,	"<sp> file-name" },
419 	{ "APPE", APPE, STR1, 1,	"<sp> file-name" },
420 	{ "MLFL", MLFL, OSTR, 0,	"(mail file)" },
421 	{ "MAIL", MAIL, OSTR, 0,	"(mail to user)" },
422 	{ "MSND", MSND, OSTR, 0,	"(mail send to terminal)" },
423 	{ "MSOM", MSOM, OSTR, 0,	"(mail send to terminal or mailbox)" },
424 	{ "MSAM", MSAM, OSTR, 0,	"(mail send to terminal and mailbox)" },
425 	{ "MRSQ", MRSQ, OSTR, 0,	"(mail recipient scheme question)" },
426 	{ "MRCP", MRCP, STR1, 0,	"(mail recipient)" },
427 	{ "ALLO", ALLO, ARGS, 1,	"allocate storage (vacuously)" },
428 	{ "REST", REST, ARGS, 0,	"(restart command)" },
429 	{ "RNFR", RNFR, STR1, 1,	"<sp> file-name" },
430 	{ "RNTO", RNTO, STR1, 1,	"<sp> file-name" },
431 	{ "ABOR", ABOR, ARGS, 1,	"(abort operation)" },
432 	{ "DELE", DELE, STR1, 1,	"<sp> file-name" },
433 	{ "CWD",  CWD,  OSTR, 1,	"[ <sp> directory-name ]" },
434 	{ "XCWD", CWD,	OSTR, 1,	"[ <sp> directory-name ]" },
435 	{ "LIST", LIST, OSTR, 1,	"[ <sp> path-name ]" },
436 	{ "NLST", NLST, OSTR, 1,	"[ <sp> path-name ]" },
437 	{ "SITE", SITE, SITECMD, 1,	"site-cmd [ <sp> arguments ]" },
438 	{ "SYST", SYST, ARGS, 1,	"(get type of operating system)" },
439 	{ "STAT", STAT, OSTR, 1,	"[ <sp> path-name ]" },
440 	{ "HELP", HELP, OSTR, 1,	"[ <sp> <string> ]" },
441 	{ "NOOP", NOOP, ARGS, 1,	"" },
442 	{ "MKD",  MKD,  STR1, 1,	"<sp> path-name" },
443 	{ "XMKD", MKD,  STR1, 1,	"<sp> path-name" },
444 	{ "RMD",  RMD,  STR1, 1,	"<sp> path-name" },
445 	{ "XRMD", RMD,  STR1, 1,	"<sp> path-name" },
446 	{ "PWD",  PWD,  ARGS, 1,	"(return current directory)" },
447 	{ "XPWD", PWD,  ARGS, 1,	"(return current directory)" },
448 	{ "CDUP", CDUP, ARGS, 1,	"(change to parent directory)" },
449 	{ "XCUP", CDUP, ARGS, 1,	"(change to parent directory)" },
450 	{ "STOU", STOU, STR1, 1,	"<sp> file-name" },
451 	{ "SIZE", SIZE, OSTR, 1,	"<sp> path-name" },
452 	{ "MDTM", MDTM, OSTR, 1,	"<sp> path-name" },
453 	{ NULL,   0,    0,    0,	0 }
454 };
455 
456 struct tab sitetab[] = {
457 	{ "UMASK", UMASK, ARGS, 1,	"[ <sp> umask ]" },
458 	{ "IDLE", IDLE, ARGS, 1,	"[ <sp> maximum-idle-time ]" },
459 	{ "CHMOD", CHMOD, NSTR, 1,	"<sp> mode <sp> file-name" },
460 	{ "HELP", HELP, OSTR, 1,	"[ <sp> <string> ]" },
461 	{ NULL,   0,    0,    0,	0 }
462 };
463 
464 struct tab *
465 lookup(p, cmd)
466 	register struct tab *p;
467 	char *cmd;
468 {
469 
470 	for (; p->name != NULL; p++)
471 		if (strcmp(cmd, p->name) == 0)
472 			return (p);
473 	return (0);
474 }
475 
476 #include <arpa/telnet.h>
477 
478 /*
479  * getline - a hacked up version of fgets to ignore TELNET escape codes.
480  */
481 char *
482 getline(s, n, iop)
483 	char *s;
484 	register FILE *iop;
485 {
486 	register c;
487 	register char *cs;
488 
489 	cs = s;
490 /* tmpline may contain saved command from urgent mode interruption */
491 	for (c = 0; tmpline[c] != '\0' && --n > 0; ++c) {
492 		*cs++ = tmpline[c];
493 		if (tmpline[c] == '\n') {
494 			*cs++ = '\0';
495 			if (debug)
496 				syslog(LOG_DEBUG, "command: %s", s);
497 			tmpline[0] = '\0';
498 			return(s);
499 		}
500 		if (c == 0)
501 			tmpline[0] = '\0';
502 	}
503 	while ((c = getc(iop)) != EOF) {
504 		c &= 0377;
505 		if (c == IAC) {
506 		    if ((c = getc(iop)) != EOF) {
507 			c &= 0377;
508 			switch (c) {
509 			case WILL:
510 			case WONT:
511 				c = getc(iop);
512 				printf("%c%c%c", IAC, DONT, 0377&c);
513 				(void) fflush(stdout);
514 				continue;
515 			case DO:
516 			case DONT:
517 				c = getc(iop);
518 				printf("%c%c%c", IAC, WONT, 0377&c);
519 				(void) fflush(stdout);
520 				continue;
521 			case IAC:
522 				break;
523 			default:
524 				continue;	/* ignore command */
525 			}
526 		    }
527 		}
528 		*cs++ = c;
529 		if (--n <= 0 || c == '\n')
530 			break;
531 	}
532 	if (c == EOF && cs == s)
533 		return (NULL);
534 	*cs++ = '\0';
535 	if (debug)
536 		syslog(LOG_DEBUG, "command: %s", s);
537 	return (s);
538 }
539 
540 static int
541 toolong()
542 {
543 	time_t now;
544 	extern char *ctime();
545 	extern time_t time();
546 
547 	reply(421,
548 	  "Timeout (%d seconds): closing control connection.", timeout);
549 	(void) time(&now);
550 	if (logging) {
551 		syslog(LOG_INFO,
552 			"User %s timed out after %d seconds at %s",
553 			(pw ? pw -> pw_name : "unknown"), timeout, ctime(&now));
554 	}
555 	dologout(1);
556 }
557 
558 yylex()
559 {
560 	static int cpos, state;
561 	register char *cp, *cp2;
562 	register struct tab *p;
563 	int n;
564 	char c, *strpbrk();
565 	char *copy();
566 
567 	for (;;) {
568 		switch (state) {
569 
570 		case CMD:
571 			(void) signal(SIGALRM, toolong);
572 			(void) alarm((unsigned) timeout);
573 			if (getline(cbuf, sizeof(cbuf)-1, stdin) == NULL) {
574 				reply(221, "You could at least say goodbye.");
575 				dologout(0);
576 			}
577 			(void) alarm(0);
578 #ifdef SETPROCTITLE
579 			if (strncasecmp(cbuf, "PASS", 4) != NULL)
580 				setproctitle("%s: %s", proctitle, cbuf);
581 #endif /* SETPROCTITLE */
582 			if ((cp = index(cbuf, '\r'))) {
583 				*cp++ = '\n';
584 				*cp = '\0';
585 			}
586 			if ((cp = strpbrk(cbuf, " \n")))
587 				cpos = cp - cbuf;
588 			if (cpos == 0)
589 				cpos = 4;
590 			c = cbuf[cpos];
591 			cbuf[cpos] = '\0';
592 			upper(cbuf);
593 			p = lookup(cmdtab, cbuf);
594 			cbuf[cpos] = c;
595 			if (p != 0) {
596 				if (p->implemented == 0) {
597 					nack(p->name);
598 					longjmp(errcatch,0);
599 					/* NOTREACHED */
600 				}
601 				state = p->state;
602 				*(char **)&yylval = p->name;
603 				return (p->token);
604 			}
605 			break;
606 
607 		case SITECMD:
608 			if (cbuf[cpos] == ' ') {
609 				cpos++;
610 				return (SP);
611 			}
612 			cp = &cbuf[cpos];
613 			if ((cp2 = strpbrk(cp, " \n")))
614 				cpos = cp2 - cbuf;
615 			c = cbuf[cpos];
616 			cbuf[cpos] = '\0';
617 			upper(cp);
618 			p = lookup(sitetab, cp);
619 			cbuf[cpos] = c;
620 			if (p != 0) {
621 				if (p->implemented == 0) {
622 					state = CMD;
623 					nack(p->name);
624 					longjmp(errcatch,0);
625 					/* NOTREACHED */
626 				}
627 				state = p->state;
628 				*(char **)&yylval = p->name;
629 				return (p->token);
630 			}
631 			state = CMD;
632 			break;
633 
634 		case OSTR:
635 			if (cbuf[cpos] == '\n') {
636 				state = CMD;
637 				return (CRLF);
638 			}
639 			/* FALLTHROUGH */
640 
641 		case STR1:
642 		case ZSTR1:
643 		dostr1:
644 			if (cbuf[cpos] == ' ') {
645 				cpos++;
646 				state = state == OSTR ? STR2 : ++state;
647 				return (SP);
648 			}
649 			break;
650 
651 		case ZSTR2:
652 			if (cbuf[cpos] == '\n') {
653 				state = CMD;
654 				return (CRLF);
655 			}
656 			/* FALLTHROUGH */
657 
658 		case STR2:
659 			cp = &cbuf[cpos];
660 			n = strlen(cp);
661 			cpos += n - 1;
662 			/*
663 			 * Make sure the string is nonempty and \n terminated.
664 			 */
665 			if (n > 1 && cbuf[cpos] == '\n') {
666 				cbuf[cpos] = '\0';
667 				*(char **)&yylval = copy(cp);
668 				cbuf[cpos] = '\n';
669 				state = ARGS;
670 				return (STRING);
671 			}
672 			break;
673 
674 		case NSTR:
675 			if (cbuf[cpos] == ' ') {
676 				cpos++;
677 				return (SP);
678 			}
679 			if (isdigit(cbuf[cpos])) {
680 				cp = &cbuf[cpos];
681 				while (isdigit(cbuf[++cpos]))
682 					;
683 				c = cbuf[cpos];
684 				cbuf[cpos] = '\0';
685 				yylval = atoi(cp);
686 				cbuf[cpos] = c;
687 				state = STR1;
688 				return (NUMBER);
689 			}
690 			state = STR1;
691 			goto dostr1;
692 
693 		case ARGS:
694 			if (isdigit(cbuf[cpos])) {
695 				cp = &cbuf[cpos];
696 				while (isdigit(cbuf[++cpos]))
697 					;
698 				c = cbuf[cpos];
699 				cbuf[cpos] = '\0';
700 				yylval = atoi(cp);
701 				cbuf[cpos] = c;
702 				return (NUMBER);
703 			}
704 			switch (cbuf[cpos++]) {
705 
706 			case '\n':
707 				state = CMD;
708 				return (CRLF);
709 
710 			case ' ':
711 				return (SP);
712 
713 			case ',':
714 				return (COMMA);
715 
716 			case 'A':
717 			case 'a':
718 				return (A);
719 
720 			case 'B':
721 			case 'b':
722 				return (B);
723 
724 			case 'C':
725 			case 'c':
726 				return (C);
727 
728 			case 'E':
729 			case 'e':
730 				return (E);
731 
732 			case 'F':
733 			case 'f':
734 				return (F);
735 
736 			case 'I':
737 			case 'i':
738 				return (I);
739 
740 			case 'L':
741 			case 'l':
742 				return (L);
743 
744 			case 'N':
745 			case 'n':
746 				return (N);
747 
748 			case 'P':
749 			case 'p':
750 				return (P);
751 
752 			case 'R':
753 			case 'r':
754 				return (R);
755 
756 			case 'S':
757 			case 's':
758 				return (S);
759 
760 			case 'T':
761 			case 't':
762 				return (T);
763 
764 			}
765 			break;
766 
767 		default:
768 			fatal("Unknown state in scanner.");
769 		}
770 		yyerror((char *) 0);
771 		state = CMD;
772 		longjmp(errcatch,0);
773 	}
774 }
775 
776 upper(s)
777 	register char *s;
778 {
779 	while (*s != '\0') {
780 		if (islower(*s))
781 			*s = toupper(*s);
782 		s++;
783 	}
784 }
785 
786 char *
787 copy(s)
788 	char *s;
789 {
790 	char *p;
791 	extern char *malloc(), *strcpy();
792 
793 	p = malloc((unsigned) strlen(s) + 1);
794 	if (p == NULL)
795 		fatal("Ran out of memory.");
796 	(void) strcpy(p, s);
797 	return (p);
798 }
799 
800 help(ctab, s)
801 	struct tab *ctab;
802 	char *s;
803 {
804 	register struct tab *c;
805 	register int width, NCMDS;
806 	char *type;
807 
808 	if (ctab == sitetab)
809 		type = "SITE ";
810 	else
811 		type = "";
812 	width = 0, NCMDS = 0;
813 	for (c = ctab; c->name != NULL; c++) {
814 		int len = strlen(c->name);
815 
816 		if (len > width)
817 			width = len;
818 		NCMDS++;
819 	}
820 	width = (width + 8) &~ 7;
821 	if (s == 0) {
822 		register int i, j, w;
823 		int columns, lines;
824 
825 		lreply(214, "The following %scommands are recognized %s.",
826 		    type, "(* =>'s unimplemented)");
827 		columns = 76 / width;
828 		if (columns == 0)
829 			columns = 1;
830 		lines = (NCMDS + columns - 1) / columns;
831 		for (i = 0; i < lines; i++) {
832 			printf("   ");
833 			for (j = 0; j < columns; j++) {
834 				c = ctab + j * lines + i;
835 				printf("%s%c", c->name,
836 					c->implemented ? ' ' : '*');
837 				if (c + lines >= &ctab[NCMDS])
838 					break;
839 				w = strlen(c->name) + 1;
840 				while (w < width) {
841 					putchar(' ');
842 					w++;
843 				}
844 			}
845 			printf("\r\n");
846 		}
847 		(void) fflush(stdout);
848 		reply(214, "Direct comments to ftp-bugs@%s.", hostname);
849 		return;
850 	}
851 	upper(s);
852 	c = lookup(ctab, s);
853 	if (c == (struct tab *)0) {
854 		reply(502, "Unknown command %s.", s);
855 		return;
856 	}
857 	if (c->implemented)
858 		reply(214, "Syntax: %s%s %s", type, c->name, c->help);
859 	else
860 		reply(214, "%s%-*s\t%s; unimplemented.", type, width,
861 		    c->name, c->help);
862 }
863 
864 sizecmd(filename)
865 char *filename;
866 {
867 	switch (type) {
868 	case TYPE_L:
869 	case TYPE_I: {
870 		struct stat stbuf;
871 		if (stat(filename, &stbuf) < 0 ||
872 		    (stbuf.st_mode&S_IFMT) != S_IFREG)
873 			reply(550, "%s: not a plain file.", filename);
874 		else
875 			reply(213, "%lu", stbuf.st_size);
876 		break;}
877 	case TYPE_A: {
878 		FILE *fin;
879 		register int c, count;
880 		struct stat stbuf;
881 		fin = fopen(filename, "r");
882 		if (fin == NULL) {
883 			perror_reply(550, filename);
884 			return;
885 		}
886 		if (fstat(fileno(fin), &stbuf) < 0 ||
887 		    (stbuf.st_mode&S_IFMT) != S_IFREG) {
888 			reply(550, "%s: not a plain file.", filename);
889 			(void) fclose(fin);
890 			return;
891 		}
892 
893 		count = 0;
894 		while((c=getc(fin)) != EOF) {
895 			if (c == '\n')	/* will get expanded to \r\n */
896 				count++;
897 			count++;
898 		}
899 		(void) fclose(fin);
900 
901 		reply(213, "%ld", count);
902 		break;}
903 	default:
904 		reply(504, "SIZE not implemented for Type %c.", "?AEIL"[type]);
905 	}
906 }
907 #line 908 "ftp.tab.c"
908 #define YYABORT goto yyabort
909 #define YYREJECT goto yyabort
910 #define YYACCEPT goto yyaccept
911 #define YYERROR goto yyerrlab
912 int
913 yyparse()
914 {
915     register int yym, yyn, yystate;
916 #if YYDEBUG
917     register char *yys;
918     extern char *getenv();
919 
920     if (yys = getenv("YYDEBUG"))
921     {
922         yyn = *yys;
923         if (yyn >= '0' && yyn <= '9')
924             yydebug = yyn - '0';
925     }
926 #endif
927 
928     yynerrs = 0;
929     yyerrflag = 0;
930     yychar = (-1);
931 
932     yyssp = yyss;
933     yyvsp = yyvs;
934     *yyssp = yystate = 0;
935 
936 yyloop:
937     if (yyn = yydefred[yystate]) goto yyreduce;
938     if (yychar < 0)
939     {
940         if ((yychar = yylex()) < 0) yychar = 0;
941 #if YYDEBUG
942         if (yydebug)
943         {
944             yys = 0;
945             if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
946             if (!yys) yys = "illegal-symbol";
947             printf("%sdebug: state %d, reading %d (%s)\n",
948                     YYPREFIX, yystate, yychar, yys);
949         }
950 #endif
951     }
952     if ((yyn = yysindex[yystate]) && (yyn += yychar) >= 0 &&
953             yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
954     {
955 #if YYDEBUG
956         if (yydebug)
957             printf("%sdebug: state %d, shifting to state %d\n",
958                     YYPREFIX, yystate, yytable[yyn]);
959 #endif
960         if (yyssp >= yyss + yystacksize - 1)
961         {
962             goto yyoverflow;
963         }
964         *++yyssp = yystate = yytable[yyn];
965         *++yyvsp = yylval;
966         yychar = (-1);
967         if (yyerrflag > 0)  --yyerrflag;
968         goto yyloop;
969     }
970     if ((yyn = yyrindex[yystate]) && (yyn += yychar) >= 0 &&
971             yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
972     {
973         yyn = yytable[yyn];
974         goto yyreduce;
975     }
976     if (yyerrflag) goto yyinrecovery;
977 #ifdef lint
978     goto yynewerror;
979 #endif
980 yynewerror:
981     yyerror("syntax error");
982 #ifdef lint
983     goto yyerrlab;
984 #endif
985 yyerrlab:
986     ++yynerrs;
987 yyinrecovery:
988     if (yyerrflag < 3)
989     {
990         yyerrflag = 3;
991         for (;;)
992         {
993             if ((yyn = yysindex[*yyssp]) && (yyn += YYERRCODE) >= 0 &&
994                     yyn <= YYTABLESIZE && yycheck[yyn] == YYERRCODE)
995             {
996 #if YYDEBUG
997                 if (yydebug)
998                     printf("%sdebug: state %d, error recovery shifting\
999  to state %d\n", YYPREFIX, *yyssp, yytable[yyn]);
1000 #endif
1001                 if (yyssp >= yyss + yystacksize - 1)
1002                 {
1003                     goto yyoverflow;
1004                 }
1005                 *++yyssp = yystate = yytable[yyn];
1006                 *++yyvsp = yylval;
1007                 goto yyloop;
1008             }
1009             else
1010             {
1011 #if YYDEBUG
1012                 if (yydebug)
1013                     printf("%sdebug: error recovery discarding state %d\n",
1014                             YYPREFIX, *yyssp);
1015 #endif
1016                 if (yyssp <= yyss) goto yyabort;
1017                 --yyssp;
1018                 --yyvsp;
1019             }
1020         }
1021     }
1022     else
1023     {
1024         if (yychar == 0) goto yyabort;
1025 #if YYDEBUG
1026         if (yydebug)
1027         {
1028             yys = 0;
1029             if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
1030             if (!yys) yys = "illegal-symbol";
1031             printf("%sdebug: state %d, error recovery discards token %d (%s)\n",
1032                     YYPREFIX, yystate, yychar, yys);
1033         }
1034 #endif
1035         yychar = (-1);
1036         goto yyloop;
1037     }
1038 yyreduce:
1039 #if YYDEBUG
1040     if (yydebug)
1041         printf("%sdebug: state %d, reducing by rule %d (%s)\n",
1042                 YYPREFIX, yystate, yyn, yyrule[yyn]);
1043 #endif
1044     yym = yylen[yyn];
1045     yyval = yyvsp[1-yym];
1046     switch (yyn)
1047     {
1048 case 2:
1049 #line 99 "ftp.y"
1050  {
1051 			fromname = (char *) 0;
1052 		}
1053 break;
1054 case 4:
1055 #line 106 "ftp.y"
1056  {
1057 			user((char *) yyvsp[-1]);
1058 			free((char *) yyvsp[-1]);
1059 		}
1060 break;
1061 case 5:
1062 #line 111 "ftp.y"
1063  {
1064 			pass((char *) yyvsp[-1]);
1065 			free((char *) yyvsp[-1]);
1066 		}
1067 break;
1068 case 6:
1069 #line 116 "ftp.y"
1070  {
1071 			usedefault = 0;
1072 			if (pdata >= 0) {
1073 				(void) close(pdata);
1074 				pdata = -1;
1075 			}
1076 			reply(200, "PORT command successful.");
1077 		}
1078 break;
1079 case 7:
1080 #line 125 "ftp.y"
1081  {
1082 			passive();
1083 		}
1084 break;
1085 case 8:
1086 #line 129 "ftp.y"
1087  {
1088 			switch (cmd_type) {
1089 
1090 			case TYPE_A:
1091 				if (cmd_form == FORM_N) {
1092 					reply(200, "Type set to A.");
1093 					type = cmd_type;
1094 					form = cmd_form;
1095 				} else
1096 					reply(504, "Form must be N.");
1097 				break;
1098 
1099 			case TYPE_E:
1100 				reply(504, "Type E not implemented.");
1101 				break;
1102 
1103 			case TYPE_I:
1104 				reply(200, "Type set to I.");
1105 				type = cmd_type;
1106 				break;
1107 
1108 			case TYPE_L:
1109 #if NBBY == 8
1110 				if (cmd_bytesz == 8) {
1111 					reply(200,
1112 					    "Type set to L (byte size 8).");
1113 					type = cmd_type;
1114 				} else
1115 					reply(504, "Byte size must be 8.");
1116 #else /* NBBY == 8 */
1117 				UNIMPLEMENTED for NBBY != 8
1118 #endif /* NBBY == 8 */
1119 			}
1120 		}
1121 break;
1122 case 9:
1123 #line 164 "ftp.y"
1124  {
1125 			switch (yyvsp[-1]) {
1126 
1127 			case STRU_F:
1128 				reply(200, "STRU F ok.");
1129 				break;
1130 
1131 			default:
1132 				reply(504, "Unimplemented STRU type.");
1133 			}
1134 		}
1135 break;
1136 case 10:
1137 #line 176 "ftp.y"
1138  {
1139 			switch (yyvsp[-1]) {
1140 
1141 			case MODE_S:
1142 				reply(200, "MODE S ok.");
1143 				break;
1144 
1145 			default:
1146 				reply(502, "Unimplemented MODE type.");
1147 			}
1148 		}
1149 break;
1150 case 11:
1151 #line 188 "ftp.y"
1152  {
1153 			reply(202, "ALLO command ignored.");
1154 		}
1155 break;
1156 case 12:
1157 #line 192 "ftp.y"
1158  {
1159 			reply(202, "ALLO command ignored.");
1160 		}
1161 break;
1162 case 13:
1163 #line 196 "ftp.y"
1164  {
1165 			if (yyvsp[-3] && yyvsp[-1] != NULL)
1166 				retrieve((char *) 0, (char *) yyvsp[-1]);
1167 			if (yyvsp[-1] != NULL)
1168 				free((char *) yyvsp[-1]);
1169 		}
1170 break;
1171 case 14:
1172 #line 203 "ftp.y"
1173  {
1174 			if (yyvsp[-3] && yyvsp[-1] != NULL)
1175 				store((char *) yyvsp[-1], "w", 0);
1176 			if (yyvsp[-1] != NULL)
1177 				free((char *) yyvsp[-1]);
1178 		}
1179 break;
1180 case 15:
1181 #line 210 "ftp.y"
1182  {
1183 			if (yyvsp[-3] && yyvsp[-1] != NULL)
1184 				store((char *) yyvsp[-1], "a", 0);
1185 			if (yyvsp[-1] != NULL)
1186 				free((char *) yyvsp[-1]);
1187 		}
1188 break;
1189 case 16:
1190 #line 217 "ftp.y"
1191  {
1192 			if (yyvsp[-1])
1193 				send_file_list(".");
1194 		}
1195 break;
1196 case 17:
1197 #line 222 "ftp.y"
1198  {
1199 			if (yyvsp[-3] && yyvsp[-1] != NULL)
1200 				send_file_list((char *) yyvsp[-1]);
1201 			if (yyvsp[-1] != NULL)
1202 				free((char *) yyvsp[-1]);
1203 		}
1204 break;
1205 case 18:
1206 #line 229 "ftp.y"
1207  {
1208 			if (yyvsp[-1])
1209 				retrieve("/bin/ls -lgA", "");
1210 		}
1211 break;
1212 case 19:
1213 #line 234 "ftp.y"
1214  {
1215 			if (yyvsp[-3] && yyvsp[-1] != NULL)
1216 				retrieve("/bin/ls -lgA %s", (char *) yyvsp[-1]);
1217 			if (yyvsp[-1] != NULL)
1218 				free((char *) yyvsp[-1]);
1219 		}
1220 break;
1221 case 20:
1222 #line 241 "ftp.y"
1223  {
1224 			if (yyvsp[-3] && yyvsp[-1] != NULL)
1225 				statfilecmd((char *) yyvsp[-1]);
1226 			if (yyvsp[-1] != NULL)
1227 				free((char *) yyvsp[-1]);
1228 		}
1229 break;
1230 case 21:
1231 #line 248 "ftp.y"
1232  {
1233 			statcmd();
1234 		}
1235 break;
1236 case 22:
1237 #line 252 "ftp.y"
1238  {
1239 			if (yyvsp[-3] && yyvsp[-1] != NULL)
1240 				delete((char *) yyvsp[-1]);
1241 			if (yyvsp[-1] != NULL)
1242 				free((char *) yyvsp[-1]);
1243 		}
1244 break;
1245 case 23:
1246 #line 259 "ftp.y"
1247  {
1248 			if (fromname) {
1249 				renamecmd(fromname, (char *) yyvsp[-1]);
1250 				free(fromname);
1251 				fromname = (char *) 0;
1252 			} else {
1253 				reply(503, "Bad sequence of commands.");
1254 			}
1255 			free((char *) yyvsp[-1]);
1256 		}
1257 break;
1258 case 24:
1259 #line 270 "ftp.y"
1260  {
1261 			reply(225, "ABOR command successful.");
1262 		}
1263 break;
1264 case 25:
1265 #line 274 "ftp.y"
1266  {
1267 			if (yyvsp[-1])
1268 				cwd(pw->pw_dir);
1269 		}
1270 break;
1271 case 26:
1272 #line 279 "ftp.y"
1273  {
1274 			if (yyvsp[-3] && yyvsp[-1] != NULL)
1275 				cwd((char *) yyvsp[-1]);
1276 			if (yyvsp[-1] != NULL)
1277 				free((char *) yyvsp[-1]);
1278 		}
1279 break;
1280 case 27:
1281 #line 286 "ftp.y"
1282  {
1283 			help(cmdtab, (char *) 0);
1284 		}
1285 break;
1286 case 28:
1287 #line 290 "ftp.y"
1288  {
1289 			register char *cp = (char *)yyvsp[-1];
1290 
1291 			if (strncasecmp(cp, "SITE", 4) == 0) {
1292 				cp = (char *)yyvsp[-1] + 4;
1293 				if (*cp == ' ')
1294 					cp++;
1295 				if (*cp)
1296 					help(sitetab, cp);
1297 				else
1298 					help(sitetab, (char *) 0);
1299 			} else
1300 				help(cmdtab, (char *) yyvsp[-1]);
1301 		}
1302 break;
1303 case 29:
1304 #line 305 "ftp.y"
1305  {
1306 			reply(200, "NOOP command successful.");
1307 		}
1308 break;
1309 case 30:
1310 #line 309 "ftp.y"
1311  {
1312 			if (yyvsp[-3] && yyvsp[-1] != NULL)
1313 				makedir((char *) yyvsp[-1]);
1314 			if (yyvsp[-1] != NULL)
1315 				free((char *) yyvsp[-1]);
1316 		}
1317 break;
1318 case 31:
1319 #line 316 "ftp.y"
1320  {
1321 			if (yyvsp[-3] && yyvsp[-1] != NULL)
1322 				removedir((char *) yyvsp[-1]);
1323 			if (yyvsp[-1] != NULL)
1324 				free((char *) yyvsp[-1]);
1325 		}
1326 break;
1327 case 32:
1328 #line 323 "ftp.y"
1329  {
1330 			if (yyvsp[-1])
1331 				pwd();
1332 		}
1333 break;
1334 case 33:
1335 #line 328 "ftp.y"
1336  {
1337 			if (yyvsp[-1])
1338 				cwd("..");
1339 		}
1340 break;
1341 case 34:
1342 #line 333 "ftp.y"
1343  {
1344 			help(sitetab, (char *) 0);
1345 		}
1346 break;
1347 case 35:
1348 #line 337 "ftp.y"
1349  {
1350 			help(sitetab, (char *) yyvsp[-1]);
1351 		}
1352 break;
1353 case 36:
1354 #line 341 "ftp.y"
1355  {
1356 			int oldmask;
1357 
1358 			if (yyvsp[-1]) {
1359 				oldmask = umask(0);
1360 				(void) umask(oldmask);
1361 				reply(200, "Current UMASK is %03o", oldmask);
1362 			}
1363 		}
1364 break;
1365 case 37:
1366 #line 351 "ftp.y"
1367  {
1368 			int oldmask;
1369 
1370 			if (yyvsp[-3]) {
1371 				if ((yyvsp[-1] == -1) || (yyvsp[-1] > 0777)) {
1372 					reply(501, "Bad UMASK value");
1373 				} else {
1374 					oldmask = umask(yyvsp[-1]);
1375 					reply(200,
1376 					    "UMASK set to %03o (was %03o)",
1377 					    yyvsp[-1], oldmask);
1378 				}
1379 			}
1380 		}
1381 break;
1382 case 38:
1383 #line 366 "ftp.y"
1384  {
1385 			if (yyvsp[-5] && (yyvsp[-1] != NULL)) {
1386 				if (yyvsp[-3] > 0777)
1387 					reply(501,
1388 				"CHMOD: Mode value must be between 0 and 0777");
1389 				else if (chmod((char *) yyvsp[-1], yyvsp[-3]) < 0)
1390 					perror_reply(550, (char *) yyvsp[-1]);
1391 				else
1392 					reply(200, "CHMOD command successful.");
1393 			}
1394 			if (yyvsp[-1] != NULL)
1395 				free((char *) yyvsp[-1]);
1396 		}
1397 break;
1398 case 39:
1399 #line 380 "ftp.y"
1400  {
1401 			reply(200,
1402 			    "Current IDLE time limit is %d seconds; max %d",
1403 				timeout, maxtimeout);
1404 		}
1405 break;
1406 case 40:
1407 #line 386 "ftp.y"
1408  {
1409 			if (yyvsp[-1] < 30 || yyvsp[-1] > maxtimeout) {
1410 				reply(501,
1411 			"Maximum IDLE time must be between 30 and %d seconds",
1412 				    maxtimeout);
1413 			} else {
1414 				timeout = yyvsp[-1];
1415 				(void) alarm((unsigned) timeout);
1416 				reply(200,
1417 				    "Maximum IDLE time set to %d seconds",
1418 				    timeout);
1419 			}
1420 		}
1421 break;
1422 case 41:
1423 #line 400 "ftp.y"
1424  {
1425 			if (yyvsp[-3] && yyvsp[-1] != NULL)
1426 				store((char *) yyvsp[-1], "w", 1);
1427 			if (yyvsp[-1] != NULL)
1428 				free((char *) yyvsp[-1]);
1429 		}
1430 break;
1431 case 42:
1432 #line 407 "ftp.y"
1433  {
1434 #ifdef unix
1435 #ifdef BSD
1436 			reply(215, "UNIX Type: L%d Version: BSD-%d",
1437 				NBBY, BSD);
1438 #else /* BSD */
1439 			reply(215, "UNIX Type: L%d", NBBY);
1440 #endif /* BSD */
1441 #else /* unix */
1442 			reply(215, "UNKNOWN Type: L%d", NBBY);
1443 #endif /* unix */
1444 		}
1445 break;
1446 case 43:
1447 #line 428 "ftp.y"
1448  {
1449 			if (yyvsp[-3] && yyvsp[-1] != NULL)
1450 				sizecmd((char *) yyvsp[-1]);
1451 			if (yyvsp[-1] != NULL)
1452 				free((char *) yyvsp[-1]);
1453 		}
1454 break;
1455 case 44:
1456 #line 445 "ftp.y"
1457  {
1458 			if (yyvsp[-3] && yyvsp[-1] != NULL) {
1459 				struct stat stbuf;
1460 				if (stat((char *) yyvsp[-1], &stbuf) < 0)
1461 					perror_reply(550, "%s", (char *) yyvsp[-1]);
1462 				else if ((stbuf.st_mode&S_IFMT) != S_IFREG) {
1463 					reply(550, "%s: not a plain file.",
1464 						(char *) yyvsp[-1]);
1465 				} else {
1466 					register struct tm *t;
1467 					struct tm *gmtime();
1468 					t = gmtime(&stbuf.st_mtime);
1469 					reply(213,
1470 					    "19%02d%02d%02d%02d%02d%02d",
1471 					    t->tm_year, t->tm_mon+1, t->tm_mday,
1472 					    t->tm_hour, t->tm_min, t->tm_sec);
1473 				}
1474 			}
1475 			if (yyvsp[-1] != NULL)
1476 				free((char *) yyvsp[-1]);
1477 		}
1478 break;
1479 case 45:
1480 #line 467 "ftp.y"
1481  {
1482 			reply(221, "Goodbye.");
1483 			dologout(0);
1484 		}
1485 break;
1486 case 46:
1487 #line 472 "ftp.y"
1488  {
1489 			yyerrok;
1490 		}
1491 break;
1492 case 47:
1493 #line 477 "ftp.y"
1494  {
1495 			char *renamefrom();
1496 
1497 			if (yyvsp[-3] && yyvsp[-1]) {
1498 				fromname = renamefrom((char *) yyvsp[-1]);
1499 				if (fromname == (char *) 0 && yyvsp[-1]) {
1500 					free((char *) yyvsp[-1]);
1501 				}
1502 			}
1503 		}
1504 break;
1505 case 49:
1506 #line 493 "ftp.y"
1507  {
1508 			*(char **)&(yyval) = "";
1509 		}
1510 break;
1511 case 52:
1512 #line 504 "ftp.y"
1513  {
1514 			register char *a, *p;
1515 
1516 			a = (char *)&data_dest.sin_addr;
1517 			a[0] = yyvsp[-10]; a[1] = yyvsp[-8]; a[2] = yyvsp[-6]; a[3] = yyvsp[-4];
1518 			p = (char *)&data_dest.sin_port;
1519 			p[0] = yyvsp[-2]; p[1] = yyvsp[0];
1520 			data_dest.sin_family = AF_INET;
1521 		}
1522 break;
1523 case 53:
1524 #line 516 "ftp.y"
1525  {
1526 		yyval = FORM_N;
1527 	}
1528 break;
1529 case 54:
1530 #line 520 "ftp.y"
1531  {
1532 		yyval = FORM_T;
1533 	}
1534 break;
1535 case 55:
1536 #line 524 "ftp.y"
1537  {
1538 		yyval = FORM_C;
1539 	}
1540 break;
1541 case 56:
1542 #line 530 "ftp.y"
1543  {
1544 		cmd_type = TYPE_A;
1545 		cmd_form = FORM_N;
1546 	}
1547 break;
1548 case 57:
1549 #line 535 "ftp.y"
1550  {
1551 		cmd_type = TYPE_A;
1552 		cmd_form = yyvsp[0];
1553 	}
1554 break;
1555 case 58:
1556 #line 540 "ftp.y"
1557  {
1558 		cmd_type = TYPE_E;
1559 		cmd_form = FORM_N;
1560 	}
1561 break;
1562 case 59:
1563 #line 545 "ftp.y"
1564  {
1565 		cmd_type = TYPE_E;
1566 		cmd_form = yyvsp[0];
1567 	}
1568 break;
1569 case 60:
1570 #line 550 "ftp.y"
1571  {
1572 		cmd_type = TYPE_I;
1573 	}
1574 break;
1575 case 61:
1576 #line 554 "ftp.y"
1577  {
1578 		cmd_type = TYPE_L;
1579 		cmd_bytesz = NBBY;
1580 	}
1581 break;
1582 case 62:
1583 #line 559 "ftp.y"
1584  {
1585 		cmd_type = TYPE_L;
1586 		cmd_bytesz = yyvsp[0];
1587 	}
1588 break;
1589 case 63:
1590 #line 565 "ftp.y"
1591  {
1592 		cmd_type = TYPE_L;
1593 		cmd_bytesz = yyvsp[0];
1594 	}
1595 break;
1596 case 64:
1597 #line 572 "ftp.y"
1598  {
1599 		yyval = STRU_F;
1600 	}
1601 break;
1602 case 65:
1603 #line 576 "ftp.y"
1604  {
1605 		yyval = STRU_R;
1606 	}
1607 break;
1608 case 66:
1609 #line 580 "ftp.y"
1610  {
1611 		yyval = STRU_P;
1612 	}
1613 break;
1614 case 67:
1615 #line 586 "ftp.y"
1616  {
1617 		yyval = MODE_S;
1618 	}
1619 break;
1620 case 68:
1621 #line 590 "ftp.y"
1622  {
1623 		yyval = MODE_B;
1624 	}
1625 break;
1626 case 69:
1627 #line 594 "ftp.y"
1628  {
1629 		yyval = MODE_C;
1630 	}
1631 break;
1632 case 70:
1633 #line 600 "ftp.y"
1634  {
1635 		/*
1636 		 * Problem: this production is used for all pathname
1637 		 * processing, but only gives a 550 error reply.
1638 		 * This is a valid reply in some cases but not in others.
1639 		 */
1640 		if (logged_in && yyvsp[0] && strncmp((char *) yyvsp[0], "~", 1) == 0) {
1641 			*(char **)&(yyval) = *glob((char *) yyvsp[0]);
1642 			if (globerr != NULL) {
1643 				reply(550, globerr);
1644 				yyval = NULL;
1645 			}
1646 			free((char *) yyvsp[0]);
1647 		} else
1648 			yyval = yyvsp[0];
1649 	}
1650 break;
1651 case 72:
1652 #line 622 "ftp.y"
1653  {
1654 		register int ret, dec, multby, digit;
1655 
1656 		/*
1657 		 * Convert a number that was read as decimal number
1658 		 * to what it would be if it had been read as octal.
1659 		 */
1660 		dec = yyvsp[0];
1661 		multby = 1;
1662 		ret = 0;
1663 		while (dec) {
1664 			digit = dec%10;
1665 			if (digit > 7) {
1666 				ret = -1;
1667 				break;
1668 			}
1669 			ret += digit * multby;
1670 			multby *= 8;
1671 			dec /= 10;
1672 		}
1673 		yyval = ret;
1674 	}
1675 break;
1676 case 73:
1677 #line 647 "ftp.y"
1678  {
1679 		if (logged_in)
1680 			yyval = 1;
1681 		else {
1682 			reply(530, "Please login with USER and PASS.");
1683 			yyval = 0;
1684 		}
1685 	}
1686 break;
1687 #line 1688 "ftp.tab.c"
1688     }
1689     yyssp -= yym;
1690     yystate = *yyssp;
1691     yyvsp -= yym;
1692     yym = yylhs[yyn];
1693     if (yystate == 0 && yym == 0)
1694     {
1695 #if YYDEBUG
1696         if (yydebug)
1697             printf("%sdebug: after reduction, shifting from state 0 to\
1698  state %d\n", YYPREFIX, YYFINAL);
1699 #endif
1700         yystate = YYFINAL;
1701         *++yyssp = YYFINAL;
1702         *++yyvsp = yyval;
1703         if (yychar < 0)
1704         {
1705             if ((yychar = yylex()) < 0) yychar = 0;
1706 #if YYDEBUG
1707             if (yydebug)
1708             {
1709                 yys = 0;
1710                 if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
1711                 if (!yys) yys = "illegal-symbol";
1712                 printf("%sdebug: state %d, reading %d (%s)\n",
1713                         YYPREFIX, YYFINAL, yychar, yys);
1714             }
1715 #endif
1716         }
1717         if (yychar == 0) goto yyaccept;
1718         goto yyloop;
1719     }
1720     if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 &&
1721             yyn <= YYTABLESIZE && yycheck[yyn] == yystate)
1722         yystate = yytable[yyn];
1723     else
1724         yystate = yydgoto[yym];
1725 #if YYDEBUG
1726     if (yydebug)
1727         printf("%sdebug: after reduction, shifting from state %d \
1728 to state %d\n", YYPREFIX, *yyssp, yystate);
1729 #endif
1730     if (yyssp >= yyss + yystacksize - 1)
1731     {
1732         goto yyoverflow;
1733     }
1734     *++yyssp = yystate;
1735     *++yyvsp = yyval;
1736     goto yyloop;
1737 yyoverflow:
1738     yyerror("yacc stack overflow");
1739 yyabort:
1740     return (1);
1741 yyaccept:
1742     return (0);
1743 }
1744