2 static const char yysccsid[] = "@(#)yaccpar 1.9 (Berkeley) 02/21/93";
13 #define yyclearin (yychar = YYEMPTY)
14 #define yyerrok (yyerrflag = 0)
15 #define YYRECOVERING() (yyerrflag != 0)
17 /* compatibility with bison */
19 /* compatibility with FreeBSD */
20 #ifdef YYPARSE_PARAM_TYPE
21 #define YYPARSE_DECL() yyparse(YYPARSE_PARAM_TYPE YYPARSE_PARAM)
23 #define YYPARSE_DECL() yyparse(void *YYPARSE_PARAM)
26 #define YYPARSE_DECL() yyparse(void)
27 #endif /* YYPARSE_PARAM */
29 extern int YYPARSE_DECL();
31 static int yygrowstack(void);
32 #define yyparse ftp_parse
34 #define yyerror ftp_error
35 #define yychar ftp_char
37 #define yylval ftp_lval
38 #define yydebug ftp_debug
39 #define yynerrs ftp_nerrs
40 #define yyerrflag ftp_errflag
47 #define yydefred ftp_defred
48 #define yydgoto ftp_dgoto
49 #define yysindex ftp_sindex
50 #define yyrindex ftp_rindex
51 #define yygindex ftp_gindex
52 #define yytable ftp_table
53 #define yycheck ftp_check
54 #define yyname ftp_name
55 #define yyrule ftp_rule
56 #define YYPREFIX "ftp_"
60 static char sccsid[] = "@(#)ftpcmd.y 5.20.1.1 (Berkeley) 3/2/89";
63 #include <sys/param.h>
64 #include <sys/socket.h>
66 #include <netinet/in.h>
79 extern struct sockaddr_in data_dest;
81 extern struct passwd *pw;
88 extern int maxtimeout;
90 extern char hostname[], remotehost[];
91 extern char proctitle[];
93 extern int usedefault;
95 extern char tmpline[];
100 static int cmd_bytesz;
105 #line 106 "ftp.tab.c"
169 #define YYERRCODE 256
170 static const short ftp_lhs[] = { -1,
171 0, 0, 0, 1, 1, 1, 1, 1, 1, 1,
172 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
173 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
174 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
175 1, 1, 1, 1, 1, 1, 2, 3, 4, 4,
176 12, 5, 13, 13, 13, 6, 6, 6, 6, 6,
177 6, 6, 6, 7, 7, 7, 8, 8, 8, 10,
180 static const short ftp_len[] = { 2,
181 0, 2, 2, 4, 4, 4, 2, 4, 4, 4,
182 4, 8, 5, 5, 5, 3, 5, 3, 5, 5,
183 2, 5, 4, 2, 3, 5, 2, 4, 2, 5,
184 5, 3, 3, 4, 6, 5, 7, 9, 4, 6,
185 5, 2, 5, 5, 2, 2, 5, 1, 0, 1,
186 1, 11, 1, 1, 1, 1, 3, 1, 3, 1,
187 1, 3, 2, 1, 1, 1, 1, 1, 1, 1,
190 static const short ftp_defred[] = { 1,
191 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
192 73, 73, 73, 0, 73, 0, 0, 73, 73, 73,
193 73, 0, 0, 0, 0, 73, 73, 73, 73, 73,
194 0, 73, 73, 2, 3, 46, 0, 0, 45, 0,
195 7, 0, 0, 0, 0, 0, 0, 0, 0, 0,
196 24, 0, 0, 0, 0, 0, 21, 0, 0, 27,
197 29, 0, 0, 0, 0, 0, 42, 0, 0, 48,
198 0, 50, 0, 0, 0, 0, 0, 60, 0, 0,
199 64, 66, 65, 0, 68, 69, 67, 0, 0, 0,
200 0, 0, 0, 71, 0, 70, 0, 0, 25, 0,
201 18, 0, 16, 0, 73, 0, 73, 0, 0, 0,
202 0, 32, 33, 0, 0, 0, 4, 5, 0, 6,
203 0, 0, 0, 51, 63, 8, 9, 10, 0, 0,
204 0, 0, 11, 0, 23, 0, 0, 0, 0, 0,
205 34, 0, 0, 39, 0, 0, 28, 0, 0, 0,
206 0, 0, 0, 55, 53, 54, 57, 59, 62, 13,
207 14, 15, 0, 47, 22, 26, 19, 17, 0, 0,
208 36, 0, 0, 20, 30, 31, 41, 43, 44, 0,
209 0, 35, 72, 0, 40, 0, 0, 0, 37, 0,
210 0, 12, 0, 0, 38, 0, 0, 0, 52,
212 static const short ftp_dgoto[] = { 1,
213 34, 35, 71, 73, 75, 80, 84, 88, 45, 95,
216 static const short ftp_sindex[] = { 0,
217 -224, -247, -239, -236, -232, -222, -204, -200, -181, -177,
218 0, 0, 0, -166, 0, -161, -199, 0, 0, 0,
219 0, -160, -159, -264, -158, 0, 0, 0, 0, 0,
220 -157, 0, 0, 0, 0, 0, -167, -162, 0, -156,
221 0, -250, -198, -165, -155, -154, -153, -151, -150, -152,
222 0, -145, -252, -229, -217, -302, 0, -144, -146, 0,
223 0, -142, -141, -140, -139, -137, 0, -136, -135, 0,
224 -134, 0, -133, -132, -130, -131, -128, 0, -249, -127,
225 0, 0, 0, -126, 0, 0, 0, -125, -152, -152,
226 -152, -205, -152, 0, -124, 0, -152, -152, 0, -152,
227 0, -143, 0, -173, 0, -171, 0, -152, -123, -152,
228 -152, 0, 0, -152, -152, -152, 0, 0, -138, 0,
229 -164, -164, -122, 0, 0, 0, 0, 0, -121, -120,
230 -118, -148, 0, -117, 0, -116, -115, -114, -113, -112,
231 0, -163, -111, 0, -110, -109, 0, -107, -106, -105,
232 -104, -103, -129, 0, 0, 0, 0, 0, 0, 0,
233 0, 0, -101, 0, 0, 0, 0, 0, -100, -102,
234 0, -98, -102, 0, 0, 0, 0, 0, 0, -99,
235 -97, 0, 0, -95, 0, -96, -94, -92, 0, -152,
236 -93, 0, -91, -90, 0, -88, -87, -86, 0,
238 static const short ftp_rindex[] = { 0,
239 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
240 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
241 0, 0, -83, 0, 0, 0, 0, 0, 0, 0,
242 0, 0, 0, 0, 0, 0, 0, -82, 0, 0,
243 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
244 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
245 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
246 0, 0, 0, 0, 0, -81, -80, 0, -158, 0,
247 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
248 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
249 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
250 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
251 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
252 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
253 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
254 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
255 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
256 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
257 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
258 0, 0, 0, 0, 0, 0, 0, 0, 0,
260 static const short ftp_gindex[] = { 0,
261 0, 0, 0, 0, 0, 0, 0, 0, 16, -89,
264 #define YYTABLESIZE 190
265 static const short ftp_table[] = { 129,
266 130, 131, 104, 134, 59, 60, 76, 136, 137, 77,
267 138, 78, 79, 105, 106, 107, 98, 99, 146, 123,
268 148, 149, 36, 124, 150, 151, 152, 46, 47, 37,
269 49, 2, 38, 52, 53, 54, 55, 39, 58, 100,
270 101, 62, 63, 64, 65, 66, 40, 68, 69, 3,
271 4, 102, 103, 5, 6, 7, 8, 9, 10, 11,
272 12, 13, 81, 132, 133, 41, 82, 83, 42, 14,
273 51, 15, 16, 17, 18, 19, 20, 21, 22, 23,
274 24, 25, 26, 27, 28, 29, 30, 43, 31, 32,
275 33, 44, 85, 86, 154, 140, 141, 143, 144, 155,
276 193, 87, 48, 156, 70, 170, 171, 50, 56, 72,
277 57, 61, 67, 89, 90, 91, 74, 163, 93, 94,
278 142, 92, 145, 97, 108, 109, 110, 111, 139, 112,
279 113, 114, 115, 116, 153, 117, 118, 121, 119, 120,
280 122, 180, 126, 127, 128, 135, 147, 186, 160, 161,
281 124, 162, 164, 165, 166, 167, 168, 159, 173, 169,
282 174, 172, 175, 176, 177, 178, 179, 181, 158, 182,
283 183, 185, 190, 187, 189, 188, 191, 192, 195, 194,
284 196, 0, 0, 198, 197, 73, 199, 49, 56, 58,
286 static const short ftp_check[] = { 89,
287 90, 91, 305, 93, 269, 270, 257, 97, 98, 260,
288 100, 262, 263, 316, 317, 318, 269, 270, 108, 269,
289 110, 111, 270, 273, 114, 115, 116, 12, 13, 269,
290 15, 256, 269, 18, 19, 20, 21, 270, 23, 269,
291 270, 26, 27, 28, 29, 30, 269, 32, 33, 274,
292 275, 269, 270, 278, 279, 280, 281, 282, 283, 284,
293 285, 286, 261, 269, 270, 270, 265, 266, 269, 294,
294 270, 296, 297, 298, 299, 300, 301, 302, 303, 304,
295 305, 306, 307, 308, 309, 310, 311, 269, 313, 314,
296 315, 269, 258, 259, 259, 269, 270, 269, 270, 264,
297 190, 267, 269, 268, 272, 269, 270, 269, 269, 272,
298 270, 270, 270, 269, 269, 269, 273, 266, 269, 272,
299 105, 273, 107, 269, 269, 272, 269, 269, 272, 270,
300 270, 269, 269, 269, 273, 270, 270, 269, 271, 270,
301 269, 271, 270, 270, 270, 270, 270, 173, 270, 270,
302 273, 270, 270, 270, 270, 270, 270, 123, 269, 272,
303 270, 273, 270, 270, 270, 270, 270, 269, 122, 270,
304 273, 270, 269, 273, 270, 273, 271, 270, 270, 273,
305 271, -1, -1, 271, 273, 269, 273, 270, 270, 270,
311 #define YYMAXTOKEN 319
313 static const char *ftp_name[] = {
315 "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,
316 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
317 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
318 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
319 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
320 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
321 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",
322 "P","R","S","T","SP","CRLF","COMMA","STRING","NUMBER","USER","PASS","ACCT",
323 "REIN","QUIT","PORT","PASV","TYPE","STRU","MODE","RETR","STOR","APPE","MLFL",
324 "MAIL","MSND","MSOM","MSAM","MRSQ","MRCP","ALLO","REST","RNFR","RNTO","ABOR",
325 "DELE","CWD","LIST","NLST","SITE","STAT","HELP","NOOP","MKD","RMD","PWD","CDUP",
326 "STOU","SMNT","SYST","SIZE","MDTM","UMASK","IDLE","CHMOD","LEXERR",
328 static const char *ftp_rule[] = {
329 "$accept : cmd_list",
331 "cmd_list : cmd_list cmd",
332 "cmd_list : cmd_list rcmd",
333 "cmd : USER SP username CRLF",
334 "cmd : PASS SP password CRLF",
335 "cmd : PORT SP host_port CRLF",
337 "cmd : TYPE SP type_code CRLF",
338 "cmd : STRU SP struct_code CRLF",
339 "cmd : MODE SP mode_code CRLF",
340 "cmd : ALLO SP NUMBER CRLF",
341 "cmd : ALLO SP NUMBER SP R SP NUMBER CRLF",
342 "cmd : RETR check_login SP pathname CRLF",
343 "cmd : STOR check_login SP pathname CRLF",
344 "cmd : APPE check_login SP pathname CRLF",
345 "cmd : NLST check_login CRLF",
346 "cmd : NLST check_login SP STRING CRLF",
347 "cmd : LIST check_login CRLF",
348 "cmd : LIST check_login SP pathname CRLF",
349 "cmd : STAT check_login SP pathname CRLF",
351 "cmd : DELE check_login SP pathname CRLF",
352 "cmd : RNTO SP pathname CRLF",
354 "cmd : CWD check_login CRLF",
355 "cmd : CWD check_login SP pathname CRLF",
357 "cmd : HELP SP STRING CRLF",
359 "cmd : MKD check_login SP pathname CRLF",
360 "cmd : RMD check_login SP pathname CRLF",
361 "cmd : PWD check_login CRLF",
362 "cmd : CDUP check_login CRLF",
363 "cmd : SITE SP HELP CRLF",
364 "cmd : SITE SP HELP SP STRING CRLF",
365 "cmd : SITE SP UMASK check_login CRLF",
366 "cmd : SITE SP UMASK check_login SP octal_number CRLF",
367 "cmd : SITE SP CHMOD check_login SP octal_number SP pathname CRLF",
368 "cmd : SITE SP IDLE CRLF",
369 "cmd : SITE SP IDLE SP NUMBER CRLF",
370 "cmd : STOU check_login SP pathname CRLF",
372 "cmd : SIZE check_login SP pathname CRLF",
373 "cmd : MDTM check_login SP pathname CRLF",
376 "rcmd : RNFR check_login SP pathname CRLF",
380 "byte_size : NUMBER",
381 "host_port : NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER",
386 "type_code : A SP form_code",
388 "type_code : E SP form_code",
391 "type_code : L SP byte_size",
392 "type_code : L byte_size",
399 "pathname : pathstring",
400 "pathstring : STRING",
401 "octal_number : NUMBER",
413 /* define the initial stack-sizes */
416 #define YYMAXDEPTH YYSTACKSIZE
419 #define YYSTACKSIZE YYMAXDEPTH
421 #define YYSTACKSIZE 500
422 #define YYMAXDEPTH 500
426 #define YYINITSTACKSIZE 500
437 /* variables for the parser stack */
439 static short *yysslim;
440 static YYSTYPE *yyvs;
441 static unsigned yystacksize;
444 extern jmp_buf errcatch;
446 #define CMD 0 /* beginning of command */
447 #define ARGS 1 /* expect miscellaneous arguments */
448 #define STR1 2 /* expect SP followed by STRING */
449 #define STR2 3 /* expect STRING */
450 #define OSTR 4 /* optional SP then STRING */
451 #define ZSTR1 5 /* SP then optional STRING */
452 #define ZSTR2 6 /* optional STRING after SP */
453 #define SITECMD 7 /* SITE command */
454 #define NSTR 8 /* Number followed by a string */
460 short implemented; /* 1 if command is implemented */
464 struct tab cmdtab[] = { /* In order defined in RFC 765 */
465 { "USER", USER, STR1, 1, "<sp> username" },
466 { "PASS", PASS, ZSTR1, 1, "<sp> password" },
467 { "ACCT", ACCT, STR1, 0, "(specify account)" },
468 { "SMNT", SMNT, ARGS, 0, "(structure mount)" },
469 { "REIN", REIN, ARGS, 0, "(reinitialize server state)" },
470 { "QUIT", QUIT, ARGS, 1, "(terminate service)", },
471 { "PORT", PORT, ARGS, 1, "<sp> b0, b1, b2, b3, b4" },
472 { "PASV", PASV, ARGS, 1, "(set server in passive mode)" },
473 { "TYPE", TYPE, ARGS, 1, "<sp> [ A | E | I | L ]" },
474 { "STRU", STRU, ARGS, 1, "(specify file structure)" },
475 { "MODE", MODE, ARGS, 1, "(specify transfer mode)" },
476 { "RETR", RETR, STR1, 1, "<sp> file-name" },
477 { "STOR", STOR, STR1, 1, "<sp> file-name" },
478 { "APPE", APPE, STR1, 1, "<sp> file-name" },
479 { "MLFL", MLFL, OSTR, 0, "(mail file)" },
480 { "MAIL", MAIL, OSTR, 0, "(mail to user)" },
481 { "MSND", MSND, OSTR, 0, "(mail send to terminal)" },
482 { "MSOM", MSOM, OSTR, 0, "(mail send to terminal or mailbox)" },
483 { "MSAM", MSAM, OSTR, 0, "(mail send to terminal and mailbox)" },
484 { "MRSQ", MRSQ, OSTR, 0, "(mail recipient scheme question)" },
485 { "MRCP", MRCP, STR1, 0, "(mail recipient)" },
486 { "ALLO", ALLO, ARGS, 1, "allocate storage (vacuously)" },
487 { "REST", REST, ARGS, 0, "(restart command)" },
488 { "RNFR", RNFR, STR1, 1, "<sp> file-name" },
489 { "RNTO", RNTO, STR1, 1, "<sp> file-name" },
490 { "ABOR", ABOR, ARGS, 1, "(abort operation)" },
491 { "DELE", DELE, STR1, 1, "<sp> file-name" },
492 { "CWD", CWD, OSTR, 1, "[ <sp> directory-name ]" },
493 { "XCWD", CWD, OSTR, 1, "[ <sp> directory-name ]" },
494 { "LIST", LIST, OSTR, 1, "[ <sp> path-name ]" },
495 { "NLST", NLST, OSTR, 1, "[ <sp> path-name ]" },
496 { "SITE", SITE, SITECMD, 1, "site-cmd [ <sp> arguments ]" },
497 { "SYST", SYST, ARGS, 1, "(get type of operating system)" },
498 { "STAT", STAT, OSTR, 1, "[ <sp> path-name ]" },
499 { "HELP", HELP, OSTR, 1, "[ <sp> <string> ]" },
500 { "NOOP", NOOP, ARGS, 1, "" },
501 { "MKD", MKD, STR1, 1, "<sp> path-name" },
502 { "XMKD", MKD, STR1, 1, "<sp> path-name" },
503 { "RMD", RMD, STR1, 1, "<sp> path-name" },
504 { "XRMD", RMD, STR1, 1, "<sp> path-name" },
505 { "PWD", PWD, ARGS, 1, "(return current directory)" },
506 { "XPWD", PWD, ARGS, 1, "(return current directory)" },
507 { "CDUP", CDUP, ARGS, 1, "(change to parent directory)" },
508 { "XCUP", CDUP, ARGS, 1, "(change to parent directory)" },
509 { "STOU", STOU, STR1, 1, "<sp> file-name" },
510 { "SIZE", SIZE, OSTR, 1, "<sp> path-name" },
511 { "MDTM", MDTM, OSTR, 1, "<sp> path-name" },
515 struct tab sitetab[] = {
516 { "UMASK", UMASK, ARGS, 1, "[ <sp> umask ]" },
517 { "IDLE", IDLE, ARGS, 1, "[ <sp> maximum-idle-time ]" },
518 { "CHMOD", CHMOD, NSTR, 1, "<sp> mode <sp> file-name" },
519 { "HELP", HELP, OSTR, 1, "[ <sp> <string> ]" },
525 register struct tab *p;
529 for (; p->name != NULL; p++)
530 if (strcmp(cmd, p->name) == 0)
535 #include <arpa/telnet.h>
538 * getline - a hacked up version of fgets to ignore TELNET escape codes.
549 /* tmpline may contain saved command from urgent mode interruption */
550 for (c = 0; tmpline[c] != '\0' && --n > 0; ++c) {
552 if (tmpline[c] == '\n') {
555 syslog(LOG_DEBUG, "command: %s", s);
562 while ((c = getc(iop)) != EOF) {
565 if ((c = getc(iop)) != EOF) {
571 printf("%c%c%c", IAC, DONT, 0377&c);
572 (void) fflush(stdout);
577 printf("%c%c%c", IAC, WONT, 0377&c);
578 (void) fflush(stdout);
583 continue; /* ignore command */
588 if (--n <= 0 || c == '\n')
591 if (c == EOF && cs == s)
595 syslog(LOG_DEBUG, "command: %s", s);
603 extern char *ctime();
604 extern time_t time();
607 "Timeout (%d seconds): closing control connection.", timeout);
611 "User %s timed out after %d seconds at %s",
612 (pw ? pw -> pw_name : "unknown"), timeout, ctime(&now));
619 static int cpos, state;
620 register char *cp, *cp2;
621 register struct tab *p;
630 (void) signal(SIGALRM, toolong);
631 (void) alarm((unsigned) timeout);
632 if (getline(cbuf, sizeof(cbuf)-1, stdin) == NULL) {
633 reply(221, "You could at least say goodbye.");
638 if (strncasecmp(cbuf, "PASS", 4) != NULL)
639 setproctitle("%s: %s", proctitle, cbuf);
640 #endif /* SETPROCTITLE */
641 if ((cp = index(cbuf, '\r'))) {
645 if ((cp = strpbrk(cbuf, " \n")))
652 p = lookup(cmdtab, cbuf);
655 if (p->implemented == 0) {
661 *(char **)&yylval = p->name;
667 if (cbuf[cpos] == ' ') {
672 if ((cp2 = strpbrk(cp, " \n")))
677 p = lookup(sitetab, cp);
680 if (p->implemented == 0) {
687 *(char **)&yylval = p->name;
694 if (cbuf[cpos] == '\n') {
703 if (cbuf[cpos] == ' ') {
705 state = state == OSTR ? STR2 : ++state;
711 if (cbuf[cpos] == '\n') {
722 * Make sure the string is nonempty and \n terminated.
724 if (n > 1 && cbuf[cpos] == '\n') {
726 *(char **)&yylval = copy(cp);
734 if (cbuf[cpos] == ' ') {
738 if (isdigit(cbuf[cpos])) {
740 while (isdigit(cbuf[++cpos]))
753 if (isdigit(cbuf[cpos])) {
755 while (isdigit(cbuf[++cpos]))
763 switch (cbuf[cpos++]) {
827 fatal("Unknown state in scanner.");
850 extern char *malloc(), *strcpy();
852 p = malloc((unsigned) strlen(s) + 1);
854 fatal("Ran out of memory.");
863 register struct tab *c;
864 register int width, NCMDS;
871 width = 0, NCMDS = 0;
872 for (c = ctab; c->name != NULL; c++) {
873 int len = strlen(c->name);
879 width = (width + 8) &~ 7;
881 register int i, j, w;
884 lreply(214, "The following %scommands are recognized %s.",
885 type, "(* =>'s unimplemented)");
886 columns = 76 / width;
889 lines = (NCMDS + columns - 1) / columns;
890 for (i = 0; i < lines; i++) {
892 for (j = 0; j < columns; j++) {
893 c = ctab + j * lines + i;
894 printf("%s%c", c->name,
895 c->implemented ? ' ' : '*');
896 if (c + lines >= &ctab[NCMDS])
898 w = strlen(c->name) + 1;
906 (void) fflush(stdout);
907 reply(214, "Direct comments to ftp-bugs@%s.", hostname);
912 if (c == (struct tab *)0) {
913 reply(502, "Unknown command %s.", s);
917 reply(214, "Syntax: %s%s %s", type, c->name, c->help);
919 reply(214, "%s%-*s\t%s; unimplemented.", type, width,
930 if (stat(filename, &stbuf) < 0 ||
931 (stbuf.st_mode&S_IFMT) != S_IFREG)
932 reply(550, "%s: not a plain file.", filename);
934 reply(213, "%lu", stbuf.st_size);
938 register int c, count;
940 fin = fopen(filename, "r");
942 perror_reply(550, filename);
945 if (fstat(fileno(fin), &stbuf) < 0 ||
946 (stbuf.st_mode&S_IFMT) != S_IFREG) {
947 reply(550, "%s: not a plain file.", filename);
953 while((c=getc(fin)) != EOF) {
954 if (c == '\n') /* will get expanded to \r\n */
960 reply(213, "%ld", count);
963 reply(504, "SIZE not implemented for Type %c.", "?AEIL"[type]);
966 #line 967 "ftp.tab.c"
967 /* allocate initial stack or double stack size, up to YYMAXDEPTH */
968 static int yygrowstack(void)
975 if ((newsize = yystacksize) == 0)
976 newsize = YYINITSTACKSIZE;
977 else if (newsize >= YYMAXDEPTH)
979 else if ((newsize *= 2) > YYMAXDEPTH)
980 newsize = YYMAXDEPTH;
984 ? (short *)realloc(yyss, newsize * sizeof(*newss))
985 : (short *)malloc(newsize * sizeof(*newss));
992 ? (YYSTYPE *)realloc(yyvs, newsize * sizeof(*newvs))
993 : (YYSTYPE *)malloc(newsize * sizeof(*newvs));
999 yystacksize = newsize;
1000 yysslim = yyss + newsize - 1;
1004 #define YYABORT goto yyabort
1005 #define YYREJECT goto yyabort
1006 #define YYACCEPT goto yyaccept
1007 #define YYERROR goto yyerrlab
1012 int yym, yyn, yystate;
1016 if ((yys = getenv("YYDEBUG")) != 0)
1019 if (yyn >= '0' && yyn <= '9')
1020 yydebug = yyn - '0';
1029 if (yyss == NULL && yygrowstack()) goto yyoverflow;
1036 if ((yyn = yydefred[yystate]) != 0) goto yyreduce;
1039 if ((yychar = yylex()) < 0) yychar = 0;
1044 if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
1045 if (!yys) yys = "illegal-symbol";
1046 printf("%sdebug: state %d, reading %d (%s)\n",
1047 YYPREFIX, yystate, yychar, yys);
1051 if ((yyn = yysindex[yystate]) && (yyn += yychar) >= 0 &&
1052 yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
1056 printf("%sdebug: state %d, shifting to state %d\n",
1057 YYPREFIX, yystate, yytable[yyn]);
1059 if (yyssp >= yysslim && yygrowstack())
1063 yystate = yytable[yyn];
1064 *++yyssp = yytable[yyn];
1067 if (yyerrflag > 0) --yyerrflag;
1070 if ((yyn = yyrindex[yystate]) && (yyn += yychar) >= 0 &&
1071 yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
1076 if (yyerrflag) goto yyinrecovery;
1078 yyerror("syntax error");
1091 if ((yyn = yysindex[*yyssp]) && (yyn += YYERRCODE) >= 0 &&
1092 yyn <= YYTABLESIZE && yycheck[yyn] == YYERRCODE)
1096 printf("%sdebug: state %d, error recovery shifting\
1097 to state %d\n", YYPREFIX, *yyssp, yytable[yyn]);
1099 if (yyssp >= yysslim && yygrowstack())
1103 yystate = yytable[yyn];
1104 *++yyssp = yytable[yyn];
1112 printf("%sdebug: error recovery discarding state %d\n",
1115 if (yyssp <= yyss) goto yyabort;
1123 if (yychar == 0) goto yyabort;
1128 if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
1129 if (!yys) yys = "illegal-symbol";
1130 printf("%sdebug: state %d, error recovery discards token %d (%s)\n",
1131 YYPREFIX, yystate, yychar, yys);
1141 printf("%sdebug: state %d, reducing by rule %d (%s)\n",
1142 YYPREFIX, yystate, yyn, yyrule[yyn]);
1146 yyval = yyvsp[1-yym];
1148 memset(&yyval, 0, sizeof yyval);
1154 fromname = (char *) 0;
1160 user((char *) yyvsp[-1]);
1161 free((char *) yyvsp[-1]);
1167 pass((char *) yyvsp[-1]);
1168 free((char *) yyvsp[-1]);
1176 (void) close(pdata);
1179 reply(200, "PORT command successful.");
1194 if (cmd_form == FORM_N) {
1195 reply(200, "Type set to A.");
1199 reply(504, "Form must be N.");
1203 reply(504, "Type E not implemented.");
1207 reply(200, "Type set to I.");
1213 if (cmd_bytesz == 8) {
1215 "Type set to L (byte size 8).");
1218 reply(504, "Byte size must be 8.");
1219 #else /* NBBY == 8 */
1220 UNIMPLEMENTED for NBBY != 8
1221 #endif /* NBBY == 8 */
1228 switch (yyvsp[-1]) {
1231 reply(200, "STRU F ok.");
1235 reply(504, "Unimplemented STRU type.");
1242 switch (yyvsp[-1]) {
1245 reply(200, "MODE S ok.");
1249 reply(502, "Unimplemented MODE type.");
1256 reply(202, "ALLO command ignored.");
1262 reply(202, "ALLO command ignored.");
1268 if (yyvsp[-3] && yyvsp[-1] != NULL)
1269 retrieve((char *) 0, (char *) yyvsp[-1]);
1270 if (yyvsp[-1] != NULL)
1271 free((char *) yyvsp[-1]);
1277 if (yyvsp[-3] && yyvsp[-1] != NULL)
1278 store((char *) yyvsp[-1], "w", 0);
1279 if (yyvsp[-1] != NULL)
1280 free((char *) yyvsp[-1]);
1286 if (yyvsp[-3] && yyvsp[-1] != NULL)
1287 store((char *) yyvsp[-1], "a", 0);
1288 if (yyvsp[-1] != NULL)
1289 free((char *) yyvsp[-1]);
1296 send_file_list(".");
1302 if (yyvsp[-3] && yyvsp[-1] != NULL)
1303 send_file_list((char *) yyvsp[-1]);
1304 if (yyvsp[-1] != NULL)
1305 free((char *) yyvsp[-1]);
1312 retrieve("/bin/ls -lgA", "");
1318 if (yyvsp[-3] && yyvsp[-1] != NULL)
1319 retrieve("/bin/ls -lgA %s", (char *) yyvsp[-1]);
1320 if (yyvsp[-1] != NULL)
1321 free((char *) yyvsp[-1]);
1327 if (yyvsp[-3] && yyvsp[-1] != NULL)
1328 statfilecmd((char *) yyvsp[-1]);
1329 if (yyvsp[-1] != NULL)
1330 free((char *) yyvsp[-1]);
1342 if (yyvsp[-3] && yyvsp[-1] != NULL)
1343 delete((char *) yyvsp[-1]);
1344 if (yyvsp[-1] != NULL)
1345 free((char *) yyvsp[-1]);
1352 renamecmd(fromname, (char *) yyvsp[-1]);
1354 fromname = (char *) 0;
1356 reply(503, "Bad sequence of commands.");
1358 free((char *) yyvsp[-1]);
1364 reply(225, "ABOR command successful.");
1377 if (yyvsp[-3] && yyvsp[-1] != NULL)
1378 cwd((char *) yyvsp[-1]);
1379 if (yyvsp[-1] != NULL)
1380 free((char *) yyvsp[-1]);
1386 help(cmdtab, (char *) 0);
1392 register char *cp = (char *)yyvsp[-1];
1394 if (strncasecmp(cp, "SITE", 4) == 0) {
1395 cp = (char *)yyvsp[-1] + 4;
1401 help(sitetab, (char *) 0);
1403 help(cmdtab, (char *) yyvsp[-1]);
1409 reply(200, "NOOP command successful.");
1415 if (yyvsp[-3] && yyvsp[-1] != NULL)
1416 makedir((char *) yyvsp[-1]);
1417 if (yyvsp[-1] != NULL)
1418 free((char *) yyvsp[-1]);
1424 if (yyvsp[-3] && yyvsp[-1] != NULL)
1425 removedir((char *) yyvsp[-1]);
1426 if (yyvsp[-1] != NULL)
1427 free((char *) yyvsp[-1]);
1447 help(sitetab, (char *) 0);
1453 help(sitetab, (char *) yyvsp[-1]);
1463 (void) umask(oldmask);
1464 reply(200, "Current UMASK is %03o", oldmask);
1474 if ((yyvsp[-1] == -1) || (yyvsp[-1] > 0777)) {
1475 reply(501, "Bad UMASK value");
1477 oldmask = umask(yyvsp[-1]);
1479 "UMASK set to %03o (was %03o)",
1480 yyvsp[-1], oldmask);
1488 if (yyvsp[-5] && (yyvsp[-1] != NULL)) {
1489 if (yyvsp[-3] > 0777)
1491 "CHMOD: Mode value must be between 0 and 0777");
1492 else if (chmod((char *) yyvsp[-1], yyvsp[-3]) < 0)
1493 perror_reply(550, (char *) yyvsp[-1]);
1495 reply(200, "CHMOD command successful.");
1497 if (yyvsp[-1] != NULL)
1498 free((char *) yyvsp[-1]);
1505 "Current IDLE time limit is %d seconds; max %d",
1506 timeout, maxtimeout);
1512 if (yyvsp[-1] < 30 || yyvsp[-1] > maxtimeout) {
1514 "Maximum IDLE time must be between 30 and %d seconds",
1517 timeout = yyvsp[-1];
1518 (void) alarm((unsigned) timeout);
1520 "Maximum IDLE time set to %d seconds",
1528 if (yyvsp[-3] && yyvsp[-1] != NULL)
1529 store((char *) yyvsp[-1], "w", 1);
1530 if (yyvsp[-1] != NULL)
1531 free((char *) yyvsp[-1]);
1539 reply(215, "UNIX Type: L%d Version: BSD-%d",
1542 reply(215, "UNIX Type: L%d", NBBY);
1545 reply(215, "UNKNOWN Type: L%d", NBBY);
1552 if (yyvsp[-3] && yyvsp[-1] != NULL)
1553 sizecmd((char *) yyvsp[-1]);
1554 if (yyvsp[-1] != NULL)
1555 free((char *) yyvsp[-1]);
1561 if (yyvsp[-3] && yyvsp[-1] != NULL) {
1563 if (stat((char *) yyvsp[-1], &stbuf) < 0)
1564 perror_reply(550, "%s", (char *) yyvsp[-1]);
1565 else if ((stbuf.st_mode&S_IFMT) != S_IFREG) {
1566 reply(550, "%s: not a plain file.",
1567 (char *) yyvsp[-1]);
1569 register struct tm *t;
1570 struct tm *gmtime();
1571 t = gmtime(&stbuf.st_mtime);
1573 "19%02d%02d%02d%02d%02d%02d",
1574 t->tm_year, t->tm_mon+1, t->tm_mday,
1575 t->tm_hour, t->tm_min, t->tm_sec);
1578 if (yyvsp[-1] != NULL)
1579 free((char *) yyvsp[-1]);
1585 reply(221, "Goodbye.");
1600 if (yyvsp[-3] && yyvsp[-1]) {
1601 fromname = renamefrom((char *) yyvsp[-1]);
1602 if (fromname == (char *) 0 && yyvsp[-1]) {
1603 free((char *) yyvsp[-1]);
1611 *(char **)&(yyval) = "";
1617 register char *a, *p;
1619 a = (char *)&data_dest.sin_addr;
1620 a[0] = yyvsp[-10]; a[1] = yyvsp[-8]; a[2] = yyvsp[-6]; a[3] = yyvsp[-4];
1621 p = (char *)&data_dest.sin_port;
1622 p[0] = yyvsp[-2]; p[1] = yyvsp[0];
1623 data_dest.sin_family = AF_INET;
1655 cmd_form = yyvsp[0];
1669 cmd_form = yyvsp[0];
1689 cmd_bytesz = yyvsp[0];
1696 cmd_bytesz = yyvsp[0];
1739 * Problem: this production is used for all pathname
1740 * processing, but only gives a 550 error reply.
1741 * This is a valid reply in some cases but not in others.
1743 if (logged_in && yyvsp[0] && strncmp((char *) yyvsp[0], "~", 1) == 0) {
1744 *(char **)&(yyval) = *glob((char *) yyvsp[0]);
1745 if (globerr != NULL) {
1746 reply(550, globerr);
1749 free((char *) yyvsp[0]);
1757 register int ret, dec, multby, digit;
1760 * Convert a number that was read as decimal number
1761 * to what it would be if it had been read as octal.
1772 ret += digit * multby;
1785 reply(530, "Please login with USER and PASS.");
1790 #line 1791 "ftp.tab.c"
1796 if (yystate == 0 && yym == 0)
1800 printf("%sdebug: after reduction, shifting from state 0 to\
1801 state %d\n", YYPREFIX, YYFINAL);
1808 if ((yychar = yylex()) < 0) yychar = 0;
1813 if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
1814 if (!yys) yys = "illegal-symbol";
1815 printf("%sdebug: state %d, reading %d (%s)\n",
1816 YYPREFIX, YYFINAL, yychar, yys);
1820 if (yychar == 0) goto yyaccept;
1823 if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 &&
1824 yyn <= YYTABLESIZE && yycheck[yyn] == yystate)
1825 yystate = yytable[yyn];
1827 yystate = yydgoto[yym];
1830 printf("%sdebug: after reduction, shifting from state %d \
1831 to state %d\n", YYPREFIX, *yyssp, yystate);
1833 if (yyssp >= yysslim && yygrowstack())
1837 *++yyssp = (short) yystate;
1842 yyerror("yacc stack overflow");