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 |
|
|
} |