2 static const char yysccsid
[] = "@(#)yaccpar 1.9 (Berkeley) 02/21/93";
16 #define yyclearin (yychar = YYEMPTY)
17 #define yyerrok (yyerrflag = 0)
18 #define YYRECOVERING() (yyerrflag != 0)
25 #include <sys/cdefs.h>
29 static char sccsid
[] = "@(#)ftpcmd.y 8.3 (Berkeley) 4/6/94";
31 __RCSID("$NetBSD: ftpcmd.y,v 1.93 2011/09/16 16:13:17 plunky Exp $");
35 #include <sys/param.h>
36 #include <sys/socket.h>
39 #include <netinet/in.h>
41 #include <arpa/inet.h>
56 #include <krb5/krb5.h>
64 static int cmd_bytesz
;
66 char cbuf
[FTP_BUFLEN
];
73 static int check_write(const char *, int);
74 static void help(struct tab
*, const char *);
75 static void port_check(const char *, int);
80 #undef YYSTYPE_IS_DECLARED
81 #define YYSTYPE_IS_DECLARED 1
83 #ifndef YYSTYPE_IS_DECLARED
84 #define YYSTYPE_IS_DECLARED 1
93 #endif /* !YYSTYPE_IS_DECLARED */
96 /* compatibility with bison */
98 /* compatibility with FreeBSD */
99 # ifdef YYPARSE_PARAM_TYPE
100 # define YYPARSE_DECL() yyparse(YYPARSE_PARAM_TYPE YYPARSE_PARAM)
102 # define YYPARSE_DECL() yyparse(void *YYPARSE_PARAM)
105 # define YYPARSE_DECL() yyparse(void)
108 /* Parameters sent to lex. */
110 # define YYLEX_DECL() yylex(void *YYLEX_PARAM)
111 # define YYLEX yylex(YYLEX_PARAM)
113 # define YYLEX_DECL() yylex(void)
114 # define YYLEX yylex()
117 /* Parameters sent to yyerror. */
118 #define YYERROR_DECL() yyerror(const char *s)
119 #define YYERROR_CALL(msg) yyerror(msg)
121 extern int YYPARSE_DECL();
206 #define YYERRCODE 256
207 static const short yylhs
[] = { -1,
208 0, 0, 16, 16, 16, 16, 16, 16, 16, 16,
209 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
210 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
211 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
212 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
213 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
214 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
215 17, 17, 12, 11, 11, 3, 18, 19, 20, 7,
216 7, 7, 6, 6, 6, 6, 6, 6, 6, 6,
217 4, 4, 4, 5, 5, 5, 10, 9, 2, 13,
220 static const short yylen
[] = { 2,
221 1, 1, 4, 4, 3, 5, 3, 2, 5, 5,
222 5, 5, 3, 3, 5, 5, 3, 5, 5, 5,
223 5, 4, 4, 4, 5, 9, 4, 3, 4, 4,
224 4, 3, 3, 5, 3, 5, 4, 8, 6, 5,
225 7, 5, 7, 5, 7, 5, 7, 2, 5, 2,
226 2, 4, 2, 4, 4, 4, 4, 2, 4, 4,
227 4, 2, 4, 5, 5, 5, 3, 5, 3, 2,
228 5, 4, 1, 0, 1, 1, 11, 17, 41, 1,
229 1, 1, 1, 3, 1, 3, 1, 1, 3, 2,
230 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
233 static const short yydefred
[] = { 0,
234 0, 0, 0, 104, 104, 0, 104, 104, 104, 104,
235 104, 104, 0, 0, 0, 104, 104, 0, 0, 104,
236 0, 0, 0, 104, 104, 104, 0, 0, 0, 0,
237 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
238 0, 104, 104, 104, 104, 104, 104, 104, 104, 0,
239 1, 2, 70, 0, 0, 0, 0, 8, 0, 0,
240 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
241 0, 0, 0, 0, 0, 0, 0, 0, 0, 48,
242 50, 0, 0, 51, 53, 0, 0, 0, 0, 58,
243 0, 0, 0, 62, 0, 0, 0, 0, 0, 0,
244 0, 0, 0, 73, 0, 75, 0, 0, 5, 7,
245 0, 13, 0, 0, 0, 0, 98, 97, 0, 0,
246 0, 0, 0, 0, 0, 28, 0, 0, 0, 32,
247 0, 33, 0, 35, 0, 0, 104, 104, 104, 104,
248 0, 0, 100, 0, 101, 0, 102, 0, 103, 0,
249 0, 0, 0, 0, 0, 0, 0, 67, 0, 69,
250 0, 14, 0, 0, 17, 3, 4, 0, 0, 0,
251 0, 0, 87, 0, 0, 91, 93, 92, 0, 95,
252 96, 94, 0, 0, 22, 23, 24, 0, 0, 72,
253 27, 29, 30, 31, 0, 0, 0, 37, 0, 0,
254 0, 0, 0, 0, 52, 54, 55, 56, 57, 59,
255 60, 61, 63, 0, 0, 0, 0, 0, 0, 0,
256 0, 0, 0, 6, 0, 9, 0, 0, 0, 76,
257 90, 18, 19, 20, 21, 0, 25, 71, 34, 36,
258 0, 99, 0, 0, 40, 0, 42, 0, 44, 0,
259 46, 49, 64, 65, 66, 68, 0, 10, 11, 12,
260 16, 15, 0, 82, 80, 81, 84, 86, 89, 0,
261 39, 0, 0, 0, 0, 0, 0, 0, 0, 0,
262 41, 43, 45, 47, 0, 0, 0, 38, 0, 0,
263 26, 0, 0, 0, 0, 0, 0, 0, 0, 0,
264 77, 0, 0, 0, 0, 0, 0, 0, 0, 0,
265 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
266 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
269 static const short yydgoto
[] = { 50,
270 56, 243, 231, 179, 183, 175, 267, 150, 118, 119,
271 107, 105, 144, 146, 148, 51, 52, 170, 219, 220,
273 static const short yysindex
[] = { -179,
274 -260, -245, -239, 0, 0, -231, 0, 0, 0, 0,
275 0, 0, -228, -225, -205, 0, 0, -203, -199, 0,
276 -195, -181, -177, 0, 0, 0, -173, -194, -171, -257,
277 -169, -124, -109, -108, -107, -106, -104, -103, -102, -101,
278 -99, 0, 0, 0, 0, 0, 0, 0, 0, 0,
279 0, 0, 0, -174, -166, -242, -98, 0, -96, -95,
280 -93, -92, -91, -90, -163, -163, -163, -89, -88, -163,
281 -163, -87, -163, -163, -163, -86, -233, -191, -272, 0,
282 0, -84, -155, 0, 0, -151, -150, -149, -170, 0,
283 -150, -150, -150, 0, -148, -79, -78, -189, -187, -77,
284 -76, -74, -185, 0, -73, 0, -72, -163, 0, 0,
285 -145, 0, -217, -193, -236, -163, 0, 0, -71, -70,
286 -69, -142, -136, -67, -65, 0, -63, -62, -61, 0,
287 -163, 0, -163, 0, -183, -59, 0, 0, 0, 0,
288 -163, -58, 0, -57, 0, -56, 0, -55, 0, -54,
289 -53, -52, -51, -50, -163, -163, -163, 0, -163, 0,
290 -134, 0, -126, -269, 0, 0, 0, -49, -48, -46,
291 -47, -43, 0, -267, -45, 0, 0, 0, -42, 0,
292 0, 0, -41, -40, 0, 0, 0, -119, -39, 0,
293 0, 0, 0, 0, -38, -37, -110, 0, -100, -117,
294 -115, -113, -111, -36, 0, 0, 0, 0, 0, 0,
295 0, 0, 0, -35, -34, -33, -31, -30, -28, -27,
296 -26, -25, -24, 0, -85, 0, -253, -253, -83, 0,
297 0, 0, 0, 0, 0, -19, 0, 0, 0, 0,
298 -22, 0, -29, -82, 0, -80, 0, -75, 0, -100,
299 0, 0, 0, 0, 0, 0, -68, 0, 0, 0,
300 0, 0, -21, 0, 0, 0, 0, 0, 0, -20,
301 0, -163, -18, -16, -12, -11, -10, -64, -60, -7,
302 0, 0, 0, 0, -32, -6, -4, 0, -3, -23,
303 0, -17, -2, 1, -15, -14, 2, 4, -13, -9,
304 0, 5, -8, 6, -5, 8, -1, 10, 3, 11,
305 7, 12, 13, 14, 15, 16, 17, 18, 19, 20,
306 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
309 static const short yyrindex
[] = { 0,
310 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
311 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
312 0, 0, 0, 0, 0, 0, 0, 0, 33, 0,
313 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
314 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
315 0, 0, 0, 0, 34, 0, 0, 0, 0, 0,
316 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
317 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
318 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
319 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
320 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
321 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
322 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
323 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
324 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
325 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
326 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
327 35, -169, 0, 37, 0, 0, 0, 0, 0, 0,
328 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
329 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
330 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
331 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
332 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
333 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
334 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
335 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
336 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
337 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
338 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
339 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
340 0, 0, 0, 0, 0, 0, 0, 38, 0, 0,
341 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
342 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
345 static const short yygindex
[] = { 0,
346 9, 36, 42, 0, 0, 0, 32, 0, 0, -66,
347 0, 0, 0, -44, 0, 0, 0, 0, 0, 0,
349 #define YYTABLESIZE 369
350 static const short yytable
[] = { 120,
351 121, 229, 222, 124, 125, 264, 127, 128, 129, 53,
352 265, 83, 84, 57, 266, 59, 60, 61, 62, 63,
353 64, 180, 181, 54, 68, 69, 108, 109, 72, 55,
354 182, 135, 76, 77, 78, 131, 132, 82, 58, 171,
355 65, 168, 172, 66, 173, 174, 151, 152, 153, 184,
356 96, 97, 98, 99, 100, 101, 102, 103, 136, 137,
357 138, 139, 140, 67, 195, 70, 196, 176, 223, 71,
358 230, 177, 178, 73, 204, 80, 1, 133, 134, 157,
359 158, 159, 160, 164, 165, 197, 198, 74, 214, 215,
360 216, 75, 217, 2, 3, 79, 4, 5, 81, 6,
361 85, 7, 8, 9, 10, 11, 12, 13, 14, 15,
362 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
363 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
364 36, 37, 38, 39, 40, 41, 42, 43, 44, 45,
365 46, 47, 48, 49, 86, 200, 201, 202, 203, 236,
366 237, 244, 245, 246, 247, 248, 249, 250, 251, 87,
367 88, 89, 104, 90, 91, 92, 93, 149, 94, 95,
368 106, 110, 111, 117, 112, 113, 114, 115, 116, 122,
369 123, 142, 126, 130, 141, 143, 145, 147, 154, 155,
370 156, 161, 169, 162, 163, 188, 166, 167, 185, 186,
371 187, 189, 190, 218, 191, 280, 192, 193, 194, 199,
372 221, 205, 206, 207, 208, 209, 210, 211, 212, 213,
373 224, 227, 225, 226, 232, 228, 241, 233, 234, 235,
374 238, 239, 240, 252, 253, 254, 255, 242, 256, 272,
375 257, 258, 259, 260, 261, 262, 270, 271, 279, 278,
376 0, 281, 263, 282, 230, 273, 274, 283, 284, 268,
377 285, 275, 288, 0, 290, 291, 0, 292, 295, 277,
378 269, 296, 299, 286, 300, 303, 305, 287, 307, 0,
379 309, 311, 313, 0, 315, 276, 317, 0, 319, 0,
380 321, 0, 323, 0, 325, 0, 327, 0, 329, 0,
381 331, 104, 0, 74, 83, 289, 88, 78, 0, 0,
382 0, 0, 0, 0, 293, 0, 0, 0, 0, 0,
383 294, 0, 297, 298, 301, 0, 0, 0, 302, 304,
384 0, 0, 306, 0, 0, 0, 308, 0, 0, 0,
385 310, 0, 0, 0, 312, 0, 0, 0, 0, 0,
386 314, 0, 316, 0, 318, 0, 320, 0, 322, 0,
387 324, 0, 326, 0, 328, 0, 330, 0, 332,
389 static const short yycheck
[] = { 66,
390 67, 269, 272, 70, 71, 259, 73, 74, 75, 270,
391 264, 269, 270, 5, 268, 7, 8, 9, 10, 11,
392 12, 258, 259, 269, 16, 17, 269, 270, 20, 269,
393 267, 304, 24, 25, 26, 269, 270, 29, 270, 257,
394 269, 108, 260, 269, 262, 263, 91, 92, 93, 116,
395 42, 43, 44, 45, 46, 47, 48, 49, 331, 332,
396 333, 334, 335, 269, 131, 269, 133, 261, 338, 269,
397 338, 265, 266, 269, 141, 270, 256, 269, 270, 269,
398 270, 269, 270, 269, 270, 269, 270, 269, 155, 156,
399 157, 269, 159, 273, 274, 269, 276, 277, 270, 279,
400 270, 281, 282, 283, 284, 285, 286, 287, 288, 289,
401 290, 291, 292, 293, 294, 295, 296, 297, 298, 299,
402 300, 301, 302, 303, 304, 305, 306, 307, 308, 309,
403 310, 311, 312, 313, 314, 315, 316, 317, 318, 319,
404 320, 321, 322, 323, 269, 137, 138, 139, 140, 269,
405 270, 269, 270, 269, 270, 269, 270, 269, 270, 269,
406 269, 269, 337, 270, 269, 269, 269, 338, 270, 269,
407 337, 270, 269, 337, 270, 269, 269, 269, 269, 269,
408 269, 337, 270, 270, 269, 337, 337, 337, 337, 269,
409 269, 269, 338, 270, 269, 338, 270, 270, 270, 270,
410 270, 338, 270, 338, 270, 272, 270, 270, 270, 269,
411 337, 270, 270, 270, 270, 270, 270, 270, 270, 270,
412 270, 269, 271, 270, 270, 269, 337, 270, 270, 270,
413 270, 270, 270, 270, 270, 270, 270, 338, 270, 269,
414 271, 270, 270, 270, 270, 270, 266, 270, 269, 271,
415 -1, 270, 338, 270, 338, 338, 337, 270, 270, 228,
416 271, 337, 270, -1, 271, 270, -1, 271, 271, 338,
417 229, 271, 271, 338, 271, 271, 271, 338, 271, -1,
418 271, 271, 271, -1, 271, 250, 271, -1, 271, -1,
419 271, -1, 271, -1, 271, -1, 271, -1, 271, -1,
420 271, 269, -1, 270, 270, 338, 270, 270, -1, -1,
421 -1, -1, -1, -1, 338, -1, -1, -1, -1, -1,
422 338, -1, 338, 338, 338, -1, -1, -1, 338, 338,
423 -1, -1, 338, -1, -1, -1, 338, -1, -1, -1,
424 338, -1, -1, -1, 338, -1, -1, -1, -1, -1,
425 338, -1, 338, -1, 338, -1, 338, -1, 338, -1,
426 338, -1, 338, -1, 338, -1, 338, -1, 338,
432 #define YYMAXTOKEN 338
434 static const char *yyname
[] = {
436 "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,
437 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
438 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
439 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
440 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
441 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
442 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",
443 "P","R","S","T","SP","CRLF","COMMA","ALL","USER","PASS","ACCT","CWD","CDUP",
444 "SMNT","QUIT","REIN","PORT","PASV","TYPE","STRU","MODE","RETR","STOR","STOU",
445 "APPE","ALLO","REST","RNFR","RNTO","ABOR","DELE","RMD","MKD","PWD","LIST",
446 "NLST","SITE","SYST","STAT","HELP","NOOP","AUTH","ADAT","PROT","PBSZ","CCC",
447 "MIC","CONF","ENC","FEAT","OPTS","SIZE","MDTM","MLST","MLSD","LPRT","LPSV",
448 "EPRT","EPSV","MAIL","MLFL","MRCP","MRSQ","MSAM","MSND","MSOM","CHMOD","IDLE",
449 "RATEGET","RATEPUT","UMASK","LEXERR","STRING","NUMBER",
451 static const char *yyrule
[] = {
455 "cmd : USER SP username CRLF",
456 "cmd : PASS SP password CRLF",
457 "cmd : CWD check_login CRLF",
458 "cmd : CWD check_login SP pathname CRLF",
459 "cmd : CDUP check_login CRLF",
461 "cmd : PORT check_login SP host_port CRLF",
462 "cmd : LPRT check_login SP host_long_port4 CRLF",
463 "cmd : LPRT check_login SP host_long_port6 CRLF",
464 "cmd : EPRT check_login SP STRING CRLF",
465 "cmd : PASV check_login CRLF",
466 "cmd : LPSV check_login CRLF",
467 "cmd : EPSV check_login SP NUMBER CRLF",
468 "cmd : EPSV check_login SP ALL CRLF",
469 "cmd : EPSV check_login CRLF",
470 "cmd : TYPE check_login SP type_code CRLF",
471 "cmd : STRU check_login SP struct_code CRLF",
472 "cmd : MODE check_login SP mode_code CRLF",
473 "cmd : RETR check_login SP pathname CRLF",
474 "cmd : STOR SP pathname CRLF",
475 "cmd : STOU SP pathname CRLF",
476 "cmd : APPE SP pathname CRLF",
477 "cmd : ALLO check_login SP NUMBER CRLF",
478 "cmd : ALLO check_login SP NUMBER SP R SP NUMBER CRLF",
479 "cmd : RNTO SP pathname CRLF",
480 "cmd : ABOR check_login CRLF",
481 "cmd : DELE SP pathname CRLF",
482 "cmd : RMD SP pathname CRLF",
483 "cmd : MKD SP pathname CRLF",
484 "cmd : PWD check_login CRLF",
485 "cmd : LIST check_login CRLF",
486 "cmd : LIST check_login SP pathname CRLF",
487 "cmd : NLST check_login CRLF",
488 "cmd : NLST check_login SP pathname CRLF",
489 "cmd : SITE SP HELP CRLF",
490 "cmd : SITE SP CHMOD SP octal_number SP pathname CRLF",
491 "cmd : SITE SP HELP SP STRING CRLF",
492 "cmd : SITE SP IDLE check_login CRLF",
493 "cmd : SITE SP IDLE check_login SP NUMBER CRLF",
494 "cmd : SITE SP RATEGET check_login CRLF",
495 "cmd : SITE SP RATEGET check_login SP STRING CRLF",
496 "cmd : SITE SP RATEPUT check_login CRLF",
497 "cmd : SITE SP RATEPUT check_login SP STRING CRLF",
498 "cmd : SITE SP UMASK check_login CRLF",
499 "cmd : SITE SP UMASK check_login SP octal_number CRLF",
501 "cmd : STAT check_login SP pathname CRLF",
504 "cmd : HELP SP STRING CRLF",
506 "cmd : AUTH SP mechanism_name CRLF",
507 "cmd : ADAT SP base64data CRLF",
508 "cmd : PROT SP prot_code CRLF",
509 "cmd : PBSZ SP decimal_integer CRLF",
511 "cmd : MIC SP base64data CRLF",
512 "cmd : CONF SP base64data CRLF",
513 "cmd : ENC SP base64data CRLF",
515 "cmd : OPTS SP STRING CRLF",
516 "cmd : SIZE check_login SP pathname CRLF",
517 "cmd : MDTM check_login SP pathname CRLF",
518 "cmd : MLST check_login SP pathname CRLF",
519 "cmd : MLST check_login CRLF",
520 "cmd : MLSD check_login SP pathname CRLF",
521 "cmd : MLSD check_login CRLF",
523 "rcmd : REST check_login SP NUMBER CRLF",
524 "rcmd : RNFR SP pathname CRLF",
528 "byte_size : NUMBER",
529 "host_port : NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER",
530 "host_long_port4 : NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER",
531 "host_long_port6 : NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER",
536 "type_code : A SP form_code",
538 "type_code : E SP form_code",
541 "type_code : L SP byte_size",
542 "type_code : L byte_size",
549 "pathname : pathstring",
550 "pathstring : STRING",
551 "octal_number : NUMBER",
552 "mechanism_name : STRING",
553 "base64data : STRING",
554 "prot_code : STRING",
555 "decimal_integer : NUMBER",
569 /* define the initial stack-sizes */
572 #define YYMAXDEPTH YYSTACKSIZE
575 #define YYSTACKSIZE YYMAXDEPTH
577 #define YYSTACKSIZE 500
578 #define YYMAXDEPTH 500
582 #define YYINITSTACKSIZE 500
592 /* variables for the parser stack */
593 static YYSTACKDATA yystack
;
594 #line 1208 "ftpcmd.y"
596 #define CMD 0 /* beginning of command */
597 #define ARGS 1 /* expect miscellaneous arguments */
598 #define STR1 2 /* expect SP followed by STRING */
599 #define STR2 3 /* expect STRING */
600 #define OSTR 4 /* optional SP then STRING */
601 #define ZSTR1 5 /* SP then optional STRING */
602 #define ZSTR2 6 /* optional STRING after SP */
603 #define SITECMD 7 /* SITE command */
604 #define NSTR 8 /* Number followed by a string */
605 #define NOARGS 9 /* No arguments allowed */
606 #define EOLN 10 /* End of line */
608 struct tab cmdtab
[] = {
609 /* From RFC 959, in order defined (5.3.1) */
610 { "USER", USER
, STR1
, 1, "<sp> username", 0, },
611 { "PASS", PASS
, ZSTR1
, 1, "<sp> password", 0, },
612 { "ACCT", ACCT
, STR1
, 0, "(specify account)", 0, },
613 { "CWD", CWD
, OSTR
, 1, "[ <sp> directory-name ]", 0, },
614 { "CDUP", CDUP
, NOARGS
, 1, "(change to parent directory)", 0, },
615 { "SMNT", SMNT
, ARGS
, 0, "(structure mount)", 0, },
616 { "QUIT", QUIT
, NOARGS
, 1, "(terminate service)", 0, },
617 { "REIN", REIN
, NOARGS
, 0, "(reinitialize server state)", 0, },
618 { "PORT", PORT
, ARGS
, 1, "<sp> b0, b1, b2, b3, b4, b5", 0, },
619 { "LPRT", LPRT
, ARGS
, 1, "<sp> af, hal, h1, h2, h3,..., pal, p1, p2...", 0, },
620 { "EPRT", EPRT
, STR1
, 1, "<sp> |af|addr|port|", 0, },
621 { "PASV", PASV
, NOARGS
, 1, "(set server in passive mode)", 0, },
622 { "LPSV", LPSV
, ARGS
, 1, "(set server in passive mode)", 0, },
623 { "EPSV", EPSV
, ARGS
, 1, "[<sp> af|ALL]", 0, },
624 { "TYPE", TYPE
, ARGS
, 1, "<sp> [ A | E | I | L ]", 0, },
625 { "STRU", STRU
, ARGS
, 1, "(specify file structure)", 0, },
626 { "MODE", MODE
, ARGS
, 1, "(specify transfer mode)", 0, },
627 { "RETR", RETR
, STR1
, 1, "<sp> file-name", 0, },
628 { "STOR", STOR
, STR1
, 1, "<sp> file-name", 0, },
629 { "STOU", STOU
, STR1
, 1, "<sp> file-name", 0, },
630 { "APPE", APPE
, STR1
, 1, "<sp> file-name", 0, },
631 { "ALLO", ALLO
, ARGS
, 1, "allocate storage (vacuously)", 0, },
632 { "REST", REST
, ARGS
, 1, "<sp> offset (restart command)", 0, },
633 { "RNFR", RNFR
, STR1
, 1, "<sp> file-name", 0, },
634 { "RNTO", RNTO
, STR1
, 1, "<sp> file-name", 0, },
635 { "ABOR", ABOR
, NOARGS
, 4, "(abort operation)", 0, },
636 { "DELE", DELE
, STR1
, 1, "<sp> file-name", 0, },
637 { "RMD", RMD
, STR1
, 1, "<sp> path-name", 0, },
638 { "MKD", MKD
, STR1
, 1, "<sp> path-name", 0, },
639 { "PWD", PWD
, NOARGS
, 1, "(return current directory)", 0, },
640 { "LIST", LIST
, OSTR
, 1, "[ <sp> path-name ]", 0, },
641 { "NLST", NLST
, OSTR
, 1, "[ <sp> path-name ]", 0, },
642 { "SITE", SITE
, SITECMD
, 1, "site-cmd [ <sp> arguments ]", 0, },
643 { "SYST", SYST
, NOARGS
, 1, "(get type of operating system)", 0, },
644 { "STAT", STAT
, OSTR
, 4, "[ <sp> path-name ]", 0, },
645 { "HELP", HELP
, OSTR
, 1, "[ <sp> <string> ]", 0, },
646 { "NOOP", NOOP
, NOARGS
, 2, "", 0, },
648 /* From RFC 2228, in order defined */
649 { "AUTH", AUTH
, STR1
, 1, "<sp> mechanism-name", 0, },
650 { "ADAT", ADAT
, STR1
, 1, "<sp> base-64-data", 0, },
651 { "PROT", PROT
, STR1
, 1, "<sp> prot-code", 0, },
652 { "PBSZ", PBSZ
, ARGS
, 1, "<sp> decimal-integer", 0, },
653 { "CCC", CCC
, NOARGS
, 1, "(Disable data protection)", 0, },
654 { "MIC", MIC
, STR1
, 4, "<sp> base64data", 0, },
655 { "CONF", CONF
, STR1
, 4, "<sp> base64data", 0, },
656 { "ENC", ENC
, STR1
, 4, "<sp> base64data", 0, },
658 /* From RFC 2389, in order defined */
659 { "FEAT", FEAT
, NOARGS
, 1, "(display extended features)", 0, },
660 { "OPTS", OPTS
, STR1
, 1, "<sp> command [ <sp> options ]", 0, },
662 /* From RFC 3659, in order defined */
663 { "MDTM", MDTM
, OSTR
, 1, "<sp> path-name", 0, },
664 { "SIZE", SIZE
, OSTR
, 1, "<sp> path-name", 0, },
665 { "MLST", MLST
, OSTR
, 2, "[ <sp> path-name ]", 0, },
666 { "MLSD", MLSD
, OSTR
, 1, "[ <sp> directory-name ]", 0, },
668 /* obsolete commands */
669 { "MAIL", MAIL
, OSTR
, 0, "(mail to user)", 0, },
670 { "MLFL", MLFL
, OSTR
, 0, "(mail file)", 0, },
671 { "MRCP", MRCP
, STR1
, 0, "(mail recipient)", 0, },
672 { "MRSQ", MRSQ
, OSTR
, 0, "(mail recipient scheme question)", 0, },
673 { "MSAM", MSAM
, OSTR
, 0, "(mail send to terminal and mailbox)", 0, },
674 { "MSND", MSND
, OSTR
, 0, "(mail send to terminal)", 0, },
675 { "MSOM", MSOM
, OSTR
, 0, "(mail send to terminal or mailbox)", 0, },
676 { "XCUP", CDUP
, NOARGS
, 1, "(change to parent directory)", 0, },
677 { "XCWD", CWD
, OSTR
, 1, "[ <sp> directory-name ]", 0, },
678 { "XMKD", MKD
, STR1
, 1, "<sp> path-name", 0, },
679 { "XPWD", PWD
, NOARGS
, 1, "(return current directory)", 0, },
680 { "XRMD", RMD
, STR1
, 1, "<sp> path-name", 0, },
682 { NULL
, 0, 0, 0, 0, 0, }
685 struct tab sitetab
[] = {
686 { "CHMOD", CHMOD
, NSTR
, 1, "<sp> mode <sp> file-name", 0, },
687 { "HELP", HELP
, OSTR
, 1, "[ <sp> <string> ]", 0, },
688 { "IDLE", IDLE
, ARGS
, 1, "[ <sp> maximum-idle-time ]", 0, },
689 { "RATEGET", RATEGET
,OSTR
, 1, "[ <sp> get-throttle-rate ]", 0, },
690 { "RATEPUT", RATEPUT
,OSTR
, 1, "[ <sp> put-throttle-rate ]", 0, },
691 { "UMASK", UMASK
, ARGS
, 1, "[ <sp> umask ]", 0, },
692 { NULL
, 0, 0, 0, 0, 0, }
696 * Check if a filename is allowed to be modified (isupload == 0) or
697 * uploaded (isupload == 1), and if necessary, check the filename is `sane'.
698 * If the filename is NULL, fail.
699 * If the filename is "", don't do the sane name check.
702 check_write(const char *file
, int isupload
)
707 reply(530, "Please login with USER and PASS.");
710 /* checking modify */
711 if (! isupload
&& ! CURCLASS_FLAGS_ISSET(modify
)) {
712 reply(502, "No permission to use this command.");
715 /* checking upload */
716 if (isupload
&& ! CURCLASS_FLAGS_ISSET(upload
)) {
717 reply(502, "No permission to use this command.");
721 /* checking sanenames */
722 if (file
[0] != '\0' && CURCLASS_FLAGS_ISSET(sanenames
)) {
727 for (p
= file
; *p
; p
++) {
728 if (isalnum((unsigned char)*p
) || *p
== '-' || *p
== '+' ||
729 *p
== ',' || *p
== '.' || *p
== '_')
732 reply(553, "File name `%s' not allowed.", file
);
740 lookup(struct tab
*p
, const char *cmd
)
743 for (; p
->name
!= NULL
; p
++)
744 if (strcasecmp(cmd
, p
->name
) == 0)
749 #include <arpa/telnet.h>
752 * get_line - a hacked up version of fgets to ignore TELNET escape codes.
753 * `s' is the buffer to read into.
754 * `n' is the 1 less than the size of the buffer, to allow trailing NUL
755 * `iop' is the FILE to read from.
756 * Returns 0 on success, -1 on EOF, -2 if the command was too long.
759 get_line(char *s
, int n
, FILE *iop
)
765 /* tmpline may contain saved command from urgent mode interruption */
766 for (c
= 0; tmpline
[c
] != '\0' && --n
> 0; ++c
) {
768 if (tmpline
[c
] == '\n') {
771 syslog(LOG_DEBUG
, "command: %s", s
);
778 while ((c
= getc(iop
)) != EOF
) {
783 if ((c
= getc(iop
)) != EOF
) {
793 cprintf(stdout
, "%c%c%c", IAC
, DONT
, 0377&c
);
794 (void) fflush(stdout
);
801 cprintf(stdout
, "%c%c%c", IAC
, WONT
, 0377&c
);
802 (void) fflush(stdout
);
807 continue; /* ignore command */
814 * If command doesn't fit into buffer, discard the
815 * rest of the command and indicate truncation.
816 * This prevents the command to be split up into
821 "command too long, last char: %d", c
);
822 while (c
!= '\n' && (c
= getc(iop
)) != EOF
)
829 if (c
== EOF
&& cs
== s
)
833 if ((curclass
.type
!= CLASS_GUEST
&&
834 strncasecmp(s
, "PASS ", 5) == 0) ||
835 strncasecmp(s
, "ACCT ", 5) == 0) {
836 /* Don't syslog passwords */
837 syslog(LOG_DEBUG
, "command: %.4s ???", s
);
842 /* Don't syslog trailing CR-LF */
845 while (cp
>= s
&& (*cp
== '\n' || *cp
== '\r')) {
849 syslog(LOG_DEBUG
, "command: %.*s", len
, s
);
856 ftp_handle_line(char *cp
)
869 (void) alarm(curclass
.timeout
);
870 ret
= get_line(cbuf
, sizeof(cbuf
)-1, stdin
);
873 reply(221, "You could at least say goodbye.");
875 } else if (ret
== -2) {
876 reply(500, "Command too long.");
878 ftp_handle_line(cbuf
);
887 static int cpos
, state
;
897 if ((cp
= strchr(cmdp
, '\r'))) {
899 #if defined(HAVE_SETPROCTITLE)
900 if (strncasecmp(cmdp
, "PASS", 4) != 0 &&
901 strncasecmp(cmdp
, "ACCT", 4) != 0)
902 setproctitle("%s: %s", proctitle
, cmdp
);
903 #endif /* defined(HAVE_SETPROCTITLE) */
907 if ((cp
= strpbrk(cmdp
, " \n")))
913 p
= lookup(cmdtab
, cmdp
);
916 if (is_oob
&& ! CMD_OOB(p
)) {
917 /* command will be handled in-band */
919 } else if (! CMD_IMPLEMENTED(p
)) {
920 reply(502, "%s command not implemented.",
932 if (cmdp
[cpos
] == ' ') {
937 if ((cp2
= strpbrk(cp
, " \n")))
941 p
= lookup(sitetab
, cp
);
944 if (!CMD_IMPLEMENTED(p
)) {
945 reply(502, "SITE %s command not implemented.",
957 if (cmdp
[cpos
] == '\n') {
966 if (cmdp
[cpos
] == ' ') {
968 state
= state
== OSTR
? STR2
: state
+1;
974 if (cmdp
[cpos
] == '\n') {
985 * Make sure the string is nonempty and \n terminated.
987 if (n
> 1 && cmdp
[cpos
] == '\n') {
989 yylval
.s
= ftpd_strdup(cp
);
997 if (cmdp
[cpos
] == ' ') {
1001 if (isdigit((unsigned char)cmdp
[cpos
])) {
1003 while (isdigit((unsigned char)cmdp
[++cpos
]))
1007 yylval
.u
.i
= atoi(cp
);
1016 if (isdigit((unsigned char)cmdp
[cpos
])) {
1018 while (isdigit((unsigned char)cmdp
[++cpos
]))
1022 yylval
.u
.i
= atoi(cp
);
1023 yylval
.u
.ll
= STRTOLL(cp
, NULL
, 10);
1027 if (strncasecmp(&cmdp
[cpos
], "ALL", 3) == 0
1028 && !isalnum((unsigned char)cmdp
[cpos
+ 3])) {
1032 switch (cmdp
[cpos
++]) {
1096 if (cmdp
[cpos
] == '\n') {
1102 reply(501, "'%s' command does not take any arguments.", cmdp
);
1112 fatal("Unknown state in scanner.");
1121 yyerror(const char *s
)
1125 if (hasyyerrored
|| is_oob
)
1127 if ((cp
= strchr(cmdp
,'\n')) != NULL
)
1129 reply(500, "'%s': command not understood.", cmdp
);
1134 help(struct tab
*ctab
, const char *s
)
1140 if (ctab
== sitetab
)
1144 width
= 0, NCMDS
= 0;
1145 for (c
= ctab
; c
->name
!= NULL
; c
++) {
1146 int len
= strlen(c
->name
);
1152 width
= (width
+ 8) &~ 7;
1157 reply(-214, "%s", "");
1158 reply(0, "The following %scommands are recognized.", htype
);
1159 reply(0, "(`-' = not implemented, `+' = supports options)");
1160 columns
= 76 / width
;
1163 lines
= (NCMDS
+ columns
- 1) / columns
;
1164 for (i
= 0; i
< lines
; i
++) {
1165 cprintf(stdout
, " ");
1166 for (j
= 0; j
< columns
; j
++) {
1167 c
= ctab
+ j
* lines
+ i
;
1168 cprintf(stdout
, "%s", c
->name
);
1169 w
= strlen(c
->name
);
1170 if (! CMD_IMPLEMENTED(c
)) {
1174 if (CMD_HAS_OPTIONS(c
)) {
1178 if (c
+ lines
>= &ctab
[NCMDS
])
1185 cprintf(stdout
, "\r\n");
1187 (void) fflush(stdout
);
1188 reply(214, "Direct comments to ftp-bugs@%s.", hostname
);
1191 c
= lookup(ctab
, s
);
1192 if (c
== (struct tab
*)0) {
1193 reply(502, "Unknown command '%s'.", s
);
1196 if (CMD_IMPLEMENTED(c
))
1197 reply(214, "Syntax: %s%s %s", htype
, c
->name
, c
->help
);
1199 reply(504, "%s%-*s\t%s; not implemented.", htype
, width
,
1204 * Check that the structures used for a PORT, LPRT or EPRT command are
1205 * valid (data_dest, his_addr), and if necessary, detect ftp bounce attacks.
1206 * If family != -1 check that his_addr.su_family == family.
1209 port_check(const char *cmd
, int family
)
1211 char h1
[NI_MAXHOST
], h2
[NI_MAXHOST
];
1212 char s1
[NI_MAXHOST
], s2
[NI_MAXHOST
];
1213 #ifdef NI_WITHSCOPEID
1214 const int niflags
= NI_NUMERICHOST
| NI_NUMERICSERV
| NI_WITHSCOPEID
;
1216 const int niflags
= NI_NUMERICHOST
| NI_NUMERICSERV
;
1220 reply(501, "%s disallowed after EPSV ALL", cmd
);
1224 if (family
!= -1 && his_addr
.su_family
!= family
) {
1226 reply(500, "Illegal %s command rejected", cmd
);
1230 if (data_dest
.su_family
!= his_addr
.su_family
)
1231 goto port_check_fail
;
1233 /* be paranoid, if told so */
1234 if (CURCLASS_FLAGS_ISSET(checkportcmd
)) {
1237 * be paranoid, there are getnameinfo implementation that does
1238 * not present scopeid portion
1240 if (data_dest
.su_family
== AF_INET6
&&
1241 data_dest
.su_scope_id
!= his_addr
.su_scope_id
)
1242 goto port_check_fail
;
1245 if (getnameinfo((struct sockaddr
*)&data_dest
, data_dest
.su_len
,
1246 h1
, sizeof(h1
), s1
, sizeof(s1
), niflags
))
1247 goto port_check_fail
;
1248 if (getnameinfo((struct sockaddr
*)&his_addr
, his_addr
.su_len
,
1249 h2
, sizeof(h2
), s2
, sizeof(s2
), niflags
))
1250 goto port_check_fail
;
1252 if (atoi(s1
) < IPPORT_RESERVED
|| strcmp(h1
, h2
) != 0)
1253 goto port_check_fail
;
1258 (void) close(pdata
);
1261 reply(200, "%s command successful.", cmd
);
1263 #line 1263 "ftpcmd.c"
1266 #include <stdio.h> /* needed for printf */
1269 #include <stdlib.h> /* needed for malloc, etc */
1270 #include <string.h> /* needed for memset */
1272 /* allocate initial stack or double stack size, up to YYMAXDEPTH */
1273 static int yygrowstack(YYSTACKDATA
*data
)
1280 if ((newsize
= data
->stacksize
) == 0)
1281 newsize
= YYINITSTACKSIZE
;
1282 else if (newsize
>= YYMAXDEPTH
)
1284 else if ((newsize
*= 2) > YYMAXDEPTH
)
1285 newsize
= YYMAXDEPTH
;
1287 i
= data
->s_mark
- data
->s_base
;
1288 newss
= (short *)realloc(data
->s_base
, newsize
* sizeof(*newss
));
1292 data
->s_base
= newss
;
1293 data
->s_mark
= newss
+ i
;
1295 newvs
= (YYSTYPE
*)realloc(data
->l_base
, newsize
* sizeof(*newvs
));
1299 data
->l_base
= newvs
;
1300 data
->l_mark
= newvs
+ i
;
1302 data
->stacksize
= newsize
;
1303 data
->s_last
= data
->s_base
+ newsize
- 1;
1307 #if YYPURE || defined(YY_NO_LEAKS)
1308 static void yyfreestack(YYSTACKDATA
*data
)
1312 memset(data
, 0, sizeof(*data
));
1315 #define yyfreestack(data) /* nothing */
1318 #define YYABORT goto yyabort
1319 #define YYREJECT goto yyabort
1320 #define YYACCEPT goto yyaccept
1321 #define YYERROR goto yyerrlab
1326 int yym
, yyn
, yystate
;
1330 if ((yys
= getenv("YYDEBUG")) != 0)
1333 if (yyn
>= '0' && yyn
<= '9')
1334 yydebug
= yyn
- '0';
1344 memset(&yystack
, 0, sizeof(yystack
));
1347 if (yystack
.s_base
== NULL
&& yygrowstack(&yystack
)) goto yyoverflow
;
1348 yystack
.s_mark
= yystack
.s_base
;
1349 yystack
.l_mark
= yystack
.l_base
;
1351 *yystack
.s_mark
= 0;
1354 if ((yyn
= yydefred
[yystate
]) != 0) goto yyreduce
;
1357 if ((yychar
= YYLEX
) < 0) yychar
= 0;
1362 if (yychar
<= YYMAXTOKEN
) yys
= yyname
[yychar
];
1363 if (!yys
) yys
= "illegal-symbol";
1364 printf("%sdebug: state %d, reading %d (%s)\n",
1365 YYPREFIX
, yystate
, yychar
, yys
);
1369 if ((yyn
= yysindex
[yystate
]) && (yyn
+= yychar
) >= 0 &&
1370 yyn
<= YYTABLESIZE
&& yycheck
[yyn
] == yychar
)
1374 printf("%sdebug: state %d, shifting to state %d\n",
1375 YYPREFIX
, yystate
, yytable
[yyn
]);
1377 if (yystack
.s_mark
>= yystack
.s_last
&& yygrowstack(&yystack
))
1381 yystate
= yytable
[yyn
];
1382 *++yystack
.s_mark
= yytable
[yyn
];
1383 *++yystack
.l_mark
= yylval
;
1385 if (yyerrflag
> 0) --yyerrflag
;
1388 if ((yyn
= yyrindex
[yystate
]) && (yyn
+= yychar
) >= 0 &&
1389 yyn
<= YYTABLESIZE
&& yycheck
[yyn
] == yychar
)
1394 if (yyerrflag
) goto yyinrecovery
;
1396 yyerror("syntax error");
1409 if ((yyn
= yysindex
[*yystack
.s_mark
]) && (yyn
+= YYERRCODE
) >= 0 &&
1410 yyn
<= YYTABLESIZE
&& yycheck
[yyn
] == YYERRCODE
)
1414 printf("%sdebug: state %d, error recovery shifting\
1415 to state %d\n", YYPREFIX
, *yystack
.s_mark
, yytable
[yyn
]);
1417 if (yystack
.s_mark
>= yystack
.s_last
&& yygrowstack(&yystack
))
1421 yystate
= yytable
[yyn
];
1422 *++yystack
.s_mark
= yytable
[yyn
];
1423 *++yystack
.l_mark
= yylval
;
1430 printf("%sdebug: error recovery discarding state %d\n",
1431 YYPREFIX
, *yystack
.s_mark
);
1433 if (yystack
.s_mark
<= yystack
.s_base
) goto yyabort
;
1441 if (yychar
== 0) goto yyabort
;
1446 if (yychar
<= YYMAXTOKEN
) yys
= yyname
[yychar
];
1447 if (!yys
) yys
= "illegal-symbol";
1448 printf("%sdebug: state %d, error recovery discards token %d (%s)\n",
1449 YYPREFIX
, yystate
, yychar
, yys
);
1459 printf("%sdebug: state %d, reducing by rule %d (%s)\n",
1460 YYPREFIX
, yystate
, yyn
, yyrule
[yyn
]);
1464 yyval
= yystack
.l_mark
[1-yym
];
1466 memset(&yyval
, 0, sizeof yyval
);
1470 #line 176 "ftpcmd.y"
1472 REASSIGN(fromname
, NULL
);
1473 restart_point
= (off_t
) 0;
1477 #line 188 "ftpcmd.y"
1479 user(yystack
.l_mark
[-1].s
);
1480 free(yystack
.l_mark
[-1].s
);
1484 #line 194 "ftpcmd.y"
1486 pass(yystack
.l_mark
[-1].s
);
1487 memset(yystack
.l_mark
[-1].s
, 0, strlen(yystack
.l_mark
[-1].s
));
1488 free(yystack
.l_mark
[-1].s
);
1492 #line 201 "ftpcmd.y"
1494 if (yystack
.l_mark
[-1].u
.i
)
1499 #line 207 "ftpcmd.y"
1501 if (yystack
.l_mark
[-3].u
.i
&& yystack
.l_mark
[-1].s
!= NULL
)
1502 cwd(yystack
.l_mark
[-1].s
);
1503 if (yystack
.l_mark
[-1].s
!= NULL
)
1504 free(yystack
.l_mark
[-1].s
);
1508 #line 215 "ftpcmd.y"
1510 if (yystack
.l_mark
[-1].u
.i
)
1515 #line 221 "ftpcmd.y"
1518 reply(-221, "%s", "");
1520 "Data traffic for this session was " LLF
" byte%s in " LLF
" file%s.",
1521 (LLT
)total_data
, PLURAL(total_data
),
1522 (LLT
)total_files
, PLURAL(total_files
));
1524 "Total traffic for this session was " LLF
" byte%s in " LLF
" transfer%s.",
1525 (LLT
)total_bytes
, PLURAL(total_bytes
),
1526 (LLT
)total_xfers
, PLURAL(total_xfers
));
1529 "Thank you for using the FTP service on %s.",
1531 if (logged_in
&& logging
) {
1533 "Data traffic: " LLF
" byte%s in " LLF
" file%s",
1534 (LLT
)total_data
, PLURAL(total_data
),
1535 (LLT
)total_files
, PLURAL(total_files
));
1537 "Total traffic: " LLF
" byte%s in " LLF
" transfer%s",
1538 (LLT
)total_bytes
, PLURAL(total_bytes
),
1539 (LLT
)total_xfers
, PLURAL(total_xfers
));
1546 #line 251 "ftpcmd.y"
1548 if (yystack
.l_mark
[-3].u
.i
)
1549 port_check("PORT", AF_INET
);
1553 #line 257 "ftpcmd.y"
1555 if (yystack
.l_mark
[-3].u
.i
)
1556 port_check("LPRT", AF_INET
);
1560 #line 263 "ftpcmd.y"
1563 if (yystack
.l_mark
[-3].u
.i
)
1564 port_check("LPRT", AF_INET6
);
1566 reply(500, "IPv6 support not available.");
1571 #line 273 "ftpcmd.y"
1573 if (yystack
.l_mark
[-3].u
.i
) {
1574 if (extended_port(yystack
.l_mark
[-1].s
) == 0)
1575 port_check("EPRT", -1);
1577 free(yystack
.l_mark
[-1].s
);
1581 #line 282 "ftpcmd.y"
1583 if (yystack
.l_mark
[-1].u
.i
) {
1584 if (CURCLASS_FLAGS_ISSET(passive
))
1587 reply(500, "PASV mode not available.");
1592 #line 292 "ftpcmd.y"
1594 if (yystack
.l_mark
[-1].u
.i
) {
1595 if (CURCLASS_FLAGS_ISSET(passive
)) {
1598 "LPSV disallowed after EPSV ALL");
1600 long_passive("LPSV", PF_UNSPEC
);
1602 reply(500, "LPSV mode not available.");
1607 #line 306 "ftpcmd.y"
1609 if (yystack
.l_mark
[-3].u
.i
) {
1610 if (CURCLASS_FLAGS_ISSET(passive
))
1611 long_passive("EPSV",
1612 epsvproto2af(yystack
.l_mark
[-1].u
.i
));
1614 reply(500, "EPSV mode not available.");
1619 #line 317 "ftpcmd.y"
1621 if (yystack
.l_mark
[-3].u
.i
) {
1622 if (CURCLASS_FLAGS_ISSET(passive
)) {
1624 "EPSV ALL command successful.");
1627 reply(500, "EPSV mode not available.");
1632 #line 329 "ftpcmd.y"
1634 if (yystack
.l_mark
[-1].u
.i
) {
1635 if (CURCLASS_FLAGS_ISSET(passive
))
1636 long_passive("EPSV", PF_UNSPEC
);
1638 reply(500, "EPSV mode not available.");
1643 #line 339 "ftpcmd.y"
1645 if (yystack
.l_mark
[-3].u
.i
) {
1650 if (cmd_form
== FORM_N
) {
1651 reply(200, "Type set to A.");
1655 reply(504, "Form must be N.");
1659 reply(504, "Type E not implemented.");
1663 reply(200, "Type set to I.");
1669 if (cmd_bytesz
== 8) {
1671 "Type set to L (byte size 8).");
1674 reply(504, "Byte size must be 8.");
1675 #else /* NBBY == 8 */
1676 UNIMPLEMENTED
for NBBY
!= 8
1677 #endif /* NBBY == 8 */
1684 #line 379 "ftpcmd.y"
1686 if (yystack
.l_mark
[-3].u
.i
) {
1687 switch (yystack
.l_mark
[-1].u
.i
) {
1690 reply(200, "STRU F ok.");
1694 reply(504, "Unimplemented STRU type.");
1700 #line 394 "ftpcmd.y"
1702 if (yystack
.l_mark
[-3].u
.i
) {
1703 switch (yystack
.l_mark
[-1].u
.i
) {
1706 reply(200, "MODE S ok.");
1710 reply(502, "Unimplemented MODE type.");
1716 #line 409 "ftpcmd.y"
1718 if (yystack
.l_mark
[-3].u
.i
&& yystack
.l_mark
[-1].s
!= NULL
)
1719 retrieve(NULL
, yystack
.l_mark
[-1].s
);
1720 if (yystack
.l_mark
[-1].s
!= NULL
)
1721 free(yystack
.l_mark
[-1].s
);
1725 #line 417 "ftpcmd.y"
1727 if (check_write(yystack
.l_mark
[-1].s
, 1))
1728 store(yystack
.l_mark
[-1].s
, "w", 0);
1729 if (yystack
.l_mark
[-1].s
!= NULL
)
1730 free(yystack
.l_mark
[-1].s
);
1734 #line 425 "ftpcmd.y"
1736 if (check_write(yystack
.l_mark
[-1].s
, 1))
1737 store(yystack
.l_mark
[-1].s
, "w", 1);
1738 if (yystack
.l_mark
[-1].s
!= NULL
)
1739 free(yystack
.l_mark
[-1].s
);
1743 #line 433 "ftpcmd.y"
1745 if (check_write(yystack
.l_mark
[-1].s
, 1))
1746 store(yystack
.l_mark
[-1].s
, "a", 0);
1747 if (yystack
.l_mark
[-1].s
!= NULL
)
1748 free(yystack
.l_mark
[-1].s
);
1752 #line 441 "ftpcmd.y"
1754 if (yystack
.l_mark
[-3].u
.i
)
1755 reply(202, "ALLO command ignored.");
1759 #line 447 "ftpcmd.y"
1761 if (yystack
.l_mark
[-7].u
.i
)
1762 reply(202, "ALLO command ignored.");
1766 #line 453 "ftpcmd.y"
1768 if (check_write(yystack
.l_mark
[-1].s
, 0)) {
1770 renamecmd(fromname
, yystack
.l_mark
[-1].s
);
1771 REASSIGN(fromname
, NULL
);
1773 reply(503, "Bad sequence of commands.");
1776 if (yystack
.l_mark
[-1].s
!= NULL
)
1777 free(yystack
.l_mark
[-1].s
);
1781 #line 467 "ftpcmd.y"
1785 else if (yystack
.l_mark
[-1].u
.i
)
1786 reply(225, "ABOR command successful.");
1790 #line 475 "ftpcmd.y"
1792 if (check_write(yystack
.l_mark
[-1].s
, 0))
1793 delete(yystack
.l_mark
[-1].s
);
1794 if (yystack
.l_mark
[-1].s
!= NULL
)
1795 free(yystack
.l_mark
[-1].s
);
1799 #line 483 "ftpcmd.y"
1801 if (check_write(yystack
.l_mark
[-1].s
, 0))
1802 removedir(yystack
.l_mark
[-1].s
);
1803 if (yystack
.l_mark
[-1].s
!= NULL
)
1804 free(yystack
.l_mark
[-1].s
);
1808 #line 491 "ftpcmd.y"
1810 if (check_write(yystack
.l_mark
[-1].s
, 0))
1811 makedir(yystack
.l_mark
[-1].s
);
1812 if (yystack
.l_mark
[-1].s
!= NULL
)
1813 free(yystack
.l_mark
[-1].s
);
1817 #line 499 "ftpcmd.y"
1819 if (yystack
.l_mark
[-1].u
.i
)
1824 #line 505 "ftpcmd.y"
1826 const char *argv
[] = { INTERNAL_LS
, "-lgA", NULL
};
1828 if (CURCLASS_FLAGS_ISSET(hidesymlinks
))
1830 if (yystack
.l_mark
[-1].u
.i
)
1835 #line 515 "ftpcmd.y"
1837 const char *argv
[] = { INTERNAL_LS
, "-lgA", NULL
, NULL
};
1839 if (CURCLASS_FLAGS_ISSET(hidesymlinks
))
1841 if (yystack
.l_mark
[-3].u
.i
&& yystack
.l_mark
[-1].s
!= NULL
) {
1842 argv
[2] = yystack
.l_mark
[-1].s
;
1843 retrieve(argv
, yystack
.l_mark
[-1].s
);
1845 if (yystack
.l_mark
[-1].s
!= NULL
)
1846 free(yystack
.l_mark
[-1].s
);
1850 #line 529 "ftpcmd.y"
1852 if (yystack
.l_mark
[-1].u
.i
)
1853 send_file_list(".");
1857 #line 535 "ftpcmd.y"
1859 if (yystack
.l_mark
[-3].u
.i
)
1860 send_file_list(yystack
.l_mark
[-1].s
);
1861 free(yystack
.l_mark
[-1].s
);
1865 #line 542 "ftpcmd.y"
1867 help(sitetab
, NULL
);
1871 #line 547 "ftpcmd.y"
1873 if (check_write(yystack
.l_mark
[-1].s
, 0)) {
1874 if ((yystack
.l_mark
[-3].u
.i
== -1) || (yystack
.l_mark
[-3].u
.i
> 0777))
1876 "CHMOD: Mode value must be between 0 and 0777");
1877 else if (chmod(yystack
.l_mark
[-1].s
, yystack
.l_mark
[-3].u
.i
) < 0)
1878 perror_reply(550, yystack
.l_mark
[-1].s
);
1880 reply(200, "CHMOD command successful.");
1882 if (yystack
.l_mark
[-1].s
!= NULL
)
1883 free(yystack
.l_mark
[-1].s
);
1887 #line 562 "ftpcmd.y"
1889 help(sitetab
, yystack
.l_mark
[-1].s
);
1890 free(yystack
.l_mark
[-1].s
);
1894 #line 568 "ftpcmd.y"
1896 if (yystack
.l_mark
[-1].u
.i
) {
1898 "Current IDLE time limit is " LLF
1899 " seconds; max " LLF
,
1900 (LLT
)curclass
.timeout
,
1901 (LLT
)curclass
.maxtimeout
);
1906 #line 579 "ftpcmd.y"
1908 if (yystack
.l_mark
[-3].u
.i
) {
1909 if (yystack
.l_mark
[-1].u
.i
< 30 || yystack
.l_mark
[-1].u
.i
> curclass
.maxtimeout
) {
1911 "IDLE time limit must be between 30 and "
1913 (LLT
)curclass
.maxtimeout
);
1915 curclass
.timeout
= yystack
.l_mark
[-1].u
.i
;
1916 (void) alarm(curclass
.timeout
);
1918 "IDLE time limit set to "
1920 (LLT
)curclass
.timeout
);
1926 #line 598 "ftpcmd.y"
1928 if (yystack
.l_mark
[-1].u
.i
) {
1930 "Current RATEGET is " LLF
" bytes/sec",
1931 (LLT
)curclass
.rateget
);
1936 #line 607 "ftpcmd.y"
1939 char *p
= yystack
.l_mark
[-1].s
;
1942 if (yystack
.l_mark
[-3].u
.i
) {
1943 rate
= strsuftollx("RATEGET", p
, 0,
1945 ? curclass
.maxrateget
1946 : LLTMAX
, errbuf
, sizeof(errbuf
));
1948 reply(501, "%s", errbuf
);
1950 curclass
.rateget
= rate
;
1952 "RATEGET set to " LLF
" bytes/sec",
1953 (LLT
)curclass
.rateget
);
1956 free(yystack
.l_mark
[-1].s
);
1960 #line 630 "ftpcmd.y"
1962 if (yystack
.l_mark
[-1].u
.i
) {
1964 "Current RATEPUT is " LLF
" bytes/sec",
1965 (LLT
)curclass
.rateput
);
1970 #line 639 "ftpcmd.y"
1973 char *p
= yystack
.l_mark
[-1].s
;
1976 if (yystack
.l_mark
[-3].u
.i
) {
1977 rate
= strsuftollx("RATEPUT", p
, 0,
1979 ? curclass
.maxrateput
1980 : LLTMAX
, errbuf
, sizeof(errbuf
));
1982 reply(501, "%s", errbuf
);
1984 curclass
.rateput
= rate
;
1986 "RATEPUT set to " LLF
" bytes/sec",
1987 (LLT
)curclass
.rateput
);
1990 free(yystack
.l_mark
[-1].s
);
1994 #line 662 "ftpcmd.y"
1998 if (yystack
.l_mark
[-1].u
.i
) {
2000 (void) umask(oldmask
);
2001 reply(200, "Current UMASK is %03o", oldmask
);
2006 #line 673 "ftpcmd.y"
2010 if (yystack
.l_mark
[-3].u
.i
&& check_write("", 0)) {
2011 if ((yystack
.l_mark
[-1].u
.i
== -1) || (yystack
.l_mark
[-1].u
.i
> 0777)) {
2012 reply(501, "Bad UMASK value");
2014 oldmask
= umask(yystack
.l_mark
[-1].u
.i
);
2016 "UMASK set to %03o (was %03o)",
2017 yystack
.l_mark
[-1].u
.i
, oldmask
);
2023 #line 689 "ftpcmd.y"
2025 if (EMPTYSTR(version
))
2026 reply(215, "UNIX Type: L%d", NBBY
);
2028 reply(215, "UNIX Type: L%d Version: %s", NBBY
,
2033 #line 698 "ftpcmd.y"
2035 if (yystack
.l_mark
[-3].u
.i
&& yystack
.l_mark
[-1].s
!= NULL
)
2036 statfilecmd(yystack
.l_mark
[-1].s
);
2037 if (yystack
.l_mark
[-1].s
!= NULL
)
2038 free(yystack
.l_mark
[-1].s
);
2042 #line 706 "ftpcmd.y"
2051 #line 714 "ftpcmd.y"
2057 #line 719 "ftpcmd.y"
2059 char *cp
= yystack
.l_mark
[-1].s
;
2061 if (strncasecmp(cp
, "SITE", 4) == 0) {
2062 cp
= yystack
.l_mark
[-1].s
+ 4;
2068 help(sitetab
, NULL
);
2070 help(cmdtab
, yystack
.l_mark
[-1].s
);
2071 free(yystack
.l_mark
[-1].s
);
2075 #line 736 "ftpcmd.y"
2077 reply(200, "NOOP command successful.");
2081 #line 742 "ftpcmd.y"
2083 reply(502, "RFC 2228 authentication not implemented.");
2084 free(yystack
.l_mark
[-1].s
);
2088 #line 748 "ftpcmd.y"
2091 "Please set authentication state with AUTH.");
2092 free(yystack
.l_mark
[-1].s
);
2096 #line 755 "ftpcmd.y"
2099 "Please set protection buffer size with PBSZ.");
2100 free(yystack
.l_mark
[-1].s
);
2104 #line 762 "ftpcmd.y"
2107 "Please set authentication state with AUTH.");
2111 #line 768 "ftpcmd.y"
2113 reply(533, "No protection enabled.");
2117 #line 773 "ftpcmd.y"
2119 reply(502, "RFC 2228 authentication not implemented.");
2120 free(yystack
.l_mark
[-1].s
);
2124 #line 779 "ftpcmd.y"
2126 reply(502, "RFC 2228 authentication not implemented.");
2127 free(yystack
.l_mark
[-1].s
);
2131 #line 785 "ftpcmd.y"
2133 reply(502, "RFC 2228 authentication not implemented.");
2134 free(yystack
.l_mark
[-1].s
);
2138 #line 792 "ftpcmd.y"
2145 #line 798 "ftpcmd.y"
2148 opts(yystack
.l_mark
[-1].s
);
2149 free(yystack
.l_mark
[-1].s
);
2153 #line 812 "ftpcmd.y"
2155 if (yystack
.l_mark
[-3].u
.i
&& yystack
.l_mark
[-1].s
!= NULL
)
2156 sizecmd(yystack
.l_mark
[-1].s
);
2157 if (yystack
.l_mark
[-1].s
!= NULL
)
2158 free(yystack
.l_mark
[-1].s
);
2162 #line 826 "ftpcmd.y"
2164 if (yystack
.l_mark
[-3].u
.i
&& yystack
.l_mark
[-1].s
!= NULL
) {
2166 if (stat(yystack
.l_mark
[-1].s
, &stbuf
) < 0)
2167 perror_reply(550, yystack
.l_mark
[-1].s
);
2168 else if (!S_ISREG(stbuf
.st_mode
)) {
2169 reply(550, "%s: not a plain file.", yystack
.l_mark
[-1].s
);
2173 t
= gmtime(&stbuf
.st_mtime
);
2175 "%04d%02d%02d%02d%02d%02d",
2176 TM_YEAR_BASE
+ t
->tm_year
,
2177 t
->tm_mon
+1, t
->tm_mday
,
2178 t
->tm_hour
, t
->tm_min
, t
->tm_sec
);
2181 if (yystack
.l_mark
[-1].s
!= NULL
)
2182 free(yystack
.l_mark
[-1].s
);
2186 #line 849 "ftpcmd.y"
2188 if (yystack
.l_mark
[-3].u
.i
&& yystack
.l_mark
[-1].s
!= NULL
)
2189 mlst(yystack
.l_mark
[-1].s
);
2190 if (yystack
.l_mark
[-1].s
!= NULL
)
2191 free(yystack
.l_mark
[-1].s
);
2195 #line 857 "ftpcmd.y"
2201 #line 862 "ftpcmd.y"
2203 if (yystack
.l_mark
[-3].u
.i
&& yystack
.l_mark
[-1].s
!= NULL
)
2204 mlsd(yystack
.l_mark
[-1].s
);
2205 if (yystack
.l_mark
[-1].s
!= NULL
)
2206 free(yystack
.l_mark
[-1].s
);
2210 #line 870 "ftpcmd.y"
2216 #line 875 "ftpcmd.y"
2222 #line 882 "ftpcmd.y"
2224 if (yystack
.l_mark
[-3].u
.i
) {
2225 REASSIGN(fromname
, NULL
);
2226 restart_point
= (off_t
)yystack
.l_mark
[-1].u
.ll
;
2228 "Restarting at " LLF
". Send STORE or RETRIEVE to initiate transfer.",
2229 (LLT
)restart_point
);
2234 #line 893 "ftpcmd.y"
2236 restart_point
= (off_t
) 0;
2237 if (check_write(yystack
.l_mark
[-1].s
, 0)) {
2238 REASSIGN(fromname
, NULL
);
2239 fromname
= renamefrom(yystack
.l_mark
[-1].s
);
2241 if (yystack
.l_mark
[-1].s
!= NULL
)
2242 free(yystack
.l_mark
[-1].s
);
2246 #line 910 "ftpcmd.y"
2248 yyval
.s
= (char *)calloc(1, sizeof(char));
2252 #line 919 "ftpcmd.y"
2254 yyval
.u
.i
= yystack
.l_mark
[0].u
.i
;
2258 #line 927 "ftpcmd.y"
2262 memset(&data_dest
, 0, sizeof(data_dest
));
2263 data_dest
.su_len
= sizeof(struct sockaddr_in
);
2264 data_dest
.su_family
= AF_INET
;
2265 p
= (char *)&data_dest
.su_port
;
2266 p
[0] = yystack
.l_mark
[-2].u
.i
; p
[1] = yystack
.l_mark
[0].u
.i
;
2267 a
= (char *)&data_dest
.su_addr
;
2268 a
[0] = yystack
.l_mark
[-10].u
.i
; a
[1] = yystack
.l_mark
[-8].u
.i
; a
[2] = yystack
.l_mark
[-6].u
.i
; a
[3] = yystack
.l_mark
[-4].u
.i
;
2272 #line 944 "ftpcmd.y"
2276 memset(&data_dest
, 0, sizeof(data_dest
));
2277 data_dest
.su_len
= sizeof(struct sockaddr_in
);
2278 data_dest
.su_family
= AF_INET
;
2279 p
= (char *)&data_dest
.su_port
;
2280 p
[0] = yystack
.l_mark
[-2].u
.i
; p
[1] = yystack
.l_mark
[0].u
.i
;
2281 a
= (char *)&data_dest
.su_addr
;
2282 a
[0] = yystack
.l_mark
[-12].u
.i
; a
[1] = yystack
.l_mark
[-10].u
.i
; a
[2] = yystack
.l_mark
[-8].u
.i
; a
[3] = yystack
.l_mark
[-6].u
.i
;
2284 /* reject invalid LPRT command */
2285 if (yystack
.l_mark
[-16].u
.i
!= 4 || yystack
.l_mark
[-14].u
.i
!= 4 || yystack
.l_mark
[-4].u
.i
!= 2)
2286 memset(&data_dest
, 0, sizeof(data_dest
));
2290 #line 968 "ftpcmd.y"
2293 unsigned char buf
[16];
2295 (void)memset(&data_dest
, 0, sizeof(data_dest
));
2296 data_dest
.su_len
= sizeof(struct sockaddr_in6
);
2297 data_dest
.su_family
= AF_INET6
;
2298 buf
[0] = yystack
.l_mark
[-2].u
.i
; buf
[1] = yystack
.l_mark
[0].u
.i
;
2299 (void)memcpy(&data_dest
.su_port
, buf
,
2300 sizeof(data_dest
.su_port
));
2301 buf
[0] = yystack
.l_mark
[-36].u
.i
; buf
[1] = yystack
.l_mark
[-34].u
.i
;
2302 buf
[2] = yystack
.l_mark
[-32].u
.i
; buf
[3] = yystack
.l_mark
[-30].u
.i
;
2303 buf
[4] = yystack
.l_mark
[-28].u
.i
; buf
[5] = yystack
.l_mark
[-26].u
.i
;
2304 buf
[6] = yystack
.l_mark
[-24].u
.i
; buf
[7] = yystack
.l_mark
[-22].u
.i
;
2305 buf
[8] = yystack
.l_mark
[-20].u
.i
; buf
[9] = yystack
.l_mark
[-18].u
.i
;
2306 buf
[10] = yystack
.l_mark
[-16].u
.i
; buf
[11] = yystack
.l_mark
[-14].u
.i
;
2307 buf
[12] = yystack
.l_mark
[-12].u
.i
; buf
[13] = yystack
.l_mark
[-10].u
.i
;
2308 buf
[14] = yystack
.l_mark
[-8].u
.i
; buf
[15] = yystack
.l_mark
[-6].u
.i
;
2309 (void)memcpy(&data_dest
.si_su
.su_sin6
.sin6_addr
,
2310 buf
, sizeof(data_dest
.si_su
.su_sin6
.sin6_addr
));
2311 if (his_addr
.su_family
== AF_INET6
) {
2312 /* XXX: more sanity checks! */
2313 data_dest
.su_scope_id
= his_addr
.su_scope_id
;
2316 memset(&data_dest
, 0, sizeof(data_dest
));
2318 /* reject invalid LPRT command */
2319 if (yystack
.l_mark
[-40].u
.i
!= 6 || yystack
.l_mark
[-38].u
.i
!= 16 || yystack
.l_mark
[-4].u
.i
!= 2)
2320 memset(&data_dest
, 0, sizeof(data_dest
));
2324 #line 1003 "ftpcmd.y"
2330 #line 1008 "ftpcmd.y"
2336 #line 1013 "ftpcmd.y"
2342 #line 1020 "ftpcmd.y"
2349 #line 1026 "ftpcmd.y"
2352 cmd_form
= yystack
.l_mark
[0].u
.i
;
2356 #line 1032 "ftpcmd.y"
2363 #line 1038 "ftpcmd.y"
2366 cmd_form
= yystack
.l_mark
[0].u
.i
;
2370 #line 1044 "ftpcmd.y"
2376 #line 1049 "ftpcmd.y"
2383 #line 1055 "ftpcmd.y"
2386 cmd_bytesz
= yystack
.l_mark
[0].u
.i
;
2390 #line 1062 "ftpcmd.y"
2393 cmd_bytesz
= yystack
.l_mark
[0].u
.i
;
2397 #line 1070 "ftpcmd.y"
2403 #line 1075 "ftpcmd.y"
2409 #line 1080 "ftpcmd.y"
2415 #line 1087 "ftpcmd.y"
2421 #line 1092 "ftpcmd.y"
2427 #line 1097 "ftpcmd.y"
2433 #line 1104 "ftpcmd.y"
2436 * Problem: this production is used for all pathname
2437 * processing, but only gives a 550 error reply.
2438 * This is a valid reply in some cases but not in
2441 if (logged_in
&& yystack
.l_mark
[0].s
&& *yystack
.l_mark
[0].s
== '~') {
2442 char *path
, *home
, *result
;
2445 path
= strchr(yystack
.l_mark
[0].s
+ 1, '/');
2448 if (yystack
.l_mark
[0].s
[1] == '\0')
2453 if ((hpw
= getpwnam(yystack
.l_mark
[0].s
+ 1)) != NULL
)
2456 home
= yystack
.l_mark
[0].s
;
2458 len
= strlen(home
) + 1;
2460 len
+= strlen(path
) + 1;
2461 if ((result
= malloc(len
)) == NULL
)
2462 fatal("Local resource failure: malloc");
2463 strlcpy(result
, home
, len
);
2465 strlcat(result
, "/", len
);
2466 strlcat(result
, path
, len
);
2469 free(yystack
.l_mark
[0].s
);
2471 yyval
.s
= yystack
.l_mark
[0].s
;
2475 #line 1151 "ftpcmd.y"
2477 int ret
, dec
, multby
, digit
;
2480 * Convert a number that was read as decimal number
2481 * to what it would be if it had been read as octal.
2483 dec
= yystack
.l_mark
[0].u
.i
;
2492 ret
+= digit
* multby
;
2500 #line 1189 "ftpcmd.y"
2502 yyval
.u
.i
= yystack
.l_mark
[0].u
.i
;
2506 #line 1196 "ftpcmd.y"
2511 reply(530, "Please login with USER and PASS.");
2517 #line 2517 "ftpcmd.c"
2519 yystack
.s_mark
-= yym
;
2520 yystate
= *yystack
.s_mark
;
2521 yystack
.l_mark
-= yym
;
2523 if (yystate
== 0 && yym
== 0)
2527 printf("%sdebug: after reduction, shifting from state 0 to\
2528 state %d\n", YYPREFIX
, YYFINAL
);
2531 *++yystack
.s_mark
= YYFINAL
;
2532 *++yystack
.l_mark
= yyval
;
2535 if ((yychar
= YYLEX
) < 0) yychar
= 0;
2540 if (yychar
<= YYMAXTOKEN
) yys
= yyname
[yychar
];
2541 if (!yys
) yys
= "illegal-symbol";
2542 printf("%sdebug: state %d, reading %d (%s)\n",
2543 YYPREFIX
, YYFINAL
, yychar
, yys
);
2547 if (yychar
== 0) goto yyaccept
;
2550 if ((yyn
= yygindex
[yym
]) && (yyn
+= yystate
) >= 0 &&
2551 yyn
<= YYTABLESIZE
&& yycheck
[yyn
] == yystate
)
2552 yystate
= yytable
[yyn
];
2554 yystate
= yydgoto
[yym
];
2557 printf("%sdebug: after reduction, shifting from state %d \
2558 to state %d\n", YYPREFIX
, *yystack
.s_mark
, yystate
);
2560 if (yystack
.s_mark
>= yystack
.s_last
&& yygrowstack(&yystack
))
2564 *++yystack
.s_mark
= (short) yystate
;
2565 *++yystack
.l_mark
= yyval
;
2569 yyerror("yacc stack overflow");
2572 yyfreestack(&yystack
);
2576 yyfreestack(&yystack
);