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