1
2 /* A Bison parser, made by GNU Bison 2.4.1. */
3
4 /* Skeleton implementation for Bison's Yacc-like parsers in C
5
6 Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
7 Free Software Foundation, Inc.
8
9 This program is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>. */
21
22 /* As a special exception, you may create a larger work that contains
23 part or all of the Bison parser skeleton and distribute that work
24 under terms of your choice, so long as that work isn't itself a
25 parser generator using the skeleton or a modified version thereof
26 as a parser skeleton. Alternatively, if you modify or redistribute
27 the parser skeleton itself, you may (at your option) remove this
28 special exception, which will cause the skeleton and the resulting
29 Bison output files to be licensed under the GNU General Public
30 License without this special exception.
31
32 This special exception was added by the Free Software Foundation in
33 version 2.2 of Bison. */
34
35 /* C LALR(1) parser skeleton written by Richard Stallman, by
36 simplifying the original so-called "semantic" parser. */
37
38 /* All symbols defined below should begin with yy or YY, to avoid
39 infringing on user name space. This should be done even for local
40 variables, as they might otherwise be expanded by user macros.
41 There are some unavoidable exceptions within include files to
42 define necessary library symbols; they are noted "INFRINGES ON
43 USER NAME SPACE" below. */
44
45 /* Identify Bison output. */
46 #define YYBISON 1
47
48 /* Bison version. */
49 #define YYBISON_VERSION "2.4.1"
50
51 /* Skeleton name. */
52 #define YYSKELETON_NAME "yacc.c"
53
54 /* Pure parsers. */
55 #define YYPURE 0
56
57 /* Push parsers. */
58 #define YYPUSH 0
59
60 /* Pull parsers. */
61 #define YYPULL 1
62
63 /* Using locations. */
64 #define YYLSP_NEEDED 0
65
66
67
68 /* Copy the first part of user declarations. */
69
70 /* Line 189 of yacc.c */
71 #line 69 "ftpcmd.y"
72
73
74 #if defined(HAVE_TNFTPD_H)
75 #include "tnftpd.h"
76 #else /* !defined(HAVE_TNFTPD_H) */
77
78 #include <sys/cdefs.h>
79
80 #ifndef lint
81 #if 0
82 static char sccsid[] = "@(#)ftpcmd.y 8.3 (Berkeley) 4/6/94";
83 #else
84 __RCSID(" NetBSD: ftpcmd.y,v 1.94 2015/08/10 07:45:50 shm Exp ");
85 #endif
86 #endif /* not lint */
87
88 #include <sys/param.h>
89 #include <sys/socket.h>
90 #include <sys/stat.h>
91
92 #include <netinet/in.h>
93 #include <arpa/ftp.h>
94 #include <arpa/inet.h>
95
96 #include <ctype.h>
97 #include <errno.h>
98 #include <pwd.h>
99 #include <stdio.h>
100 #include <stdlib.h>
101 #include <string.h>
102 #include <syslog.h>
103 #include <time.h>
104 #include <tzfile.h>
105 #include <unistd.h>
106 #include <netdb.h>
107
108 #ifdef KERBEROS5
109 #include <krb5/krb5.h>
110 #endif
111
112 #endif /* !defined(HAVE_TNFTPD_H) */
113
114 #include "extern.h"
115 #include "version.h"
116
117 static int cmd_type;
118 static int cmd_form;
119 static int cmd_bytesz;
120
121 char cbuf[FTP_BUFLEN];
122 char *cmdp;
123 char *fromname;
124
125 extern int epsvall;
126 struct tab sitetab[];
127
128 static int check_write(const char *, int);
129 static void help(struct tab *, const char *);
130 static void port_check(const char *, int);
131 int yylex(void);
132
133
134
135 /* Line 189 of yacc.c */
136 #line 137 "ftpcmd.c"
137
138 /* Enabling traces. */
139 #ifndef YYDEBUG
140 # define YYDEBUG 0
141 #endif
142
143 /* Enabling verbose error messages. */
144 #ifdef YYERROR_VERBOSE
145 # undef YYERROR_VERBOSE
146 # define YYERROR_VERBOSE 1
147 #else
148 # define YYERROR_VERBOSE 0
149 #endif
150
151 /* Enabling the token table. */
152 #ifndef YYTOKEN_TABLE
153 # define YYTOKEN_TABLE 0
154 #endif
155
156
157 /* Tokens. */
158 #ifndef YYTOKENTYPE
159 # define YYTOKENTYPE
160 /* Put the tokens into the symbol table, so that GDB and other debuggers
161 know about them. */
162 enum yytokentype {
163 A = 258,
164 B = 259,
165 C = 260,
166 E = 261,
167 F = 262,
168 I = 263,
169 L = 264,
170 N = 265,
171 P = 266,
172 R = 267,
173 S = 268,
174 T = 269,
175 SP = 270,
176 CRLF = 271,
177 COMMA = 272,
178 ALL = 273,
179 USER = 274,
180 PASS = 275,
181 ACCT = 276,
182 CWD = 277,
183 CDUP = 278,
184 SMNT = 279,
185 QUIT = 280,
186 REIN = 281,
187 PORT = 282,
188 PASV = 283,
189 TYPE = 284,
190 STRU = 285,
191 MODE = 286,
192 RETR = 287,
193 STOR = 288,
194 STOU = 289,
195 APPE = 290,
196 ALLO = 291,
197 REST = 292,
198 RNFR = 293,
199 RNTO = 294,
200 ABOR = 295,
201 DELE = 296,
202 RMD = 297,
203 MKD = 298,
204 PWD = 299,
205 LIST = 300,
206 NLST = 301,
207 SITE = 302,
208 SYST = 303,
209 STAT = 304,
210 HELP = 305,
211 NOOP = 306,
212 AUTH = 307,
213 ADAT = 308,
214 PROT = 309,
215 PBSZ = 310,
216 CCC = 311,
217 MIC = 312,
218 CONF = 313,
219 ENC = 314,
220 FEAT = 315,
221 OPTS = 316,
222 SIZE = 317,
223 MDTM = 318,
224 MLST = 319,
225 MLSD = 320,
226 LPRT = 321,
227 LPSV = 322,
228 EPRT = 323,
229 EPSV = 324,
230 MAIL = 325,
231 MLFL = 326,
232 MRCP = 327,
233 MRSQ = 328,
234 MSAM = 329,
235 MSND = 330,
236 MSOM = 331,
237 CHMOD = 332,
238 IDLE = 333,
239 RATEGET = 334,
240 RATEPUT = 335,
241 UMASK = 336,
242 LEXERR = 337,
243 STRING = 338,
244 NUMBER = 339
245 };
246 #endif
247 /* Tokens. */
248 #define A 258
249 #define B 259
250 #define C 260
251 #define E 261
252 #define F 262
253 #define I 263
254 #define L 264
255 #define N 265
256 #define P 266
257 #define R 267
258 #define S 268
259 #define T 269
260 #define SP 270
261 #define CRLF 271
262 #define COMMA 272
263 #define ALL 273
264 #define USER 274
265 #define PASS 275
266 #define ACCT 276
267 #define CWD 277
268 #define CDUP 278
269 #define SMNT 279
270 #define QUIT 280
271 #define REIN 281
272 #define PORT 282
273 #define PASV 283
274 #define TYPE 284
275 #define STRU 285
276 #define MODE 286
277 #define RETR 287
278 #define STOR 288
279 #define STOU 289
280 #define APPE 290
281 #define ALLO 291
282 #define REST 292
283 #define RNFR 293
284 #define RNTO 294
285 #define ABOR 295
286 #define DELE 296
287 #define RMD 297
288 #define MKD 298
289 #define PWD 299
290 #define LIST 300
291 #define NLST 301
292 #define SITE 302
293 #define SYST 303
294 #define STAT 304
295 #define HELP 305
296 #define NOOP 306
297 #define AUTH 307
298 #define ADAT 308
299 #define PROT 309
300 #define PBSZ 310
301 #define CCC 311
302 #define MIC 312
303 #define CONF 313
304 #define ENC 314
305 #define FEAT 315
306 #define OPTS 316
307 #define SIZE 317
308 #define MDTM 318
309 #define MLST 319
310 #define MLSD 320
311 #define LPRT 321
312 #define LPSV 322
313 #define EPRT 323
314 #define EPSV 324
315 #define MAIL 325
316 #define MLFL 326
317 #define MRCP 327
318 #define MRSQ 328
319 #define MSAM 329
320 #define MSND 330
321 #define MSOM 331
322 #define CHMOD 332
323 #define IDLE 333
324 #define RATEGET 334
325 #define RATEPUT 335
326 #define UMASK 336
327 #define LEXERR 337
328 #define STRING 338
329 #define NUMBER 339
330
331
332
333
334 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
335 typedef union YYSTYPE
336 {
337
338 /* Line 214 of yacc.c */
339 #line 132 "ftpcmd.y"
340
341 struct {
342 LLT ll;
343 int i;
344 } u;
345 char *s;
346 const char *cs;
347
348
349
350 /* Line 214 of yacc.c */
351 #line 352 "ftpcmd.c"
352 } YYSTYPE;
353 # define YYSTYPE_IS_TRIVIAL 1
354 # define yystype YYSTYPE /* obsolescent; will be withdrawn */
355 # define YYSTYPE_IS_DECLARED 1
356 #endif
357
358
359 /* Copy the second part of user declarations. */
360
361
362 /* Line 264 of yacc.c */
363 #line 364 "ftpcmd.c"
364
365 #ifdef short
366 # undef short
367 #endif
368
369 #ifdef YYTYPE_UINT8
370 typedef YYTYPE_UINT8 yytype_uint8;
371 #else
372 typedef unsigned char yytype_uint8;
373 #endif
374
375 #ifdef YYTYPE_INT8
376 typedef YYTYPE_INT8 yytype_int8;
377 #elif (defined __STDC__ || defined __C99__FUNC__ \
378 || defined __cplusplus || defined _MSC_VER)
379 typedef signed char yytype_int8;
380 #else
381 typedef short int yytype_int8;
382 #endif
383
384 #ifdef YYTYPE_UINT16
385 typedef YYTYPE_UINT16 yytype_uint16;
386 #else
387 typedef unsigned short int yytype_uint16;
388 #endif
389
390 #ifdef YYTYPE_INT16
391 typedef YYTYPE_INT16 yytype_int16;
392 #else
393 typedef short int yytype_int16;
394 #endif
395
396 #ifndef YYSIZE_T
397 # ifdef __SIZE_TYPE__
398 # define YYSIZE_T __SIZE_TYPE__
399 # elif defined size_t
400 # define YYSIZE_T size_t
401 # elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \
402 || defined __cplusplus || defined _MSC_VER)
403 # include <stddef.h> /* INFRINGES ON USER NAME SPACE */
404 # define YYSIZE_T size_t
405 # else
406 # define YYSIZE_T unsigned int
407 # endif
408 #endif
409
410 #define YYSIZE_MAXIMUM ((YYSIZE_T) -1)
411
412 #ifndef YY_
413 # if YYENABLE_NLS
414 # if ENABLE_NLS
415 # include <libintl.h> /* INFRINGES ON USER NAME SPACE */
416 # define YY_(msgid) dgettext ("bison-runtime", msgid)
417 # endif
418 # endif
419 # ifndef YY_
420 # define YY_(msgid) msgid
421 # endif
422 #endif
423
424 /* Suppress unused-variable warnings by "using" E. */
425 #if ! defined lint || defined __GNUC__
426 # define YYUSE(e) ((void) (e))
427 #else
428 # define YYUSE(e) /* empty */
429 #endif
430
431 /* Identity function, used to suppress warnings about constant conditions. */
432 #ifndef lint
433 # define YYID(n) (n)
434 #else
435 #if (defined __STDC__ || defined __C99__FUNC__ \
436 || defined __cplusplus || defined _MSC_VER)
437 static int
438 YYID (int yyi)
439 #else
440 static int
441 YYID (yyi)
442 int yyi;
443 #endif
444 {
445 return yyi;
446 }
447 #endif
448
449 #if ! defined yyoverflow || YYERROR_VERBOSE
450
451 /* The parser invokes alloca or malloc; define the necessary symbols. */
452
453 # ifdef YYSTACK_USE_ALLOCA
454 # if YYSTACK_USE_ALLOCA
455 # ifdef __GNUC__
456 # define YYSTACK_ALLOC __builtin_alloca
457 # elif defined __BUILTIN_VA_ARG_INCR
458 # include <alloca.h> /* INFRINGES ON USER NAME SPACE */
459 # elif defined _AIX
460 # define YYSTACK_ALLOC __alloca
461 # elif defined _MSC_VER
462 # include <malloc.h> /* INFRINGES ON USER NAME SPACE */
463 # define alloca _alloca
464 # else
465 # define YYSTACK_ALLOC alloca
466 # if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
467 || defined __cplusplus || defined _MSC_VER)
468 # include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
469 # ifndef _STDLIB_H
470 # define _STDLIB_H 1
471 # endif
472 # endif
473 # endif
474 # endif
475 # endif
476
477 # ifdef YYSTACK_ALLOC
478 /* Pacify GCC's `empty if-body' warning. */
479 # define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0))
480 # ifndef YYSTACK_ALLOC_MAXIMUM
481 /* The OS might guarantee only one guard page at the bottom of the stack,
482 and a page size can be as small as 4096 bytes. So we cannot safely
483 invoke alloca (N) if N exceeds 4096. Use a slightly smaller number
484 to allow for a few compiler-allocated temporary stack slots. */
485 # define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */
486 # endif
487 # else
488 # define YYSTACK_ALLOC YYMALLOC
489 # define YYSTACK_FREE YYFREE
490 # ifndef YYSTACK_ALLOC_MAXIMUM
491 # define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
492 # endif
493 # if (defined __cplusplus && ! defined _STDLIB_H \
494 && ! ((defined YYMALLOC || defined malloc) \
495 && (defined YYFREE || defined free)))
496 # include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
497 # ifndef _STDLIB_H
498 # define _STDLIB_H 1
499 # endif
500 # endif
501 # ifndef YYMALLOC
502 # define YYMALLOC malloc
503 # if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
504 || defined __cplusplus || defined _MSC_VER)
505 void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
506 # endif
507 # endif
508 # ifndef YYFREE
509 # define YYFREE free
510 # if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
511 || defined __cplusplus || defined _MSC_VER)
512 void free (void *); /* INFRINGES ON USER NAME SPACE */
513 # endif
514 # endif
515 # endif
516 #endif /* ! defined yyoverflow || YYERROR_VERBOSE */
517
518
519 #if (! defined yyoverflow \
520 && (! defined __cplusplus \
521 || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
522
523 /* A type that is properly aligned for any stack member. */
524 union yyalloc
525 {
526 yytype_int16 yyss_alloc;
527 YYSTYPE yyvs_alloc;
528 };
529
530 /* The size of the maximum gap between one aligned stack and the next. */
531 # define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
532
533 /* The size of an array large to enough to hold all stacks, each with
534 N elements. */
535 # define YYSTACK_BYTES(N) \
536 ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \
537 + YYSTACK_GAP_MAXIMUM)
538
539 /* Copy COUNT objects from FROM to TO. The source and destination do
540 not overlap. */
541 # ifndef YYCOPY
542 # if defined __GNUC__ && 1 < __GNUC__
543 # define YYCOPY(To, From, Count) \
544 __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
545 # else
546 # define YYCOPY(To, From, Count) \
547 do \
548 { \
549 YYSIZE_T yyi; \
550 for (yyi = 0; yyi < (Count); yyi++) \
551 (To)[yyi] = (From)[yyi]; \
552 } \
553 while (YYID (0))
554 # endif
555 # endif
556
557 /* Relocate STACK from its old location to the new one. The
558 local variables YYSIZE and YYSTACKSIZE give the old and new number of
559 elements in the stack, and YYPTR gives the new location of the
560 stack. Advance YYPTR to a properly aligned location for the next
561 stack. */
562 # define YYSTACK_RELOCATE(Stack_alloc, Stack) \
563 do \
564 { \
565 YYSIZE_T yynewbytes; \
566 YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \
567 Stack = &yyptr->Stack_alloc; \
568 yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
569 yyptr += yynewbytes / sizeof (*yyptr); \
570 } \
571 while (YYID (0))
572
573 #endif
574
575 /* YYFINAL -- State number of the termination state. */
576 #define YYFINAL 104
577 /* YYLAST -- Last index in YYTABLE. */
578 #define YYLAST 366
579
580 /* YYNTOKENS -- Number of terminals. */
581 #define YYNTOKENS 85
582 /* YYNNTS -- Number of nonterminals. */
583 #define YYNNTS 22
584 /* YYNRULES -- Number of rules. */
585 #define YYNRULES 105
586 /* YYNRULES -- Number of states. */
587 #define YYNSTATES 334
588
589 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
590 #define YYUNDEFTOK 2
591 #define YYMAXUTOK 339
592
593 #define YYTRANSLATE(YYX) \
594 ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
595
596 /* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */
597 static const yytype_uint8 yytranslate[] =
598 {
599 0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
600 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
601 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
602 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
603 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
604 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
605 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
606 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
607 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
608 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
609 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
610 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
611 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
612 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
613 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
614 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
615 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
616 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
617 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
618 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
619 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
620 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
621 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
622 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
623 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
624 2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
625 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
626 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
627 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
628 35, 36, 37, 38, 39, 40, 41, 42, 43, 44,
629 45, 46, 47, 48, 49, 50, 51, 52, 53, 54,
630 55, 56, 57, 58, 59, 60, 61, 62, 63, 64,
631 65, 66, 67, 68, 69, 70, 71, 72, 73, 74,
632 75, 76, 77, 78, 79, 80, 81, 82, 83, 84
633 };
634
635 #if YYDEBUG
636 /* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
637 YYRHS. */
638 static const yytype_uint16 yyprhs[] =
639 {
640 0, 0, 3, 5, 7, 12, 17, 21, 27, 31,
641 34, 40, 46, 52, 58, 62, 66, 72, 78, 82,
642 88, 94, 100, 106, 111, 116, 121, 127, 137, 142,
643 146, 151, 156, 161, 165, 169, 175, 179, 185, 190,
644 199, 206, 212, 220, 226, 234, 240, 248, 254, 262,
645 265, 271, 274, 277, 282, 285, 290, 295, 300, 305,
646 308, 313, 318, 323, 326, 331, 337, 343, 349, 353,
647 359, 363, 366, 372, 377, 379, 380, 382, 384, 396,
648 414, 456, 458, 460, 462, 464, 468, 470, 474, 476,
649 478, 482, 485, 487, 489, 491, 493, 495, 497, 499,
650 501, 503, 505, 507, 509, 511
651 };
652
653 /* YYRHS -- A `-1'-separated list of the rules' RHS. */
654 static const yytype_int8 yyrhs[] =
655 {
656 86, 0, -1, 87, -1, 88, -1, 19, 15, 89,
657 16, -1, 20, 15, 90, 16, -1, 22, 106, 16,
658 -1, 22, 106, 15, 99, 16, -1, 23, 106, 16,
659 -1, 25, 16, -1, 27, 106, 15, 92, 16, -1,
660 66, 106, 15, 93, 16, -1, 66, 106, 15, 94,
661 16, -1, 68, 106, 15, 83, 16, -1, 28, 106,
662 16, -1, 67, 106, 16, -1, 69, 106, 15, 84,
663 16, -1, 69, 106, 15, 18, 16, -1, 69, 106,
664 16, -1, 29, 106, 15, 96, 16, -1, 30, 106,
665 15, 97, 16, -1, 31, 106, 15, 98, 16, -1,
666 32, 106, 15, 99, 16, -1, 33, 15, 99, 16,
667 -1, 34, 15, 99, 16, -1, 35, 15, 99, 16,
668 -1, 36, 106, 15, 84, 16, -1, 36, 106, 15,
669 84, 15, 12, 15, 84, 16, -1, 39, 15, 99,
670 16, -1, 40, 106, 16, -1, 41, 15, 99, 16,
671 -1, 42, 15, 99, 16, -1, 43, 15, 99, 16,
672 -1, 44, 106, 16, -1, 45, 106, 16, -1, 45,
673 106, 15, 99, 16, -1, 46, 106, 16, -1, 46,
674 106, 15, 99, 16, -1, 47, 15, 50, 16, -1,
675 47, 15, 77, 15, 101, 15, 99, 16, -1, 47,
676 15, 50, 15, 83, 16, -1, 47, 15, 78, 106,
677 16, -1, 47, 15, 78, 106, 15, 84, 16, -1,
678 47, 15, 79, 106, 16, -1, 47, 15, 79, 106,
679 15, 83, 16, -1, 47, 15, 80, 106, 16, -1,
680 47, 15, 80, 106, 15, 83, 16, -1, 47, 15,
681 81, 106, 16, -1, 47, 15, 81, 106, 15, 101,
682 16, -1, 48, 16, -1, 49, 106, 15, 99, 16,
683 -1, 49, 16, -1, 50, 16, -1, 50, 15, 83,
684 16, -1, 51, 16, -1, 52, 15, 102, 16, -1,
685 53, 15, 103, 16, -1, 54, 15, 104, 16, -1,
686 55, 15, 105, 16, -1, 56, 16, -1, 57, 15,
687 103, 16, -1, 58, 15, 103, 16, -1, 59, 15,
688 103, 16, -1, 60, 16, -1, 61, 15, 83, 16,
689 -1, 62, 106, 15, 99, 16, -1, 63, 106, 15,
690 99, 16, -1, 64, 106, 15, 99, 16, -1, 64,
691 106, 16, -1, 65, 106, 15, 99, 16, -1, 65,
692 106, 16, -1, 1, 16, -1, 37, 106, 15, 84,
693 16, -1, 38, 15, 99, 16, -1, 83, -1, -1,
694 83, -1, 84, -1, 84, 17, 84, 17, 84, 17,
695 84, 17, 84, 17, 84, -1, 84, 17, 84, 17,
696 84, 17, 84, 17, 84, 17, 84, 17, 84, 17,
697 84, 17, 84, -1, 84, 17, 84, 17, 84, 17,
698 84, 17, 84, 17, 84, 17, 84, 17, 84, 17,
699 84, 17, 84, 17, 84, 17, 84, 17, 84, 17,
700 84, 17, 84, 17, 84, 17, 84, 17, 84, 17,
701 84, 17, 84, 17, 84, -1, 10, -1, 14, -1,
702 5, -1, 3, -1, 3, 15, 95, -1, 6, -1,
703 6, 15, 95, -1, 8, -1, 9, -1, 9, 15,
704 91, -1, 9, 91, -1, 7, -1, 12, -1, 11,
705 -1, 13, -1, 4, -1, 5, -1, 100, -1, 83,
706 -1, 84, -1, 83, -1, 83, -1, 83, -1, 84,
707 -1, -1
708 };
709
710 /* YYRLINE[YYN] -- source line where rule number YYN was defined. */
711 static const yytype_uint16 yyrline[] =
712 {
713 0, 183, 183, 189, 195, 201, 208, 214, 222, 228,
714 258, 264, 270, 280, 289, 299, 313, 324, 336, 346,
715 386, 401, 416, 424, 432, 440, 448, 454, 460, 474,
716 482, 490, 498, 506, 512, 522, 536, 542, 549, 554,
717 569, 575, 586, 605, 614, 637, 646, 669, 680, 696,
718 705, 713, 721, 726, 743, 749, 755, 762, 769, 775,
719 780, 786, 792, 799, 805, 819, 833, 856, 864, 869,
720 877, 882, 889, 900, 913, 918, 922, 926, 933, 949,
721 970, 1010, 1015, 1020, 1027, 1033, 1039, 1045, 1051, 1056,
722 1062, 1069, 1077, 1082, 1087, 1094, 1099, 1104, 1111, 1154,
723 1158, 1184, 1188, 1192, 1196, 1204
724 };
725 #endif
726
727 #if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE
728 /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
729 First, the terminals, then, starting at YYNTOKENS, nonterminals. */
730 static const char *const yytname[] =
731 {
732 "$end", "error", "$undefined", "A", "B", "C", "E", "F", "I", "L", "N",
733 "P", "R", "S", "T", "SP", "CRLF", "COMMA", "ALL", "USER", "PASS", "ACCT",
734 "CWD", "CDUP", "SMNT", "QUIT", "REIN", "PORT", "PASV", "TYPE", "STRU",
735 "MODE", "RETR", "STOR", "STOU", "APPE", "ALLO", "REST", "RNFR", "RNTO",
736 "ABOR", "DELE", "RMD", "MKD", "PWD", "LIST", "NLST", "SITE", "SYST",
737 "STAT", "HELP", "NOOP", "AUTH", "ADAT", "PROT", "PBSZ", "CCC", "MIC",
738 "CONF", "ENC", "FEAT", "OPTS", "SIZE", "MDTM", "MLST", "MLSD", "LPRT",
739 "LPSV", "EPRT", "EPSV", "MAIL", "MLFL", "MRCP", "MRSQ", "MSAM", "MSND",
740 "MSOM", "CHMOD", "IDLE", "RATEGET", "RATEPUT", "UMASK", "LEXERR",
741 "STRING", "NUMBER", "$accept", "cmd_sel", "cmd", "rcmd", "username",
742 "password", "byte_size", "host_port", "host_long_port4",
743 "host_long_port6", "form_code", "type_code", "struct_code", "mode_code",
744 "pathname", "pathstring", "octal_number", "mechanism_name", "base64data",
745 "prot_code", "decimal_integer", "check_login", 0
746 };
747 #endif
748
749 # ifdef YYPRINT
750 /* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
751 token YYLEX-NUM. */
752 static const yytype_uint16 yytoknum[] =
753 {
754 0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
755 265, 266, 267, 268, 269, 270, 271, 272, 273, 274,
756 275, 276, 277, 278, 279, 280, 281, 282, 283, 284,
757 285, 286, 287, 288, 289, 290, 291, 292, 293, 294,
758 295, 296, 297, 298, 299, 300, 301, 302, 303, 304,
759 305, 306, 307, 308, 309, 310, 311, 312, 313, 314,
760 315, 316, 317, 318, 319, 320, 321, 322, 323, 324,
761 325, 326, 327, 328, 329, 330, 331, 332, 333, 334,
762 335, 336, 337, 338, 339
763 };
764 # endif
765
766 /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
767 static const yytype_uint8 yyr1[] =
768 {
769 0, 85, 86, 86, 87, 87, 87, 87, 87, 87,
770 87, 87, 87, 87, 87, 87, 87, 87, 87, 87,
771 87, 87, 87, 87, 87, 87, 87, 87, 87, 87,
772 87, 87, 87, 87, 87, 87, 87, 87, 87, 87,
773 87, 87, 87, 87, 87, 87, 87, 87, 87, 87,
774 87, 87, 87, 87, 87, 87, 87, 87, 87, 87,
775 87, 87, 87, 87, 87, 87, 87, 87, 87, 87,
776 87, 87, 88, 88, 89, 90, 90, 91, 92, 93,
777 94, 95, 95, 95, 96, 96, 96, 96, 96, 96,
778 96, 96, 97, 97, 97, 98, 98, 98, 99, 100,
779 101, 102, 103, 104, 105, 106
780 };
781
782 /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
783 static const yytype_uint8 yyr2[] =
784 {
785 0, 2, 1, 1, 4, 4, 3, 5, 3, 2,
786 5, 5, 5, 5, 3, 3, 5, 5, 3, 5,
787 5, 5, 5, 4, 4, 4, 5, 9, 4, 3,
788 4, 4, 4, 3, 3, 5, 3, 5, 4, 8,
789 6, 5, 7, 5, 7, 5, 7, 5, 7, 2,
790 5, 2, 2, 4, 2, 4, 4, 4, 4, 2,
791 4, 4, 4, 2, 4, 5, 5, 5, 3, 5,
792 3, 2, 5, 4, 1, 0, 1, 1, 11, 17,
793 41, 1, 1, 1, 1, 3, 1, 3, 1, 1,
794 3, 2, 1, 1, 1, 1, 1, 1, 1, 1,
795 1, 1, 1, 1, 1, 0
796 };
797
798 /* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
799 STATE-NUM when YYTABLE doesn't specify something else to do. Zero
800 means the default is an error. */
801 static const yytype_uint8 yydefact[] =
802 {
803 0, 0, 0, 0, 105, 105, 0, 105, 105, 105,
804 105, 105, 105, 0, 0, 0, 105, 105, 0, 0,
805 105, 0, 0, 0, 105, 105, 105, 0, 0, 105,
806 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
807 0, 0, 105, 105, 105, 105, 105, 105, 105, 105,
808 0, 2, 3, 71, 0, 75, 0, 0, 9, 0,
809 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
810 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
811 49, 51, 0, 0, 52, 54, 0, 0, 0, 0,
812 59, 0, 0, 0, 63, 0, 0, 0, 0, 0,
813 0, 0, 0, 0, 1, 74, 0, 76, 0, 0,
814 6, 8, 0, 14, 0, 0, 0, 0, 99, 0,
815 98, 0, 0, 0, 0, 0, 0, 29, 0, 0,
816 0, 33, 0, 34, 0, 36, 0, 0, 105, 105,
817 105, 105, 0, 0, 101, 0, 102, 0, 103, 0,
818 104, 0, 0, 0, 0, 0, 0, 0, 0, 68,
819 0, 70, 0, 15, 0, 0, 18, 4, 5, 0,
820 0, 0, 84, 86, 88, 89, 0, 92, 94, 93,
821 0, 96, 97, 95, 0, 0, 23, 24, 25, 0,
822 0, 73, 28, 30, 31, 32, 0, 0, 0, 38,
823 0, 0, 0, 0, 0, 0, 53, 55, 56, 57,
824 58, 60, 61, 62, 64, 0, 0, 0, 0, 0,
825 0, 0, 0, 0, 0, 7, 0, 10, 0, 0,
826 0, 77, 91, 19, 20, 21, 22, 0, 26, 72,
827 35, 37, 0, 100, 0, 0, 41, 0, 43, 0,
828 45, 0, 47, 50, 65, 66, 67, 69, 0, 11,
829 12, 13, 17, 16, 0, 83, 81, 82, 85, 87,
830 90, 0, 40, 0, 0, 0, 0, 0, 0, 0,
831 0, 0, 42, 44, 46, 48, 0, 0, 0, 39,
832 0, 0, 27, 0, 0, 0, 0, 0, 0, 0,
833 0, 0, 78, 0, 0, 0, 0, 0, 0, 79,
834 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
835 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
836 0, 0, 0, 80
837 };
838
839 /* YYDEFGOTO[NTERM-NUM]. */
840 static const yytype_int16 yydefgoto[] =
841 {
842 -1, 50, 51, 52, 106, 108, 232, 171, 220, 221,
843 268, 176, 180, 184, 119, 120, 244, 145, 147, 149,
844 151, 56
845 };
846
847 /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
848 STATE-NUM. */
849 #define YYPACT_NINF -80
850 static const yytype_int16 yypact[] =
851 {
852 76, 0, 16, 23, -80, -80, 9, -80, -80, -80,
853 -80, -80, -80, 30, 33, 50, -80, -80, 52, 55,
854 -80, 78, 82, 85, -80, -80, -80, 87, 140, 141,
855 13, 142, 144, 145, 146, 147, 148, 150, 151, 152,
856 153, 155, -80, -80, -80, -80, -80, -80, -80, -80,
857 163, -80, -80, -80, 88, 89, 25, 157, -80, 159,
858 160, 162, 164, 165, 166, 92, 92, 92, 167, 168,
859 92, 92, 169, 92, 92, 92, 170, 57, 59, -17,
860 -80, -80, 172, 95, -80, -80, 101, 105, 106, 84,
861 -80, 105, 105, 105, -80, 107, 176, 177, 63, 65,
862 178, 179, 181, 67, -80, -80, 182, -80, 183, 92,
863 -80, -80, 110, -80, 41, -1, 19, 92, -80, 184,
864 -80, 185, 186, 113, 119, 188, 189, -80, 190, 192,
865 193, -80, 92, -80, 92, -80, 69, 195, -80, -80,
866 -80, -80, 92, 196, -80, 197, -80, 198, -80, 199,
867 -80, 200, 201, 202, 203, 204, 92, 92, 92, -80,
868 92, -80, 127, -80, 138, -15, -80, -80, -80, 206,
869 207, 209, 208, 211, -80, -13, 212, -80, -80, -80,
870 213, -80, -80, -80, 214, 215, -80, -80, -80, 71,
871 216, -80, -80, -80, -80, -80, 217, 218, 154, -80,
872 143, 73, 131, 137, 139, 219, -80, -80, -80, -80,
873 -80, -80, -80, -80, -80, 220, 222, 223, 224, 225,
874 227, 228, 229, 230, 231, -80, 171, -80, 32, 32,
875 173, -80, -80, -80, -80, -80, -80, 236, -80, -80,
876 -80, -80, 233, -80, 226, 174, -80, 180, -80, 187,
877 -80, 143, -80, -80, -80, -80, -80, -80, 175, -80,
878 -80, -80, -80, -80, 234, -80, -80, -80, -80, -80,
879 -80, 235, -80, 92, 237, 238, 240, 244, 245, 191,
880 194, 248, -80, -80, -80, -80, 205, 249, 251, -80,
881 252, 210, -80, 221, 254, 255, 232, 239, 256, 257,
882 241, 242, -80, 259, 243, 260, 246, 262, 247, 263,
883 250, 264, 253, 265, 258, 266, 261, 267, 268, 269,
884 270, 271, 272, 273, 274, 275, 276, 278, 277, 279,
885 280, 281, 282, -80
886 };
887
888 /* YYPGOTO[NTERM-NUM]. */
889 static const yytype_int8 yypgoto[] =
890 {
891 -80, -80, -80, -80, -80, -80, 22, -80, -80, -80,
892 36, -80, -80, -80, -66, -80, 17, -80, -79, -80,
893 -80, 10
894 };
895
896 /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
897 positive, shift that token. If negative, reduce the rule which
898 number is the opposite. If zero, do what YYDEFACT says.
899 If YYTABLE_NINF, syntax error. */
900 #define YYTABLE_NINF -1
901 static const yytype_uint16 yytable[] =
902 {
903 121, 122, 230, 223, 125, 126, 177, 128, 129, 130,
904 178, 179, 152, 153, 154, 57, 53, 59, 60, 61,
905 62, 63, 64, 181, 182, 58, 68, 69, 83, 84,
906 72, 54, 183, 136, 76, 77, 78, 265, 55, 82,
907 109, 110, 266, 169, 172, 65, 267, 173, 66, 174,
908 175, 185, 96, 97, 98, 99, 100, 101, 102, 103,
909 137, 138, 139, 140, 141, 67, 196, 70, 197, 224,
910 71, 231, 132, 133, 134, 135, 205, 1, 158, 159,
911 160, 161, 165, 166, 198, 199, 237, 238, 245, 246,
912 215, 216, 217, 73, 218, 2, 3, 74, 4, 5,
913 75, 6, 79, 7, 8, 9, 10, 11, 12, 13,
914 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
915 24, 25, 26, 27, 28, 29, 30, 31, 32, 33,
916 34, 35, 36, 37, 38, 39, 40, 41, 42, 43,
917 44, 45, 46, 47, 48, 49, 247, 248, 201, 202,
918 203, 204, 249, 250, 251, 252, 80, 81, 85, 86,
919 87, 88, 89, 104, 90, 91, 92, 93, 150, 94,
920 95, 105, 107, 111, 112, 118, 113, 114, 143, 115,
921 116, 117, 123, 124, 144, 127, 131, 142, 146, 148,
922 155, 156, 157, 162, 170, 163, 164, 189, 167, 168,
923 186, 187, 188, 190, 191, 192, 193, 281, 194, 195,
924 200, 219, 206, 207, 208, 209, 210, 211, 212, 213,
925 214, 222, 225, 228, 226, 227, 229, 243, 233, 234,
926 235, 236, 239, 240, 241, 253, 254, 242, 255, 256,
927 257, 273, 258, 259, 260, 261, 262, 263, 271, 272,
928 280, 279, 270, 282, 283, 264, 284, 231, 274, 278,
929 285, 0, 286, 275, 289, 269, 291, 292, 277, 293,
930 276, 296, 297, 300, 301, 287, 304, 306, 288, 308,
931 310, 312, 314, 316, 318, 0, 320, 0, 322, 290,
932 324, 0, 326, 0, 294, 328, 330, 0, 332, 0,
933 0, 0, 0, 0, 0, 295, 0, 0, 0, 0,
934 0, 0, 0, 0, 0, 0, 298, 0, 0, 0,
935 0, 0, 0, 299, 0, 302, 303, 305, 0, 0,
936 307, 309, 0, 0, 311, 0, 0, 313, 0, 0,
937 0, 0, 315, 0, 0, 317, 0, 0, 0, 0,
938 0, 0, 319, 0, 321, 0, 323, 0, 325, 0,
939 327, 329, 0, 0, 331, 0, 333
940 };
941
942 static const yytype_int16 yycheck[] =
943 {
944 66, 67, 15, 18, 70, 71, 7, 73, 74, 75,
945 11, 12, 91, 92, 93, 5, 16, 7, 8, 9,
946 10, 11, 12, 4, 5, 16, 16, 17, 15, 16,
947 20, 15, 13, 50, 24, 25, 26, 5, 15, 29,
948 15, 16, 10, 109, 3, 15, 14, 6, 15, 8,
949 9, 117, 42, 43, 44, 45, 46, 47, 48, 49,
950 77, 78, 79, 80, 81, 15, 132, 15, 134, 84,
951 15, 84, 15, 16, 15, 16, 142, 1, 15, 16,
952 15, 16, 15, 16, 15, 16, 15, 16, 15, 16,
953 156, 157, 158, 15, 160, 19, 20, 15, 22, 23,
954 15, 25, 15, 27, 28, 29, 30, 31, 32, 33,
955 34, 35, 36, 37, 38, 39, 40, 41, 42, 43,
956 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
957 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
958 64, 65, 66, 67, 68, 69, 15, 16, 138, 139,
959 140, 141, 15, 16, 15, 16, 16, 16, 16, 15,
960 15, 15, 15, 0, 16, 15, 15, 15, 84, 16,
961 15, 83, 83, 16, 15, 83, 16, 15, 83, 15,
962 15, 15, 15, 15, 83, 16, 16, 15, 83, 83,
963 83, 15, 15, 15, 84, 16, 15, 84, 16, 16,
964 16, 16, 16, 84, 16, 16, 16, 273, 16, 16,
965 15, 84, 16, 16, 16, 16, 16, 16, 16, 16,
966 16, 83, 16, 15, 17, 16, 15, 84, 16, 16,
967 16, 16, 16, 16, 16, 16, 16, 83, 16, 16,
968 16, 15, 17, 16, 16, 16, 16, 16, 12, 16,
969 15, 17, 230, 16, 16, 84, 16, 84, 84, 84,
970 16, -1, 17, 83, 16, 229, 17, 16, 251, 17,
971 83, 17, 17, 17, 17, 84, 17, 17, 84, 17,
972 17, 17, 17, 17, 17, -1, 17, -1, 17, 84,
973 17, -1, 17, -1, 84, 17, 17, -1, 17, -1,
974 -1, -1, -1, -1, -1, 84, -1, -1, -1, -1,
975 -1, -1, -1, -1, -1, -1, 84, -1, -1, -1,
976 -1, -1, -1, 84, -1, 84, 84, 84, -1, -1,
977 84, 84, -1, -1, 84, -1, -1, 84, -1, -1,
978 -1, -1, 84, -1, -1, 84, -1, -1, -1, -1,
979 -1, -1, 84, -1, 84, -1, 84, -1, 84, -1,
980 84, 84, -1, -1, 84, -1, 84
981 };
982
983 /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
984 symbol of state STATE-NUM. */
985 static const yytype_uint8 yystos[] =
986 {
987 0, 1, 19, 20, 22, 23, 25, 27, 28, 29,
988 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
989 40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
990 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
991 60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
992 86, 87, 88, 16, 15, 15, 106, 106, 16, 106,
993 106, 106, 106, 106, 106, 15, 15, 15, 106, 106,
994 15, 15, 106, 15, 15, 15, 106, 106, 106, 15,
995 16, 16, 106, 15, 16, 16, 15, 15, 15, 15,
996 16, 15, 15, 15, 16, 15, 106, 106, 106, 106,
997 106, 106, 106, 106, 0, 83, 89, 83, 90, 15,
998 16, 16, 15, 16, 15, 15, 15, 15, 83, 99,
999 100, 99, 99, 15, 15, 99, 99, 16, 99, 99,
1000 99, 16, 15, 16, 15, 16, 50, 77, 78, 79,
1001 80, 81, 15, 83, 83, 102, 83, 103, 83, 104,
1002 84, 105, 103, 103, 103, 83, 15, 15, 15, 16,
1003 15, 16, 15, 16, 15, 15, 16, 16, 16, 99,
1004 84, 92, 3, 6, 8, 9, 96, 7, 11, 12,
1005 97, 4, 5, 13, 98, 99, 16, 16, 16, 84,
1006 84, 16, 16, 16, 16, 16, 99, 99, 15, 16,
1007 15, 106, 106, 106, 106, 99, 16, 16, 16, 16,
1008 16, 16, 16, 16, 16, 99, 99, 99, 99, 84,
1009 93, 94, 83, 18, 84, 16, 17, 16, 15, 15,
1010 15, 84, 91, 16, 16, 16, 16, 15, 16, 16,
1011 16, 16, 83, 84, 101, 15, 16, 15, 16, 15,
1012 16, 15, 16, 16, 16, 16, 16, 16, 17, 16,
1013 16, 16, 16, 16, 84, 5, 10, 14, 95, 95,
1014 91, 12, 16, 15, 84, 83, 83, 101, 84, 17,
1015 15, 99, 16, 16, 16, 16, 17, 84, 84, 16,
1016 84, 17, 16, 17, 84, 84, 17, 17, 84, 84,
1017 17, 17, 84, 84, 17, 84, 17, 84, 17, 84,
1018 17, 84, 17, 84, 17, 84, 17, 84, 17, 84,
1019 17, 84, 17, 84, 17, 84, 17, 84, 17, 84,
1020 17, 84, 17, 84
1021 };
1022
1023 #define yyerrok (yyerrstatus = 0)
1024 #define yyclearin (yychar = YYEMPTY)
1025 #define YYEMPTY (-2)
1026 #define YYEOF 0
1027
1028 #define YYACCEPT goto yyacceptlab
1029 #define YYABORT goto yyabortlab
1030 #define YYERROR goto yyerrorlab
1031
1032
1033 /* Like YYERROR except do call yyerror. This remains here temporarily
1034 to ease the transition to the new meaning of YYERROR, for GCC.
1035 Once GCC version 2 has supplanted version 1, this can go. */
1036
1037 #define YYFAIL goto yyerrlab
1038
1039 #define YYRECOVERING() (!!yyerrstatus)
1040
1041 #define YYBACKUP(Token, Value) \
1042 do \
1043 if (yychar == YYEMPTY && yylen == 1) \
1044 { \
1045 yychar = (Token); \
1046 yylval = (Value); \
1047 yytoken = YYTRANSLATE (yychar); \
1048 YYPOPSTACK (1); \
1049 goto yybackup; \
1050 } \
1051 else \
1052 { \
1053 yyerror (YY_("syntax error: cannot back up")); \
1054 YYERROR; \
1055 } \
1056 while (YYID (0))
1057
1058
1059 #define YYTERROR 1
1060 #define YYERRCODE 256
1061
1062
1063 /* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
1064 If N is 0, then set CURRENT to the empty location which ends
1065 the previous symbol: RHS[0] (always defined). */
1066
1067 #define YYRHSLOC(Rhs, K) ((Rhs)[K])
1068 #ifndef YYLLOC_DEFAULT
1069 # define YYLLOC_DEFAULT(Current, Rhs, N) \
1070 do \
1071 if (YYID (N)) \
1072 { \
1073 (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \
1074 (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \
1075 (Current).last_line = YYRHSLOC (Rhs, N).last_line; \
1076 (Current).last_column = YYRHSLOC (Rhs, N).last_column; \
1077 } \
1078 else \
1079 { \
1080 (Current).first_line = (Current).last_line = \
1081 YYRHSLOC (Rhs, 0).last_line; \
1082 (Current).first_column = (Current).last_column = \
1083 YYRHSLOC (Rhs, 0).last_column; \
1084 } \
1085 while (YYID (0))
1086 #endif
1087
1088
1089 /* YY_LOCATION_PRINT -- Print the location on the stream.
1090 This macro was not mandated originally: define only if we know
1091 we won't break user code: when these are the locations we know. */
1092
1093 #ifndef YY_LOCATION_PRINT
1094 # if YYLTYPE_IS_TRIVIAL
1095 # define YY_LOCATION_PRINT(File, Loc) \
1096 fprintf (File, "%d.%d-%d.%d", \
1097 (Loc).first_line, (Loc).first_column, \
1098 (Loc).last_line, (Loc).last_column)
1099 # else
1100 # define YY_LOCATION_PRINT(File, Loc) ((void) 0)
1101 # endif
1102 #endif
1103
1104
1105 /* YYLEX -- calling `yylex' with the right arguments. */
1106
1107 #ifdef YYLEX_PARAM
1108 # define YYLEX yylex (YYLEX_PARAM)
1109 #else
1110 # define YYLEX yylex ()
1111 #endif
1112
1113 /* Enable debugging if requested. */
1114 #if YYDEBUG
1115
1116 # ifndef YYFPRINTF
1117 # include <stdio.h> /* INFRINGES ON USER NAME SPACE */
1118 # define YYFPRINTF fprintf
1119 # endif
1120
1121 # define YYDPRINTF(Args) \
1122 do { \
1123 if (yydebug) \
1124 YYFPRINTF Args; \
1125 } while (YYID (0))
1126
1127 # define YY_SYMBOL_PRINT(Title, Type, Value, Location) \
1128 do { \
1129 if (yydebug) \
1130 { \
1131 YYFPRINTF (stderr, "%s ", Title); \
1132 yy_symbol_print (stderr, \
1133 Type, Value); \
1134 YYFPRINTF (stderr, "\n"); \
1135 } \
1136 } while (YYID (0))
1137
1138
1139 /*--------------------------------.
1140 | Print this symbol on YYOUTPUT. |
1141 `--------------------------------*/
1142
1143 /*ARGSUSED*/
1144 #if (defined __STDC__ || defined __C99__FUNC__ \
1145 || defined __cplusplus || defined _MSC_VER)
1146 static void
1147 yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
1148 #else
1149 static void
1150 yy_symbol_value_print (yyoutput, yytype, yyvaluep)
1151 FILE *yyoutput;
1152 int yytype;
1153 YYSTYPE const * const yyvaluep;
1154 #endif
1155 {
1156 if (!yyvaluep)
1157 return;
1158 # ifdef YYPRINT
1159 if (yytype < YYNTOKENS)
1160 YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
1161 # else
1162 YYUSE (yyoutput);
1163 # endif
1164 switch (yytype)
1165 {
1166 default:
1167 break;
1168 }
1169 }
1170
1171
1172 /*--------------------------------.
1173 | Print this symbol on YYOUTPUT. |
1174 `--------------------------------*/
1175
1176 #if (defined __STDC__ || defined __C99__FUNC__ \
1177 || defined __cplusplus || defined _MSC_VER)
1178 static void
1179 yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
1180 #else
1181 static void
1182 yy_symbol_print (yyoutput, yytype, yyvaluep)
1183 FILE *yyoutput;
1184 int yytype;
1185 YYSTYPE const * const yyvaluep;
1186 #endif
1187 {
1188 if (yytype < YYNTOKENS)
1189 YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
1190 else
1191 YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
1192
1193 yy_symbol_value_print (yyoutput, yytype, yyvaluep);
1194 YYFPRINTF (yyoutput, ")");
1195 }
1196
1197 /*------------------------------------------------------------------.
1198 | yy_stack_print -- Print the state stack from its BOTTOM up to its |
1199 | TOP (included). |
1200 `------------------------------------------------------------------*/
1201
1202 #if (defined __STDC__ || defined __C99__FUNC__ \
1203 || defined __cplusplus || defined _MSC_VER)
1204 static void
1205 yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop)
1206 #else
1207 static void
1208 yy_stack_print (yybottom, yytop)
1209 yytype_int16 *yybottom;
1210 yytype_int16 *yytop;
1211 #endif
1212 {
1213 YYFPRINTF (stderr, "Stack now");
1214 for (; yybottom <= yytop; yybottom++)
1215 {
1216 int yybot = *yybottom;
1217 YYFPRINTF (stderr, " %d", yybot);
1218 }
1219 YYFPRINTF (stderr, "\n");
1220 }
1221
1222 # define YY_STACK_PRINT(Bottom, Top) \
1223 do { \
1224 if (yydebug) \
1225 yy_stack_print ((Bottom), (Top)); \
1226 } while (YYID (0))
1227
1228
1229 /*------------------------------------------------.
1230 | Report that the YYRULE is going to be reduced. |
1231 `------------------------------------------------*/
1232
1233 #if (defined __STDC__ || defined __C99__FUNC__ \
1234 || defined __cplusplus || defined _MSC_VER)
1235 static void
1236 yy_reduce_print (YYSTYPE *yyvsp, int yyrule)
1237 #else
1238 static void
1239 yy_reduce_print (yyvsp, yyrule)
1240 YYSTYPE *yyvsp;
1241 int yyrule;
1242 #endif
1243 {
1244 int yynrhs = yyr2[yyrule];
1245 int yyi;
1246 unsigned long int yylno = yyrline[yyrule];
1247 YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n",
1248 yyrule - 1, yylno);
1249 /* The symbols being reduced. */
1250 for (yyi = 0; yyi < yynrhs; yyi++)
1251 {
1252 YYFPRINTF (stderr, " $%d = ", yyi + 1);
1253 yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi],
1254 &(yyvsp[(yyi + 1) - (yynrhs)])
1255 );
1256 YYFPRINTF (stderr, "\n");
1257 }
1258 }
1259
1260 # define YY_REDUCE_PRINT(Rule) \
1261 do { \
1262 if (yydebug) \
1263 yy_reduce_print (yyvsp, Rule); \
1264 } while (YYID (0))
1265
1266 /* Nonzero means print parse trace. It is left uninitialized so that
1267 multiple parsers can coexist. */
1268 int yydebug;
1269 #else /* !YYDEBUG */
1270 # define YYDPRINTF(Args)
1271 # define YY_SYMBOL_PRINT(Title, Type, Value, Location)
1272 # define YY_STACK_PRINT(Bottom, Top)
1273 # define YY_REDUCE_PRINT(Rule)
1274 #endif /* !YYDEBUG */
1275
1276
1277 /* YYINITDEPTH -- initial size of the parser's stacks. */
1278 #ifndef YYINITDEPTH
1279 # define YYINITDEPTH 200
1280 #endif
1281
1282 /* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
1283 if the built-in stack extension method is used).
1284
1285 Do not make this value too large; the results are undefined if
1286 YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)
1287 evaluated with infinite-precision integer arithmetic. */
1288
1289 #ifndef YYMAXDEPTH
1290 # define YYMAXDEPTH 10000
1291 #endif
1292
1293
1294
1295 #if YYERROR_VERBOSE
1296
1297 # ifndef yystrlen
1298 # if defined __GLIBC__ && defined _STRING_H
1299 # define yystrlen strlen
1300 # else
1301 /* Return the length of YYSTR. */
1302 #if (defined __STDC__ || defined __C99__FUNC__ \
1303 || defined __cplusplus || defined _MSC_VER)
1304 static YYSIZE_T
1305 yystrlen (const char *yystr)
1306 #else
1307 static YYSIZE_T
1308 yystrlen (yystr)
1309 const char *yystr;
1310 #endif
1311 {
1312 YYSIZE_T yylen;
1313 for (yylen = 0; yystr[yylen]; yylen++)
1314 continue;
1315 return yylen;
1316 }
1317 # endif
1318 # endif
1319
1320 # ifndef yystpcpy
1321 # if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE
1322 # define yystpcpy stpcpy
1323 # else
1324 /* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
1325 YYDEST. */
1326 #if (defined __STDC__ || defined __C99__FUNC__ \
1327 || defined __cplusplus || defined _MSC_VER)
1328 static char *
1329 yystpcpy (char *yydest, const char *yysrc)
1330 #else
1331 static char *
1332 yystpcpy (yydest, yysrc)
1333 char *yydest;
1334 const char *yysrc;
1335 #endif
1336 {
1337 char *yyd = yydest;
1338 const char *yys = yysrc;
1339
1340 while ((*yyd++ = *yys++) != '\0')
1341 continue;
1342
1343 return yyd - 1;
1344 }
1345 # endif
1346 # endif
1347
1348 # ifndef yytnamerr
1349 /* Copy to YYRES the contents of YYSTR after stripping away unnecessary
1350 quotes and backslashes, so that it's suitable for yyerror. The
1351 heuristic is that double-quoting is unnecessary unless the string
1352 contains an apostrophe, a comma, or backslash (other than
1353 backslash-backslash). YYSTR is taken from yytname. If YYRES is
1354 null, do not copy; instead, return the length of what the result
1355 would have been. */
1356 static YYSIZE_T
yytnamerr(char * yyres,const char * yystr)1357 yytnamerr (char *yyres, const char *yystr)
1358 {
1359 if (*yystr == '"')
1360 {
1361 YYSIZE_T yyn = 0;
1362 char const *yyp = yystr;
1363
1364 for (;;)
1365 switch (*++yyp)
1366 {
1367 case '\'':
1368 case ',':
1369 goto do_not_strip_quotes;
1370
1371 case '\\':
1372 if (*++yyp != '\\')
1373 goto do_not_strip_quotes;
1374 /* Fall through. */
1375 default:
1376 if (yyres)
1377 yyres[yyn] = *yyp;
1378 yyn++;
1379 break;
1380
1381 case '"':
1382 if (yyres)
1383 yyres[yyn] = '\0';
1384 return yyn;
1385 }
1386 do_not_strip_quotes: ;
1387 }
1388
1389 if (! yyres)
1390 return yystrlen (yystr);
1391
1392 return yystpcpy (yyres, yystr) - yyres;
1393 }
1394 # endif
1395
1396 /* Copy into YYRESULT an error message about the unexpected token
1397 YYCHAR while in state YYSTATE. Return the number of bytes copied,
1398 including the terminating null byte. If YYRESULT is null, do not
1399 copy anything; just return the number of bytes that would be
1400 copied. As a special case, return 0 if an ordinary "syntax error"
1401 message will do. Return YYSIZE_MAXIMUM if overflow occurs during
1402 size calculation. */
1403 static YYSIZE_T
yysyntax_error(char * yyresult,int yystate,int yychar)1404 yysyntax_error (char *yyresult, int yystate, int yychar)
1405 {
1406 int yyn = yypact[yystate];
1407
1408 if (! (YYPACT_NINF < yyn && yyn <= YYLAST))
1409 return 0;
1410 else
1411 {
1412 int yytype = YYTRANSLATE (yychar);
1413 YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]);
1414 YYSIZE_T yysize = yysize0;
1415 YYSIZE_T yysize1;
1416 int yysize_overflow = 0;
1417 enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
1418 char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
1419 int yyx;
1420
1421 # if 0
1422 /* This is so xgettext sees the translatable formats that are
1423 constructed on the fly. */
1424 YY_("syntax error, unexpected %s");
1425 YY_("syntax error, unexpected %s, expecting %s");
1426 YY_("syntax error, unexpected %s, expecting %s or %s");
1427 YY_("syntax error, unexpected %s, expecting %s or %s or %s");
1428 YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s");
1429 # endif
1430 char *yyfmt;
1431 char const *yyf;
1432 static char const yyunexpected[] = "syntax error, unexpected %s";
1433 static char const yyexpecting[] = ", expecting %s";
1434 static char const yyor[] = " or %s";
1435 char yyformat[sizeof yyunexpected
1436 + sizeof yyexpecting - 1
1437 + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2)
1438 * (sizeof yyor - 1))];
1439 char const *yyprefix = yyexpecting;
1440
1441 /* Start YYX at -YYN if negative to avoid negative indexes in
1442 YYCHECK. */
1443 int yyxbegin = yyn < 0 ? -yyn : 0;
1444
1445 /* Stay within bounds of both yycheck and yytname. */
1446 int yychecklim = YYLAST - yyn + 1;
1447 int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
1448 int yycount = 1;
1449
1450 yyarg[0] = yytname[yytype];
1451 yyfmt = yystpcpy (yyformat, yyunexpected);
1452
1453 for (yyx = yyxbegin; yyx < yyxend; ++yyx)
1454 if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
1455 {
1456 if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
1457 {
1458 yycount = 1;
1459 yysize = yysize0;
1460 yyformat[sizeof yyunexpected - 1] = '\0';
1461 break;
1462 }
1463 yyarg[yycount++] = yytname[yyx];
1464 yysize1 = yysize + yytnamerr (0, yytname[yyx]);
1465 yysize_overflow |= (yysize1 < yysize);
1466 yysize = yysize1;
1467 yyfmt = yystpcpy (yyfmt, yyprefix);
1468 yyprefix = yyor;
1469 }
1470
1471 yyf = YY_(yyformat);
1472 yysize1 = yysize + yystrlen (yyf);
1473 yysize_overflow |= (yysize1 < yysize);
1474 yysize = yysize1;
1475
1476 if (yysize_overflow)
1477 return YYSIZE_MAXIMUM;
1478
1479 if (yyresult)
1480 {
1481 /* Avoid sprintf, as that infringes on the user's name space.
1482 Don't have undefined behavior even if the translation
1483 produced a string with the wrong number of "%s"s. */
1484 char *yyp = yyresult;
1485 int yyi = 0;
1486 while ((*yyp = *yyf) != '\0')
1487 {
1488 if (*yyp == '%' && yyf[1] == 's' && yyi < yycount)
1489 {
1490 yyp += yytnamerr (yyp, yyarg[yyi++]);
1491 yyf += 2;
1492 }
1493 else
1494 {
1495 yyp++;
1496 yyf++;
1497 }
1498 }
1499 }
1500 return yysize;
1501 }
1502 }
1503 #endif /* YYERROR_VERBOSE */
1504
1505
1506 /*-----------------------------------------------.
1507 | Release the memory associated to this symbol. |
1508 `-----------------------------------------------*/
1509
1510 /*ARGSUSED*/
1511 #if (defined __STDC__ || defined __C99__FUNC__ \
1512 || defined __cplusplus || defined _MSC_VER)
1513 static void
1514 yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep)
1515 #else
1516 static void
1517 yydestruct (yymsg, yytype, yyvaluep)
1518 const char *yymsg;
1519 int yytype;
1520 YYSTYPE *yyvaluep;
1521 #endif
1522 {
1523 YYUSE (yyvaluep);
1524
1525 if (!yymsg)
1526 yymsg = "Deleting";
1527 YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
1528
1529 switch (yytype)
1530 {
1531
1532 default:
1533 break;
1534 }
1535 }
1536
1537 /* Prevent warnings from -Wmissing-prototypes. */
1538 #ifdef YYPARSE_PARAM
1539 #if defined __STDC__ || defined __cplusplus
1540 int yyparse (void *YYPARSE_PARAM);
1541 #else
1542 int yyparse ();
1543 #endif
1544 #else /* ! YYPARSE_PARAM */
1545 #if defined __STDC__ || defined __cplusplus
1546 int yyparse (void);
1547 #else
1548 int yyparse ();
1549 #endif
1550 #endif /* ! YYPARSE_PARAM */
1551
1552
1553 /* The lookahead symbol. */
1554 int yychar;
1555
1556 /* The semantic value of the lookahead symbol. */
1557 YYSTYPE yylval;
1558
1559 /* Number of syntax errors so far. */
1560 int yynerrs;
1561
1562
1563
1564 /*-------------------------.
1565 | yyparse or yypush_parse. |
1566 `-------------------------*/
1567
1568 #ifdef YYPARSE_PARAM
1569 #if (defined __STDC__ || defined __C99__FUNC__ \
1570 || defined __cplusplus || defined _MSC_VER)
1571 int
1572 yyparse (void *YYPARSE_PARAM)
1573 #else
1574 int
1575 yyparse (YYPARSE_PARAM)
1576 void *YYPARSE_PARAM;
1577 #endif
1578 #else /* ! YYPARSE_PARAM */
1579 #if (defined __STDC__ || defined __C99__FUNC__ \
1580 || defined __cplusplus || defined _MSC_VER)
1581 int
yyparse(void)1582 yyparse (void)
1583 #else
1584 int
1585 yyparse ()
1586
1587 #endif
1588 #endif
1589 {
1590
1591
1592 int yystate;
1593 /* Number of tokens to shift before error messages enabled. */
1594 int yyerrstatus;
1595
1596 /* The stacks and their tools:
1597 `yyss': related to states.
1598 `yyvs': related to semantic values.
1599
1600 Refer to the stacks thru separate pointers, to allow yyoverflow
1601 to reallocate them elsewhere. */
1602
1603 /* The state stack. */
1604 yytype_int16 yyssa[YYINITDEPTH];
1605 yytype_int16 *yyss;
1606 yytype_int16 *yyssp;
1607
1608 /* The semantic value stack. */
1609 YYSTYPE yyvsa[YYINITDEPTH];
1610 YYSTYPE *yyvs;
1611 YYSTYPE *yyvsp;
1612
1613 YYSIZE_T yystacksize;
1614
1615 int yyn;
1616 int yyresult;
1617 /* Lookahead token as an internal (translated) token number. */
1618 int yytoken;
1619 /* The variables used to return semantic value and location from the
1620 action routines. */
1621 YYSTYPE yyval;
1622
1623 #if YYERROR_VERBOSE
1624 /* Buffer for error messages, and its allocated size. */
1625 char yymsgbuf[128];
1626 char *yymsg = yymsgbuf;
1627 YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
1628 #endif
1629
1630 #define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N))
1631
1632 /* The number of symbols on the RHS of the reduced rule.
1633 Keep to zero when no symbol should be popped. */
1634 int yylen = 0;
1635
1636 yytoken = 0;
1637 yyss = yyssa;
1638 yyvs = yyvsa;
1639 yystacksize = YYINITDEPTH;
1640
1641 YYDPRINTF ((stderr, "Starting parse\n"));
1642
1643 yystate = 0;
1644 yyerrstatus = 0;
1645 yynerrs = 0;
1646 yychar = YYEMPTY; /* Cause a token to be read. */
1647
1648 /* Initialize stack pointers.
1649 Waste one element of value and location stack
1650 so that they stay on the same level as the state stack.
1651 The wasted elements are never initialized. */
1652 yyssp = yyss;
1653 yyvsp = yyvs;
1654
1655 goto yysetstate;
1656
1657 /*------------------------------------------------------------.
1658 | yynewstate -- Push a new state, which is found in yystate. |
1659 `------------------------------------------------------------*/
1660 yynewstate:
1661 /* In all cases, when you get here, the value and location stacks
1662 have just been pushed. So pushing a state here evens the stacks. */
1663 yyssp++;
1664
1665 yysetstate:
1666 *yyssp = yystate;
1667
1668 if (yyss + yystacksize - 1 <= yyssp)
1669 {
1670 /* Get the current used size of the three stacks, in elements. */
1671 YYSIZE_T yysize = yyssp - yyss + 1;
1672
1673 #ifdef yyoverflow
1674 {
1675 /* Give user a chance to reallocate the stack. Use copies of
1676 these so that the &'s don't force the real ones into
1677 memory. */
1678 YYSTYPE *yyvs1 = yyvs;
1679 yytype_int16 *yyss1 = yyss;
1680
1681 /* Each stack pointer address is followed by the size of the
1682 data in use in that stack, in bytes. This used to be a
1683 conditional around just the two extra args, but that might
1684 be undefined if yyoverflow is a macro. */
1685 yyoverflow (YY_("memory exhausted"),
1686 &yyss1, yysize * sizeof (*yyssp),
1687 &yyvs1, yysize * sizeof (*yyvsp),
1688 &yystacksize);
1689
1690 yyss = yyss1;
1691 yyvs = yyvs1;
1692 }
1693 #else /* no yyoverflow */
1694 # ifndef YYSTACK_RELOCATE
1695 goto yyexhaustedlab;
1696 # else
1697 /* Extend the stack our own way. */
1698 if (YYMAXDEPTH <= yystacksize)
1699 goto yyexhaustedlab;
1700 yystacksize *= 2;
1701 if (YYMAXDEPTH < yystacksize)
1702 yystacksize = YYMAXDEPTH;
1703
1704 {
1705 yytype_int16 *yyss1 = yyss;
1706 union yyalloc *yyptr =
1707 (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
1708 if (! yyptr)
1709 goto yyexhaustedlab;
1710 YYSTACK_RELOCATE (yyss_alloc, yyss);
1711 YYSTACK_RELOCATE (yyvs_alloc, yyvs);
1712 # undef YYSTACK_RELOCATE
1713 if (yyss1 != yyssa)
1714 YYSTACK_FREE (yyss1);
1715 }
1716 # endif
1717 #endif /* no yyoverflow */
1718
1719 yyssp = yyss + yysize - 1;
1720 yyvsp = yyvs + yysize - 1;
1721
1722 YYDPRINTF ((stderr, "Stack size increased to %lu\n",
1723 (unsigned long int) yystacksize));
1724
1725 if (yyss + yystacksize - 1 <= yyssp)
1726 YYABORT;
1727 }
1728
1729 YYDPRINTF ((stderr, "Entering state %d\n", yystate));
1730
1731 if (yystate == YYFINAL)
1732 YYACCEPT;
1733
1734 goto yybackup;
1735
1736 /*-----------.
1737 | yybackup. |
1738 `-----------*/
1739 yybackup:
1740
1741 /* Do appropriate processing given the current state. Read a
1742 lookahead token if we need one and don't already have one. */
1743
1744 /* First try to decide what to do without reference to lookahead token. */
1745 yyn = yypact[yystate];
1746 if (yyn == YYPACT_NINF)
1747 goto yydefault;
1748
1749 /* Not known => get a lookahead token if don't already have one. */
1750
1751 /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */
1752 if (yychar == YYEMPTY)
1753 {
1754 YYDPRINTF ((stderr, "Reading a token: "));
1755 yychar = YYLEX;
1756 }
1757
1758 if (yychar <= YYEOF)
1759 {
1760 yychar = yytoken = YYEOF;
1761 YYDPRINTF ((stderr, "Now at end of input.\n"));
1762 }
1763 else
1764 {
1765 yytoken = YYTRANSLATE (yychar);
1766 YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
1767 }
1768
1769 /* If the proper action on seeing token YYTOKEN is to reduce or to
1770 detect an error, take that action. */
1771 yyn += yytoken;
1772 if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
1773 goto yydefault;
1774 yyn = yytable[yyn];
1775 if (yyn <= 0)
1776 {
1777 if (yyn == 0 || yyn == YYTABLE_NINF)
1778 goto yyerrlab;
1779 yyn = -yyn;
1780 goto yyreduce;
1781 }
1782
1783 /* Count tokens shifted since error; after three, turn off error
1784 status. */
1785 if (yyerrstatus)
1786 yyerrstatus--;
1787
1788 /* Shift the lookahead token. */
1789 YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
1790
1791 /* Discard the shifted token. */
1792 yychar = YYEMPTY;
1793
1794 yystate = yyn;
1795 *++yyvsp = yylval;
1796
1797 goto yynewstate;
1798
1799
1800 /*-----------------------------------------------------------.
1801 | yydefault -- do the default action for the current state. |
1802 `-----------------------------------------------------------*/
1803 yydefault:
1804 yyn = yydefact[yystate];
1805 if (yyn == 0)
1806 goto yyerrlab;
1807 goto yyreduce;
1808
1809
1810 /*-----------------------------.
1811 | yyreduce -- Do a reduction. |
1812 `-----------------------------*/
1813 yyreduce:
1814 /* yyn is the number of a rule to reduce with. */
1815 yylen = yyr2[yyn];
1816
1817 /* If YYLEN is nonzero, implement the default value of the action:
1818 `$$ = $1'.
1819
1820 Otherwise, the following line sets YYVAL to garbage.
1821 This behavior is undocumented and Bison
1822 users should not rely upon it. Assigning to YYVAL
1823 unconditionally makes the parser a bit smaller, and it avoids a
1824 GCC warning that YYVAL may be used uninitialized. */
1825 yyval = yyvsp[1-yylen];
1826
1827
1828 YY_REDUCE_PRINT (yyn);
1829 switch (yyn)
1830 {
1831 case 2:
1832
1833 /* Line 1455 of yacc.c */
1834 #line 184 "ftpcmd.y"
1835 {
1836 REASSIGN(fromname, NULL);
1837 restart_point = (off_t) 0;
1838 }
1839 break;
1840
1841 case 4:
1842
1843 /* Line 1455 of yacc.c */
1844 #line 196 "ftpcmd.y"
1845 {
1846 user((yyvsp[(3) - (4)].s));
1847 free((yyvsp[(3) - (4)].s));
1848 }
1849 break;
1850
1851 case 5:
1852
1853 /* Line 1455 of yacc.c */
1854 #line 202 "ftpcmd.y"
1855 {
1856 pass((yyvsp[(3) - (4)].s));
1857 explicit_memset((yyvsp[(3) - (4)].s), 0, strlen((yyvsp[(3) - (4)].s)));
1858 free((yyvsp[(3) - (4)].s));
1859 }
1860 break;
1861
1862 case 6:
1863
1864 /* Line 1455 of yacc.c */
1865 #line 209 "ftpcmd.y"
1866 {
1867 if ((yyvsp[(2) - (3)].u.i))
1868 cwd(homedir);
1869 }
1870 break;
1871
1872 case 7:
1873
1874 /* Line 1455 of yacc.c */
1875 #line 215 "ftpcmd.y"
1876 {
1877 if ((yyvsp[(2) - (5)].u.i) && (yyvsp[(4) - (5)].s) != NULL)
1878 cwd((yyvsp[(4) - (5)].s));
1879 if ((yyvsp[(4) - (5)].s) != NULL)
1880 free((yyvsp[(4) - (5)].s));
1881 }
1882 break;
1883
1884 case 8:
1885
1886 /* Line 1455 of yacc.c */
1887 #line 223 "ftpcmd.y"
1888 {
1889 if ((yyvsp[(2) - (3)].u.i))
1890 cwd("..");
1891 }
1892 break;
1893
1894 case 9:
1895
1896 /* Line 1455 of yacc.c */
1897 #line 229 "ftpcmd.y"
1898 {
1899 if (logged_in) {
1900 reply(-221, "%s", "");
1901 reply(0,
1902 "Data traffic for this session was " LLF " byte%s in " LLF " file%s.",
1903 (LLT)total_data, PLURAL(total_data),
1904 (LLT)total_files, PLURAL(total_files));
1905 reply(0,
1906 "Total traffic for this session was " LLF " byte%s in " LLF " transfer%s.",
1907 (LLT)total_bytes, PLURAL(total_bytes),
1908 (LLT)total_xfers, PLURAL(total_xfers));
1909 }
1910 reply(221,
1911 "Thank you for using the FTP service on %s.",
1912 hostname);
1913 if (logged_in && logging) {
1914 syslog(LOG_INFO,
1915 "Data traffic: " LLF " byte%s in " LLF " file%s",
1916 (LLT)total_data, PLURAL(total_data),
1917 (LLT)total_files, PLURAL(total_files));
1918 syslog(LOG_INFO,
1919 "Total traffic: " LLF " byte%s in " LLF " transfer%s",
1920 (LLT)total_bytes, PLURAL(total_bytes),
1921 (LLT)total_xfers, PLURAL(total_xfers));
1922 }
1923
1924 dologout(0);
1925 }
1926 break;
1927
1928 case 10:
1929
1930 /* Line 1455 of yacc.c */
1931 #line 259 "ftpcmd.y"
1932 {
1933 if ((yyvsp[(2) - (5)].u.i))
1934 port_check("PORT", AF_INET);
1935 }
1936 break;
1937
1938 case 11:
1939
1940 /* Line 1455 of yacc.c */
1941 #line 265 "ftpcmd.y"
1942 {
1943 if ((yyvsp[(2) - (5)].u.i))
1944 port_check("LPRT", AF_INET);
1945 }
1946 break;
1947
1948 case 12:
1949
1950 /* Line 1455 of yacc.c */
1951 #line 271 "ftpcmd.y"
1952 {
1953 #ifdef INET6
1954 if ((yyvsp[(2) - (5)].u.i))
1955 port_check("LPRT", AF_INET6);
1956 #else
1957 reply(500, "IPv6 support not available.");
1958 #endif
1959 }
1960 break;
1961
1962 case 13:
1963
1964 /* Line 1455 of yacc.c */
1965 #line 281 "ftpcmd.y"
1966 {
1967 if ((yyvsp[(2) - (5)].u.i)) {
1968 if (extended_port((yyvsp[(4) - (5)].s)) == 0)
1969 port_check("EPRT", -1);
1970 }
1971 free((yyvsp[(4) - (5)].s));
1972 }
1973 break;
1974
1975 case 14:
1976
1977 /* Line 1455 of yacc.c */
1978 #line 290 "ftpcmd.y"
1979 {
1980 if ((yyvsp[(2) - (3)].u.i)) {
1981 if (CURCLASS_FLAGS_ISSET(passive))
1982 passive();
1983 else
1984 reply(500, "PASV mode not available.");
1985 }
1986 }
1987 break;
1988
1989 case 15:
1990
1991 /* Line 1455 of yacc.c */
1992 #line 300 "ftpcmd.y"
1993 {
1994 if ((yyvsp[(2) - (3)].u.i)) {
1995 if (CURCLASS_FLAGS_ISSET(passive)) {
1996 if (epsvall)
1997 reply(501,
1998 "LPSV disallowed after EPSV ALL");
1999 else
2000 long_passive("LPSV", PF_UNSPEC);
2001 } else
2002 reply(500, "LPSV mode not available.");
2003 }
2004 }
2005 break;
2006
2007 case 16:
2008
2009 /* Line 1455 of yacc.c */
2010 #line 314 "ftpcmd.y"
2011 {
2012 if ((yyvsp[(2) - (5)].u.i)) {
2013 if (CURCLASS_FLAGS_ISSET(passive))
2014 long_passive("EPSV",
2015 epsvproto2af((yyvsp[(4) - (5)].u).i));
2016 else
2017 reply(500, "EPSV mode not available.");
2018 }
2019 }
2020 break;
2021
2022 case 17:
2023
2024 /* Line 1455 of yacc.c */
2025 #line 325 "ftpcmd.y"
2026 {
2027 if ((yyvsp[(2) - (5)].u.i)) {
2028 if (CURCLASS_FLAGS_ISSET(passive)) {
2029 reply(200,
2030 "EPSV ALL command successful.");
2031 epsvall++;
2032 } else
2033 reply(500, "EPSV mode not available.");
2034 }
2035 }
2036 break;
2037
2038 case 18:
2039
2040 /* Line 1455 of yacc.c */
2041 #line 337 "ftpcmd.y"
2042 {
2043 if ((yyvsp[(2) - (3)].u.i)) {
2044 if (CURCLASS_FLAGS_ISSET(passive))
2045 long_passive("EPSV", PF_UNSPEC);
2046 else
2047 reply(500, "EPSV mode not available.");
2048 }
2049 }
2050 break;
2051
2052 case 19:
2053
2054 /* Line 1455 of yacc.c */
2055 #line 347 "ftpcmd.y"
2056 {
2057 if ((yyvsp[(2) - (5)].u.i)) {
2058
2059 switch (cmd_type) {
2060
2061 case TYPE_A:
2062 if (cmd_form == FORM_N) {
2063 reply(200, "Type set to A.");
2064 type = cmd_type;
2065 form = cmd_form;
2066 } else
2067 reply(504, "Form must be N.");
2068 break;
2069
2070 case TYPE_E:
2071 reply(504, "Type E not implemented.");
2072 break;
2073
2074 case TYPE_I:
2075 reply(200, "Type set to I.");
2076 type = cmd_type;
2077 break;
2078
2079 case TYPE_L:
2080 #if NBBY == 8
2081 if (cmd_bytesz == 8) {
2082 reply(200,
2083 "Type set to L (byte size 8).");
2084 type = cmd_type;
2085 } else
2086 reply(504, "Byte size must be 8.");
2087 #else /* NBBY == 8 */
2088 UNIMPLEMENTED for NBBY != 8
2089 #endif /* NBBY == 8 */
2090 }
2091
2092 }
2093 }
2094 break;
2095
2096 case 20:
2097
2098 /* Line 1455 of yacc.c */
2099 #line 387 "ftpcmd.y"
2100 {
2101 if ((yyvsp[(2) - (5)].u.i)) {
2102 switch ((yyvsp[(4) - (5)].u.i)) {
2103
2104 case STRU_F:
2105 reply(200, "STRU F ok.");
2106 break;
2107
2108 default:
2109 reply(504, "Unimplemented STRU type.");
2110 }
2111 }
2112 }
2113 break;
2114
2115 case 21:
2116
2117 /* Line 1455 of yacc.c */
2118 #line 402 "ftpcmd.y"
2119 {
2120 if ((yyvsp[(2) - (5)].u.i)) {
2121 switch ((yyvsp[(4) - (5)].u.i)) {
2122
2123 case MODE_S:
2124 reply(200, "MODE S ok.");
2125 break;
2126
2127 default:
2128 reply(502, "Unimplemented MODE type.");
2129 }
2130 }
2131 }
2132 break;
2133
2134 case 22:
2135
2136 /* Line 1455 of yacc.c */
2137 #line 417 "ftpcmd.y"
2138 {
2139 if ((yyvsp[(2) - (5)].u.i) && (yyvsp[(4) - (5)].s) != NULL)
2140 retrieve(NULL, (yyvsp[(4) - (5)].s));
2141 if ((yyvsp[(4) - (5)].s) != NULL)
2142 free((yyvsp[(4) - (5)].s));
2143 }
2144 break;
2145
2146 case 23:
2147
2148 /* Line 1455 of yacc.c */
2149 #line 425 "ftpcmd.y"
2150 {
2151 if (check_write((yyvsp[(3) - (4)].s), 1))
2152 store((yyvsp[(3) - (4)].s), "w", 0);
2153 if ((yyvsp[(3) - (4)].s) != NULL)
2154 free((yyvsp[(3) - (4)].s));
2155 }
2156 break;
2157
2158 case 24:
2159
2160 /* Line 1455 of yacc.c */
2161 #line 433 "ftpcmd.y"
2162 {
2163 if (check_write((yyvsp[(3) - (4)].s), 1))
2164 store((yyvsp[(3) - (4)].s), "w", 1);
2165 if ((yyvsp[(3) - (4)].s) != NULL)
2166 free((yyvsp[(3) - (4)].s));
2167 }
2168 break;
2169
2170 case 25:
2171
2172 /* Line 1455 of yacc.c */
2173 #line 441 "ftpcmd.y"
2174 {
2175 if (check_write((yyvsp[(3) - (4)].s), 1))
2176 store((yyvsp[(3) - (4)].s), "a", 0);
2177 if ((yyvsp[(3) - (4)].s) != NULL)
2178 free((yyvsp[(3) - (4)].s));
2179 }
2180 break;
2181
2182 case 26:
2183
2184 /* Line 1455 of yacc.c */
2185 #line 449 "ftpcmd.y"
2186 {
2187 if ((yyvsp[(2) - (5)].u.i))
2188 reply(202, "ALLO command ignored.");
2189 }
2190 break;
2191
2192 case 27:
2193
2194 /* Line 1455 of yacc.c */
2195 #line 455 "ftpcmd.y"
2196 {
2197 if ((yyvsp[(2) - (9)].u.i))
2198 reply(202, "ALLO command ignored.");
2199 }
2200 break;
2201
2202 case 28:
2203
2204 /* Line 1455 of yacc.c */
2205 #line 461 "ftpcmd.y"
2206 {
2207 if (check_write((yyvsp[(3) - (4)].s), 0)) {
2208 if (fromname) {
2209 renamecmd(fromname, (yyvsp[(3) - (4)].s));
2210 REASSIGN(fromname, NULL);
2211 } else {
2212 reply(503, "Bad sequence of commands.");
2213 }
2214 }
2215 if ((yyvsp[(3) - (4)].s) != NULL)
2216 free((yyvsp[(3) - (4)].s));
2217 }
2218 break;
2219
2220 case 29:
2221
2222 /* Line 1455 of yacc.c */
2223 #line 475 "ftpcmd.y"
2224 {
2225 if (is_oob)
2226 abor();
2227 else if ((yyvsp[(2) - (3)].u.i))
2228 reply(225, "ABOR command successful.");
2229 }
2230 break;
2231
2232 case 30:
2233
2234 /* Line 1455 of yacc.c */
2235 #line 483 "ftpcmd.y"
2236 {
2237 if (check_write((yyvsp[(3) - (4)].s), 0))
2238 delete((yyvsp[(3) - (4)].s));
2239 if ((yyvsp[(3) - (4)].s) != NULL)
2240 free((yyvsp[(3) - (4)].s));
2241 }
2242 break;
2243
2244 case 31:
2245
2246 /* Line 1455 of yacc.c */
2247 #line 491 "ftpcmd.y"
2248 {
2249 if (check_write((yyvsp[(3) - (4)].s), 0))
2250 removedir((yyvsp[(3) - (4)].s));
2251 if ((yyvsp[(3) - (4)].s) != NULL)
2252 free((yyvsp[(3) - (4)].s));
2253 }
2254 break;
2255
2256 case 32:
2257
2258 /* Line 1455 of yacc.c */
2259 #line 499 "ftpcmd.y"
2260 {
2261 if (check_write((yyvsp[(3) - (4)].s), 0))
2262 makedir((yyvsp[(3) - (4)].s));
2263 if ((yyvsp[(3) - (4)].s) != NULL)
2264 free((yyvsp[(3) - (4)].s));
2265 }
2266 break;
2267
2268 case 33:
2269
2270 /* Line 1455 of yacc.c */
2271 #line 507 "ftpcmd.y"
2272 {
2273 if ((yyvsp[(2) - (3)].u.i))
2274 pwd();
2275 }
2276 break;
2277
2278 case 34:
2279
2280 /* Line 1455 of yacc.c */
2281 #line 513 "ftpcmd.y"
2282 {
2283 const char *argv[] = { INTERNAL_LS, "-lgA", NULL };
2284
2285 if (CURCLASS_FLAGS_ISSET(hidesymlinks))
2286 argv[1] = "-LlgA";
2287 if ((yyvsp[(2) - (3)].u.i))
2288 retrieve(argv, "");
2289 }
2290 break;
2291
2292 case 35:
2293
2294 /* Line 1455 of yacc.c */
2295 #line 523 "ftpcmd.y"
2296 {
2297 const char *argv[] = { INTERNAL_LS, "-lgA", NULL, NULL };
2298
2299 if (CURCLASS_FLAGS_ISSET(hidesymlinks))
2300 argv[1] = "-LlgA";
2301 if ((yyvsp[(2) - (5)].u.i) && (yyvsp[(4) - (5)].s) != NULL) {
2302 argv[2] = (yyvsp[(4) - (5)].s);
2303 retrieve(argv, (yyvsp[(4) - (5)].s));
2304 }
2305 if ((yyvsp[(4) - (5)].s) != NULL)
2306 free((yyvsp[(4) - (5)].s));
2307 }
2308 break;
2309
2310 case 36:
2311
2312 /* Line 1455 of yacc.c */
2313 #line 537 "ftpcmd.y"
2314 {
2315 if ((yyvsp[(2) - (3)].u.i))
2316 send_file_list(".");
2317 }
2318 break;
2319
2320 case 37:
2321
2322 /* Line 1455 of yacc.c */
2323 #line 543 "ftpcmd.y"
2324 {
2325 if ((yyvsp[(2) - (5)].u.i))
2326 send_file_list((yyvsp[(4) - (5)].s));
2327 free((yyvsp[(4) - (5)].s));
2328 }
2329 break;
2330
2331 case 38:
2332
2333 /* Line 1455 of yacc.c */
2334 #line 550 "ftpcmd.y"
2335 {
2336 help(sitetab, NULL);
2337 }
2338 break;
2339
2340 case 39:
2341
2342 /* Line 1455 of yacc.c */
2343 #line 555 "ftpcmd.y"
2344 {
2345 if (check_write((yyvsp[(7) - (8)].s), 0)) {
2346 if (((yyvsp[(5) - (8)].u.i) == -1) || ((yyvsp[(5) - (8)].u.i) > 0777))
2347 reply(501,
2348 "CHMOD: Mode value must be between 0 and 0777");
2349 else if (chmod((yyvsp[(7) - (8)].s), (yyvsp[(5) - (8)].u.i)) < 0)
2350 perror_reply(550, (yyvsp[(7) - (8)].s));
2351 else
2352 reply(200, "CHMOD command successful.");
2353 }
2354 if ((yyvsp[(7) - (8)].s) != NULL)
2355 free((yyvsp[(7) - (8)].s));
2356 }
2357 break;
2358
2359 case 40:
2360
2361 /* Line 1455 of yacc.c */
2362 #line 570 "ftpcmd.y"
2363 {
2364 help(sitetab, (yyvsp[(5) - (6)].s));
2365 free((yyvsp[(5) - (6)].s));
2366 }
2367 break;
2368
2369 case 41:
2370
2371 /* Line 1455 of yacc.c */
2372 #line 576 "ftpcmd.y"
2373 {
2374 if ((yyvsp[(4) - (5)].u.i)) {
2375 reply(200,
2376 "Current IDLE time limit is " LLF
2377 " seconds; max " LLF,
2378 (LLT)curclass.timeout,
2379 (LLT)curclass.maxtimeout);
2380 }
2381 }
2382 break;
2383
2384 case 42:
2385
2386 /* Line 1455 of yacc.c */
2387 #line 587 "ftpcmd.y"
2388 {
2389 if ((yyvsp[(4) - (7)].u.i)) {
2390 if ((yyvsp[(6) - (7)].u).i < 30 || (yyvsp[(6) - (7)].u).i > curclass.maxtimeout) {
2391 reply(501,
2392 "IDLE time limit must be between 30 and "
2393 LLF " seconds",
2394 (LLT)curclass.maxtimeout);
2395 } else {
2396 curclass.timeout = (yyvsp[(6) - (7)].u).i;
2397 (void) alarm(curclass.timeout);
2398 reply(200,
2399 "IDLE time limit set to "
2400 LLF " seconds",
2401 (LLT)curclass.timeout);
2402 }
2403 }
2404 }
2405 break;
2406
2407 case 43:
2408
2409 /* Line 1455 of yacc.c */
2410 #line 606 "ftpcmd.y"
2411 {
2412 if ((yyvsp[(4) - (5)].u.i)) {
2413 reply(200,
2414 "Current RATEGET is " LLF " bytes/sec",
2415 (LLT)curclass.rateget);
2416 }
2417 }
2418 break;
2419
2420 case 44:
2421
2422 /* Line 1455 of yacc.c */
2423 #line 615 "ftpcmd.y"
2424 {
2425 char errbuf[100];
2426 char *p = (yyvsp[(6) - (7)].s);
2427 LLT rate;
2428
2429 if ((yyvsp[(4) - (7)].u.i)) {
2430 rate = strsuftollx("RATEGET", p, 0,
2431 curclass.maxrateget
2432 ? curclass.maxrateget
2433 : LLTMAX, errbuf, sizeof(errbuf));
2434 if (errbuf[0])
2435 reply(501, "%s", errbuf);
2436 else {
2437 curclass.rateget = rate;
2438 reply(200,
2439 "RATEGET set to " LLF " bytes/sec",
2440 (LLT)curclass.rateget);
2441 }
2442 }
2443 free((yyvsp[(6) - (7)].s));
2444 }
2445 break;
2446
2447 case 45:
2448
2449 /* Line 1455 of yacc.c */
2450 #line 638 "ftpcmd.y"
2451 {
2452 if ((yyvsp[(4) - (5)].u.i)) {
2453 reply(200,
2454 "Current RATEPUT is " LLF " bytes/sec",
2455 (LLT)curclass.rateput);
2456 }
2457 }
2458 break;
2459
2460 case 46:
2461
2462 /* Line 1455 of yacc.c */
2463 #line 647 "ftpcmd.y"
2464 {
2465 char errbuf[100];
2466 char *p = (yyvsp[(6) - (7)].s);
2467 LLT rate;
2468
2469 if ((yyvsp[(4) - (7)].u.i)) {
2470 rate = strsuftollx("RATEPUT", p, 0,
2471 curclass.maxrateput
2472 ? curclass.maxrateput
2473 : LLTMAX, errbuf, sizeof(errbuf));
2474 if (errbuf[0])
2475 reply(501, "%s", errbuf);
2476 else {
2477 curclass.rateput = rate;
2478 reply(200,
2479 "RATEPUT set to " LLF " bytes/sec",
2480 (LLT)curclass.rateput);
2481 }
2482 }
2483 free((yyvsp[(6) - (7)].s));
2484 }
2485 break;
2486
2487 case 47:
2488
2489 /* Line 1455 of yacc.c */
2490 #line 670 "ftpcmd.y"
2491 {
2492 int oldmask;
2493
2494 if ((yyvsp[(4) - (5)].u.i)) {
2495 oldmask = umask(0);
2496 (void) umask(oldmask);
2497 reply(200, "Current UMASK is %03o", oldmask);
2498 }
2499 }
2500 break;
2501
2502 case 48:
2503
2504 /* Line 1455 of yacc.c */
2505 #line 681 "ftpcmd.y"
2506 {
2507 int oldmask;
2508
2509 if ((yyvsp[(4) - (7)].u.i) && check_write("", 0)) {
2510 if (((yyvsp[(6) - (7)].u.i) == -1) || ((yyvsp[(6) - (7)].u.i) > 0777)) {
2511 reply(501, "Bad UMASK value");
2512 } else {
2513 oldmask = umask((yyvsp[(6) - (7)].u.i));
2514 reply(200,
2515 "UMASK set to %03o (was %03o)",
2516 (yyvsp[(6) - (7)].u.i), oldmask);
2517 }
2518 }
2519 }
2520 break;
2521
2522 case 49:
2523
2524 /* Line 1455 of yacc.c */
2525 #line 697 "ftpcmd.y"
2526 {
2527 if (EMPTYSTR(version))
2528 reply(215, "UNIX Type: L%d", NBBY);
2529 else
2530 reply(215, "UNIX Type: L%d Version: %s", NBBY,
2531 version);
2532 }
2533 break;
2534
2535 case 50:
2536
2537 /* Line 1455 of yacc.c */
2538 #line 706 "ftpcmd.y"
2539 {
2540 if ((yyvsp[(2) - (5)].u.i) && (yyvsp[(4) - (5)].s) != NULL)
2541 statfilecmd((yyvsp[(4) - (5)].s));
2542 if ((yyvsp[(4) - (5)].s) != NULL)
2543 free((yyvsp[(4) - (5)].s));
2544 }
2545 break;
2546
2547 case 51:
2548
2549 /* Line 1455 of yacc.c */
2550 #line 714 "ftpcmd.y"
2551 {
2552 if (is_oob)
2553 statxfer();
2554 else
2555 statcmd();
2556 }
2557 break;
2558
2559 case 52:
2560
2561 /* Line 1455 of yacc.c */
2562 #line 722 "ftpcmd.y"
2563 {
2564 help(cmdtab, NULL);
2565 }
2566 break;
2567
2568 case 53:
2569
2570 /* Line 1455 of yacc.c */
2571 #line 727 "ftpcmd.y"
2572 {
2573 char *cp = (yyvsp[(3) - (4)].s);
2574
2575 if (strncasecmp(cp, "SITE", 4) == 0) {
2576 cp = (yyvsp[(3) - (4)].s) + 4;
2577 if (*cp == ' ')
2578 cp++;
2579 if (*cp)
2580 help(sitetab, cp);
2581 else
2582 help(sitetab, NULL);
2583 } else
2584 help(cmdtab, (yyvsp[(3) - (4)].s));
2585 free((yyvsp[(3) - (4)].s));
2586 }
2587 break;
2588
2589 case 54:
2590
2591 /* Line 1455 of yacc.c */
2592 #line 744 "ftpcmd.y"
2593 {
2594 reply(200, "NOOP command successful.");
2595 }
2596 break;
2597
2598 case 55:
2599
2600 /* Line 1455 of yacc.c */
2601 #line 750 "ftpcmd.y"
2602 {
2603 reply(502, "RFC 2228 authentication not implemented.");
2604 free((yyvsp[(3) - (4)].s));
2605 }
2606 break;
2607
2608 case 56:
2609
2610 /* Line 1455 of yacc.c */
2611 #line 756 "ftpcmd.y"
2612 {
2613 reply(503,
2614 "Please set authentication state with AUTH.");
2615 free((yyvsp[(3) - (4)].s));
2616 }
2617 break;
2618
2619 case 57:
2620
2621 /* Line 1455 of yacc.c */
2622 #line 763 "ftpcmd.y"
2623 {
2624 reply(503,
2625 "Please set protection buffer size with PBSZ.");
2626 free((yyvsp[(3) - (4)].s));
2627 }
2628 break;
2629
2630 case 58:
2631
2632 /* Line 1455 of yacc.c */
2633 #line 770 "ftpcmd.y"
2634 {
2635 reply(503,
2636 "Please set authentication state with AUTH.");
2637 }
2638 break;
2639
2640 case 59:
2641
2642 /* Line 1455 of yacc.c */
2643 #line 776 "ftpcmd.y"
2644 {
2645 reply(533, "No protection enabled.");
2646 }
2647 break;
2648
2649 case 60:
2650
2651 /* Line 1455 of yacc.c */
2652 #line 781 "ftpcmd.y"
2653 {
2654 reply(502, "RFC 2228 authentication not implemented.");
2655 free((yyvsp[(3) - (4)].s));
2656 }
2657 break;
2658
2659 case 61:
2660
2661 /* Line 1455 of yacc.c */
2662 #line 787 "ftpcmd.y"
2663 {
2664 reply(502, "RFC 2228 authentication not implemented.");
2665 free((yyvsp[(3) - (4)].s));
2666 }
2667 break;
2668
2669 case 62:
2670
2671 /* Line 1455 of yacc.c */
2672 #line 793 "ftpcmd.y"
2673 {
2674 reply(502, "RFC 2228 authentication not implemented.");
2675 free((yyvsp[(3) - (4)].s));
2676 }
2677 break;
2678
2679 case 63:
2680
2681 /* Line 1455 of yacc.c */
2682 #line 800 "ftpcmd.y"
2683 {
2684
2685 feat();
2686 }
2687 break;
2688
2689 case 64:
2690
2691 /* Line 1455 of yacc.c */
2692 #line 806 "ftpcmd.y"
2693 {
2694
2695 opts((yyvsp[(3) - (4)].s));
2696 free((yyvsp[(3) - (4)].s));
2697 }
2698 break;
2699
2700 case 65:
2701
2702 /* Line 1455 of yacc.c */
2703 #line 820 "ftpcmd.y"
2704 {
2705 if ((yyvsp[(2) - (5)].u.i) && (yyvsp[(4) - (5)].s) != NULL)
2706 sizecmd((yyvsp[(4) - (5)].s));
2707 if ((yyvsp[(4) - (5)].s) != NULL)
2708 free((yyvsp[(4) - (5)].s));
2709 }
2710 break;
2711
2712 case 66:
2713
2714 /* Line 1455 of yacc.c */
2715 #line 834 "ftpcmd.y"
2716 {
2717 if ((yyvsp[(2) - (5)].u.i) && (yyvsp[(4) - (5)].s) != NULL) {
2718 struct stat stbuf;
2719 if (stat((yyvsp[(4) - (5)].s), &stbuf) < 0)
2720 perror_reply(550, (yyvsp[(4) - (5)].s));
2721 else if (!S_ISREG(stbuf.st_mode)) {
2722 reply(550, "%s: not a plain file.", (yyvsp[(4) - (5)].s));
2723 } else {
2724 struct tm *t;
2725
2726 t = gmtime(&stbuf.st_mtime);
2727 reply(213,
2728 "%04d%02d%02d%02d%02d%02d",
2729 TM_YEAR_BASE + t->tm_year,
2730 t->tm_mon+1, t->tm_mday,
2731 t->tm_hour, t->tm_min, t->tm_sec);
2732 }
2733 }
2734 if ((yyvsp[(4) - (5)].s) != NULL)
2735 free((yyvsp[(4) - (5)].s));
2736 }
2737 break;
2738
2739 case 67:
2740
2741 /* Line 1455 of yacc.c */
2742 #line 857 "ftpcmd.y"
2743 {
2744 if ((yyvsp[(2) - (5)].u.i) && (yyvsp[(4) - (5)].s) != NULL)
2745 mlst((yyvsp[(4) - (5)].s));
2746 if ((yyvsp[(4) - (5)].s) != NULL)
2747 free((yyvsp[(4) - (5)].s));
2748 }
2749 break;
2750
2751 case 68:
2752
2753 /* Line 1455 of yacc.c */
2754 #line 865 "ftpcmd.y"
2755 {
2756 mlst(NULL);
2757 }
2758 break;
2759
2760 case 69:
2761
2762 /* Line 1455 of yacc.c */
2763 #line 870 "ftpcmd.y"
2764 {
2765 if ((yyvsp[(2) - (5)].u.i) && (yyvsp[(4) - (5)].s) != NULL)
2766 mlsd((yyvsp[(4) - (5)].s));
2767 if ((yyvsp[(4) - (5)].s) != NULL)
2768 free((yyvsp[(4) - (5)].s));
2769 }
2770 break;
2771
2772 case 70:
2773
2774 /* Line 1455 of yacc.c */
2775 #line 878 "ftpcmd.y"
2776 {
2777 mlsd(NULL);
2778 }
2779 break;
2780
2781 case 71:
2782
2783 /* Line 1455 of yacc.c */
2784 #line 883 "ftpcmd.y"
2785 {
2786 yyerrok;
2787 }
2788 break;
2789
2790 case 72:
2791
2792 /* Line 1455 of yacc.c */
2793 #line 890 "ftpcmd.y"
2794 {
2795 if ((yyvsp[(2) - (5)].u.i)) {
2796 REASSIGN(fromname, NULL);
2797 restart_point = (off_t)(yyvsp[(4) - (5)].u).ll;
2798 reply(350,
2799 "Restarting at " LLF ". Send STORE or RETRIEVE to initiate transfer.",
2800 (LLT)restart_point);
2801 }
2802 }
2803 break;
2804
2805 case 73:
2806
2807 /* Line 1455 of yacc.c */
2808 #line 901 "ftpcmd.y"
2809 {
2810 restart_point = (off_t) 0;
2811 if (check_write((yyvsp[(3) - (4)].s), 0)) {
2812 REASSIGN(fromname, NULL);
2813 fromname = renamefrom((yyvsp[(3) - (4)].s));
2814 }
2815 if ((yyvsp[(3) - (4)].s) != NULL)
2816 free((yyvsp[(3) - (4)].s));
2817 }
2818 break;
2819
2820 case 75:
2821
2822 /* Line 1455 of yacc.c */
2823 #line 918 "ftpcmd.y"
2824 {
2825 (yyval.s) = (char *)calloc(1, sizeof(char));
2826 }
2827 break;
2828
2829 case 77:
2830
2831 /* Line 1455 of yacc.c */
2832 #line 927 "ftpcmd.y"
2833 {
2834 (yyval.u.i) = (yyvsp[(1) - (1)].u).i;
2835 }
2836 break;
2837
2838 case 78:
2839
2840 /* Line 1455 of yacc.c */
2841 #line 935 "ftpcmd.y"
2842 {
2843 char *a, *p;
2844
2845 memset(&data_dest, 0, sizeof(data_dest));
2846 data_dest.su_len = sizeof(struct sockaddr_in);
2847 data_dest.su_family = AF_INET;
2848 p = (char *)&data_dest.su_port;
2849 p[0] = (yyvsp[(9) - (11)].u).i; p[1] = (yyvsp[(11) - (11)].u).i;
2850 a = (char *)&data_dest.su_addr;
2851 a[0] = (yyvsp[(1) - (11)].u).i; a[1] = (yyvsp[(3) - (11)].u).i; a[2] = (yyvsp[(5) - (11)].u).i; a[3] = (yyvsp[(7) - (11)].u).i;
2852 }
2853 break;
2854
2855 case 79:
2856
2857 /* Line 1455 of yacc.c */
2858 #line 952 "ftpcmd.y"
2859 {
2860 char *a, *p;
2861
2862 memset(&data_dest, 0, sizeof(data_dest));
2863 data_dest.su_len = sizeof(struct sockaddr_in);
2864 data_dest.su_family = AF_INET;
2865 p = (char *)&data_dest.su_port;
2866 p[0] = (yyvsp[(15) - (17)].u).i; p[1] = (yyvsp[(17) - (17)].u).i;
2867 a = (char *)&data_dest.su_addr;
2868 a[0] = (yyvsp[(5) - (17)].u).i; a[1] = (yyvsp[(7) - (17)].u).i; a[2] = (yyvsp[(9) - (17)].u).i; a[3] = (yyvsp[(11) - (17)].u).i;
2869
2870 /* reject invalid LPRT command */
2871 if ((yyvsp[(1) - (17)].u).i != 4 || (yyvsp[(3) - (17)].u).i != 4 || (yyvsp[(13) - (17)].u).i != 2)
2872 memset(&data_dest, 0, sizeof(data_dest));
2873 }
2874 break;
2875
2876 case 80:
2877
2878 /* Line 1455 of yacc.c */
2879 #line 976 "ftpcmd.y"
2880 {
2881 #ifdef INET6
2882 unsigned char buf[16];
2883
2884 (void)memset(&data_dest, 0, sizeof(data_dest));
2885 data_dest.su_len = sizeof(struct sockaddr_in6);
2886 data_dest.su_family = AF_INET6;
2887 buf[0] = (yyvsp[(39) - (41)].u).i; buf[1] = (yyvsp[(41) - (41)].u).i;
2888 (void)memcpy(&data_dest.su_port, buf,
2889 sizeof(data_dest.su_port));
2890 buf[0] = (yyvsp[(5) - (41)].u).i; buf[1] = (yyvsp[(7) - (41)].u).i;
2891 buf[2] = (yyvsp[(9) - (41)].u).i; buf[3] = (yyvsp[(11) - (41)].u).i;
2892 buf[4] = (yyvsp[(13) - (41)].u).i; buf[5] = (yyvsp[(15) - (41)].u).i;
2893 buf[6] = (yyvsp[(17) - (41)].u).i; buf[7] = (yyvsp[(19) - (41)].u).i;
2894 buf[8] = (yyvsp[(21) - (41)].u).i; buf[9] = (yyvsp[(23) - (41)].u).i;
2895 buf[10] = (yyvsp[(25) - (41)].u).i; buf[11] = (yyvsp[(27) - (41)].u).i;
2896 buf[12] = (yyvsp[(29) - (41)].u).i; buf[13] = (yyvsp[(31) - (41)].u).i;
2897 buf[14] = (yyvsp[(33) - (41)].u).i; buf[15] = (yyvsp[(35) - (41)].u).i;
2898 (void)memcpy(&data_dest.si_su.su_sin6.sin6_addr,
2899 buf, sizeof(data_dest.si_su.su_sin6.sin6_addr));
2900 if (his_addr.su_family == AF_INET6) {
2901 /* XXX: more sanity checks! */
2902 data_dest.su_scope_id = his_addr.su_scope_id;
2903 }
2904 #else
2905 memset(&data_dest, 0, sizeof(data_dest));
2906 #endif /* INET6 */
2907 /* reject invalid LPRT command */
2908 if ((yyvsp[(1) - (41)].u).i != 6 || (yyvsp[(3) - (41)].u).i != 16 || (yyvsp[(37) - (41)].u).i != 2)
2909 memset(&data_dest, 0, sizeof(data_dest));
2910 }
2911 break;
2912
2913 case 81:
2914
2915 /* Line 1455 of yacc.c */
2916 #line 1011 "ftpcmd.y"
2917 {
2918 (yyval.u.i) = FORM_N;
2919 }
2920 break;
2921
2922 case 82:
2923
2924 /* Line 1455 of yacc.c */
2925 #line 1016 "ftpcmd.y"
2926 {
2927 (yyval.u.i) = FORM_T;
2928 }
2929 break;
2930
2931 case 83:
2932
2933 /* Line 1455 of yacc.c */
2934 #line 1021 "ftpcmd.y"
2935 {
2936 (yyval.u.i) = FORM_C;
2937 }
2938 break;
2939
2940 case 84:
2941
2942 /* Line 1455 of yacc.c */
2943 #line 1028 "ftpcmd.y"
2944 {
2945 cmd_type = TYPE_A;
2946 cmd_form = FORM_N;
2947 }
2948 break;
2949
2950 case 85:
2951
2952 /* Line 1455 of yacc.c */
2953 #line 1034 "ftpcmd.y"
2954 {
2955 cmd_type = TYPE_A;
2956 cmd_form = (yyvsp[(3) - (3)].u.i);
2957 }
2958 break;
2959
2960 case 86:
2961
2962 /* Line 1455 of yacc.c */
2963 #line 1040 "ftpcmd.y"
2964 {
2965 cmd_type = TYPE_E;
2966 cmd_form = FORM_N;
2967 }
2968 break;
2969
2970 case 87:
2971
2972 /* Line 1455 of yacc.c */
2973 #line 1046 "ftpcmd.y"
2974 {
2975 cmd_type = TYPE_E;
2976 cmd_form = (yyvsp[(3) - (3)].u.i);
2977 }
2978 break;
2979
2980 case 88:
2981
2982 /* Line 1455 of yacc.c */
2983 #line 1052 "ftpcmd.y"
2984 {
2985 cmd_type = TYPE_I;
2986 }
2987 break;
2988
2989 case 89:
2990
2991 /* Line 1455 of yacc.c */
2992 #line 1057 "ftpcmd.y"
2993 {
2994 cmd_type = TYPE_L;
2995 cmd_bytesz = NBBY;
2996 }
2997 break;
2998
2999 case 90:
3000
3001 /* Line 1455 of yacc.c */
3002 #line 1063 "ftpcmd.y"
3003 {
3004 cmd_type = TYPE_L;
3005 cmd_bytesz = (yyvsp[(3) - (3)].u.i);
3006 }
3007 break;
3008
3009 case 91:
3010
3011 /* Line 1455 of yacc.c */
3012 #line 1070 "ftpcmd.y"
3013 {
3014 cmd_type = TYPE_L;
3015 cmd_bytesz = (yyvsp[(2) - (2)].u.i);
3016 }
3017 break;
3018
3019 case 92:
3020
3021 /* Line 1455 of yacc.c */
3022 #line 1078 "ftpcmd.y"
3023 {
3024 (yyval.u.i) = STRU_F;
3025 }
3026 break;
3027
3028 case 93:
3029
3030 /* Line 1455 of yacc.c */
3031 #line 1083 "ftpcmd.y"
3032 {
3033 (yyval.u.i) = STRU_R;
3034 }
3035 break;
3036
3037 case 94:
3038
3039 /* Line 1455 of yacc.c */
3040 #line 1088 "ftpcmd.y"
3041 {
3042 (yyval.u.i) = STRU_P;
3043 }
3044 break;
3045
3046 case 95:
3047
3048 /* Line 1455 of yacc.c */
3049 #line 1095 "ftpcmd.y"
3050 {
3051 (yyval.u.i) = MODE_S;
3052 }
3053 break;
3054
3055 case 96:
3056
3057 /* Line 1455 of yacc.c */
3058 #line 1100 "ftpcmd.y"
3059 {
3060 (yyval.u.i) = MODE_B;
3061 }
3062 break;
3063
3064 case 97:
3065
3066 /* Line 1455 of yacc.c */
3067 #line 1105 "ftpcmd.y"
3068 {
3069 (yyval.u.i) = MODE_C;
3070 }
3071 break;
3072
3073 case 98:
3074
3075 /* Line 1455 of yacc.c */
3076 #line 1112 "ftpcmd.y"
3077 {
3078 /*
3079 * Problem: this production is used for all pathname
3080 * processing, but only gives a 550 error reply.
3081 * This is a valid reply in some cases but not in
3082 * others.
3083 */
3084 if (logged_in && (yyvsp[(1) - (1)].s) && *(yyvsp[(1) - (1)].s) == '~') {
3085 char *path, *home, *result;
3086 size_t len;
3087
3088 path = strchr((yyvsp[(1) - (1)].s) + 1, '/');
3089 if (path != NULL)
3090 *path++ = '\0';
3091 if ((yyvsp[(1) - (1)].s)[1] == '\0')
3092 home = homedir;
3093 else {
3094 struct passwd *hpw;
3095
3096 if ((hpw = getpwnam((yyvsp[(1) - (1)].s) + 1)) != NULL)
3097 home = hpw->pw_dir;
3098 else
3099 home = (yyvsp[(1) - (1)].s);
3100 }
3101 len = strlen(home) + 1;
3102 if (path != NULL)
3103 len += strlen(path) + 1;
3104 if ((result = malloc(len)) == NULL)
3105 fatal("Local resource failure: malloc");
3106 strlcpy(result, home, len);
3107 if (path != NULL) {
3108 strlcat(result, "/", len);
3109 strlcat(result, path, len);
3110 }
3111 (yyval.s) = result;
3112 free((yyvsp[(1) - (1)].s));
3113 } else
3114 (yyval.s) = (yyvsp[(1) - (1)].s);
3115 }
3116 break;
3117
3118 case 100:
3119
3120 /* Line 1455 of yacc.c */
3121 #line 1159 "ftpcmd.y"
3122 {
3123 int ret, dec, multby, digit;
3124
3125 /*
3126 * Convert a number that was read as decimal number
3127 * to what it would be if it had been read as octal.
3128 */
3129 dec = (yyvsp[(1) - (1)].u).i;
3130 multby = 1;
3131 ret = 0;
3132 while (dec) {
3133 digit = dec%10;
3134 if (digit > 7) {
3135 ret = -1;
3136 break;
3137 }
3138 ret += digit * multby;
3139 multby *= 8;
3140 dec /= 10;
3141 }
3142 (yyval.u.i) = ret;
3143 }
3144 break;
3145
3146 case 104:
3147
3148 /* Line 1455 of yacc.c */
3149 #line 1197 "ftpcmd.y"
3150 {
3151 (yyval.u.i) = (yyvsp[(1) - (1)].u).i;
3152 }
3153 break;
3154
3155 case 105:
3156
3157 /* Line 1455 of yacc.c */
3158 #line 1204 "ftpcmd.y"
3159 {
3160 if (logged_in)
3161 (yyval.u.i) = 1;
3162 else {
3163 reply(530, "Please login with USER and PASS.");
3164 (yyval.u.i) = 0;
3165 hasyyerrored = 1;
3166 }
3167 }
3168 break;
3169
3170
3171
3172 /* Line 1455 of yacc.c */
3173 #line 3174 "ftpcmd.c"
3174 default: break;
3175 }
3176 YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
3177
3178 YYPOPSTACK (yylen);
3179 yylen = 0;
3180 YY_STACK_PRINT (yyss, yyssp);
3181
3182 *++yyvsp = yyval;
3183
3184 /* Now `shift' the result of the reduction. Determine what state
3185 that goes to, based on the state we popped back to and the rule
3186 number reduced by. */
3187
3188 yyn = yyr1[yyn];
3189
3190 yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
3191 if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
3192 yystate = yytable[yystate];
3193 else
3194 yystate = yydefgoto[yyn - YYNTOKENS];
3195
3196 goto yynewstate;
3197
3198
3199 /*------------------------------------.
3200 | yyerrlab -- here on detecting error |
3201 `------------------------------------*/
3202 yyerrlab:
3203 /* If not already recovering from an error, report this error. */
3204 if (!yyerrstatus)
3205 {
3206 ++yynerrs;
3207 #if ! YYERROR_VERBOSE
3208 yyerror (YY_("syntax error"));
3209 #else
3210 {
3211 YYSIZE_T yysize = yysyntax_error (0, yystate, yychar);
3212 if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM)
3213 {
3214 YYSIZE_T yyalloc = 2 * yysize;
3215 if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM))
3216 yyalloc = YYSTACK_ALLOC_MAXIMUM;
3217 if (yymsg != yymsgbuf)
3218 YYSTACK_FREE (yymsg);
3219 yymsg = (char *) YYSTACK_ALLOC (yyalloc);
3220 if (yymsg)
3221 yymsg_alloc = yyalloc;
3222 else
3223 {
3224 yymsg = yymsgbuf;
3225 yymsg_alloc = sizeof yymsgbuf;
3226 }
3227 }
3228
3229 if (0 < yysize && yysize <= yymsg_alloc)
3230 {
3231 (void) yysyntax_error (yymsg, yystate, yychar);
3232 yyerror (yymsg);
3233 }
3234 else
3235 {
3236 yyerror (YY_("syntax error"));
3237 if (yysize != 0)
3238 goto yyexhaustedlab;
3239 }
3240 }
3241 #endif
3242 }
3243
3244
3245
3246 if (yyerrstatus == 3)
3247 {
3248 /* If just tried and failed to reuse lookahead token after an
3249 error, discard it. */
3250
3251 if (yychar <= YYEOF)
3252 {
3253 /* Return failure if at end of input. */
3254 if (yychar == YYEOF)
3255 YYABORT;
3256 }
3257 else
3258 {
3259 yydestruct ("Error: discarding",
3260 yytoken, &yylval);
3261 yychar = YYEMPTY;
3262 }
3263 }
3264
3265 /* Else will try to reuse lookahead token after shifting the error
3266 token. */
3267 goto yyerrlab1;
3268
3269
3270 /*---------------------------------------------------.
3271 | yyerrorlab -- error raised explicitly by YYERROR. |
3272 `---------------------------------------------------*/
3273 yyerrorlab:
3274
3275 /* Pacify compilers like GCC when the user code never invokes
3276 YYERROR and the label yyerrorlab therefore never appears in user
3277 code. */
3278 if (/*CONSTCOND*/ 0)
3279 goto yyerrorlab;
3280
3281 /* Do not reclaim the symbols of the rule which action triggered
3282 this YYERROR. */
3283 YYPOPSTACK (yylen);
3284 yylen = 0;
3285 YY_STACK_PRINT (yyss, yyssp);
3286 yystate = *yyssp;
3287 goto yyerrlab1;
3288
3289
3290 /*-------------------------------------------------------------.
3291 | yyerrlab1 -- common code for both syntax error and YYERROR. |
3292 `-------------------------------------------------------------*/
3293 yyerrlab1:
3294 yyerrstatus = 3; /* Each real token shifted decrements this. */
3295
3296 for (;;)
3297 {
3298 yyn = yypact[yystate];
3299 if (yyn != YYPACT_NINF)
3300 {
3301 yyn += YYTERROR;
3302 if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
3303 {
3304 yyn = yytable[yyn];
3305 if (0 < yyn)
3306 break;
3307 }
3308 }
3309
3310 /* Pop the current state because it cannot handle the error token. */
3311 if (yyssp == yyss)
3312 YYABORT;
3313
3314
3315 yydestruct ("Error: popping",
3316 yystos[yystate], yyvsp);
3317 YYPOPSTACK (1);
3318 yystate = *yyssp;
3319 YY_STACK_PRINT (yyss, yyssp);
3320 }
3321
3322 *++yyvsp = yylval;
3323
3324
3325 /* Shift the error token. */
3326 YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
3327
3328 yystate = yyn;
3329 goto yynewstate;
3330
3331
3332 /*-------------------------------------.
3333 | yyacceptlab -- YYACCEPT comes here. |
3334 `-------------------------------------*/
3335 yyacceptlab:
3336 yyresult = 0;
3337 goto yyreturn;
3338
3339 /*-----------------------------------.
3340 | yyabortlab -- YYABORT comes here. |
3341 `-----------------------------------*/
3342 yyabortlab:
3343 yyresult = 1;
3344 goto yyreturn;
3345
3346 #if !defined(yyoverflow) || YYERROR_VERBOSE
3347 /*-------------------------------------------------.
3348 | yyexhaustedlab -- memory exhaustion comes here. |
3349 `-------------------------------------------------*/
3350 yyexhaustedlab:
3351 yyerror (YY_("memory exhausted"));
3352 yyresult = 2;
3353 /* Fall through. */
3354 #endif
3355
3356 yyreturn:
3357 if (yychar != YYEMPTY)
3358 yydestruct ("Cleanup: discarding lookahead",
3359 yytoken, &yylval);
3360 /* Do not reclaim the symbols of the rule which action triggered
3361 this YYABORT or YYACCEPT. */
3362 YYPOPSTACK (yylen);
3363 YY_STACK_PRINT (yyss, yyssp);
3364 while (yyssp != yyss)
3365 {
3366 yydestruct ("Cleanup: popping",
3367 yystos[*yyssp], yyvsp);
3368 YYPOPSTACK (1);
3369 }
3370 #ifndef yyoverflow
3371 if (yyss != yyssa)
3372 YYSTACK_FREE (yyss);
3373 #endif
3374 #if YYERROR_VERBOSE
3375 if (yymsg != yymsgbuf)
3376 YYSTACK_FREE (yymsg);
3377 #endif
3378 /* Make sure YYID is used. */
3379 return YYID (yyresult);
3380 }
3381
3382
3383
3384 /* Line 1675 of yacc.c */
3385 #line 1215 "ftpcmd.y"
3386
3387
3388 #define CMD 0 /* beginning of command */
3389 #define ARGS 1 /* expect miscellaneous arguments */
3390 #define STR1 2 /* expect SP followed by STRING */
3391 #define STR2 3 /* expect STRING */
3392 #define OSTR 4 /* optional SP then STRING */
3393 #define ZSTR1 5 /* SP then optional STRING */
3394 #define ZSTR2 6 /* optional STRING after SP */
3395 #define SITECMD 7 /* SITE command */
3396 #define NSTR 8 /* Number followed by a string */
3397 #define NOARGS 9 /* No arguments allowed */
3398 #define EOLN 10 /* End of line */
3399
3400 struct tab cmdtab[] = {
3401 /* From RFC 959, in order defined (5.3.1) */
3402 { "USER", USER, STR1, 1, "<sp> username", 0, },
3403 { "PASS", PASS, ZSTR1, 1, "<sp> password", 0, },
3404 { "ACCT", ACCT, STR1, 0, "(specify account)", 0, },
3405 { "CWD", CWD, OSTR, 1, "[ <sp> directory-name ]", 0, },
3406 { "CDUP", CDUP, NOARGS, 1, "(change to parent directory)", 0, },
3407 { "SMNT", SMNT, ARGS, 0, "(structure mount)", 0, },
3408 { "QUIT", QUIT, NOARGS, 1, "(terminate service)", 0, },
3409 { "REIN", REIN, NOARGS, 0, "(reinitialize server state)", 0, },
3410 { "PORT", PORT, ARGS, 1, "<sp> b0, b1, b2, b3, b4, b5", 0, },
3411 { "LPRT", LPRT, ARGS, 1, "<sp> af, hal, h1, h2, h3,..., pal, p1, p2...", 0, },
3412 { "EPRT", EPRT, STR1, 1, "<sp> |af|addr|port|", 0, },
3413 { "PASV", PASV, NOARGS, 1, "(set server in passive mode)", 0, },
3414 { "LPSV", LPSV, ARGS, 1, "(set server in passive mode)", 0, },
3415 { "EPSV", EPSV, ARGS, 1, "[<sp> af|ALL]", 0, },
3416 { "TYPE", TYPE, ARGS, 1, "<sp> [ A | E | I | L ]", 0, },
3417 { "STRU", STRU, ARGS, 1, "(specify file structure)", 0, },
3418 { "MODE", MODE, ARGS, 1, "(specify transfer mode)", 0, },
3419 { "RETR", RETR, STR1, 1, "<sp> file-name", 0, },
3420 { "STOR", STOR, STR1, 1, "<sp> file-name", 0, },
3421 { "STOU", STOU, STR1, 1, "<sp> file-name", 0, },
3422 { "APPE", APPE, STR1, 1, "<sp> file-name", 0, },
3423 { "ALLO", ALLO, ARGS, 1, "allocate storage (vacuously)", 0, },
3424 { "REST", REST, ARGS, 1, "<sp> offset (restart command)", 0, },
3425 { "RNFR", RNFR, STR1, 1, "<sp> file-name", 0, },
3426 { "RNTO", RNTO, STR1, 1, "<sp> file-name", 0, },
3427 { "ABOR", ABOR, NOARGS, 4, "(abort operation)", 0, },
3428 { "DELE", DELE, STR1, 1, "<sp> file-name", 0, },
3429 { "RMD", RMD, STR1, 1, "<sp> path-name", 0, },
3430 { "MKD", MKD, STR1, 1, "<sp> path-name", 0, },
3431 { "PWD", PWD, NOARGS, 1, "(return current directory)", 0, },
3432 { "LIST", LIST, OSTR, 1, "[ <sp> path-name ]", 0, },
3433 { "NLST", NLST, OSTR, 1, "[ <sp> path-name ]", 0, },
3434 { "SITE", SITE, SITECMD, 1, "site-cmd [ <sp> arguments ]", 0, },
3435 { "SYST", SYST, NOARGS, 1, "(get type of operating system)", 0, },
3436 { "STAT", STAT, OSTR, 4, "[ <sp> path-name ]", 0, },
3437 { "HELP", HELP, OSTR, 1, "[ <sp> <string> ]", 0, },
3438 { "NOOP", NOOP, NOARGS, 2, "", 0, },
3439
3440 /* From RFC 2228, in order defined */
3441 { "AUTH", AUTH, STR1, 1, "<sp> mechanism-name", 0, },
3442 { "ADAT", ADAT, STR1, 1, "<sp> base-64-data", 0, },
3443 { "PROT", PROT, STR1, 1, "<sp> prot-code", 0, },
3444 { "PBSZ", PBSZ, ARGS, 1, "<sp> decimal-integer", 0, },
3445 { "CCC", CCC, NOARGS, 1, "(Disable data protection)", 0, },
3446 { "MIC", MIC, STR1, 4, "<sp> base64data", 0, },
3447 { "CONF", CONF, STR1, 4, "<sp> base64data", 0, },
3448 { "ENC", ENC, STR1, 4, "<sp> base64data", 0, },
3449
3450 /* From RFC 2389, in order defined */
3451 { "FEAT", FEAT, NOARGS, 1, "(display extended features)", 0, },
3452 { "OPTS", OPTS, STR1, 1, "<sp> command [ <sp> options ]", 0, },
3453
3454 /* From RFC 3659, in order defined */
3455 { "MDTM", MDTM, OSTR, 1, "<sp> path-name", 0, },
3456 { "SIZE", SIZE, OSTR, 1, "<sp> path-name", 0, },
3457 { "MLST", MLST, OSTR, 2, "[ <sp> path-name ]", 0, },
3458 { "MLSD", MLSD, OSTR, 1, "[ <sp> directory-name ]", 0, },
3459
3460 /* obsolete commands */
3461 { "MAIL", MAIL, OSTR, 0, "(mail to user)", 0, },
3462 { "MLFL", MLFL, OSTR, 0, "(mail file)", 0, },
3463 { "MRCP", MRCP, STR1, 0, "(mail recipient)", 0, },
3464 { "MRSQ", MRSQ, OSTR, 0, "(mail recipient scheme question)", 0, },
3465 { "MSAM", MSAM, OSTR, 0, "(mail send to terminal and mailbox)", 0, },
3466 { "MSND", MSND, OSTR, 0, "(mail send to terminal)", 0, },
3467 { "MSOM", MSOM, OSTR, 0, "(mail send to terminal or mailbox)", 0, },
3468 { "XCUP", CDUP, NOARGS, 1, "(change to parent directory)", 0, },
3469 { "XCWD", CWD, OSTR, 1, "[ <sp> directory-name ]", 0, },
3470 { "XMKD", MKD, STR1, 1, "<sp> path-name", 0, },
3471 { "XPWD", PWD, NOARGS, 1, "(return current directory)", 0, },
3472 { "XRMD", RMD, STR1, 1, "<sp> path-name", 0, },
3473
3474 { NULL, 0, 0, 0, 0, 0, }
3475 };
3476
3477 struct tab sitetab[] = {
3478 { "CHMOD", CHMOD, NSTR, 1, "<sp> mode <sp> file-name", 0, },
3479 { "HELP", HELP, OSTR, 1, "[ <sp> <string> ]", 0, },
3480 { "IDLE", IDLE, ARGS, 1, "[ <sp> maximum-idle-time ]", 0, },
3481 { "RATEGET", RATEGET,OSTR, 1, "[ <sp> get-throttle-rate ]", 0, },
3482 { "RATEPUT", RATEPUT,OSTR, 1, "[ <sp> put-throttle-rate ]", 0, },
3483 { "UMASK", UMASK, ARGS, 1, "[ <sp> umask ]", 0, },
3484 { NULL, 0, 0, 0, 0, 0, }
3485 };
3486
3487 /*
3488 * Check if a filename is allowed to be modified (isupload == 0) or
3489 * uploaded (isupload == 1), and if necessary, check the filename is `sane'.
3490 * If the filename is NULL, fail.
3491 * If the filename is "", don't do the sane name check.
3492 */
3493 static int
3494 check_write(const char *file, int isupload)
3495 {
3496 if (file == NULL)
3497 return (0);
3498 if (! logged_in) {
3499 reply(530, "Please login with USER and PASS.");
3500 return (0);
3501 }
3502 /* checking modify */
3503 if (! isupload && ! CURCLASS_FLAGS_ISSET(modify)) {
3504 reply(502, "No permission to use this command.");
3505 return (0);
3506 }
3507 /* checking upload */
3508 if (isupload && ! CURCLASS_FLAGS_ISSET(upload)) {
3509 reply(502, "No permission to use this command.");
3510 return (0);
3511 }
3512
3513 /* checking sanenames */
3514 if (file[0] != '\0' && CURCLASS_FLAGS_ISSET(sanenames)) {
3515 const char *p;
3516
3517 if (file[0] == '.')
3518 goto insane_name;
3519 for (p = file; *p; p++) {
3520 if (isalnum((unsigned char)*p) || *p == '-' || *p == '+' ||
3521 *p == ',' || *p == '.' || *p == '_')
3522 continue;
3523 insane_name:
3524 reply(553, "File name `%s' not allowed.", file);
3525 return (0);
3526 }
3527 }
3528 return (1);
3529 }
3530
3531 struct tab *
3532 lookup(struct tab *p, const char *cmd)
3533 {
3534
3535 for (; p->name != NULL; p++)
3536 if (strcasecmp(cmd, p->name) == 0)
3537 return (p);
3538 return (0);
3539 }
3540
3541 #include <arpa/telnet.h>
3542
3543 /*
3544 * get_line - a hacked up version of fgets to ignore TELNET escape codes.
3545 * `s' is the buffer to read into.
3546 * `n' is the 1 less than the size of the buffer, to allow trailing NUL
3547 * `iop' is the FILE to read from.
3548 * Returns 0 on success, -1 on EOF, -2 if the command was too long.
3549 */
3550 int
3551 get_line(char *s, int n, FILE *iop)
3552 {
3553 int c;
3554 char *cs;
3555
3556 cs = s;
3557 /* tmpline may contain saved command from urgent mode interruption */
3558 for (c = 0; tmpline[c] != '\0' && --n > 0; ++c) {
3559 *cs++ = tmpline[c];
3560 if (tmpline[c] == '\n') {
3561 *cs++ = '\0';
3562 if (ftpd_debug)
3563 syslog(LOG_DEBUG, "command: %s", s);
3564 tmpline[0] = '\0';
3565 return(0);
3566 }
3567 if (c == 0)
3568 tmpline[0] = '\0';
3569 }
3570 while ((c = getc(iop)) != EOF) {
3571 total_bytes++;
3572 total_bytes_in++;
3573 c &= 0377;
3574 if (c == IAC) {
3575 if ((c = getc(iop)) != EOF) {
3576 total_bytes++;
3577 total_bytes_in++;
3578 c &= 0377;
3579 switch (c) {
3580 case WILL:
3581 case WONT:
3582 c = getc(iop);
3583 total_bytes++;
3584 total_bytes_in++;
3585 cprintf(stdout, "%c%c%c", IAC, DONT, 0377&c);
3586 (void) fflush(stdout);
3587 continue;
3588 case DO:
3589 case DONT:
3590 c = getc(iop);
3591 total_bytes++;
3592 total_bytes_in++;
3593 cprintf(stdout, "%c%c%c", IAC, WONT, 0377&c);
3594 (void) fflush(stdout);
3595 continue;
3596 case IAC:
3597 break;
3598 default:
3599 continue; /* ignore command */
3600 }
3601 }
3602 }
3603 *cs++ = c;
3604 if (--n <= 0) {
3605 /*
3606 * If command doesn't fit into buffer, discard the
3607 * rest of the command and indicate truncation.
3608 * This prevents the command to be split up into
3609 * multiple commands.
3610 */
3611 if (ftpd_debug)
3612 syslog(LOG_DEBUG,
3613 "command too long, last char: %d", c);
3614 while (c != '\n' && (c = getc(iop)) != EOF)
3615 continue;
3616 return (-2);
3617 }
3618 if (c == '\n')
3619 break;
3620 }
3621 if (c == EOF && cs == s)
3622 return (-1);
3623 *cs++ = '\0';
3624 if (ftpd_debug) {
3625 if ((curclass.type != CLASS_GUEST &&
3626 strncasecmp(s, "PASS ", 5) == 0) ||
3627 strncasecmp(s, "ACCT ", 5) == 0) {
3628 /* Don't syslog passwords */
3629 syslog(LOG_DEBUG, "command: %.4s ???", s);
3630 } else {
3631 char *cp;
3632 int len;
3633
3634 /* Don't syslog trailing CR-LF */
3635 len = strlen(s);
3636 cp = s + len - 1;
3637 while (cp >= s && (*cp == '\n' || *cp == '\r')) {
3638 --cp;
3639 --len;
3640 }
3641 syslog(LOG_DEBUG, "command: %.*s", len, s);
3642 }
3643 }
3644 return (0);
3645 }
3646
3647 void
3648 ftp_handle_line(char *cp)
3649 {
3650
3651 cmdp = cp;
3652 yyparse();
3653 }
3654
3655 void
3656 ftp_loop(void)
3657 {
3658 int ret;
3659
3660 while (1) {
3661 (void) alarm(curclass.timeout);
3662 ret = get_line(cbuf, sizeof(cbuf)-1, stdin);
3663 (void) alarm(0);
3664 if (ret == -1) {
3665 reply(221, "You could at least say goodbye.");
3666 dologout(0);
3667 } else if (ret == -2) {
3668 reply(500, "Command too long.");
3669 } else {
3670 ftp_handle_line(cbuf);
3671 }
3672 }
3673 /*NOTREACHED*/
3674 }
3675
3676 int
3677 yylex(void)
3678 {
3679 static int cpos, state;
3680 char *cp, *cp2;
3681 struct tab *p;
3682 int n;
3683 char c;
3684
3685 switch (state) {
3686
3687 case CMD:
3688 hasyyerrored = 0;
3689 if ((cp = strchr(cmdp, '\r'))) {
3690 *cp = '\0';
3691 #if defined(HAVE_SETPROCTITLE)
3692 if (strncasecmp(cmdp, "PASS", 4) != 0 &&
3693 strncasecmp(cmdp, "ACCT", 4) != 0)
3694 setproctitle("%s: %s", proctitle, cmdp);
3695 #endif /* defined(HAVE_SETPROCTITLE) */
3696 *cp++ = '\n';
3697 *cp = '\0';
3698 }
3699 if ((cp = strpbrk(cmdp, " \n")))
3700 cpos = cp - cmdp;
3701 if (cpos == 0)
3702 cpos = 4;
3703 c = cmdp[cpos];
3704 cmdp[cpos] = '\0';
3705 p = lookup(cmdtab, cmdp);
3706 cmdp[cpos] = c;
3707 if (p != NULL) {
3708 if (is_oob && ! CMD_OOB(p)) {
3709 /* command will be handled in-band */
3710 return (0);
3711 } else if (! CMD_IMPLEMENTED(p)) {
3712 reply(502, "%s command not implemented.",
3713 p->name);
3714 hasyyerrored = 1;
3715 break;
3716 }
3717 state = p->state;
3718 yylval.cs = p->name;
3719 return (p->token);
3720 }
3721 break;
3722
3723 case SITECMD:
3724 if (cmdp[cpos] == ' ') {
3725 cpos++;
3726 return (SP);
3727 }
3728 cp = &cmdp[cpos];
3729 if ((cp2 = strpbrk(cp, " \n")))
3730 cpos = cp2 - cmdp;
3731 c = cmdp[cpos];
3732 cmdp[cpos] = '\0';
3733 p = lookup(sitetab, cp);
3734 cmdp[cpos] = c;
3735 if (p != NULL) {
3736 if (!CMD_IMPLEMENTED(p)) {
3737 reply(502, "SITE %s command not implemented.",
3738 p->name);
3739 hasyyerrored = 1;
3740 break;
3741 }
3742 state = p->state;
3743 yylval.cs = p->name;
3744 return (p->token);
3745 }
3746 break;
3747
3748 case OSTR:
3749 if (cmdp[cpos] == '\n') {
3750 state = EOLN;
3751 return (CRLF);
3752 }
3753 /* FALLTHROUGH */
3754
3755 case STR1:
3756 case ZSTR1:
3757 dostr1:
3758 if (cmdp[cpos] == ' ') {
3759 cpos++;
3760 state = state == OSTR ? STR2 : state+1;
3761 return (SP);
3762 }
3763 break;
3764
3765 case ZSTR2:
3766 if (cmdp[cpos] == '\n') {
3767 state = EOLN;
3768 return (CRLF);
3769 }
3770 /* FALLTHROUGH */
3771
3772 case STR2:
3773 cp = &cmdp[cpos];
3774 n = strlen(cp);
3775 cpos += n - 1;
3776 /*
3777 * Make sure the string is nonempty and \n terminated.
3778 */
3779 if (n > 1 && cmdp[cpos] == '\n') {
3780 cmdp[cpos] = '\0';
3781 yylval.s = ftpd_strdup(cp);
3782 cmdp[cpos] = '\n';
3783 state = ARGS;
3784 return (STRING);
3785 }
3786 break;
3787
3788 case NSTR:
3789 if (cmdp[cpos] == ' ') {
3790 cpos++;
3791 return (SP);
3792 }
3793 if (isdigit((unsigned char)cmdp[cpos])) {
3794 cp = &cmdp[cpos];
3795 while (isdigit((unsigned char)cmdp[++cpos]))
3796 ;
3797 c = cmdp[cpos];
3798 cmdp[cpos] = '\0';
3799 yylval.u.i = atoi(cp);
3800 cmdp[cpos] = c;
3801 state = STR1;
3802 return (NUMBER);
3803 }
3804 state = STR1;
3805 goto dostr1;
3806
3807 case ARGS:
3808 if (isdigit((unsigned char)cmdp[cpos])) {
3809 cp = &cmdp[cpos];
3810 while (isdigit((unsigned char)cmdp[++cpos]))
3811 ;
3812 c = cmdp[cpos];
3813 cmdp[cpos] = '\0';
3814 yylval.u.i = atoi(cp);
3815 yylval.u.ll = STRTOLL(cp, NULL, 10);
3816 cmdp[cpos] = c;
3817 return (NUMBER);
3818 }
3819 if (strncasecmp(&cmdp[cpos], "ALL", 3) == 0
3820 && !isalnum((unsigned char)cmdp[cpos + 3])) {
3821 cpos += 3;
3822 return (ALL);
3823 }
3824 switch (cmdp[cpos++]) {
3825
3826 case '\n':
3827 state = EOLN;
3828 return (CRLF);
3829
3830 case ' ':
3831 return (SP);
3832
3833 case ',':
3834 return (COMMA);
3835
3836 case 'A':
3837 case 'a':
3838 return (A);
3839
3840 case 'B':
3841 case 'b':
3842 return (B);
3843
3844 case 'C':
3845 case 'c':
3846 return (C);
3847
3848 case 'E':
3849 case 'e':
3850 return (E);
3851
3852 case 'F':
3853 case 'f':
3854 return (F);
3855
3856 case 'I':
3857 case 'i':
3858 return (I);
3859
3860 case 'L':
3861 case 'l':
3862 return (L);
3863
3864 case 'N':
3865 case 'n':
3866 return (N);
3867
3868 case 'P':
3869 case 'p':
3870 return (P);
3871
3872 case 'R':
3873 case 'r':
3874 return (R);
3875
3876 case 'S':
3877 case 's':
3878 return (S);
3879
3880 case 'T':
3881 case 't':
3882 return (T);
3883
3884 }
3885 break;
3886
3887 case NOARGS:
3888 if (cmdp[cpos] == '\n') {
3889 state = EOLN;
3890 return (CRLF);
3891 }
3892 c = cmdp[cpos];
3893 cmdp[cpos] = '\0';
3894 reply(501, "'%s' command does not take any arguments.", cmdp);
3895 hasyyerrored = 1;
3896 cmdp[cpos] = c;
3897 break;
3898
3899 case EOLN:
3900 state = CMD;
3901 return (0);
3902
3903 default:
3904 fatal("Unknown state in scanner.");
3905 }
3906 yyerror(NULL);
3907 state = CMD;
3908 return (0);
3909 }
3910
3911 /* ARGSUSED */
3912 void
3913 yyerror(const char *s)
3914 {
3915 char *cp;
3916
3917 if (hasyyerrored || is_oob)
3918 return;
3919 if ((cp = strchr(cmdp,'\n')) != NULL)
3920 *cp = '\0';
3921 reply(500, "'%s': command not understood.", cmdp);
3922 hasyyerrored = 1;
3923 }
3924
3925 static void
3926 help(struct tab *ctab, const char *s)
3927 {
3928 struct tab *c;
3929 int width, NCMDS;
3930 const char *htype;
3931
3932 if (ctab == sitetab)
3933 htype = "SITE ";
3934 else
3935 htype = "";
3936 width = 0, NCMDS = 0;
3937 for (c = ctab; c->name != NULL; c++) {
3938 int len = strlen(c->name);
3939
3940 if (len > width)
3941 width = len;
3942 NCMDS++;
3943 }
3944 width = (width + 8) &~ 7;
3945 if (s == 0) {
3946 int i, j, w;
3947 int columns, lines;
3948
3949 reply(-214, "%s", "");
3950 reply(0, "The following %scommands are recognized.", htype);
3951 reply(0, "(`-' = not implemented, `+' = supports options)");
3952 columns = 76 / width;
3953 if (columns == 0)
3954 columns = 1;
3955 lines = (NCMDS + columns - 1) / columns;
3956 for (i = 0; i < lines; i++) {
3957 cprintf(stdout, " ");
3958 for (j = 0; j < columns; j++) {
3959 c = ctab + j * lines + i;
3960 cprintf(stdout, "%s", c->name);
3961 w = strlen(c->name);
3962 if (! CMD_IMPLEMENTED(c)) {
3963 CPUTC('-', stdout);
3964 w++;
3965 }
3966 if (CMD_HAS_OPTIONS(c)) {
3967 CPUTC('+', stdout);
3968 w++;
3969 }
3970 if (c + lines >= &ctab[NCMDS])
3971 break;
3972 while (w < width) {
3973 CPUTC(' ', stdout);
3974 w++;
3975 }
3976 }
3977 cprintf(stdout, "\r\n");
3978 }
3979 (void) fflush(stdout);
3980 reply(214, "Direct comments to ftp-bugs@%s.", hostname);
3981 return;
3982 }
3983 c = lookup(ctab, s);
3984 if (c == (struct tab *)0) {
3985 reply(502, "Unknown command '%s'.", s);
3986 return;
3987 }
3988 if (CMD_IMPLEMENTED(c))
3989 reply(214, "Syntax: %s%s %s", htype, c->name, c->help);
3990 else
3991 reply(504, "%s%-*s\t%s; not implemented.", htype, width,
3992 c->name, c->help);
3993 }
3994
3995 /*
3996 * Check that the structures used for a PORT, LPRT or EPRT command are
3997 * valid (data_dest, his_addr), and if necessary, detect ftp bounce attacks.
3998 * If family != -1 check that his_addr.su_family == family.
3999 */
4000 static void
4001 port_check(const char *cmd, int family)
4002 {
4003 char h1[NI_MAXHOST], h2[NI_MAXHOST];
4004 char s1[NI_MAXHOST], s2[NI_MAXHOST];
4005 #ifdef NI_WITHSCOPEID
4006 const int niflags = NI_NUMERICHOST | NI_NUMERICSERV | NI_WITHSCOPEID;
4007 #else
4008 const int niflags = NI_NUMERICHOST | NI_NUMERICSERV;
4009 #endif
4010
4011 if (epsvall) {
4012 reply(501, "%s disallowed after EPSV ALL", cmd);
4013 return;
4014 }
4015
4016 if (family != -1 && his_addr.su_family != family) {
4017 port_check_fail:
4018 reply(500, "Illegal %s command rejected", cmd);
4019 return;
4020 }
4021
4022 if (data_dest.su_family != his_addr.su_family)
4023 goto port_check_fail;
4024
4025 /* be paranoid, if told so */
4026 if (CURCLASS_FLAGS_ISSET(checkportcmd)) {
4027 #ifdef INET6
4028 /*
4029 * be paranoid, there are getnameinfo implementation that does
4030 * not present scopeid portion
4031 */
4032 if (data_dest.su_family == AF_INET6 &&
4033 data_dest.su_scope_id != his_addr.su_scope_id)
4034 goto port_check_fail;
4035 #endif
4036
4037 if (getnameinfo((struct sockaddr *)&data_dest, data_dest.su_len,
4038 h1, sizeof(h1), s1, sizeof(s1), niflags))
4039 goto port_check_fail;
4040 if (getnameinfo((struct sockaddr *)&his_addr, his_addr.su_len,
4041 h2, sizeof(h2), s2, sizeof(s2), niflags))
4042 goto port_check_fail;
4043
4044 if (atoi(s1) < IPPORT_RESERVED || strcmp(h1, h2) != 0)
4045 goto port_check_fail;
4046 }
4047
4048 usedefault = 0;
4049 if (pdata >= 0) {
4050 (void) close(pdata);
4051 pdata = -1;
4052 }
4053 reply(200, "%s command successful.", cmd);
4054 }
4055
4056