GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: libexec/ftpd/ftpcmd.c Lines: 0 463 0.0 %
Date: 2017-11-07 Branches: 0 554 0.0 %

Line Branch Exec Source
1
#include <stdlib.h>
2
#include <string.h>
3
#define YYBYACC 1
4
#define YYMAJOR 1
5
#define YYMINOR 9
6
#define YYLEX yylex()
7
#define YYEMPTY -1
8
#define yyclearin (yychar=(YYEMPTY))
9
#define yyerrok (yyerrflag=0)
10
#define YYRECOVERING() (yyerrflag!=0)
11
#define YYPREFIX "yy"
12
#line 41 "ftpcmd.y"
13
14
#include <sys/types.h>
15
#include <sys/socket.h>
16
#include <sys/stat.h>
17
18
#include <netinet/in.h>
19
#include <arpa/ftp.h>
20
21
#include <ctype.h>
22
#include <errno.h>
23
#include <glob.h>
24
#include <pwd.h>
25
#include <signal.h>
26
#include <stdio.h>
27
#include <stdlib.h>
28
#include <string.h>
29
#include <syslog.h>
30
#include <time.h>
31
#include <unistd.h>
32
#include <netdb.h>
33
#include <limits.h>
34
35
#include "monitor.h"
36
#include "extern.h"
37
38
extern	union sockunion data_dest;
39
extern	int logged_in;
40
extern	struct passwd *pw;
41
extern	int guest;
42
extern	int logging;
43
extern	int type;
44
extern	int form;
45
extern	int debug;
46
extern	int timeout;
47
extern	int maxtimeout;
48
extern  int pdata;
49
extern	char hostname[], remotehost[];
50
extern	char proctitle[];
51
extern	int usedefault;
52
extern  int transflag;
53
extern  char tmpline[];
54
extern	int portcheck;
55
extern	union sockunion his_addr;
56
extern	int umaskchange;
57
58
off_t	restart_point;
59
60
static	int cmd_type;
61
static	int cmd_form;
62
static	int cmd_bytesz;
63
static	int state;
64
static	int quit;
65
char	cbuf[512];
66
char	*fromname;
67
68
#line 98 "ftpcmd.y"
69
#ifndef YYSTYPE_DEFINED
70
#define YYSTYPE_DEFINED
71
typedef union {
72
	int	i;
73
	off_t	o;
74
	char   *s;
75
} YYSTYPE;
76
#endif /* YYSTYPE_DEFINED */
77
#line 78 "ftpcmd.c"
78
#define A 257
79
#define B 258
80
#define C 259
81
#define E 260
82
#define F 261
83
#define I 262
84
#define L 263
85
#define N 264
86
#define P 265
87
#define R 266
88
#define S 267
89
#define T 268
90
#define SP 269
91
#define CRLF 270
92
#define COMMA 271
93
#define ALL 272
94
#define USER 273
95
#define PASS 274
96
#define ACCT 275
97
#define REIN 276
98
#define QUIT 277
99
#define PORT 278
100
#define PASV 279
101
#define TYPE 280
102
#define STRU 281
103
#define MODE 282
104
#define RETR 283
105
#define STOR 284
106
#define APPE 285
107
#define MLFL 286
108
#define MAIL 287
109
#define MSND 288
110
#define MSOM 289
111
#define MSAM 290
112
#define MRSQ 291
113
#define MRCP 292
114
#define ALLO 293
115
#define REST 294
116
#define RNFR 295
117
#define RNTO 296
118
#define ABOR 297
119
#define DELE 298
120
#define CWD 299
121
#define LIST 300
122
#define NLST 301
123
#define SITE 302
124
#define STAT 303
125
#define HELP 304
126
#define NOOP 305
127
#define MKD 306
128
#define RMD 307
129
#define PWD 308
130
#define CDUP 309
131
#define STOU 310
132
#define SMNT 311
133
#define SYST 312
134
#define SIZE 313
135
#define MDTM 314
136
#define LPRT 315
137
#define LPSV 316
138
#define EPRT 317
139
#define EPSV 318
140
#define UMASK 319
141
#define IDLE 320
142
#define CHMOD 321
143
#define LEXERR 322
144
#define STRING 323
145
#define NUMBER 324
146
#define BIGNUM 325
147
#define YYERRCODE 256
148
const short yylhs[] =
149
	{                                        -1,
150
    0,    0,    0,   17,   17,   17,   17,   17,   17,   17,
151
   17,   17,   17,   17,   17,   17,   17,   17,   17,   17,
152
   17,   17,   17,   17,   17,   17,   17,   17,   17,   17,
153
   17,   17,   17,   17,   17,   17,   17,   17,   17,   17,
154
   17,   17,   17,   17,   17,   17,   17,   17,   17,   17,
155
   17,   17,   17,   18,   18,   16,   15,   15,    4,   12,
156
   12,    9,   10,   11,    8,    8,    8,    7,    7,    7,
157
    7,    7,    7,    7,    7,    5,    5,    5,    6,    6,
158
    6,   14,   13,    3,    1,    2,
159
};
160
const short yylen[] =
161
	{                                         2,
162
    0,    2,    2,    4,    4,    5,    5,    5,    5,    3,
163
    3,    5,    5,    3,    5,    5,    5,    5,    9,    5,
164
    5,    5,    3,    5,    3,    5,    5,    3,    5,    5,
165
    3,    3,    5,    2,    4,    2,    5,    5,    3,    3,
166
    4,    6,    5,    7,    9,    5,    7,    5,    3,    5,
167
    5,    2,    1,    5,    5,    1,    0,    1,    1,    1,
168
    1,   11,   17,   41,    1,    1,    1,    1,    3,    1,
169
    3,    1,    1,    3,    2,    1,    1,    1,    1,    1,
170
    1,    1,    1,    1,    0,    0,
171
};
172
const short yydefred[] =
173
	{                                      1,
174
    0,   53,    0,    0,    0,   86,   86,   85,   85,   85,
175
   85,   85,   85,   85,   85,   85,   85,   85,   85,   85,
176
   85,   85,    0,   85,    0,    0,   85,   85,   85,   85,
177
   85,   85,   85,   85,   86,   86,   86,   85,    2,    3,
178
    0,    0,   52,    0,    0,    0,    0,    0,    0,    0,
179
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
180
    0,    0,    0,   34,   36,    0,    0,    0,    0,    0,
181
    0,    0,    0,    0,    0,    0,    0,   56,    0,   58,
182
    0,    0,   10,    0,    0,    0,    0,    0,    0,    0,
183
    0,    0,    0,   31,    0,    0,   32,    0,   25,    0,
184
   23,    0,   85,   85,    0,    0,   28,    0,    0,    0,
185
   39,   40,    0,   49,    0,    0,    0,   11,    0,    0,
186
   14,    4,    5,    0,    0,    0,    0,   72,    0,    0,
187
   76,   78,   77,    0,   80,   81,   79,    0,   83,   82,
188
    0,    0,    0,    0,   60,   61,    0,    0,    0,    0,
189
    0,    0,    0,    0,   41,    0,    0,    0,    0,   35,
190
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
191
    0,    0,    6,    0,    0,    0,   59,   75,   15,   16,
192
   17,   20,   21,   22,    0,   18,   55,   54,   30,   29,
193
   33,   26,   24,    0,    0,   43,    0,    0,   46,   27,
194
   37,   38,   48,   50,   51,    0,    7,    8,    9,   13,
195
   12,    0,   67,   65,   66,   69,   71,   74,    0,   42,
196
   84,    0,    0,    0,    0,    0,    0,   44,    0,   47,
197
    0,    0,    0,    0,    0,    0,   19,   45,    0,    0,
198
    0,    0,    0,    0,    0,    0,    0,   62,    0,    0,
199
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
200
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
201
    0,    0,    0,    0,    0,    0,    0,    0,   64,
202
};
203
const short yydgoto[] =
204
	{                                       1,
205
   46,   44,  222,  178,  134,  138,  130,  216,  125,  167,
206
  168,  147,  140,  141,   81,   79,   39,   40,
207
};
208
const short yysindex[] =
209
	{                                      0,
210
 -211,    0, -263, -256, -253,    0,    0,    0,    0,    0,
211
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
212
    0,    0, -226,    0, -254, -224,    0,    0,    0,    0,
213
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
214
 -264, -244,    0, -169, -155, -147, -136, -135, -134, -133,
215
 -132, -131, -130, -129, -127, -126, -124, -194, -192, -157,
216
 -295, -151, -180,    0,    0, -123, -122, -121, -120, -118,
217
 -117, -115, -114, -113, -112, -110, -149,    0, -109,    0,
218
 -108, -176,    0, -146, -205, -247, -171, -171, -171, -167,
219
 -260, -171, -171,    0, -171, -171,    0, -171,    0, -163,
220
    0, -144,    0,    0, -156, -171,    0, -107, -171, -171,
221
    0,    0, -171,    0, -171, -171, -159,    0, -154, -269,
222
    0,    0,    0, -105, -103, -101,  -99,    0, -267,  -98,
223
    0,    0,    0,  -97,    0,    0,    0,  -96,    0,    0,
224
  -95,  -94,  -93, -142,    0,    0,  -92,  -91,  -90,  -89,
225
  -87,  -86,  -85, -152,    0, -140,  -83, -138,  -82,    0,
226
  -81,  -80,  -79,  -78,  -77,  -84,  -76,  -75,  -74,  -73,
227
  -72, -125,    0, -245, -245, -119,    0,    0,    0,    0,
228
    0,    0,    0,    0,  -66,    0,    0,    0,    0,    0,
229
    0,    0,    0,  -69, -116,    0, -116, -111,    0,    0,
230
    0,    0,    0,    0,    0, -106,    0,    0,    0,    0,
231
    0,  -68,    0,    0,    0,    0,    0,    0,  -67,    0,
232
    0,  -64,  -65,  -63,  -62, -104, -102,    0, -171,    0,
233
 -100,  -61,  -59,  -58,  -57,  -71,    0,    0,  -70,  -56,
234
  -55,  -60,  -54,  -52,  -50,  -53,  -51,    0,  -48,  -49,
235
  -46,  -47,  -45,  -44,  -43,  -42,  -41,  -40,  -39,  -38,
236
  -37,  -36,  -35,  -34,  -33,  -32,  -31,  -30,  -29,  -28,
237
  -27,  -26,  -25,  -24,  -23,  -22,  -21,  -20,    0,};
