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