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