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