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