1 #ifndef lint
2 static char yysccsid[] = "@(#)yaccpar 1.9 (Berkeley) 02/21/93";
3 #endif
4 #define YYBYACC 1
5 #define YYMAJOR 1
6 #define YYMINOR 9
7 #define yyclearin (yychar=(-1))
8 #define yyerrok (yyerrflag=0)
9 #define YYRECOVERING (yyerrflag!=0)
10 #define YYPREFIX "yy"
11 #line 26 "ftp.y"
12
13 #ifndef lint
14 static char sccsid[] = "@(#)ftpcmd.y 5.20.1.1 (Berkeley) 3/2/89";
15 #endif /* not lint */
16
17 #include <sys/param.h>
18 #include <sys/socket.h>
19
20 #include <netinet/in.h>
21
22 #include <arpa/ftp.h>
23
24 #include <stdio.h>
25 #include <signal.h>
26 #include <ctype.h>
27 #include <pwd.h>
28 #include <setjmp.h>
29 #include <syslog.h>
30 #include <sys/stat.h>
31 #include <time.h>
32
33 extern struct sockaddr_in data_dest;
34 extern int logged_in;
35 extern struct passwd *pw;
36 extern int guest;
37 extern int logging;
38 extern int type;
39 extern int form;
40 extern int debug;
41 extern int timeout;
42 extern int maxtimeout;
43 extern int pdata;
44 extern char hostname[], remotehost[];
45 extern char proctitle[];
46 extern char *globerr;
47 extern int usedefault;
48 extern int transflag;
49 extern char tmpline[];
50 char **glob();
51
52 static int cmd_type;
53 static int cmd_form;
54 static int cmd_bytesz;
55 char cbuf[512];
56 char *fromname;
57
58 char *index();
59 #line 60 "ftp.tab.c"
60 #define A 257
61 #define B 258
62 #define C 259
63 #define E 260
64 #define F 261
65 #define I 262
66 #define L 263
67 #define N 264
68 #define P 265
69 #define R 266
70 #define S 267
71 #define T 268
72 #define SP 269
73 #define CRLF 270
74 #define COMMA 271
75 #define STRING 272
76 #define NUMBER 273
77 #define USER 274
78 #define PASS 275
79 #define ACCT 276
80 #define REIN 277
81 #define QUIT 278
82 #define PORT 279
83 #define PASV 280
84 #define TYPE 281
85 #define STRU 282
86 #define MODE 283
87 #define RETR 284
88 #define STOR 285
89 #define APPE 286
90 #define MLFL 287
91 #define MAIL 288
92 #define MSND 289
93 #define MSOM 290
94 #define MSAM 291
95 #define MRSQ 292
96 #define MRCP 293
97 #define ALLO 294
98 #define REST 295
99 #define RNFR 296
100 #define RNTO 297
101 #define ABOR 298
102 #define DELE 299
103 #define CWD 300
104 #define LIST 301
105 #define NLST 302
106 #define SITE 303
107 #define STAT 304
108 #define HELP 305
109 #define NOOP 306
110 #define MKD 307
111 #define RMD 308
112 #define PWD 309
113 #define CDUP 310
114 #define STOU 311
115 #define SMNT 312
116 #define SYST 313
117 #define SIZE 314
118 #define MDTM 315
119 #define UMASK 316
120 #define IDLE 317
121 #define CHMOD 318
122 #define LEXERR 319
123 #define YYERRCODE 256
124 short yylhs[] = { -1,
125 0, 0, 0, 1, 1, 1, 1, 1, 1, 1,
126 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
127 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
128 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
129 1, 1, 1, 1, 1, 1, 2, 3, 4, 4,
130 12, 5, 13, 13, 13, 6, 6, 6, 6, 6,
131 6, 6, 6, 7, 7, 7, 8, 8, 8, 10,
132 14, 11, 9,
133 };
134 short yylen[] = { 2,
135 0, 2, 2, 4, 4, 4, 2, 4, 4, 4,
136 4, 8, 5, 5, 5, 3, 5, 3, 5, 5,
137 2, 5, 4, 2, 3, 5, 2, 4, 2, 5,
138 5, 3, 3, 4, 6, 5, 7, 9, 4, 6,
139 5, 2, 5, 5, 2, 2, 5, 1, 0, 1,
140 1, 11, 1, 1, 1, 1, 3, 1, 3, 1,
141 1, 3, 2, 1, 1, 1, 1, 1, 1, 1,
142 1, 1, 0,
143 };
144 short yydefred[] = { 1,
145 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
146 73, 73, 73, 0, 73, 0, 0, 73, 73, 73,
147 73, 0, 0, 0, 0, 73, 73, 73, 73, 73,
148 0, 73, 73, 2, 3, 46, 0, 0, 45, 0,
149 7, 0, 0, 0, 0, 0, 0, 0, 0, 0,
150 24, 0, 0, 0, 0, 0, 21, 0, 0, 27,
151 29, 0, 0, 0, 0, 0, 42, 0, 0, 48,
152 0, 50, 0, 0, 0, 0, 0, 60, 0, 0,
153 64, 66, 65, 0, 68, 69, 67, 0, 0, 0,
154 0, 0, 0, 71, 0, 70, 0, 0, 25, 0,
155 18, 0, 16, 0, 73, 0, 73, 0, 0, 0,
156 0, 32, 33, 0, 0, 0, 4, 5, 0, 6,
157 0, 0, 0, 51, 63, 8, 9, 10, 0, 0,
158 0, 0, 11, 0, 23, 0, 0, 0, 0, 0,
159 34, 0, 0, 39, 0, 0, 28, 0, 0, 0,
160 0, 0, 0, 55, 53, 54, 57, 59, 62, 13,
161 14, 15, 0, 47, 22, 26, 19, 17, 0, 0,
162 36, 0, 0, 20, 30, 31, 41, 43, 44, 0,
163 0, 35, 72, 0, 40, 0, 0, 0, 37, 0,
164 0, 12, 0, 0, 38, 0, 0, 0, 52,
165 };
166 short yydgoto[] = { 1,
167 34, 35, 71, 73, 75, 80, 84, 88, 45, 95,
168 184, 125, 157, 96,
169 };
170 short yysindex[] = { 0,
171 -224, -247, -239, -236, -232, -222, -204, -200, -181, -177,
172 0, 0, 0, -166, 0, -161, -199, 0, 0, 0,
173 0, -160, -159, -264, -158, 0, 0, 0, 0, 0,
174 -157, 0, 0, 0, 0, 0, -167, -162, 0, -156,
175 0, -250, -198, -165, -155, -154, -153, -151, -150, -152,
176 0, -145, -252, -229, -217, -302, 0, -144, -146, 0,
177 0, -142, -141, -140, -139, -137, 0, -136, -135, 0,
178 -134, 0, -133, -132, -130, -131, -128, 0, -249, -127,
179 0, 0, 0, -126, 0, 0, 0, -125, -152, -152,
180 -152, -205, -152, 0, -124, 0, -152, -152, 0, -152,
181 0, -143, 0, -173, 0, -171, 0, -152, -123, -152,
182 -152, 0, 0, -152, -152, -152, 0, 0, -138, 0,
183 -164, -164, -122, 0, 0, 0, 0, 0, -121, -120,
184 -118, -148, 0, -117, 0, -116, -115, -114, -113, -112,
185 0, -163, -111, 0, -110, -109, 0, -107, -106, -105,
186 -104, -103, -129, 0, 0, 0, 0, 0, 0, 0,
187 0, 0, -101, 0, 0, 0, 0, 0, -100, -102,
188 0, -98, -102, 0, 0, 0, 0, 0, 0, -99,
189 -97, 0, 0, -95, 0, -96, -94, -92, 0, -152,
190 -93, 0, -91, -90, 0, -88, -87, -86, 0,
191 };
192 short yyrindex[] = { 0,
193 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
194 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
195 0, 0, -83, 0, 0, 0, 0, 0, 0, 0,
196 0, 0, 0, 0, 0, 0, 0, -82, 0, 0,
197 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
198 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
199 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
200 0, 0, 0, 0, 0, -81, -80, 0, -158, 0,
201 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
202 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
203 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
204 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
205 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
206 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
207 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
208 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
209 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
210 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
211 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
212 0, 0, 0, 0, 0, 0, 0, 0, 0,
213 };
214 short yygindex[] = { 0,
215 0, 0, 0, 0, 0, 0, 0, 0, 16, -89,
216 -25, 35, 47, 0,
217 };
218 #define YYTABLESIZE 190
219 short yytable[] = { 129,
220 130, 131, 104, 134, 59, 60, 76, 136, 137, 77,
221 138, 78, 79, 105, 106, 107, 98, 99, 146, 123,
222 148, 149, 36, 124, 150, 151, 152, 46, 47, 37,
223 49, 2, 38, 52, 53, 54, 55, 39, 58, 100,
224 101, 62, 63, 64, 65, 66, 40, 68, 69, 3,
225 4, 102, 103, 5, 6, 7, 8, 9, 10, 11,
226 12, 13, 81, 132, 133, 41, 82, 83, 42, 14,
227 51, 15, 16, 17, 18, 19, 20, 21, 22, 23,
228 24, 25, 26, 27, 28, 29, 30, 43, 31, 32,
229 33, 44, 85, 86, 154, 140, 141, 143, 144, 155,
230 193, 87, 48, 156, 70, 170, 171, 50, 56, 72,
231 57, 61, 67, 89, 90, 91, 74, 163, 93, 94,
232 142, 92, 145, 97, 108, 109, 110, 111, 139, 112,
233 113, 114, 115, 116, 153, 117, 118, 121, 119, 120,
234 122, 180, 126, 127, 128, 135, 147, 186, 160, 161,
235 124, 162, 164, 165, 166, 167, 168, 159, 173, 169,
236 174, 172, 175, 176, 177, 178, 179, 181, 158, 182,
237 183, 185, 190, 187, 189, 188, 191, 192, 195, 194,
238 196, 0, 0, 198, 197, 73, 199, 49, 56, 58,
239 };
240 short yycheck[] = { 89,
241 90, 91, 305, 93, 269, 270, 257, 97, 98, 260,
242 100, 262, 263, 316, 317, 318, 269, 270, 108, 269,
243 110, 111, 270, 273, 114, 115, 116, 12, 13, 269,
244 15, 256, 269, 18, 19, 20, 21, 270, 23, 269,
245 270, 26, 27, 28, 29, 30, 269, 32, 33, 274,
246 275, 269, 270, 278, 279, 280, 281, 282, 283, 284,
247 285, 286, 261, 269, 270, 270, 265, 266, 269, 294,
248 270, 296, 297, 298, 299, 300, 301, 302, 303, 304,
249 305, 306, 307, 308, 309, 310, 311, 269, 313, 314,
250 315, 269, 258, 259, 259, 269, 270, 269, 270, 264,
251 190, 267, 269, 268, 272, 269, 270, 269, 269, 272,
252 270, 270, 270, 269, 269, 269, 273, 266, 269, 272,
253 105, 273, 107, 269, 269, 272, 269, 269, 272, 270,
254 270, 269, 269, 269, 273, 270, 270, 269, 271, 270,
255 269, 271, 270, 270, 270, 270, 270, 173, 270, 270,
256 273, 270, 270, 270, 270, 270, 270, 123, 269, 272,
257 270, 273, 270, 270, 270, 270, 270, 269, 122, 270,
258 273, 270, 269, 273, 270, 273, 271, 270, 270, 273,
259 271, -1, -1, 271, 273, 269, 273, 270, 270, 270,
260 };
261 #define YYFINAL 1
262 #ifndef YYDEBUG
263 #define YYDEBUG 0
264 #endif
265 #define YYMAXTOKEN 319
266 #if YYDEBUG
267 char *yyname[] = {
268 "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,
269 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,
270 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,
271 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,
272 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,
273 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,
274 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",
275 "P","R","S","T","SP","CRLF","COMMA","STRING","NUMBER","USER","PASS","ACCT",
276 "REIN","QUIT","PORT","PASV","TYPE","STRU","MODE","RETR","STOR","APPE","MLFL",
277 "MAIL","MSND","MSOM","MSAM","MRSQ","MRCP","ALLO","REST","RNFR","RNTO","ABOR",
278 "DELE","CWD","LIST","NLST","SITE","STAT","HELP","NOOP","MKD","RMD","PWD","CDUP",
279 "STOU","SMNT","SYST","SIZE","MDTM","UMASK","IDLE","CHMOD","LEXERR",
280 };
281 char *yyrule[] = {
282 "$accept : cmd_list",
283 "cmd_list :",
284 "cmd_list : cmd_list cmd",
285 "cmd_list : cmd_list rcmd",
286 "cmd : USER SP username CRLF",
287 "cmd : PASS SP password CRLF",
288 "cmd : PORT SP host_port CRLF",
289 "cmd : PASV CRLF",
290 "cmd : TYPE SP type_code CRLF",
291 "cmd : STRU SP struct_code CRLF",
292 "cmd : MODE SP mode_code CRLF",
293 "cmd : ALLO SP NUMBER CRLF",
294 "cmd : ALLO SP NUMBER SP R SP NUMBER CRLF",
295 "cmd : RETR check_login SP pathname CRLF",
296 "cmd : STOR check_login SP pathname CRLF",
297 "cmd : APPE check_login SP pathname CRLF",
298 "cmd : NLST check_login CRLF",
299 "cmd : NLST check_login SP STRING CRLF",
300 "cmd : LIST check_login CRLF",
301 "cmd : LIST check_login SP pathname CRLF",
302 "cmd : STAT check_login SP pathname CRLF",
303 "cmd : STAT CRLF",
304 "cmd : DELE check_login SP pathname CRLF",
305 "cmd : RNTO SP pathname CRLF",
306 "cmd : ABOR CRLF",
307 "cmd : CWD check_login CRLF",
308 "cmd : CWD check_login SP pathname CRLF",
309 "cmd : HELP CRLF",
310 "cmd : HELP SP STRING CRLF",
311 "cmd : NOOP CRLF",
312 "cmd : MKD check_login SP pathname CRLF",
313 "cmd : RMD check_login SP pathname CRLF",
314 "cmd : PWD check_login CRLF",
315 "cmd : CDUP check_login CRLF",
316 "cmd : SITE SP HELP CRLF",
317 "cmd : SITE SP HELP SP STRING CRLF",
318 "cmd : SITE SP UMASK check_login CRLF",
319 "cmd : SITE SP UMASK check_login SP octal_number CRLF",
320 "cmd : SITE SP CHMOD check_login SP octal_number SP pathname CRLF",
321 "cmd : SITE SP IDLE CRLF",
322 "cmd : SITE SP IDLE SP NUMBER CRLF",
323 "cmd : STOU check_login SP pathname CRLF",
324 "cmd : SYST CRLF",
325 "cmd : SIZE check_login SP pathname CRLF",
326 "cmd : MDTM check_login SP pathname CRLF",
327 "cmd : QUIT CRLF",
328 "cmd : error CRLF",
329 "rcmd : RNFR check_login SP pathname CRLF",
330 "username : STRING",
331 "password :",
332 "password : STRING",
333 "byte_size : NUMBER",
334 "host_port : NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER",
335 "form_code : N",
336 "form_code : T",
337 "form_code : C",
338 "type_code : A",
339 "type_code : A SP form_code",
340 "type_code : E",
341 "type_code : E SP form_code",
342 "type_code : I",
343 "type_code : L",
344 "type_code : L SP byte_size",
345 "type_code : L byte_size",
346 "struct_code : F",
347 "struct_code : R",
348 "struct_code : P",
349 "mode_code : S",
350 "mode_code : B",
351 "mode_code : C",
352 "pathname : pathstring",
353 "pathstring : STRING",
354 "octal_number : NUMBER",
355 "check_login :",
356 };
357 #endif
358 #ifndef YYSTYPE
359 typedef int YYSTYPE;
360 #endif
361 #ifdef YYSTACKSIZE
362 #undef YYMAXDEPTH
363 #define YYMAXDEPTH YYSTACKSIZE
364 #else
365 #ifdef YYMAXDEPTH
366 #define YYSTACKSIZE YYMAXDEPTH
367 #else
368 #define YYSTACKSIZE 500
369 #define YYMAXDEPTH 500
370 #endif
371 #endif
372 int yydebug;
373 int yynerrs;
374 int yyerrflag;
375 int yychar;
376 short *yyssp;
377 YYSTYPE *yyvsp;
378 YYSTYPE yyval;
379 YYSTYPE yylval;
380 short yyss[YYSTACKSIZE];
381 YYSTYPE yyvs[YYSTACKSIZE];
382 #define yystacksize YYSTACKSIZE
383 #line 658 "ftp.y"
384
385 extern jmp_buf errcatch;
386
387 #define CMD 0 /* beginning of command */
388 #define ARGS 1 /* expect miscellaneous arguments */
389 #define STR1 2 /* expect SP followed by STRING */
390 #define STR2 3 /* expect STRING */
391 #define OSTR 4 /* optional SP then STRING */
392 #define ZSTR1 5 /* SP then optional STRING */
393 #define ZSTR2 6 /* optional STRING after SP */
394 #define SITECMD 7 /* SITE command */
395 #define NSTR 8 /* Number followed by a string */
396
397 struct tab {
398 char *name;
399 short token;
400 short state;
401 short implemented; /* 1 if command is implemented */
402 char *help;
403 };
404
405 struct tab cmdtab[] = { /* In order defined in RFC 765 */
406 { "USER", USER, STR1, 1, "<sp> username" },
407 { "PASS", PASS, ZSTR1, 1, "<sp> password" },
408 { "ACCT", ACCT, STR1, 0, "(specify account)" },
409 { "SMNT", SMNT, ARGS, 0, "(structure mount)" },
410 { "REIN", REIN, ARGS, 0, "(reinitialize server state)" },
411 { "QUIT", QUIT, ARGS, 1, "(terminate service)", },
412 { "PORT", PORT, ARGS, 1, "<sp> b0, b1, b2, b3, b4" },
413 { "PASV", PASV, ARGS, 1, "(set server in passive mode)" },
414 { "TYPE", TYPE, ARGS, 1, "<sp> [ A | E | I | L ]" },
415 { "STRU", STRU, ARGS, 1, "(specify file structure)" },
416 { "MODE", MODE, ARGS, 1, "(specify transfer mode)" },
417 { "RETR", RETR, STR1, 1, "<sp> file-name" },
418 { "STOR", STOR, STR1, 1, "<sp> file-name" },
419 { "APPE", APPE, STR1, 1, "<sp> file-name" },
420 { "MLFL", MLFL, OSTR, 0, "(mail file)" },
421 { "MAIL", MAIL, OSTR, 0, "(mail to user)" },
422 { "MSND", MSND, OSTR, 0, "(mail send to terminal)" },
423 { "MSOM", MSOM, OSTR, 0, "(mail send to terminal or mailbox)" },
424 { "MSAM", MSAM, OSTR, 0, "(mail send to terminal and mailbox)" },
425 { "MRSQ", MRSQ, OSTR, 0, "(mail recipient scheme question)" },
426 { "MRCP", MRCP, STR1, 0, "(mail recipient)" },
427 { "ALLO", ALLO, ARGS, 1, "allocate storage (vacuously)" },
428 { "REST", REST, ARGS, 0, "(restart command)" },
429 { "RNFR", RNFR, STR1, 1, "<sp> file-name" },
430 { "RNTO", RNTO, STR1, 1, "<sp> file-name" },
431 { "ABOR", ABOR, ARGS, 1, "(abort operation)" },
432 { "DELE", DELE, STR1, 1, "<sp> file-name" },
433 { "CWD", CWD, OSTR, 1, "[ <sp> directory-name ]" },
434 { "XCWD", CWD, OSTR, 1, "[ <sp> directory-name ]" },
435 { "LIST", LIST, OSTR, 1, "[ <sp> path-name ]" },
436 { "NLST", NLST, OSTR, 1, "[ <sp> path-name ]" },
437 { "SITE", SITE, SITECMD, 1, "site-cmd [ <sp> arguments ]" },
438 { "SYST", SYST, ARGS, 1, "(get type of operating system)" },
439 { "STAT", STAT, OSTR, 1, "[ <sp> path-name ]" },
440 { "HELP", HELP, OSTR, 1, "[ <sp> <string> ]" },
441 { "NOOP", NOOP, ARGS, 1, "" },
442 { "MKD", MKD, STR1, 1, "<sp> path-name" },
443 { "XMKD", MKD, STR1, 1, "<sp> path-name" },
444 { "RMD", RMD, STR1, 1, "<sp> path-name" },
445 { "XRMD", RMD, STR1, 1, "<sp> path-name" },
446 { "PWD", PWD, ARGS, 1, "(return current directory)" },
447 { "XPWD", PWD, ARGS, 1, "(return current directory)" },
448 { "CDUP", CDUP, ARGS, 1, "(change to parent directory)" },
449 { "XCUP", CDUP, ARGS, 1, "(change to parent directory)" },
450 { "STOU", STOU, STR1, 1, "<sp> file-name" },
451 { "SIZE", SIZE, OSTR, 1, "<sp> path-name" },
452 { "MDTM", MDTM, OSTR, 1, "<sp> path-name" },
453 { NULL, 0, 0, 0, 0 }
454 };
455
456 struct tab sitetab[] = {
457 { "UMASK", UMASK, ARGS, 1, "[ <sp> umask ]" },
458 { "IDLE", IDLE, ARGS, 1, "[ <sp> maximum-idle-time ]" },
459 { "CHMOD", CHMOD, NSTR, 1, "<sp> mode <sp> file-name" },
460 { "HELP", HELP, OSTR, 1, "[ <sp> <string> ]" },
461 { NULL, 0, 0, 0, 0 }
462 };
463
464 struct tab *
lookup(p,cmd)465 lookup(p, cmd)
466 register struct tab *p;
467 char *cmd;
468 {
469
470 for (; p->name != NULL; p++)
471 if (strcmp(cmd, p->name) == 0)
472 return (p);
473 return (0);
474 }
475
476 #include <arpa/telnet.h>
477
478 /*
479 * getline - a hacked up version of fgets to ignore TELNET escape codes.
480 */
481 char *
getline(s,n,iop)482 getline(s, n, iop)
483 char *s;
484 register FILE *iop;
485 {
486 register c;
487 register char *cs;
488
489 cs = s;
490 /* tmpline may contain saved command from urgent mode interruption */
491 for (c = 0; tmpline[c] != '\0' && --n > 0; ++c) {
492 *cs++ = tmpline[c];
493 if (tmpline[c] == '\n') {
494 *cs++ = '\0';
495 if (debug)
496 syslog(LOG_DEBUG, "command: %s", s);
497 tmpline[0] = '\0';
498 return(s);
499 }
500 if (c == 0)
501 tmpline[0] = '\0';
502 }
503 while ((c = getc(iop)) != EOF) {
504 c &= 0377;
505 if (c == IAC) {
506 if ((c = getc(iop)) != EOF) {
507 c &= 0377;
508 switch (c) {
509 case WILL:
510 case WONT:
511 c = getc(iop);
512 printf("%c%c%c", IAC, DONT, 0377&c);
513 (void) fflush(stdout);
514 continue;
515 case DO:
516 case DONT:
517 c = getc(iop);
518 printf("%c%c%c", IAC, WONT, 0377&c);
519 (void) fflush(stdout);
520 continue;
521 case IAC:
522 break;
523 default:
524 continue; /* ignore command */
525 }
526 }
527 }
528 *cs++ = c;
529 if (--n <= 0 || c == '\n')
530 break;
531 }
532 if (c == EOF && cs == s)
533 return (NULL);
534 *cs++ = '\0';
535 if (debug)
536 syslog(LOG_DEBUG, "command: %s", s);
537 return (s);
538 }
539
540 static int
toolong()541 toolong()
542 {
543 time_t now;
544 extern char *ctime();
545 extern time_t time();
546
547 reply(421,
548 "Timeout (%d seconds): closing control connection.", timeout);
549 (void) time(&now);
550 if (logging) {
551 syslog(LOG_INFO,
552 "User %s timed out after %d seconds at %s",
553 (pw ? pw -> pw_name : "unknown"), timeout, ctime(&now));
554 }
555 dologout(1);
556 }
557
yylex()558 yylex()
559 {
560 static int cpos, state;
561 register char *cp, *cp2;
562 register struct tab *p;
563 int n;
564 char c, *strpbrk();
565 char *copy();
566
567 for (;;) {
568 switch (state) {
569
570 case CMD:
571 (void) signal(SIGALRM, toolong);
572 (void) alarm((unsigned) timeout);
573 if (getline(cbuf, sizeof(cbuf)-1, stdin) == NULL) {
574 reply(221, "You could at least say goodbye.");
575 dologout(0);
576 }
577 (void) alarm(0);
578 #ifdef SETPROCTITLE
579 if (strncasecmp(cbuf, "PASS", 4) != NULL)
580 setproctitle("%s: %s", proctitle, cbuf);
581 #endif /* SETPROCTITLE */
582 if ((cp = index(cbuf, '\r'))) {
583 *cp++ = '\n';
584 *cp = '\0';
585 }
586 if ((cp = strpbrk(cbuf, " \n")))
587 cpos = cp - cbuf;
588 if (cpos == 0)
589 cpos = 4;
590 c = cbuf[cpos];
591 cbuf[cpos] = '\0';
592 upper(cbuf);
593 p = lookup(cmdtab, cbuf);
594 cbuf[cpos] = c;
595 if (p != 0) {
596 if (p->implemented == 0) {
597 nack(p->name);
598 longjmp(errcatch,0);
599 /* NOTREACHED */
600 }
601 state = p->state;
602 *(char **)&yylval = p->name;
603 return (p->token);
604 }
605 break;
606
607 case SITECMD:
608 if (cbuf[cpos] == ' ') {
609 cpos++;
610 return (SP);
611 }
612 cp = &cbuf[cpos];
613 if ((cp2 = strpbrk(cp, " \n")))
614 cpos = cp2 - cbuf;
615 c = cbuf[cpos];
616 cbuf[cpos] = '\0';
617 upper(cp);
618 p = lookup(sitetab, cp);
619 cbuf[cpos] = c;
620 if (p != 0) {
621 if (p->implemented == 0) {
622 state = CMD;
623 nack(p->name);
624 longjmp(errcatch,0);
625 /* NOTREACHED */
626 }
627 state = p->state;
628 *(char **)&yylval = p->name;
629 return (p->token);
630 }
631 state = CMD;
632 break;
633
634 case OSTR:
635 if (cbuf[cpos] == '\n') {
636 state = CMD;
637 return (CRLF);
638 }
639 /* FALLTHROUGH */
640
641 case STR1:
642 case ZSTR1:
643 dostr1:
644 if (cbuf[cpos] == ' ') {
645 cpos++;
646 state = state == OSTR ? STR2 : ++state;
647 return (SP);
648 }
649 break;
650
651 case ZSTR2:
652 if (cbuf[cpos] == '\n') {
653 state = CMD;
654 return (CRLF);
655 }
656 /* FALLTHROUGH */
657
658 case STR2:
659 cp = &cbuf[cpos];
660 n = strlen(cp);
661 cpos += n - 1;
662 /*
663 * Make sure the string is nonempty and \n terminated.
664 */
665 if (n > 1 && cbuf[cpos] == '\n') {
666 cbuf[cpos] = '\0';
667 *(char **)&yylval = copy(cp);
668 cbuf[cpos] = '\n';
669 state = ARGS;
670 return (STRING);
671 }
672 break;
673
674 case NSTR:
675 if (cbuf[cpos] == ' ') {
676 cpos++;
677 return (SP);
678 }
679 if (isdigit(cbuf[cpos])) {
680 cp = &cbuf[cpos];
681 while (isdigit(cbuf[++cpos]))
682 ;
683 c = cbuf[cpos];
684 cbuf[cpos] = '\0';
685 yylval = atoi(cp);
686 cbuf[cpos] = c;
687 state = STR1;
688 return (NUMBER);
689 }
690 state = STR1;
691 goto dostr1;
692
693 case ARGS:
694 if (isdigit(cbuf[cpos])) {
695 cp = &cbuf[cpos];
696 while (isdigit(cbuf[++cpos]))
697 ;
698 c = cbuf[cpos];
699 cbuf[cpos] = '\0';
700 yylval = atoi(cp);
701 cbuf[cpos] = c;
702 return (NUMBER);
703 }
704 switch (cbuf[cpos++]) {
705
706 case '\n':
707 state = CMD;
708 return (CRLF);
709
710 case ' ':
711 return (SP);
712
713 case ',':
714 return (COMMA);
715
716 case 'A':
717 case 'a':
718 return (A);
719
720 case 'B':
721 case 'b':
722 return (B);
723
724 case 'C':
725 case 'c':
726 return (C);
727
728 case 'E':
729 case 'e':
730 return (E);
731
732 case 'F':
733 case 'f':
734 return (F);
735
736 case 'I':
737 case 'i':
738 return (I);
739
740 case 'L':
741 case 'l':
742 return (L);
743
744 case 'N':
745 case 'n':
746 return (N);
747
748 case 'P':
749 case 'p':
750 return (P);
751
752 case 'R':
753 case 'r':
754 return (R);
755
756 case 'S':
757 case 's':
758 return (S);
759
760 case 'T':
761 case 't':
762 return (T);
763
764 }
765 break;
766
767 default:
768 fatal("Unknown state in scanner.");
769 }
770 yyerror((char *) 0);
771 state = CMD;
772 longjmp(errcatch,0);
773 }
774 }
775
upper(s)776 upper(s)
777 register char *s;
778 {
779 while (*s != '\0') {
780 if (islower(*s))
781 *s = toupper(*s);
782 s++;
783 }
784 }
785
786 char *
copy(s)787 copy(s)
788 char *s;
789 {
790 char *p;
791 extern char *malloc(), *strcpy();
792
793 p = malloc((unsigned) strlen(s) + 1);
794 if (p == NULL)
795 fatal("Ran out of memory.");
796 (void) strcpy(p, s);
797 return (p);
798 }
799
800 help(ctab, s)
801 struct tab *ctab;
802 char *s;
803 {
804 register struct tab *c;
805 register int width, NCMDS;
806 char *type;
807
808 if (ctab == sitetab)
809 type = "SITE ";
810 else
811 type = "";
812 width = 0, NCMDS = 0;
813 for (c = ctab; c->name != NULL; c++) {
814 int len = strlen(c->name);
815
816 if (len > width)
817 width = len;
818 NCMDS++;
819 }
820 width = (width + 8) &~ 7;
821 if (s == 0) {
822 register int i, j, w;
823 int columns, lines;
824
825 lreply(214, "The following %scommands are recognized %s.",
826 type, "(* =>'s unimplemented)");
827 columns = 76 / width;
828 if (columns == 0)
829 columns = 1;
830 lines = (NCMDS + columns - 1) / columns;
831 for (i = 0; i < lines; i++) {
832 printf(" ");
833 for (j = 0; j < columns; j++) {
834 c = ctab + j * lines + i;
835 printf("%s%c", c->name,
836 c->implemented ? ' ' : '*');
837 if (c + lines >= &ctab[NCMDS])
838 break;
839 w = strlen(c->name) + 1;
840 while (w < width) {
841 putchar(' ');
842 w++;
843 }
844 }
845 printf("\r\n");
846 }
847 (void) fflush(stdout);
848 reply(214, "Direct comments to ftp-bugs@%s.", hostname);
849 return;
850 }
851 upper(s);
852 c = lookup(ctab, s);
853 if (c == (struct tab *)0) {
854 reply(502, "Unknown command %s.", s);
855 return;
856 }
857 if (c->implemented)
858 reply(214, "Syntax: %s%s %s", type, c->name, c->help);
859 else
860 reply(214, "%s%-*s\t%s; unimplemented.", type, width,
861 c->name, c->help);
862 }
863
sizecmd(filename)864 sizecmd(filename)
865 char *filename;
866 {
867 switch (type) {
868 case TYPE_L:
869 case TYPE_I: {
870 struct stat stbuf;
871 if (stat(filename, &stbuf) < 0 ||
872 (stbuf.st_mode&S_IFMT) != S_IFREG)
873 reply(550, "%s: not a plain file.", filename);
874 else
875 reply(213, "%lu", stbuf.st_size);
876 break;}
877 case TYPE_A: {
878 FILE *fin;
879 register int c, count;
880 struct stat stbuf;
881 fin = fopen(filename, "r");
882 if (fin == NULL) {
883 perror_reply(550, filename);
884 return;
885 }
886 if (fstat(fileno(fin), &stbuf) < 0 ||
887 (stbuf.st_mode&S_IFMT) != S_IFREG) {
888 reply(550, "%s: not a plain file.", filename);
889 (void) fclose(fin);
890 return;
891 }
892
893 count = 0;
894 while((c=getc(fin)) != EOF) {
895 if (c == '\n') /* will get expanded to \r\n */
896 count++;
897 count++;
898 }
899 (void) fclose(fin);
900
901 reply(213, "%ld", count);
902 break;}
903 default:
904 reply(504, "SIZE not implemented for Type %c.", "?AEIL"[type]);
905 }
906 }
907 #line 908 "ftp.tab.c"
908 #define YYABORT goto yyabort
909 #define YYREJECT goto yyabort
910 #define YYACCEPT goto yyaccept
911 #define YYERROR goto yyerrlab
912 int
yyparse()913 yyparse()
914 {
915 register int yym, yyn, yystate;
916 #if YYDEBUG
917 register char *yys;
918 extern char *getenv();
919
920 if (yys = getenv("YYDEBUG"))
921 {
922 yyn = *yys;
923 if (yyn >= '0' && yyn <= '9')
924 yydebug = yyn - '0';
925 }
926 #endif
927
928 yynerrs = 0;
929 yyerrflag = 0;
930 yychar = (-1);
931
932 yyssp = yyss;
933 yyvsp = yyvs;
934 *yyssp = yystate = 0;
935
936 yyloop:
937 if (yyn = yydefred[yystate]) goto yyreduce;
938 if (yychar < 0)
939 {
940 if ((yychar = yylex()) < 0) yychar = 0;
941 #if YYDEBUG
942 if (yydebug)
943 {
944 yys = 0;
945 if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
946 if (!yys) yys = "illegal-symbol";
947 printf("%sdebug: state %d, reading %d (%s)\n",
948 YYPREFIX, yystate, yychar, yys);
949 }
950 #endif
951 }
952 if ((yyn = yysindex[yystate]) && (yyn += yychar) >= 0 &&
953 yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
954 {
955 #if YYDEBUG
956 if (yydebug)
957 printf("%sdebug: state %d, shifting to state %d\n",
958 YYPREFIX, yystate, yytable[yyn]);
959 #endif
960 if (yyssp >= yyss + yystacksize - 1)
961 {
962 goto yyoverflow;
963 }
964 *++yyssp = yystate = yytable[yyn];
965 *++yyvsp = yylval;
966 yychar = (-1);
967 if (yyerrflag > 0) --yyerrflag;
968 goto yyloop;
969 }
970 if ((yyn = yyrindex[yystate]) && (yyn += yychar) >= 0 &&
971 yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
972 {
973 yyn = yytable[yyn];
974 goto yyreduce;
975 }
976 if (yyerrflag) goto yyinrecovery;
977 #ifdef lint
978 goto yynewerror;
979 #endif
980 yynewerror:
981 yyerror("syntax error");
982 #ifdef lint
983 goto yyerrlab;
984 #endif
985 yyerrlab:
986 ++yynerrs;
987 yyinrecovery:
988 if (yyerrflag < 3)
989 {
990 yyerrflag = 3;
991 for (;;)
992 {
993 if ((yyn = yysindex[*yyssp]) && (yyn += YYERRCODE) >= 0 &&
994 yyn <= YYTABLESIZE && yycheck[yyn] == YYERRCODE)
995 {
996 #if YYDEBUG
997 if (yydebug)
998 printf("%sdebug: state %d, error recovery shifting\
999 to state %d\n", YYPREFIX, *yyssp, yytable[yyn]);
1000 #endif
1001 if (yyssp >= yyss + yystacksize - 1)
1002 {
1003 goto yyoverflow;
1004 }
1005 *++yyssp = yystate = yytable[yyn];
1006 *++yyvsp = yylval;
1007 goto yyloop;
1008 }
1009 else
1010 {
1011 #if YYDEBUG
1012 if (yydebug)
1013 printf("%sdebug: error recovery discarding state %d\n",
1014 YYPREFIX, *yyssp);
1015 #endif
1016 if (yyssp <= yyss) goto yyabort;
1017 --yyssp;
1018 --yyvsp;
1019 }
1020 }
1021 }
1022 else
1023 {
1024 if (yychar == 0) goto yyabort;
1025 #if YYDEBUG
1026 if (yydebug)
1027 {
1028 yys = 0;
1029 if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
1030 if (!yys) yys = "illegal-symbol";
1031 printf("%sdebug: state %d, error recovery discards token %d (%s)\n",
1032 YYPREFIX, yystate, yychar, yys);
1033 }
1034 #endif
1035 yychar = (-1);
1036 goto yyloop;
1037 }
1038 yyreduce:
1039 #if YYDEBUG
1040 if (yydebug)
1041 printf("%sdebug: state %d, reducing by rule %d (%s)\n",
1042 YYPREFIX, yystate, yyn, yyrule[yyn]);
1043 #endif
1044 yym = yylen[yyn];
1045 yyval = yyvsp[1-yym];
1046 switch (yyn)
1047 {
1048 case 2:
1049 #line 99 "ftp.y"
1050 {
1051 fromname = (char *) 0;
1052 }
1053 break;
1054 case 4:
1055 #line 106 "ftp.y"
1056 {
1057 user((char *) yyvsp[-1]);
1058 free((char *) yyvsp[-1]);
1059 }
1060 break;
1061 case 5:
1062 #line 111 "ftp.y"
1063 {
1064 pass((char *) yyvsp[-1]);
1065 free((char *) yyvsp[-1]);
1066 }
1067 break;
1068 case 6:
1069 #line 116 "ftp.y"
1070 {
1071 usedefault = 0;
1072 if (pdata >= 0) {
1073 (void) close(pdata);
1074 pdata = -1;
1075 }
1076 reply(200, "PORT command successful.");
1077 }
1078 break;
1079 case 7:
1080 #line 125 "ftp.y"
1081 {
1082 passive();
1083 }
1084 break;
1085 case 8:
1086 #line 129 "ftp.y"
1087 {
1088 switch (cmd_type) {
1089
1090 case TYPE_A:
1091 if (cmd_form == FORM_N) {
1092 reply(200, "Type set to A.");
1093 type = cmd_type;
1094 form = cmd_form;
1095 } else
1096 reply(504, "Form must be N.");
1097 break;
1098
1099 case TYPE_E:
1100 reply(504, "Type E not implemented.");
1101 break;
1102
1103 case TYPE_I:
1104 reply(200, "Type set to I.");
1105 type = cmd_type;
1106 break;
1107
1108 case TYPE_L:
1109 #if NBBY == 8
1110 if (cmd_bytesz == 8) {
1111 reply(200,
1112 "Type set to L (byte size 8).");
1113 type = cmd_type;
1114 } else
1115 reply(504, "Byte size must be 8.");
1116 #else /* NBBY == 8 */
1117 UNIMPLEMENTED for NBBY != 8
1118 #endif /* NBBY == 8 */
1119 }
1120 }
1121 break;
1122 case 9:
1123 #line 164 "ftp.y"
1124 {
1125 switch (yyvsp[-1]) {
1126
1127 case STRU_F:
1128 reply(200, "STRU F ok.");
1129 break;
1130
1131 default:
1132 reply(504, "Unimplemented STRU type.");
1133 }
1134 }
1135 break;
1136 case 10:
1137 #line 176 "ftp.y"
1138 {
1139 switch (yyvsp[-1]) {
1140
1141 case MODE_S:
1142 reply(200, "MODE S ok.");
1143 break;
1144
1145 default:
1146 reply(502, "Unimplemented MODE type.");
1147 }
1148 }
1149 break;
1150 case 11:
1151 #line 188 "ftp.y"
1152 {
1153 reply(202, "ALLO command ignored.");
1154 }
1155 break;
1156 case 12:
1157 #line 192 "ftp.y"
1158 {
1159 reply(202, "ALLO command ignored.");
1160 }
1161 break;
1162 case 13:
1163 #line 196 "ftp.y"
1164 {
1165 if (yyvsp[-3] && yyvsp[-1] != NULL)
1166 retrieve((char *) 0, (char *) yyvsp[-1]);
1167 if (yyvsp[-1] != NULL)
1168 free((char *) yyvsp[-1]);
1169 }
1170 break;
1171 case 14:
1172 #line 203 "ftp.y"
1173 {
1174 if (yyvsp[-3] && yyvsp[-1] != NULL)
1175 store((char *) yyvsp[-1], "w", 0);
1176 if (yyvsp[-1] != NULL)
1177 free((char *) yyvsp[-1]);
1178 }
1179 break;
1180 case 15:
1181 #line 210 "ftp.y"
1182 {
1183 if (yyvsp[-3] && yyvsp[-1] != NULL)
1184 store((char *) yyvsp[-1], "a", 0);
1185 if (yyvsp[-1] != NULL)
1186 free((char *) yyvsp[-1]);
1187 }
1188 break;
1189 case 16:
1190 #line 217 "ftp.y"
1191 {
1192 if (yyvsp[-1])
1193 send_file_list(".");
1194 }
1195 break;
1196 case 17:
1197 #line 222 "ftp.y"
1198 {
1199 if (yyvsp[-3] && yyvsp[-1] != NULL)
1200 send_file_list((char *) yyvsp[-1]);
1201 if (yyvsp[-1] != NULL)
1202 free((char *) yyvsp[-1]);
1203 }
1204 break;
1205 case 18:
1206 #line 229 "ftp.y"
1207 {
1208 if (yyvsp[-1])
1209 retrieve("/bin/ls -lgA", "");
1210 }
1211 break;
1212 case 19:
1213 #line 234 "ftp.y"
1214 {
1215 if (yyvsp[-3] && yyvsp[-1] != NULL)
1216 retrieve("/bin/ls -lgA %s", (char *) yyvsp[-1]);
1217 if (yyvsp[-1] != NULL)
1218 free((char *) yyvsp[-1]);
1219 }
1220 break;
1221 case 20:
1222 #line 241 "ftp.y"
1223 {
1224 if (yyvsp[-3] && yyvsp[-1] != NULL)
1225 statfilecmd((char *) yyvsp[-1]);
1226 if (yyvsp[-1] != NULL)
1227 free((char *) yyvsp[-1]);
1228 }
1229 break;
1230 case 21:
1231 #line 248 "ftp.y"
1232 {
1233 statcmd();
1234 }
1235 break;
1236 case 22:
1237 #line 252 "ftp.y"
1238 {
1239 if (yyvsp[-3] && yyvsp[-1] != NULL)
1240 delete((char *) yyvsp[-1]);
1241 if (yyvsp[-1] != NULL)
1242 free((char *) yyvsp[-1]);
1243 }
1244 break;
1245 case 23:
1246 #line 259 "ftp.y"
1247 {
1248 if (fromname) {
1249 renamecmd(fromname, (char *) yyvsp[-1]);
1250 free(fromname);
1251 fromname = (char *) 0;
1252 } else {
1253 reply(503, "Bad sequence of commands.");
1254 }
1255 free((char *) yyvsp[-1]);
1256 }
1257 break;
1258 case 24:
1259 #line 270 "ftp.y"
1260 {
1261 reply(225, "ABOR command successful.");
1262 }
1263 break;
1264 case 25:
1265 #line 274 "ftp.y"
1266 {
1267 if (yyvsp[-1])
1268 cwd(pw->pw_dir);
1269 }
1270 break;
1271 case 26:
1272 #line 279 "ftp.y"
1273 {
1274 if (yyvsp[-3] && yyvsp[-1] != NULL)
1275 cwd((char *) yyvsp[-1]);
1276 if (yyvsp[-1] != NULL)
1277 free((char *) yyvsp[-1]);
1278 }
1279 break;
1280 case 27:
1281 #line 286 "ftp.y"
1282 {
1283 help(cmdtab, (char *) 0);
1284 }
1285 break;
1286 case 28:
1287 #line 290 "ftp.y"
1288 {
1289 register char *cp = (char *)yyvsp[-1];
1290
1291 if (strncasecmp(cp, "SITE", 4) == 0) {
1292 cp = (char *)yyvsp[-1] + 4;
1293 if (*cp == ' ')
1294 cp++;
1295 if (*cp)
1296 help(sitetab, cp);
1297 else
1298 help(sitetab, (char *) 0);
1299 } else
1300 help(cmdtab, (char *) yyvsp[-1]);
1301 }
1302 break;
1303 case 29:
1304 #line 305 "ftp.y"
1305 {
1306 reply(200, "NOOP command successful.");
1307 }
1308 break;
1309 case 30:
1310 #line 309 "ftp.y"
1311 {
1312 if (yyvsp[-3] && yyvsp[-1] != NULL)
1313 makedir((char *) yyvsp[-1]);
1314 if (yyvsp[-1] != NULL)
1315 free((char *) yyvsp[-1]);
1316 }
1317 break;
1318 case 31:
1319 #line 316 "ftp.y"
1320 {
1321 if (yyvsp[-3] && yyvsp[-1] != NULL)
1322 removedir((char *) yyvsp[-1]);
1323 if (yyvsp[-1] != NULL)
1324 free((char *) yyvsp[-1]);
1325 }
1326 break;
1327 case 32:
1328 #line 323 "ftp.y"
1329 {
1330 if (yyvsp[-1])
1331 pwd();
1332 }
1333 break;
1334 case 33:
1335 #line 328 "ftp.y"
1336 {
1337 if (yyvsp[-1])
1338 cwd("..");
1339 }
1340 break;
1341 case 34:
1342 #line 333 "ftp.y"
1343 {
1344 help(sitetab, (char *) 0);
1345 }
1346 break;
1347 case 35:
1348 #line 337 "ftp.y"
1349 {
1350 help(sitetab, (char *) yyvsp[-1]);
1351 }
1352 break;
1353 case 36:
1354 #line 341 "ftp.y"
1355 {
1356 int oldmask;
1357
1358 if (yyvsp[-1]) {
1359 oldmask = umask(0);
1360 (void) umask(oldmask);
1361 reply(200, "Current UMASK is %03o", oldmask);
1362 }
1363 }
1364 break;
1365 case 37:
1366 #line 351 "ftp.y"
1367 {
1368 int oldmask;
1369
1370 if (yyvsp[-3]) {
1371 if ((yyvsp[-1] == -1) || (yyvsp[-1] > 0777)) {
1372 reply(501, "Bad UMASK value");
1373 } else {
1374 oldmask = umask(yyvsp[-1]);
1375 reply(200,
1376 "UMASK set to %03o (was %03o)",
1377 yyvsp[-1], oldmask);
1378 }
1379 }
1380 }
1381 break;
1382 case 38:
1383 #line 366 "ftp.y"
1384 {
1385 if (yyvsp[-5] && (yyvsp[-1] != NULL)) {
1386 if (yyvsp[-3] > 0777)
1387 reply(501,
1388 "CHMOD: Mode value must be between 0 and 0777");
1389 else if (chmod((char *) yyvsp[-1], yyvsp[-3]) < 0)
1390 perror_reply(550, (char *) yyvsp[-1]);
1391 else
1392 reply(200, "CHMOD command successful.");
1393 }
1394 if (yyvsp[-1] != NULL)
1395 free((char *) yyvsp[-1]);
1396 }
1397 break;
1398 case 39:
1399 #line 380 "ftp.y"
1400 {
1401 reply(200,
1402 "Current IDLE time limit is %d seconds; max %d",
1403 timeout, maxtimeout);
1404 }
1405 break;
1406 case 40:
1407 #line 386 "ftp.y"
1408 {
1409 if (yyvsp[-1] < 30 || yyvsp[-1] > maxtimeout) {
1410 reply(501,
1411 "Maximum IDLE time must be between 30 and %d seconds",
1412 maxtimeout);
1413 } else {
1414 timeout = yyvsp[-1];
1415 (void) alarm((unsigned) timeout);
1416 reply(200,
1417 "Maximum IDLE time set to %d seconds",
1418 timeout);
1419 }
1420 }
1421 break;
1422 case 41:
1423 #line 400 "ftp.y"
1424 {
1425 if (yyvsp[-3] && yyvsp[-1] != NULL)
1426 store((char *) yyvsp[-1], "w", 1);
1427 if (yyvsp[-1] != NULL)
1428 free((char *) yyvsp[-1]);
1429 }
1430 break;
1431 case 42:
1432 #line 407 "ftp.y"
1433 {
1434 #ifdef unix
1435 #ifdef BSD
1436 reply(215, "UNIX Type: L%d Version: BSD-%d",
1437 NBBY, BSD);
1438 #else /* BSD */
1439 reply(215, "UNIX Type: L%d", NBBY);
1440 #endif /* BSD */
1441 #else /* unix */
1442 reply(215, "UNKNOWN Type: L%d", NBBY);
1443 #endif /* unix */
1444 }
1445 break;
1446 case 43:
1447 #line 428 "ftp.y"
1448 {
1449 if (yyvsp[-3] && yyvsp[-1] != NULL)
1450 sizecmd((char *) yyvsp[-1]);
1451 if (yyvsp[-1] != NULL)
1452 free((char *) yyvsp[-1]);
1453 }
1454 break;
1455 case 44:
1456 #line 445 "ftp.y"
1457 {
1458 if (yyvsp[-3] && yyvsp[-1] != NULL) {
1459 struct stat stbuf;
1460 if (stat((char *) yyvsp[-1], &stbuf) < 0)
1461 perror_reply(550, "%s", (char *) yyvsp[-1]);
1462 else if ((stbuf.st_mode&S_IFMT) != S_IFREG) {
1463 reply(550, "%s: not a plain file.",
1464 (char *) yyvsp[-1]);
1465 } else {
1466 register struct tm *t;
1467 struct tm *gmtime();
1468 t = gmtime(&stbuf.st_mtime);
1469 reply(213,
1470 "19%02d%02d%02d%02d%02d%02d",
1471 t->tm_year, t->tm_mon+1, t->tm_mday,
1472 t->tm_hour, t->tm_min, t->tm_sec);
1473 }
1474 }
1475 if (yyvsp[-1] != NULL)
1476 free((char *) yyvsp[-1]);
1477 }
1478 break;
1479 case 45:
1480 #line 467 "ftp.y"
1481 {
1482 reply(221, "Goodbye.");
1483 dologout(0);
1484 }
1485 break;
1486 case 46:
1487 #line 472 "ftp.y"
1488 {
1489 yyerrok;
1490 }
1491 break;
1492 case 47:
1493 #line 477 "ftp.y"
1494 {
1495 char *renamefrom();
1496
1497 if (yyvsp[-3] && yyvsp[-1]) {
1498 fromname = renamefrom((char *) yyvsp[-1]);
1499 if (fromname == (char *) 0 && yyvsp[-1]) {
1500 free((char *) yyvsp[-1]);
1501 }
1502 }
1503 }
1504 break;
1505 case 49:
1506 #line 493 "ftp.y"
1507 {
1508 *(char **)&(yyval) = "";
1509 }
1510 break;
1511 case 52:
1512 #line 504 "ftp.y"
1513 {
1514 register char *a, *p;
1515
1516 a = (char *)&data_dest.sin_addr;
1517 a[0] = yyvsp[-10]; a[1] = yyvsp[-8]; a[2] = yyvsp[-6]; a[3] = yyvsp[-4];
1518 p = (char *)&data_dest.sin_port;
1519 p[0] = yyvsp[-2]; p[1] = yyvsp[0];
1520 data_dest.sin_family = AF_INET;
1521 }
1522 break;
1523 case 53:
1524 #line 516 "ftp.y"
1525 {
1526 yyval = FORM_N;
1527 }
1528 break;
1529 case 54:
1530 #line 520 "ftp.y"
1531 {
1532 yyval = FORM_T;
1533 }
1534 break;
1535 case 55:
1536 #line 524 "ftp.y"
1537 {
1538 yyval = FORM_C;
1539 }
1540 break;
1541 case 56:
1542 #line 530 "ftp.y"
1543 {
1544 cmd_type = TYPE_A;
1545 cmd_form = FORM_N;
1546 }
1547 break;
1548 case 57:
1549 #line 535 "ftp.y"
1550 {
1551 cmd_type = TYPE_A;
1552 cmd_form = yyvsp[0];
1553 }
1554 break;
1555 case 58:
1556 #line 540 "ftp.y"
1557 {
1558 cmd_type = TYPE_E;
1559 cmd_form = FORM_N;
1560 }
1561 break;
1562 case 59:
1563 #line 545 "ftp.y"
1564 {
1565 cmd_type = TYPE_E;
1566 cmd_form = yyvsp[0];
1567 }
1568 break;
1569 case 60:
1570 #line 550 "ftp.y"
1571 {
1572 cmd_type = TYPE_I;
1573 }
1574 break;
1575 case 61:
1576 #line 554 "ftp.y"
1577 {
1578 cmd_type = TYPE_L;
1579 cmd_bytesz = NBBY;
1580 }
1581 break;
1582 case 62:
1583 #line 559 "ftp.y"
1584 {
1585 cmd_type = TYPE_L;
1586 cmd_bytesz = yyvsp[0];
1587 }
1588 break;
1589 case 63:
1590 #line 565 "ftp.y"
1591 {
1592 cmd_type = TYPE_L;
1593 cmd_bytesz = yyvsp[0];
1594 }
1595 break;
1596 case 64:
1597 #line 572 "ftp.y"
1598 {
1599 yyval = STRU_F;
1600 }
1601 break;
1602 case 65:
1603 #line 576 "ftp.y"
1604 {
1605 yyval = STRU_R;
1606 }
1607 break;
1608 case 66:
1609 #line 580 "ftp.y"
1610 {
1611 yyval = STRU_P;
1612 }
1613 break;
1614 case 67:
1615 #line 586 "ftp.y"
1616 {
1617 yyval = MODE_S;
1618 }
1619 break;
1620 case 68:
1621 #line 590 "ftp.y"
1622 {
1623 yyval = MODE_B;
1624 }
1625 break;
1626 case 69:
1627 #line 594 "ftp.y"
1628 {
1629 yyval = MODE_C;
1630 }
1631 break;
1632 case 70:
1633 #line 600 "ftp.y"
1634 {
1635 /*
1636 * Problem: this production is used for all pathname
1637 * processing, but only gives a 550 error reply.
1638 * This is a valid reply in some cases but not in others.
1639 */
1640 if (logged_in && yyvsp[0] && strncmp((char *) yyvsp[0], "~", 1) == 0) {
1641 *(char **)&(yyval) = *glob((char *) yyvsp[0]);
1642 if (globerr != NULL) {
1643 reply(550, globerr);
1644 yyval = NULL;
1645 }
1646 free((char *) yyvsp[0]);
1647 } else
1648 yyval = yyvsp[0];
1649 }
1650 break;
1651 case 72:
1652 #line 622 "ftp.y"
1653 {
1654 register int ret, dec, multby, digit;
1655
1656 /*
1657 * Convert a number that was read as decimal number
1658 * to what it would be if it had been read as octal.
1659 */
1660 dec = yyvsp[0];
1661 multby = 1;
1662 ret = 0;
1663 while (dec) {
1664 digit = dec%10;
1665 if (digit > 7) {
1666 ret = -1;
1667 break;
1668 }
1669 ret += digit * multby;
1670 multby *= 8;
1671 dec /= 10;
1672 }
1673 yyval = ret;
1674 }
1675 break;
1676 case 73:
1677 #line 647 "ftp.y"
1678 {
1679 if (logged_in)
1680 yyval = 1;
1681 else {
1682 reply(530, "Please login with USER and PASS.");
1683 yyval = 0;
1684 }
1685 }
1686 break;
1687 #line 1688 "ftp.tab.c"
1688 }
1689 yyssp -= yym;
1690 yystate = *yyssp;
1691 yyvsp -= yym;
1692 yym = yylhs[yyn];
1693 if (yystate == 0 && yym == 0)
1694 {
1695 #if YYDEBUG
1696 if (yydebug)
1697 printf("%sdebug: after reduction, shifting from state 0 to\
1698 state %d\n", YYPREFIX, YYFINAL);
1699 #endif
1700 yystate = YYFINAL;
1701 *++yyssp = YYFINAL;
1702 *++yyvsp = yyval;
1703 if (yychar < 0)
1704 {
1705 if ((yychar = yylex()) < 0) yychar = 0;
1706 #if YYDEBUG
1707 if (yydebug)
1708 {
1709 yys = 0;
1710 if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
1711 if (!yys) yys = "illegal-symbol";
1712 printf("%sdebug: state %d, reading %d (%s)\n",
1713 YYPREFIX, YYFINAL, yychar, yys);
1714 }
1715 #endif
1716 }
1717 if (yychar == 0) goto yyaccept;
1718 goto yyloop;
1719 }
1720 if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 &&
1721 yyn <= YYTABLESIZE && yycheck[yyn] == yystate)
1722 yystate = yytable[yyn];
1723 else
1724 yystate = yydgoto[yym];
1725 #if YYDEBUG
1726 if (yydebug)
1727 printf("%sdebug: after reduction, shifting from state %d \
1728 to state %d\n", YYPREFIX, *yyssp, yystate);
1729 #endif
1730 if (yyssp >= yyss + yystacksize - 1)
1731 {
1732 goto yyoverflow;
1733 }
1734 *++yyssp = yystate;
1735 *++yyvsp = yyval;
1736 goto yyloop;
1737 yyoverflow:
1738 yyerror("yacc stack overflow");
1739 yyabort:
1740 return (1);
1741 yyaccept:
1742 return (0);
1743 }
1744