genericunixprotocols/ftpsrv/src/ftpcmd.cpp
changeset 0 c6b0df440bee
equal deleted inserted replaced
-1:000000000000 0:c6b0df440bee
       
     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