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