238
const short yyrindex[] =
239
	{                                      0,
240
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
241
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
242
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
243
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
244
    0,  -19,    0,    0,    0,    0,    0,    0,    0,    0,
245
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
246
  -17,    0,    0,    0,    0,    0,    0,    0,    0,    0,
247
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
248
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
249
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
250
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
251
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
252
    0,    0,    0,    0,    0,  -18,  -15,    0,  -14,    0,
253
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
254
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
255
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
256
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
257
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
258
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
259
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
260
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
261
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
262
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
263
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
264
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
265
    0,    0,    0,    0,  -13,    0,    0,    0,    0,    0,
266
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
267
    0,    0,    0,    0,    0,    0,    0,    0,    0,};
268
const short yygindex[] =
269
	{                                      0,
270
   20,   73,   30,    6,    0,    0,    0,   42,    0,    0,
271
    0,    0,    0,  -88,    0,    0,    0,    0,
272
};
273
#define YYTABLESIZE 304
274
const short yytable[] =
275
	{                                     142,
276
  143,  176,  170,  148,  149,   41,  150,  151,  102,  152,
277
  135,  136,   42,  213,   63,   64,   43,  159,  214,  137,
278
  161,  162,  215,  103,  163,  104,  164,  165,   47,   48,
279
   49,   50,   51,   52,   53,   54,   55,   56,   57,   58,
280
   59,   60,   61,   62,    2,   65,   66,   67,   68,   69,
281
   70,   71,   72,   73,  171,  131,  177,   77,   78,  132,
282
  133,    3,    4,  145,  146,    5,    6,    7,    8,    9,
283
   10,   11,   12,   13,   96,   97,   98,   99,   80,   45,
284
  105,   14,   15,   16,   17,   18,   19,   20,   21,   22,
285
   23,   24,   25,   26,   27,   28,   29,   30,   31,   82,
286
   32,   33,   34,   35,   36,   37,   38,   74,   75,   76,
287
  126,  100,  101,  127,   83,  128,  129,  106,  107,  120,
288
  121,   84,  156,  157,  154,  155,  185,  186,  195,  196,
289
  198,  199,   85,   86,   87,   88,   89,   90,   91,   92,
290
  234,   93,  108,   94,   95,  109,  110,  124,  111,  112,
291
  113,  139,  114,  115,  116,  117,  144,  118,  119,  153,
292
  122,  123,  160,  158,  166,  172,  173,  174,  169,  175,
293
  194,  179,  180,  181,  182,  183,  184,  187,  188,  189,
294
  190,  218,  191,  192,  193,  197,  206,  200,  201,  202,
295
  203,  204,  205,  207,  208,  209,  210,  211,  212,  219,
296
  220,  227,  226,  229,  177,  228,  230,  221,  231,  236,
297
  237,  238,  224,  239,  242,  243,  217,  225,  246,  232,
298
  247,  233,  250,  235,  252,  254,  223,  256,    0,  258,
299
    0,  260,    0,  262,    0,  264,    0,  266,    0,  268,
300
    0,  270,    0,  272,    0,  274,    0,  276,    0,  278,
301
   57,   68,  240,  241,   70,   73,   63,    0,    0,    0,
302
    0,    0,    0,  244,    0,    0,    0,    0,    0,  245,
303
  248,    0,  249,    0,  251,    0,  253,    0,    0,  255,
304
    0,  257,    0,  259,    0,  261,    0,  263,    0,  265,
305
    0,  267,    0,  269,    0,  271,    0,  273,    0,  275,
306
    0,  277,   85,  279,
307
};
308
const short yycheck[] =
309
	{                                      88,
310
   89,  269,  272,   92,   93,  269,   95,   96,  304,   98,
311
  258,  259,  269,  259,  269,  270,  270,  106,  264,  267,
312
  109,  110,  268,  319,  113,  321,  115,  116,    9,   10,
313
   11,   12,   13,   14,   15,   16,   17,   18,   19,   20,
314
   21,   22,  269,   24,  256,  270,   27,   28,   29,   30,
315
   31,   32,   33,   34,  324,  261,  324,   38,  323,  265,
316
  266,  273,  274,  324,  325,  277,  278,  279,  280,  281,
317
  282,  283,  284,  285,  269,  270,  269,  270,  323,    7,
318
   61,  293,  294,  295,  296,  297,  298,  299,  300,  301,
319
  302,  303,  304,  305,  306,  307,  308,  309,  310,  269,
320
  312,  313,  314,  315,  316,  317,  318,   35,   36,   37,
321
  257,  269,  270,  260,  270,  262,  263,  269,  270,  269,
322
  270,  269,  103,  104,  269,  270,  269,  270,  269,  270,
323
  269,  270,  269,  269,  269,  269,  269,  269,  269,  269,
324
  229,  269,  323,  270,  269,  269,  269,  324,  270,  270,
325
  269,  323,  270,  269,  269,  269,  324,  270,  269,  323,
326
  270,  270,  270,  320,  324,  271,  270,  269,  323,  269,
327
  323,  270,  270,  270,  270,  270,  270,  270,  270,  270,
328
  270,  176,  270,  270,  270,  269,  271,  270,  270,  270,
329
  270,  270,  270,  270,  270,  270,  270,  270,  324,  266,
330
  270,  269,  271,  269,  324,  270,  270,  324,  271,  271,
331
  270,  270,  324,  271,  271,  271,  175,  324,  271,  324,
332
  271,  324,  271,  324,  271,  271,  197,  271,   -1,  271,
333
   -1,  271,   -1,  271,   -1,  271,   -1,  271,   -1,  271,
334
   -1,  271,   -1,  271,   -1,  271,   -1,  271,   -1,  271,
335
  270,  270,  324,  324,  270,  270,  270,   -1,   -1,   -1,
336
   -1,   -1,   -1,  324,   -1,   -1,   -1,   -1,   -1,  324,
337
  324,   -1,  324,   -1,  324,   -1,  324,   -1,   -1,  324,
338
   -1,  324,   -1,  324,   -1,  324,   -1,  324,   -1,  324,
339
   -1,  324,   -1,  324,   -1,  324,   -1,  324,   -1,  324,
340
   -1,  324,  320,  324,
341
};
342
#define YYFINAL 1
343
#ifndef YYDEBUG
344
#define YYDEBUG 0
345
#endif
346
#define YYMAXTOKEN 325
347
#if YYDEBUG
348
const char * const yyname[] =
349
	{
350
"end-of-file",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
351
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
352
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
353
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
354
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
355
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
356
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"A","B","C","E","F","I","L","N",
357
"P","R","S","T","SP","CRLF","COMMA","ALL","USER","PASS","ACCT","REIN","QUIT",
358
"PORT","PASV","TYPE","STRU","MODE","RETR","STOR","APPE","MLFL","MAIL","MSND",
359
"MSOM","MSAM","MRSQ","MRCP","ALLO","REST","RNFR","RNTO","ABOR","DELE","CWD",
360
"LIST","NLST","SITE","STAT","HELP","NOOP","MKD","RMD","PWD","CDUP","STOU",
361
"SMNT","SYST","SIZE","MDTM","LPRT","LPSV","EPRT","EPSV","UMASK","IDLE","CHMOD",
362
"LEXERR","STRING","NUMBER","BIGNUM",
363
};
364
const char * const yyrule[] =
365
	{"$accept : cmd_list",
366
"cmd_list :",
367
"cmd_list : cmd_list cmd",
368
"cmd_list : cmd_list rcmd",
369
"cmd : USER SP username CRLF",
370
"cmd : PASS SP password CRLF",
371
"cmd : PORT check_login_epsvall SP host_port CRLF",
372
"cmd : LPRT check_login_epsvall SP host_long_port4 CRLF",
373
"cmd : LPRT check_login_epsvall SP host_long_port6 CRLF",
374
"cmd : EPRT check_login_epsvall SP STRING CRLF",
375
"cmd : PASV check_login_epsvall CRLF",
376
"cmd : LPSV check_login_epsvall CRLF",
377
"cmd : EPSV check_login SP NUMBER CRLF",
378
"cmd : EPSV check_login SP ALL CRLF",
379
"cmd : EPSV check_login CRLF",
380
"cmd : TYPE check_login SP type_code CRLF",
381
"cmd : STRU check_login SP struct_code CRLF",
382
"cmd : MODE check_login SP mode_code CRLF",
383
"cmd : ALLO check_login SP NUMBER CRLF",
384
"cmd : ALLO check_login SP NUMBER SP R SP NUMBER CRLF",
385
"cmd : RETR check_login SP pathname CRLF",
386
"cmd : STOR check_login SP pathname CRLF",
387
"cmd : APPE check_login SP pathname CRLF",
388
"cmd : NLST check_login CRLF",
389
"cmd : NLST check_login SP STRING CRLF",
390
"cmd : LIST check_login CRLF",
391
"cmd : LIST check_login SP pathname CRLF",
392
"cmd : STAT check_login SP pathname CRLF",
393
"cmd : STAT check_login CRLF",
394
"cmd : DELE check_login SP pathname CRLF",
395
"cmd : RNTO check_login SP pathname CRLF",
396
"cmd : ABOR check_login CRLF",
397
"cmd : CWD check_login CRLF",
398
"cmd : CWD check_login SP pathname CRLF",
399
"cmd : HELP CRLF",
400
"cmd : HELP SP STRING CRLF",
401
"cmd : NOOP CRLF",
402
"cmd : MKD check_login SP pathname CRLF",
403
"cmd : RMD check_login SP pathname CRLF",
404
"cmd : PWD check_login CRLF",
405
"cmd : CDUP check_login CRLF",
406
"cmd : SITE SP HELP CRLF",
407
"cmd : SITE SP HELP SP STRING CRLF",
408
"cmd : SITE SP UMASK check_login CRLF",
409
"cmd : SITE SP UMASK check_login SP octal_number CRLF",
410
"cmd : SITE SP CHMOD check_login SP octal_number SP pathname CRLF",
411
"cmd : SITE SP check_login IDLE CRLF",
412
"cmd : SITE SP check_login IDLE SP NUMBER CRLF",
413
"cmd : STOU check_login SP pathname CRLF",
414
"cmd : SYST check_login CRLF",
415
"cmd : SIZE check_login SP pathname CRLF",
416
"cmd : MDTM check_login SP pathname CRLF",
417
"cmd : QUIT CRLF",
418
"cmd : error",
419
"rcmd : RNFR check_login SP pathname CRLF",
420
"rcmd : REST check_login SP file_size CRLF",
421
"username : STRING",
422
"password :",
423
"password : STRING",
424
"byte_size : NUMBER",
425
"file_size : NUMBER",
426
"file_size : BIGNUM",
427
"host_port : NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER",
428
"host_long_port4 : NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER",
429
"host_long_port6 : NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER",
430
"form_code : N",
431
"form_code : T",
432
"form_code : C",
433
"type_code : A",
434
"type_code : A SP form_code",
435
"type_code : E",
436
"type_code : E SP form_code",
437
"type_code : I",
438
"type_code : L",
439
"type_code : L SP byte_size",
440
"type_code : L byte_size",
441
"struct_code : F",
442
"struct_code : R",
443
"struct_code : P",
444
"mode_code : S",
445
"mode_code : B",
446
"mode_code : C",
447
"pathname : pathstring",
448
"pathstring : STRING",
449
"octal_number : NUMBER",
450
"check_login :",
451
"check_login_epsvall :",
452
};
453
#endif
454
#ifdef YYSTACKSIZE
455
#undef YYMAXDEPTH
456
#define YYMAXDEPTH YYSTACKSIZE
457
#else
458
#ifdef YYMAXDEPTH
459
#define YYSTACKSIZE YYMAXDEPTH
460
#else
461
#define YYSTACKSIZE 10000
462
#define YYMAXDEPTH 10000
463
#endif
464
#endif
465
#define YYINITSTACKSIZE 200
466
/* LINTUSED */
467
int yydebug;
468
int yynerrs;
469
int yyerrflag;
470
int yychar;
471
short *yyssp;
472
YYSTYPE *yyvsp;
473
YYSTYPE yyval;
474
YYSTYPE yylval;
475
short *yyss;
476
short *yysslim;
477
YYSTYPE *yyvs;
478
unsigned int yystacksize;
479
int yyparse(void);
480
#line 984 "ftpcmd.y"
481
482
#define	CMD	0	/* beginning of command */
483
#define	ARGS	1	/* expect miscellaneous arguments */
484
#define	STR1	2	/* expect SP followed by STRING */
485
#define	STR2	3	/* expect STRING */
486
#define	OSTR	4	/* optional SP then STRING */
487
#define	ZSTR1	5	/* SP then optional STRING */
488
#define	ZSTR2	6	/* optional STRING after SP */
489
#define	SITECMD	7	/* SITE command */
490
#define	NSTR	8	/* Number followed by a string */
491
492
struct tab {
493
	char	*name;
494
	short	token;
495
	short	state;
496
	short	implemented;	/* 1 if command is implemented */
497
	char	*help;
498
};
499
500
struct tab cmdtab[] = {		/* In order defined in RFC 765 */
501
	{ "USER", USER, STR1, 1,	"<sp> username" },
502
	{ "PASS", PASS, ZSTR1, 1,	"<sp> password" },
503
	{ "ACCT", ACCT, STR1, 0,	"(specify account)" },
504
	{ "SMNT", SMNT, ARGS, 0,	"(structure mount)" },
505
	{ "REIN", REIN, ARGS, 0,	"(reinitialize server state)" },
506
	{ "QUIT", QUIT, ARGS, 1,	"(terminate service)", },
507
	{ "PORT", PORT, ARGS, 1,	"<sp> b0, b1, b2, b3, b4" },
508
	{ "LPRT", LPRT, ARGS, 1,	"<sp> af, hal, h1, h2, h3,..., pal, p1, p2..." },
509
	{ "EPRT", EPRT, STR1, 1,	"<sp> |af|addr|port|" },
510
	{ "PASV", PASV, ARGS, 1,	"(set server in passive mode)" },
511
	{ "LPSV", LPSV, ARGS, 1,	"(set server in passive mode)" },
512
	{ "EPSV", EPSV, ARGS, 1,	"[<sp> af|ALL]" },
513
	{ "TYPE", TYPE, ARGS, 1,	"<sp> [ A | E | I | L ]" },
514
	{ "STRU", STRU, ARGS, 1,	"(specify file structure)" },
515
	{ "MODE", MODE, ARGS, 1,	"(specify transfer mode)" },
516
	{ "RETR", RETR, STR1, 1,	"<sp> file-name" },
517
	{ "STOR", STOR, STR1, 1,	"<sp> file-name" },
518
	{ "APPE", APPE, STR1, 1,	"<sp> file-name" },
519
	{ "MLFL", MLFL, OSTR, 0,	"(mail file)" },
520
	{ "MAIL", MAIL, OSTR, 0,	"(mail to user)" },
521
	{ "MSND", MSND, OSTR, 0,	"(mail send to terminal)" },
522
	{ "MSOM", MSOM, OSTR, 0,	"(mail send to terminal or mailbox)" },
523
	{ "MSAM", MSAM, OSTR, 0,	"(mail send to terminal and mailbox)" },
524
	{ "MRSQ", MRSQ, OSTR, 0,	"(mail recipient scheme question)" },
525
	{ "MRCP", MRCP, STR1, 0,	"(mail recipient)" },
526
	{ "ALLO", ALLO, ARGS, 1,	"allocate storage (vacuously)" },
527
	{ "REST", REST, ARGS, 1,	"<sp> offset (restart command)" },
528
	{ "RNFR", RNFR, STR1, 1,	"<sp> file-name" },
529
	{ "RNTO", RNTO, STR1, 1,	"<sp> file-name" },
530
	{ "ABOR", ABOR, ARGS, 1,	"(abort operation)" },
531
	{ "DELE", DELE, STR1, 1,	"<sp> file-name" },
532
	{ "CWD",  CWD,  OSTR, 1,	"[ <sp> directory-name ]" },
533
	{ "XCWD", CWD,	OSTR, 1,	"[ <sp> directory-name ]" },
534
	{ "LIST", LIST, OSTR, 1,	"[ <sp> path-name ]" },
535
	{ "NLST", NLST, OSTR, 1,	"[ <sp> path-name ]" },
536
	{ "SITE", SITE, SITECMD, 1,	"site-cmd [ <sp> arguments ]" },
537
	{ "SYST", SYST, ARGS, 1,	"(get type of operating system)" },
538
	{ "STAT", STAT, OSTR, 1,	"[ <sp> path-name ]" },
539
	{ "HELP", HELP, OSTR, 1,	"[ <sp> <string> ]" },
540
	{ "NOOP", NOOP, ARGS, 1,	"" },
541
	{ "MKD",  MKD,  STR1, 1,	"<sp> path-name" },
542
	{ "XMKD", MKD,  STR1, 1,	"<sp> path-name" },
543
	{ "RMD",  RMD,  STR1, 1,	"<sp> path-name" },
544
	{ "XRMD", RMD,  STR1, 1,	"<sp> path-name" },
545
	{ "PWD",  PWD,  ARGS, 1,	"(return current directory)" },
546
	{ "XPWD", PWD,  ARGS, 1,	"(return current directory)" },
547
	{ "CDUP", CDUP, ARGS, 1,	"(change to parent directory)" },
548
	{ "XCUP", CDUP, ARGS, 1,	"(change to parent directory)" },
549
	{ "STOU", STOU, STR1, 1,	"<sp> file-name" },
550
	{ "SIZE", SIZE, OSTR, 1,	"<sp> path-name" },
551
	{ "MDTM", MDTM, OSTR, 1,	"<sp> path-name" },
552
	{ NULL,   0,    0,    0,	0 }
553
};
554
555
struct tab sitetab[] = {
556
	{ "UMASK", UMASK, ARGS, 1,	"[ <sp> umask ]" },
557
	{ "IDLE", IDLE, ARGS, 1,	"[ <sp> maximum-idle-time ]" },
558
	{ "CHMOD", CHMOD, NSTR, 1,	"<sp> mode <sp> file-name" },
559
	{ "HELP", HELP, OSTR, 1,	"[ <sp> <string> ]" },
560
	{ NULL,   0,    0,    0,	0 }
561
};
562
563
static void	 help(struct tab *, char *);
564
static struct tab *
565
		 lookup(struct tab *, char *);
