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