1 /* $NetBSD: ftp.tab.c,v 1.5 2013/04/06 14:52:24 christos Exp $ */
4 /* static const char yysccsid[] = "@(#)yaccpar 1.9 (Berkeley) 02/21/93"; */
5 static char rcsid
[] = "$NetBSD: ftp.tab.c,v 1.5 2013/04/06 14:52:24 christos Exp $";
13 #define yyclearin (yychar = YYEMPTY)
14 #define yyerrok (yyerrflag = 0)
15 #define YYRECOVERING() (yyerrflag != 0)
19 #define yyparse ftp_parse
27 #define yyerror ftp_error
31 #define yychar ftp_char
39 #define yylval ftp_lval
43 #define yydebug ftp_debug
47 #define yynerrs ftp_nerrs
51 #define yyerrflag ftp_errflag
52 #endif /* yyerrflag */
63 #define yydefred ftp_defred
67 #define yydgoto ftp_dgoto
71 #define yysindex ftp_sindex
75 #define yyrindex ftp_rindex
79 #define yygindex ftp_gindex
83 #define yytable ftp_table
87 #define yycheck ftp_check
91 #define yyname ftp_name
95 #define yyrule ftp_rule
97 #define YYPREFIX "ftp_"
103 /* sccsid[] = "@(#)ftpcmd.y 5.20.1.1 (Berkeley) 3/2/89"; */
105 #include <sys/param.h>
106 #include <sys/socket.h>
108 #include <netinet/in.h>
110 #include <arpa/ftp.h>
120 #include <sys/stat.h>
127 static void yyerror(const char *);
130 extern struct sockaddr_in data_dest
;
131 extern int logged_in
;
132 extern struct passwd
*pw
;
139 extern int maxtimeout
;
141 extern char hostname
[], remotehost
[];
142 extern char proctitle
[];
143 extern char *globerr
;
144 extern int usedefault
;
145 extern int transflag
;
146 extern char tmpline
[];
148 extern char **glob(char *);
149 extern char *renamefrom(char *);
150 extern void cwd(const char *);
152 extern void dologout(int);
153 extern void fatal(const char *);
154 extern void makedir(const char *);
155 extern void nack(const char *);
156 extern void pass(const char *);
157 extern void passive(void);
158 extern void pwd(void);
159 extern void removedir(char *);
160 extern void renamecmd(char *, char *);
161 extern void retrieve(const char *, const char *);
162 extern void send_file_list(const char *);
163 extern void statcmd(void);
164 extern void statfilecmd(const char *);
165 extern void store(char *, const char *, int);
166 extern void user(const char *);
168 extern void perror_reply(int, const char *, ...);
169 extern void reply(int, const char *, ...);
170 extern void lreply(int, const char *, ...);
174 static int cmd_bytesz
;
182 short implemented
; /* 1 if command is implemented */
186 static char * copy(const char *);
189 static void sizecmd(char *filename
);
190 static void help(struct tab
*ctab
, char *s
);
192 struct tab sitetab
[];
196 yyerror(const char *msg
)
202 #undef YYSTYPE_IS_DECLARED
203 #define YYSTYPE_IS_DECLARED 1
205 #ifndef YYSTYPE_IS_DECLARED
206 #define YYSTYPE_IS_DECLARED 1
212 #endif /* !YYSTYPE_IS_DECLARED */
213 #line 211 "ftp.tab.c"
215 /* compatibility with bison */
217 /* compatibility with FreeBSD */
218 # ifdef YYPARSE_PARAM_TYPE
219 # define YYPARSE_DECL() yyparse(YYPARSE_PARAM_TYPE YYPARSE_PARAM)
221 # define YYPARSE_DECL() yyparse(void *YYPARSE_PARAM)
224 # define YYPARSE_DECL() yyparse(void)
227 /* Parameters sent to lex. */
229 # define YYLEX_DECL() yylex(void *YYLEX_PARAM)
230 # define YYLEX yylex(YYLEX_PARAM)
232 # define YYLEX_DECL() yylex(void)
233 # define YYLEX yylex()
236 /* Parameters sent to yyerror. */
238 #define YYERROR_DECL() yyerror(const char *s)
241 #define YYERROR_CALL(msg) yyerror(msg)
244 extern int YYPARSE_DECL();
309 #define YYERRCODE 256
310 static const short ftp_lhs
[] = { -1,
311 0, 0, 0, 11, 11, 11, 11, 11, 11, 11,
312 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
313 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
314 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
315 11, 11, 11, 11, 11, 11, 12, 10, 7, 7,
316 1, 13, 3, 3, 3, 14, 14, 14, 14, 14,
317 14, 14, 14, 6, 6, 6, 4, 4, 4, 8,
320 static const short ftp_len
[] = { 2,
321 0, 2, 2, 4, 4, 4, 2, 4, 4, 4,
322 4, 8, 5, 5, 5, 3, 5, 3, 5, 5,
323 2, 5, 4, 2, 3, 5, 2, 4, 2, 5,
324 5, 3, 3, 4, 6, 5, 7, 9, 4, 6,
325 5, 2, 5, 5, 2, 2, 5, 1, 0, 1,
326 1, 11, 1, 1, 1, 1, 3, 1, 3, 1,
327 1, 3, 2, 1, 1, 1, 1, 1, 1, 1,
330 static const short ftp_defred
[] = { 1,
331 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
332 73, 73, 73, 0, 73, 0, 0, 73, 73, 73,
333 73, 0, 0, 0, 0, 73, 73, 73, 73, 73,
334 0, 73, 73, 2, 3, 46, 0, 0, 45, 0,
335 7, 0, 0, 0, 0, 0, 0, 0, 0, 0,
336 24, 0, 0, 0, 0, 0, 21, 0, 0, 27,
337 29, 0, 0, 0, 0, 0, 42, 0, 0, 48,
338 0, 50, 0, 0, 0, 0, 0, 60, 0, 0,
339 64, 66, 65, 0, 68, 69, 67, 0, 0, 0,
340 0, 0, 0, 71, 0, 70, 0, 0, 25, 0,
341 18, 0, 16, 0, 73, 0, 73, 0, 0, 0,
342 0, 32, 33, 0, 0, 0, 4, 5, 0, 6,
343 0, 0, 51, 0, 63, 8, 9, 10, 0, 0,
344 0, 0, 11, 0, 23, 0, 0, 0, 0, 0,
345 34, 0, 0, 39, 0, 0, 28, 0, 0, 0,
346 0, 0, 0, 55, 53, 54, 57, 59, 62, 13,
347 14, 15, 0, 47, 22, 26, 19, 17, 0, 0,
348 36, 0, 0, 20, 30, 31, 41, 43, 44, 0,
349 0, 35, 72, 0, 40, 0, 0, 0, 37, 0,
350 0, 12, 0, 0, 38, 0, 0, 0, 52,
352 static const short ftp_dgoto
[] = { 1,
353 125, 45, 157, 88, 184, 84, 73, 95, 96, 71,
356 static const short ftp_sindex
[] = { 0,
357 -224, -256, -248, -241, -239, -233, -225, -218, -200, -165,
358 0, 0, 0, -164, 0, -163, -176, 0, 0, 0,
359 0, -162, -161, -231, -160, 0, 0, 0, 0, 0,
360 -159, 0, 0, 0, 0, 0, -240, -148, 0, -143,
361 0, -252, -175, -255, -156, -155, -154, -139, -152, -138,
362 0, -149, -205, -203, -177, -253, 0, -147, -133, 0,
363 0, -145, -144, -142, -141, -137, 0, -136, -135, 0,
364 -140, 0, -134, -132, -130, -131, -128, 0, -254, -127,
365 0, 0, 0, -126, 0, 0, 0, -125, -138, -138,
366 -138, -174, -138, 0, -124, 0, -138, -138, 0, -138,
367 0, -129, 0, -172, 0, -169, 0, -138, -123, -138,
368 -138, 0, 0, -138, -138, -138, 0, 0, -120, 0,
369 -246, -246, 0, -118, 0, 0, 0, 0, -122, -121,
370 -119, -116, 0, -117, 0, -115, -114, -113, -112, -104,
371 0, -167, -101, 0, -110, -109, 0, -108, -107, -106,
372 -105, -103, -111, 0, 0, 0, 0, 0, 0, 0,
373 0, 0, -100, 0, 0, 0, 0, 0, -102, -85,
374 0, -99, -85, 0, 0, 0, 0, 0, 0, -83,
375 -82, 0, 0, -96, 0, -94, -95, -93, 0, -138,
376 -77, 0, -91, -90, 0, -75, -88, -73, 0,
378 static const short ftp_rindex
[] = { 0,
379 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
380 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
381 0, 0, -84, 0, 0, 0, 0, 0, 0, 0,
382 0, 0, 0, 0, 0, 0, 0, -86, 0, 0,
383 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
384 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
385 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
386 0, 0, 0, 0, 0, -81, -80, 0, -160, 0,
387 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
388 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
389 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
390 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
391 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
392 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
393 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
394 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
395 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
396 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
397 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
398 0, 0, 0, 0, 0, 0, 0, 0, 0,
400 static const short ftp_gindex
[] = { 0,
401 4, 16, 11, 0, -29, 0, 0, -89, 0, 0,
404 #define YYTABLESIZE 192
405 static const short ftp_table
[] = { 129,
406 130, 131, 123, 134, 85, 86, 76, 136, 137, 77,
407 138, 78, 79, 87, 154, 36, 124, 70, 146, 155,
408 148, 149, 37, 156, 150, 151, 152, 46, 47, 38,
409 49, 2, 39, 52, 53, 54, 55, 40, 58, 59,
410 60, 62, 63, 64, 65, 66, 41, 68, 69, 3,
411 4, 104, 42, 5, 6, 7, 8, 9, 10, 11,
412 12, 13, 105, 106, 107, 98, 99, 100, 101, 14,
413 43, 15, 16, 17, 18, 19, 20, 21, 22, 23,
414 24, 25, 26, 27, 28, 29, 30, 81, 31, 32,
415 33, 82, 83, 102, 103, 51, 132, 133, 140, 141,
416 193, 143, 144, 170, 171, 44, 48, 50, 56, 72,
417 57, 61, 67, 74, 89, 90, 91, 92, 93, 94,
418 142, 97, 145, 108, 109, 110, 111, 159, 139, 112,
419 113, 117, 158, 114, 115, 116, 153, 118, 123, 121,
420 119, 120, 122, 186, 126, 127, 128, 135, 147, 160,
421 161, 163, 162, 169, 164, 172, 165, 166, 167, 168,
422 173, 180, 174, 175, 176, 177, 178, 0, 179, 182,
423 181, 183, 185, 187, 188, 189, 190, 191, 192, 194,
424 195, 197, 196, 199, 198, 49, 73, 0, 0, 0,
427 static const short ftp_check
[] = { 89,
428 90, 91, 257, 93, 260, 261, 259, 97, 98, 262,
429 100, 264, 265, 269, 261, 272, 271, 258, 108, 266,
430 110, 111, 271, 270, 114, 115, 116, 12, 13, 271,
431 15, 256, 272, 18, 19, 20, 21, 271, 23, 271,
432 272, 26, 27, 28, 29, 30, 272, 32, 33, 274,
433 275, 305, 271, 278, 279, 280, 281, 282, 283, 284,
434 285, 286, 316, 317, 318, 271, 272, 271, 272, 294,
435 271, 296, 297, 298, 299, 300, 301, 302, 303, 304,
436 305, 306, 307, 308, 309, 310, 311, 263, 313, 314,
437 315, 267, 268, 271, 272, 272, 271, 272, 271, 272,
438 190, 271, 272, 271, 272, 271, 271, 271, 271, 258,
439 272, 272, 272, 257, 271, 271, 271, 257, 271, 258,
440 105, 271, 107, 271, 258, 271, 271, 124, 258, 272,
441 272, 272, 122, 271, 271, 271, 257, 272, 257, 271,
442 273, 272, 271, 173, 272, 272, 272, 272, 272, 272,
443 272, 268, 272, 258, 272, 257, 272, 272, 272, 272,
444 271, 273, 272, 272, 272, 272, 272, -1, 272, 272,
445 271, 257, 272, 257, 257, 272, 271, 273, 272, 257,
446 272, 257, 273, 257, 273, 272, 271, -1, -1, -1,
453 #define YYMAXTOKEN 319
455 static const char *yyname
[] = {
457 "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,
458 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
459 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
460 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
461 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
462 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
463 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"NUMBER","STRING","A","B","C","E",
464 "F","I","L","N","P","R","S","T","SP","CRLF","COMMA","USER","PASS","ACCT","REIN",
465 "QUIT","PORT","PASV","TYPE","STRU","MODE","RETR","STOR","APPE","MLFL","MAIL",
466 "MSND","MSOM","MSAM","MRSQ","MRCP","ALLO","REST","RNFR","RNTO","ABOR","DELE",
467 "CWD","LIST","NLST","SITE","STAT","HELP","NOOP","MKD","RMD","PWD","CDUP","STOU",
468 "SMNT","SYST","SIZE","MDTM","UMASK","IDLE","CHMOD","LEXERR",
470 static const char *yyrule
[] = {
471 "$accept : cmd_list",
473 "cmd_list : cmd_list cmd",
474 "cmd_list : cmd_list rcmd",
475 "cmd : USER SP username CRLF",
476 "cmd : PASS SP password CRLF",
477 "cmd : PORT SP host_port CRLF",
479 "cmd : TYPE SP type_code CRLF",
480 "cmd : STRU SP struct_code CRLF",
481 "cmd : MODE SP mode_code CRLF",
482 "cmd : ALLO SP NUMBER CRLF",
483 "cmd : ALLO SP NUMBER SP R SP NUMBER CRLF",
484 "cmd : RETR check_login SP pathname CRLF",
485 "cmd : STOR check_login SP pathname CRLF",
486 "cmd : APPE check_login SP pathname CRLF",
487 "cmd : NLST check_login CRLF",
488 "cmd : NLST check_login SP STRING CRLF",
489 "cmd : LIST check_login CRLF",
490 "cmd : LIST check_login SP pathname CRLF",
491 "cmd : STAT check_login SP pathname CRLF",
493 "cmd : DELE check_login SP pathname CRLF",
494 "cmd : RNTO SP pathname CRLF",
496 "cmd : CWD check_login CRLF",
497 "cmd : CWD check_login SP pathname CRLF",
499 "cmd : HELP SP STRING CRLF",
501 "cmd : MKD check_login SP pathname CRLF",
502 "cmd : RMD check_login SP pathname CRLF",
503 "cmd : PWD check_login CRLF",
504 "cmd : CDUP check_login CRLF",
505 "cmd : SITE SP HELP CRLF",
506 "cmd : SITE SP HELP SP STRING CRLF",
507 "cmd : SITE SP UMASK check_login CRLF",
508 "cmd : SITE SP UMASK check_login SP octal_number CRLF",
509 "cmd : SITE SP CHMOD check_login SP octal_number SP pathname CRLF",
510 "cmd : SITE SP IDLE CRLF",
511 "cmd : SITE SP IDLE SP NUMBER CRLF",
512 "cmd : STOU check_login SP pathname CRLF",
514 "cmd : SIZE check_login SP pathname CRLF",
515 "cmd : MDTM check_login SP pathname CRLF",
518 "rcmd : RNFR check_login SP pathname CRLF",
522 "byte_size : NUMBER",
523 "host_port : NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER",
528 "type_code : A SP form_code",
530 "type_code : E SP form_code",
533 "type_code : L SP byte_size",
534 "type_code : L byte_size",
541 "pathname : pathstring",
542 "pathstring : STRING",
543 "octal_number : NUMBER",
557 /* define the initial stack-sizes */
560 #define YYMAXDEPTH YYSTACKSIZE
563 #define YYSTACKSIZE YYMAXDEPTH
565 #define YYSTACKSIZE 500
566 #define YYMAXDEPTH 500
570 #define YYINITSTACKSIZE 500
580 /* variables for the parser stack */
581 static YYSTACKDATA yystack
;
585 extern int YYLEX_DECL();
588 extern jmp_buf errcatch
;
590 static void upper(char *);
592 #define CMD 0 /* beginning of command */
593 #define ARGS 1 /* expect miscellaneous arguments */
594 #define STR1 2 /* expect SP followed by STRING */
595 #define STR2 3 /* expect STRING */
596 #define OSTR 4 /* optional SP then STRING */
597 #define ZSTR1 5 /* SP then optional STRING */
598 #define ZSTR2 6 /* optional STRING after SP */
599 #define SITECMD 7 /* SITE command */
600 #define NSTR 8 /* Number followed by a string */
602 struct tab cmdtab
[] = { /* In order defined in RFC 765 */
603 { "USER", USER
, STR1
, 1, "<sp> username" },
604 { "PASS", PASS
, ZSTR1
, 1, "<sp> password" },
605 { "ACCT", ACCT
, STR1
, 0, "(specify account)" },
606 { "SMNT", SMNT
, ARGS
, 0, "(structure mount)" },
607 { "REIN", REIN
, ARGS
, 0, "(reinitialize server state)" },
608 { "QUIT", QUIT
, ARGS
, 1, "(terminate service)", },
609 { "PORT", PORT
, ARGS
, 1, "<sp> b0, b1, b2, b3, b4" },
610 { "PASV", PASV
, ARGS
, 1, "(set server in passive mode)" },
611 { "TYPE", TYPE
, ARGS
, 1, "<sp> [ A | E | I | L ]" },
612 { "STRU", STRU
, ARGS
, 1, "(specify file structure)" },
613 { "MODE", MODE
, ARGS
, 1, "(specify transfer mode)" },
614 { "RETR", RETR
, STR1
, 1, "<sp> file-name" },
615 { "STOR", STOR
, STR1
, 1, "<sp> file-name" },
616 { "APPE", APPE
, STR1
, 1, "<sp> file-name" },
617 { "MLFL", MLFL
, OSTR
, 0, "(mail file)" },
618 { "MAIL", MAIL
, OSTR
, 0, "(mail to user)" },
619 { "MSND", MSND
, OSTR
, 0, "(mail send to terminal)" },
620 { "MSOM", MSOM
, OSTR
, 0, "(mail send to terminal or mailbox)" },
621 { "MSAM", MSAM
, OSTR
, 0, "(mail send to terminal and mailbox)" },
622 { "MRSQ", MRSQ
, OSTR
, 0, "(mail recipient scheme question)" },
623 { "MRCP", MRCP
, STR1
, 0, "(mail recipient)" },
624 { "ALLO", ALLO
, ARGS
, 1, "allocate storage (vacuously)" },
625 { "REST", REST
, ARGS
, 0, "(restart command)" },
626 { "RNFR", RNFR
, STR1
, 1, "<sp> file-name" },
627 { "RNTO", RNTO
, STR1
, 1, "<sp> file-name" },
628 { "ABOR", ABOR
, ARGS
, 1, "(abort operation)" },
629 { "DELE", DELE
, STR1
, 1, "<sp> file-name" },
630 { "CWD", CWD
, OSTR
, 1, "[ <sp> directory-name ]" },
631 { "XCWD", CWD
, OSTR
, 1, "[ <sp> directory-name ]" },
632 { "LIST", LIST
, OSTR
, 1, "[ <sp> path-name ]" },
633 { "NLST", NLST
, OSTR
, 1, "[ <sp> path-name ]" },
634 { "SITE", SITE
, SITECMD
, 1, "site-cmd [ <sp> arguments ]" },
635 { "SYST", SYST
, ARGS
, 1, "(get type of operating system)" },
636 { "STAT", STAT
, OSTR
, 1, "[ <sp> path-name ]" },
637 { "HELP", HELP
, OSTR
, 1, "[ <sp> <string> ]" },
638 { "NOOP", NOOP
, ARGS
, 1, "" },
639 { "MKD", MKD
, STR1
, 1, "<sp> path-name" },
640 { "XMKD", MKD
, STR1
, 1, "<sp> path-name" },
641 { "RMD", RMD
, STR1
, 1, "<sp> path-name" },
642 { "XRMD", RMD
, STR1
, 1, "<sp> path-name" },
643 { "PWD", PWD
, ARGS
, 1, "(return current directory)" },
644 { "XPWD", PWD
, ARGS
, 1, "(return current directory)" },
645 { "CDUP", CDUP
, ARGS
, 1, "(change to parent directory)" },
646 { "XCUP", CDUP
, ARGS
, 1, "(change to parent directory)" },
647 { "STOU", STOU
, STR1
, 1, "<sp> file-name" },
648 { "SIZE", SIZE
, OSTR
, 1, "<sp> path-name" },
649 { "MDTM", MDTM
, OSTR
, 1, "<sp> path-name" },
653 struct tab sitetab
[] = {
654 { "UMASK", UMASK
, ARGS
, 1, "[ <sp> umask ]" },
655 { "IDLE", IDLE
, ARGS
, 1, "[ <sp> maximum-idle-time ]" },
656 { "CHMOD", CHMOD
, NSTR
, 1, "<sp> mode <sp> file-name" },
657 { "HELP", HELP
, OSTR
, 1, "[ <sp> <string> ]" },
662 lookup(struct tab
*p
, char *cmd
)
665 for (; p
->name
!= 0; p
++)
666 if (strcmp(cmd
, p
->name
) == 0)
671 #include <arpa/telnet.h>
674 * get_line - a hacked up version of fgets to ignore TELNET escape codes.
677 get_line(char *s
, int n
, FILE *iop
)
683 /* tmpline may contain saved command from urgent mode interruption */
684 for (c
= 0; tmpline
[c
] != '\0' && --n
> 0; ++c
) {
686 if (tmpline
[c
] == '\n') {
689 syslog(LOG_DEBUG
, "command: %s", s
);
696 while ((c
= getc(iop
)) != EOF
) {
699 if ((c
= getc(iop
)) != EOF
) {
705 printf("%c%c%c", IAC
, DONT
, 0377&c
);
706 (void) fflush(stdout
);
711 printf("%c%c%c", IAC
, WONT
, 0377&c
);
712 (void) fflush(stdout
);
717 continue; /* ignore command */
722 if (--n
<= 0 || c
== '\n')
725 if (c
== EOF
&& cs
== s
)
729 syslog(LOG_DEBUG
, "command: %s", s
);
740 "Timeout (%d seconds): closing control connection.", timeout
);
744 "User %s timed out after %d seconds at %s",
745 (pw
? pw
-> pw_name
: "unknown"), timeout
, ctime(&now
));
753 static int cpos
, state
;
754 register char *cp
, *cp2
;
755 register struct tab
*p
;
763 (void) signal(SIGALRM
, toolong
);
764 (void) alarm((unsigned) timeout
);
765 if (get_line(cbuf
, sizeof(cbuf
)-1, stdin
) == 0) {
766 reply(221, "You could at least say goodbye.");
771 if (strncasecmp(cbuf
, "PASS", 4) != 0)
772 setproctitle("%s: %s", proctitle
, cbuf
);
773 #endif /* SETPROCTITLE */
774 if ((cp
= strchr(cbuf
, '\r'))) {
778 if ((cp
= strpbrk(cbuf
, " \n")))
779 cpos
= (int) (cp
- cbuf
);
785 p
= lookup(cmdtab
, cbuf
);
788 if (p
->implemented
== 0) {
794 *(const char **)(&yylval
) = p
->name
;
800 if (cbuf
[cpos
] == ' ') {
805 if ((cp2
= strpbrk(cp
, " \n")))
806 cpos
= (int) (cp2
- cbuf
);
810 p
= lookup(sitetab
, cp
);
813 if (p
->implemented
== 0) {
820 *(const char **)(&yylval
) = p
->name
;
827 if (cbuf
[cpos
] == '\n') {
836 if (cbuf
[cpos
] == ' ') {
847 if (cbuf
[cpos
] == '\n') {
855 n
= (int) strlen(cp
);
858 * Make sure the string is nonempty and \n terminated.
860 if (n
> 1 && cbuf
[cpos
] == '\n') {
862 *(char **)&yylval
= copy(cp
);
870 if (cbuf
[cpos
] == ' ') {
874 if (isdigit(cbuf
[cpos
])) {
876 while (isdigit(cbuf
[++cpos
]))
880 yylval
.ival
= atoi(cp
);
889 if (isdigit(cbuf
[cpos
])) {
891 while (isdigit(cbuf
[++cpos
]))
895 yylval
.ival
= atoi(cp
);
899 switch (cbuf
[cpos
++]) {
963 fatal("Unknown state in scanner.");
986 p
= (char * )malloc(strlen(s
) + 1);
988 fatal("Ran out of memory.");
995 help(struct tab
*ctab
, char *s
)
997 register struct tab
*c
;
998 register int width
, NCMDS
;
999 const char *help_type
;
1001 if (ctab
== sitetab
)
1002 help_type
= "SITE ";
1005 width
= 0, NCMDS
= 0;
1006 for (c
= ctab
; c
->name
!= 0; c
++) {
1007 int len
= (int) strlen(c
->name
);
1013 width
= (width
+ 8) &~ 7;
1015 register int i
, j
, w
;
1018 lreply(214, "The following %scommands are recognized %s.",
1019 help_type
, "(* =>'s unimplemented)");
1020 columns
= 76 / width
;
1023 lines
= (NCMDS
+ columns
- 1) / columns
;
1024 for (i
= 0; i
< lines
; i
++) {
1026 for (j
= 0; j
< columns
; j
++) {
1027 c
= ctab
+ j
* lines
+ i
;
1028 assert(c
->name
!= 0);
1029 printf("%s%c", c
->name
,
1030 c
->implemented
? ' ' : '*');
1031 if (c
+ lines
>= &ctab
[NCMDS
])
1033 w
= (int) strlen(c
->name
) + 1;
1041 (void) fflush(stdout
);
1042 reply(214, "Direct comments to ftp-bugs@%s.", hostname
);
1046 c
= lookup(ctab
, s
);
1047 if (c
== (struct tab
*)0) {
1048 reply(502, "Unknown command %s.", s
);
1052 reply(214, "Syntax: %s%s %s", help_type
, c
->name
, c
->help
);
1054 reply(214, "%s%-*s\t%s; unimplemented.", help_type
, width
,
1059 sizecmd(char *filename
)
1065 if (stat(filename
, &stbuf
) < 0 ||
1066 (stbuf
.st_mode
&S_IFMT
) != S_IFREG
)
1067 reply(550, "%s: not a plain file.", filename
);
1069 #ifdef HAVE_LONG_LONG
1070 reply(213, "%llu", (long long) stbuf
.st_size
);
1072 reply(213, "%lu", stbuf
.st_size
);
1077 register int c
, count
;
1079 fin
= fopen(filename
, "r");
1081 perror_reply(550, filename
);
1084 if (fstat(fileno(fin
), &stbuf
) < 0 ||
1085 (stbuf
.st_mode
&S_IFMT
) != S_IFREG
) {
1086 reply(550, "%s: not a plain file.", filename
);
1092 while((c
=getc(fin
)) != EOF
) {
1093 if (c
== '\n') /* will get expanded to \r\n */
1099 reply(213, "%ld", count
);
1102 reply(504, "SIZE not implemented for Type %c.", "?AEIL"[type
]);
1105 #line 1103 "ftp.tab.c"
1108 #include <stdio.h> /* needed for printf */
1111 #include <stdlib.h> /* needed for malloc, etc */
1112 #include <string.h> /* needed for memset */
1114 /* allocate initial stack or double stack size, up to YYMAXDEPTH */
1115 static int yygrowstack(YYSTACKDATA
*data
)
1122 if ((newsize
= data
->stacksize
) == 0)
1123 newsize
= YYINITSTACKSIZE
;
1124 else if (newsize
>= YYMAXDEPTH
)
1126 else if ((newsize
*= 2) > YYMAXDEPTH
)
1127 newsize
= YYMAXDEPTH
;
1129 i
= (int) (data
->s_mark
- data
->s_base
);
1130 newss
= (short *)realloc(data
->s_base
, newsize
* sizeof(*newss
));
1134 data
->s_base
= newss
;
1135 data
->s_mark
= newss
+ i
;
1137 newvs
= (YYSTYPE
*)realloc(data
->l_base
, newsize
* sizeof(*newvs
));
1141 data
->l_base
= newvs
;
1142 data
->l_mark
= newvs
+ i
;
1144 data
->stacksize
= newsize
;
1145 data
->s_last
= data
->s_base
+ newsize
- 1;
1149 #if YYPURE || defined(YY_NO_LEAKS)
1150 static void yyfreestack(YYSTACKDATA
*data
)
1154 memset(data
, 0, sizeof(*data
));
1157 #define yyfreestack(data) /* nothing */
1160 #define YYABORT goto yyabort
1161 #define YYREJECT goto yyabort
1162 #define YYACCEPT goto yyaccept
1163 #define YYERROR goto yyerrlab
1168 int yym
, yyn
, yystate
;
1172 if ((yys
= getenv("YYDEBUG")) != 0)
1175 if (yyn
>= '0' && yyn
<= '9')
1176 yydebug
= yyn
- '0';
1186 memset(&yystack
, 0, sizeof(yystack
));
1189 if (yystack
.s_base
== NULL
&& yygrowstack(&yystack
)) goto yyoverflow
;
1190 yystack
.s_mark
= yystack
.s_base
;
1191 yystack
.l_mark
= yystack
.l_base
;
1193 *yystack
.s_mark
= 0;
1196 if ((yyn
= yydefred
[yystate
]) != 0) goto yyreduce
;
1199 if ((yychar
= YYLEX
) < 0) yychar
= 0;
1204 if (yychar
<= YYMAXTOKEN
) yys
= yyname
[yychar
];
1205 if (!yys
) yys
= "illegal-symbol";
1206 printf("%sdebug: state %d, reading %d (%s)\n",
1207 YYPREFIX
, yystate
, yychar
, yys
);
1211 if ((yyn
= yysindex
[yystate
]) && (yyn
+= yychar
) >= 0 &&
1212 yyn
<= YYTABLESIZE
&& yycheck
[yyn
] == yychar
)
1216 printf("%sdebug: state %d, shifting to state %d\n",
1217 YYPREFIX
, yystate
, yytable
[yyn
]);
1219 if (yystack
.s_mark
>= yystack
.s_last
&& yygrowstack(&yystack
))
1223 yystate
= yytable
[yyn
];
1224 *++yystack
.s_mark
= yytable
[yyn
];
1225 *++yystack
.l_mark
= yylval
;
1227 if (yyerrflag
> 0) --yyerrflag
;
1230 if ((yyn
= yyrindex
[yystate
]) && (yyn
+= yychar
) >= 0 &&
1231 yyn
<= YYTABLESIZE
&& yycheck
[yyn
] == yychar
)
1236 if (yyerrflag
) goto yyinrecovery
;
1238 yyerror("syntax error");
1251 if ((yyn
= yysindex
[*yystack
.s_mark
]) && (yyn
+= YYERRCODE
) >= 0 &&
1252 yyn
<= YYTABLESIZE
&& yycheck
[yyn
] == YYERRCODE
)
1256 printf("%sdebug: state %d, error recovery shifting\
1257 to state %d\n", YYPREFIX
, *yystack
.s_mark
, yytable
[yyn
]);
1259 if (yystack
.s_mark
>= yystack
.s_last
&& yygrowstack(&yystack
))
1263 yystate
= yytable
[yyn
];
1264 *++yystack
.s_mark
= yytable
[yyn
];
1265 *++yystack
.l_mark
= yylval
;
1272 printf("%sdebug: error recovery discarding state %d\n",
1273 YYPREFIX
, *yystack
.s_mark
);
1275 if (yystack
.s_mark
<= yystack
.s_base
) goto yyabort
;
1283 if (yychar
== 0) goto yyabort
;
1288 if (yychar
<= YYMAXTOKEN
) yys
= yyname
[yychar
];
1289 if (!yys
) yys
= "illegal-symbol";
1290 printf("%sdebug: state %d, error recovery discards token %d (%s)\n",
1291 YYPREFIX
, yystate
, yychar
, yys
);
1301 printf("%sdebug: state %d, reducing by rule %d (%s)\n",
1302 YYPREFIX
, yystate
, yyn
, yyrule
[yyn
]);
1306 yyval
= yystack
.l_mark
[1-yym
];
1308 memset(&yyval
, 0, sizeof yyval
);
1314 fromname
= (char *) 0;
1320 user(yystack
.l_mark
[-1].sval
);
1321 free(yystack
.l_mark
[-1].sval
);
1327 pass(yystack
.l_mark
[-1].sval
);
1328 free(yystack
.l_mark
[-1].sval
);
1336 (void) close(pdata
);
1339 reply(200, "PORT command successful.");
1354 if (cmd_form
== FORM_N
) {
1355 reply(200, "Type set to A.");
1359 reply(504, "Form must be N.");
1363 reply(504, "Type E not implemented.");
1367 reply(200, "Type set to I.");
1373 if (cmd_bytesz
== 8) {
1375 "Type set to L (byte size 8).");
1378 reply(504, "Byte size must be 8.");
1379 #else /* NBBY == 8 */
1380 UNIMPLEMENTED
for NBBY
!= 8
1381 #endif /* NBBY == 8 */
1388 switch (yystack
.l_mark
[-1].ival
) {
1391 reply(200, "STRU F ok.");
1395 reply(504, "Unimplemented STRU type.");
1402 switch (yystack
.l_mark
[-1].ival
) {
1405 reply(200, "MODE S ok.");
1409 reply(502, "Unimplemented MODE type.");
1416 reply(202, "ALLO command ignored.");
1422 reply(202, "ALLO command ignored.");
1428 if (yystack
.l_mark
[-3].ival
&& yystack
.l_mark
[-1].sval
!= 0)
1429 retrieve((char *) 0, yystack
.l_mark
[-1].sval
);
1430 if (yystack
.l_mark
[-1].sval
!= 0)
1431 free(yystack
.l_mark
[-1].sval
);
1437 if (yystack
.l_mark
[-3].ival
&& yystack
.l_mark
[-1].sval
!= 0)
1438 store(yystack
.l_mark
[-1].sval
, "w", 0);
1439 if (yystack
.l_mark
[-1].sval
!= 0)
1440 free(yystack
.l_mark
[-1].sval
);
1446 if (yystack
.l_mark
[-3].ival
&& yystack
.l_mark
[-1].sval
!= 0)
1447 store(yystack
.l_mark
[-1].sval
, "a", 0);
1448 if (yystack
.l_mark
[-1].sval
!= 0)
1449 free(yystack
.l_mark
[-1].sval
);
1455 if (yystack
.l_mark
[-1].ival
)
1456 send_file_list(".");
1462 if (yystack
.l_mark
[-3].ival
&& yystack
.l_mark
[-1].sval
!= 0)
1463 send_file_list((char *) yystack
.l_mark
[-1].sval
);
1464 if (yystack
.l_mark
[-1].sval
!= 0)
1465 free((char *) yystack
.l_mark
[-1].sval
);
1471 if (yystack
.l_mark
[-1].ival
)
1472 retrieve("/bin/ls -lgA", "");
1478 if (yystack
.l_mark
[-3].ival
&& yystack
.l_mark
[-1].sval
!= 0)
1479 retrieve("/bin/ls -lgA %s", yystack
.l_mark
[-1].sval
);
1480 if (yystack
.l_mark
[-1].sval
!= 0)
1481 free(yystack
.l_mark
[-1].sval
);
1487 if (yystack
.l_mark
[-3].ival
&& yystack
.l_mark
[-1].sval
!= 0)
1488 statfilecmd(yystack
.l_mark
[-1].sval
);
1489 if (yystack
.l_mark
[-1].sval
!= 0)
1490 free(yystack
.l_mark
[-1].sval
);
1502 if (yystack
.l_mark
[-3].ival
&& yystack
.l_mark
[-1].sval
!= 0)
1503 remove((char *) yystack
.l_mark
[-1].sval
);
1504 if (yystack
.l_mark
[-1].sval
!= 0)
1505 free((char *) yystack
.l_mark
[-1].sval
);
1512 renamecmd(fromname
, (char *) yystack
.l_mark
[-1].sval
);
1514 fromname
= (char *) 0;
1516 reply(503, "Bad sequence of commands.");
1518 free((char *) yystack
.l_mark
[-1].sval
);
1524 reply(225, "ABOR command successful.");
1530 if (yystack
.l_mark
[-1].ival
)
1537 if (yystack
.l_mark
[-3].ival
&& yystack
.l_mark
[-1].sval
!= 0)
1538 cwd((char *) yystack
.l_mark
[-1].sval
);
1539 if (yystack
.l_mark
[-1].sval
!= 0)
1540 free((char *) yystack
.l_mark
[-1].sval
);
1546 help(cmdtab
, (char *) 0);
1552 register char *cp
= (char *)yystack
.l_mark
[-1].sval
;
1554 if (strncasecmp(cp
, "SITE", 4) == 0) {
1555 cp
= (char *)yystack
.l_mark
[-1].sval
+ 4;
1561 help(sitetab
, (char *) 0);
1563 help(cmdtab
, (char *) yystack
.l_mark
[-1].sval
);
1569 reply(200, "NOOP command successful.");
1575 if (yystack
.l_mark
[-3].ival
&& yystack
.l_mark
[-1].sval
!= 0)
1576 makedir((char *) yystack
.l_mark
[-1].sval
);
1577 if (yystack
.l_mark
[-1].sval
!= 0)
1578 free((char *) yystack
.l_mark
[-1].sval
);
1584 if (yystack
.l_mark
[-3].ival
&& yystack
.l_mark
[-1].sval
!= 0)
1585 removedir((char *) yystack
.l_mark
[-1].sval
);
1586 if (yystack
.l_mark
[-1].sval
!= 0)
1587 free((char *) yystack
.l_mark
[-1].sval
);
1593 if (yystack
.l_mark
[-1].ival
)
1600 if (yystack
.l_mark
[-1].ival
)
1607 help(sitetab
, (char *) 0);
1613 help(sitetab
, (char *) yystack
.l_mark
[-1].sval
);
1621 if (yystack
.l_mark
[-1].ival
) {
1623 (void) umask(oldmask
);
1624 reply(200, "Current UMASK is %03o", oldmask
);
1633 if (yystack
.l_mark
[-3].ival
) {
1634 if ((yystack
.l_mark
[-1].ival
== -1) || (yystack
.l_mark
[-1].ival
> 0777)) {
1635 reply(501, "Bad UMASK value");
1637 oldmask
= umask(yystack
.l_mark
[-1].ival
);
1639 "UMASK set to %03o (was %03o)",
1640 yystack
.l_mark
[-1].ival
, oldmask
);
1648 if (yystack
.l_mark
[-5].ival
&& (yystack
.l_mark
[-1].sval
!= 0)) {
1649 if (yystack
.l_mark
[-3].ival
> 0777)
1651 "CHMOD: Mode value must be between 0 and 0777");
1652 else if (chmod((char *) yystack
.l_mark
[-1].sval
, yystack
.l_mark
[-3].ival
) < 0)
1653 perror_reply(550, (char *) yystack
.l_mark
[-1].sval
);
1655 reply(200, "CHMOD command successful.");
1657 if (yystack
.l_mark
[-1].sval
!= 0)
1658 free((char *) yystack
.l_mark
[-1].sval
);
1665 "Current IDLE time limit is %d seconds; max %d",
1666 timeout
, maxtimeout
);
1672 if (yystack
.l_mark
[-1].ival
< 30 || yystack
.l_mark
[-1].ival
> maxtimeout
) {
1674 "Maximum IDLE time must be between 30 and %d seconds",
1677 timeout
= yystack
.l_mark
[-1].ival
;
1678 (void) alarm((unsigned) timeout
);
1680 "Maximum IDLE time set to %d seconds",
1688 if (yystack
.l_mark
[-3].ival
&& yystack
.l_mark
[-1].sval
!= 0)
1689 store((char *) yystack
.l_mark
[-1].sval
, "w", 1);
1690 if (yystack
.l_mark
[-1].sval
!= 0)
1691 free((char *) yystack
.l_mark
[-1].sval
);
1699 reply(215, "UNIX Type: L%d Version: BSD-%d",
1702 reply(215, "UNIX Type: L%d", NBBY
);
1705 reply(215, "UNKNOWN Type: L%d", NBBY
);
1712 if (yystack
.l_mark
[-3].ival
&& yystack
.l_mark
[-1].sval
!= 0)
1713 sizecmd((char *) yystack
.l_mark
[-1].sval
);
1714 if (yystack
.l_mark
[-1].sval
!= 0)
1715 free((char *) yystack
.l_mark
[-1].sval
);
1721 if (yystack
.l_mark
[-3].ival
&& yystack
.l_mark
[-1].sval
!= 0) {
1723 if (stat((char *) yystack
.l_mark
[-1].sval
, &stbuf
) < 0)
1724 perror_reply(550, "%s", (char *) yystack
.l_mark
[-1].sval
);
1725 else if ((stbuf
.st_mode
&S_IFMT
) != S_IFREG
) {
1726 reply(550, "%s: not a plain file.",
1727 (char *) yystack
.l_mark
[-1].sval
);
1729 register struct tm
*t
;
1730 t
= gmtime(&stbuf
.st_mtime
);
1732 "%04d%02d%02d%02d%02d%02d",
1734 t
->tm_mon
+1, t
->tm_mday
,
1735 t
->tm_hour
, t
->tm_min
, t
->tm_sec
);
1738 if (yystack
.l_mark
[-1].sval
!= 0)
1739 free((char *) yystack
.l_mark
[-1].sval
);
1745 reply(221, "Goodbye.");
1758 if (yystack
.l_mark
[-3].ival
&& yystack
.l_mark
[-1].sval
) {
1759 fromname
= renamefrom((char *) yystack
.l_mark
[-1].sval
);
1760 if (fromname
== (char *) 0 && yystack
.l_mark
[-1].sval
) {
1761 free((char *) yystack
.l_mark
[-1].sval
);
1769 *(const char **)(&(yyval
.sval
)) = "";
1775 register char *a
, *p
;
1777 a
= (char *)&data_dest
.sin_addr
;
1778 a
[0] = (char) yystack
.l_mark
[-10].ival
;
1779 a
[1] = (char) yystack
.l_mark
[-8].ival
;
1780 a
[2] = (char) yystack
.l_mark
[-6].ival
;
1781 a
[3] = (char) yystack
.l_mark
[-4].ival
;
1782 p
= (char *)&data_dest
.sin_port
;
1783 p
[0] = (char) yystack
.l_mark
[-2].ival
;
1784 p
[1] = (char) yystack
.l_mark
[0].ival
;
1785 data_dest
.sin_family
= AF_INET
;
1791 yyval
.ival
= FORM_N
;
1797 yyval
.ival
= FORM_T
;
1803 yyval
.ival
= FORM_C
;
1817 cmd_form
= yystack
.l_mark
[0].ival
;
1831 cmd_form
= yystack
.l_mark
[0].ival
;
1851 cmd_bytesz
= yystack
.l_mark
[0].ival
;
1858 cmd_bytesz
= yystack
.l_mark
[0].ival
;
1864 yyval
.ival
= STRU_F
;
1870 yyval
.ival
= STRU_R
;
1876 yyval
.ival
= STRU_P
;
1882 yyval
.ival
= MODE_S
;
1888 yyval
.ival
= MODE_B
;
1894 yyval
.ival
= MODE_C
;
1901 * Problem: this production is used for all pathname
1902 * processing, but only gives a 550 error reply.
1903 * This is a valid reply in some cases but not in others.
1905 if (logged_in
&& yystack
.l_mark
[0].sval
&& strncmp((char *) yystack
.l_mark
[0].sval
, "~", 1) == 0) {
1906 *(char **)&(yyval
.sval
) = *glob((char *) yystack
.l_mark
[0].sval
);
1908 reply(550, globerr
);
1911 free((char *) yystack
.l_mark
[0].sval
);
1913 yyval
.sval
= yystack
.l_mark
[0].sval
;
1919 register int ret
, dec
, multby
, digit
;
1922 * Convert a number that was read as decimal number
1923 * to what it would be if it had been read as octal.
1925 dec
= yystack
.l_mark
[0].ival
;
1934 ret
+= digit
* multby
;
1947 reply(530, "Please login with USER and PASS.");
1952 #line 1950 "ftp.tab.c"
1954 yystack
.s_mark
-= yym
;
1955 yystate
= *yystack
.s_mark
;
1956 yystack
.l_mark
-= yym
;
1958 if (yystate
== 0 && yym
== 0)
1962 printf("%sdebug: after reduction, shifting from state 0 to\
1963 state %d\n", YYPREFIX
, YYFINAL
);
1966 *++yystack
.s_mark
= YYFINAL
;
1967 *++yystack
.l_mark
= yyval
;
1970 if ((yychar
= YYLEX
) < 0) yychar
= 0;
1975 if (yychar
<= YYMAXTOKEN
) yys
= yyname
[yychar
];
1976 if (!yys
) yys
= "illegal-symbol";
1977 printf("%sdebug: state %d, reading %d (%s)\n",
1978 YYPREFIX
, YYFINAL
, yychar
, yys
);
1982 if (yychar
== 0) goto yyaccept
;
1985 if ((yyn
= yygindex
[yym
]) && (yyn
+= yystate
) >= 0 &&
1986 yyn
<= YYTABLESIZE
&& yycheck
[yyn
] == yystate
)
1987 yystate
= yytable
[yyn
];
1989 yystate
= yydgoto
[yym
];
1992 printf("%sdebug: after reduction, shifting from state %d \
1993 to state %d\n", YYPREFIX
, *yystack
.s_mark
, yystate
);
1995 if (yystack
.s_mark
>= yystack
.s_last
&& yygrowstack(&yystack
))
1999 *++yystack
.s_mark
= (short) yystate
;
2000 *++yystack
.l_mark
= yyval
;
2004 yyerror("yacc stack overflow");
2007 yyfreestack(&yystack
);
2011 yyfreestack(&yystack
);