566
static void	 sizecmd(char *);
567
static int	 yylex(void);
568
569
extern int epsvall;
570
571
static struct tab *
572
lookup(p, cmd)
573
	struct tab *p;
574
	char *cmd;
575
{
576
577
	for (; p->name != NULL; p++)
578
		if (strcmp(cmd, p->name) == 0)
579
			return (p);
580
	return (NULL);
581
}
582
583
#include <arpa/telnet.h>
584
585
/*
586
 * get_line - a hacked up version of fgets to ignore TELNET escape codes.
587
 */
588
int
589
get_line(s, n, iop)
590
	char *s;
591
	int n;
592
	FILE *iop;
593
{
594
	int c;
595
	char *cs;
596
597
	cs = s;
598
/* tmpline may contain saved command from urgent mode interruption */
599
	for (c = 0; tmpline[c] != '\0' && --n > 0; ++c) {
600
		*cs++ = tmpline[c];
601
		if (tmpline[c] == '\n') {
602
			*cs++ = '\0';
603
			if (debug)
604
				syslog(LOG_DEBUG, "command: %s", s);
605
			tmpline[0] = '\0';
606
			return(0);
607
		}
608
		if (c == 0)
609
			tmpline[0] = '\0';
610
	}
611
	while ((c = getc(iop)) != EOF) {
612
		c &= 0377;
613
		if (c == IAC) {
614
		    if ((c = getc(iop)) != EOF) {
615
			c &= 0377;
616
			switch (c) {
617
			case WILL:
618
			case WONT:
619
				c = getc(iop);
620
				printf("%c%c%c", IAC, DONT, 0377&c);
621
				(void) fflush(stdout);
622
				continue;
623
			case DO:
624
			case DONT:
625
				c = getc(iop);
626
				printf("%c%c%c", IAC, WONT, 0377&c);
627
				(void) fflush(stdout);
628
				continue;
629
			case IAC:
630
				break;
631
			default:
632
				continue;	/* ignore command */
633
			}
634
		    }
635
		}
636
		*cs++ = c;
637
		if (--n <= 0) {
638
			/*
639
			 * If command doesn't fit into buffer, discard the
640
			 * rest of the command and indicate truncation.
641
			 * This prevents the command to be split up into
642
			 * multiple commands.
643
			 */
644
			while (c != '\n' && (c = getc(iop)) != EOF)
645
				;
646
			return (-2);
647
		}
648
		if (c == '\n')
649
			break;
650
	}
651
	if (c == EOF && cs == s)
652
		return (-1);
653
	*cs++ = '\0';
654
	if (debug) {
655
		if (!guest && strncasecmp("pass ", s, 5) == 0) {
656
			/* Don't syslog passwords */
657
			syslog(LOG_DEBUG, "command: %.5s ???", s);
658
		} else {
659
			char *cp;
660
			int len;
661
662
			/* Don't syslog trailing CR-LF */
663
			len = strlen(s);
664
			cp = s + len - 1;
665
			while (cp >= s && (*cp == '\n' || *cp == '\r')) {
666
				--cp;
667
				--len;
668
			}
669
			syslog(LOG_DEBUG, "command: %.*s", len, s);
670
		}
671
	}
672
	return (0);
673
}
674
675
/*ARGSUSED*/
676
void
677
toolong(signo)
678
	int signo;
