|
1 // |
|
2 // Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 // All rights reserved. |
|
4 // This component and the accompanying materials are made available |
|
5 // under the terms of "Eclipse Public License v1.0" |
|
6 // which accompanies this distribution, and is available |
|
7 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 // |
|
9 // Initial Contributors: |
|
10 // Nokia Corporation - initial contribution. |
|
11 // |
|
12 // Contributors: |
|
13 // |
|
14 // Description: |
|
15 // |
|
16 |
|
17 /* A Bison parser, made by GNU Bison 2.1. */ |
|
18 |
|
19 /* Skeleton parser for Yacc-like parsing with Bison, |
|
20 Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. |
|
21 |
|
22 This program is free software; you can redistribute it and/or modify |
|
23 it under the terms of the GNU General Public License as published by |
|
24 the Free Software Foundation; either version 2, or (at your option) |
|
25 any later version. |
|
26 |
|
27 This program is distributed in the hope that it will be useful, |
|
28 but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
29 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
30 GNU General Public License for more details. |
|
31 |
|
32 You should have received a copy of the GNU General Public License |
|
33 along with this program; if not, write to the Free Software |
|
34 Foundation, Inc., 51 Franklin Street, Fifth Floor, |
|
35 Boston, MA 02110-1301, USA. */ |
|
36 |
|
37 /* As a special exception, when this file is copied by Bison into a |
|
38 Bison output file, you may use that output file without restriction. |
|
39 This special exception was added by the Free Software Foundation |
|
40 in version 1.24 of Bison. */ |
|
41 |
|
42 /* Written by Richard Stallman by simplifying the original so called |
|
43 ``semantic'' parser. */ |
|
44 |
|
45 /* All symbols defined below should begin with yy or YY, to avoid |
|
46 infringing on user name space. This should be done even for local |
|
47 variables, as they might otherwise be expanded by user macros. |
|
48 There are some unavoidable exceptions within include files to |
|
49 define necessary library symbols; they are noted "INFRINGES ON |
|
50 USER NAME SPACE" below. */ |
|
51 |
|
52 /* Identify Bison output. */ |
|
53 #define YYBISON 1 |
|
54 |
|
55 /* Bison version. */ |
|
56 #define YYBISON_VERSION "2.1" |
|
57 |
|
58 /* Skeleton name. */ |
|
59 #define YYSKELETON_NAME "yacc.c" |
|
60 |
|
61 /* Pure parsers. */ |
|
62 #define YYPURE 0 |
|
63 |
|
64 /* Using locations. */ |
|
65 #define YYLSP_NEEDED 0 |
|
66 |
|
67 |
|
68 |
|
69 /* Tokens. */ |
|
70 #ifndef YYTOKENTYPE |
|
71 # define YYTOKENTYPE |
|
72 /* Put the tokens into the symbol table, so that GDB and other debuggers |
|
73 know about them. */ |
|
74 enum yytokentype { |
|
75 A = 258, |
|
76 B = 259, |
|
77 C = 260, |
|
78 E = 261, |
|
79 F = 262, |
|
80 I = 263, |
|
81 L = 264, |
|
82 N = 265, |
|
83 P = 266, |
|
84 R = 267, |
|
85 S = 268, |
|
86 T = 269, |
|
87 SP = 270, |
|
88 CRLF = 271, |
|
89 COMMA = 272, |
|
90 USER = 273, |
|
91 PASS = 274, |
|
92 ACCT = 275, |
|
93 REIN = 276, |
|
94 QUIT = 277, |
|
95 PORT = 278, |
|
96 PASV = 279, |
|
97 TYPE = 280, |
|
98 STRU = 281, |
|
99 MODE = 282, |
|
100 RETR = 283, |
|
101 STOR = 284, |
|
102 APPE = 285, |
|
103 MLFL = 286, |
|
104 MAIL = 287, |
|
105 MSND = 288, |
|
106 MSOM = 289, |
|
107 MSAM = 290, |
|
108 MRSQ = 291, |
|
109 MRCP = 292, |
|
110 ALLO = 293, |
|
111 REST = 294, |
|
112 RNFR = 295, |
|
113 RNTO = 296, |
|
114 ABOR = 297, |
|
115 DELE = 298, |
|
116 CWD = 299, |
|
117 LIST = 300, |
|
118 NLST = 301, |
|
119 SITE = 302, |
|
120 STAT = 303, |
|
121 HELP = 304, |
|
122 NOOP = 305, |
|
123 MKD = 306, |
|
124 RMD = 307, |
|
125 PWD = 308, |
|
126 CDUP = 309, |
|
127 STOU = 310, |
|
128 SMNT = 311, |
|
129 SYST = 312, |
|
130 SIZE = 313, |
|
131 MDTM = 314, |
|
132 UMASK = 315, |
|
133 IDLE = 316, |
|
134 CHMOD = 317, |
|
135 LEXERR = 318, |
|
136 STRING = 319, |
|
137 NUMBER = 320 |
|
138 }; |
|
139 #endif |
|
140 /* Tokens. */ |
|
141 #define A 258 |
|
142 #define B 259 |
|
143 #define C 260 |
|
144 #define E 261 |
|
145 #define F 262 |
|
146 #define I 263 |
|
147 #define L 264 |
|
148 #define N 265 |
|
149 #define P 266 |
|
150 #define R 267 |
|
151 #define S 268 |
|
152 #define T 269 |
|
153 #define SP 270 |
|
154 #define CRLF 271 |
|
155 #define COMMA 272 |
|
156 #define USER 273 |
|
157 #define PASS 274 |
|
158 #define ACCT 275 |
|
159 #define REIN 276 |
|
160 #define QUIT 277 |
|
161 #define PORT 278 |
|
162 #define PASV 279 |
|
163 #define TYPE 280 |
|
164 #define STRU 281 |
|
165 #define MODE 282 |
|
166 #define RETR 283 |
|
167 #define STOR 284 |
|
168 #define APPE 285 |
|
169 #define MLFL 286 |
|
170 #define MAIL 287 |
|
171 #define MSND 288 |
|
172 #define MSOM 289 |
|
173 #define MSAM 290 |
|
174 #define MRSQ 291 |
|
175 #define MRCP 292 |
|
176 #define ALLO 293 |
|
177 #define REST 294 |
|
178 #define RNFR 295 |
|
179 #define RNTO 296 |
|
180 #define ABOR 297 |
|
181 #define DELE 298 |
|
182 #define CWD 299 |
|
183 #define LIST 300 |
|
184 #define NLST 301 |
|
185 #define SITE 302 |
|
186 #define STAT 303 |
|
187 #define HELP 304 |
|
188 #define NOOP 305 |
|
189 #define MKD 306 |
|
190 #define RMD 307 |
|
191 #define PWD 308 |
|
192 #define CDUP 309 |
|
193 #define STOU 310 |
|
194 #define SMNT 311 |
|
195 #define SYST 312 |
|
196 #define SIZE 313 |
|
197 #define MDTM 314 |
|
198 #define UMASK 315 |
|
199 #define IDLE 316 |
|
200 #define CHMOD 317 |
|
201 #define LEXERR 318 |
|
202 #define STRING 319 |
|
203 #define NUMBER 320 |
|
204 |
|
205 |
|
206 |
|
207 |
|
208 /* Copy the first part of user declarations. */ |
|
209 #line 43 "ftpcmd.y" |
|
210 |
|
211 |
|
212 char ftpcmd_rcsid[] = |
|
213 "$Id: ftpcmd.y,v 1.11 1999/10/09 02:32:12 dholland Exp $"; |
|
214 |
|
215 #include <sys/param.h> |
|
216 #include <sys/socket.h> |
|
217 #include <sys/stat.h> |
|
218 |
|
219 #include <netinet/in.h> |
|
220 #include <arpa/ftp.h> |
|
221 |
|
222 #include <ctype.h> |
|
223 #include <errno.h> |
|
224 #include <glob.h> |
|
225 #include <pwd.h> |
|
226 #include <setjmp.h> |
|
227 #include <signal.h> |
|
228 #include <stdio.h> |
|
229 #include <stdlib.h> |
|
230 #include <string.h> |
|
231 //#include <syslog.h> |
|
232 #include <time.h> |
|
233 #include <unistd.h> |
|
234 |
|
235 //#ifndef __linux__ |
|
236 //#include <tzfile.h> |
|
237 //#else |
|
238 #define TM_YEAR_BASE 1900 |
|
239 //#endif |
|
240 |
|
241 #include "extern.h" |
|
242 |
|
243 extern struct sockaddr_in data_dest; |
|
244 extern int logged_in; |
|
245 extern struct passwd *pw; |
|
246 extern int guest; |
|
247 extern int logging; |
|
248 extern int type; |
|
249 extern int form; |
|
250 extern int debug; |
|
251 extern int timeout; |
|
252 extern int maxtimeout; |
|
253 extern int pdata; |
|
254 extern char hostname[], remotehost[]; |
|
255 extern char proctitle[]; |
|
256 extern int usedefault; |
|
257 extern int transflag; |
|
258 extern char tmpline[]; |
|
259 extern int portcheck; |
|
260 extern struct sockaddr_in his_addr; |
|
261 |
|
262 off_t restart_point; |
|
263 |
|
264 static int cmd_type; |
|
265 static int cmd_form; |
|
266 static int cmd_bytesz; |
|
267 char cbuf[512]; |
|
268 char *fromname; |
|
269 |
|
270 struct tab; |
|
271 static int yylex __P((void)); |
|
272 //static void sizecmd __P((char *)); |
|
273 static void help __P((struct tab *, char *)); |
|
274 |
|
275 //extern struct tab cmdtab[]; |
|
276 //extern struct tab sitetab[]; |
|
277 |
|
278 #define CMD 0 /* beginning of command */ |
|
279 #define ARGS 1 /* expect miscellaneous arguments */ |
|
280 #define STR1 2 /* expect SP followed by STRING */ |
|
281 #define STR2 3 /* expect STRING */ |
|
282 #define OSTR 4 /* optional SP then STRING */ |
|
283 #define ZSTR1 5 /* SP then optional STRING */ |
|
284 #define ZSTR2 6 /* optional STRING after SP */ |
|
285 #define SITECMD 7 /* SITE command */ |
|
286 #define NSTR 8 /* Number followed by a string */ |
|
287 |
|
288 struct tab { |
|
289 const char *name; |
|
290 short token; |
|
291 short state; |
|
292 short implemented; /* 1 if command is implemented */ |
|
293 const char *help; |
|
294 }; |
|
295 |
|
296 |
|
297 |
|
298 extern struct tab cmdtab[] = { /* In order defined in RFC 765 */ |
|
299 { "USER", USER, STR1, 1, "<sp> username" }, |
|
300 { "PASS", PASS, ZSTR1, 1, "<sp> password" }, |
|
301 { "ACCT", ACCT, STR1, 0, "(specify account)" }, |
|
302 { "SMNT", SMNT, ARGS, 0, "(structure mount)" }, |
|
303 { "REIN", REIN, ARGS, 0, "(reinitialize server state)" }, |
|
304 { "QUIT", QUIT, ARGS, 1, "(terminate service)", }, |
|
305 { "PORT", PORT, ARGS, 1, "<sp> b0, b1, b2, b3, b4" }, |
|
306 { "PASV", PASV, ARGS, 1, "(set server in passive mode)" }, |
|
307 { "TYPE", TYPE, ARGS, 1, "<sp> [ A | E | I | L ]" }, |
|
308 { "STRU", STRU, ARGS, 1, "(specify file structure)" }, |
|
309 { "MODE", MODE, ARGS, 1, "(specify transfer mode)" }, |
|
310 { "RETR", RETR, STR1, 1, "<sp> file-name" }, |
|
311 { "STOR", STOR, STR1, 1, "<sp> file-name" }, |
|
312 { "APPE", APPE, STR1, 1, "<sp> file-name" }, |
|
313 { "MLFL", MLFL, OSTR, 0, "(mail file)" }, |
|
314 { "MAIL", MAIL, OSTR, 0, "(mail to user)" }, |
|
315 { "MSND", MSND, OSTR, 0, "(mail send to terminal)" }, |
|
316 { "MSOM", MSOM, OSTR, 0, "(mail send to terminal or mailbox)" }, |
|
317 { "MSAM", MSAM, OSTR, 0, "(mail send to terminal and mailbox)" }, |
|
318 { "MRSQ", MRSQ, OSTR, 0, "(mail recipient scheme question)" }, |
|
319 { "MRCP", MRCP, STR1, 0, "(mail recipient)" }, |
|
320 { "ALLO", ALLO, ARGS, 1, "allocate storage (vacuously)" }, |
|
321 { "REST", REST, ARGS, 1, "<sp> offset (restart command)" }, |
|
322 { "RNFR", RNFR, STR1, 1, "<sp> file-name" }, |
|
323 { "RNTO", RNTO, STR1, 1, "<sp> file-name" }, |
|
324 { "ABOR", ABOR, ARGS, 1, "(abort operation)" }, |
|
325 { "DELE", DELE, STR1, 1, "<sp> file-name" }, |
|
326 { "CWD", CWD, OSTR, 1, "[ <sp> directory-name ]" }, |
|
327 { "XCWD", CWD, OSTR, 1, "[ <sp> directory-name ]" }, |
|
328 { "LIST", LIST, OSTR, 1, "[ <sp> path-name ]" }, |
|
329 { "NLST", NLST, OSTR, 1, "[ <sp> path-name ]" }, |
|
330 { "SITE", SITE, SITECMD, 1, "site-cmd [ <sp> arguments ]" }, |
|
331 { "SYST", SYST, ARGS, 1, "(get type of operating system)" }, |
|
332 { "STAT", STAT, OSTR, 1, "[ <sp> path-name ]" }, |
|
333 { "HELP", HELP, OSTR, 1, "[ <sp> <string> ]" }, |
|
334 { "NOOP", NOOP, ARGS, 1, "" }, |
|
335 { "MKD", MKD, STR1, 1, "<sp> path-name" }, |
|
336 { "XMKD", MKD, STR1, 1, "<sp> path-name" }, |
|
337 { "RMD", RMD, STR1, 1, "<sp> path-name" }, |
|
338 { "XRMD", RMD, STR1, 1, "<sp> path-name" }, |
|
339 { "PWD", PWD, ARGS, 1, "(return current directory)" }, |
|
340 { "XPWD", PWD, ARGS, 1, "(return current directory)" }, |
|
341 { "CDUP", CDUP, ARGS, 1, "(change to parent directory)" }, |
|
342 { "XCUP", CDUP, ARGS, 1, "(change to parent directory)" }, |
|
343 { "STOU", STOU, STR1, 1, "<sp> file-name" }, |
|
344 { "SIZE", SIZE, OSTR, 1, "<sp> path-name" }, |
|
345 { "MDTM", MDTM, OSTR, 1, "<sp> path-name" }, |
|
346 { NULL, 0, 0, 0, 0 } |
|
347 }; |
|
348 |
|
349 extern struct tab sitetab[] = { |
|
350 { "UMASK", UMASK, ARGS, 1, "[ <sp> umask ]" }, |
|
351 { "IDLE", IDLE, ARGS, 1, "[ <sp> maximum-idle-time ]" }, |
|
352 { "CHMOD", CHMOD, NSTR, 1, "<sp> mode <sp> file-name" }, |
|
353 { "HELP", HELP, OSTR, 1, "[ <sp> <string> ]" }, |
|
354 { NULL, 0, 0, 0, 0 } |
|
355 }; |
|
356 |
|
357 |
|
358 |
|
359 /* Enabling traces. */ |
|
360 #ifndef YYDEBUG |
|
361 # define YYDEBUG 0 |
|
362 #endif |
|
363 |
|
364 /* Enabling verbose error messages. */ |
|
365 #ifdef YYERROR_VERBOSE |
|
366 # undef YYERROR_VERBOSE |
|
367 # define YYERROR_VERBOSE 1 |
|
368 #else |
|
369 # define YYERROR_VERBOSE 0 |
|
370 #endif |
|
371 |
|
372 /* Enabling the token table. */ |
|
373 #ifndef YYTOKEN_TABLE |
|
374 # define YYTOKEN_TABLE 0 |
|
375 #endif |
|
376 |
|
377 #if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED) |
|
378 #line 113 "ftpcmd.y" |
|
379 typedef union YYSTYPE { |
|
380 int i; |
|
381 char *s; |
|
382 } YYSTYPE; |
|
383 /* Line 196 of yacc.c. */ |
|
384 # define yystype YYSTYPE /* obsolescent; will be withdrawn */ |
|
385 # define YYSTYPE_IS_DECLARED 1 |
|
386 # define YYSTYPE_IS_TRIVIAL 1 |
|
387 #endif |
|
388 |
|
389 |
|
390 |
|
391 /* Copy the second part of user declarations. */ |
|
392 |
|
393 |
|
394 /* Line 219 of yacc.c. */ |
|
395 |
|
396 #if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__) |
|
397 # define YYSIZE_T __SIZE_TYPE__ |
|
398 #endif |
|
399 #if ! defined (YYSIZE_T) && defined (size_t) |
|
400 # define YYSIZE_T size_t |
|
401 #endif |
|
402 #if ! defined (YYSIZE_T) && (defined (__STDC__) || defined (__cplusplus)) |
|
403 # include <stddef.h> /* INFRINGES ON USER NAME SPACE */ |
|
404 # define YYSIZE_T size_t |
|
405 #endif |
|
406 #if ! defined (YYSIZE_T) |
|
407 # define YYSIZE_T unsigned int |
|
408 #endif |
|
409 |
|
410 #ifndef YY_ |
|
411 # if YYENABLE_NLS |
|
412 # if ENABLE_NLS |
|
413 # include <libintl.h> /* INFRINGES ON USER NAME SPACE */ |
|
414 # define YY_(msgid) dgettext ("bison-runtime", msgid) |
|
415 # endif |
|
416 # endif |
|
417 # ifndef YY_ |
|
418 # define YY_(msgid) msgid |
|
419 # endif |
|
420 #endif |
|
421 |
|
422 #if ! defined (yyoverflow) || YYERROR_VERBOSE |
|
423 |
|
424 /* The parser invokes alloca or malloc; define the necessary symbols. */ |
|
425 |
|
426 # ifdef YYSTACK_USE_ALLOCA |
|
427 # if YYSTACK_USE_ALLOCA |
|
428 # ifdef __GNUC__ |
|
429 # define YYSTACK_ALLOC __builtin_alloca |
|
430 # else |
|
431 # define YYSTACK_ALLOC alloca |
|
432 # if defined (__STDC__) || defined (__cplusplus) |
|
433 # include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ |
|
434 # define YYINCLUDED_STDLIB_H |
|
435 # endif |
|
436 # endif |
|
437 # endif |
|
438 # endif |
|
439 |
|
440 # ifdef YYSTACK_ALLOC |
|
441 /* Pacify GCC's `empty if-body' warning. */ |
|
442 # define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) |
|
443 # ifndef YYSTACK_ALLOC_MAXIMUM |
|
444 /* The OS might guarantee only one guard page at the bottom of the stack, |
|
445 and a page size can be as small as 4096 bytes. So we cannot safely |
|
446 invoke alloca (N) if N exceeds 4096. Use a slightly smaller number |
|
447 to allow for a few compiler-allocated temporary stack slots. */ |
|
448 # define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2005 */ |
|
449 # endif |
|
450 # else |
|
451 # define YYSTACK_ALLOC YYMALLOC |
|
452 # define YYSTACK_FREE YYFREE |
|
453 # ifndef YYSTACK_ALLOC_MAXIMUM |
|
454 # define YYSTACK_ALLOC_MAXIMUM ((YYSIZE_T) -1) |
|
455 # endif |
|
456 # ifdef __cplusplus |
|
457 extern "C" { |
|
458 # endif |
|
459 # ifndef YYMALLOC |
|
460 # define YYMALLOC malloc |
|
461 # if (! defined (malloc) && ! defined (YYINCLUDED_STDLIB_H) \ |
|
462 && (defined (__STDC__) || defined (__cplusplus))) |
|
463 void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ |
|
464 # endif |
|
465 # endif |
|
466 # ifndef YYFREE |
|
467 # define YYFREE free |
|
468 # if (! defined (free) && ! defined (YYINCLUDED_STDLIB_H) \ |
|
469 && (defined (__STDC__) || defined (__cplusplus))) |
|
470 void free (void *); /* INFRINGES ON USER NAME SPACE */ |
|
471 # endif |
|
472 # endif |
|
473 # ifdef __cplusplus |
|
474 } |
|
475 # endif |
|
476 # endif |
|
477 #endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */ |
|
478 |
|
479 |
|
480 #if (! defined (yyoverflow) \ |
|
481 && (! defined (__cplusplus) \ |
|
482 || (defined (YYSTYPE_IS_TRIVIAL) && YYSTYPE_IS_TRIVIAL))) |
|
483 |
|
484 /* A type that is properly aligned for any stack member. */ |
|
485 union yyalloc |
|
486 { |
|
487 short int yyss; |
|
488 YYSTYPE yyvs; |
|
489 }; |
|
490 |
|
491 /* The size of the maximum gap between one aligned stack and the next. */ |
|
492 # define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) |
|
493 |
|
494 /* The size of an array large to enough to hold all stacks, each with |
|
495 N elements. */ |
|
496 # define YYSTACK_BYTES(N) \ |
|
497 ((N) * (sizeof (short int) + sizeof (YYSTYPE)) \ |
|
498 + YYSTACK_GAP_MAXIMUM) |
|
499 |
|
500 /* Copy COUNT objects from FROM to TO. The source and destination do |
|
501 not overlap. */ |
|
502 # ifndef YYCOPY |
|
503 # if defined (__GNUC__) && 1 < __GNUC__ |
|
504 # define YYCOPY(To, From, Count) \ |
|
505 __builtin_memcpy (To, From, (Count) * sizeof (*(From))) |
|
506 # else |
|
507 # define YYCOPY(To, From, Count) \ |
|
508 do \ |
|
509 { \ |
|
510 YYSIZE_T yyi; \ |
|
511 for (yyi = 0; yyi < (Count); yyi++) \ |
|
512 (To)[yyi] = (From)[yyi]; \ |
|
513 } \ |
|
514 while (0) |
|
515 # endif |
|
516 # endif |
|
517 |
|
518 /* Relocate STACK from its old location to the new one. The |
|
519 local variables YYSIZE and YYSTACKSIZE give the old and new number of |
|
520 elements in the stack, and YYPTR gives the new location of the |
|
521 stack. Advance YYPTR to a properly aligned location for the next |
|
522 stack. */ |
|
523 # define YYSTACK_RELOCATE(Stack) \ |
|
524 do \ |
|
525 { \ |
|
526 YYSIZE_T yynewbytes; \ |
|
527 YYCOPY (&yyptr->Stack, Stack, yysize); \ |
|
528 Stack = &yyptr->Stack; \ |
|
529 yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ |
|
530 yyptr += yynewbytes / sizeof (*yyptr); \ |
|
531 } \ |
|
532 while (0) |
|
533 |
|
534 #endif |
|
535 |
|
536 #if defined (__STDC__) || defined (__cplusplus) |
|
537 typedef signed char yysigned_char; |
|
538 #else |
|
539 typedef short int yysigned_char; |
|
540 #endif |
|
541 |
|
542 /* YYFINAL -- State number of the termination state. */ |
|
543 #define YYFINAL 2 |
|
544 /* YYLAST -- Last index in YYTABLE. */ |
|
545 #define YYLAST 206 |
|
546 |
|
547 /* YYNTOKENS -- Number of terminals. */ |
|
548 #define YYNTOKENS 66 |
|
549 /* YYNNTS -- Number of nonterminals. */ |
|
550 #define YYNNTS 16 |
|
551 /* YYNRULES -- Number of rules. */ |
|
552 #define YYNRULES 75 |
|
553 /* YYNRULES -- Number of states. */ |
|
554 #define YYNSTATES 216 |
|
555 |
|
556 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ |
|
557 #define YYUNDEFTOK 2 |
|
558 #define YYMAXUTOK 320 |
|
559 |
|
560 #define YYTRANSLATE(YYX) \ |
|
561 ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) |
|
562 |
|
563 /* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ |
|
564 static const unsigned char yytranslate[] = |
|
565 { |
|
566 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
|
567 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
|
568 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
|
569 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
|
570 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
|
571 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
|
572 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
|
573 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
|
574 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
|
575 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
|
576 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
|
577 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
|
578 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
|
579 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
|
580 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
|
581 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
|
582 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
|
583 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
|
584 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
|
585 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
|
586 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
|
587 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
|
588 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
|
589 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
|
590 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
|
591 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, |
|
592 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, |
|
593 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, |
|
594 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, |
|
595 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, |
|
596 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, |
|
597 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, |
|
598 65 |
|
599 }; |
|
600 |
|
601 #if YYDEBUG |
|
602 /* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in |
|
603 YYRHS. */ |
|
604 static const unsigned short int yyprhs[] = |
|
605 { |
|
606 0, 0, 3, 4, 7, 10, 15, 20, 26, 30, |
|
607 36, 42, 48, 54, 64, 70, 76, 82, 86, 92, |
|
608 96, 102, 108, 112, 118, 124, 128, 132, 138, 141, |
|
609 146, 149, 155, 161, 165, 169, 174, 181, 187, 195, |
|
610 205, 211, 219, 225, 229, 235, 241, 244, 247, 253, |
|
611 259, 261, 262, 264, 266, 278, 280, 282, 284, 286, |
|
612 290, 292, 296, 298, 300, 304, 307, 309, 311, 313, |
|
613 315, 317, 319, 321, 323, 325 |
|
614 }; |
|
615 |
|
616 /* YYRHS -- A `-1'-separated list of the rules' RHS. */ |
|
617 static const yysigned_char yyrhs[] = |
|
618 { |
|
619 67, 0, -1, -1, 67, 68, -1, 67, 69, -1, |
|
620 18, 15, 70, 16, -1, 19, 15, 71, 16, -1, |
|
621 23, 81, 15, 73, 16, -1, 24, 81, 16, -1, |
|
622 25, 81, 15, 75, 16, -1, 26, 81, 15, 76, |
|
623 16, -1, 27, 81, 15, 77, 16, -1, 38, 81, |
|
624 15, 65, 16, -1, 38, 81, 15, 65, 15, 12, |
|
625 15, 65, 16, -1, 28, 81, 15, 78, 16, -1, |
|
626 29, 81, 15, 78, 16, -1, 30, 81, 15, 78, |
|
627 16, -1, 46, 81, 16, -1, 46, 81, 15, 64, |
|
628 16, -1, 45, 81, 16, -1, 45, 81, 15, 78, |
|
629 16, -1, 48, 81, 15, 78, 16, -1, 48, 81, |
|
630 16, -1, 43, 81, 15, 78, 16, -1, 41, 81, |
|
631 15, 78, 16, -1, 42, 81, 16, -1, 44, 81, |
|
632 16, -1, 44, 81, 15, 78, 16, -1, 49, 16, |
|
633 -1, 49, 15, 64, 16, -1, 50, 16, -1, 51, |
|
634 81, 15, 78, 16, -1, 52, 81, 15, 78, 16, |
|
635 -1, 53, 81, 16, -1, 54, 81, 16, -1, 47, |
|
636 15, 49, 16, -1, 47, 15, 49, 15, 64, 16, |
|
637 -1, 47, 15, 60, 81, 16, -1, 47, 15, 60, |
|
638 81, 15, 80, 16, -1, 47, 15, 62, 81, 15, |
|
639 80, 15, 78, 16, -1, 47, 15, 81, 61, 16, |
|
640 -1, 47, 15, 81, 61, 15, 65, 16, -1, 55, |
|
641 81, 15, 78, 16, -1, 57, 81, 16, -1, 58, |
|
642 81, 15, 78, 16, -1, 59, 81, 15, 78, 16, |
|
643 -1, 22, 16, -1, 1, 16, -1, 40, 81, 15, |
|
644 78, 16, -1, 39, 81, 15, 72, 16, -1, 64, |
|
645 -1, -1, 64, -1, 65, -1, 65, 17, 65, 17, |
|
646 65, 17, 65, 17, 65, 17, 65, -1, 10, -1, |
|
647 14, -1, 5, -1, 3, -1, 3, 15, 74, -1, |
|
648 6, -1, 6, 15, 74, -1, 8, -1, 9, -1, |
|
649 9, 15, 72, -1, 9, 72, -1, 7, -1, 12, |
|
650 -1, 11, -1, 13, -1, 4, -1, 5, -1, 79, |
|
651 -1, 64, -1, 65, -1, -1 |
|
652 }; |
|
653 |
|
654 /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ |
|
655 static const unsigned short int yyrline[] = |
|
656 { |
|
657 0, 148, 148, 150, 155, 159, 164, 170, 199, 205, |
|
658 239, 253, 267, 273, 279, 286, 293, 300, 305, 312, |
|
659 317, 324, 331, 336, 343, 357, 362, 367, 374, 378, |
|
660 396, 400, 407, 414, 419, 424, 428, 435, 445, 460, |
|
661 474, 481, 497, 504, 530, 547, 569, 574, 580, 594, |
|
662 607, 612, 615, 619, 623, 647, 651, 655, 662, 667, |
|
663 672, 677, 682, 686, 691, 697, 705, 709, 713, 720, |
|
664 724, 728, 735, 779, 783, 811 |
|
665 }; |
|
666 #endif |
|
667 |
|
668 #if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE |
|
669 /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. |
|
670 First, the terminals, then, starting at YYNTOKENS, nonterminals. */ |
|
671 static const char *const yytname[] = |
|
672 { |
|
673 "$end", "error", "$undefined", "A", "B", "C", "E", "F", "I", "L", "N", |
|
674 "P", "R", "S", "T", "SP", "CRLF", "COMMA", "USER", "PASS", "ACCT", |
|
675 "REIN", "QUIT", "PORT", "PASV", "TYPE", "STRU", "MODE", "RETR", "STOR", |
|
676 "APPE", "MLFL", "MAIL", "MSND", "MSOM", "MSAM", "MRSQ", "MRCP", "ALLO", |
|
677 "REST", "RNFR", "RNTO", "ABOR", "DELE", "CWD", "LIST", "NLST", "SITE", |
|
678 "STAT", "HELP", "NOOP", "MKD", "RMD", "PWD", "CDUP", "STOU", "SMNT", |
|
679 "SYST", "SIZE", "MDTM", "UMASK", "IDLE", "CHMOD", "LEXERR", "STRING", |
|
680 "NUMBER", "$accept", "cmd_list", "cmd", "rcmd", "username", "password", |
|
681 "byte_size", "host_port", "form_code", "type_code", "struct_code", |
|
682 "mode_code", "pathname", "pathstring", "octal_number", "check_login", 0 |
|
683 }; |
|
684 #endif |
|
685 |
|
686 # ifdef YYPRINT |
|
687 /* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to |
|
688 token YYLEX-NUM. */ |
|
689 static const unsigned short int yytoknum[] = |
|
690 { |
|
691 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, |
|
692 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, |
|
693 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, |
|
694 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, |
|
695 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, |
|
696 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, |
|
697 315, 316, 317, 318, 319, 320 |
|
698 }; |
|
699 # endif |
|
700 |
|
701 /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ |
|
702 static const unsigned char yyr1[] = |
|
703 { |
|
704 0, 66, 67, 67, 67, 68, 68, 68, 68, 68, |
|
705 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, |
|
706 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, |
|
707 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, |
|
708 68, 68, 68, 68, 68, 68, 68, 68, 69, 69, |
|
709 70, 71, 71, 72, 73, 74, 74, 74, 75, 75, |
|
710 75, 75, 75, 75, 75, 75, 76, 76, 76, 77, |
|
711 77, 77, 78, 79, 80, 81 |
|
712 }; |
|
713 |
|
714 /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ |
|
715 static const unsigned char yyr2[] = |
|
716 { |
|
717 0, 2, 0, 2, 2, 4, 4, 5, 3, 5, |
|
718 5, 5, 5, 9, 5, 5, 5, 3, 5, 3, |
|
719 5, 5, 3, 5, 5, 3, 3, 5, 2, 4, |
|
720 2, 5, 5, 3, 3, 4, 6, 5, 7, 9, |
|
721 5, 7, 5, 3, 5, 5, 2, 2, 5, 5, |
|
722 1, 0, 1, 1, 11, 1, 1, 1, 1, 3, |
|
723 1, 3, 1, 1, 3, 2, 1, 1, 1, 1, |
|
724 1, 1, 1, 1, 1, 0 |
|
725 }; |
|
726 |
|
727 /* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state |
|
728 STATE-NUM when YYTABLE doesn't specify something else to do. Zero |
|
729 means the default is an error. */ |
|
730 static const unsigned char yydefact[] = |
|
731 { |
|
732 2, 0, 1, 0, 0, 0, 0, 75, 75, 75, |
|
733 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, |
|
734 75, 75, 75, 75, 0, 75, 0, 0, 75, 75, |
|
735 75, 75, 75, 75, 75, 75, 3, 4, 47, 0, |
|
736 51, 46, 0, 0, 0, 0, 0, 0, 0, 0, |
|
737 0, 0, 0, 0, 0, 0, 0, 0, 0, 75, |
|
738 0, 0, 28, 30, 0, 0, 0, 0, 0, 0, |
|
739 0, 0, 50, 0, 52, 0, 0, 8, 0, 0, |
|
740 0, 0, 0, 0, 0, 0, 0, 0, 25, 0, |
|
741 0, 26, 0, 19, 0, 17, 0, 75, 75, 0, |
|
742 0, 22, 0, 0, 0, 33, 34, 0, 43, 0, |
|
743 0, 5, 6, 0, 0, 58, 60, 62, 63, 0, |
|
744 66, 68, 67, 0, 70, 71, 69, 0, 73, 0, |
|
745 72, 0, 0, 0, 53, 0, 0, 0, 0, 0, |
|
746 0, 0, 0, 35, 0, 0, 0, 0, 29, 0, |
|
747 0, 0, 0, 0, 0, 7, 0, 0, 0, 65, |
|
748 9, 10, 11, 14, 15, 16, 0, 12, 49, 48, |
|
749 24, 23, 27, 20, 18, 0, 0, 37, 0, 0, |
|
750 40, 21, 31, 32, 42, 44, 45, 0, 57, 55, |
|
751 56, 59, 61, 64, 0, 36, 74, 0, 0, 0, |
|
752 0, 0, 38, 0, 41, 0, 0, 0, 0, 13, |
|
753 39, 0, 0, 0, 0, 54 |
|
754 }; |
|
755 |
|
756 /* YYDEFGOTO[NTERM-NUM]. */ |
|
757 static const short int yydefgoto[] = |
|
758 { |
|
759 -1, 1, 36, 37, 73, 75, 135, 114, 191, 119, |
|
760 123, 127, 129, 130, 197, 42 |
|
761 }; |
|
762 |
|
763 /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing |
|
764 STATE-NUM. */ |
|
765 #define YYPACT_NINF -102 |
|
766 static const short int yypact[] = |
|
767 { |
|
768 -102, 47, -102, -13, -9, 1, 8, -102, -102, -102, |
|
769 -102, -102, -102, -102, -102, -102, -102, -102, -102, -102, |
|
770 -102, -102, -102, -102, 11, -102, 52, 29, -102, -102, |
|
771 -102, -102, -102, -102, -102, -102, -102, -102, -102, -4, |
|
772 -2, -102, 64, 65, 69, 88, 102, 105, 113, 114, |
|
773 115, 116, 117, 118, 119, 121, 92, 94, 96, -47, |
|
774 98, 70, -102, -102, 122, 123, 124, 125, 127, 128, |
|
775 130, 131, -102, 132, -102, 133, 74, -102, 55, 71, |
|
776 7, 79, 79, 79, 82, 85, 79, 79, -102, 79, |
|
777 79, -102, 79, -102, 87, -102, 100, -102, -102, 91, |
|
778 79, -102, 137, 79, 79, -102, -102, 79, -102, 79, |
|
779 79, -102, -102, 138, 140, 139, 142, -102, -6, 143, |
|
780 -102, -102, -102, 144, -102, -102, -102, 145, -102, 146, |
|
781 -102, 147, 148, 107, -102, 149, 150, 151, 152, 153, |
|
782 154, 155, 108, -102, 109, 158, 111, 159, -102, 160, |
|
783 161, 162, 163, 164, 93, -102, 9, 9, 85, -102, |
|
784 -102, -102, -102, -102, -102, -102, 169, -102, -102, -102, |
|
785 -102, -102, -102, -102, -102, 166, 120, -102, 120, 126, |
|
786 -102, -102, -102, -102, -102, -102, -102, 157, -102, -102, |
|
787 -102, -102, -102, -102, 168, -102, -102, 170, 172, 173, |
|
788 129, 134, -102, 79, -102, 167, 174, 176, 135, -102, |
|
789 -102, 171, 136, 178, 141, -102 |
|
790 }; |
|
791 |
|
792 /* YYPGOTO[NTERM-NUM]. */ |
|
793 static const yysigned_char yypgoto[] = |
|
794 { |
|
795 -102, -102, -102, -102, -102, -102, -101, -102, 36, -102, |
|
796 -102, -102, -82, -102, 18, 21 |
|
797 }; |
|
798 |
|
799 /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If |
|
800 positive, shift that token. If negative, reduce the rule which |
|
801 number is the opposite. If zero, do what YYDEFACT says. |
|
802 If YYTABLE_NINF, syntax error. */ |
|
803 #define YYTABLE_NINF -1 |
|
804 static const unsigned char yytable[] = |
|
805 { |
|
806 131, 132, 96, 38, 136, 137, 39, 138, 139, 158, |
|
807 140, 124, 125, 97, 188, 98, 40, 159, 147, 189, |
|
808 126, 149, 150, 190, 41, 151, 59, 152, 153, 43, |
|
809 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, |
|
810 54, 55, 56, 57, 58, 63, 60, 2, 3, 64, |
|
811 65, 66, 67, 68, 69, 70, 71, 193, 115, 134, |
|
812 72, 116, 74, 117, 118, 4, 5, 61, 62, 6, |
|
813 7, 8, 9, 10, 11, 12, 13, 14, 120, 76, |
|
814 99, 77, 121, 122, 78, 15, 16, 17, 18, 19, |
|
815 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, |
|
816 30, 31, 32, 79, 33, 34, 35, 90, 91, 92, |
|
817 93, 94, 95, 100, 101, 142, 143, 80, 144, 145, |
|
818 81, 207, 166, 167, 176, 177, 179, 180, 82, 83, |
|
819 84, 85, 86, 87, 102, 88, 89, 103, 104, 113, |
|
820 105, 106, 107, 128, 108, 109, 110, 133, 111, 112, |
|
821 134, 141, 146, 148, 156, 154, 155, 157, 187, 160, |
|
822 161, 162, 163, 164, 165, 168, 169, 170, 171, 172, |
|
823 173, 174, 175, 178, 200, 181, 182, 183, 184, 185, |
|
824 186, 194, 195, 201, 208, 196, 202, 203, 212, 204, |
|
825 209, 199, 210, 192, 205, 214, 198, 0, 0, 206, |
|
826 211, 213, 0, 0, 0, 0, 215 |
|
827 }; |
|
828 |
|
829 static const short int yycheck[] = |
|
830 { |
|
831 82, 83, 49, 16, 86, 87, 15, 89, 90, 15, |
|
832 92, 4, 5, 60, 5, 62, 15, 118, 100, 10, |
|
833 13, 103, 104, 14, 16, 107, 15, 109, 110, 8, |
|
834 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, |
|
835 19, 20, 21, 22, 23, 16, 25, 0, 1, 28, |
|
836 29, 30, 31, 32, 33, 34, 35, 158, 3, 65, |
|
837 64, 6, 64, 8, 9, 18, 19, 15, 16, 22, |
|
838 23, 24, 25, 26, 27, 28, 29, 30, 7, 15, |
|
839 59, 16, 11, 12, 15, 38, 39, 40, 41, 42, |
|
840 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, |
|
841 53, 54, 55, 15, 57, 58, 59, 15, 16, 15, |
|
842 16, 15, 16, 15, 16, 15, 16, 15, 97, 98, |
|
843 15, 203, 15, 16, 15, 16, 15, 16, 15, 15, |
|
844 15, 15, 15, 15, 64, 16, 15, 15, 15, 65, |
|
845 16, 16, 15, 64, 16, 15, 15, 65, 16, 16, |
|
846 65, 64, 61, 16, 15, 17, 16, 15, 65, 16, |
|
847 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, |
|
848 16, 16, 64, 15, 17, 16, 16, 16, 16, 16, |
|
849 16, 12, 16, 15, 17, 65, 16, 15, 17, 16, |
|
850 16, 65, 16, 157, 65, 17, 178, -1, -1, 65, |
|
851 65, 65, -1, -1, -1, -1, 65 |
|
852 }; |
|
853 |
|
854 /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing |
|
855 symbol of state STATE-NUM. */ |
|
856 static const unsigned char yystos[] = |
|
857 { |
|
858 0, 67, 0, 1, 18, 19, 22, 23, 24, 25, |
|
859 26, 27, 28, 29, 30, 38, 39, 40, 41, 42, |
|
860 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, |
|
861 53, 54, 55, 57, 58, 59, 68, 69, 16, 15, |
|
862 15, 16, 81, 81, 81, 81, 81, 81, 81, 81, |
|
863 81, 81, 81, 81, 81, 81, 81, 81, 81, 15, |
|
864 81, 15, 16, 16, 81, 81, 81, 81, 81, 81, |
|
865 81, 81, 64, 70, 64, 71, 15, 16, 15, 15, |
|
866 15, 15, 15, 15, 15, 15, 15, 15, 16, 15, |
|
867 15, 16, 15, 16, 15, 16, 49, 60, 62, 81, |
|
868 15, 16, 64, 15, 15, 16, 16, 15, 16, 15, |
|
869 15, 16, 16, 65, 73, 3, 6, 8, 9, 75, |
|
870 7, 11, 12, 76, 4, 5, 13, 77, 64, 78, |
|
871 79, 78, 78, 65, 65, 72, 78, 78, 78, 78, |
|
872 78, 64, 15, 16, 81, 81, 61, 78, 16, 78, |
|
873 78, 78, 78, 78, 17, 16, 15, 15, 15, 72, |
|
874 16, 16, 16, 16, 16, 16, 15, 16, 16, 16, |
|
875 16, 16, 16, 16, 16, 64, 15, 16, 15, 15, |
|
876 16, 16, 16, 16, 16, 16, 16, 65, 5, 10, |
|
877 14, 74, 74, 72, 12, 16, 65, 80, 80, 65, |
|
878 17, 15, 16, 15, 16, 65, 65, 78, 17, 16, |
|
879 16, 65, 17, 65, 17, 65 |
|
880 }; |
|
881 |
|
882 #define yyerrok (yyerrstatus = 0) |
|
883 #define yyclearin (yychar = YYEMPTY) |
|
884 #define YYEMPTY (-2) |
|
885 #define YYEOF 0 |
|
886 |
|
887 #define YYACCEPT goto yyacceptlab |
|
888 #define YYABORT goto yyabortlab |
|
889 #define YYERROR goto yyerrorlab |
|
890 |
|
891 |
|
892 /* Like YYERROR except do call yyerror. This remains here temporarily |
|
893 to ease the transition to the new meaning of YYERROR, for GCC. |
|
894 Once GCC version 2 has supplanted version 1, this can go. */ |
|
895 |
|
896 #define YYFAIL goto yyerrlab |
|
897 |
|
898 #define YYRECOVERING() (!!yyerrstatus) |
|
899 |
|
900 #define YYBACKUP(Token, Value) \ |
|
901 do \ |
|
902 if (yychar == YYEMPTY && yylen == 1) \ |
|
903 { \ |
|
904 yychar = (Token); \ |
|
905 yylval = (Value); \ |
|
906 yytoken = YYTRANSLATE (yychar); \ |
|
907 YYPOPSTACK; \ |
|
908 goto yybackup; \ |
|
909 } \ |
|
910 else \ |
|
911 { \ |
|
912 yyerror (YY_("syntax error: cannot back up")); \ |
|
913 YYERROR; \ |
|
914 } \ |
|
915 while (0) |
|
916 |
|
917 |
|
918 #define YYTERROR 1 |
|
919 #define YYERRCODE 256 |
|
920 |
|
921 |
|
922 /* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. |
|
923 If N is 0, then set CURRENT to the empty location which ends |
|
924 the previous symbol: RHS[0] (always defined). */ |
|
925 |
|
926 #define YYRHSLOC(Rhs, K) ((Rhs)[K]) |
|
927 #ifndef YYLLOC_DEFAULT |
|
928 # define YYLLOC_DEFAULT(Current, Rhs, N) \ |
|
929 do \ |
|
930 if (N) \ |
|
931 { \ |
|
932 (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ |
|
933 (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ |
|
934 (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ |
|
935 (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ |
|
936 } \ |
|
937 else \ |
|
938 { \ |
|
939 (Current).first_line = (Current).last_line = \ |
|
940 YYRHSLOC (Rhs, 0).last_line; \ |
|
941 (Current).first_column = (Current).last_column = \ |
|
942 YYRHSLOC (Rhs, 0).last_column; \ |
|
943 } \ |
|
944 while (0) |
|
945 #endif |
|
946 |
|
947 |
|
948 /* YY_LOCATION_PRINT -- Print the location on the stream. |
|
949 This macro was not mandated originally: define only if we know |
|
950 we won't break user code: when these are the locations we know. */ |
|
951 |
|
952 #ifndef YY_LOCATION_PRINT |
|
953 # if YYLTYPE_IS_TRIVIAL |
|
954 # define YY_LOCATION_PRINT(File, Loc) \ |
|
955 fprintf (File, "%d.%d-%d.%d", \ |
|
956 (Loc).first_line, (Loc).first_column, \ |
|
957 (Loc).last_line, (Loc).last_column) |
|
958 # else |
|
959 # define YY_LOCATION_PRINT(File, Loc) ((void) 0) |
|
960 # endif |
|
961 #endif |
|
962 |
|
963 |
|
964 /* YYLEX -- calling `yylex' with the right arguments. */ |
|
965 |
|
966 #ifdef YYLEX_PARAM |
|
967 # define YYLEX yylex (YYLEX_PARAM) |
|
968 #else |
|
969 # define YYLEX yylex () |
|
970 #endif |
|
971 |
|
972 /* Enable debugging if requested. */ |
|
973 #if YYDEBUG |
|
974 |
|
975 # ifndef YYFPRINTF |
|
976 # include <stdio.h> /* INFRINGES ON USER NAME SPACE */ |
|
977 # define YYFPRINTF fprintf |
|
978 # endif |
|
979 |
|
980 # define YYDPRINTF(Args) \ |
|
981 do { \ |
|
982 if (yydebug) \ |
|
983 YYFPRINTF Args; \ |
|
984 } while (0) |
|
985 |
|
986 # define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ |
|
987 do { \ |
|
988 if (yydebug) \ |
|
989 { \ |
|
990 YYFPRINTF (stderr, "%s ", Title); \ |
|
991 yysymprint (stderr, \ |
|
992 Type, Value); \ |
|
993 YYFPRINTF (stderr, "\n"); \ |
|
994 } \ |
|
995 } while (0) |
|
996 |
|
997 /*------------------------------------------------------------------. |
|
998 | yy_stack_print -- Print the state stack from its BOTTOM up to its | |
|
999 | TOP (included). | |
|
1000 `------------------------------------------------------------------*/ |
|
1001 |
|
1002 #if defined (__STDC__) || defined (__cplusplus) |
|
1003 static void |
|
1004 yy_stack_print (short int *bottom, short int *top) |
|
1005 #else |
|
1006 static void |
|
1007 yy_stack_print (bottom, top) |
|
1008 short int *bottom; |
|
1009 short int *top; |
|
1010 #endif |
|
1011 { |
|
1012 YYFPRINTF (stderr, "Stack now"); |
|
1013 for (/* Nothing. */; bottom <= top; ++bottom) |
|
1014 YYFPRINTF (stderr, " %d", *bottom); |
|
1015 YYFPRINTF (stderr, "\n"); |
|
1016 } |
|
1017 |
|
1018 # define YY_STACK_PRINT(Bottom, Top) \ |
|
1019 do { \ |
|
1020 if (yydebug) \ |
|
1021 yy_stack_print ((Bottom), (Top)); \ |
|
1022 } while (0) |
|
1023 |
|
1024 |
|
1025 /*------------------------------------------------. |
|
1026 | Report that the YYRULE is going to be reduced. | |
|
1027 `------------------------------------------------*/ |
|
1028 |
|
1029 #if defined (__STDC__) || defined (__cplusplus) |
|
1030 static void |
|
1031 yy_reduce_print (int yyrule) |
|
1032 #else |
|
1033 static void |
|
1034 yy_reduce_print (yyrule) |
|
1035 int yyrule; |
|
1036 #endif |
|
1037 { |
|
1038 int yyi; |
|
1039 unsigned long int yylno = yyrline[yyrule]; |
|
1040 YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu), ", |
|
1041 yyrule - 1, yylno); |
|
1042 /* Print the symbols being reduced, and their result. */ |
|
1043 for (yyi = yyprhs[yyrule]; 0 <= yyrhs[yyi]; yyi++) |
|
1044 YYFPRINTF (stderr, "%s ", yytname[yyrhs[yyi]]); |
|
1045 YYFPRINTF (stderr, "-> %s\n", yytname[yyr1[yyrule]]); |
|
1046 } |
|
1047 |
|
1048 # define YY_REDUCE_PRINT(Rule) \ |
|
1049 do { \ |
|
1050 if (yydebug) \ |
|
1051 yy_reduce_print (Rule); \ |
|
1052 } while (0) |
|
1053 |
|
1054 /* Nonzero means print parse trace. It is left uninitialized so that |
|
1055 multiple parsers can coexist. */ |
|
1056 int yydebug; |
|
1057 #else /* !YYDEBUG */ |
|
1058 # define YYDPRINTF(Args) |
|
1059 # define YY_SYMBOL_PRINT(Title, Type, Value, Location) |
|
1060 # define YY_STACK_PRINT(Bottom, Top) |
|
1061 # define YY_REDUCE_PRINT(Rule) |
|
1062 #endif /* !YYDEBUG */ |
|
1063 |
|
1064 |
|
1065 /* YYINITDEPTH -- initial size of the parser's stacks. */ |
|
1066 #ifndef YYINITDEPTH |
|
1067 # define YYINITDEPTH 200 |
|
1068 #endif |
|
1069 |
|
1070 /* YYMAXDEPTH -- maximum size the stacks can grow to (effective only |
|
1071 if the built-in stack extension method is used). |
|
1072 |
|
1073 Do not make this value too large; the results are undefined if |
|
1074 YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) |
|
1075 evaluated with infinite-precision integer arithmetic. */ |
|
1076 |
|
1077 #ifndef YYMAXDEPTH |
|
1078 # define YYMAXDEPTH 10000 |
|
1079 #endif |
|
1080 |
|
1081 |
|
1082 |
|
1083 #if YYERROR_VERBOSE |
|
1084 |
|
1085 # ifndef yystrlen |
|
1086 # if defined (__GLIBC__) && defined (_STRING_H) |
|
1087 # define yystrlen strlen |
|
1088 # else |
|
1089 /* Return the length of YYSTR. */ |
|
1090 static YYSIZE_T |
|
1091 # if defined (__STDC__) || defined (__cplusplus) |
|
1092 yystrlen (const char *yystr) |
|
1093 # else |
|
1094 yystrlen (yystr) |
|
1095 const char *yystr; |
|
1096 # endif |
|
1097 { |
|
1098 const char *yys = yystr; |
|
1099 |
|
1100 while (*yys++ != '\0') |
|
1101 continue; |
|
1102 |
|
1103 return yys - yystr - 1; |
|
1104 } |
|
1105 # endif |
|
1106 # endif |
|
1107 |
|
1108 # ifndef yystpcpy |
|
1109 # if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE) |
|
1110 # define yystpcpy stpcpy |
|
1111 # else |
|
1112 /* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in |
|
1113 YYDEST. */ |
|
1114 static char * |
|
1115 # if defined (__STDC__) || defined (__cplusplus) |
|
1116 yystpcpy (char *yydest, const char *yysrc) |
|
1117 # else |
|
1118 yystpcpy (yydest, yysrc) |
|
1119 char *yydest; |
|
1120 const char *yysrc; |
|
1121 # endif |
|
1122 { |
|
1123 char *yyd = yydest; |
|
1124 const char *yys = yysrc; |
|
1125 |
|
1126 while ((*yyd++ = *yys++) != '\0') |
|
1127 continue; |
|
1128 |
|
1129 return yyd - 1; |
|
1130 } |
|
1131 # endif |
|
1132 # endif |
|
1133 |
|
1134 # ifndef yytnamerr |
|
1135 /* Copy to YYRES the contents of YYSTR after stripping away unnecessary |
|
1136 quotes and backslashes, so that it's suitable for yyerror. The |
|
1137 heuristic is that double-quoting is unnecessary unless the string |
|
1138 contains an apostrophe, a comma, or backslash (other than |
|
1139 backslash-backslash). YYSTR is taken from yytname. If YYRES is |
|
1140 null, do not copy; instead, return the length of what the result |
|
1141 would have been. */ |
|
1142 static YYSIZE_T |
|
1143 yytnamerr (char *yyres, const char *yystr) |
|
1144 { |
|
1145 if (*yystr == '"') |
|
1146 { |
|
1147 size_t yyn = 0; |
|
1148 char const *yyp = yystr; |
|
1149 |
|
1150 for (;;) |
|
1151 switch (*++yyp) |
|
1152 { |
|
1153 case '\'': |
|
1154 case ',': |
|
1155 goto do_not_strip_quotes; |
|
1156 |
|
1157 case '\\': |
|
1158 if (*++yyp != '\\') |
|
1159 goto do_not_strip_quotes; |
|
1160 /* Fall through. */ |
|
1161 default: |
|
1162 if (yyres) |
|
1163 yyres[yyn] = *yyp; |
|
1164 yyn++; |
|
1165 break; |
|
1166 |
|
1167 case '"': |
|
1168 if (yyres) |
|
1169 yyres[yyn] = '\0'; |
|
1170 return yyn; |
|
1171 } |
|
1172 do_not_strip_quotes: ; |
|
1173 } |
|
1174 |
|
1175 if (! yyres) |
|
1176 return yystrlen (yystr); |
|
1177 |
|
1178 return yystpcpy (yyres, yystr) - yyres; |
|
1179 } |
|
1180 # endif |
|
1181 |
|
1182 #endif /* YYERROR_VERBOSE */ |
|
1183 |
|
1184 |
|
1185 |
|
1186 #if YYDEBUG |
|
1187 /*--------------------------------. |
|
1188 | Print this symbol on YYOUTPUT. | |
|
1189 `--------------------------------*/ |
|
1190 |
|
1191 #if defined (__STDC__) || defined (__cplusplus) |
|
1192 static void |
|
1193 yysymprint (FILE *yyoutput, int yytype, YYSTYPE *yyvaluep) |
|
1194 #else |
|
1195 static void |
|
1196 yysymprint (yyoutput, yytype, yyvaluep) |
|
1197 FILE *yyoutput; |
|
1198 int yytype; |
|
1199 YYSTYPE *yyvaluep; |
|
1200 #endif |
|
1201 { |
|
1202 /* Pacify ``unused variable'' warnings. */ |
|
1203 (void) yyvaluep; |
|
1204 |
|
1205 if (yytype < YYNTOKENS) |
|
1206 YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); |
|
1207 else |
|
1208 YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); |
|
1209 |
|
1210 |
|
1211 # ifdef YYPRINT |
|
1212 if (yytype < YYNTOKENS) |
|
1213 YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); |
|
1214 # endif |
|
1215 switch (yytype) |
|
1216 { |
|
1217 default: |
|
1218 break; |
|
1219 } |
|
1220 YYFPRINTF (yyoutput, ")"); |
|
1221 } |
|
1222 |
|
1223 #endif /* ! YYDEBUG */ |
|
1224 /*-----------------------------------------------. |
|
1225 | Release the memory associated to this symbol. | |
|
1226 `-----------------------------------------------*/ |
|
1227 |
|
1228 #if defined (__STDC__) || defined (__cplusplus) |
|
1229 static void |
|
1230 yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep) |
|
1231 #else |
|
1232 static void |
|
1233 yydestruct (yymsg, yytype, yyvaluep) |
|
1234 const char *yymsg; |
|
1235 int yytype; |
|
1236 YYSTYPE *yyvaluep; |
|
1237 #endif |
|
1238 { |
|
1239 /* Pacify ``unused variable'' warnings. */ |
|
1240 (void) yyvaluep; |
|
1241 |
|
1242 if (!yymsg) |
|
1243 yymsg = "Deleting"; |
|
1244 YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); |
|
1245 |
|
1246 switch (yytype) |
|
1247 { |
|
1248 |
|
1249 default: |
|
1250 break; |
|
1251 } |
|
1252 } |
|
1253 |
|
1254 |
|
1255 /* Prevent warnings from -Wmissing-prototypes. */ |
|
1256 |
|
1257 #ifdef YYPARSE_PARAM |
|
1258 # if defined (__STDC__) || defined (__cplusplus) |
|
1259 int yyparse (void *YYPARSE_PARAM); |
|
1260 # else |
|
1261 int yyparse (); |
|
1262 # endif |
|
1263 #else /* ! YYPARSE_PARAM */ |
|
1264 #if defined (__STDC__) || defined (__cplusplus) |
|
1265 int yyparse (void); |
|
1266 #else |
|
1267 int yyparse (); |
|
1268 #endif |
|
1269 #endif /* ! YYPARSE_PARAM */ |
|
1270 |
|
1271 |
|
1272 |
|
1273 /* The look-ahead symbol. */ |
|
1274 int yychar; |
|
1275 |
|
1276 /* The semantic value of the look-ahead symbol. */ |
|
1277 YYSTYPE yylval; |
|
1278 |
|
1279 /* Number of syntax errors so far. */ |
|
1280 int yynerrs; |
|
1281 |
|
1282 |
|
1283 |
|
1284 /*----------. |
|
1285 | yyparse. | |
|
1286 `----------*/ |
|
1287 |
|
1288 #ifdef YYPARSE_PARAM |
|
1289 # if defined (__STDC__) || defined (__cplusplus) |
|
1290 int yyparse (void *YYPARSE_PARAM) |
|
1291 # else |
|
1292 int yyparse (YYPARSE_PARAM) |
|
1293 void *YYPARSE_PARAM; |
|
1294 # endif |
|
1295 #else /* ! YYPARSE_PARAM */ |
|
1296 #if defined (__STDC__) || defined (__cplusplus) |
|
1297 int |
|
1298 yyparse (void) |
|
1299 #else |
|
1300 int |
|
1301 yyparse () |
|
1302 ; |
|
1303 #endif |
|
1304 #endif |
|
1305 { |
|
1306 |
|
1307 int yystate; |
|
1308 int yyn; |
|
1309 int yyresult; |
|
1310 /* Number of tokens to shift before error messages enabled. */ |
|
1311 int yyerrstatus; |
|
1312 /* Look-ahead token as an internal (translated) token number. */ |
|
1313 int yytoken = 0; |
|
1314 |
|
1315 /* Three stacks and their tools: |
|
1316 `yyss': related to states, |
|
1317 `yyvs': related to semantic values, |
|
1318 `yyls': related to locations. |
|
1319 |
|
1320 Refer to the stacks thru separate pointers, to allow yyoverflow |
|
1321 to reallocate them elsewhere. */ |
|
1322 |
|
1323 /* The state stack. */ |
|
1324 short int yyssa[YYINITDEPTH]; |
|
1325 short int *yyss = yyssa; |
|
1326 short int *yyssp; |
|
1327 |
|
1328 /* The semantic value stack. */ |
|
1329 YYSTYPE yyvsa[YYINITDEPTH]; |
|
1330 YYSTYPE *yyvs = yyvsa; |
|
1331 YYSTYPE *yyvsp; |
|
1332 |
|
1333 |
|
1334 |
|
1335 #define YYPOPSTACK (yyvsp--, yyssp--) |
|
1336 |
|
1337 YYSIZE_T yystacksize = YYINITDEPTH; |
|
1338 |
|
1339 /* The variables used to return semantic value and location from the |
|
1340 action routines. */ |
|
1341 YYSTYPE yyval; |
|
1342 |
|
1343 |
|
1344 /* When reducing, the number of symbols on the RHS of the reduced |
|
1345 rule. */ |
|
1346 int yylen; |
|
1347 |
|
1348 YYDPRINTF ((stderr, "Starting parse\n")); |
|
1349 |
|
1350 yystate = 0; |
|
1351 yyerrstatus = 0; |
|
1352 yynerrs = 0; |
|
1353 yychar = YYEMPTY; /* Cause a token to be read. */ |
|
1354 |
|
1355 /* Initialize stack pointers. |
|
1356 Waste one element of value and location stack |
|
1357 so that they stay on the same level as the state stack. |
|
1358 The wasted elements are never initialized. */ |
|
1359 |
|
1360 yyssp = yyss; |
|
1361 yyvsp = yyvs; |
|
1362 |
|
1363 goto yysetstate; |
|
1364 |
|
1365 /*------------------------------------------------------------. |
|
1366 | yynewstate -- Push a new state, which is found in yystate. | |
|
1367 `------------------------------------------------------------*/ |
|
1368 yynewstate: |
|
1369 /* In all cases, when you get here, the value and location stacks |
|
1370 have just been pushed. so pushing a state here evens the stacks. |
|
1371 */ |
|
1372 yyssp++; |
|
1373 |
|
1374 yysetstate: |
|
1375 *yyssp = yystate; |
|
1376 |
|
1377 if (yyss + yystacksize - 1 <= yyssp) |
|
1378 { |
|
1379 /* Get the current used size of the three stacks, in elements. */ |
|
1380 YYSIZE_T yysize = yyssp - yyss + 1; |
|
1381 |
|
1382 #ifdef yyoverflow |
|
1383 { |
|
1384 /* Give user a chance to reallocate the stack. Use copies of |
|
1385 these so that the &'s don't force the real ones into |
|
1386 memory. */ |
|
1387 YYSTYPE *yyvs1 = yyvs; |
|
1388 short int *yyss1 = yyss; |
|
1389 |
|
1390 |
|
1391 /* Each stack pointer address is followed by the size of the |
|
1392 data in use in that stack, in bytes. This used to be a |
|
1393 conditional around just the two extra args, but that might |
|
1394 be undefined if yyoverflow is a macro. */ |
|
1395 yyoverflow (YY_("memory exhausted"), |
|
1396 &yyss1, yysize * sizeof (*yyssp), |
|
1397 &yyvs1, yysize * sizeof (*yyvsp), |
|
1398 |
|
1399 &yystacksize); |
|
1400 |
|
1401 yyss = yyss1; |
|
1402 yyvs = yyvs1; |
|
1403 } |
|
1404 #else /* no yyoverflow */ |
|
1405 # ifndef YYSTACK_RELOCATE |
|
1406 goto yyexhaustedlab; |
|
1407 # else |
|
1408 /* Extend the stack our own way. */ |
|
1409 if (YYMAXDEPTH <= yystacksize) |
|
1410 goto yyexhaustedlab; |
|
1411 yystacksize *= 2; |
|
1412 if (YYMAXDEPTH < yystacksize) |
|
1413 yystacksize = YYMAXDEPTH; |
|
1414 |
|
1415 { |
|
1416 short int *yyss1 = yyss; |
|
1417 union yyalloc *yyptr = |
|
1418 (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); |
|
1419 if (! yyptr) |
|
1420 goto yyexhaustedlab; |
|
1421 YYSTACK_RELOCATE (yyss); |
|
1422 YYSTACK_RELOCATE (yyvs); |
|
1423 |
|
1424 # undef YYSTACK_RELOCATE |
|
1425 if (yyss1 != yyssa) |
|
1426 YYSTACK_FREE (yyss1); |
|
1427 } |
|
1428 # endif |
|
1429 #endif /* no yyoverflow */ |
|
1430 |
|
1431 yyssp = yyss + yysize - 1; |
|
1432 yyvsp = yyvs + yysize - 1; |
|
1433 |
|
1434 |
|
1435 YYDPRINTF ((stderr, "Stack size increased to %lu\n", |
|
1436 (unsigned long int) yystacksize)); |
|
1437 |
|
1438 if (yyss + yystacksize - 1 <= yyssp) |
|
1439 YYABORT; |
|
1440 } |
|
1441 |
|
1442 YYDPRINTF ((stderr, "Entering state %d\n", yystate)); |
|
1443 |
|
1444 goto yybackup; |
|
1445 |
|
1446 /*-----------. |
|
1447 | yybackup. | |
|
1448 `-----------*/ |
|
1449 yybackup: |
|
1450 |
|
1451 /* Do appropriate processing given the current state. */ |
|
1452 /* Read a look-ahead token if we need one and don't already have one. */ |
|
1453 /* yyresume: */ |
|
1454 |
|
1455 /* First try to decide what to do without reference to look-ahead token. */ |
|
1456 |
|
1457 yyn = yypact[yystate]; |
|
1458 if (yyn == YYPACT_NINF) |
|
1459 goto yydefault; |
|
1460 |
|
1461 /* Not known => get a look-ahead token if don't already have one. */ |
|
1462 |
|
1463 /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */ |
|
1464 if (yychar == YYEMPTY) |
|
1465 { |
|
1466 YYDPRINTF ((stderr, "Reading a token: ")); |
|
1467 yychar = YYLEX; |
|
1468 } |
|
1469 |
|
1470 if (yychar <= YYEOF) |
|
1471 { |
|
1472 yychar = yytoken = YYEOF; |
|
1473 YYDPRINTF ((stderr, "Now at end of input.\n")); |
|
1474 } |
|
1475 else |
|
1476 { |
|
1477 yytoken = YYTRANSLATE (yychar); |
|
1478 YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); |
|
1479 } |
|
1480 |
|
1481 /* If the proper action on seeing token YYTOKEN is to reduce or to |
|
1482 detect an error, take that action. */ |
|
1483 yyn += yytoken; |
|
1484 if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) |
|
1485 goto yydefault; |
|
1486 yyn = yytable[yyn]; |
|
1487 if (yyn <= 0) |
|
1488 { |
|
1489 if (yyn == 0 || yyn == YYTABLE_NINF) |
|
1490 goto yyerrlab; |
|
1491 yyn = -yyn; |
|
1492 goto yyreduce; |
|
1493 } |
|
1494 |
|
1495 if (yyn == YYFINAL) |
|
1496 YYACCEPT; |
|
1497 |
|
1498 /* Shift the look-ahead token. */ |
|
1499 YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); |
|
1500 |
|
1501 /* Discard the token being shifted unless it is eof. */ |
|
1502 if (yychar != YYEOF) |
|
1503 yychar = YYEMPTY; |
|
1504 |
|
1505 *++yyvsp = yylval; |
|
1506 |
|
1507 |
|
1508 /* Count tokens shifted since error; after three, turn off error |
|
1509 status. */ |
|
1510 if (yyerrstatus) |
|
1511 yyerrstatus--; |
|
1512 |
|
1513 yystate = yyn; |
|
1514 goto yynewstate; |
|
1515 |
|
1516 |
|
1517 /*-----------------------------------------------------------. |
|
1518 | yydefault -- do the default action for the current state. | |
|
1519 `-----------------------------------------------------------*/ |
|
1520 yydefault: |
|
1521 yyn = yydefact[yystate]; |
|
1522 if (yyn == 0) |
|
1523 goto yyerrlab; |
|
1524 goto yyreduce; |
|
1525 |
|
1526 |
|
1527 /*-----------------------------. |
|
1528 | yyreduce -- Do a reduction. | |
|
1529 `-----------------------------*/ |
|
1530 yyreduce: |
|
1531 /* yyn is the number of a rule to reduce with. */ |
|
1532 yylen = yyr2[yyn]; |
|
1533 |
|
1534 /* If YYLEN is nonzero, implement the default value of the action: |
|
1535 `$$ = $1'. |
|
1536 |
|
1537 Otherwise, the following line sets YYVAL to garbage. |
|
1538 This behavior is undocumented and Bison |
|
1539 users should not rely upon it. Assigning to YYVAL |
|
1540 unconditionally makes the parser a bit smaller, and it avoids a |
|
1541 GCC warning that YYVAL may be used uninitialized. */ |
|
1542 yyval = yyvsp[1-yylen]; |
|
1543 |
|
1544 |
|
1545 YY_REDUCE_PRINT (yyn); |
|
1546 switch (yyn) |
|
1547 { |
|
1548 case 3: |
|
1549 #line 151 "ftpcmd.y" |
|
1550 { |
|
1551 fromname = (char *) 0; |
|
1552 restart_point = (off_t) 0; |
|
1553 } |
|
1554 break; |
|
1555 |
|
1556 case 5: |
|
1557 #line 160 "ftpcmd.y" |
|
1558 { |
|
1559 user((yyvsp[-1].s)); |
|
1560 free((yyvsp[-1].s)); |
|
1561 } |
|
1562 break; |
|
1563 |
|
1564 case 6: |
|
1565 #line 165 "ftpcmd.y" |
|
1566 { |
|
1567 pass((yyvsp[-1].s)); |
|
1568 memset((yyvsp[-1].s), 0, strlen((yyvsp[-1].s))); |
|
1569 free((yyvsp[-1].s)); |
|
1570 } |
|
1571 break; |
|
1572 |
|
1573 case 7: |
|
1574 #line 171 "ftpcmd.y" |
|
1575 { |
|
1576 if ((yyvsp[-3].i)) { |
|
1577 if ((yyvsp[-1].i)) { |
|
1578 usedefault = 1; |
|
1579 reply(500, |
|
1580 "Illegal PORT rejected (range errors)."); |
|
1581 } else if (portcheck && |
|
1582 /*ntohs(*/data_dest.sin_port/*)*/ < IPPORT_RESERVED) { |
|
1583 usedefault = 1; |
|
1584 reply(500, |
|
1585 "Illegal PORT rejected (reserved port)."); |
|
1586 } else if (portcheck && |
|
1587 memcmp(&data_dest.sin_addr, |
|
1588 &his_addr.sin_addr, |
|
1589 sizeof data_dest.sin_addr)) { |
|
1590 usedefault = 1; |
|
1591 reply(500, |
|
1592 "Illegal PORT rejected (address wrong)."); |
|
1593 } else { |
|
1594 usedefault = 0; |
|
1595 if (pdata >= 0) { |
|
1596 (void) close(pdata); |
|
1597 pdata = -1; |
|
1598 } |
|
1599 reply(200, "PORT command successful."); |
|
1600 } |
|
1601 } |
|
1602 } |
|
1603 break; |
|
1604 |
|
1605 case 8: |
|
1606 #line 200 "ftpcmd.y" |
|
1607 { |
|
1608 if ((yyvsp[-1].i)) { |
|
1609 passive(); |
|
1610 } |
|
1611 } |
|
1612 break; |
|
1613 |
|
1614 case 9: |
|
1615 #line 206 "ftpcmd.y" |
|
1616 { |
|
1617 if ((yyvsp[-3].i)) { |
|
1618 switch (cmd_type) { |
|
1619 |
|
1620 case TYPE_A: |
|
1621 if (cmd_form == FORM_N) { |
|
1622 reply(200, "Type set to A."); |
|
1623 type = cmd_type; |
|
1624 form = cmd_form; |
|
1625 } else |
|
1626 reply(504, "Form must be N."); |
|
1627 break; |
|
1628 |
|
1629 case TYPE_E: |
|
1630 reply(504, "Type E not implemented."); |
|
1631 break; |
|
1632 |
|
1633 case TYPE_I: |
|
1634 reply(200, "Type set to I."); |
|
1635 type = cmd_type; |
|
1636 break; |
|
1637 |
|
1638 case TYPE_L: |
|
1639 if (cmd_bytesz == 8) { |
|
1640 reply(200, |
|
1641 "Type set to L (byte size 8)."); |
|
1642 type = cmd_type; |
|
1643 } else |
|
1644 reply(504, "Byte size must be 8."); |
|
1645 |
|
1646 } |
|
1647 } |
|
1648 } |
|
1649 break; |
|
1650 |
|
1651 case 10: |
|
1652 #line 240 "ftpcmd.y" |
|
1653 { |
|
1654 if ((yyvsp[-3].i)) { |
|
1655 switch ((yyvsp[-1].i)) { |
|
1656 |
|
1657 case STRU_F: |
|
1658 reply(200, "STRU F ok."); |
|
1659 break; |
|
1660 |
|
1661 default: |
|
1662 reply(504, "Unimplemented STRU type."); |
|
1663 } |
|
1664 } |
|
1665 } |
|
1666 break; |
|
1667 |
|
1668 case 11: |
|
1669 #line 254 "ftpcmd.y" |
|
1670 { |
|
1671 if ((yyvsp[-3].i)) { |
|
1672 switch ((yyvsp[-1].i)) { |
|
1673 |
|
1674 case MODE_S: |
|
1675 reply(200, "MODE S ok."); |
|
1676 break; |
|
1677 |
|
1678 default: |
|
1679 reply(502, "Unimplemented MODE type."); |
|
1680 } |
|
1681 } |
|
1682 } |
|
1683 break; |
|
1684 |
|
1685 case 12: |
|
1686 #line 268 "ftpcmd.y" |
|
1687 { |
|
1688 if ((yyvsp[-3].i)) { |
|
1689 reply(202, "ALLO command ignored."); |
|
1690 } |
|
1691 } |
|
1692 break; |
|
1693 |
|
1694 case 13: |
|
1695 #line 274 "ftpcmd.y" |
|
1696 { |
|
1697 if ((yyvsp[-7].i)) { |
|
1698 reply(202, "ALLO command ignored."); |
|
1699 } |
|
1700 } |
|
1701 break; |
|
1702 |
|
1703 case 14: |
|
1704 #line 280 "ftpcmd.y" |
|
1705 { |
|
1706 if ((yyvsp[-3].i) && (yyvsp[-1].s) != NULL) |
|
1707 retrieve((char *) 0, (yyvsp[-1].s)); |
|
1708 if ((yyvsp[-1].s) != NULL) |
|
1709 free((yyvsp[-1].s)); |
|
1710 } |
|
1711 break; |
|
1712 |
|
1713 case 15: |
|
1714 #line 287 "ftpcmd.y" |
|
1715 { |
|
1716 if ((yyvsp[-3].i) && (yyvsp[-1].s) != NULL) |
|
1717 store((yyvsp[-1].s), "w", 0); |
|
1718 if ((yyvsp[-1].s) != NULL) |
|
1719 free((yyvsp[-1].s)); |
|
1720 } |
|
1721 break; |
|
1722 |
|
1723 case 16: |
|
1724 #line 294 "ftpcmd.y" |
|
1725 { |
|
1726 if ((yyvsp[-3].i) && (yyvsp[-1].s) != NULL) |
|
1727 store((yyvsp[-1].s), "a", 0); |
|
1728 if ((yyvsp[-1].s) != NULL) |
|
1729 free((yyvsp[-1].s)); |
|
1730 } |
|
1731 break; |
|
1732 |
|
1733 case 17: |
|
1734 #line 301 "ftpcmd.y" |
|
1735 { |
|
1736 if ((yyvsp[-1].i)) |
|
1737 send_file_list(".",1); |
|
1738 } |
|
1739 break; |
|
1740 |
|
1741 case 18: |
|
1742 #line 306 "ftpcmd.y" |
|
1743 { |
|
1744 if ((yyvsp[-3].i) && (yyvsp[-1].s) != NULL) |
|
1745 send_file_list((yyvsp[-1].s),1); |
|
1746 if ((yyvsp[-1].s) != NULL) |
|
1747 free((yyvsp[-1].s)); |
|
1748 } |
|
1749 break; |
|
1750 |
|
1751 case 19: |
|
1752 #line 313 "ftpcmd.y" |
|
1753 { |
|
1754 if ((yyvsp[-1].i)) |
|
1755 send_file_list(".",0); |
|
1756 //retrieve("/bin/ls -lgA", ""); |
|
1757 } |
|
1758 break; |
|
1759 |
|
1760 case 20: |
|
1761 #line 318 "ftpcmd.y" |
|
1762 { |
|
1763 if ((yyvsp[-3].i) && (yyvsp[-1].s) != NULL) |
|
1764 send_file_list((yyvsp[-1].s),0); |
|
1765 //retrieve("/bin/ls -lgA %s", (yyvsp[-1].s)); |
|
1766 if ((yyvsp[-1].s) != NULL) |
|
1767 free((yyvsp[-1].s)); |
|
1768 } |
|
1769 break; |
|
1770 |
|
1771 case 21: |
|
1772 #line 325 "ftpcmd.y" |
|
1773 { |
|
1774 if ((yyvsp[-3].i) && (yyvsp[-1].s) != NULL) |
|
1775 statfilecmd((yyvsp[-1].s)); |
|
1776 if ((yyvsp[-1].s) != NULL) |
|
1777 free((yyvsp[-1].s)); |
|
1778 } |
|
1779 break; |
|
1780 |
|
1781 case 22: |
|
1782 #line 332 "ftpcmd.y" |
|
1783 { |
|
1784 if ((yyvsp[-1].i)) |
|
1785 statcmd(); |
|
1786 } |
|
1787 break; |
|
1788 |
|
1789 case 23: |
|
1790 #line 337 "ftpcmd.y" |
|
1791 { |
|
1792 if ((yyvsp[-3].i) && (yyvsp[-1].s) != NULL) |
|
1793 dele((yyvsp[-1].s)); |
|
1794 if ((yyvsp[-1].s) != NULL) |
|
1795 free((yyvsp[-1].s)); |
|
1796 } |
|
1797 break; |
|
1798 |
|
1799 case 24: |
|
1800 #line 344 "ftpcmd.y" |
|
1801 { |
|
1802 if ((yyvsp[-3].i)) { |
|
1803 if (fromname) { |
|
1804 renamecmd(fromname, (yyvsp[-1].s)); |
|
1805 free(fromname); |
|
1806 fromname = (char *) 0; |
|
1807 } else { |
|
1808 reply(503, |
|
1809 "Bad sequence of commands."); |
|
1810 } |
|
1811 } |
|
1812 free((yyvsp[-1].s)); |
|
1813 } |
|
1814 break; |
|
1815 |
|
1816 case 25: |
|
1817 #line 358 "ftpcmd.y" |
|
1818 { |
|
1819 if ((yyvsp[-1].i)) |
|
1820 reply(225, "ABOR command successful."); |
|
1821 } |
|
1822 break; |
|
1823 |
|
1824 case 26: |
|
1825 #line 363 "ftpcmd.y" |
|
1826 { |
|
1827 if ((yyvsp[-1].i)) |
|
1828 cwd(pw->pw_dir); |
|
1829 } |
|
1830 break; |
|
1831 |
|
1832 case 27: |
|
1833 #line 368 "ftpcmd.y" |
|
1834 { |
|
1835 if ((yyvsp[-3].i) && (yyvsp[-1].s) != NULL) |
|
1836 cwd((yyvsp[-1].s)); |
|
1837 if ((yyvsp[-1].s) != NULL) |
|
1838 free((yyvsp[-1].s)); |
|
1839 } |
|
1840 break; |
|
1841 |
|
1842 case 28: |
|
1843 #line 375 "ftpcmd.y" |
|
1844 { |
|
1845 help(cmdtab, (char *) 0); |
|
1846 } |
|
1847 break; |
|
1848 |
|
1849 case 29: |
|
1850 #line 379 "ftpcmd.y" |
|
1851 { |
|
1852 char *cp = (yyvsp[-1].s); |
|
1853 |
|
1854 if (strncasecmp(cp, "SITE", 4) == 0) { |
|
1855 cp = (yyvsp[-1].s) + 4; |
|
1856 if (*cp == ' ') |
|
1857 cp++; |
|
1858 if (*cp) |
|
1859 help(sitetab, cp); |
|
1860 else |
|
1861 help(sitetab, (char *) 0); |
|
1862 } |
|
1863 else |
|
1864 help(cmdtab, (yyvsp[-1].s)); |
|
1865 |
|
1866 if ((yyvsp[-1].s) != NULL) |
|
1867 free ((yyvsp[-1].s)); |
|
1868 } |
|
1869 break; |
|
1870 |
|
1871 case 30: |
|
1872 #line 397 "ftpcmd.y" |
|
1873 { |
|
1874 reply(200, "NOOP command successful."); |
|
1875 } |
|
1876 break; |
|
1877 |
|
1878 case 31: |
|
1879 #line 401 "ftpcmd.y" |
|
1880 { |
|
1881 if ((yyvsp[-3].i) && (yyvsp[-1].s) != NULL) |
|
1882 makedir((yyvsp[-1].s)); |
|
1883 if ((yyvsp[-1].s) != NULL) |
|
1884 free((yyvsp[-1].s)); |
|
1885 } |
|
1886 break; |
|
1887 |
|
1888 case 32: |
|
1889 #line 408 "ftpcmd.y" |
|
1890 { |
|
1891 if ((yyvsp[-3].i) && (yyvsp[-1].s) != NULL) |
|
1892 removedir((yyvsp[-1].s)); |
|
1893 if ((yyvsp[-1].s) != NULL) |
|
1894 free((yyvsp[-1].s)); |
|
1895 } |
|
1896 break; |
|
1897 |
|
1898 case 33: |
|
1899 #line 415 "ftpcmd.y" |
|
1900 { |
|
1901 if ((yyvsp[-1].i)) |
|
1902 pwd(); |
|
1903 } |
|
1904 break; |
|
1905 |
|
1906 case 34: |
|
1907 #line 420 "ftpcmd.y" |
|
1908 { |
|
1909 if ((yyvsp[-1].i)) |
|
1910 cwd(".."); |
|
1911 } |
|
1912 break; |
|
1913 |
|
1914 case 35: |
|
1915 #line 425 "ftpcmd.y" |
|
1916 { |
|
1917 help(sitetab, (char *) 0); |
|
1918 } |
|
1919 break; |
|
1920 |
|
1921 case 36: |
|
1922 #line 429 "ftpcmd.y" |
|
1923 { |
|
1924 help(sitetab, (yyvsp[-1].s)); |
|
1925 |
|
1926 if ((yyvsp[-1].s) != NULL) |
|
1927 free ((yyvsp[-1].s)); |
|
1928 } |
|
1929 break; |
|
1930 |
|
1931 case 37: |
|
1932 #line 436 "ftpcmd.y" |
|
1933 { |
|
1934 int oldmask; |
|
1935 |
|
1936 if ((yyvsp[-1].i)) { |
|
1937 oldmask = umask(0); |
|
1938 (void) umask(oldmask); |
|
1939 reply(200, "Current UMASK is %03o", oldmask); |
|
1940 } |
|
1941 } |
|
1942 break; |
|
1943 |
|
1944 case 38: |
|
1945 #line 446 "ftpcmd.y" |
|
1946 { |
|
1947 int oldmask; |
|
1948 |
|
1949 if ((yyvsp[-3].i)) { |
|
1950 if (((yyvsp[-1].i) == -1) || ((yyvsp[-1].i) > 0777)) { |
|
1951 reply(501, "Bad UMASK value"); |
|
1952 } else { |
|
1953 oldmask = umask((yyvsp[-1].i)); |
|
1954 reply(200, |
|
1955 "UMASK set to %03o (was %03o)", |
|
1956 (yyvsp[-1].i), oldmask); |
|
1957 } |
|
1958 } |
|
1959 } |
|
1960 break; |
|
1961 |
|
1962 case 39: |
|
1963 #line 461 "ftpcmd.y" |
|
1964 { |
|
1965 if ((yyvsp[-5].i) && ((yyvsp[-1].s) != NULL)) { |
|
1966 if ((yyvsp[-3].i) > 0777) |
|
1967 reply(501, |
|
1968 "CHMOD: Mode value must be between 0 and 0777"); |
|
1969 else if (chmod((yyvsp[-1].s), (yyvsp[-3].i)) < 0) |
|
1970 perror_reply(550, (yyvsp[-1].s)); |
|
1971 else |
|
1972 reply(200, "CHMOD command successful."); |
|
1973 } |
|
1974 if ((yyvsp[-1].s) != NULL) |
|
1975 free((yyvsp[-1].s)); |
|
1976 } |
|
1977 break; |
|
1978 |
|
1979 case 40: |
|
1980 #line 475 "ftpcmd.y" |
|
1981 { |
|
1982 if ((yyvsp[-2].i)) |
|
1983 reply(200, |
|
1984 "Current IDLE time limit is %d seconds; max %d", |
|
1985 timeout, maxtimeout); |
|
1986 } |
|
1987 break; |
|
1988 |
|
1989 case 41: |
|
1990 #line 482 "ftpcmd.y" |
|
1991 { |
|
1992 if ((yyvsp[-4].i)) { |
|
1993 if ((yyvsp[-1].i) < 30 || (yyvsp[-1].i) > maxtimeout) { |
|
1994 reply(501, |
|
1995 "Maximum IDLE time must be between 30 and %d seconds", |
|
1996 maxtimeout); |
|
1997 } else { |
|
1998 timeout = (yyvsp[-1].i); |
|
1999 //(void) alarm((unsigned) timeout); |
|
2000 reply(200, |
|
2001 "Maximum IDLE time set to %d seconds", |
|
2002 timeout); |
|
2003 } |
|
2004 } |
|
2005 } |
|
2006 break; |
|
2007 |
|
2008 case 42: |
|
2009 #line 498 "ftpcmd.y" |
|
2010 { |
|
2011 if ((yyvsp[-3].i) && (yyvsp[-1].s) != NULL) |
|
2012 store((yyvsp[-1].s), "w", 1); |
|
2013 if ((yyvsp[-1].s) != NULL) |
|
2014 free((yyvsp[-1].s)); |
|
2015 } |
|
2016 break; |
|
2017 |
|
2018 case 43: |
|
2019 #line 505 "ftpcmd.y" |
|
2020 { |
|
2021 if ((yyvsp[-1].i)) |
|
2022 #ifdef __linux__ |
|
2023 reply(215, "UNIX Type: L%d (Linux)", CHAR_BIT); |
|
2024 #else |
|
2025 #ifdef unix |
|
2026 #ifdef BSD |
|
2027 reply(215, "UNIX Type: L%d Version: BSD-%d", |
|
2028 CHAR_BIT, BSD); |
|
2029 #else /* BSD */ |
|
2030 reply(215, "UNIX Type: L%d", CHAR_BIT); |
|
2031 #endif /* BSD */ |
|
2032 #else /* unix */ |
|
2033 #ifdef __SYMBIAN32__ |
|
2034 reply(215, "UNIX Type: L%d", CHAR_BIT); |
|
2035 #else |
|
2036 reply(215, "UNKNOWN Type: L%d", CHAR_BIT); |
|
2037 #endif /* __SYMBIAN32__ */ |
|
2038 #endif /* unix */ |
|
2039 #endif /* __linux__ */ |
|
2040 } |
|
2041 break; |
|
2042 |
|
2043 case 44: |
|
2044 #line 531 "ftpcmd.y" |
|
2045 { |
|
2046 if ((yyvsp[-3].i) && (yyvsp[-1].s) != NULL) |
|
2047 sizecmd((yyvsp[-1].s)); |
|
2048 if ((yyvsp[-1].s) != NULL) |
|
2049 free((yyvsp[-1].s)); |
|
2050 } |
|
2051 break; |
|
2052 |
|
2053 case 45: |
|
2054 #line 548 "ftpcmd.y" |
|
2055 { |
|
2056 if ((yyvsp[-3].i) && (yyvsp[-1].s) != NULL) { |
|
2057 struct stat stbuf; |
|
2058 if (stat((yyvsp[-1].s), &stbuf) < 0) |
|
2059 reply(550, "%s: %s", |
|
2060 (yyvsp[-1].s), strerror(errno)); |
|
2061 else if (!S_ISREG(stbuf.st_mode)) { |
|
2062 reply(550, "%s: not a plain file.", (yyvsp[-1].s)); |
|
2063 } else { |
|
2064 struct tm *t; |
|
2065 t = gmtime(&stbuf.st_mtime); |
|
2066 reply(213, |
|
2067 "%04d%02d%02d%02d%02d%02d", |
|
2068 TM_YEAR_BASE + t->tm_year, |
|
2069 t->tm_mon+1, t->tm_mday, |
|
2070 t->tm_hour, t->tm_min, t->tm_sec); |
|
2071 } |
|
2072 } |
|
2073 if ((yyvsp[-1].s) != NULL) |
|
2074 free((yyvsp[-1].s)); |
|
2075 } |
|
2076 break; |
|
2077 |
|
2078 case 46: |
|
2079 #line 570 "ftpcmd.y" |
|
2080 { |
|
2081 reply(221, "Goodbye."); |
|
2082 dologout(0); |
|
2083 } |
|
2084 break; |
|
2085 |
|
2086 case 47: |
|
2087 #line 575 "ftpcmd.y" |
|
2088 { |
|
2089 yyerrok; |
|
2090 } |
|
2091 break; |
|
2092 |
|
2093 case 48: |
|
2094 #line 581 "ftpcmd.y" |
|
2095 { |
|
2096 restart_point = (off_t) 0; |
|
2097 if ((yyvsp[-3].i) && (yyvsp[-1].s)) { |
|
2098 fromname = renamefrom((yyvsp[-1].s)); |
|
2099 if (fromname == (char *) 0 && (yyvsp[-1].s)) { |
|
2100 free((yyvsp[-1].s)); |
|
2101 } |
|
2102 } else { |
|
2103 if ((yyvsp[-1].s)) |
|
2104 free ((yyvsp[-1].s)); |
|
2105 } |
|
2106 } |
|
2107 break; |
|
2108 |
|
2109 case 49: |
|
2110 #line 595 "ftpcmd.y" |
|
2111 { |
|
2112 if ((yyvsp[-3].i)) { |
|
2113 fromname = (char *) 0; |
|
2114 restart_point = (yyvsp[-1].i); /* XXX $4 is only "int" */ |
|
2115 reply(350, "Restarting at %qd. %s", |
|
2116 (quad_t) restart_point, |
|
2117 "Send STORE or RETRIEVE to initiate transfer."); |
|
2118 } |
|
2119 } |
|
2120 break; |
|
2121 |
|
2122 case 51: |
|
2123 #line 612 "ftpcmd.y" |
|
2124 { |
|
2125 (yyval.s) = (char *)calloc(1, sizeof(char)); |
|
2126 } |
|
2127 break; |
|
2128 |
|
2129 case 54: |
|
2130 #line 625 "ftpcmd.y" |
|
2131 { |
|
2132 char *a, *p; |
|
2133 |
|
2134 if ((yyvsp[-10].i) < 0 || (yyvsp[-10].i) > 255 || (yyvsp[-8].i) < 0 || (yyvsp[-8].i) > 255 || |
|
2135 (yyvsp[-6].i) < 0 || (yyvsp[-6].i) > 255 || (yyvsp[-4].i) < 0 || (yyvsp[-4].i) > 255 || |
|
2136 (yyvsp[-2].i) < 0 || (yyvsp[-2].i) > 255 || (yyvsp[0].i) < 0 || (yyvsp[0].i) > 255) { |
|
2137 (yyval.i) = 1; |
|
2138 } else { |
|
2139 //#ifndef __linux__ |
|
2140 // data_dest.sin_len = sizeof(struct sockaddr_in); |
|
2141 //#endif |
|
2142 data_dest.sin_family = AF_INET; |
|
2143 p = (char *)&data_dest.sin_port; |
|
2144 p[0] = (yyvsp[-2].i); p[1] = (yyvsp[0].i); |
|
2145 a = (char *)&data_dest.sin_addr; |
|
2146 a[0] = (yyvsp[-10].i); a[1] = (yyvsp[-8].i); a[2] = (yyvsp[-6].i); a[3] = (yyvsp[-4].i); |
|
2147 (yyval.i) = 0; |
|
2148 } |
|
2149 } |
|
2150 break; |
|
2151 |
|
2152 case 55: |
|
2153 #line 648 "ftpcmd.y" |
|
2154 { |
|
2155 (yyval.i) = FORM_N; |
|
2156 } |
|
2157 break; |
|
2158 |
|
2159 case 56: |
|
2160 #line 652 "ftpcmd.y" |
|
2161 { |
|
2162 (yyval.i) = FORM_T; |
|
2163 } |
|
2164 break; |
|
2165 |
|
2166 case 57: |
|
2167 #line 656 "ftpcmd.y" |
|
2168 { |
|
2169 (yyval.i) = FORM_C; |
|
2170 } |
|
2171 break; |
|
2172 |
|
2173 case 58: |
|
2174 #line 663 "ftpcmd.y" |
|
2175 { |
|
2176 cmd_type = TYPE_A; |
|
2177 cmd_form = FORM_N; |
|
2178 } |
|
2179 break; |
|
2180 |
|
2181 case 59: |
|
2182 #line 668 "ftpcmd.y" |
|
2183 { |
|
2184 cmd_type = TYPE_A; |
|
2185 cmd_form = (yyvsp[0].i); |
|
2186 } |
|
2187 break; |
|
2188 |
|
2189 case 60: |
|
2190 #line 673 "ftpcmd.y" |
|
2191 { |
|
2192 cmd_type = TYPE_E; |
|
2193 cmd_form = FORM_N; |
|
2194 } |
|
2195 break; |
|
2196 |
|
2197 case 61: |
|
2198 #line 678 "ftpcmd.y" |
|
2199 { |
|
2200 cmd_type = TYPE_E; |
|
2201 cmd_form = (yyvsp[0].i); |
|
2202 } |
|
2203 break; |
|
2204 |
|
2205 case 62: |
|
2206 #line 683 "ftpcmd.y" |
|
2207 { |
|
2208 cmd_type = TYPE_I; |
|
2209 } |
|
2210 break; |
|
2211 |
|
2212 case 63: |
|
2213 #line 687 "ftpcmd.y" |
|
2214 { |
|
2215 cmd_type = TYPE_L; |
|
2216 cmd_bytesz = CHAR_BIT; |
|
2217 } |
|
2218 break; |
|
2219 |
|
2220 case 64: |
|
2221 #line 692 "ftpcmd.y" |
|
2222 { |
|
2223 cmd_type = TYPE_L; |
|
2224 cmd_bytesz = (yyvsp[0].i); |
|
2225 } |
|
2226 break; |
|
2227 |
|
2228 case 65: |
|
2229 #line 698 "ftpcmd.y" |
|
2230 { |
|
2231 cmd_type = TYPE_L; |
|
2232 cmd_bytesz = (yyvsp[0].i); |
|
2233 } |
|
2234 break; |
|
2235 |
|
2236 case 66: |
|
2237 #line 706 "ftpcmd.y" |
|
2238 { |
|
2239 (yyval.i) = STRU_F; |
|
2240 } |
|
2241 break; |
|
2242 |
|
2243 case 67: |
|
2244 #line 710 "ftpcmd.y" |
|
2245 { |
|
2246 (yyval.i) = STRU_R; |
|
2247 } |
|
2248 break; |
|
2249 |
|
2250 case 68: |
|
2251 #line 714 "ftpcmd.y" |
|
2252 { |
|
2253 (yyval.i) = STRU_P; |
|
2254 } |
|
2255 break; |
|
2256 |
|
2257 case 69: |
|
2258 #line 721 "ftpcmd.y" |
|
2259 { |
|
2260 (yyval.i) = MODE_S; |
|
2261 } |
|
2262 break; |
|
2263 |
|
2264 case 70: |
|
2265 #line 725 "ftpcmd.y" |
|
2266 { |
|
2267 (yyval.i) = MODE_B; |
|
2268 } |
|
2269 break; |
|
2270 |
|
2271 case 71: |
|
2272 #line 729 "ftpcmd.y" |
|
2273 { |
|
2274 (yyval.i) = MODE_C; |
|
2275 } |
|
2276 break; |
|
2277 |
|
2278 case 72: |
|
2279 #line 736 "ftpcmd.y" |
|
2280 { |
|
2281 /* |
|
2282 * Problem: this production is used for all pathname |
|
2283 * processing, but only gives a 550 error reply. |
|
2284 * This is a valid reply in some cases but not in others. |
|
2285 */ |
|
2286 if (logged_in && (yyvsp[0].s) && strchr((yyvsp[0].s), '~') != NULL) { |
|
2287 glob_t gl; |
|
2288 #ifdef __linux__ |
|
2289 /* see popen.c */ |
|
2290 int flags = GLOB_NOCHECK; |
|
2291 #else |
|
2292 int flags = |
|
2293 GLOB_BRACE|GLOB_NOCHECK|GLOB_QUOTE|GLOB_TILDE; |
|
2294 #endif |
|
2295 char *pptr = (yyvsp[0].s); |
|
2296 |
|
2297 /* |
|
2298 * glob() will only find a leading ~, but |
|
2299 * Netscape kindly puts a slash in front of |
|
2300 * it for publish URLs. There needs to be |
|
2301 * a flag for glob() that expands tildes |
|
2302 * anywhere in the string. |
|
2303 */ |
|
2304 if ((pptr[0] == '/') && (pptr[1] == '~')) |
|
2305 pptr++; |
|
2306 |
|
2307 memset(&gl, 0, sizeof(gl)); |
|
2308 if (glob(pptr, flags, NULL, &gl) || |
|
2309 gl.gl_pathc == 0) { |
|
2310 reply(550, "not found"); |
|
2311 (yyval.s) = NULL; |
|
2312 } else { |
|
2313 (yyval.s) = strdup(gl.gl_pathv[0]); |
|
2314 } |
|
2315 globfree(&gl); |
|
2316 free((yyvsp[0].s)); |
|
2317 } else |
|
2318 (yyval.s) = (yyvsp[0].s); |
|
2319 } |
|
2320 break; |
|
2321 |
|
2322 case 74: |
|
2323 #line 784 "ftpcmd.y" |
|
2324 { |
|
2325 int ret, dec, multby, digit; |
|
2326 |
|
2327 /* |
|
2328 * Convert a number that was read as decimal number |
|
2329 * to what it would be if it had been read as octal. |
|
2330 */ |
|
2331 dec = (yyvsp[0].i); |
|
2332 multby = 1; |
|
2333 ret = 0; |
|
2334 while (dec) { |
|
2335 digit = dec%10; |
|
2336 if (digit > 7) { |
|
2337 ret = -1; |
|
2338 break; |
|
2339 } |
|
2340 ret += digit * multby; |
|
2341 multby *= 8; |
|
2342 dec /= 10; |
|
2343 } |
|
2344 (yyval.i) = ret; |
|
2345 } |
|
2346 break; |
|
2347 |
|
2348 case 75: |
|
2349 #line 811 "ftpcmd.y" |
|
2350 { |
|
2351 if (logged_in) |
|
2352 (yyval.i) = 1; |
|
2353 else { |
|
2354 reply(530, "Please login with USER and PASS."); |
|
2355 (yyval.i) = 0; |
|
2356 } |
|
2357 } |
|
2358 break; |
|
2359 |
|
2360 |
|
2361 default: break; |
|
2362 } |
|
2363 |
|
2364 /* Line 1126 of yacc.c. */ |
|
2365 |
|
2366 yyvsp -= yylen; |
|
2367 yyssp -= yylen; |
|
2368 |
|
2369 |
|
2370 YY_STACK_PRINT (yyss, yyssp); |
|
2371 |
|
2372 *++yyvsp = yyval; |
|
2373 |
|
2374 |
|
2375 /* Now `shift' the result of the reduction. Determine what state |
|
2376 that goes to, based on the state we popped back to and the rule |
|
2377 number reduced by. */ |
|
2378 |
|
2379 yyn = yyr1[yyn]; |
|
2380 |
|
2381 yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; |
|
2382 if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) |
|
2383 yystate = yytable[yystate]; |
|
2384 else |
|
2385 yystate = yydefgoto[yyn - YYNTOKENS]; |
|
2386 |
|
2387 goto yynewstate; |
|
2388 |
|
2389 |
|
2390 /*------------------------------------. |
|
2391 | yyerrlab -- here on detecting error | |
|
2392 `------------------------------------*/ |
|
2393 yyerrlab: |
|
2394 /* If not already recovering from an error, report this error. */ |
|
2395 if (!yyerrstatus) |
|
2396 { |
|
2397 ++yynerrs; |
|
2398 #if YYERROR_VERBOSE |
|
2399 yyn = yypact[yystate]; |
|
2400 |
|
2401 if (YYPACT_NINF < yyn && yyn < YYLAST) |
|
2402 { |
|
2403 int yytype = YYTRANSLATE (yychar); |
|
2404 YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]); |
|
2405 YYSIZE_T yysize = yysize0; |
|
2406 YYSIZE_T yysize1; |
|
2407 int yysize_overflow = 0; |
|
2408 char *yymsg = 0; |
|
2409 # define YYERROR_VERBOSE_ARGS_MAXIMUM 5 |
|
2410 char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; |
|
2411 int yyx; |
|
2412 |
|
2413 #if 0 |
|
2414 /* This is so xgettext sees the translatable formats that are |
|
2415 constructed on the fly. */ |
|
2416 YY_("syntax error, unexpected %s"); |
|
2417 YY_("syntax error, unexpected %s, expecting %s"); |
|
2418 YY_("syntax error, unexpected %s, expecting %s or %s"); |
|
2419 YY_("syntax error, unexpected %s, expecting %s or %s or %s"); |
|
2420 YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"); |
|
2421 #endif |
|
2422 char *yyfmt; |
|
2423 char const *yyf; |
|
2424 static char const yyunexpected[] = "syntax error, unexpected %s"; |
|
2425 static char const yyexpecting[] = ", expecting %s"; |
|
2426 static char const yyor[] = " or %s"; |
|
2427 char yyformat[sizeof yyunexpected |
|
2428 + sizeof yyexpecting - 1 |
|
2429 + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2) |
|
2430 * (sizeof yyor - 1))]; |
|
2431 char const *yyprefix = yyexpecting; |
|
2432 |
|
2433 /* Start YYX at -YYN if negative to avoid negative indexes in |
|
2434 YYCHECK. */ |
|
2435 int yyxbegin = yyn < 0 ? -yyn : 0; |
|
2436 |
|
2437 /* Stay within bounds of both yycheck and yytname. */ |
|
2438 int yychecklim = YYLAST - yyn; |
|
2439 int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; |
|
2440 int yycount = 1; |
|
2441 |
|
2442 yyarg[0] = yytname[yytype]; |
|
2443 yyfmt = yystpcpy (yyformat, yyunexpected); |
|
2444 |
|
2445 for (yyx = yyxbegin; yyx < yyxend; ++yyx) |
|
2446 if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) |
|
2447 { |
|
2448 if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) |
|
2449 { |
|
2450 yycount = 1; |
|
2451 yysize = yysize0; |
|
2452 yyformat[sizeof yyunexpected - 1] = '\0'; |
|
2453 break; |
|
2454 } |
|
2455 yyarg[yycount++] = yytname[yyx]; |
|
2456 yysize1 = yysize + yytnamerr (0, yytname[yyx]); |
|
2457 yysize_overflow |= yysize1 < yysize; |
|
2458 yysize = yysize1; |
|
2459 yyfmt = yystpcpy (yyfmt, yyprefix); |
|
2460 yyprefix = yyor; |
|
2461 } |
|
2462 |
|
2463 yyf = YY_(yyformat); |
|
2464 yysize1 = yysize + yystrlen (yyf); |
|
2465 yysize_overflow |= yysize1 < yysize; |
|
2466 yysize = yysize1; |
|
2467 |
|
2468 if (!yysize_overflow && yysize <= YYSTACK_ALLOC_MAXIMUM) |
|
2469 yymsg = (char *) YYSTACK_ALLOC (yysize); |
|
2470 if (yymsg) |
|
2471 { |
|
2472 /* Avoid sprintf, as that infringes on the user's name space. |
|
2473 Don't have undefined behavior even if the translation |
|
2474 produced a string with the wrong number of "%s"s. */ |
|
2475 char *yyp = yymsg; |
|
2476 int yyi = 0; |
|
2477 while ((*yyp = *yyf)) |
|
2478 { |
|
2479 if (*yyp == '%' && yyf[1] == 's' && yyi < yycount) |
|
2480 { |
|
2481 yyp += yytnamerr (yyp, yyarg[yyi++]); |
|
2482 yyf += 2; |
|
2483 } |
|
2484 else |
|
2485 { |
|
2486 yyp++; |
|
2487 yyf++; |
|
2488 } |
|
2489 } |
|
2490 yyerror (yymsg); |
|
2491 YYSTACK_FREE (yymsg); |
|
2492 } |
|
2493 else |
|
2494 { |
|
2495 yyerror (YY_("syntax error")); |
|
2496 goto yyexhaustedlab; |
|
2497 } |
|
2498 } |
|
2499 else |
|
2500 #endif /* YYERROR_VERBOSE */ |
|
2501 yyerror (YY_("syntax error")); |
|
2502 } |
|
2503 |
|
2504 |
|
2505 |
|
2506 if (yyerrstatus == 3) |
|
2507 { |
|
2508 /* If just tried and failed to reuse look-ahead token after an |
|
2509 error, discard it. */ |
|
2510 |
|
2511 if (yychar <= YYEOF) |
|
2512 { |
|
2513 /* Return failure if at end of input. */ |
|
2514 if (yychar == YYEOF) |
|
2515 YYABORT; |
|
2516 } |
|
2517 else |
|
2518 { |
|
2519 yydestruct ("Error: discarding", yytoken, &yylval); |
|
2520 yychar = YYEMPTY; |
|
2521 } |
|
2522 } |
|
2523 |
|
2524 /* Else will try to reuse look-ahead token after shifting the error |
|
2525 token. */ |
|
2526 goto yyerrlab1; |
|
2527 |
|
2528 |
|
2529 /*---------------------------------------------------. |
|
2530 | yyerrorlab -- error raised explicitly by YYERROR. | |
|
2531 `---------------------------------------------------*/ |
|
2532 yyerrorlab: |
|
2533 |
|
2534 /* Pacify compilers like GCC when the user code never invokes |
|
2535 YYERROR and the label yyerrorlab therefore never appears in user |
|
2536 code. */ |
|
2537 if (0) |
|
2538 goto yyerrorlab; |
|
2539 |
|
2540 yyvsp -= yylen; |
|
2541 yyssp -= yylen; |
|
2542 yystate = *yyssp; |
|
2543 goto yyerrlab1; |
|
2544 |
|
2545 |
|
2546 /*-------------------------------------------------------------. |
|
2547 | yyerrlab1 -- common code for both syntax error and YYERROR. | |
|
2548 `-------------------------------------------------------------*/ |
|
2549 yyerrlab1: |
|
2550 yyerrstatus = 3; /* Each real token shifted decrements this. */ |
|
2551 |
|
2552 for (;;) |
|
2553 { |
|
2554 yyn = yypact[yystate]; |
|
2555 if (yyn != YYPACT_NINF) |
|
2556 { |
|
2557 yyn += YYTERROR; |
|
2558 if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) |
|
2559 { |
|
2560 yyn = yytable[yyn]; |
|
2561 if (0 < yyn) |
|
2562 break; |
|
2563 } |
|
2564 } |
|
2565 |
|
2566 /* Pop the current state because it cannot handle the error token. */ |
|
2567 if (yyssp == yyss) |
|
2568 YYABORT; |
|
2569 |
|
2570 |
|
2571 yydestruct ("Error: popping", yystos[yystate], yyvsp); |
|
2572 YYPOPSTACK; |
|
2573 yystate = *yyssp; |
|
2574 YY_STACK_PRINT (yyss, yyssp); |
|
2575 } |
|
2576 |
|
2577 if (yyn == YYFINAL) |
|
2578 YYACCEPT; |
|
2579 |
|
2580 *++yyvsp = yylval; |
|
2581 |
|
2582 |
|
2583 /* Shift the error token. */ |
|
2584 YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); |
|
2585 |
|
2586 yystate = yyn; |
|
2587 goto yynewstate; |
|
2588 |
|
2589 |
|
2590 /*-------------------------------------. |
|
2591 | yyacceptlab -- YYACCEPT comes here. | |
|
2592 `-------------------------------------*/ |
|
2593 yyacceptlab: |
|
2594 yyresult = 0; |
|
2595 goto yyreturn; |
|
2596 |
|
2597 /*-----------------------------------. |
|
2598 | yyabortlab -- YYABORT comes here. | |
|
2599 `-----------------------------------*/ |
|
2600 yyabortlab: |
|
2601 yyresult = 1; |
|
2602 goto yyreturn; |
|
2603 |
|
2604 #ifndef yyoverflow |
|
2605 /*-------------------------------------------------. |
|
2606 | yyexhaustedlab -- memory exhaustion comes here. | |
|
2607 `-------------------------------------------------*/ |
|
2608 yyexhaustedlab: |
|
2609 yyerror (YY_("memory exhausted")); |
|
2610 yyresult = 2; |
|
2611 /* Fall through. */ |
|
2612 #endif |
|
2613 |
|
2614 yyreturn: |
|
2615 if (yychar != YYEOF && yychar != YYEMPTY) |
|
2616 yydestruct ("Cleanup: discarding lookahead", |
|
2617 yytoken, &yylval); |
|
2618 while (yyssp != yyss) |
|
2619 { |
|
2620 yydestruct ("Cleanup: popping", |
|
2621 yystos[*yyssp], yyvsp); |
|
2622 YYPOPSTACK; |
|
2623 } |
|
2624 #ifndef yyoverflow |
|
2625 if (yyss != yyssa) |
|
2626 YYSTACK_FREE (yyss); |
|
2627 #endif |
|
2628 return yyresult; |
|
2629 } |
|
2630 |
|
2631 |
|
2632 #line 821 "ftpcmd.y" |
|
2633 |
|
2634 |
|
2635 extern jmp_buf errcatch; |
|
2636 |
|
2637 |
|
2638 |
|
2639 |
|
2640 |
|
2641 //static void help __P((struct tab *, char *)); |
|
2642 static struct tab * |
|
2643 lookup __P((struct tab *, char *)); |
|
2644 //static void sizecmd __P((char *)); |
|
2645 static int yylex __P((void)); |
|
2646 |
|
2647 static struct tab *lookup(struct tab *p, char *cmd) |
|
2648 { |
|
2649 |
|
2650 for (; p->name != NULL; p++) |
|
2651 if (strcmp(cmd, p->name) == 0) |
|
2652 return (p); |
|
2653 return (0); |
|
2654 } |
|
2655 |
|
2656 #include <arpa/telnet.h> |
|
2657 |
|
2658 /* |
|
2659 * getline - a hacked up version of fgets to ignore TELNET escape codes. |
|
2660 */ |
|
2661 char * ftpd_getline(char *s, int n, FILE *iop) |
|
2662 { |
|
2663 int c; |
|
2664 register char *cs; |
|
2665 |
|
2666 cs = s; |
|
2667 /* tmpline may contain saved command from urgent mode interruption */ |
|
2668 for (c = 0; tmpline[c] != '\0' && --n > 0; ++c) { |
|
2669 *cs++ = tmpline[c]; |
|
2670 if (tmpline[c] == '\n') { |
|
2671 *cs++ = '\0'; |
|
2672 // if (debug) |
|
2673 // syslog(LOG_DEBUG, "command: %s", s); |
|
2674 tmpline[0] = '\0'; |
|
2675 return(s); |
|
2676 } |
|
2677 if (c == 0) |
|
2678 tmpline[0] = '\0'; |
|
2679 } |
|
2680 while ((c = getc(iop)) != EOF) { |
|
2681 c &= 0377; |
|
2682 if (c == IAC) { |
|
2683 if ((c = getc(iop)) != EOF) { |
|
2684 c &= 0377; |
|
2685 switch (c) { |
|
2686 case WILL: |
|
2687 case WONT: |
|
2688 c = getc(iop); |
|
2689 printf("%c%c%c", IAC, DONT, 0377&c); |
|
2690 (void) fflush(stdout); |
|
2691 continue; |
|
2692 case DO: |
|
2693 case DONT: |
|
2694 c = getc(iop); |
|
2695 printf("%c%c%c", IAC, WONT, 0377&c); |
|
2696 (void) fflush(stdout); |
|
2697 continue; |
|
2698 case IAC: |
|
2699 break; |
|
2700 default: |
|
2701 continue; /* ignore command */ |
|
2702 } |
|
2703 } |
|
2704 } |
|
2705 *cs++ = c; |
|
2706 if (--n <= 0 || c == '\n') |
|
2707 break; |
|
2708 } |
|
2709 if (c == EOF && cs == s) |
|
2710 return (NULL); |
|
2711 *cs++ = '\0'; |
|
2712 if (debug) { |
|
2713 if (!guest && strncasecmp("pass ", s, 5) == 0) { |
|
2714 /* Don't syslog passwords */ |
|
2715 //syslog(LOG_DEBUG, "command: %.5s ???", s); |
|
2716 } else { |
|
2717 register char *cp; |
|
2718 register int len; |
|
2719 |
|
2720 /* Don't syslog trailing CR-LF */ |
|
2721 len = strlen(s); |
|
2722 cp = s + len - 1; |
|
2723 while (cp >= s && (*cp == '\n' || *cp == '\r')) { |
|
2724 --cp; |
|
2725 --len; |
|
2726 } |
|
2727 //syslog(LOG_DEBUG, "command: %.*s", len, s); |
|
2728 } |
|
2729 } |
|
2730 return (s); |
|
2731 } |
|
2732 |
|
2733 void toolong(int signo) |
|
2734 { |
|
2735 (void)signo; |
|
2736 |
|
2737 reply(421, |
|
2738 "Timeout (%d seconds): closing control connection.", timeout); |
|
2739 // if (logging) |
|
2740 // syslog(LOG_INFO, "User %s timed out after %d seconds", |
|
2741 // (pw ? pw -> pw_name : "unknown"), timeout); |
|
2742 dologout(1); |
|
2743 } |
|
2744 |
|
2745 static int yylex(void) |
|
2746 { |
|
2747 static int cpos, state; |
|
2748 char *cp, *cp2; |
|
2749 struct tab *p; |
|
2750 int n, value; |
|
2751 char c; |
|
2752 |
|
2753 for (;;) { |
|
2754 switch (state) { |
|
2755 |
|
2756 case CMD: |
|
2757 //(void) signal(SIGALRM, toolong); |
|
2758 //(void) alarm((unsigned) timeout); |
|
2759 if (ftpd_getline(cbuf, sizeof(cbuf)-1, stdin)==NULL) { |
|
2760 reply(221, "You could at least say goodbye."); |
|
2761 dologout(0); |
|
2762 } |
|
2763 //(void) alarm(0); |
|
2764 cp = strchr(cbuf, '\r'); |
|
2765 if (cp) { |
|
2766 *cp++ = '\n'; |
|
2767 *cp = '\0'; |
|
2768 } |
|
2769 #ifdef HASSETPROCTITLE |
|
2770 if (strncasecmp(cbuf, "PASS", 4) != 0) { |
|
2771 cp = strpbrk(cbuf, "\n"); |
|
2772 if (cp) { |
|
2773 c = *cp; |
|
2774 *cp = '\0'; |
|
2775 setproctitle("%s: %s", proctitle, cbuf); |
|
2776 *cp = c; |
|
2777 } |
|
2778 } |
|
2779 #endif /* HASSETPROCTITLE */ |
|
2780 cp = strpbrk(cbuf, " \n"); |
|
2781 if (cp) |
|
2782 cpos = cp - cbuf; |
|
2783 if (cpos == 0) |
|
2784 cpos = 4; |
|
2785 c = cbuf[cpos]; |
|
2786 cbuf[cpos] = '\0'; |
|
2787 upper(cbuf); |
|
2788 p = lookup(cmdtab, cbuf); |
|
2789 cbuf[cpos] = c; |
|
2790 if (p != 0) { |
|
2791 if (p->implemented == 0) { |
|
2792 nack(p->name); |
|
2793 longjmp(errcatch,0); |
|
2794 /* NOTREACHED */ |
|
2795 } |
|
2796 state = p->state; |
|
2797 yylval.s = (char *)p->name; /* XXX */ |
|
2798 return (p->token); |
|
2799 } |
|
2800 break; |
|
2801 |
|
2802 case SITECMD: |
|
2803 if (cbuf[cpos] == ' ') { |
|
2804 cpos++; |
|
2805 return (SP); |
|
2806 } |
|
2807 cp = &cbuf[cpos]; |
|
2808 cp2 = strpbrk(cp, " \n"); |
|
2809 if (cp2) |
|
2810 cpos = cp2 - cbuf; |
|
2811 c = cbuf[cpos]; |
|
2812 cbuf[cpos] = '\0'; |
|
2813 upper(cp); |
|
2814 p = lookup(sitetab, cp); |
|
2815 cbuf[cpos] = c; |
|
2816 if (p != 0) { |
|
2817 if (p->implemented == 0) { |
|
2818 state = CMD; |
|
2819 nack(p->name); |
|
2820 longjmp(errcatch,0); |
|
2821 /* NOTREACHED */ |
|
2822 } |
|
2823 state = p->state; |
|
2824 yylval.s = (char *) p->name; /* XXX */ |
|
2825 return (p->token); |
|
2826 } |
|
2827 state = CMD; |
|
2828 break; |
|
2829 |
|
2830 case OSTR: |
|
2831 if (cbuf[cpos] == '\n') { |
|
2832 state = CMD; |
|
2833 return (CRLF); |
|
2834 } |
|
2835 /* FALLTHROUGH */ |
|
2836 |
|
2837 case STR1: |
|
2838 case ZSTR1: |
|
2839 dostr1: |
|
2840 if (cbuf[cpos] == ' ') { |
|
2841 cpos++; |
|
2842 /* DOH!!! who wrote this? |
|
2843 * state = ++state; is undefined in C! |
|
2844 * state = state == OSTR ? STR2 : ++state; |
|
2845 * looks elegant but not correct, adding 'value' |
|
2846 */ |
|
2847 value = state == OSTR ? STR2 : ++state; |
|
2848 state = value; |
|
2849 return (SP); |
|
2850 } |
|
2851 break; |
|
2852 |
|
2853 case ZSTR2: |
|
2854 if (cbuf[cpos] == '\n') { |
|
2855 state = CMD; |
|
2856 return (CRLF); |
|
2857 } |
|
2858 /* FALLTHROUGH */ |
|
2859 |
|
2860 case STR2: |
|
2861 cp = &cbuf[cpos]; |
|
2862 n = strlen(cp); |
|
2863 cpos += n - 1; |
|
2864 /* |
|
2865 * Make sure the string is nonempty and \n terminated. |
|
2866 */ |
|
2867 if (n > 1 && cbuf[cpos] == '\n') { |
|
2868 cbuf[cpos] = '\0'; |
|
2869 yylval.s = strdup(cp); |
|
2870 if (yylval.s == NULL) |
|
2871 fatal("Ran out of memory."); |
|
2872 cbuf[cpos] = '\n'; |
|
2873 state = ARGS; |
|
2874 return (STRING); |
|
2875 } |
|
2876 break; |
|
2877 |
|
2878 case NSTR: |
|
2879 if (cbuf[cpos] == ' ') { |
|
2880 cpos++; |
|
2881 return (SP); |
|
2882 } |
|
2883 if (isdigit(cbuf[cpos])) { |
|
2884 cp = &cbuf[cpos]; |
|
2885 while (isdigit(cbuf[++cpos])) |
|
2886 ; |
|
2887 c = cbuf[cpos]; |
|
2888 cbuf[cpos] = '\0'; |
|
2889 yylval.i = atoi(cp); |
|
2890 cbuf[cpos] = c; |
|
2891 state = STR1; |
|
2892 return (NUMBER); |
|
2893 } |
|
2894 state = STR1; |
|
2895 goto dostr1; |
|
2896 |
|
2897 case ARGS: |
|
2898 if (isdigit(cbuf[cpos])) { |
|
2899 cp = &cbuf[cpos]; |
|
2900 while (isdigit(cbuf[++cpos])) |
|
2901 ; |
|
2902 c = cbuf[cpos]; |
|
2903 cbuf[cpos] = '\0'; |
|
2904 yylval.i = atoi(cp); |
|
2905 cbuf[cpos] = c; |
|
2906 return (NUMBER); |
|
2907 } |
|
2908 switch (cbuf[cpos++]) { |
|
2909 |
|
2910 case '\n': |
|
2911 state = CMD; |
|
2912 return (CRLF); |
|
2913 |
|
2914 case ' ': |
|
2915 return (SP); |
|
2916 |
|
2917 case ',': |
|
2918 return (COMMA); |
|
2919 |
|
2920 case 'A': |
|
2921 case 'a': |
|
2922 return (A); |
|
2923 |
|
2924 case 'B': |
|
2925 case 'b': |
|
2926 return (B); |
|
2927 |
|
2928 case 'C': |
|
2929 case 'c': |
|
2930 return (C); |
|
2931 |
|
2932 case 'E': |
|
2933 case 'e': |
|
2934 return (E); |
|
2935 |
|
2936 case 'F': |
|
2937 case 'f': |
|
2938 return (F); |
|
2939 |
|
2940 case 'I': |
|
2941 case 'i': |
|
2942 return (I); |
|
2943 |
|
2944 case 'L': |
|
2945 case 'l': |
|
2946 return (L); |
|
2947 |
|
2948 case 'N': |
|
2949 case 'n': |
|
2950 return (N); |
|
2951 |
|
2952 case 'P': |
|
2953 case 'p': |
|
2954 return (P); |
|
2955 |
|
2956 case 'R': |
|
2957 case 'r': |
|
2958 return (R); |
|
2959 |
|
2960 case 'S': |
|
2961 case 's': |
|
2962 return (S); |
|
2963 |
|
2964 case 'T': |
|
2965 case 't': |
|
2966 return (T); |
|
2967 |
|
2968 } |
|
2969 break; |
|
2970 |
|
2971 default: |
|
2972 fatal("Unknown state in scanner."); |
|
2973 } |
|
2974 yyerror((char *) 0); |
|
2975 state = CMD; |
|
2976 longjmp(errcatch,0); |
|
2977 } |
|
2978 } |
|
2979 |
|
2980 void upper(char *s) |
|
2981 { |
|
2982 while (*s != '\0') { |
|
2983 if (islower(*s)) |
|
2984 *s = toupper(*s); |
|
2985 s++; |
|
2986 } |
|
2987 } |
|
2988 |
|
2989 |
|
2990 static void help(struct tab *ctab, char *s) |
|
2991 { |
|
2992 struct tab *c; |
|
2993 int width, NCMDS; |
|
2994 const char *type; |
|
2995 |
|
2996 if (ctab == sitetab) |
|
2997 type = "SITE "; |
|
2998 else |
|
2999 type = ""; |
|
3000 width = 0, NCMDS = 0; |
|
3001 for (c = ctab; c->name != NULL; c++) { |
|
3002 int len = strlen(c->name); |
|
3003 |
|
3004 if (len > width) |
|
3005 width = len; |
|
3006 NCMDS++; |
|
3007 } |
|
3008 width = (width + 8) &~ 7; |
|
3009 if (s == 0) { |
|
3010 int i, j, w; |
|
3011 int columns, lines; |
|
3012 |
|
3013 lreply(214, "The following %scommands are recognized %s.", |
|
3014 type, "(* =>'s unimplemented)"); |
|
3015 columns = 76 / width; |
|
3016 if (columns == 0) |
|
3017 columns = 1; |
|
3018 lines = (NCMDS + columns - 1) / columns; |
|
3019 for (i = 0; i < lines; i++) { |
|
3020 printf(" "); |
|
3021 for (j = 0; j < columns; j++) { |
|
3022 c = ctab + j * lines + i; |
|
3023 printf("%s%c", c->name, |
|
3024 c->implemented ? ' ' : '*'); |
|
3025 if (c + lines >= &ctab[NCMDS]) |
|
3026 break; |
|
3027 w = strlen(c->name) + 1; |
|
3028 while (w < width) { |
|
3029 putchar(' '); |
|
3030 w++; |
|
3031 } |
|
3032 } |
|
3033 printf("\r\n"); |
|
3034 } |
|
3035 (void) fflush(stdout); |
|
3036 reply(214, "Direct comments to ftp-bugs@%s.", hostname); |
|
3037 return; |
|
3038 } |
|
3039 upper(s); |
|
3040 c = lookup(ctab, s); |
|
3041 if (c == (struct tab *)0) { |
|
3042 reply(502, "Unknown command %s.", s); |
|
3043 return; |
|
3044 } |
|
3045 if (c->implemented) |
|
3046 reply(214, "Syntax: %s%s %s", type, c->name, c->help); |
|
3047 else |
|
3048 reply(214, "%s%-*s\t%s; unimplemented.", type, width, |
|
3049 c->name, c->help); |
|
3050 } |
|
3051 |