3 /* static const char yysccsid[] = "@(#)yaccpar 1.9 (Berkeley) 02/21/93"; */
4 static char rcsid
[] = "$NetBSD: ftp.tab.c,v 1.7 2001/01/04 23:05:57 lukem Exp $";
15 #define yyclearin (yychar = YYEMPTY)
16 #define yyerrok (yyerrflag = 0)
17 #define YYRECOVERING() (yyerrflag != 0)
19 /* compatibility with bison */
21 /* compatibility with FreeBSD */
22 #ifdef YYPARSE_PARAM_TYPE
23 #define YYPARSE_DECL() yyparse(YYPARSE_PARAM_TYPE YYPARSE_PARAM)
25 #define YYPARSE_DECL() yyparse(void *YYPARSE_PARAM)
28 #define YYPARSE_DECL() yyparse(void)
29 #endif /* YYPARSE_PARAM */
31 extern int YYPARSE_DECL();
33 static int yygrowstack(void);
34 #define yyparse ftp_parse
36 #define yyerror ftp_error
37 #define yychar ftp_char
39 #define yylval ftp_lval
40 #define yydebug ftp_debug
41 #define yynerrs ftp_nerrs
42 #define yyerrflag ftp_errflag
49 #define yydefred ftp_defred
50 #define yydgoto ftp_dgoto
51 #define yysindex ftp_sindex
52 #define yyrindex ftp_rindex
53 #define yygindex ftp_gindex
54 #define yytable ftp_table
55 #define yycheck ftp_check
56 #define yyname ftp_name
57 #define yyrule ftp_rule
58 #define YYPREFIX "ftp_"
62 static char sccsid
[] = "@(#)ftpcmd.y 5.20.1.1 (Berkeley) 3/2/89";
65 #include <sys/param.h>
66 #include <sys/socket.h>
68 #include <netinet/in.h>
81 extern struct sockaddr_in data_dest
;
83 extern struct passwd
*pw
;
90 extern int maxtimeout
;
92 extern char hostname
[], remotehost
[];
93 extern char proctitle
[];
95 extern int usedefault
;
97 extern char tmpline
[];
102 static int cmd_bytesz
;
107 #line 106 "ftp.tab.c"
171 #define YYERRCODE 256
172 static const short ftp_lhs
[] = { -1,
173 0, 0, 0, 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, 1, 1, 1, 1,
176 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
177 1, 1, 1, 1, 1, 1, 2, 3, 4, 4,
178 12, 5, 13, 13, 13, 6, 6, 6, 6, 6,
179 6, 6, 6, 7, 7, 7, 8, 8, 8, 10,
182 static const short ftp_len
[] = { 2,
183 0, 2, 2, 4, 4, 4, 2, 4, 4, 4,
184 4, 8, 5, 5, 5, 3, 5, 3, 5, 5,
185 2, 5, 4, 2, 3, 5, 2, 4, 2, 5,
186 5, 3, 3, 4, 6, 5, 7, 9, 4, 6,
187 5, 2, 5, 5, 2, 2, 5, 1, 0, 1,
188 1, 11, 1, 1, 1, 1, 3, 1, 3, 1,
189 1, 3, 2, 1, 1, 1, 1, 1, 1, 1,
192 static const short ftp_defred
[] = { 1,
193 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
194 73, 73, 73, 0, 73, 0, 0, 73, 73, 73,
195 73, 0, 0, 0, 0, 73, 73, 73, 73, 73,
196 0, 73, 73, 2, 3, 46, 0, 0, 45, 0,
197 7, 0, 0, 0, 0, 0, 0, 0, 0, 0,
198 24, 0, 0, 0, 0, 0, 21, 0, 0, 27,
199 29, 0, 0, 0, 0, 0, 42, 0, 0, 48,
200 0, 50, 0, 0, 0, 0, 0, 60, 0, 0,
201 64, 66, 65, 0, 68, 69, 67, 0, 0, 0,
202 0, 0, 0, 71, 0, 70, 0, 0, 25, 0,
203 18, 0, 16, 0, 73, 0, 73, 0, 0, 0,
204 0, 32, 33, 0, 0, 0, 4, 5, 0, 6,
205 0, 0, 0, 51, 63, 8, 9, 10, 0, 0,
206 0, 0, 11, 0, 23, 0, 0, 0, 0, 0,
207 34, 0, 0, 39, 0, 0, 28, 0, 0, 0,
208 0, 0, 0, 55, 53, 54, 57, 59, 62, 13,
209 14, 15, 0, 47, 22, 26, 19, 17, 0, 0,
210 36, 0, 0, 20, 30, 31, 41, 43, 44, 0,
211 0, 35, 72, 0, 40, 0, 0, 0, 37, 0,
212 0, 12, 0, 0, 38, 0, 0, 0, 52,
214 static const short ftp_dgoto
[] = { 1,
215 34, 35, 71, 73, 75, 80, 84, 88, 45, 95,
218 static const short ftp_sindex
[] = { 0,
219 -224, -247, -239, -236, -232, -222, -204, -200, -181, -177,
220 0, 0, 0, -166, 0, -161, -199, 0, 0, 0,
221 0, -160, -159, -264, -158, 0, 0, 0, 0, 0,
222 -157, 0, 0, 0, 0, 0, -167, -162, 0, -156,
223 0, -250, -198, -165, -155, -154, -153, -151, -150, -152,
224 0, -145, -252, -229, -217, -302, 0, -144, -146, 0,
225 0, -142, -141, -140, -139, -137, 0, -136, -135, 0,
226 -134, 0, -133, -132, -130, -131, -128, 0, -249, -127,
227 0, 0, 0, -126, 0, 0, 0, -125, -152, -152,
228 -152, -205, -152, 0, -124, 0, -152, -152, 0, -152,
229 0, -143, 0, -173, 0, -171, 0, -152, -123, -152,
230 -152, 0, 0, -152, -152, -152, 0, 0, -138, 0,
231 -164, -164, -122, 0, 0, 0, 0, 0, -121, -120,
232 -118, -148, 0, -117, 0, -116, -115, -114, -113, -112,
233 0, -163, -111, 0, -110, -109, 0, -107, -106, -105,
234 -104, -103, -129, 0, 0, 0, 0, 0, 0, 0,
235 0, 0, -101, 0, 0, 0, 0, 0, -100, -102,
236 0, -98, -102, 0, 0, 0, 0, 0, 0, -99,
237 -97, 0, 0, -95, 0, -96, -94, -92, 0, -152,
238 -93, 0, -91, -90, 0, -88, -87, -86, 0,
240 static const short ftp_rindex
[] = { 0,
241 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
242 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
243 0, 0, -83, 0, 0, 0, 0, 0, 0, 0,
244 0, 0, 0, 0, 0, 0, 0, -82, 0, 0,
245 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
246 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
247 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
248 0, 0, 0, 0, 0, -81, -80, 0, -158, 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, 0,
259 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
260 0, 0, 0, 0, 0, 0, 0, 0, 0,
262 static const short ftp_gindex
[] = { 0,
263 0, 0, 0, 0, 0, 0, 0, 0, 16, -89,
266 #define YYTABLESIZE 190
267 static const short ftp_table
[] = { 129,
268 130, 131, 104, 134, 59, 60, 76, 136, 137, 77,
269 138, 78, 79, 105, 106, 107, 98, 99, 146, 123,
270 148, 149, 36, 124, 150, 151, 152, 46, 47, 37,
271 49, 2, 38, 52, 53, 54, 55, 39, 58, 100,
272 101, 62, 63, 64, 65, 66, 40, 68, 69, 3,
273 4, 102, 103, 5, 6, 7, 8, 9, 10, 11,
274 12, 13, 81, 132, 133, 41, 82, 83, 42, 14,
275 51, 15, 16, 17, 18, 19, 20, 21, 22, 23,
276 24, 25, 26, 27, 28, 29, 30, 43, 31, 32,
277 33, 44, 85, 86, 154, 140, 141, 143, 144, 155,
278 193, 87, 48, 156, 70, 170, 171, 50, 56, 72,
279 57, 61, 67, 89, 90, 91, 74, 163, 93, 94,
280 142, 92, 145, 97, 108, 109, 110, 111, 139, 112,
281 113, 114, 115, 116, 153, 117, 118, 121, 119, 120,
282 122, 180, 126, 127, 128, 135, 147, 186, 160, 161,
283 124, 162, 164, 165, 166, 167, 168, 159, 173, 169,
284 174, 172, 175, 176, 177, 178, 179, 181, 158, 182,
285 183, 185, 190, 187, 189, 188, 191, 192, 195, 194,
286 196, 0, 0, 198, 197, 73, 199, 49, 56, 58,
288 static const short ftp_check
[] = { 89,
289 90, 91, 305, 93, 269, 270, 257, 97, 98, 260,
290 100, 262, 263, 316, 317, 318, 269, 270, 108, 269,
291 110, 111, 270, 273, 114, 115, 116, 12, 13, 269,
292 15, 256, 269, 18, 19, 20, 21, 270, 23, 269,
293 270, 26, 27, 28, 29, 30, 269, 32, 33, 274,
294 275, 269, 270, 278, 279, 280, 281, 282, 283, 284,
295 285, 286, 261, 269, 270, 270, 265, 266, 269, 294,
296 270, 296, 297, 298, 299, 300, 301, 302, 303, 304,
297 305, 306, 307, 308, 309, 310, 311, 269, 313, 314,
298 315, 269, 258, 259, 259, 269, 270, 269, 270, 264,
299 190, 267, 269, 268, 272, 269, 270, 269, 269, 272,
300 270, 270, 270, 269, 269, 269, 273, 266, 269, 272,
301 105, 273, 107, 269, 269, 272, 269, 269, 272, 270,
302 270, 269, 269, 269, 273, 270, 270, 269, 271, 270,
303 269, 271, 270, 270, 270, 270, 270, 173, 270, 270,
304 273, 270, 270, 270, 270, 270, 270, 123, 269, 272,
305 270, 273, 270, 270, 270, 270, 270, 269, 122, 270,
306 273, 270, 269, 273, 270, 273, 271, 270, 270, 273,
307 271, -1, -1, 271, 273, 269, 273, 270, 270, 270,
313 #define YYMAXTOKEN 319
315 static const char *ftp_name
[] = {
317 "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,
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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
322 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
323 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",
324 "P","R","S","T","SP","CRLF","COMMA","STRING","NUMBER","USER","PASS","ACCT",
325 "REIN","QUIT","PORT","PASV","TYPE","STRU","MODE","RETR","STOR","APPE","MLFL",
326 "MAIL","MSND","MSOM","MSAM","MRSQ","MRCP","ALLO","REST","RNFR","RNTO","ABOR",
327 "DELE","CWD","LIST","NLST","SITE","STAT","HELP","NOOP","MKD","RMD","PWD","CDUP",
328 "STOU","SMNT","SYST","SIZE","MDTM","UMASK","IDLE","CHMOD","LEXERR",
330 static const char *ftp_rule
[] = {
331 "$accept : cmd_list",
333 "cmd_list : cmd_list cmd",
334 "cmd_list : cmd_list rcmd",
335 "cmd : USER SP username CRLF",
336 "cmd : PASS SP password CRLF",
337 "cmd : PORT SP host_port CRLF",
339 "cmd : TYPE SP type_code CRLF",
340 "cmd : STRU SP struct_code CRLF",
341 "cmd : MODE SP mode_code CRLF",
342 "cmd : ALLO SP NUMBER CRLF",
343 "cmd : ALLO SP NUMBER SP R SP NUMBER CRLF",
344 "cmd : RETR check_login SP pathname CRLF",
345 "cmd : STOR check_login SP pathname CRLF",
346 "cmd : APPE check_login SP pathname CRLF",
347 "cmd : NLST check_login CRLF",
348 "cmd : NLST check_login SP STRING CRLF",
349 "cmd : LIST check_login CRLF",
350 "cmd : LIST check_login SP pathname CRLF",
351 "cmd : STAT check_login SP pathname CRLF",
353 "cmd : DELE check_login SP pathname CRLF",
354 "cmd : RNTO SP pathname CRLF",
356 "cmd : CWD check_login CRLF",
357 "cmd : CWD check_login SP pathname CRLF",
359 "cmd : HELP SP STRING CRLF",
361 "cmd : MKD check_login SP pathname CRLF",
362 "cmd : RMD check_login SP pathname CRLF",
363 "cmd : PWD check_login CRLF",
364 "cmd : CDUP check_login CRLF",
365 "cmd : SITE SP HELP CRLF",
366 "cmd : SITE SP HELP SP STRING CRLF",
367 "cmd : SITE SP UMASK check_login CRLF",
368 "cmd : SITE SP UMASK check_login SP octal_number CRLF",
369 "cmd : SITE SP CHMOD check_login SP octal_number SP pathname CRLF",
370 "cmd : SITE SP IDLE CRLF",
371 "cmd : SITE SP IDLE SP NUMBER CRLF",
372 "cmd : STOU check_login SP pathname CRLF",
374 "cmd : SIZE check_login SP pathname CRLF",
375 "cmd : MDTM check_login SP pathname CRLF",
378 "rcmd : RNFR check_login SP pathname CRLF",
382 "byte_size : NUMBER",
383 "host_port : NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER",
388 "type_code : A SP form_code",
390 "type_code : E SP form_code",
393 "type_code : L SP byte_size",
394 "type_code : L byte_size",
401 "pathname : pathstring",
402 "pathstring : STRING",
403 "octal_number : NUMBER",
415 /* define the initial stack-sizes */
418 #define YYMAXDEPTH YYSTACKSIZE
421 #define YYSTACKSIZE YYMAXDEPTH
423 #define YYSTACKSIZE 500
424 #define YYMAXDEPTH 500
428 #define YYINITSTACKSIZE 500
439 /* variables for the parser stack */
441 static short *yysslim
;
442 static YYSTYPE
*yyvs
;
443 static unsigned yystacksize
;
446 extern jmp_buf errcatch
;
448 #define CMD 0 /* beginning of command */
449 #define ARGS 1 /* expect miscellaneous arguments */
450 #define STR1 2 /* expect SP followed by STRING */
451 #define STR2 3 /* expect STRING */
452 #define OSTR 4 /* optional SP then STRING */
453 #define ZSTR1 5 /* SP then optional STRING */
454 #define ZSTR2 6 /* optional STRING after SP */
455 #define SITECMD 7 /* SITE command */
456 #define NSTR 8 /* Number followed by a string */
462 short implemented
; /* 1 if command is implemented */
466 struct tab cmdtab
[] = { /* In order defined in RFC 765 */
467 { "USER", USER
, STR1
, 1, "<sp> username" },
468 { "PASS", PASS
, ZSTR1
, 1, "<sp> password" },
469 { "ACCT", ACCT
, STR1
, 0, "(specify account)" },
470 { "SMNT", SMNT
, ARGS
, 0, "(structure mount)" },
471 { "REIN", REIN
, ARGS
, 0, "(reinitialize server state)" },
472 { "QUIT", QUIT
, ARGS
, 1, "(terminate service)", },
473 { "PORT", PORT
, ARGS
, 1, "<sp> b0, b1, b2, b3, b4" },
474 { "PASV", PASV
, ARGS
, 1, "(set server in passive mode)" },
475 { "TYPE", TYPE
, ARGS
, 1, "<sp> [ A | E | I | L ]" },
476 { "STRU", STRU
, ARGS
, 1, "(specify file structure)" },
477 { "MODE", MODE
, ARGS
, 1, "(specify transfer mode)" },
478 { "RETR", RETR
, STR1
, 1, "<sp> file-name" },
479 { "STOR", STOR
, STR1
, 1, "<sp> file-name" },
480 { "APPE", APPE
, STR1
, 1, "<sp> file-name" },
481 { "MLFL", MLFL
, OSTR
, 0, "(mail file)" },
482 { "MAIL", MAIL
, OSTR
, 0, "(mail to user)" },
483 { "MSND", MSND
, OSTR
, 0, "(mail send to terminal)" },
484 { "MSOM", MSOM
, OSTR
, 0, "(mail send to terminal or mailbox)" },
485 { "MSAM", MSAM
, OSTR
, 0, "(mail send to terminal and mailbox)" },
486 { "MRSQ", MRSQ
, OSTR
, 0, "(mail recipient scheme question)" },
487 { "MRCP", MRCP
, STR1
, 0, "(mail recipient)" },
488 { "ALLO", ALLO
, ARGS
, 1, "allocate storage (vacuously)" },
489 { "REST", REST
, ARGS
, 0, "(restart command)" },
490 { "RNFR", RNFR
, STR1
, 1, "<sp> file-name" },
491 { "RNTO", RNTO
, STR1
, 1, "<sp> file-name" },
492 { "ABOR", ABOR
, ARGS
, 1, "(abort operation)" },
493 { "DELE", DELE
, STR1
, 1, "<sp> file-name" },
494 { "CWD", CWD
, OSTR
, 1, "[ <sp> directory-name ]" },
495 { "XCWD", CWD
, OSTR
, 1, "[ <sp> directory-name ]" },
496 { "LIST", LIST
, OSTR
, 1, "[ <sp> path-name ]" },
497 { "NLST", NLST
, OSTR
, 1, "[ <sp> path-name ]" },
498 { "SITE", SITE
, SITECMD
, 1, "site-cmd [ <sp> arguments ]" },
499 { "SYST", SYST
, ARGS
, 1, "(get type of operating system)" },
500 { "STAT", STAT
, OSTR
, 1, "[ <sp> path-name ]" },
501 { "HELP", HELP
, OSTR
, 1, "[ <sp> <string> ]" },
502 { "NOOP", NOOP
, ARGS
, 1, "" },
503 { "MKD", MKD
, STR1
, 1, "<sp> path-name" },
504 { "XMKD", MKD
, STR1
, 1, "<sp> path-name" },
505 { "RMD", RMD
, STR1
, 1, "<sp> path-name" },
506 { "XRMD", RMD
, STR1
, 1, "<sp> path-name" },
507 { "PWD", PWD
, ARGS
, 1, "(return current directory)" },
508 { "XPWD", PWD
, ARGS
, 1, "(return current directory)" },
509 { "CDUP", CDUP
, ARGS
, 1, "(change to parent directory)" },
510 { "XCUP", CDUP
, ARGS
, 1, "(change to parent directory)" },
511 { "STOU", STOU
, STR1
, 1, "<sp> file-name" },
512 { "SIZE", SIZE
, OSTR
, 1, "<sp> path-name" },
513 { "MDTM", MDTM
, OSTR
, 1, "<sp> path-name" },
517 struct tab sitetab
[] = {
518 { "UMASK", UMASK
, ARGS
, 1, "[ <sp> umask ]" },
519 { "IDLE", IDLE
, ARGS
, 1, "[ <sp> maximum-idle-time ]" },
520 { "CHMOD", CHMOD
, NSTR
, 1, "<sp> mode <sp> file-name" },
521 { "HELP", HELP
, OSTR
, 1, "[ <sp> <string> ]" },
527 register struct tab
*p
;
531 for (; p
->name
!= NULL
; p
++)
532 if (strcmp(cmd
, p
->name
) == 0)
537 #include <arpa/telnet.h>
540 * getline - a hacked up version of fgets to ignore TELNET escape codes.
551 /* tmpline may contain saved command from urgent mode interruption */
552 for (c
= 0; tmpline
[c
] != '\0' && --n
> 0; ++c
) {
554 if (tmpline
[c
] == '\n') {
557 syslog(LOG_DEBUG
, "command: %s", s
);
564 while ((c
= getc(iop
)) != EOF
) {
567 if ((c
= getc(iop
)) != EOF
) {
573 printf("%c%c%c", IAC
, DONT
, 0377&c
);
574 (void) fflush(stdout
);
579 printf("%c%c%c", IAC
, WONT
, 0377&c
);
580 (void) fflush(stdout
);
585 continue; /* ignore command */
590 if (--n
<= 0 || c
== '\n')
593 if (c
== EOF
&& cs
== s
)
597 syslog(LOG_DEBUG
, "command: %s", s
);
605 extern char *ctime();
606 extern time_t time();
609 "Timeout (%d seconds): closing control connection.", timeout
);
613 "User %s timed out after %d seconds at %s",
614 (pw
? pw
-> pw_name
: "unknown"), timeout
, ctime(&now
));
621 static int cpos
, state
;
622 register char *cp
, *cp2
;
623 register struct tab
*p
;
632 (void) signal(SIGALRM
, toolong
);
633 (void) alarm((unsigned) timeout
);
634 if (getline(cbuf
, sizeof(cbuf
)-1, stdin
) == NULL
) {
635 reply(221, "You could at least say goodbye.");
640 if (strncasecmp(cbuf
, "PASS", 4) != NULL
)
641 setproctitle("%s: %s", proctitle
, cbuf
);
642 #endif /* SETPROCTITLE */
643 if ((cp
= index(cbuf
, '\r'))) {
647 if ((cp
= strpbrk(cbuf
, " \n")))
654 p
= lookup(cmdtab
, cbuf
);
657 if (p
->implemented
== 0) {
663 *(char **)&yylval
= p
->name
;
669 if (cbuf
[cpos
] == ' ') {
674 if ((cp2
= strpbrk(cp
, " \n")))
679 p
= lookup(sitetab
, cp
);
682 if (p
->implemented
== 0) {
689 *(char **)&yylval
= p
->name
;
696 if (cbuf
[cpos
] == '\n') {
705 if (cbuf
[cpos
] == ' ') {
707 state
= state
== OSTR
? STR2
: ++state
;
713 if (cbuf
[cpos
] == '\n') {
724 * Make sure the string is nonempty and \n terminated.
726 if (n
> 1 && cbuf
[cpos
] == '\n') {
728 *(char **)&yylval
= copy(cp
);
736 if (cbuf
[cpos
] == ' ') {
740 if (isdigit(cbuf
[cpos
])) {
742 while (isdigit(cbuf
[++cpos
]))
755 if (isdigit(cbuf
[cpos
])) {
757 while (isdigit(cbuf
[++cpos
]))
765 switch (cbuf
[cpos
++]) {
829 fatal("Unknown state in scanner.");
852 extern char *malloc(), *strcpy();
854 p
= malloc((unsigned) strlen(s
) + 1);
856 fatal("Ran out of memory.");
865 register struct tab
*c
;
866 register int width
, NCMDS
;
873 width
= 0, NCMDS
= 0;
874 for (c
= ctab
; c
->name
!= NULL
; c
++) {
875 int len
= strlen(c
->name
);
881 width
= (width
+ 8) &~ 7;
883 register int i
, j
, w
;
886 lreply(214, "The following %scommands are recognized %s.",
887 type
, "(* =>'s unimplemented)");
888 columns
= 76 / width
;
891 lines
= (NCMDS
+ columns
- 1) / columns
;
892 for (i
= 0; i
< lines
; i
++) {
894 for (j
= 0; j
< columns
; j
++) {
895 c
= ctab
+ j
* lines
+ i
;
896 printf("%s%c", c
->name
,
897 c
->implemented
? ' ' : '*');
898 if (c
+ lines
>= &ctab
[NCMDS
])
900 w
= strlen(c
->name
) + 1;
908 (void) fflush(stdout
);
909 reply(214, "Direct comments to ftp-bugs@%s.", hostname
);
914 if (c
== (struct tab
*)0) {
915 reply(502, "Unknown command %s.", s
);
919 reply(214, "Syntax: %s%s %s", type
, c
->name
, c
->help
);
921 reply(214, "%s%-*s\t%s; unimplemented.", type
, width
,
932 if (stat(filename
, &stbuf
) < 0 ||
933 (stbuf
.st_mode
&S_IFMT
) != S_IFREG
)
934 reply(550, "%s: not a plain file.", filename
);
936 reply(213, "%lu", stbuf
.st_size
);
940 register int c
, count
;
942 fin
= fopen(filename
, "r");
944 perror_reply(550, filename
);
947 if (fstat(fileno(fin
), &stbuf
) < 0 ||
948 (stbuf
.st_mode
&S_IFMT
) != S_IFREG
) {
949 reply(550, "%s: not a plain file.", filename
);
955 while((c
=getc(fin
)) != EOF
) {
956 if (c
== '\n') /* will get expanded to \r\n */
962 reply(213, "%ld", count
);
965 reply(504, "SIZE not implemented for Type %c.", "?AEIL"[type
]);
968 #line 967 "ftp.tab.c"
969 /* allocate initial stack or double stack size, up to YYMAXDEPTH */
970 static int yygrowstack(void)
977 if ((newsize
= yystacksize
) == 0)
978 newsize
= YYINITSTACKSIZE
;
979 else if (newsize
>= YYMAXDEPTH
)
981 else if ((newsize
*= 2) > YYMAXDEPTH
)
982 newsize
= YYMAXDEPTH
;
986 ? (short *)realloc(yyss
, newsize
* sizeof(*newss
))
987 : (short *)malloc(newsize
* sizeof(*newss
));
994 ? (YYSTYPE
*)realloc(yyvs
, newsize
* sizeof(*newvs
))
995 : (YYSTYPE
*)malloc(newsize
* sizeof(*newvs
));
1001 yystacksize
= newsize
;
1002 yysslim
= yyss
+ newsize
- 1;
1006 #define YYABORT goto yyabort
1007 #define YYREJECT goto yyabort
1008 #define YYACCEPT goto yyaccept
1009 #define YYERROR goto yyerrlab
1014 int yym
, yyn
, yystate
;
1018 if ((yys
= getenv("YYDEBUG")) != 0)
1021 if (yyn
>= '0' && yyn
<= '9')
1022 yydebug
= yyn
- '0';
1031 if (yyss
== NULL
&& yygrowstack()) goto yyoverflow
;
1038 if ((yyn
= yydefred
[yystate
]) != 0) goto yyreduce
;
1041 if ((yychar
= yylex()) < 0) yychar
= 0;
1046 if (yychar
<= YYMAXTOKEN
) yys
= yyname
[yychar
];
1047 if (!yys
) yys
= "illegal-symbol";
1048 printf("%sdebug: state %d, reading %d (%s)\n",
1049 YYPREFIX
, yystate
, yychar
, yys
);
1053 if ((yyn
= yysindex
[yystate
]) && (yyn
+= yychar
) >= 0 &&
1054 yyn
<= YYTABLESIZE
&& yycheck
[yyn
] == yychar
)
1058 printf("%sdebug: state %d, shifting to state %d\n",
1059 YYPREFIX
, yystate
, yytable
[yyn
]);
1061 if (yyssp
>= yysslim
&& yygrowstack())
1065 yystate
= yytable
[yyn
];
1066 *++yyssp
= yytable
[yyn
];
1069 if (yyerrflag
> 0) --yyerrflag
;
1072 if ((yyn
= yyrindex
[yystate
]) && (yyn
+= yychar
) >= 0 &&
1073 yyn
<= YYTABLESIZE
&& yycheck
[yyn
] == yychar
)
1078 if (yyerrflag
) goto yyinrecovery
;
1080 yyerror("syntax error");
1093 if ((yyn
= yysindex
[*yyssp
]) && (yyn
+= YYERRCODE
) >= 0 &&
1094 yyn
<= YYTABLESIZE
&& yycheck
[yyn
] == YYERRCODE
)
1098 printf("%sdebug: state %d, error recovery shifting\
1099 to state %d\n", YYPREFIX
, *yyssp
, yytable
[yyn
]);
1101 if (yyssp
>= yysslim
&& yygrowstack())
1105 yystate
= yytable
[yyn
];
1106 *++yyssp
= yytable
[yyn
];
1114 printf("%sdebug: error recovery discarding state %d\n",
1117 if (yyssp
<= yyss
) goto yyabort
;
1125 if (yychar
== 0) goto yyabort
;
1130 if (yychar
<= YYMAXTOKEN
) yys
= yyname
[yychar
];
1131 if (!yys
) yys
= "illegal-symbol";
1132 printf("%sdebug: state %d, error recovery discards token %d (%s)\n",
1133 YYPREFIX
, yystate
, yychar
, yys
);
1143 printf("%sdebug: state %d, reducing by rule %d (%s)\n",
1144 YYPREFIX
, yystate
, yyn
, yyrule
[yyn
]);
1148 yyval
= yyvsp
[1-yym
];
1150 memset(&yyval
, 0, sizeof yyval
);
1156 fromname
= (char *) 0;
1162 user((char *) yyvsp
[-1]);
1163 free((char *) yyvsp
[-1]);
1169 pass((char *) yyvsp
[-1]);
1170 free((char *) yyvsp
[-1]);
1178 (void) close(pdata
);
1181 reply(200, "PORT command successful.");
1196 if (cmd_form
== FORM_N
) {
1197 reply(200, "Type set to A.");
1201 reply(504, "Form must be N.");
1205 reply(504, "Type E not implemented.");
1209 reply(200, "Type set to I.");
1215 if (cmd_bytesz
== 8) {
1217 "Type set to L (byte size 8).");
1220 reply(504, "Byte size must be 8.");
1221 #else /* NBBY == 8 */
1222 UNIMPLEMENTED
for NBBY
!= 8
1223 #endif /* NBBY == 8 */
1230 switch (yyvsp
[-1]) {
1233 reply(200, "STRU F ok.");
1237 reply(504, "Unimplemented STRU type.");
1244 switch (yyvsp
[-1]) {
1247 reply(200, "MODE S ok.");
1251 reply(502, "Unimplemented MODE type.");
1258 reply(202, "ALLO command ignored.");
1264 reply(202, "ALLO command ignored.");
1270 if (yyvsp
[-3] && yyvsp
[-1] != NULL
)
1271 retrieve((char *) 0, (char *) yyvsp
[-1]);
1272 if (yyvsp
[-1] != NULL
)
1273 free((char *) yyvsp
[-1]);
1279 if (yyvsp
[-3] && yyvsp
[-1] != NULL
)
1280 store((char *) yyvsp
[-1], "w", 0);
1281 if (yyvsp
[-1] != NULL
)
1282 free((char *) yyvsp
[-1]);
1288 if (yyvsp
[-3] && yyvsp
[-1] != NULL
)
1289 store((char *) yyvsp
[-1], "a", 0);
1290 if (yyvsp
[-1] != NULL
)
1291 free((char *) yyvsp
[-1]);
1298 send_file_list(".");
1304 if (yyvsp
[-3] && yyvsp
[-1] != NULL
)
1305 send_file_list((char *) yyvsp
[-1]);
1306 if (yyvsp
[-1] != NULL
)
1307 free((char *) yyvsp
[-1]);
1314 retrieve("/bin/ls -lgA", "");
1320 if (yyvsp
[-3] && yyvsp
[-1] != NULL
)
1321 retrieve("/bin/ls -lgA %s", (char *) yyvsp
[-1]);
1322 if (yyvsp
[-1] != NULL
)
1323 free((char *) yyvsp
[-1]);
1329 if (yyvsp
[-3] && yyvsp
[-1] != NULL
)
1330 statfilecmd((char *) yyvsp
[-1]);
1331 if (yyvsp
[-1] != NULL
)
1332 free((char *) yyvsp
[-1]);
1344 if (yyvsp
[-3] && yyvsp
[-1] != NULL
)
1345 delete((char *) yyvsp
[-1]);
1346 if (yyvsp
[-1] != NULL
)
1347 free((char *) yyvsp
[-1]);
1354 renamecmd(fromname
, (char *) yyvsp
[-1]);
1356 fromname
= (char *) 0;
1358 reply(503, "Bad sequence of commands.");
1360 free((char *) yyvsp
[-1]);
1366 reply(225, "ABOR command successful.");
1379 if (yyvsp
[-3] && yyvsp
[-1] != NULL
)
1380 cwd((char *) yyvsp
[-1]);
1381 if (yyvsp
[-1] != NULL
)
1382 free((char *) yyvsp
[-1]);
1388 help(cmdtab
, (char *) 0);
1394 register char *cp
= (char *)yyvsp
[-1];
1396 if (strncasecmp(cp
, "SITE", 4) == 0) {
1397 cp
= (char *)yyvsp
[-1] + 4;
1403 help(sitetab
, (char *) 0);
1405 help(cmdtab
, (char *) yyvsp
[-1]);
1411 reply(200, "NOOP command successful.");
1417 if (yyvsp
[-3] && yyvsp
[-1] != NULL
)
1418 makedir((char *) yyvsp
[-1]);
1419 if (yyvsp
[-1] != NULL
)
1420 free((char *) yyvsp
[-1]);
1426 if (yyvsp
[-3] && yyvsp
[-1] != NULL
)
1427 removedir((char *) yyvsp
[-1]);
1428 if (yyvsp
[-1] != NULL
)
1429 free((char *) yyvsp
[-1]);
1449 help(sitetab
, (char *) 0);
1455 help(sitetab
, (char *) yyvsp
[-1]);
1465 (void) umask(oldmask
);
1466 reply(200, "Current UMASK is %03o", oldmask
);
1476 if ((yyvsp
[-1] == -1) || (yyvsp
[-1] > 0777)) {
1477 reply(501, "Bad UMASK value");
1479 oldmask
= umask(yyvsp
[-1]);
1481 "UMASK set to %03o (was %03o)",
1482 yyvsp
[-1], oldmask
);
1490 if (yyvsp
[-5] && (yyvsp
[-1] != NULL
)) {
1491 if (yyvsp
[-3] > 0777)
1493 "CHMOD: Mode value must be between 0 and 0777");
1494 else if (chmod((char *) yyvsp
[-1], yyvsp
[-3]) < 0)
1495 perror_reply(550, (char *) yyvsp
[-1]);
1497 reply(200, "CHMOD command successful.");
1499 if (yyvsp
[-1] != NULL
)
1500 free((char *) yyvsp
[-1]);
1507 "Current IDLE time limit is %d seconds; max %d",
1508 timeout
, maxtimeout
);
1514 if (yyvsp
[-1] < 30 || yyvsp
[-1] > maxtimeout
) {
1516 "Maximum IDLE time must be between 30 and %d seconds",
1519 timeout
= yyvsp
[-1];
1520 (void) alarm((unsigned) timeout
);
1522 "Maximum IDLE time set to %d seconds",
1530 if (yyvsp
[-3] && yyvsp
[-1] != NULL
)
1531 store((char *) yyvsp
[-1], "w", 1);
1532 if (yyvsp
[-1] != NULL
)
1533 free((char *) yyvsp
[-1]);
1541 reply(215, "UNIX Type: L%d Version: BSD-%d",
1544 reply(215, "UNIX Type: L%d", NBBY
);
1547 reply(215, "UNKNOWN Type: L%d", NBBY
);
1554 if (yyvsp
[-3] && yyvsp
[-1] != NULL
)
1555 sizecmd((char *) yyvsp
[-1]);
1556 if (yyvsp
[-1] != NULL
)
1557 free((char *) yyvsp
[-1]);
1563 if (yyvsp
[-3] && yyvsp
[-1] != NULL
) {
1565 if (stat((char *) yyvsp
[-1], &stbuf
) < 0)
1566 perror_reply(550, "%s", (char *) yyvsp
[-1]);
1567 else if ((stbuf
.st_mode
&S_IFMT
) != S_IFREG
) {
1568 reply(550, "%s: not a plain file.",
1569 (char *) yyvsp
[-1]);
1571 register struct tm
*t
;
1572 struct tm
*gmtime();
1573 t
= gmtime(&stbuf
.st_mtime
);
1575 "19%02d%02d%02d%02d%02d%02d",
1576 t
->tm_year
, t
->tm_mon
+1, t
->tm_mday
,
1577 t
->tm_hour
, t
->tm_min
, t
->tm_sec
);
1580 if (yyvsp
[-1] != NULL
)
1581 free((char *) yyvsp
[-1]);
1587 reply(221, "Goodbye.");
1602 if (yyvsp
[-3] && yyvsp
[-1]) {
1603 fromname
= renamefrom((char *) yyvsp
[-1]);
1604 if (fromname
== (char *) 0 && yyvsp
[-1]) {
1605 free((char *) yyvsp
[-1]);
1613 *(char **)&(yyval
) = "";
1619 register char *a
, *p
;
1621 a
= (char *)&data_dest
.sin_addr
;
1622 a
[0] = yyvsp
[-10]; a
[1] = yyvsp
[-8]; a
[2] = yyvsp
[-6]; a
[3] = yyvsp
[-4];
1623 p
= (char *)&data_dest
.sin_port
;
1624 p
[0] = yyvsp
[-2]; p
[1] = yyvsp
[0];
1625 data_dest
.sin_family
= AF_INET
;
1657 cmd_form
= yyvsp
[0];
1671 cmd_form
= yyvsp
[0];
1691 cmd_bytesz
= yyvsp
[0];
1698 cmd_bytesz
= yyvsp
[0];
1741 * Problem: this production is used for all pathname
1742 * processing, but only gives a 550 error reply.
1743 * This is a valid reply in some cases but not in others.
1745 if (logged_in
&& yyvsp
[0] && strncmp((char *) yyvsp
[0], "~", 1) == 0) {
1746 *(char **)&(yyval
) = *glob((char *) yyvsp
[0]);
1747 if (globerr
!= NULL
) {
1748 reply(550, globerr
);
1751 free((char *) yyvsp
[0]);
1759 register int ret
, dec
, multby
, digit
;
1762 * Convert a number that was read as decimal number
1763 * to what it would be if it had been read as octal.
1774 ret
+= digit
* multby
;
1787 reply(530, "Please login with USER and PASS.");
1792 #line 1791 "ftp.tab.c"
1798 if (yystate
== 0 && yym
== 0)
1802 printf("%sdebug: after reduction, shifting from state 0 to\
1803 state %d\n", YYPREFIX
, YYFINAL
);
1810 if ((yychar
= yylex()) < 0) yychar
= 0;
1815 if (yychar
<= YYMAXTOKEN
) yys
= yyname
[yychar
];
1816 if (!yys
) yys
= "illegal-symbol";
1817 printf("%sdebug: state %d, reading %d (%s)\n",
1818 YYPREFIX
, YYFINAL
, yychar
, yys
);
1822 if (yychar
== 0) goto yyaccept
;
1825 if ((yyn
= yygindex
[yym
]) && (yyn
+= yystate
) >= 0 &&
1826 yyn
<= YYTABLESIZE
&& yycheck
[yyn
] == yystate
)
1827 yystate
= yytable
[yyn
];
1829 yystate
= yydgoto
[yym
];
1832 printf("%sdebug: after reduction, shifting from state %d \
1833 to state %d\n", YYPREFIX
, *yyssp
, yystate
);
1835 if (yyssp
>= yysslim
&& yygrowstack())
1839 *++yyssp
= (short) yystate
;
1844 yyerror("yacc stack overflow");