home *** CD-ROM | disk | FTP | other *** search
/ Fish 'n' More 2 / fishmore-publicdomainlibraryvol.ii1991xetec.iso / fish / misc_utils / yacc_419 / src / test / ftp.tab.c < prev    next >
C/C++ Source or Header  |  1990-06-03  |  40KB  |  1,734 lines

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