home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / c / compcomp / byacc / ftp_tab.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-01-08  |  40.6 KB  |  1,740 lines

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