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