679
{
680
	struct syslog_data sdata = SYSLOG_DATA_INIT;
681
682
	reply_r(421,
683
	    "Timeout (%d seconds): closing control connection.", timeout);
684
	if (logging)
685
		syslog_r(LOG_INFO, &sdata, "User %s timed out after %d seconds",
686
		    (pw ? pw -> pw_name : "unknown"), timeout);
687
	dologout(1);
688
}
689
690
static int
691
yylex()
692
{
693
	static int cpos;
694
	char *cp, *cp2;
695
	struct tab *p;
696
	int n;
697
	char c;
698
699
	for (;;) {
700
		switch (state) {
701
702
		case CMD:
703
			(void) alarm((unsigned) timeout);
704
			n = get_line(cbuf, sizeof(cbuf)-1, stdin);
705
			if (n == -1) {
706
				reply(221, "You could at least say goodbye.");
707
				dologout(0);
708
			} else if (n == -2) {
709
				reply(500, "Command too long.");
710
				alarm(0);
711
				continue;
712
			}
713
			(void) alarm(0);
714
			if ((cp = strchr(cbuf, '\r'))) {
715
				*cp++ = '\n';
716
				*cp = '\0';
717
			}
718
			if (strncasecmp(cbuf, "PASS", 4) != 0) {
719
				if ((cp = strpbrk(cbuf, "\n"))) {
720
					c = *cp;
721
					*cp = '\0';
722
					setproctitle("%s: %s", proctitle, cbuf);
723
					*cp = c;
724
				}
725
			}
726
			if ((cp = strpbrk(cbuf, " \n")))
727
				cpos = cp - cbuf;
728
			if (cpos == 0)
729
				cpos = 4;
730
			c = cbuf[cpos];
731
			cbuf[cpos] = '\0';
732
			upper(cbuf);
733
			p = lookup(cmdtab, cbuf);
734
			cbuf[cpos] = c;
735
			if (p != NULL) {
736
				if (p->implemented == 0) {
737
					nack(p->name);
738
					return (LEXERR);
739
				}
740
				state = p->state;
741
				yylval.s = p->name;
742
				return (p->token);
743
			}
744
			break;
745
746
		case SITECMD:
747
			if (cbuf[cpos] == ' ') {
748
				cpos++;
749
				return (SP);
750
			}
751
			cp = &cbuf[cpos];
752
			if ((cp2 = strpbrk(cp, " \n")))
753
				cpos = cp2 - cbuf;
754
			c = cbuf[cpos];
755
			cbuf[cpos] = '\0';
756
			upper(cp);
757
			p = lookup(sitetab, cp);
758
			cbuf[cpos] = c;
759
			if (p != NULL) {
760
				if (p->implemented == 0) {
761
					state = CMD;
762
					nack(p->name);
763
					return (LEXERR);
764
				}
765
				state = p->state;
766
				yylval.s = p->name;
767
				return (p->token);
768
			}
769
			state = CMD;
770
			break;
771
772
		case OSTR:
773
			if (cbuf[cpos] == '\n') {
774
				state = CMD;
775
				return (CRLF);
776
			}
777
			/* FALLTHROUGH */
778
779
		case STR1:
780
		case ZSTR1:
781
		dostr1:
782
			if (cbuf[cpos] == ' ') {
783
				cpos++;
784
				state = state == OSTR ? STR2 : state+1;
785
				return (SP);
786
			}
787
			break;
788
789
		case ZSTR2:
790
			if (cbuf[cpos] == '\n') {
791
				state = CMD;
792
				return (CRLF);
793
			}
794
			/* FALLTHROUGH */
795
796
		case STR2:
797
			cp = &cbuf[cpos];
798
			n = strlen(cp);
799
			cpos += n - 1;
800
			/*
801
			 * Make sure the string is nonempty and \n terminated.
802
			 */
803
			if (n > 1 && cbuf[cpos] == '\n') {
804
				cbuf[cpos] = '\0';
805
				yylval.s = strdup(cp);
806
				if (yylval.s == NULL)
807
					fatal("Ran out of memory.");
808
				cbuf[cpos] = '\n';
809
				state = ARGS;
810
				return (STRING);
811
			}
812
			break;
813
814
		case NSTR:
815
			if (cbuf[cpos] == ' ') {
816
				cpos++;
817
				return (SP);
818
			}
819
			if (isdigit((unsigned char)cbuf[cpos])) {
820
				cp = &cbuf[cpos];
821
				while (isdigit((unsigned char)cbuf[++cpos]))
822
					;
823
				c = cbuf[cpos];
824
				cbuf[cpos] = '\0';
825
				yylval.i = atoi(cp);
826
				cbuf[cpos] = c;
827
				state = STR1;
828
				return (NUMBER);
829
			}
830
			state = STR1;
831
			goto dostr1;
832
833
		case ARGS:
834
			if (isdigit((unsigned char)cbuf[cpos])) {
835
				long long llval;
836
837
				cp = &cbuf[cpos];
838
				errno = 0;
839
				llval = strtoll(cp, &cp2, 10);
840
				if (llval < 0 ||
841
				    (errno == ERANGE && llval == LLONG_MAX))
842
					break;
843
844
				cpos = (int)(cp2 - cbuf);
845
				if (llval > INT_MAX) {
846
					yylval.o = llval;
847
					return (BIGNUM);
848
				} else {
849
					yylval.i = (int)llval;
850
					return (NUMBER);
851
				}
852
			}
853
			if (strncasecmp(&cbuf[cpos], "ALL", 3) == 0 &&
854
			    !isalnum((unsigned char)cbuf[cpos + 3])) {
855
				cpos += 3;
856
				return ALL;
857
			}
858
			switch (cbuf[cpos++]) {
859
860
			case '\n':
861
				state = CMD;
862
				return (CRLF);
863
864
			case ' ':
865
				return (SP);
866
867
			case ',':
868
				return (COMMA);
869
870
			case 'A':
871
			case 'a':
872
				return (A);
873
874
			case 'B':
875
			case 'b':
876
				return (B);
877
878
			case 'C':
879
			case 'c':
880
				return (C);
881
882
			case 'E':
883
			case 'e':
884
				return (E);
885
886
			case 'F':
887
			case 'f':
888
				return (F);
889
890
			case 'I':
891
			case 'i':
892
				return (I);
893
894
			case 'L':
895
			case 'l':
896
				return (L);
897
898
			case 'N':
899
			case 'n':
900
				return (N);
901
902
			case 'P':
903
			case 'p':
904
				return (P);
905
906
			case 'R':
907
			case 'r':
908
				return (R);
909
910
			case 'S':
911
			case 's':
912
				return (S);
913
914
			case 'T':
915
			case 't':
916
				return (T);
917
918
			}
919
			break;
920
921
		default:
922
			fatal("Unknown state in scanner.");
923
		}
924
		state = CMD;
925
		return (LEXERR);
926
	}
927
}
928
929
void
930
upper(s)
931
	char *s;
932
{
933
	char *p;
934
935
	for (p = s; *p; p++) {
936
		if (islower((unsigned char)*p))
937
			*p = (char)toupper((unsigned char)*p);
938
	}
939
}
940
941
static void
942
help(ctab, s)
943
	struct tab *ctab;
944
	char *s;
945
{
946
	struct tab *c;
947
	int width, NCMDS;
948
	char *type;
949
950
	if (ctab == sitetab)
951
		type = "SITE ";
952
	else
953
		type = "";
954
	width = 0, NCMDS = 0;
955
	for (c = ctab; c->name != NULL; c++) {
956
		int len = strlen(c->name);
957
958
		if (len > width)
959
			width = len;
960
		NCMDS++;
961
	}
962
	width = (width + 8) &~ 7;
963
	if (s == NULL) {
964
		int i, j, w;
965
		int columns, lines;
966
967
		lreply(214, "The following %scommands are recognized %s.",
968
		    type, "(* =>'s unimplemented)");
969
		columns = 76 / width;
970
		if (columns == 0)
971
			columns = 1;
972
		lines = (NCMDS + columns - 1) / columns;
973
		for (i = 0; i < lines; i++) {
974
			printf("   ");
975
			for (j = 0; j < columns; j++) {
976
				c = ctab + j * lines + i;
977
				printf("%s%c", c->name,
978
					c->implemented ? ' ' : '*');
979
				if (c + lines >= &ctab[NCMDS])
980
					break;
981
				w = strlen(c->name) + 1;
982
				while (w < width) {
983
					putchar(' ');
984
					w++;
985
				}
986
			}
987
			printf("\r\n");
988
		}
989
		(void) fflush(stdout);
990
		reply(214, "Direct comments to ftp-bugs@%s.", hostname);
991
		return;
992
	}
993
	upper(s);
994
	c = lookup(ctab, s);
995
	if (c == NULL) {
996
		reply(502, "Unknown command %s.", s);
997
		return;
998
	}
999
	if (c->implemented)
1000
		reply(214, "Syntax: %s%s %s", type, c->name, c->help);
1001
	else
1002
		reply(214, "%s%-*s\t%s; unimplemented.", type, width,
1003
		    c->name, c->help);
1004
}
1005
1006
static void
1007
sizecmd(filename)
1008
	char *filename;
