Mercurial > gftp.yaz
annotate lib/rfc959.c @ 414:e55f3cd03048
Updated Serbian translation.
author | danilo |
---|---|
date | Mon, 01 Mar 2004 17:29:13 +0000 |
parents | c43caf0691c6 |
children | 1ffdbc487a70 |
rev | line source |
---|---|
1 | 1 /*****************************************************************************/ |
2 /* rfc959.c - General purpose routines for the FTP protocol (RFC 959) */ | |
122 | 3 /* Copyright (C) 1998-2003 Brian Masney <masneyb@gftp.org> */ |
1 | 4 /* */ |
5 /* This program is free software; you can redistribute it and/or modify */ | |
6 /* it under the terms of the GNU General Public License as published by */ | |
7 /* the Free Software Foundation; either version 2 of the License, or */ | |
8 /* (at your option) any later version. */ | |
9 /* */ | |
10 /* This program is distributed in the hope that it will be useful, */ | |
11 /* but WITHOUT ANY WARRANTY; without even the implied warranty of */ | |
12 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ | |
13 /* GNU General Public License for more details. */ | |
14 /* */ | |
15 /* You should have received a copy of the GNU General Public License */ | |
16 /* along with this program; if not, write to the Free Software */ | |
17 /* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA */ | |
18 /*****************************************************************************/ | |
19 | |
20 #include "gftp.h" | |
389 | 21 #include "ftpcommon.h" |
22 | |
33 | 23 static const char cvsid[] = "$Id$"; |
1 | 24 |
126 | 25 static gftp_textcomboedt_data gftp_proxy_type[] = { |
136 | 26 {N_("none"), "", 0}, |
27 {N_("SITE command"), "USER %pu\nPASS %pp\nSITE %hh\nUSER %hu\nPASS %hp\n", 0}, | |
28 {N_("user@host"), "USER %pu\nPASS %pp\nUSER %hu@%hh\nPASS %hp\n", 0}, | |
29 {N_("user@host:port"), "USER %hu@%hh:%ho\nPASS %hp\n", 0}, | |
30 {N_("AUTHENTICATE"), "USER %hu@%hh\nPASS %hp\nSITE AUTHENTICATE %pu\nSITE RESPONSE %pp\n", 0}, | |
31 {N_("user@host port"), "USER %hu@%hh %ho\nPASS %hp\n", 0}, | |
32 {N_("user@host NOAUTH"), "USER %hu@%hh\nPASS %hp\n", 0}, | |
33 {N_("HTTP Proxy"), "http", 0}, | |
34 {N_("Custom"), "", GFTP_TEXTCOMBOEDT_EDITABLE}, | |
126 | 35 {NULL, NULL} |
36 }; | |
37 | |
122 | 38 static gftp_config_vars config_vars[] = |
39 { | |
227 | 40 {"", N_("FTP"), gftp_option_type_notebook, NULL, NULL, |
41 GFTP_CVARS_FLAGS_SHOW_BOOKMARK, NULL, GFTP_PORT_GTK, NULL}, | |
122 | 42 |
43 {"email", N_("Email address:"), | |
227 | 44 gftp_option_type_text, "", NULL, GFTP_CVARS_FLAGS_SHOW_BOOKMARK, |
122 | 45 N_("This is the password that will be used whenever you log into a remote FTP server as anonymous"), |
46 GFTP_PORT_ALL, NULL}, | |
47 {"ftp_proxy_host", N_("Proxy hostname:"), | |
48 gftp_option_type_text, "", NULL, 0, | |
49 N_("Firewall hostname"), GFTP_PORT_ALL, NULL}, | |
50 {"ftp_proxy_port", N_("Proxy port:"), | |
51 gftp_option_type_int, GINT_TO_POINTER(21), NULL, 0, | |
52 N_("Port to connect to on the firewall"), GFTP_PORT_ALL, NULL}, | |
53 {"ftp_proxy_username", N_("Proxy username:"), | |
54 gftp_option_type_text, "", NULL, 0, | |
55 N_("Your firewall username"), GFTP_PORT_ALL, NULL}, | |
56 {"ftp_proxy_password", N_("Proxy password:"), | |
57 gftp_option_type_hidetext, "", NULL, 0, | |
58 N_("Your firewall password"), GFTP_PORT_ALL, NULL}, | |
59 {"ftp_proxy_account", N_("Proxy account:"), | |
60 gftp_option_type_text, "", NULL, 0, | |
61 N_("Your firewall account (optional)"), GFTP_PORT_ALL, NULL}, | |
62 | |
126 | 63 {"proxy_config", N_("Proxy server type:"), |
64 gftp_option_type_textcomboedt, "", gftp_proxy_type, 0, | |
149 | 65 /* xgettext:no-c-format */ |
126 | 66 N_("This specifies how your proxy server expects us to log in. You can specify a 2 character replacement string prefixed by a % that will be replaced with the proper data. The first character can be either p for proxy or h for the host of the FTP server. The second character can be u (user), p (pass), h (host), o (port) or a (account). For example, to specify the proxy user, you can you type in %pu"), |
67 GFTP_PORT_ALL, NULL}, | |
68 | |
136 | 69 {"passive_transfer", N_("Passive file transfers"), |
227 | 70 gftp_option_type_checkbox, GINT_TO_POINTER(1), NULL, |
71 GFTP_CVARS_FLAGS_SHOW_BOOKMARK, | |
136 | 72 N_("If this is enabled, then the remote FTP server will open up a port for the data connection. If you are behind a firewall, you will need to enable this. Generally, it is a good idea to keep this enabled unless you are connecting to an older FTP server that doesn't support this. If this is disabled, then gFTP will open up a port on the client side and the remote server will attempt to connect to it."), |
73 GFTP_PORT_ALL, NULL}, | |
74 {"resolve_symlinks", N_("Resolve Remote Symlinks (LIST -L)"), | |
227 | 75 gftp_option_type_checkbox, GINT_TO_POINTER(1), NULL, |
76 GFTP_CVARS_FLAGS_SHOW_BOOKMARK, | |
136 | 77 N_("The remote FTP server will attempt to resolve symlinks in the directory listings. Generally, this is a good idea to leave enabled. The only time you will want to disable this is if the remote FTP server doesn't support the -L option to LIST"), |
78 GFTP_PORT_ALL, NULL}, | |
79 {"ascii_transfers", N_("Transfer files in ASCII mode"), | |
227 | 80 gftp_option_type_checkbox, GINT_TO_POINTER(0), NULL, |
81 GFTP_CVARS_FLAGS_SHOW_BOOKMARK, | |
136 | 82 N_("If you are transfering a text file from Windows to UNIX box or vice versa, then you should enable this. Each system represents newlines differently for text files. If you are transfering from UNIX to UNIX, then it is safe to leave this off. If you are downloading binary data, you will want to disable this."), |
83 GFTP_PORT_ALL, NULL}, | |
84 | |
122 | 85 {NULL, NULL, 0, NULL, NULL, 0, NULL, 0, NULL} |
86 }; | |
87 | |
88 | |
48 | 89 static int |
292 | 90 rfc959_read_response (gftp_request * request, int disconnect_on_42x) |
48 | 91 { |
92 char tempstr[255], code[4]; | |
58 | 93 rfc959_parms * parms; |
94 ssize_t num_read; | |
48 | 95 |
84 | 96 g_return_val_if_fail (request != NULL, GFTP_EFATAL); |
97 g_return_val_if_fail (request->protonum == GFTP_FTP_NUM, GFTP_EFATAL); | |
169 | 98 g_return_val_if_fail (request->datafd > 0, GFTP_EFATAL); |
48 | 99 |
100 *code = '\0'; | |
101 if (request->last_ftp_response) | |
102 { | |
103 g_free (request->last_ftp_response); | |
104 request->last_ftp_response = NULL; | |
105 } | |
106 | |
58 | 107 parms = request->protocol_data; |
108 | |
48 | 109 do |
110 { | |
169 | 111 if ((num_read = gftp_get_line (request, &parms->datafd_rbuf, tempstr, |
112 sizeof (tempstr), request->datafd)) <= 0) | |
48 | 113 break; |
58 | 114 |
48 | 115 if (isdigit ((int) *tempstr) && isdigit ((int) *(tempstr + 1)) |
116 && isdigit ((int) *(tempstr + 2))) | |
117 { | |
118 strncpy (code, tempstr, 3); | |
119 code[3] = ' '; | |
120 } | |
186 | 121 request->logging_function (gftp_logging_recv, request, |
48 | 122 "%s\n", tempstr); |
123 } | |
124 while (strncmp (code, tempstr, 4) != 0); | |
125 | |
58 | 126 if (num_read < 0) |
84 | 127 return ((int) num_read); |
48 | 128 |
105 | 129 request->last_ftp_response = g_strdup (tempstr); |
48 | 130 |
131 if (request->last_ftp_response[0] == '4' && | |
292 | 132 request->last_ftp_response[1] == '2' && |
133 disconnect_on_42x) | |
48 | 134 gftp_disconnect (request); |
135 | |
136 return (*request->last_ftp_response); | |
137 } | |
138 | |
139 | |
389 | 140 int |
292 | 141 rfc959_send_command (gftp_request * request, const char *command, |
142 int read_response) | |
48 | 143 { |
84 | 144 int ret; |
145 | |
146 g_return_val_if_fail (request != NULL, GFTP_EFATAL); | |
147 g_return_val_if_fail (request->protonum == GFTP_FTP_NUM, GFTP_EFATAL); | |
148 g_return_val_if_fail (command != NULL, GFTP_EFATAL); | |
169 | 149 g_return_val_if_fail (request->datafd > 0, GFTP_EFATAL); |
48 | 150 |
151 if (strncmp (command, "PASS", 4) == 0) | |
152 { | |
186 | 153 request->logging_function (gftp_logging_send, request, |
48 | 154 "PASS xxxx\n"); |
155 } | |
156 else if (strncmp (command, "ACCT", 4) == 0) | |
157 { | |
186 | 158 request->logging_function (gftp_logging_send, request, |
48 | 159 "ACCT xxxx\n"); |
160 } | |
161 else | |
162 { | |
186 | 163 request->logging_function (gftp_logging_send, request, "%s", |
48 | 164 command); |
165 } | |
166 | |
389 | 167 if ((ret = request->write_function (request, command, strlen (command), |
168 request->datafd)) < 0) | |
84 | 169 return (ret); |
48 | 170 |
292 | 171 if (read_response) |
172 return (rfc959_read_response (request, 1)); | |
173 else | |
174 return (0); | |
48 | 175 } |
176 | |
177 | |
178 static char * | |
179 parse_ftp_proxy_string (gftp_request * request) | |
180 { | |
298 | 181 char *startpos, *endpos, *newstr, *newval, tempport[6], *proxy_config, *utf8, |
126 | 182 savechar; |
183 size_t len; | |
325 | 184 intptr_t tmp; |
48 | 185 |
186 g_return_val_if_fail (request != NULL, NULL); | |
187 g_return_val_if_fail (request->protonum == GFTP_FTP_NUM, NULL); | |
1 | 188 |
122 | 189 gftp_lookup_request_option (request, "proxy_config", &proxy_config); |
126 | 190 |
191 newstr = g_malloc0 (1); | |
192 len = 0; | |
122 | 193 startpos = endpos = proxy_config; |
48 | 194 while (*endpos != '\0') |
195 { | |
196 if (*endpos == '%' && tolower ((int) *(endpos + 1)) == 'p') | |
197 { | |
198 switch (tolower ((int) *(endpos + 2))) | |
199 { | |
200 case 'u': | |
124 | 201 gftp_lookup_request_option (request, "ftp_proxy_username", &newval); |
48 | 202 break; |
203 case 'p': | |
124 | 204 gftp_lookup_request_option (request, "ftp_proxy_password", &newval); |
48 | 205 break; |
206 case 'h': | |
124 | 207 gftp_lookup_request_option (request, "ftp_proxy_host", &newval); |
48 | 208 break; |
209 case 'o': | |
124 | 210 gftp_lookup_request_option (request, "ftp_proxy_port", &tmp); |
325 | 211 g_snprintf (tempport, sizeof (tempport), "%d", (int)tmp); |
48 | 212 newval = tempport; |
213 break; | |
214 case 'a': | |
124 | 215 gftp_lookup_request_option (request, "ftp_proxy_account", &newval); |
48 | 216 break; |
217 default: | |
218 endpos++; | |
219 continue; | |
220 } | |
221 } | |
222 else if (*endpos == '%' && tolower ((int) *(endpos + 1)) == 'h') | |
223 { | |
224 switch (tolower ((int) *(endpos + 2))) | |
225 { | |
226 case 'u': | |
227 newval = request->username; | |
228 break; | |
229 case 'p': | |
230 newval = request->password; | |
231 break; | |
232 case 'h': | |
233 newval = request->hostname; | |
234 break; | |
235 case 'o': | |
126 | 236 g_snprintf (tempport, sizeof (tempport), "%d", request->port); |
48 | 237 newval = tempport; |
238 break; | |
239 case 'a': | |
240 newval = request->account; | |
241 break; | |
242 default: | |
243 endpos++; | |
244 continue; | |
245 } | |
246 } | |
247 else if (*endpos == '%' && tolower ((int) *(endpos + 1)) == 'n') | |
248 { | |
126 | 249 savechar = *endpos; |
250 *endpos = '\0'; | |
251 | |
252 len += strlen (startpos) + 2; | |
253 newstr = g_realloc (newstr, sizeof (char) * (len + 1)); | |
254 strcat (newstr, startpos); | |
255 strcat (newstr, "\r\n"); | |
256 | |
257 *endpos = savechar; | |
48 | 258 endpos += 2; |
259 startpos = endpos; | |
260 continue; | |
261 } | |
262 else | |
263 { | |
264 endpos++; | |
265 continue; | |
266 } | |
1 | 267 |
126 | 268 savechar = *endpos; |
48 | 269 *endpos = '\0'; |
126 | 270 len += strlen (startpos); |
48 | 271 if (!newval) |
126 | 272 { |
273 newstr = g_realloc (newstr, sizeof (char) * (len + 1)); | |
274 strcat (newstr, startpos); | |
275 } | |
48 | 276 else |
126 | 277 { |
298 | 278 utf8 = gftp_string_from_utf8 (request, newval); |
279 if (utf8 != NULL) | |
280 len += strlen (utf8); | |
281 else | |
282 len += strlen (newval); | |
283 | |
126 | 284 newstr = g_realloc (newstr, sizeof (char) * (len + 1)); |
285 strcat (newstr, startpos); | |
298 | 286 |
287 if (utf8 != NULL) | |
288 { | |
289 strcat (newstr, utf8); | |
290 g_free (utf8); | |
291 } | |
292 else | |
293 strcat (newstr, newval); | |
126 | 294 } |
295 | |
296 *endpos = savechar; | |
48 | 297 endpos += 3; |
298 startpos = endpos; | |
299 } | |
126 | 300 |
48 | 301 return (newstr); |
302 } | |
303 | |
304 | |
305 static int | |
58 | 306 rfc959_getcwd (gftp_request * request) |
307 { | |
308 char *pos, *dir; | |
309 int ret; | |
310 | |
292 | 311 ret = rfc959_send_command (request, "PWD\r\n", 1); |
58 | 312 if (ret < 0) |
84 | 313 return (ret); |
58 | 314 else if (ret != '2') |
315 { | |
186 | 316 request->logging_function (gftp_logging_error, request, |
411 | 317 _("Invalid response '%c' received from server.\n"), |
318 ret); | |
58 | 319 gftp_disconnect (request); |
84 | 320 return (GFTP_ERETRYABLE); |
58 | 321 } |
322 | |
323 if ((pos = strchr (request->last_ftp_response, '"')) == NULL) | |
324 { | |
186 | 325 request->logging_function (gftp_logging_error, request, |
411 | 326 _("Invalid response '%c' received from server.\n"), |
327 ret); | |
58 | 328 gftp_disconnect (request); |
84 | 329 return (GFTP_EFATAL); |
58 | 330 } |
331 | |
332 dir = pos + 1; | |
333 | |
334 if ((pos = strchr (dir, '"')) == NULL) | |
335 { | |
186 | 336 request->logging_function (gftp_logging_error, request, |
411 | 337 _("Invalid response '%c' received from server.\n"), |
338 ret); | |
58 | 339 gftp_disconnect (request); |
84 | 340 return (GFTP_EFATAL); |
58 | 341 } |
342 | |
343 *pos = '\0'; | |
344 | |
345 if (request->directory) | |
346 g_free (request->directory); | |
347 | |
105 | 348 request->directory = g_strdup (dir); |
58 | 349 return (0); |
350 } | |
351 | |
352 | |
353 static int | |
48 | 354 rfc959_chdir (gftp_request * request, const char *directory) |
355 { | |
58 | 356 char ret, *tempstr; |
84 | 357 int r; |
48 | 358 |
84 | 359 g_return_val_if_fail (request != NULL, GFTP_EFATAL); |
360 g_return_val_if_fail (request->protonum == GFTP_FTP_NUM, GFTP_EFATAL); | |
361 g_return_val_if_fail (directory != NULL, GFTP_EFATAL); | |
48 | 362 |
363 if (strcmp (directory, "..") == 0) | |
292 | 364 ret = rfc959_send_command (request, "CDUP\r\n", 1); |
48 | 365 else |
366 { | |
367 tempstr = g_strconcat ("CWD ", directory, "\r\n", NULL); | |
292 | 368 ret = rfc959_send_command (request, tempstr, 1); |
48 | 369 g_free (tempstr); |
370 } | |
371 | |
372 if (ret != '2') | |
84 | 373 return (GFTP_ERETRYABLE); |
48 | 374 |
375 if (directory != request->directory) | |
376 { | |
84 | 377 if ((r = rfc959_getcwd (request)) < 0) |
378 return (r); | |
48 | 379 } |
380 | |
381 return (0); | |
1 | 382 } |
383 | |
384 | |
385 static int | |
91 | 386 rfc959_syst (gftp_request * request) |
387 { | |
388 char *stpos, *endpos; | |
389 int ret; | |
390 | |
391 g_return_val_if_fail (request != NULL, GFTP_EFATAL); | |
392 g_return_val_if_fail (request->protonum == GFTP_FTP_NUM, GFTP_EFATAL); | |
169 | 393 g_return_val_if_fail (request->datafd > 0, GFTP_EFATAL); |
91 | 394 |
292 | 395 ret = rfc959_send_command (request, "SYST\r\n", 1); |
91 | 396 |
397 if (ret < 0) | |
398 return (ret); | |
399 else if (ret != '2') | |
400 return (GFTP_ERETRYABLE); | |
401 | |
402 if ((stpos = strchr (request->last_ftp_response, ' ')) == NULL) | |
403 return (GFTP_ERETRYABLE); | |
404 | |
114 | 405 stpos++; |
406 | |
91 | 407 if ((endpos = strchr (stpos, ' ')) == NULL) |
408 return (GFTP_ERETRYABLE); | |
409 | |
410 *endpos = '\0'; | |
411 if (strcmp (stpos, "UNIX") == 0) | |
122 | 412 request->server_type = GFTP_DIRTYPE_UNIX; |
107 | 413 else if (strcmp (stpos, "VMS") == 0) |
122 | 414 request->server_type = GFTP_DIRTYPE_VMS; |
367 | 415 else if (strcmp (stpos, "MVS") == 0 || |
416 strcmp (stpos, "OS/MVS") == 0) | |
358 | 417 request->server_type = GFTP_DIRTYPE_MVS; |
305 | 418 else if (strcmp (stpos, "NETWARE") == 0) |
419 request->server_type = GFTP_DIRTYPE_NOVELL; | |
136 | 420 else if (strcmp (stpos, "CRAY") == 0) |
421 request->server_type = GFTP_DIRTYPE_CRAY; | |
91 | 422 else |
122 | 423 request->server_type = GFTP_DIRTYPE_OTHER; |
91 | 424 |
425 return (0); | |
426 } | |
427 | |
428 | |
429 static int | |
1 | 430 rfc959_connect (gftp_request * request) |
431 { | |
298 | 432 char tempchar, *startpos, *endpos, *tempstr, *email, *proxy_hostname, *utf8; |
325 | 433 int ret, resp; |
434 intptr_t ascii_transfers, proxy_port; | |
122 | 435 rfc959_parms * parms; |
1 | 436 |
84 | 437 g_return_val_if_fail (request != NULL, GFTP_EFATAL); |
438 g_return_val_if_fail (request->protonum == GFTP_FTP_NUM, GFTP_EFATAL); | |
439 g_return_val_if_fail (request->hostname != NULL, GFTP_EFATAL); | |
1 | 440 |
169 | 441 if (request->datafd > 0) |
58 | 442 return (0); |
443 | |
122 | 444 parms = request->protocol_data; |
445 | |
124 | 446 gftp_lookup_request_option (request, "ftp_proxy_host", &proxy_hostname); |
447 gftp_lookup_request_option (request, "ftp_proxy_port", &proxy_port); | |
122 | 448 |
7 | 449 if (request->username == NULL || *request->username == '\0') |
370 | 450 gftp_set_username (request, "anonymous"); |
451 | |
452 if (strcasecmp (request->username, "anonymous") == 0 && | |
453 (request->password == NULL || *request->password == '\0')) | |
7 | 454 { |
370 | 455 gftp_lookup_request_option (request, "email", &email); |
122 | 456 gftp_set_password (request, email); |
7 | 457 } |
122 | 458 |
177 | 459 if ((ret = gftp_connect_server (request, "ftp", proxy_hostname, proxy_port)) < 0) |
460 return (ret); | |
1 | 461 |
462 /* Get the banner */ | |
292 | 463 if ((ret = rfc959_read_response (request, 1)) != '2') |
1 | 464 { |
465 gftp_disconnect (request); | |
84 | 466 return (ret); |
1 | 467 } |
468 | |
389 | 469 if (parms->auth_tls_start != NULL) |
470 { | |
471 if ((ret = parms->auth_tls_start (request)) < 0) | |
472 { | |
473 gftp_disconnect (request); | |
474 return (ret); | |
475 } | |
476 } | |
477 | |
1 | 478 /* Login the proxy server if available */ |
479 if (request->use_proxy) | |
480 { | |
481 resp = '3'; | |
482 startpos = endpos = tempstr = parse_ftp_proxy_string (request); | |
483 while ((resp == '3' || resp == '2') && *startpos != '\0') | |
484 { | |
485 if (*endpos == '\n' || *endpos == '\0') | |
486 { | |
487 tempchar = *(endpos + 1); | |
488 if (*endpos != '\0') | |
489 *(endpos + 1) = '\0'; | |
292 | 490 if ((resp = rfc959_send_command (request, startpos, 1)) < 0) |
84 | 491 return (resp); |
1 | 492 if (*endpos != '\0') |
493 *(endpos + 1) = tempchar; | |
494 else | |
495 break; | |
496 startpos = endpos + 1; | |
497 } | |
498 endpos++; | |
499 } | |
500 g_free (tempstr); | |
501 } | |
502 else | |
503 { | |
504 tempstr = g_strconcat ("USER ", request->username, "\r\n", NULL); | |
292 | 505 resp = rfc959_send_command (request, tempstr, 1); |
1 | 506 g_free (tempstr); |
507 if (resp < 0) | |
84 | 508 return (GFTP_ERETRYABLE); |
286 | 509 |
1 | 510 if (resp == '3') |
511 { | |
298 | 512 utf8 = gftp_string_from_utf8 (request, request->password); |
513 if (utf8 != NULL) | |
514 { | |
515 tempstr = g_strconcat ("PASS ", utf8, "\r\n", NULL); | |
516 g_free (utf8); | |
517 } | |
518 else | |
519 tempstr = g_strconcat ("PASS ", request->password, "\r\n", NULL); | |
520 | |
292 | 521 resp = rfc959_send_command (request, tempstr, 1); |
1 | 522 g_free (tempstr); |
523 if (resp < 0) | |
84 | 524 return (GFTP_ERETRYABLE); |
1 | 525 } |
286 | 526 |
1 | 527 if (resp == '3' && request->account) |
528 { | |
529 tempstr = g_strconcat ("ACCT ", request->account, "\r\n", NULL); | |
292 | 530 resp = rfc959_send_command (request, tempstr, 1); |
1 | 531 g_free (tempstr); |
532 if (resp < 0) | |
84 | 533 return (GFTP_ERETRYABLE); |
1 | 534 } |
535 } | |
536 | |
537 if (resp != '2') | |
538 { | |
411 | 539 request->logging_function (gftp_logging_error, request, |
540 _("Invalid response '%c' received from server.\n"), | |
541 resp); | |
1 | 542 gftp_disconnect (request); |
286 | 543 |
544 if (resp == '5') | |
545 return (GFTP_EFATAL); | |
546 else | |
547 return (GFTP_ERETRYABLE); | |
1 | 548 } |
549 | |
169 | 550 if ((ret = rfc959_syst (request)) < 0 && request->datafd < 0) |
91 | 551 return (ret); |
552 | |
122 | 553 gftp_lookup_request_option (request, "ascii_transfers", &ascii_transfers); |
554 if (ascii_transfers) | |
555 { | |
556 tempstr = "TYPE A\r\n"; | |
557 parms->is_ascii_transfer = 1; | |
558 } | |
1 | 559 else |
122 | 560 { |
561 tempstr = "TYPE I\r\n"; | |
562 parms->is_ascii_transfer = 0; | |
563 } | |
1 | 564 |
292 | 565 if ((ret = rfc959_send_command (request, tempstr, 1)) < 0) |
84 | 566 return (ret); |
1 | 567 |
568 ret = -1; | |
569 if (request->directory != NULL && *request->directory != '\0') | |
570 { | |
571 ret = rfc959_chdir (request, request->directory); | |
169 | 572 if (request->datafd < 0) |
84 | 573 return (ret); |
1 | 574 } |
575 | |
576 if (ret != 0) | |
577 { | |
84 | 578 if ((ret = rfc959_getcwd (request)) < 0) |
579 return (ret); | |
1 | 580 } |
581 | |
169 | 582 if (request->datafd < 0) |
84 | 583 return (GFTP_EFATAL); |
1 | 584 |
585 return (0); | |
586 } | |
587 | |
588 | |
589 static void | |
590 rfc959_disconnect (gftp_request * request) | |
591 { | |
169 | 592 rfc959_parms * parms; |
593 | |
1 | 594 g_return_if_fail (request != NULL); |
595 g_return_if_fail (request->protonum == GFTP_FTP_NUM); | |
596 | |
169 | 597 parms = request->protocol_data; |
598 | |
599 if (request->datafd > 0) | |
1 | 600 { |
186 | 601 request->logging_function (gftp_logging_misc, request, |
1 | 602 _("Disconnecting from site %s\n"), |
603 request->hostname); | |
169 | 604 close (request->datafd); |
605 request->datafd = -1; | |
606 } | |
607 | |
608 if (parms->data_connection > 0) | |
609 { | |
610 close (parms->data_connection); | |
611 parms->data_connection = -1; | |
1 | 612 } |
613 } | |
614 | |
615 | |
48 | 616 static int |
146 | 617 rfc959_ipv4_data_connection_new (gftp_request * request) |
48 | 618 { |
619 char *pos, *pos1, resp, *command; | |
620 struct sockaddr_in data_addr; | |
325 | 621 int i; |
622 intptr_t passive_transfer; | |
169 | 623 rfc959_parms * parms; |
195 | 624 socklen_t data_addr_len; |
48 | 625 unsigned int temp[6]; |
626 unsigned char ad[6]; | |
627 | |
169 | 628 parms = request->protocol_data; |
629 | |
630 if ((parms->data_connection = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) | |
48 | 631 { |
186 | 632 request->logging_function (gftp_logging_error, request, |
313 | 633 _("Failed to create a IPv4 socket: %s\n"), |
48 | 634 g_strerror (errno)); |
635 gftp_disconnect (request); | |
84 | 636 return (GFTP_ERETRYABLE); |
48 | 637 } |
638 | |
182 | 639 if (fcntl (parms->data_connection, F_SETFD, 1) == -1) |
640 { | |
186 | 641 request->logging_function (gftp_logging_error, request, |
182 | 642 _("Error: Cannot set close on exec flag: %s\n"), |
643 g_strerror (errno)); | |
644 | |
645 return (GFTP_ERETRYABLE); | |
646 } | |
647 | |
48 | 648 data_addr_len = sizeof (data_addr); |
649 memset (&data_addr, 0, data_addr_len); | |
650 data_addr.sin_family = AF_INET; | |
651 | |
122 | 652 gftp_lookup_request_option (request, "passive_transfer", &passive_transfer); |
653 if (passive_transfer) | |
48 | 654 { |
292 | 655 if ((resp = rfc959_send_command (request, "PASV\r\n", 1)) != '2') |
48 | 656 { |
169 | 657 if (request->datafd < 0) |
288 | 658 return (GFTP_ERETRYABLE); |
48 | 659 |
122 | 660 gftp_set_request_option (request, "passive_transfer", GINT_TO_POINTER(0)); |
146 | 661 return (rfc959_ipv4_data_connection_new (request)); |
48 | 662 } |
58 | 663 |
48 | 664 pos = request->last_ftp_response + 4; |
665 while (!isdigit ((int) *pos) && *pos != '\0') | |
666 pos++; | |
58 | 667 |
48 | 668 if (*pos == '\0') |
669 { | |
186 | 670 request->logging_function (gftp_logging_error, request, |
58 | 671 _("Cannot find an IP address in PASV response '%s'\n"), |
672 request->last_ftp_response); | |
48 | 673 gftp_disconnect (request); |
84 | 674 return (GFTP_EFATAL); |
48 | 675 } |
58 | 676 |
48 | 677 if (sscanf (pos, "%u,%u,%u,%u,%u,%u", &temp[0], &temp[1], &temp[2], |
678 &temp[3], &temp[4], &temp[5]) != 6) | |
679 { | |
186 | 680 request->logging_function (gftp_logging_error, request, |
58 | 681 _("Cannot find an IP address in PASV response '%s'\n"), |
682 request->last_ftp_response); | |
48 | 683 gftp_disconnect (request); |
84 | 684 return (GFTP_EFATAL); |
48 | 685 } |
58 | 686 |
48 | 687 for (i = 0; i < 6; i++) |
688 ad[i] = (unsigned char) (temp[i] & 0xff); | |
689 | |
690 memcpy (&data_addr.sin_addr, &ad[0], 4); | |
691 memcpy (&data_addr.sin_port, &ad[4], 2); | |
169 | 692 if (connect (parms->data_connection, (struct sockaddr *) &data_addr, |
58 | 693 data_addr_len) == -1) |
48 | 694 { |
186 | 695 request->logging_function (gftp_logging_error, request, |
48 | 696 _("Cannot create a data connection: %s\n"), |
697 g_strerror (errno)); | |
698 gftp_disconnect (request); | |
84 | 699 return (GFTP_ERETRYABLE); |
48 | 700 } |
701 } | |
702 else | |
703 { | |
169 | 704 if (getsockname (request->datafd, (struct sockaddr *) &data_addr, |
58 | 705 &data_addr_len) == -1) |
706 { | |
186 | 707 request->logging_function (gftp_logging_error, request, |
58 | 708 _("Cannot get socket name: %s\n"), |
709 g_strerror (errno)); | |
710 gftp_disconnect (request); | |
84 | 711 return (GFTP_ERETRYABLE); |
58 | 712 } |
713 | |
48 | 714 data_addr.sin_port = 0; |
169 | 715 if (bind (parms->data_connection, (struct sockaddr *) &data_addr, |
58 | 716 data_addr_len) == -1) |
48 | 717 { |
186 | 718 request->logging_function (gftp_logging_error, request, |
48 | 719 _("Cannot bind a port: %s\n"), |
720 g_strerror (errno)); | |
721 gftp_disconnect (request); | |
84 | 722 return (GFTP_ERETRYABLE); |
48 | 723 } |
724 | |
169 | 725 if (getsockname (parms->data_connection, (struct sockaddr *) &data_addr, |
58 | 726 &data_addr_len) == -1) |
727 { | |
186 | 728 request->logging_function (gftp_logging_error, request, |
58 | 729 _("Cannot get socket name: %s\n"), |
730 g_strerror (errno)); | |
731 gftp_disconnect (request); | |
84 | 732 return (GFTP_ERETRYABLE); |
58 | 733 } |
734 | |
169 | 735 if (listen (parms->data_connection, 1) == -1) |
48 | 736 { |
186 | 737 request->logging_function (gftp_logging_error, request, |
48 | 738 _("Cannot listen on port %d: %s\n"), |
739 ntohs (data_addr.sin_port), | |
740 g_strerror (errno)); | |
741 gftp_disconnect (request); | |
84 | 742 return (GFTP_ERETRYABLE); |
48 | 743 } |
58 | 744 |
48 | 745 pos = (char *) &data_addr.sin_addr; |
746 pos1 = (char *) &data_addr.sin_port; | |
747 command = g_strdup_printf ("PORT %u,%u,%u,%u,%u,%u\r\n", | |
748 pos[0] & 0xff, pos[1] & 0xff, pos[2] & 0xff, | |
749 pos[3] & 0xff, pos1[0] & 0xff, | |
750 pos1[1] & 0xff); | |
292 | 751 resp = rfc959_send_command (request, command, 1); |
48 | 752 g_free (command); |
753 if (resp != '2') | |
754 { | |
411 | 755 request->logging_function (gftp_logging_error, request, |
756 _("Invalid response '%c' received from server.\n"), | |
757 resp); | |
48 | 758 gftp_disconnect (request); |
84 | 759 return (GFTP_ERETRYABLE); |
48 | 760 } |
761 } | |
762 | |
763 return (0); | |
764 } | |
765 | |
766 | |
146 | 767 #ifdef HAVE_IPV6 |
768 | |
769 static int | |
770 rfc959_ipv6_data_connection_new (gftp_request * request) | |
771 { | |
772 char *pos, resp, buf[64], *command; | |
773 struct sockaddr_in6 data_addr; | |
774 int passive_transfer; | |
195 | 775 socklen_t data_addr_len; |
169 | 776 rfc959_parms * parms; |
146 | 777 unsigned int port; |
778 | |
169 | 779 parms = request->protocol_data; |
780 if ((parms->data_connection = socket (AF_INET6, SOCK_STREAM, IPPROTO_TCP)) < 0) | |
146 | 781 { |
186 | 782 request->logging_function (gftp_logging_error, request, |
313 | 783 _("Failed to create a IPv6 socket: %s\n"), |
146 | 784 g_strerror (errno)); |
785 gftp_disconnect (request); | |
786 return (GFTP_ERETRYABLE); | |
787 } | |
788 | |
182 | 789 if (fcntl (parms->data_connection, F_SETFD, 1) == -1) |
790 { | |
186 | 791 request->logging_function (gftp_logging_error, request, |
182 | 792 _("Error: Cannot set close on exec flag: %s\n"), |
793 g_strerror (errno)); | |
794 | |
795 return (GFTP_ERETRYABLE); | |
796 } | |
797 | |
146 | 798 data_addr_len = sizeof (data_addr); |
799 /* This condition shouldn't happen. We better check anyway... */ | |
800 if (data_addr_len != request->hostp->ai_addrlen) | |
801 { | |
186 | 802 request->logging_function (gftp_logging_error, request, |
146 | 803 _("Error: It doesn't look like we are connected via IPv6. Aborting connection.\n")); |
804 gftp_disconnect (request); | |
805 return (GFTP_EFATAL); | |
806 } | |
807 | |
808 memset (&data_addr, 0, data_addr_len); | |
809 data_addr.sin6_family = AF_INET6; | |
810 | |
811 gftp_lookup_request_option (request, "passive_transfer", &passive_transfer); | |
812 if (passive_transfer) | |
813 { | |
292 | 814 if ((resp = rfc959_send_command (request, "EPSV\r\n", 1)) != '2') |
146 | 815 { |
169 | 816 if (request->datafd < 0) |
288 | 817 return (GFTP_ERETRYABLE); |
146 | 818 |
819 gftp_set_request_option (request, "passive_transfer", | |
820 GINT_TO_POINTER(0)); | |
821 return (rfc959_ipv6_data_connection_new (request)); | |
822 } | |
823 | |
824 pos = request->last_ftp_response + 4; | |
825 while (*pos != '(' && *pos != '\0') | |
826 pos++; | |
827 pos++; | |
828 | |
829 if (*pos == '\0') | |
830 { | |
186 | 831 request->logging_function (gftp_logging_error, request, |
146 | 832 _("Invalid EPSV response '%s'\n"), |
833 request->last_ftp_response); | |
834 gftp_disconnect (request); | |
835 return (GFTP_EFATAL); | |
836 } | |
837 | |
319 | 838 if (sscanf (pos, "|||%u|", &port) != 1) |
146 | 839 { |
186 | 840 request->logging_function (gftp_logging_error, request, |
146 | 841 _("Invalid EPSV response '%s'\n"), |
842 request->last_ftp_response); | |
843 gftp_disconnect (request); | |
844 return (GFTP_EFATAL); | |
845 } | |
846 | |
847 memcpy (&data_addr, request->hostp->ai_addr, data_addr_len); | |
848 data_addr.sin6_port = htons (port); | |
849 | |
169 | 850 if (connect (parms->data_connection, (struct sockaddr *) &data_addr, |
146 | 851 data_addr_len) == -1) |
852 { | |
186 | 853 request->logging_function (gftp_logging_error, request, |
146 | 854 _("Cannot create a data connection: %s\n"), |
855 g_strerror (errno)); | |
856 gftp_disconnect (request); | |
857 return (GFTP_ERETRYABLE); | |
858 } | |
859 } | |
860 else | |
861 { | |
862 memcpy (&data_addr, request->hostp->ai_addr, data_addr_len); | |
863 data_addr.sin6_port = 0; | |
864 | |
169 | 865 if (bind (parms->data_connection, (struct sockaddr *) &data_addr, |
146 | 866 data_addr_len) == -1) |
867 { | |
186 | 868 request->logging_function (gftp_logging_error, request, |
146 | 869 _("Cannot bind a port: %s\n"), |
870 g_strerror (errno)); | |
871 gftp_disconnect (request); | |
872 return (GFTP_ERETRYABLE); | |
873 } | |
874 | |
169 | 875 if (getsockname (parms->data_connection, (struct sockaddr *) &data_addr, |
146 | 876 &data_addr_len) == -1) |
877 { | |
186 | 878 request->logging_function (gftp_logging_error, request, |
146 | 879 _("Cannot get socket name: %s\n"), |
880 g_strerror (errno)); | |
881 gftp_disconnect (request); | |
882 return (GFTP_ERETRYABLE); | |
883 } | |
884 | |
169 | 885 if (listen (parms->data_connection, 1) == -1) |
146 | 886 { |
186 | 887 request->logging_function (gftp_logging_error, request, |
146 | 888 _("Cannot listen on port %d: %s\n"), |
889 ntohs (data_addr.sin6_port), | |
890 g_strerror (errno)); | |
891 gftp_disconnect (request); | |
892 return (GFTP_ERETRYABLE); | |
893 } | |
894 | |
895 if (inet_ntop (AF_INET6, &data_addr.sin6_addr, buf, sizeof (buf)) == NULL) | |
896 { | |
186 | 897 request->logging_function (gftp_logging_error, request, |
146 | 898 _("Cannot get address of local socket: %s\n"), |
899 g_strerror (errno)); | |
900 gftp_disconnect (request); | |
901 return (GFTP_ERETRYABLE); | |
902 } | |
903 | |
904 command = g_strdup_printf ("EPRT |2|%s|%d|\n", buf, | |
905 ntohs (data_addr.sin6_port)); | |
906 | |
292 | 907 resp = rfc959_send_command (request, command, 1); |
146 | 908 g_free (command); |
909 if (resp != '2') | |
910 { | |
911 gftp_disconnect (request); | |
912 return (GFTP_ERETRYABLE); | |
913 } | |
914 } | |
915 | |
916 return (0); | |
917 } | |
918 | |
919 #endif /* HAVE_IPV6 */ | |
920 | |
921 | |
922 static int | |
923 rfc959_data_connection_new (gftp_request * request) | |
924 { | |
925 g_return_val_if_fail (request != NULL, GFTP_EFATAL); | |
926 g_return_val_if_fail (request->protonum == GFTP_FTP_NUM, GFTP_EFATAL); | |
169 | 927 g_return_val_if_fail (request->datafd > 0, GFTP_EFATAL); |
146 | 928 |
929 #ifdef HAVE_IPV6 | |
151 | 930 if (GFTP_GET_AI_FAMILY(request) == AF_INET6) |
146 | 931 return (rfc959_ipv6_data_connection_new (request)); |
932 else | |
151 | 933 return (rfc959_ipv4_data_connection_new (request)); |
934 #else | |
935 return (rfc959_ipv4_data_connection_new (request)); | |
146 | 936 #endif |
937 } | |
938 | |
939 | |
48 | 940 static int |
941 rfc959_accept_active_connection (gftp_request * request) | |
942 { | |
325 | 943 int infd, ret; |
944 intptr_t passive_transfer; | |
169 | 945 rfc959_parms * parms; |
146 | 946 #ifdef HAVE_IPV6 |
339 | 947 struct sockaddr_in6 cli_addr; |
146 | 948 #else |
339 | 949 struct sockaddr_in cli_addr; |
146 | 950 #endif |
195 | 951 socklen_t cli_addr_len; |
48 | 952 |
169 | 953 parms = request->protocol_data; |
954 | |
84 | 955 g_return_val_if_fail (request != NULL, GFTP_EFATAL); |
956 g_return_val_if_fail (request->protonum == GFTP_FTP_NUM, GFTP_EFATAL); | |
169 | 957 g_return_val_if_fail (parms->data_connection > 0, GFTP_EFATAL); |
122 | 958 |
959 gftp_lookup_request_option (request, "passive_transfer", &passive_transfer); | |
960 g_return_val_if_fail (!passive_transfer, GFTP_EFATAL); | |
48 | 961 |
962 cli_addr_len = sizeof (cli_addr); | |
58 | 963 |
169 | 964 if ((ret = gftp_fd_set_sockblocking (request, parms->data_connection, 0)) < 0) |
84 | 965 return (ret); |
58 | 966 |
169 | 967 if ((infd = accept (parms->data_connection, (struct sockaddr *) &cli_addr, |
48 | 968 &cli_addr_len)) == -1) |
969 { | |
186 | 970 request->logging_function (gftp_logging_error, request, |
48 | 971 _("Cannot accept connection from server: %s\n"), |
972 g_strerror (errno)); | |
973 gftp_disconnect (request); | |
84 | 974 return (GFTP_ERETRYABLE); |
48 | 975 } |
976 | |
169 | 977 close (parms->data_connection); |
48 | 978 |
169 | 979 parms->data_connection = infd; |
980 if ((ret = gftp_fd_set_sockblocking (request, parms->data_connection, 1)) < 0) | |
84 | 981 return (ret); |
58 | 982 |
48 | 983 return (0); |
984 } | |
985 | |
986 | |
122 | 987 static int |
254 | 988 rfc959_is_ascii_transfer (gftp_request * request, const char *filename) |
122 | 989 { |
990 gftp_config_list_vars * tmplistvar; | |
991 gftp_file_extensions * tempext; | |
325 | 992 int stlen; |
993 intptr_t ascii_transfers; | |
122 | 994 GList * templist; |
995 | |
996 gftp_lookup_global_option ("ext", &tmplistvar); | |
254 | 997 gftp_lookup_request_option (request, "ascii_transfers", &ascii_transfers); |
122 | 998 |
999 stlen = strlen (filename); | |
1000 for (templist = tmplistvar->list; templist != NULL; templist = templist->next) | |
1001 { | |
1002 tempext = templist->data; | |
1003 | |
1004 if (stlen >= tempext->stlen && | |
1005 strcmp (&filename[stlen - tempext->stlen], tempext->ext) == 0) | |
1006 { | |
1007 if (toupper (*tempext->ascii_binary == 'A')) | |
254 | 1008 ascii_transfers = 1; |
1009 else if (toupper (*tempext->ascii_binary == 'B')) | |
1010 ascii_transfers = 0; | |
122 | 1011 break; |
1012 } | |
1013 } | |
1014 | |
254 | 1015 return (ascii_transfers); |
122 | 1016 } |
1017 | |
1018 | |
309 | 1019 static int |
122 | 1020 rfc959_set_data_type (gftp_request * request, const char *filename) |
1021 { | |
1022 rfc959_parms * parms; | |
309 | 1023 int new_ascii, ret; |
122 | 1024 char *tempstr; |
1025 | |
309 | 1026 g_return_val_if_fail (request != NULL, GFTP_EFATAL); |
1027 g_return_val_if_fail (request->protonum == GFTP_FTP_NUM, GFTP_EFATAL); | |
122 | 1028 |
1029 parms = request->protocol_data; | |
254 | 1030 new_ascii = rfc959_is_ascii_transfer (request, filename); |
122 | 1031 |
169 | 1032 if (request->datafd > 0 && new_ascii != parms->is_ascii_transfer) |
122 | 1033 { |
1034 if (new_ascii) | |
1035 { | |
1036 tempstr = "TYPE A\r\n"; | |
1037 parms->is_ascii_transfer = 1; | |
1038 } | |
1039 else | |
1040 { | |
1041 tempstr = "TYPE I\r\n"; | |
254 | 1042 parms->is_ascii_transfer = 0; |
122 | 1043 } |
1044 | |
309 | 1045 if ((ret = rfc959_send_command (request, tempstr, 1)) < 0) |
1046 return (ret); | |
122 | 1047 } |
1048 | |
309 | 1049 return (0); |
122 | 1050 } |
1051 | |
1052 | |
58 | 1053 static off_t |
1054 rfc959_get_file (gftp_request * request, const char *filename, int fd, | |
1 | 1055 off_t startsize) |
1056 { | |
1057 char *command, *tempstr, resp; | |
325 | 1058 int ret; |
1059 intptr_t passive_transfer; | |
169 | 1060 rfc959_parms * parms; |
1 | 1061 |
84 | 1062 g_return_val_if_fail (request != NULL, GFTP_EFATAL); |
1063 g_return_val_if_fail (request->protonum == GFTP_FTP_NUM, GFTP_EFATAL); | |
1064 g_return_val_if_fail (filename != NULL, GFTP_EFATAL); | |
169 | 1065 g_return_val_if_fail (request->datafd > 0, GFTP_EFATAL); |
1 | 1066 |
169 | 1067 parms = request->protocol_data; |
58 | 1068 if (fd > 0) |
169 | 1069 parms->data_connection = fd; |
1 | 1070 |
309 | 1071 if ((ret = rfc959_set_data_type (request, filename)) < 0) |
1072 return (ret); | |
122 | 1073 |
169 | 1074 if (parms->data_connection < 0 && |
1 | 1075 (ret = rfc959_data_connection_new (request)) < 0) |
1076 return (ret); | |
1077 | |
169 | 1078 if ((ret = gftp_fd_set_sockblocking (request, parms->data_connection, 1)) < 0) |
84 | 1079 return (ret); |
1 | 1080 |
1081 if (startsize > 0) | |
1082 { | |
14
83090328581e
* More largefile support. Hopefully all that is left is the configure stuff
masneyb
parents:
7
diff
changeset
|
1083 #if defined (_LARGEFILE_SOURCE) |
372 | 1084 command = g_strdup_printf ("REST %lld\r\n", (long long) startsize); |
14
83090328581e
* More largefile support. Hopefully all that is left is the configure stuff
masneyb
parents:
7
diff
changeset
|
1085 #else |
1 | 1086 command = g_strdup_printf ("REST %ld\r\n", startsize); |
14
83090328581e
* More largefile support. Hopefully all that is left is the configure stuff
masneyb
parents:
7
diff
changeset
|
1087 #endif |
292 | 1088 resp = rfc959_send_command (request, command, 1); |
1 | 1089 g_free (command); |
1090 | |
1091 if (resp != '3') | |
1092 { | |
169 | 1093 close (parms->data_connection); |
1094 parms->data_connection = -1; | |
84 | 1095 return (GFTP_ERETRYABLE); |
1 | 1096 } |
1097 } | |
1098 | |
1099 tempstr = g_strconcat ("RETR ", filename, "\r\n", NULL); | |
292 | 1100 ret = rfc959_send_command (request, tempstr, 1); |
1 | 1101 g_free (tempstr); |
1102 | |
1103 if (ret != '1') | |
58 | 1104 { |
169 | 1105 close (parms->data_connection); |
1106 parms->data_connection = -1; | |
84 | 1107 return (GFTP_ERETRYABLE); |
58 | 1108 } |
1 | 1109 |
122 | 1110 gftp_lookup_request_option (request, "passive_transfer", &passive_transfer); |
1111 if (!passive_transfer && | |
1 | 1112 (ret = rfc959_accept_active_connection (request)) < 0) |
1113 return (ret); | |
1114 | |
1115 if ((tempstr = strrchr (request->last_ftp_response, '(')) == NULL) | |
1116 { | |
1117 tempstr = request->last_ftp_response + 4; | |
1118 while (!isdigit ((int) *tempstr) && *tempstr != '\0') | |
1119 tempstr++; | |
1120 } | |
1121 else | |
1122 tempstr++; | |
1123 | |
292 | 1124 parms->sent_retr = 1; |
244 | 1125 return (gftp_parse_file_size (tempstr) + startsize); |
1 | 1126 } |
1127 | |
1128 | |
1129 static int | |
58 | 1130 rfc959_put_file (gftp_request * request, const char *filename, int fd, |
1 | 1131 off_t startsize, off_t totalsize) |
1132 { | |
1133 char *command, *tempstr, resp; | |
325 | 1134 int ret; |
1135 intptr_t passive_transfer; | |
169 | 1136 rfc959_parms * parms; |
1 | 1137 |
84 | 1138 g_return_val_if_fail (request != NULL, GFTP_EFATAL); |
1139 g_return_val_if_fail (request->protonum == GFTP_FTP_NUM, GFTP_EFATAL); | |
1140 g_return_val_if_fail (filename != NULL, GFTP_EFATAL); | |
169 | 1141 g_return_val_if_fail (request->datafd > 0, GFTP_EFATAL); |
1 | 1142 |
169 | 1143 parms = request->protocol_data; |
58 | 1144 if (fd > 0) |
169 | 1145 fd = parms->data_connection; |
1 | 1146 |
309 | 1147 if ((ret = rfc959_set_data_type (request, filename)) < 0) |
1148 return (ret); | |
122 | 1149 |
169 | 1150 if (parms->data_connection < 0 && |
1 | 1151 (ret = rfc959_data_connection_new (request)) < 0) |
1152 return (ret); | |
1153 | |
169 | 1154 if ((ret = gftp_fd_set_sockblocking (request, parms->data_connection, 1)) < 0) |
84 | 1155 return (ret); |
1 | 1156 |
1157 if (startsize > 0) | |
1158 { | |
14
83090328581e
* More largefile support. Hopefully all that is left is the configure stuff
masneyb
parents:
7
diff
changeset
|
1159 #if defined (_LARGEFILE_SOURCE) |
372 | 1160 command = g_strdup_printf ("REST %lld\r\n", (long long) startsize); |
14
83090328581e
* More largefile support. Hopefully all that is left is the configure stuff
masneyb
parents:
7
diff
changeset
|
1161 #else |
83090328581e
* More largefile support. Hopefully all that is left is the configure stuff
masneyb
parents:
7
diff
changeset
|
1162 command = g_strdup_printf ("REST %ld\r\n", startsize); |
83090328581e
* More largefile support. Hopefully all that is left is the configure stuff
masneyb
parents:
7
diff
changeset
|
1163 #endif |
292 | 1164 resp = rfc959_send_command (request, command, 1); |
1 | 1165 g_free (command); |
1166 if (resp != '3') | |
1167 { | |
169 | 1168 close (parms->data_connection); |
1169 parms->data_connection = -1; | |
84 | 1170 return (GFTP_ERETRYABLE); |
1 | 1171 } |
1172 } | |
1173 | |
1174 tempstr = g_strconcat ("STOR ", filename, "\r\n", NULL); | |
292 | 1175 ret = rfc959_send_command (request, tempstr, 1); |
1 | 1176 g_free (tempstr); |
1177 if (ret != '1') | |
58 | 1178 { |
169 | 1179 close (parms->data_connection); |
1180 parms->data_connection = -1; | |
84 | 1181 return (GFTP_ERETRYABLE); |
58 | 1182 } |
1 | 1183 |
122 | 1184 gftp_lookup_request_option (request, "passive_transfer", &passive_transfer); |
1185 if (!passive_transfer && | |
1 | 1186 (ret = rfc959_accept_active_connection (request)) < 0) |
1187 return (ret); | |
1188 | |
1189 return (0); | |
1190 } | |
1191 | |
58 | 1192 |
1 | 1193 static long |
1194 rfc959_transfer_file (gftp_request *fromreq, const char *fromfile, | |
1195 off_t fromsize, gftp_request *toreq, | |
1196 const char *tofile, off_t tosize) | |
1197 { | |
1198 char *tempstr, *pos, *endpos; | |
84 | 1199 int ret; |
1 | 1200 |
84 | 1201 g_return_val_if_fail (fromreq != NULL, GFTP_EFATAL); |
1202 g_return_val_if_fail (fromfile != NULL, GFTP_EFATAL); | |
1203 g_return_val_if_fail (toreq != NULL, GFTP_EFATAL); | |
1204 g_return_val_if_fail (tofile != NULL, GFTP_EFATAL); | |
169 | 1205 g_return_val_if_fail (fromreq->datafd > 0, GFTP_EFATAL); |
1206 g_return_val_if_fail (toreq->datafd > 0, GFTP_EFATAL); | |
1 | 1207 |
122 | 1208 gftp_set_request_option (fromreq, "passive_transfer", GINT_TO_POINTER(1)); |
1209 gftp_set_request_option (toreq, "passive_transfer", GINT_TO_POINTER(0)); | |
1 | 1210 |
292 | 1211 if ((ret = rfc959_send_command (fromreq, "PASV\r\n", 1)) != '2') |
84 | 1212 return (ret); |
1 | 1213 |
1214 pos = fromreq->last_ftp_response + 4; | |
1215 while (!isdigit ((int) *pos) && *pos != '\0') | |
1216 pos++; | |
1217 if (*pos == '\0') | |
84 | 1218 return (GFTP_EFATAL); |
1 | 1219 |
1220 endpos = pos; | |
1221 while (*endpos != ')' && *endpos != '\0') | |
1222 endpos++; | |
1223 if (*endpos == ')') | |
1224 *endpos = '\0'; | |
1225 | |
1226 tempstr = g_strconcat ("PORT ", pos, "\r\n", NULL); | |
292 | 1227 if ((ret = rfc959_send_command (toreq, tempstr, 1)) != '2') |
15
82fabd6ef1c4
FXP fixes (from Tobias Gruetzmacher <tobias@portfolio16.de>)
masneyb
parents:
14
diff
changeset
|
1228 { |
82fabd6ef1c4
FXP fixes (from Tobias Gruetzmacher <tobias@portfolio16.de>)
masneyb
parents:
14
diff
changeset
|
1229 g_free (tempstr); |
84 | 1230 return (ret); |
15
82fabd6ef1c4
FXP fixes (from Tobias Gruetzmacher <tobias@portfolio16.de>)
masneyb
parents:
14
diff
changeset
|
1231 } |
1 | 1232 g_free (tempstr); |
1233 | |
1234 tempstr = g_strconcat ("RETR ", fromfile, "\r\n", NULL); | |
390 | 1235 if ((ret = rfc959_send_command (fromreq, tempstr, 0)) < 0) |
58 | 1236 { |
1237 g_free (tempstr); | |
84 | 1238 return (ret); |
58 | 1239 } |
1 | 1240 g_free (tempstr); |
1241 | |
1242 tempstr = g_strconcat ("STOR ", tofile, "\r\n", NULL); | |
390 | 1243 if ((ret = rfc959_send_command (toreq, tempstr, 0)) < 0) |
58 | 1244 { |
1245 g_free (tempstr); | |
84 | 1246 return (ret); |
58 | 1247 } |
1 | 1248 g_free (tempstr); |
1249 | |
292 | 1250 if ((ret = rfc959_read_response (fromreq, 1)) < 0) |
84 | 1251 return (ret); |
1252 | |
292 | 1253 if ((ret = rfc959_read_response (toreq, 1)) < 0) |
84 | 1254 return (ret); |
1 | 1255 |
1256 return (0); | |
1257 } | |
1258 | |
1259 | |
1260 static int | |
1261 rfc959_end_transfer (gftp_request * request) | |
1262 { | |
169 | 1263 rfc959_parms * parms; |
84 | 1264 int ret; |
1265 | |
1266 g_return_val_if_fail (request != NULL, GFTP_EFATAL); | |
1267 g_return_val_if_fail (request->protonum == GFTP_FTP_NUM, GFTP_EFATAL); | |
169 | 1268 g_return_val_if_fail (request->datafd > 0, GFTP_EFATAL); |
1 | 1269 |
169 | 1270 parms = request->protocol_data; |
292 | 1271 parms->sent_retr = 0; |
1272 | |
169 | 1273 if (parms->data_connection > 0) |
1 | 1274 { |
169 | 1275 close (parms->data_connection); |
1276 parms->data_connection = -1; | |
1 | 1277 } |
84 | 1278 |
292 | 1279 ret = rfc959_read_response (request, 1); |
84 | 1280 |
1281 if (ret < 0) | |
1282 return (ret); | |
1283 else if (ret == '2') | |
1284 return (0); | |
1285 else | |
1286 return (GFTP_ERETRYABLE); | |
1 | 1287 } |
1288 | |
1289 | |
1290 static int | |
40 | 1291 rfc959_abort_transfer (gftp_request * request) |
1292 { | |
169 | 1293 rfc959_parms * parms; |
40 | 1294 int ret; |
1295 | |
84 | 1296 g_return_val_if_fail (request != NULL, GFTP_EFATAL); |
1297 g_return_val_if_fail (request->protonum == GFTP_FTP_NUM, GFTP_EFATAL); | |
169 | 1298 g_return_val_if_fail (request->datafd > 0, GFTP_EFATAL); |
40 | 1299 |
169 | 1300 parms = request->protocol_data; |
254 | 1301 |
292 | 1302 if ((ret = rfc959_send_command (request, "ABOR\r\n", 0)) < 0) |
1303 return (ret); | |
1304 | |
169 | 1305 if (parms->data_connection > 0) |
40 | 1306 { |
169 | 1307 close (parms->data_connection); |
1308 parms->data_connection = -1; | |
40 | 1309 } |
1310 | |
169 | 1311 if (request->datafd > 0) |
40 | 1312 { |
292 | 1313 if ((ret = rfc959_read_response (request, 0)) < 0) |
40 | 1314 gftp_disconnect (request); |
1315 } | |
292 | 1316 |
40 | 1317 return (0); |
1318 } | |
1319 | |
1320 | |
1321 static int | |
1 | 1322 rfc959_list_files (gftp_request * request) |
1323 { | |
325 | 1324 int ret; |
1325 intptr_t show_hidden_files, resolve_symlinks, passive_transfer; | |
1 | 1326 char *tempstr, parms[3]; |
1327 | |
84 | 1328 g_return_val_if_fail (request != NULL, GFTP_EFATAL); |
1329 g_return_val_if_fail (request->protonum == GFTP_FTP_NUM, GFTP_EFATAL); | |
169 | 1330 g_return_val_if_fail (request->datafd > 0, GFTP_EFATAL); |
1 | 1331 |
1332 if ((ret = rfc959_data_connection_new (request)) < 0) | |
1333 return (ret); | |
1334 | |
122 | 1335 gftp_lookup_request_option (request, "show_hidden_files", &show_hidden_files); |
1336 gftp_lookup_request_option (request, "resolve_symlinks", &resolve_symlinks); | |
1337 gftp_lookup_request_option (request, "passive_transfer", &passive_transfer); | |
1338 | |
1 | 1339 *parms = '\0'; |
1340 strcat (parms, show_hidden_files ? "a" : ""); | |
1341 strcat (parms, resolve_symlinks ? "L" : ""); | |
1342 tempstr = g_strconcat ("LIST", *parms != '\0' ? " -" : "", parms, "\r\n", | |
1343 NULL); | |
1344 | |
292 | 1345 ret = rfc959_send_command (request, tempstr, 1); |
1 | 1346 g_free (tempstr); |
1347 | |
1348 if (ret != '1') | |
411 | 1349 { |
1350 request->logging_function (gftp_logging_error, request, | |
1351 _("Invalid response '%c' received from server.\n"), | |
1352 ret); | |
1353 return (GFTP_ERETRYABLE); | |
1354 } | |
1 | 1355 |
1356 ret = 0; | |
122 | 1357 if (!passive_transfer) |
1 | 1358 ret = rfc959_accept_active_connection (request); |
1359 | |
1360 return (ret); | |
1361 } | |
1362 | |
1363 | |
122 | 1364 static ssize_t |
1365 rfc959_get_next_file_chunk (gftp_request * request, char *buf, size_t size) | |
1366 { | |
301 | 1367 ssize_t num_read, ret; |
169 | 1368 rfc959_parms * parms; |
299 | 1369 int i, j; |
122 | 1370 |
169 | 1371 parms = request->protocol_data; |
299 | 1372 |
390 | 1373 num_read = parms->data_conn_read (request, buf, size, parms->data_connection); |
122 | 1374 if (num_read < 0) |
1375 return (num_read); | |
1376 | |
301 | 1377 ret = num_read; |
299 | 1378 if (parms->is_ascii_transfer) |
122 | 1379 { |
1380 for (i = 0, j = 0; i < num_read; i++) | |
1381 { | |
1382 if (buf[i] != '\r') | |
1383 buf[j++] = buf[i]; | |
1384 else | |
301 | 1385 ret--; |
122 | 1386 } |
1387 } | |
1388 | |
301 | 1389 return (ret); |
122 | 1390 } |
1391 | |
1392 | |
1393 static ssize_t | |
1394 rfc959_put_next_file_chunk (gftp_request * request, char *buf, size_t size) | |
1395 { | |
169 | 1396 rfc959_parms * parms; |
122 | 1397 ssize_t num_wrote; |
1398 char *tempstr; | |
1399 size_t rsize; | |
299 | 1400 int i, j; |
122 | 1401 |
1402 if (size == 0) | |
1403 return (0); | |
1404 | |
169 | 1405 parms = request->protocol_data; |
1406 | |
299 | 1407 if (parms->is_ascii_transfer) |
122 | 1408 { |
1409 rsize = 0; | |
1410 for (i = 0; i < size; i++) | |
1411 { | |
1412 rsize++; | |
1413 if (i > 0 && buf[i] == '\n' && buf[i - 1] != '\r') | |
1414 rsize++; | |
1415 } | |
1416 | |
1417 if (rsize != size) | |
1418 { | |
1419 tempstr = g_malloc (rsize); | |
1420 | |
1421 for (i = 0, j = 0; i < size; i++) | |
1422 { | |
1423 if (i > 0 && buf[i] == '\n' && buf[i - 1] != '\r') | |
1424 tempstr[j++] = '\r'; | |
1425 tempstr[j++] = buf[i]; | |
1426 } | |
1427 } | |
1428 else | |
1429 tempstr = buf; | |
1430 } | |
1431 else | |
1432 { | |
1433 rsize = size; | |
1434 tempstr = buf; | |
1435 } | |
1436 | |
390 | 1437 num_wrote = parms->data_conn_write (request, tempstr, rsize, |
1438 parms->data_connection); | |
122 | 1439 |
1440 if (tempstr != buf) | |
1441 g_free (tempstr); | |
1442 | |
1443 return (num_wrote); | |
1444 } | |
1445 | |
1446 | |
1 | 1447 int |
58 | 1448 rfc959_get_next_file (gftp_request * request, gftp_file * fle, int fd) |
1 | 1449 { |
389 | 1450 ssize_t (*oldread_func) (gftp_request * request, void *ptr, size_t size, |
1451 int fd); | |
58 | 1452 rfc959_parms * parms; |
249 | 1453 char tempstr[1024]; |
58 | 1454 ssize_t len; |
1 | 1455 |
84 | 1456 g_return_val_if_fail (request != NULL, GFTP_EFATAL); |
1457 g_return_val_if_fail (request->protonum == GFTP_FTP_NUM, GFTP_EFATAL); | |
1458 g_return_val_if_fail (fle != NULL, GFTP_EFATAL); | |
1459 g_return_val_if_fail (fd > 0, GFTP_EFATAL); | |
1 | 1460 |
1461 if (request->last_dir_entry) | |
1462 { | |
1463 g_free (request->last_dir_entry); | |
1464 request->last_dir_entry = NULL; | |
1465 } | |
58 | 1466 |
1467 parms = request->protocol_data; | |
1468 | |
169 | 1469 if (fd == request->datafd) |
1470 fd = parms->data_connection; | |
1471 | |
1 | 1472 do |
1473 { | |
389 | 1474 oldread_func = request->read_function; |
390 | 1475 request->read_function = parms->data_conn_read; |
389 | 1476 len = gftp_get_line (request, &parms->dataconn_rbuf, tempstr, |
1477 sizeof (tempstr), fd); | |
1478 request->read_function = oldread_func; | |
1479 | |
1480 if (len <= 0) | |
1 | 1481 { |
1482 gftp_file_destroy (fle); | |
58 | 1483 return ((int) len); |
1 | 1484 } |
1485 | |
91 | 1486 if (gftp_parse_ls (request, tempstr, fle) != 0) |
1 | 1487 { |
58 | 1488 if (strncmp (tempstr, "total", strlen ("total")) != 0 && |
1489 strncmp (tempstr, _("total"), strlen (_("total"))) != 0) | |
186 | 1490 request->logging_function (gftp_logging_error, request, |
1 | 1491 _("Warning: Cannot parse listing %s\n"), |
1492 tempstr); | |
1493 gftp_file_destroy (fle); | |
1494 continue; | |
1495 } | |
1496 else | |
1497 break; | |
1498 } | |
1499 while (1); | |
1500 | |
1501 len = strlen (tempstr); | |
1502 if (!request->cached) | |
1503 { | |
60 | 1504 request->last_dir_entry = g_strdup_printf ("%s\n", tempstr); |
168 | 1505 request->last_dir_entry_len = strlen (tempstr) + 1; |
1 | 1506 } |
1507 return (len); | |
1508 } | |
1509 | |
1510 | |
1511 static off_t | |
1512 rfc959_get_file_size (gftp_request * request, const char *filename) | |
1513 { | |
1514 char *tempstr; | |
1515 int ret; | |
1516 | |
1517 g_return_val_if_fail (request != NULL, 0); | |
84 | 1518 g_return_val_if_fail (request->protonum == GFTP_FTP_NUM, GFTP_EFATAL); |
1 | 1519 g_return_val_if_fail (filename != NULL, 0); |
169 | 1520 g_return_val_if_fail (request->datafd > 0, 0); |
1 | 1521 |
1522 tempstr = g_strconcat ("SIZE ", filename, "\r\n", NULL); | |
292 | 1523 ret = rfc959_send_command (request, tempstr, 1); |
1 | 1524 g_free (tempstr); |
1525 if (ret < 0) | |
84 | 1526 return (ret); |
1 | 1527 |
1528 if (*request->last_ftp_response != '2') | |
1529 return (0); | |
1530 return (strtol (request->last_ftp_response + 4, NULL, 10)); | |
1531 } | |
1532 | |
1533 | |
1534 static int | |
1535 rfc959_rmdir (gftp_request * request, const char *directory) | |
1536 { | |
1537 char *tempstr, ret; | |
1538 | |
84 | 1539 g_return_val_if_fail (request != NULL, GFTP_EFATAL); |
1540 g_return_val_if_fail (request->protonum == GFTP_FTP_NUM, GFTP_EFATAL); | |
1541 g_return_val_if_fail (directory != NULL, GFTP_EFATAL); | |
169 | 1542 g_return_val_if_fail (request->datafd > 0, GFTP_EFATAL); |
1 | 1543 |
1544 tempstr = g_strconcat ("RMD ", directory, "\r\n", NULL); | |
292 | 1545 ret = rfc959_send_command (request, tempstr, 1); |
1 | 1546 g_free (tempstr); |
84 | 1547 |
1548 if (ret < 0) | |
1549 return (ret); | |
1550 else if (ret == '2') | |
1551 return (0); | |
1552 else | |
1553 return (GFTP_ERETRYABLE); | |
1 | 1554 } |
1555 | |
1556 | |
1557 static int | |
1558 rfc959_rmfile (gftp_request * request, const char *file) | |
1559 { | |
1560 char *tempstr, ret; | |
1561 | |
84 | 1562 g_return_val_if_fail (request != NULL, GFTP_EFATAL); |
1563 g_return_val_if_fail (request->protonum == GFTP_FTP_NUM, GFTP_EFATAL); | |
1564 g_return_val_if_fail (file != NULL, GFTP_EFATAL); | |
169 | 1565 g_return_val_if_fail (request->datafd > 0, GFTP_EFATAL); |
1 | 1566 |
1567 tempstr = g_strconcat ("DELE ", file, "\r\n", NULL); | |
292 | 1568 ret = rfc959_send_command (request, tempstr, 1); |
1 | 1569 g_free (tempstr); |
84 | 1570 |
1571 if (ret < 0) | |
1572 return (ret); | |
1573 else if (ret == '2') | |
1574 return (0); | |
1575 else | |
1576 return (GFTP_ERETRYABLE); | |
1 | 1577 } |
1578 | |
1579 | |
1580 static int | |
1581 rfc959_mkdir (gftp_request * request, const char *directory) | |
1582 { | |
1583 char *tempstr, ret; | |
1584 | |
84 | 1585 g_return_val_if_fail (request != NULL, GFTP_EFATAL); |
1586 g_return_val_if_fail (request->protonum == GFTP_FTP_NUM, GFTP_EFATAL); | |
1587 g_return_val_if_fail (directory != NULL, GFTP_EFATAL); | |
169 | 1588 g_return_val_if_fail (request->datafd > 0, GFTP_EFATAL); |
1 | 1589 |
1590 tempstr = g_strconcat ("MKD ", directory, "\r\n", NULL); | |
292 | 1591 ret = rfc959_send_command (request, tempstr, 1); |
1 | 1592 g_free (tempstr); |
84 | 1593 |
1594 if (ret < 0) | |
1595 return (ret); | |
1596 else if (ret == '2') | |
1597 return (0); | |
1598 else | |
1599 return (GFTP_ERETRYABLE); | |
1 | 1600 } |
1601 | |
1602 | |
1603 static int | |
1604 rfc959_rename (gftp_request * request, const char *oldname, | |
1605 const char *newname) | |
1606 { | |
1607 char *tempstr, ret; | |
1608 | |
84 | 1609 g_return_val_if_fail (request != NULL, GFTP_EFATAL); |
1610 g_return_val_if_fail (request->protonum == GFTP_FTP_NUM, GFTP_EFATAL); | |
1611 g_return_val_if_fail (oldname != NULL, GFTP_EFATAL); | |
1612 g_return_val_if_fail (newname != NULL, GFTP_EFATAL); | |
169 | 1613 g_return_val_if_fail (request->datafd > 0, GFTP_EFATAL); |
1 | 1614 |
1615 tempstr = g_strconcat ("RNFR ", oldname, "\r\n", NULL); | |
292 | 1616 ret = rfc959_send_command (request, tempstr, 1); |
1 | 1617 g_free (tempstr); |
84 | 1618 |
1619 if (ret < 0) | |
1620 return (ret); | |
278 | 1621 else if (ret != '3') |
84 | 1622 return (GFTP_ERETRYABLE); |
1 | 1623 |
1624 tempstr = g_strconcat ("RNTO ", newname, "\r\n", NULL); | |
292 | 1625 ret = rfc959_send_command (request, tempstr, 1); |
1 | 1626 g_free (tempstr); |
84 | 1627 |
1628 if (ret < 0) | |
1629 return (ret); | |
1630 else if (ret == '2') | |
1631 return (0); | |
1632 else | |
1633 return (GFTP_ERETRYABLE); | |
1 | 1634 } |
1635 | |
1636 | |
1637 static int | |
1638 rfc959_chmod (gftp_request * request, const char *file, int mode) | |
1639 { | |
1640 char *tempstr, ret; | |
1641 | |
84 | 1642 g_return_val_if_fail (request != NULL, GFTP_EFATAL); |
1643 g_return_val_if_fail (request->protonum == GFTP_FTP_NUM, GFTP_EFATAL); | |
1644 g_return_val_if_fail (file != NULL, GFTP_EFATAL); | |
169 | 1645 g_return_val_if_fail (request->datafd > 0, GFTP_EFATAL); |
1 | 1646 |
1647 tempstr = g_malloc (strlen (file) + (mode / 10) + 16); | |
1648 sprintf (tempstr, "SITE CHMOD %d %s\r\n", mode, file); | |
292 | 1649 ret = rfc959_send_command (request, tempstr, 1); |
1 | 1650 g_free (tempstr); |
84 | 1651 |
1652 if (ret < 0) | |
1653 return (ret); | |
1654 else if (ret == '2') | |
1655 return (0); | |
1656 else | |
1657 return (GFTP_ERETRYABLE); | |
1 | 1658 } |
1659 | |
1660 | |
1661 static int | |
1662 rfc959_site (gftp_request * request, const char *command) | |
1663 { | |
1664 char *tempstr, ret; | |
1665 | |
84 | 1666 g_return_val_if_fail (request != NULL, GFTP_EFATAL); |
1667 g_return_val_if_fail (request->protonum == GFTP_FTP_NUM, GFTP_EFATAL); | |
1668 g_return_val_if_fail (command != NULL, GFTP_EFATAL); | |
169 | 1669 g_return_val_if_fail (request->datafd > 0, GFTP_EFATAL); |
1 | 1670 |
1671 tempstr = g_strconcat ("SITE ", command, "\r\n", NULL); | |
292 | 1672 ret = rfc959_send_command (request, tempstr, 1); |
1 | 1673 g_free (tempstr); |
84 | 1674 |
1675 if (ret < 0) | |
1676 return (ret); | |
1677 else if (ret == '2') | |
1678 return (0); | |
1679 else | |
1680 return (GFTP_ERETRYABLE); | |
58 | 1681 } |
1682 | |
1683 | |
177 | 1684 static int |
58 | 1685 rfc959_set_config_options (gftp_request * request) |
1686 { | |
122 | 1687 char *proxy_config; |
177 | 1688 int ret; |
58 | 1689 |
122 | 1690 gftp_lookup_request_option (request, "proxy_config", &proxy_config); |
1691 if (strcmp (proxy_config, "http") == 0) | |
58 | 1692 { |
177 | 1693 if ((ret = gftp_protocols[GFTP_HTTP_NUM].init (request)) < 0) |
1694 return (ret); | |
173 | 1695 |
122 | 1696 gftp_set_request_option (request, "proxy_config", "ftp"); |
58 | 1697 } |
177 | 1698 |
1699 return (0); | |
122 | 1700 } |
58 | 1701 |
1702 | |
122 | 1703 void |
1704 rfc959_register_module (void) | |
1705 { | |
1706 gftp_register_config_vars (config_vars); | |
1 | 1707 } |
1708 | |
1709 | |
201 | 1710 void |
1711 rfc959_request_destroy (gftp_request * request) | |
1712 { | |
1713 rfc959_parms * parms; | |
1714 | |
1715 parms = request->protocol_data; | |
1716 | |
1717 if (parms->datafd_rbuf != NULL) | |
1718 gftp_free_getline_buffer (&parms->datafd_rbuf); | |
1719 | |
1720 if (parms->dataconn_rbuf != NULL) | |
1721 gftp_free_getline_buffer (&parms->dataconn_rbuf); | |
1722 } | |
1723 | |
1724 | |
309 | 1725 void |
1726 rfc959_copy_param_options (gftp_request * dest_request, | |
1727 gftp_request * src_request) | |
1728 { | |
1729 rfc959_parms * dparms, * sparms; | |
1730 | |
1731 dparms = dest_request->protocol_data; | |
1732 sparms = src_request->protocol_data; | |
1733 | |
1734 dparms->is_ascii_transfer = sparms->is_ascii_transfer; | |
1735 } | |
1736 | |
1737 | |
173 | 1738 int |
48 | 1739 rfc959_init (gftp_request * request) |
1 | 1740 { |
169 | 1741 rfc959_parms * parms; |
227 | 1742 struct hostent *hent; |
1743 struct utsname unme; | |
1744 struct passwd *pw; | |
1745 char *tempstr; | |
169 | 1746 |
173 | 1747 g_return_val_if_fail (request != NULL, GFTP_EFATAL); |
1 | 1748 |
227 | 1749 gftp_lookup_global_option ("email", &tempstr); |
1750 if (tempstr == NULL || *tempstr == '\0') | |
1751 { | |
1752 /* If there is no email address specified, then we'll just use the | |
1753 currentuser@currenthost */ | |
1754 uname (&unme); | |
1755 pw = getpwuid (geteuid ()); | |
1756 hent = gethostbyname (unme.nodename); | |
1757 if (strchr (unme.nodename, '.') == NULL && hent != NULL) | |
1758 tempstr = g_strconcat (pw->pw_name, "@", hent->h_name, NULL); | |
1759 else | |
1760 tempstr = g_strconcat (pw->pw_name, "@", unme.nodename, NULL); | |
1761 gftp_set_global_option ("email", tempstr); | |
1762 g_free (tempstr); | |
1763 } | |
1764 | |
48 | 1765 request->protonum = GFTP_FTP_NUM; |
1766 request->init = rfc959_init; | |
309 | 1767 request->copy_param_options = rfc959_copy_param_options; |
201 | 1768 request->destroy = rfc959_request_destroy; |
168 | 1769 request->read_function = gftp_fd_read; |
1770 request->write_function = gftp_fd_write; | |
48 | 1771 request->connect = rfc959_connect; |
168 | 1772 request->post_connect = NULL; |
48 | 1773 request->disconnect = rfc959_disconnect; |
1774 request->get_file = rfc959_get_file; | |
1775 request->put_file = rfc959_put_file; | |
1776 request->transfer_file = rfc959_transfer_file; | |
122 | 1777 request->get_next_file_chunk = rfc959_get_next_file_chunk; |
1778 request->put_next_file_chunk = rfc959_put_next_file_chunk; | |
48 | 1779 request->end_transfer = rfc959_end_transfer; |
1780 request->abort_transfer = rfc959_abort_transfer; | |
1781 request->list_files = rfc959_list_files; | |
1782 request->get_next_file = rfc959_get_next_file; | |
1783 request->get_file_size = rfc959_get_file_size; | |
1784 request->chdir = rfc959_chdir; | |
1785 request->rmdir = rfc959_rmdir; | |
1786 request->rmfile = rfc959_rmfile; | |
1787 request->mkdir = rfc959_mkdir; | |
1788 request->rename = rfc959_rename; | |
1789 request->chmod = rfc959_chmod; | |
1790 request->set_file_time = NULL; | |
1791 request->site = rfc959_site; | |
1792 request->parse_url = NULL; | |
63 | 1793 request->swap_socks = NULL; |
58 | 1794 request->set_config_options = rfc959_set_config_options; |
48 | 1795 request->url_prefix = "ftp"; |
1796 request->need_hostport = 1; | |
1797 request->need_userpass = 1; | |
1798 request->use_cache = 1; | |
1799 request->always_connected = 0; | |
169 | 1800 |
58 | 1801 request->protocol_data = g_malloc0 (sizeof (rfc959_parms)); |
169 | 1802 parms = request->protocol_data; |
1803 parms->data_connection = -1; | |
389 | 1804 parms->auth_tls_start = NULL; |
390 | 1805 parms->data_conn_read = gftp_fd_read; |
1806 parms->data_conn_write = gftp_fd_write; | |
169 | 1807 |
177 | 1808 return (gftp_set_config_options (request)); |
1 | 1809 } |
1810 |