home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 342a.lha / Yacc_v1.0a / test / ftp.tab.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-02-05  |  38.9 KB  |  1,736 lines

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