1009
{
1010
	switch (type) {
1011
	case TYPE_L:
1012
	case TYPE_I: {
1013
		struct stat stbuf;
1014
		if (stat(filename, &stbuf) < 0 || !S_ISREG(stbuf.st_mode))
1015
			reply(550, "%s: not a plain file.", filename);
1016
		else
1017
			reply(213, "%lld", (long long)stbuf.st_size);
1018
		break; }
1019
	case TYPE_A: {
1020
		FILE *fin;
1021
		int c;
1022
		off_t count;
1023
		struct stat stbuf;
1024
		fin = fopen(filename, "r");
1025
		if (fin == NULL) {
1026
			perror_reply(550, filename);
1027
			return;
1028
		}
1029
		if (fstat(fileno(fin), &stbuf) < 0 || !S_ISREG(stbuf.st_mode)) {
1030
			reply(550, "%s: not a plain file.", filename);
1031
			(void) fclose(fin);
1032
			return;
1033
		}
1034
		if (stbuf.st_size > 10240) {
1035
			reply(550, "%s: file too large for SIZE.", filename);
1036
			(void) fclose(fin);
1037
			return;
1038
		}
1039
1040
		count = 0;
1041
		while((c = getc(fin)) != EOF) {
1042
			if (c == '\n')	/* will get expanded to \r\n */
1043
				count++;
1044
			count++;
1045
		}
1046
		(void) fclose(fin);
1047
1048
		reply(213, "%lld", (long long)count);
1049
		break; }
1050
	default:
1051
		reply(504, "SIZE not implemented for Type %c.", "?AEIL"[type]);
1052
	}
1053
}
1054
#line 1047 "ftpcmd.c"
1055
/* allocate initial stack or double stack size, up to YYMAXDEPTH */
1056
static int yygrowstack(void)
1057
{
1058
    unsigned int newsize;
1059
    long sslen;
1060
    short *newss;
1061
    YYSTYPE *newvs;
1062
1063
    if ((newsize = yystacksize) == 0)
1064
        newsize = YYINITSTACKSIZE;
1065
    else if (newsize >= YYMAXDEPTH)
1066
        return -1;
1067
    else if ((newsize *= 2) > YYMAXDEPTH)
1068
        newsize = YYMAXDEPTH;
1069
    sslen = yyssp - yyss;
1070
#ifdef SIZE_MAX
1071
#define YY_SIZE_MAX SIZE_MAX
1072
#else
1073
#define YY_SIZE_MAX 0xffffffffU
1074
#endif
1075
    if (newsize && YY_SIZE_MAX / newsize < sizeof *newss)
1076
        goto bail;
1077
    newss = yyss ? (short *)realloc(yyss, newsize * sizeof *newss) :
1078
      (short *)malloc(newsize * sizeof *newss); /* overflow check above */
1079
    if (newss == NULL)
1080
        goto bail;
1081
    yyss = newss;
1082
    yyssp = newss + sslen;
1083
    if (newsize && YY_SIZE_MAX / newsize < sizeof *newvs)
1084
        goto bail;
1085
    newvs = yyvs ? (YYSTYPE *)realloc(yyvs, newsize * sizeof *newvs) :
1086
      (YYSTYPE *)malloc(newsize * sizeof *newvs); /* overflow check above */
1087
    if (newvs == NULL)
1088
        goto bail;
1089
    yyvs = newvs;
1090
    yyvsp = newvs + sslen;
1091
    yystacksize = newsize;
1092
    yysslim = yyss + newsize - 1;
1093
    return 0;
1094
bail:
1095
    if (yyss)
1096
            free(yyss);
1097
    if (yyvs)
1098
            free(yyvs);
1099
    yyss = yyssp = NULL;
1100
    yyvs = yyvsp = NULL;
1101
    yystacksize = 0;
1102
    return -1;
1103
}
1104
1105
#define YYABORT goto yyabort
1106
#define YYREJECT goto yyabort
1107
#define YYACCEPT goto yyaccept
1108
#define YYERROR goto yyerrlab
1109
int
1110
yyparse(void)
1111
{
1112
    int yym, yyn, yystate;
1113
#if YYDEBUG
1114
    const char *yys;
1115
1116
    if ((yys = getenv("YYDEBUG")))
1117
    {
1118
        yyn = *yys;
1119
        if (yyn >= '0' && yyn <= '9')
1120
            yydebug = yyn - '0';
1121
    }
1122
#endif /* YYDEBUG */
1123
1124
    yynerrs = 0;
1125
    yyerrflag = 0;
1126
    yychar = (-1);
1127
1128
    if (yyss == NULL && yygrowstack()) goto yyoverflow;
1129
    yyssp = yyss;
1130
    yyvsp = yyvs;
1131
    *yyssp = yystate = 0;
1132
1133
yyloop:
1134
    if ((yyn = yydefred[yystate]) != 0) goto yyreduce;
1135
    if (yychar < 0)
1136
    {
1137
        if ((yychar = yylex()) < 0) yychar = 0;
1138
#if YYDEBUG
1139
        if (yydebug)
1140
        {
1141
            yys = 0;
1142
            if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
1143
            if (!yys) yys = "illegal-symbol";
1144
            printf("%sdebug: state %d, reading %d (%s)\n",
1145
                    YYPREFIX, yystate, yychar, yys);
1146
        }
1147
#endif
1148
    }
1149
    if ((yyn = yysindex[yystate]) && (yyn += yychar) >= 0 &&
1150
            yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
1151
    {
1152
#if YYDEBUG
1153
        if (yydebug)
1154
            printf("%sdebug: state %d, shifting to state %d\n",
1155
                    YYPREFIX, yystate, yytable[yyn]);
1156
#endif
1157
        if (yyssp >= yysslim && yygrowstack())
1158
        {
1159
            goto yyoverflow;
1160
        }
1161
        *++yyssp = yystate = yytable[yyn];
1162
        *++yyvsp = yylval;
1163
        yychar = (-1);
1164
        if (yyerrflag > 0)  --yyerrflag;
1165
        goto yyloop;
1166
    }
1167
    if ((yyn = yyrindex[yystate]) && (yyn += yychar) >= 0 &&
1168
            yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
1169
    {
1170
        yyn = yytable[yyn];
1171
        goto yyreduce;
1172
    }
1173
    if (yyerrflag) goto yyinrecovery;
1174
#if defined(__GNUC__)
1175
    goto yynewerror;
1176
#endif
1177
yynewerror:
1178
    yyerror("syntax error");
1179
#if defined(__GNUC__)
1180
    goto yyerrlab;
1181
#endif
1182
yyerrlab:
1183
    ++yynerrs;
1184
yyinrecovery:
1185
    if (yyerrflag < 3)
1186
    {
1187
        yyerrflag = 3;
1188
        for (;;)
1189
        {
1190
            if ((yyn = yysindex[*yyssp]) && (yyn += YYERRCODE) >= 0 &&
1191
                    yyn <= YYTABLESIZE && yycheck[yyn] == YYERRCODE)
1192
            {
1193
#if YYDEBUG
1194
                if (yydebug)
1195
                    printf("%sdebug: state %d, error recovery shifting\
1196
 to state %d\n", YYPREFIX, *yyssp, yytable[yyn]);
1197
#endif
1198
                if (yyssp >= yysslim && yygrowstack())
1199
                {
1200
                    goto yyoverflow;
1201
                }
1202
                *++yyssp = yystate = yytable[yyn];
1203
                *++yyvsp = yylval;
1204
                goto yyloop;
1205
            }
1206
            else
1207
            {
1208
#if YYDEBUG
1209
                if (yydebug)
1210
                    printf("%sdebug: error recovery discarding state %d\n",
1211
                            YYPREFIX, *yyssp);
1212
#endif
1213
                if (yyssp <= yyss) goto yyabort;
1214
                --yyssp;
1215
                --yyvsp;
1216
            }
1217
        }
1218
    }
1219
    else
1220
    {
1221
        if (yychar == 0) goto yyabort;
1222
#if YYDEBUG
1223
        if (yydebug)
1224
        {
1225
            yys = 0;
1226
            if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
1227
            if (!yys) yys = "illegal-symbol";
1228
            printf("%sdebug: state %d, error recovery discards token %d (%s)\n",
1229
                    YYPREFIX, yystate, yychar, yys);
1230
        }
1231
#endif
1232
        yychar = (-1);
1233
        goto yyloop;
1234
    }
1235
yyreduce:
1236
#if YYDEBUG
1237
    if (yydebug)
1238
        printf("%sdebug: state %d, reducing by rule %d (%s)\n",
1239
                YYPREFIX, yystate, yyn, yyrule[yyn]);
1240
#endif
1241
    yym = yylen[yyn];
1242
    if (yym)
1243
        yyval = yyvsp[1-yym];
1244
    else
1245
        memset(&yyval, 0, sizeof yyval);
1246
    switch (yyn)
1247
    {
1248
case 2:
1249
#line 141 "ftpcmd.y"
1250
{
1251
			if (fromname) {
1252
				free(fromname);
1253
				fromname = NULL;
1254
			}
1255
			restart_point = 0;
1256
		}
1257
break;
1258
case 4:
1259
#line 153 "ftpcmd.y"
1260
{
1261
			monitor_user(yyvsp[-1].s);
1262
			free(yyvsp[-1].s);
1263
		}
1264
break;
1265
case 5:
1266
#line 158 "ftpcmd.y"
1267
{
1268
			quit = monitor_pass(yyvsp[-1].s);
1269
			explicit_bzero(yyvsp[-1].s, strlen(yyvsp[-1].s));
1270
			free(yyvsp[-1].s);
1271
1272
			/* Terminate unprivileged pre-auth slave */
1273
			if (quit)
1274
				_exit(0);
1275
		}
1276
break;
1277
case 6:
1278
#line 168 "ftpcmd.y"
1279
{
1280
			if (yyvsp[-3].i) {
1281
				if (yyvsp[-1].i) {
1282
					usedefault = 1;
1283
					reply(500,
1284
					    "Illegal PORT rejected (range errors).");
1285
				} else if (portcheck &&
1286
				    ntohs(data_dest.su_sin.sin_port) < IPPORT_RESERVED) {
1287
					usedefault = 1;
1288
					reply(500,
1289
					    "Illegal PORT rejected (reserved port).");
1290
				} else if (portcheck &&
1291
				    memcmp(&data_dest.su_sin.sin_addr,
1292
				    &his_addr.su_sin.sin_addr,
1293
				    sizeof data_dest.su_sin.sin_addr)) {
1294
					usedefault = 1;
1295
					reply(500,
1296
					    "Illegal PORT rejected (address wrong).");
1297
				} else {
1298
					usedefault = 0;
1299
					if (pdata >= 0) {
1300
						(void) close(pdata);
1301
						pdata = -1;
1302
					}
1303
					reply(200, "PORT command successful.");
1304
				}
1305
			}
1306
		}
1307
break;
1308
case 7:
1309
#line 197 "ftpcmd.y"
1310
{
1311
			if (yyvsp[-3].i) {
1312
				/* reject invalid host_long_port4 */
1313
				if (yyvsp[-1].i) {
1314
					reply(500,
1315
					    "Illegal LPRT command rejected");
1316
					usedefault = 1;
1317
				} else {
1318
					usedefault = 0;
1319
					if (pdata >= 0) {
1320
						(void) close(pdata);
1321
						pdata = -1;
1322
					}
1323
					reply(200, "LPRT command successful.");
1324
				}
1325
			}
1326
		}
1327
break;
1328
case 8:
1329
#line 216 "ftpcmd.y"
1330
{
1331
			if (yyvsp[-3].i) {
1332
				/* reject invalid host_long_port6 */
1333
				if (yyvsp[-1].i) {
1334
					reply(500,
1335
					    "Illegal LPRT command rejected");
1336
					usedefault = 1;
1337
				} else {
1338
					usedefault = 0;
1339
					if (pdata >= 0) {
1340
						(void) close(pdata);
1341
						pdata = -1;
1342
					}
1343
					reply(200, "LPRT command successful.");
1344
				}
1345
			}
1346
		}
1347
break;
1348
case 9:
1349
#line 235 "ftpcmd.y"
1350
{
1351
			if (yyvsp[-3].i)
1352
				extended_port(yyvsp[-1].s);
1353
			free(yyvsp[-1].s);
1354
		}
1355
break;
1356
case 10:
1357
#line 242 "ftpcmd.y"
1358
{
1359
			if (yyvsp[-1].i)
1360
				passive();
1361
		}
1362
break;
1363
case 11:
1364
#line 247 "ftpcmd.y"
1365
{
1366
			if (yyvsp[-1].i)
1367
				long_passive("LPSV", PF_UNSPEC);
1368
		}
1369
break;
1370
case 12:
1371
#line 252 "ftpcmd.y"
1372
{
1373
			if (yyvsp[-3].i)
1374
				long_passive("EPSV", epsvproto2af(yyvsp[-1].i));
1375
		}
1376
break;
1377
case 13:
1378
#line 257 "ftpcmd.y"
1379
{
1380
			if (yyvsp[-3].i) {
1381
				reply(200, "EPSV ALL command successful.");
1382
				epsvall++;
1383
			}
1384
		}
1385
break;
1386
case 14:
1387
#line 264 "ftpcmd.y"
1388
{
1389
			if (yyvsp[-1].i)
1390
				long_passive("EPSV", PF_UNSPEC);
1391
		}
1392
break;
1393
case 15:
1394
#line 269 "ftpcmd.y"
1395
{
1396
			if (yyvsp[-3].i) {
1397
				switch (cmd_type) {
1398
1399
				case TYPE_A:
1400
					if (cmd_form == FORM_N) {
1401
						reply(200, "Type set to A.");
1402
						type = cmd_type;
1403
						form = cmd_form;
1404
					} else
1405
						reply(504, "Form must be N.");
1406
					break;
1407
1408
				case TYPE_E:
1409
					reply(504, "Type E not implemented.");
1410
					break;
1411
1412
				case TYPE_I:
1413
					reply(200, "Type set to I.");
1414
					type = cmd_type;
1415
					break;
1416
1417
				case TYPE_L:
1418
					if (cmd_bytesz == 8) {
1419
						reply(200,
1420
						    "Type set to L (byte size 8).");
1421
						    type = cmd_type;
1422
					} else
1423
						reply(504, "Byte size must be 8.");
1424
1425
				}
1426
			}
1427
		}
1428
break;
1429
case 16:
1430
#line 303 "ftpcmd.y"
1431
{
1432
			if (yyvsp[-3].i) {
1433
				switch (yyvsp[-1].i) {
1434
1435
				case STRU_F:
1436
					reply(200, "STRU F ok.");
1437
					break;
1438
1439
				default:
1440
					reply(504, "Unimplemented STRU type.");
1441
				}
1442
			}
1443
		}
1444
break;
1445
case 17:
1446
#line 317 "ftpcmd.y"
1447
{
1448
			if (yyvsp[-3].i) {
1449
				switch (yyvsp[-1].i) {
1450
1451
				case MODE_S:
1452
					reply(200, "MODE S ok.");
1453
					break;
1454
1455
				default:
1456
					reply(502, "Unimplemented MODE type.");
1457
				}
1458
			}
1459
		}
1460
break;
1461
case 18:
1462
#line 331 "ftpcmd.y"
1463
{
1464
			if (yyvsp[-3].i) {
1465
				reply(202, "ALLO command ignored.");
1466
			}
1467
		}
1468
break;
1469
case 19:
1470
#line 337 "ftpcmd.y"
1471
{
1472
			if (yyvsp[-7].i) {
1473
				reply(202, "ALLO command ignored.");
1474
			}
1475
		}
1476
break;
1477
case 20:
1478
#line 343 "ftpcmd.y"
1479
{
1480
			if (yyvsp[-3].i && yyvsp[-1].s != NULL)
1481
				retrieve(NULL, yyvsp[-1].s);
1482
			if (yyvsp[-1].s != NULL)
1483
				free(yyvsp[-1].s);
1484
		}
1485
break;
1486
case 21:
1487
#line 350 "ftpcmd.y"
1488
{
1489
			if (yyvsp[-3].i && yyvsp[-1].s != NULL)
1490
				store(yyvsp[-1].s, "w", 0);
1491
			if (yyvsp[-1].s != NULL)
1492
				free(yyvsp[-1].s);
1493
		}
1494
break;
1495
case 22:
1496
#line 357 "ftpcmd.y"
1497
{
1498
			if (yyvsp[-3].i && yyvsp[-1].s != NULL)
1499
				store(yyvsp[-1].s, "a", 0);
1500
			if (yyvsp[-1].s != NULL)
1501
				free(yyvsp[-1].s);
1502
		}
1503
break;
1504
case 23:
1505
#line 364 "ftpcmd.y"
1506
{
1507
			if (yyvsp[-1].i)
1508
				send_file_list(".");
1509
		}
1510
break;
1511
case 24:
1512
#line 369 "ftpcmd.y"
1513
{
1514
			if (yyvsp[-3].i && yyvsp[-1].s != NULL)
1515
				send_file_list(yyvsp[-1].s);
1516
			free(yyvsp[-1].s);
1517
		}
1518
break;
1519
case 25:
1520
#line 375 "ftpcmd.y"
1521
{
1522
			if (yyvsp[-1].i)
1523
				retrieve("/bin/ls -lgA", "");
1524
		}
1525
break;
1526
case 26:
1527
#line 380 "ftpcmd.y"
1528
{
1529
			if (yyvsp[-3].i && yyvsp[-1].s != NULL)
1530
				retrieve("/bin/ls -lgA %s", yyvsp[-1].s);
1531
			if (yyvsp[-1].s != NULL)
1532
				free(yyvsp[-1].s);
1533
		}
1534
break;
1535
case 27:
1536
#line 387 "ftpcmd.y"
1537
{
1538
			if (yyvsp[-3].i && yyvsp[-1].s != NULL)
1539
				statfilecmd(yyvsp[-1].s);
1540
			if (yyvsp[-1].s != NULL)
1541
				free(yyvsp[-1].s);
1542
		}
1543
break;
1544
case 28:
1545
#line 394 "ftpcmd.y"
1546
{
1547
			if (yyvsp[-1].i)
1548
				statcmd();
1549
		}
1550
break;
1551
case 29:
1552
#line 399 "ftpcmd.y"
1553
{
1554
			if (yyvsp[-3].i && yyvsp[-1].s != NULL)
1555
				delete(yyvsp[-1].s);
1556
			if (yyvsp[-1].s != NULL)
1557
				free(yyvsp[-1].s);
1558
		}
1559
break;
1560
case 30:
1561
#line 406 "ftpcmd.y"
1562
{
1563
			if (yyvsp[-3].i && yyvsp[-1].s != NULL) {
1564
				if (fromname) {
1565
					renamecmd(fromname, yyvsp[-1].s);
1566
					free(fromname);
1567
					fromname = NULL;
1568
				} else {
1569
					reply(503,
1570
					  "Bad sequence of commands.");
1571
				}
1572
			}
1573
			if (yyvsp[-1].s != NULL)
1574
				free(yyvsp[-1].s);
1575
		}
1576
break;
1577
case 31:
1578
#line 421 "ftpcmd.y"
1579
{
1580
			if (yyvsp[-1].i)
1581
				reply(225, "ABOR command successful.");
1582
		}
1583
break;
1584
case 32:
1585
#line 426 "ftpcmd.y"
1586
{
1587
			if (yyvsp[-1].i)
1588
				cwd(pw->pw_dir);
1589
		}
1590
break;
1591
case 33:
1592
#line 431 "ftpcmd.y"
1593
{
1594
			if (yyvsp[-3].i && yyvsp[-1].s != NULL)
1595
				cwd(yyvsp[-1].s);
1596
			if (yyvsp[-1].s != NULL)
1597
				free(yyvsp[-1].s);
1598
		}
1599
break;
1600
case 34:
1601
#line 438 "ftpcmd.y"
1602
{
1603
			help(cmdtab, NULL);
1604
		}
1605
break;
1606
case 35:
1607
#line 442 "ftpcmd.y"
1608
{
1609
			char *cp = yyvsp[-1].s;
1610
1611
			if (strncasecmp(cp, "SITE", 4) == 0) {
1612
				cp = yyvsp[-1].s + 4;
1613
				if (*cp == ' ')
1614
					cp++;
1615
				if (*cp)
1616
					help(sitetab, cp);
1617
				else
1618
					help(sitetab, NULL);
1619
			} else
1620
				help(cmdtab, yyvsp[-1].s);
1621
			free (yyvsp[-1].s);
1622
		}
1623
break;
1624
case 36:
1625
#line 458 "ftpcmd.y"
1626
{
1627
			reply(200, "NOOP command successful.");
1628
		}
1629
break;
1630
case 37:
1631
#line 462 "ftpcmd.y"
1632
{
1633
			if (yyvsp[-3].i && yyvsp[-1].s != NULL)
1634
				makedir(yyvsp[-1].s);
1635
			if (yyvsp[-1].s != NULL)
1636
				free(yyvsp[-1].s);
1637
		}
1638
break;
1639
case 38:
1640
#line 469 "ftpcmd.y"
1641
{
1642
			if (yyvsp[-3].i && yyvsp[-1].s != NULL)
1643
				removedir(yyvsp[-1].s);
1644
			if (yyvsp[-1].s != NULL)
1645
				free(yyvsp[-1].s);
1646
		}
1647
break;
1648
case 39:
1649
#line 476 "ftpcmd.y"
1650
{
1651
			if (yyvsp[-1].i)
1652
				pwd();
1653
		}
1654
break;
1655
case 40:
1656
#line 481 "ftpcmd.y"
1657
{
1658
			if (yyvsp[-1].i)
1659
				cwd("..");
1660
		}
1661
break;
1662
case 41:
1663
#line 486 "ftpcmd.y"
1664
{
1665
			help(sitetab, NULL);
1666
		}
1667
break;
1668
case 42:
1669
#line 490 "ftpcmd.y"
1670
{
1671
			help(sitetab, yyvsp[-1].s);
1672
			free (yyvsp[-1].s);
1673
		}
1674
break;
1675
case 43:
1676
#line 495 "ftpcmd.y"
1677
{
1678
			mode_t oldmask;
1679
1680
			if (yyvsp[-1].i) {
1681
				oldmask = umask(0);
1682
				(void) umask(oldmask);
1683
				reply(200, "Current UMASK is %03o", oldmask);
1684
			}
1685
		}
1686
break;
1687
case 44:
1688
#line 505 "ftpcmd.y"
1689
{
1690
			mode_t oldmask;
1691
1692
			if (yyvsp[-3].i) {
1693
				if ((yyvsp[-1].i == -1) || (yyvsp[-1].i > 0777)) {
1694
					reply(501, "Bad UMASK value");
1695
				} else if (!umaskchange) {
1696
					reply(550,
1697
					    "No permission to change umask.");
1698
				} else {
1699
					oldmask = umask(yyvsp[-1].i);
1700
					reply(200,
1701
					    "UMASK set to %03o (was %03o)",
1702
					    yyvsp[-1].i, oldmask);
1703
				}
1704
			}
1705
		}
1706
break;
1707
case 45:
1708
#line 523 "ftpcmd.y"
1709
{
1710
			if (yyvsp[-5].i && (yyvsp[-1].s != NULL)) {
1711
				if ((yyvsp[-3].i == -1) || (yyvsp[-3].i > 0777))
1712
					reply(501,
1713
					    "CHMOD: Mode value must be between "
1714
					    "0 and 0777");
1715
				else if (!umaskchange)
1716
					reply(550,
1717
					    "No permission to change mode of %s.",
1718
					    yyvsp[-1].s);
1719
				else if (chmod(yyvsp[-1].s, yyvsp[-3].i) < 0)
1720
					perror_reply(550, yyvsp[-1].s);
1721
				else
1722
					reply(200,
1723
					    "CHMOD command successful.");
1724
			}
1725
			if (yyvsp[-1].s != NULL)
1726
				free(yyvsp[-1].s);
1727
		}
1728
break;
1729
case 46:
1730
#line 543 "ftpcmd.y"
1731
{
1732
			if (yyvsp[-2].i)
1733
				reply(200,
1734
				    "Current IDLE time limit is %d "
1735
				    "seconds; max %d",
1736
				    timeout, maxtimeout);
1737
		}
1738
break;
1739
case 47:
1740
#line 551 "ftpcmd.y"
1741
{
1742
			if (yyvsp[-4].i) {
1743
				if (yyvsp[-1].i < 30 || yyvsp[-1].i > maxtimeout) {
1744
					reply(501,
1745
					    "Maximum IDLE time must be between "
1746
					    "30 and %d seconds",
1747
					    maxtimeout);
1748
				} else {
1749
					timeout = yyvsp[-1].i;
1750
					(void) alarm((unsigned) timeout);
1751
					reply(200,
1752
					    "Maximum IDLE time set to %d seconds",
1753
					    timeout);
1754
				}
1755
			}
1756
		}
1757
break;
1758
case 48:
1759
#line 568 "ftpcmd.y"
1760
{
1761
			if (yyvsp[-3].i && yyvsp[-1].s != NULL)
1762
				store(yyvsp[-1].s, "w", 1);
1763
			if (yyvsp[-1].s != NULL)
1764
				free(yyvsp[-1].s);
1765
		}
1766
break;
1767
case 49:
1768
#line 575 "ftpcmd.y"
1769
{
1770
			if (yyvsp[-1].i)
1771
			reply(215, "UNIX Type: L8");
1772
		}
1773
break;
1774
case 50:
1775
#line 588 "ftpcmd.y"
1776
{
1777
			if (yyvsp[-3].i && yyvsp[-1].s != NULL)
1778
				sizecmd(yyvsp[-1].s);
1779
			if (yyvsp[-1].s != NULL)
1780
				free(yyvsp[-1].s);
1781
		}
1782
break;
1783
case 51:
1784
#line 605 "ftpcmd.y"
1785
{
1786
			if (yyvsp[-3].i && yyvsp[-1].s != NULL) {
1787
				struct stat stbuf;
1788
				if (stat(yyvsp[-1].s, &stbuf) < 0)
1789
					reply(550, "%s: %s",
1790
					    yyvsp[-1].s, strerror(errno));
1791
				else if (!S_ISREG(stbuf.st_mode)) {
1792
					reply(550, "%s: not a plain file.", yyvsp[-1].s);
1793
				} else {
1794
					struct tm *t;
1795
					t = gmtime(&stbuf.st_mtime);
1796
					reply(213,
1797
					    "%04d%02d%02d%02d%02d%02d",
1798
					    1900 + t->tm_year,
1799
					    t->tm_mon+1, t->tm_mday,
1800
					    t->tm_hour, t->tm_min, t->tm_sec);
1801
				}
1802
			}
1803
			if (yyvsp[-1].s != NULL)
1804
				free(yyvsp[-1].s);
1805
		}
1806
break;
1807
case 52:
1808
#line 627 "ftpcmd.y"
1809
{
1810
			reply(221, "Goodbye.");
1811
			dologout(0);
1812
		}
1813
break;
1814
case 53:
1815
#line 632 "ftpcmd.y"
1816
{
1817
			yyclearin;		/* discard lookahead data */
1818
			yyerrok;		/* clear error condition */
1819
			state = 0;		/* reset lexer state */
1820
		}
1821
break;
1822
case 54:
1823
#line 640 "ftpcmd.y"
1824
{
1825
			restart_point = 0;
1826
			if (yyvsp[-3].i && yyvsp[-1].s) {
1827
				if (fromname)
1828
					free(fromname);
1829
				fromname = renamefrom(yyvsp[-1].s);
1830
				if (fromname == NULL)
1831
					free(yyvsp[-1].s);
1832
			} else if (yyvsp[-1].s) {
1833
				free (yyvsp[-1].s);
1834
			}
1835
		}
1836
break;
1837
case 55:
1838
#line 654 "ftpcmd.y"
1839
{
1840
			if (yyvsp[-3].i) {
1841
				if (fromname) {
1842
					free(fromname);
1843
					fromname = NULL;
1844
				}
1845
				restart_point = yyvsp[-1].o;
1846
				reply(350, "Restarting at %lld. %s",
1847
				    (long long)restart_point,
1848
				    "Send STORE or RETRIEVE to initiate transfer.");
1849
			}
1850
		}
1851
break;
1852
case 57:
1853
#line 674 "ftpcmd.y"
1854
{
1855
			yyval.s = calloc(1, sizeof(char));
1856
		}
1857
break;
1858
case 60:
1859
#line 686 "ftpcmd.y"
1860
{
1861
			yyval.o = yyvsp[0].i;
1862
		}
1863
break;
1864
case 61:
1865
#line 690 "ftpcmd.y"
1866
{
1867
			yyval.o = yyvsp[0].o;
1868
		}
1869
break;
1870
case 62:
1871
#line 698 "ftpcmd.y"
1872
{
1873
			char *a, *p;
1874
1875
			if (yyvsp[-10].i < 0 || yyvsp[-10].i > 255 || yyvsp[-8].i < 0 || yyvsp[-8].i > 255 ||
1876
			    yyvsp[-6].i < 0 || yyvsp[-6].i > 255 || yyvsp[-4].i < 0 || yyvsp[-4].i > 255 ||
1877
			    yyvsp[-2].i < 0 || yyvsp[-2].i > 255 || yyvsp[0].i < 0 || yyvsp[0].i > 255) {
1878
				yyval.i = 1;
1879
			} else {
1880
				data_dest.su_sin.sin_len = sizeof(struct sockaddr_in);
1881
				data_dest.su_sin.sin_family = AF_INET;
1882
				p = (char *)&data_dest.su_sin.sin_port;
1883
				p[0] = yyvsp[-2].i; p[1] = yyvsp[0].i;
1884
				a = (char *)&data_dest.su_sin.sin_addr;
1885
				a[0] = yyvsp[-10].i; a[1] = yyvsp[-8].i; a[2] = yyvsp[-6].i; a[3] = yyvsp[-4].i;
1886
				yyval.i = 0;
1887
			}
1888
		}
1889
break;
1890
case 63:
1891
#line 721 "ftpcmd.y"
1892
{
1893
			char *a, *p;
1894
1895
			/* reject invalid LPRT command */
1896
			if (yyvsp[-16].i != 4 || yyvsp[-14].i != 4 ||
1897
			    yyvsp[-12].i < 0 || yyvsp[-12].i > 255 || yyvsp[-10].i < 0 || yyvsp[-10].i > 255 ||
1898
			    yyvsp[-8].i < 0 || yyvsp[-8].i > 255 || yyvsp[-6].i < 0 || yyvsp[-6].i > 255 ||
1899
			    yyvsp[-4].i != 2 ||
1900
			    yyvsp[-2].i < 0 || yyvsp[-2].i > 255 || yyvsp[0].i < 0 || yyvsp[0].i > 255) {
1901
				yyval.i = 1;
1902
			} else {
1903
				data_dest.su_sin.sin_len =
1904
					sizeof(struct sockaddr_in);
1905
				data_dest.su_family = AF_INET;
1906
				p = (char *)&data_dest.su_port;
1907
				p[0] = yyvsp[-2].i; p[1] = yyvsp[0].i;
1908
				a = (char *)&data_dest.su_sin.sin_addr;
1909
				a[0] = yyvsp[-12].i; a[1] = yyvsp[-10].i; a[2] = yyvsp[-8].i; a[3] = yyvsp[-6].i;
1910
				yyval.i = 0;
1911
			}
1912
		}
1913
break;
1914
case 64:
1915
#line 751 "ftpcmd.y"
1916
{
1917
			char *a, *p;
1918
1919
			/* reject invalid LPRT command */
1920
			if (yyvsp[-40].i != 6 || yyvsp[-38].i != 16 ||
1921
			    yyvsp[-36].i < 0 || yyvsp[-36].i > 255 || yyvsp[-34].i < 0 || yyvsp[-34].i > 255 ||
1922
			    yyvsp[-32].i < 0 || yyvsp[-32].i > 255 || yyvsp[-30].i < 0 || yyvsp[-30].i > 255 ||
1923
			    yyvsp[-28].i < 0 || yyvsp[-28].i > 255 || yyvsp[-26].i < 0 || yyvsp[-26].i > 255 ||
1924
			    yyvsp[-24].i < 0 || yyvsp[-24].i > 255 || yyvsp[-22].i < 0 || yyvsp[-22].i > 255 ||
1925
			    yyvsp[-20].i < 0 || yyvsp[-20].i > 255 || yyvsp[-18].i < 0 || yyvsp[-18].i > 255 ||
1926
			    yyvsp[-16].i < 0 || yyvsp[-16].i > 255 || yyvsp[-14].i < 0 || yyvsp[-14].i > 255 ||
1927
			    yyvsp[-12].i < 0 || yyvsp[-12].i > 255 || yyvsp[-10].i < 0 || yyvsp[-10].i > 255 ||
1928
			    yyvsp[-8].i < 0 || yyvsp[-8].i > 255 || yyvsp[-6].i < 0 || yyvsp[-6].i > 255 ||
1929
			    yyvsp[-4].i != 2 ||
1930
			    yyvsp[-2].i < 0 || yyvsp[-2].i > 255 || yyvsp[0].i < 0 || yyvsp[0].i > 255) {
1931
				yyval.i = 1;
1932
			} else {
1933
				data_dest.su_sin6.sin6_len =
1934
					sizeof(struct sockaddr_in6);
1935
				data_dest.su_family = AF_INET6;
1936
				p = (char *)&data_dest.su_port;
1937
				p[0] = yyvsp[-2].i; p[1] = yyvsp[0].i;
1938
				a = (char *)&data_dest.su_sin6.sin6_addr;
1939
				 a[0] =  yyvsp[-36].i;  a[1] =  yyvsp[-34].i;
1940
				 a[2] =  yyvsp[-32].i;  a[3] = yyvsp[-30].i;
1941
				 a[4] = yyvsp[-28].i;  a[5] = yyvsp[-26].i;
1942
				 a[6] = yyvsp[-24].i;  a[7] = yyvsp[-22].i;
1943
				 a[8] = yyvsp[-20].i;  a[9] = yyvsp[-18].i;
1944
				a[10] = yyvsp[-16].i; a[11] = yyvsp[-14].i;
1945
				a[12] = yyvsp[-12].i; a[13] = yyvsp[-10].i;
1946
				a[14] = yyvsp[-8].i; a[15] = yyvsp[-6].i;
1947
				if (his_addr.su_family == AF_INET6) {
1948
					/* XXX more sanity checks! */
1949
					data_dest.su_sin6.sin6_scope_id =
1950
					    his_addr.su_sin6.sin6_scope_id;
1951
				}
1952
1953
				yyval.i = 0;
1954
			}
1955
		}
1956
break;
1957
case 65:
1958
#line 795 "ftpcmd.y"
1959
{
1960
			yyval.i = FORM_N;
1961
		}
1962
break;
1963
case 66:
1964
#line 799 "ftpcmd.y"
1965
{
1966
			yyval.i = FORM_T;
1967
		}
1968
break;
1969
case 67:
1970
#line 803 "ftpcmd.y"
1971
{
1972
			yyval.i = FORM_C;
1973
		}
1974
break;
1975
case 68:
1976
#line 810 "ftpcmd.y"
1977
{
1978
			cmd_type = TYPE_A;
1979
			cmd_form = FORM_N;
1980
		}
1981
break;
1982
case 69:
1983
#line 815 "ftpcmd.y"
1984
{
1985
			cmd_type = TYPE_A;
1986
			cmd_form = yyvsp[0].i;
1987
		}
1988
break;
1989
case 70:
1990
#line 820 "ftpcmd.y"
1991
{
1992
			cmd_type = TYPE_E;
1993
			cmd_form = FORM_N;
1994
		}
1995
break;
1996
case 71:
1997
#line 825 "ftpcmd.y"
1998
{
1999
			cmd_type = TYPE_E;
2000
			cmd_form = yyvsp[0].i;
2001
		}
2002
break;
2003
case 72:
2004
#line 830 "ftpcmd.y"
2005
{
2006
			cmd_type = TYPE_I;
2007
		}
2008
break;
2009
case 73:
2010
#line 834 "ftpcmd.y"
2011
{
2012
			cmd_type = TYPE_L;
2013
			cmd_bytesz = 8;
2014
		}
2015
break;
2016
case 74:
2017
#line 839 "ftpcmd.y"
2018
{
2019
			cmd_type = TYPE_L;
2020
			cmd_bytesz = yyvsp[0].i;
2021
		}
2022
break;
2023
case 75:
2024
#line 845 "ftpcmd.y"
2025
{
2026
			cmd_type = TYPE_L;
2027
			cmd_bytesz = yyvsp[0].i;
2028
		}
2029
break;
2030
case 76:
2031
#line 853 "ftpcmd.y"
2032
{
2033
			yyval.i = STRU_F;
2034
		}
2035
break;
2036
case 77:
2037
#line 857 "ftpcmd.y"
2038
{
2039
			yyval.i = STRU_R;
2040
		}
2041
break;
2042
case 78:
2043
#line 861 "ftpcmd.y"
2044
{
2045
			yyval.i = STRU_P;
2046
		}
2047
break;
2048
case 79:
2049
#line 868 "ftpcmd.y"
2050
{
2051
			yyval.i = MODE_S;
2052
		}
2053
break;
2054
case 80:
2055
#line 872 "ftpcmd.y"
2056
{
2057
			yyval.i = MODE_B;
2058
		}
2059
break;
2060
case 81:
2061
#line 876 "ftpcmd.y"
2062
{
2063
			yyval.i = MODE_C;
2064
		}
2065
break;
2066
case 82:
2067
#line 883 "ftpcmd.y"
2068
{
2069
			/*
2070
			 * Problem: this production is used for all pathname
2071
			 * processing, but only gives a 550 error reply.
2072
			 * This is a valid reply in some cases but not in others.
2073
			 */
2074
			if (logged_in && yyvsp[0].s && strchr(yyvsp[0].s, '~') != NULL) {
2075
				glob_t gl;
2076
				int flags =
2077
				 GLOB_BRACE|GLOB_NOCHECK|GLOB_QUOTE|GLOB_TILDE;
2078
				char *pptr = yyvsp[0].s;
2079
2080
				/*
2081
				 * glob() will only find a leading ~, but
2082
				 * Netscape kindly puts a slash in front of
2083
				 * it for publish URLs.  There needs to be
2084
				 * a flag for glob() that expands tildes
2085
				 * anywhere in the string.
2086
				 */
2087
				if ((pptr[0] == '/') && (pptr[1] == '~'))
2088
					pptr++;
2089
2090
				memset(&gl, 0, sizeof(gl));
2091
				if (glob(pptr, flags, NULL, &gl) ||
2092
				    gl.gl_pathc == 0) {
2093
					reply(550, "not found");
2094
					yyval.s = NULL;
2095
				} else {
2096
					yyval.s = strdup(gl.gl_pathv[0]);
2097
				}
2098
				globfree(&gl);
2099
				free(yyvsp[0].s);
2100
			} else
2101
				yyval.s = yyvsp[0].s;
2102
		}
2103
break;
2104
case 84:
2105
#line 926 "ftpcmd.y"
2106
{
2107
			int ret, dec, multby, digit;
2108
2109
			/*
2110
			 * Convert a number that was read as decimal number
2111
			 * to what it would be if it had been read as octal.
2112
			 */
2113
			dec = yyvsp[0].i;
2114
			multby = 1;
2115
			ret = 0;
2116
			while (dec) {
2117
				digit = dec%10;
2118
				if (digit > 7) {
2119
					ret = -1;
2120
					break;
2121
				}
2122
				ret += digit * multby;
2123
				multby *= 8;
2124
				dec /= 10;
2125
			}
2126
			yyval.i = ret;
2127
		}
2128
break;
2129
case 85:
2130
#line 953 "ftpcmd.y"
2131
{
2132
			if (logged_in)
2133
				yyval.i = 1;
2134
			else {
2135
				reply(530, "Please login with USER and PASS.");
2136
				yyval.i = 0;
2137
				state = 0;
2138
				YYABORT;
2139
			}
2140
		}
2141
break;
2142
case 86:
2143
#line 967 "ftpcmd.y"
2144
{
2145
			if (!logged_in) {
2146
				reply(530, "Please login with USER and PASS.");
2147
				yyval.i = 0;
2148
				state = 0;
2149
				YYABORT;
2150
			} else if (epsvall) {
2151
				reply(501, "the command is disallowed "
2152
				    "after EPSV ALL");
2153
				usedefault = 1;
2154
				yyval.i = 0;
2155
			} else
2156
				yyval.i = 1;
2157
		}
2158
break;
2159
#line 2152 "ftpcmd.c"
2160
    }
2161
    yyssp -= yym;
2162
    yystate = *yyssp;
2163
    yyvsp -= yym;
2164
    yym = yylhs[yyn];
2165
    if (yystate == 0 && yym == 0)
2166
    {
2167
#if YYDEBUG
2168
        if (yydebug)
2169
            printf("%sdebug: after reduction, shifting from state 0 to\
2170
 state %d\n", YYPREFIX, YYFINAL);
2171
#endif
2172
        yystate = YYFINAL;
2173
        *++yyssp = YYFINAL;
2174
        *++yyvsp = yyval;
2175
        if (yychar < 0)
2176
        {
2177
            if ((yychar = yylex()) < 0) yychar = 0;
2178
#if YYDEBUG
2179
            if (yydebug)
2180
            {
2181
                yys = 0;
2182
                if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
2183
                if (!yys) yys = "illegal-symbol";
2184
                printf("%sdebug: state %d, reading %d (%s)\n",
2185
                        YYPREFIX, YYFINAL, yychar, yys);
2186
            }
2187
#endif
2188
        }
2189
        if (yychar == 0) goto yyaccept;
2190
        goto yyloop;
2191
    }
2192
    if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 &&
2193
            yyn <= YYTABLESIZE && yycheck[yyn] == yystate)
2194
        yystate = yytable[yyn];
2195
    else
2196
        yystate = yydgoto[yym];
2197
#if YYDEBUG
2198
    if (yydebug)
2199
        printf("%sdebug: after reduction, shifting from state %d \
2200
to state %d\n", YYPREFIX, *yyssp, yystate);
2201
#endif
2202
    if (yyssp >= yysslim && yygrowstack())
2203
    {
2204
        goto yyoverflow;
2205
    }
2206
    *++yyssp = yystate;
2207
    *++yyvsp = yyval;
2208
    goto yyloop;
2209
yyoverflow:
2210
    yyerror("yacc stack overflow");
2211
yyabort:
2212
    if (yyss)
2213
            free(yyss);
2214
    if (yyvs)
2215
            free(yyvs);
2216
    yyss = yyssp = NULL;
2217
    yyvs = yyvsp = NULL;
2218
    yystacksize = 0;
2219
    return (1);
2220
yyaccept:
2221
    if (yyss)
2222
            free(yyss);
2223
    if (yyvs)
2224
            free(yyvs);
2225
    yyss = yyssp = NULL;
2226
    yyvs = yyvsp = NULL;
2227
    yystacksize = 0;
2228
    return (0);
2229
}