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