Mercurial > gftp.yaz
annotate lib/rfc959.c @ 390:0444232dc494
2003-2-3 Brian Masney <masneyb@gftp.org>
* lib/ftpcommon.h lib/ftps.c lib/rfc959.c - added pointers to
read/write functions to the rfc959_params structure for the data
connection. For now, this is always set to the plaintext version.
author | masneyb |
---|---|
date | Wed, 04 Feb 2004 02:20:33 +0000 |
parents | b39a312323ec |
children | c43caf0691c6 |
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, |
58 | 317 _("Received invalid response to PWD command: '%s'\n"), |
318 request->last_ftp_response); | |
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, |
58 | 326 _("Received invalid response to PWD command: '%s'\n"), |
327 request->last_ftp_response); | |
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, |
58 | 337 _("Received invalid response to PWD command: '%s'\n"), |
338 request->last_ftp_response); | |
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 { | |
539 gftp_disconnect (request); | |
286 | 540 |
541 if (resp == '5') | |
542 return (GFTP_EFATAL); | |
543 else | |
544 return (GFTP_ERETRYABLE); | |
1 | 545 } |
546 | |
169 | 547 if ((ret = rfc959_syst (request)) < 0 && request->datafd < 0) |
91 | 548 return (ret); |
549 | |
122 | 550 gftp_lookup_request_option (request, "ascii_transfers", &ascii_transfers); |
551 if (ascii_transfers) | |
552 { | |
553 tempstr = "TYPE A\r\n"; | |
554 parms->is_ascii_transfer = 1; | |
555 } | |
1 | 556 else |
122 | 557 { |
558 tempstr = "TYPE I\r\n"; | |
559 parms->is_ascii_transfer = 0; | |
560 } | |
1 | 561 |
292 | 562 if ((ret = rfc959_send_command (request, tempstr, 1)) < 0) |
84 | 563 return (ret); |
1 | 564 |
565 ret = -1; | |
566 if (request->directory != NULL && *request->directory != '\0') | |
567 { | |
568 ret = rfc959_chdir (request, request->directory); | |
169 | 569 if (request->datafd < 0) |
84 | 570 return (ret); |
1 | 571 } |
572 | |
573 if (ret != 0) | |
574 { | |
84 | 575 if ((ret = rfc959_getcwd (request)) < 0) |
576 return (ret); | |
1 | 577 } |
578 | |
169 | 579 if (request->datafd < 0) |
84 | 580 return (GFTP_EFATAL); |
1 | 581 |
582 return (0); | |
583 } | |
584 | |
585 | |
586 static void | |
587 rfc959_disconnect (gftp_request * request) | |
588 { | |
169 | 589 rfc959_parms * parms; |
590 | |
1 | 591 g_return_if_fail (request != NULL); |
592 g_return_if_fail (request->protonum == GFTP_FTP_NUM); | |
593 | |
169 | 594 parms = request->protocol_data; |
595 | |
596 if (request->datafd > 0) | |
1 | 597 { |
186 | 598 request->logging_function (gftp_logging_misc, request, |
1 | 599 _("Disconnecting from site %s\n"), |
600 request->hostname); | |
169 | 601 close (request->datafd); |
602 request->datafd = -1; | |
603 } | |
604 | |
605 if (parms->data_connection > 0) | |
606 { | |
607 close (parms->data_connection); | |
608 parms->data_connection = -1; | |
1 | 609 } |
610 } | |
611 | |
612 | |
48 | 613 static int |
146 | 614 rfc959_ipv4_data_connection_new (gftp_request * request) |
48 | 615 { |
616 char *pos, *pos1, resp, *command; | |
617 struct sockaddr_in data_addr; | |
325 | 618 int i; |
619 intptr_t passive_transfer; | |
169 | 620 rfc959_parms * parms; |
195 | 621 socklen_t data_addr_len; |
48 | 622 unsigned int temp[6]; |
623 unsigned char ad[6]; | |
624 | |
169 | 625 parms = request->protocol_data; |
626 | |
627 if ((parms->data_connection = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) | |
48 | 628 { |
186 | 629 request->logging_function (gftp_logging_error, request, |
313 | 630 _("Failed to create a IPv4 socket: %s\n"), |
48 | 631 g_strerror (errno)); |
632 gftp_disconnect (request); | |
84 | 633 return (GFTP_ERETRYABLE); |
48 | 634 } |
635 | |
182 | 636 if (fcntl (parms->data_connection, F_SETFD, 1) == -1) |
637 { | |
186 | 638 request->logging_function (gftp_logging_error, request, |
182 | 639 _("Error: Cannot set close on exec flag: %s\n"), |
640 g_strerror (errno)); | |
641 | |
642 return (GFTP_ERETRYABLE); | |
643 } | |
644 | |
48 | 645 data_addr_len = sizeof (data_addr); |
646 memset (&data_addr, 0, data_addr_len); | |
647 data_addr.sin_family = AF_INET; | |
648 | |
122 | 649 gftp_lookup_request_option (request, "passive_transfer", &passive_transfer); |
650 if (passive_transfer) | |
48 | 651 { |
292 | 652 if ((resp = rfc959_send_command (request, "PASV\r\n", 1)) != '2') |
48 | 653 { |
169 | 654 if (request->datafd < 0) |
288 | 655 return (GFTP_ERETRYABLE); |
48 | 656 |
122 | 657 gftp_set_request_option (request, "passive_transfer", GINT_TO_POINTER(0)); |
146 | 658 return (rfc959_ipv4_data_connection_new (request)); |
48 | 659 } |
58 | 660 |
48 | 661 pos = request->last_ftp_response + 4; |
662 while (!isdigit ((int) *pos) && *pos != '\0') | |
663 pos++; | |
58 | 664 |
48 | 665 if (*pos == '\0') |
666 { | |
186 | 667 request->logging_function (gftp_logging_error, request, |
58 | 668 _("Cannot find an IP address in PASV response '%s'\n"), |
669 request->last_ftp_response); | |
48 | 670 gftp_disconnect (request); |
84 | 671 return (GFTP_EFATAL); |
48 | 672 } |
58 | 673 |
48 | 674 if (sscanf (pos, "%u,%u,%u,%u,%u,%u", &temp[0], &temp[1], &temp[2], |
675 &temp[3], &temp[4], &temp[5]) != 6) | |
676 { | |
186 | 677 request->logging_function (gftp_logging_error, request, |
58 | 678 _("Cannot find an IP address in PASV response '%s'\n"), |
679 request->last_ftp_response); | |
48 | 680 gftp_disconnect (request); |
84 | 681 return (GFTP_EFATAL); |
48 | 682 } |
58 | 683 |
48 | 684 for (i = 0; i < 6; i++) |
685 ad[i] = (unsigned char) (temp[i] & 0xff); | |
686 | |
687 memcpy (&data_addr.sin_addr, &ad[0], 4); | |
688 memcpy (&data_addr.sin_port, &ad[4], 2); | |
169 | 689 if (connect (parms->data_connection, (struct sockaddr *) &data_addr, |
58 | 690 data_addr_len) == -1) |
48 | 691 { |
186 | 692 request->logging_function (gftp_logging_error, request, |
48 | 693 _("Cannot create a data connection: %s\n"), |
694 g_strerror (errno)); | |
695 gftp_disconnect (request); | |
84 | 696 return (GFTP_ERETRYABLE); |
48 | 697 } |
698 } | |
699 else | |
700 { | |
169 | 701 if (getsockname (request->datafd, (struct sockaddr *) &data_addr, |
58 | 702 &data_addr_len) == -1) |
703 { | |
186 | 704 request->logging_function (gftp_logging_error, request, |
58 | 705 _("Cannot get socket name: %s\n"), |
706 g_strerror (errno)); | |
707 gftp_disconnect (request); | |
84 | 708 return (GFTP_ERETRYABLE); |
58 | 709 } |
710 | |
48 | 711 data_addr.sin_port = 0; |
169 | 712 if (bind (parms->data_connection, (struct sockaddr *) &data_addr, |
58 | 713 data_addr_len) == -1) |
48 | 714 { |
186 | 715 request->logging_function (gftp_logging_error, request, |
48 | 716 _("Cannot bind a port: %s\n"), |
717 g_strerror (errno)); | |
718 gftp_disconnect (request); | |
84 | 719 return (GFTP_ERETRYABLE); |
48 | 720 } |
721 | |
169 | 722 if (getsockname (parms->data_connection, (struct sockaddr *) &data_addr, |
58 | 723 &data_addr_len) == -1) |
724 { | |
186 | 725 request->logging_function (gftp_logging_error, request, |
58 | 726 _("Cannot get socket name: %s\n"), |
727 g_strerror (errno)); | |
728 gftp_disconnect (request); | |
84 | 729 return (GFTP_ERETRYABLE); |
58 | 730 } |
731 | |
169 | 732 if (listen (parms->data_connection, 1) == -1) |
48 | 733 { |
186 | 734 request->logging_function (gftp_logging_error, request, |
48 | 735 _("Cannot listen on port %d: %s\n"), |
736 ntohs (data_addr.sin_port), | |
737 g_strerror (errno)); | |
738 gftp_disconnect (request); | |
84 | 739 return (GFTP_ERETRYABLE); |
48 | 740 } |
58 | 741 |
48 | 742 pos = (char *) &data_addr.sin_addr; |
743 pos1 = (char *) &data_addr.sin_port; | |
744 command = g_strdup_printf ("PORT %u,%u,%u,%u,%u,%u\r\n", | |
745 pos[0] & 0xff, pos[1] & 0xff, pos[2] & 0xff, | |
746 pos[3] & 0xff, pos1[0] & 0xff, | |
747 pos1[1] & 0xff); | |
292 | 748 resp = rfc959_send_command (request, command, 1); |
48 | 749 g_free (command); |
750 if (resp != '2') | |
751 { | |
752 gftp_disconnect (request); | |
84 | 753 return (GFTP_ERETRYABLE); |
48 | 754 } |
755 } | |
756 | |
757 return (0); | |
758 } | |
759 | |
760 | |
146 | 761 #ifdef HAVE_IPV6 |
762 | |
763 static int | |
764 rfc959_ipv6_data_connection_new (gftp_request * request) | |
765 { | |
766 char *pos, resp, buf[64], *command; | |
767 struct sockaddr_in6 data_addr; | |
768 int passive_transfer; | |
195 | 769 socklen_t data_addr_len; |
169 | 770 rfc959_parms * parms; |
146 | 771 unsigned int port; |
772 | |
169 | 773 parms = request->protocol_data; |
774 if ((parms->data_connection = socket (AF_INET6, SOCK_STREAM, IPPROTO_TCP)) < 0) | |
146 | 775 { |
186 | 776 request->logging_function (gftp_logging_error, request, |
313 | 777 _("Failed to create a IPv6 socket: %s\n"), |
146 | 778 g_strerror (errno)); |
779 gftp_disconnect (request); | |
780 return (GFTP_ERETRYABLE); | |
781 } | |
782 | |
182 | 783 if (fcntl (parms->data_connection, F_SETFD, 1) == -1) |
784 { | |
186 | 785 request->logging_function (gftp_logging_error, request, |
182 | 786 _("Error: Cannot set close on exec flag: %s\n"), |
787 g_strerror (errno)); | |
788 | |
789 return (GFTP_ERETRYABLE); | |
790 } | |
791 | |
146 | 792 data_addr_len = sizeof (data_addr); |
793 /* This condition shouldn't happen. We better check anyway... */ | |
794 if (data_addr_len != request->hostp->ai_addrlen) | |
795 { | |
186 | 796 request->logging_function (gftp_logging_error, request, |
146 | 797 _("Error: It doesn't look like we are connected via IPv6. Aborting connection.\n")); |
798 gftp_disconnect (request); | |
799 return (GFTP_EFATAL); | |
800 } | |
801 | |
802 memset (&data_addr, 0, data_addr_len); | |
803 data_addr.sin6_family = AF_INET6; | |
804 | |
805 gftp_lookup_request_option (request, "passive_transfer", &passive_transfer); | |
806 if (passive_transfer) | |
807 { | |
292 | 808 if ((resp = rfc959_send_command (request, "EPSV\r\n", 1)) != '2') |
146 | 809 { |
169 | 810 if (request->datafd < 0) |
288 | 811 return (GFTP_ERETRYABLE); |
146 | 812 |
813 gftp_set_request_option (request, "passive_transfer", | |
814 GINT_TO_POINTER(0)); | |
815 return (rfc959_ipv6_data_connection_new (request)); | |
816 } | |
817 | |
818 pos = request->last_ftp_response + 4; | |
819 while (*pos != '(' && *pos != '\0') | |
820 pos++; | |
821 pos++; | |
822 | |
823 if (*pos == '\0') | |
824 { | |
186 | 825 request->logging_function (gftp_logging_error, request, |
146 | 826 _("Invalid EPSV response '%s'\n"), |
827 request->last_ftp_response); | |
828 gftp_disconnect (request); | |
829 return (GFTP_EFATAL); | |
830 } | |
831 | |
319 | 832 if (sscanf (pos, "|||%u|", &port) != 1) |
146 | 833 { |
186 | 834 request->logging_function (gftp_logging_error, request, |
146 | 835 _("Invalid EPSV response '%s'\n"), |
836 request->last_ftp_response); | |
837 gftp_disconnect (request); | |
838 return (GFTP_EFATAL); | |
839 } | |
840 | |
841 memcpy (&data_addr, request->hostp->ai_addr, data_addr_len); | |
842 data_addr.sin6_port = htons (port); | |
843 | |
169 | 844 if (connect (parms->data_connection, (struct sockaddr *) &data_addr, |
146 | 845 data_addr_len) == -1) |
846 { | |
186 | 847 request->logging_function (gftp_logging_error, request, |
146 | 848 _("Cannot create a data connection: %s\n"), |
849 g_strerror (errno)); | |
850 gftp_disconnect (request); | |
851 return (GFTP_ERETRYABLE); | |
852 } | |
853 } | |
854 else | |
855 { | |
856 memcpy (&data_addr, request->hostp->ai_addr, data_addr_len); | |
857 data_addr.sin6_port = 0; | |
858 | |
169 | 859 if (bind (parms->data_connection, (struct sockaddr *) &data_addr, |
146 | 860 data_addr_len) == -1) |
861 { | |
186 | 862 request->logging_function (gftp_logging_error, request, |
146 | 863 _("Cannot bind a port: %s\n"), |
864 g_strerror (errno)); | |
865 gftp_disconnect (request); | |
866 return (GFTP_ERETRYABLE); | |
867 } | |
868 | |
169 | 869 if (getsockname (parms->data_connection, (struct sockaddr *) &data_addr, |
146 | 870 &data_addr_len) == -1) |
871 { | |
186 | 872 request->logging_function (gftp_logging_error, request, |
146 | 873 _("Cannot get socket name: %s\n"), |
874 g_strerror (errno)); | |
875 gftp_disconnect (request); | |
876 return (GFTP_ERETRYABLE); | |
877 } | |
878 | |
169 | 879 if (listen (parms->data_connection, 1) == -1) |
146 | 880 { |
186 | 881 request->logging_function (gftp_logging_error, request, |
146 | 882 _("Cannot listen on port %d: %s\n"), |
883 ntohs (data_addr.sin6_port), | |
884 g_strerror (errno)); | |
885 gftp_disconnect (request); | |
886 return (GFTP_ERETRYABLE); | |
887 } | |
888 | |
889 if (inet_ntop (AF_INET6, &data_addr.sin6_addr, buf, sizeof (buf)) == NULL) | |
890 { | |
186 | 891 request->logging_function (gftp_logging_error, request, |
146 | 892 _("Cannot get address of local socket: %s\n"), |
893 g_strerror (errno)); | |
894 gftp_disconnect (request); | |
895 return (GFTP_ERETRYABLE); | |
896 } | |
897 | |
898 command = g_strdup_printf ("EPRT |2|%s|%d|\n", buf, | |
899 ntohs (data_addr.sin6_port)); | |
900 | |
292 | 901 resp = rfc959_send_command (request, command, 1); |
146 | 902 g_free (command); |
903 if (resp != '2') | |
904 { | |
905 gftp_disconnect (request); | |
906 return (GFTP_ERETRYABLE); | |
907 } | |
908 } | |
909 | |
910 return (0); | |
911 } | |
912 | |
913 #endif /* HAVE_IPV6 */ | |
914 | |
915 | |
916 static int | |
917 rfc959_data_connection_new (gftp_request * request) | |
918 { | |
919 g_return_val_if_fail (request != NULL, GFTP_EFATAL); | |
920 g_return_val_if_fail (request->protonum == GFTP_FTP_NUM, GFTP_EFATAL); | |
169 | 921 g_return_val_if_fail (request->datafd > 0, GFTP_EFATAL); |
146 | 922 |
923 #ifdef HAVE_IPV6 | |
151 | 924 if (GFTP_GET_AI_FAMILY(request) == AF_INET6) |
146 | 925 return (rfc959_ipv6_data_connection_new (request)); |
926 else | |
151 | 927 return (rfc959_ipv4_data_connection_new (request)); |
928 #else | |
929 return (rfc959_ipv4_data_connection_new (request)); | |
146 | 930 #endif |
931 } | |
932 | |
933 | |
48 | 934 static int |
935 rfc959_accept_active_connection (gftp_request * request) | |
936 { | |
325 | 937 int infd, ret; |
938 intptr_t passive_transfer; | |
169 | 939 rfc959_parms * parms; |
146 | 940 #ifdef HAVE_IPV6 |
339 | 941 struct sockaddr_in6 cli_addr; |
146 | 942 #else |
339 | 943 struct sockaddr_in cli_addr; |
146 | 944 #endif |
195 | 945 socklen_t cli_addr_len; |
48 | 946 |
169 | 947 parms = request->protocol_data; |
948 | |
84 | 949 g_return_val_if_fail (request != NULL, GFTP_EFATAL); |
950 g_return_val_if_fail (request->protonum == GFTP_FTP_NUM, GFTP_EFATAL); | |
169 | 951 g_return_val_if_fail (parms->data_connection > 0, GFTP_EFATAL); |
122 | 952 |
953 gftp_lookup_request_option (request, "passive_transfer", &passive_transfer); | |
954 g_return_val_if_fail (!passive_transfer, GFTP_EFATAL); | |
48 | 955 |
956 cli_addr_len = sizeof (cli_addr); | |
58 | 957 |
169 | 958 if ((ret = gftp_fd_set_sockblocking (request, parms->data_connection, 0)) < 0) |
84 | 959 return (ret); |
58 | 960 |
169 | 961 if ((infd = accept (parms->data_connection, (struct sockaddr *) &cli_addr, |
48 | 962 &cli_addr_len)) == -1) |
963 { | |
186 | 964 request->logging_function (gftp_logging_error, request, |
48 | 965 _("Cannot accept connection from server: %s\n"), |
966 g_strerror (errno)); | |
967 gftp_disconnect (request); | |
84 | 968 return (GFTP_ERETRYABLE); |
48 | 969 } |
970 | |
169 | 971 close (parms->data_connection); |
48 | 972 |
169 | 973 parms->data_connection = infd; |
974 if ((ret = gftp_fd_set_sockblocking (request, parms->data_connection, 1)) < 0) | |
84 | 975 return (ret); |
58 | 976 |
48 | 977 return (0); |
978 } | |
979 | |
980 | |
122 | 981 static int |
254 | 982 rfc959_is_ascii_transfer (gftp_request * request, const char *filename) |
122 | 983 { |
984 gftp_config_list_vars * tmplistvar; | |
985 gftp_file_extensions * tempext; | |
325 | 986 int stlen; |
987 intptr_t ascii_transfers; | |
122 | 988 GList * templist; |
989 | |
990 gftp_lookup_global_option ("ext", &tmplistvar); | |
254 | 991 gftp_lookup_request_option (request, "ascii_transfers", &ascii_transfers); |
122 | 992 |
993 stlen = strlen (filename); | |
994 for (templist = tmplistvar->list; templist != NULL; templist = templist->next) | |
995 { | |
996 tempext = templist->data; | |
997 | |
998 if (stlen >= tempext->stlen && | |
999 strcmp (&filename[stlen - tempext->stlen], tempext->ext) == 0) | |
1000 { | |
1001 if (toupper (*tempext->ascii_binary == 'A')) | |
254 | 1002 ascii_transfers = 1; |
1003 else if (toupper (*tempext->ascii_binary == 'B')) | |
1004 ascii_transfers = 0; | |
122 | 1005 break; |
1006 } | |
1007 } | |
1008 | |
254 | 1009 return (ascii_transfers); |
122 | 1010 } |
1011 | |
1012 | |
309 | 1013 static int |
122 | 1014 rfc959_set_data_type (gftp_request * request, const char *filename) |
1015 { | |
1016 rfc959_parms * parms; | |
309 | 1017 int new_ascii, ret; |
122 | 1018 char *tempstr; |
1019 | |
309 | 1020 g_return_val_if_fail (request != NULL, GFTP_EFATAL); |
1021 g_return_val_if_fail (request->protonum == GFTP_FTP_NUM, GFTP_EFATAL); | |
122 | 1022 |
1023 parms = request->protocol_data; | |
254 | 1024 new_ascii = rfc959_is_ascii_transfer (request, filename); |
122 | 1025 |
169 | 1026 if (request->datafd > 0 && new_ascii != parms->is_ascii_transfer) |
122 | 1027 { |
1028 if (new_ascii) | |
1029 { | |
1030 tempstr = "TYPE A\r\n"; | |
1031 parms->is_ascii_transfer = 1; | |
1032 } | |
1033 else | |
1034 { | |
1035 tempstr = "TYPE I\r\n"; | |
254 | 1036 parms->is_ascii_transfer = 0; |
122 | 1037 } |
1038 | |
309 | 1039 if ((ret = rfc959_send_command (request, tempstr, 1)) < 0) |
1040 return (ret); | |
122 | 1041 } |
1042 | |
309 | 1043 return (0); |
122 | 1044 } |
1045 | |
1046 | |
58 | 1047 static off_t |
1048 rfc959_get_file (gftp_request * request, const char *filename, int fd, | |
1 | 1049 off_t startsize) |
1050 { | |
1051 char *command, *tempstr, resp; | |
325 | 1052 int ret; |
1053 intptr_t passive_transfer; | |
169 | 1054 rfc959_parms * parms; |
1 | 1055 |
84 | 1056 g_return_val_if_fail (request != NULL, GFTP_EFATAL); |
1057 g_return_val_if_fail (request->protonum == GFTP_FTP_NUM, GFTP_EFATAL); | |
1058 g_return_val_if_fail (filename != NULL, GFTP_EFATAL); | |
169 | 1059 g_return_val_if_fail (request->datafd > 0, GFTP_EFATAL); |
1 | 1060 |
169 | 1061 parms = request->protocol_data; |
58 | 1062 if (fd > 0) |
169 | 1063 parms->data_connection = fd; |
1 | 1064 |
309 | 1065 if ((ret = rfc959_set_data_type (request, filename)) < 0) |
1066 return (ret); | |
122 | 1067 |
169 | 1068 if (parms->data_connection < 0 && |
1 | 1069 (ret = rfc959_data_connection_new (request)) < 0) |
1070 return (ret); | |
1071 | |
169 | 1072 if ((ret = gftp_fd_set_sockblocking (request, parms->data_connection, 1)) < 0) |
84 | 1073 return (ret); |
1 | 1074 |
1075 if (startsize > 0) | |
1076 { | |
14
83090328581e
* More largefile support. Hopefully all that is left is the configure stuff
masneyb
parents:
7
diff
changeset
|
1077 #if defined (_LARGEFILE_SOURCE) |
372 | 1078 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
|
1079 #else |
1 | 1080 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
|
1081 #endif |
292 | 1082 resp = rfc959_send_command (request, command, 1); |
1 | 1083 g_free (command); |
1084 | |
1085 if (resp != '3') | |
1086 { | |
169 | 1087 close (parms->data_connection); |
1088 parms->data_connection = -1; | |
84 | 1089 return (GFTP_ERETRYABLE); |
1 | 1090 } |
1091 } | |
1092 | |
1093 tempstr = g_strconcat ("RETR ", filename, "\r\n", NULL); | |
292 | 1094 ret = rfc959_send_command (request, tempstr, 1); |
1 | 1095 g_free (tempstr); |
1096 | |
1097 if (ret != '1') | |
58 | 1098 { |
169 | 1099 close (parms->data_connection); |
1100 parms->data_connection = -1; | |
84 | 1101 return (GFTP_ERETRYABLE); |
58 | 1102 } |
1 | 1103 |
122 | 1104 gftp_lookup_request_option (request, "passive_transfer", &passive_transfer); |
1105 if (!passive_transfer && | |
1 | 1106 (ret = rfc959_accept_active_connection (request)) < 0) |
1107 return (ret); | |
1108 | |
1109 if ((tempstr = strrchr (request->last_ftp_response, '(')) == NULL) | |
1110 { | |
1111 tempstr = request->last_ftp_response + 4; | |
1112 while (!isdigit ((int) *tempstr) && *tempstr != '\0') | |
1113 tempstr++; | |
1114 } | |
1115 else | |
1116 tempstr++; | |
1117 | |
292 | 1118 parms->sent_retr = 1; |
244 | 1119 return (gftp_parse_file_size (tempstr) + startsize); |
1 | 1120 } |
1121 | |
1122 | |
1123 static int | |
58 | 1124 rfc959_put_file (gftp_request * request, const char *filename, int fd, |
1 | 1125 off_t startsize, off_t totalsize) |
1126 { | |
1127 char *command, *tempstr, resp; | |
325 | 1128 int ret; |
1129 intptr_t passive_transfer; | |
169 | 1130 rfc959_parms * parms; |
1 | 1131 |
84 | 1132 g_return_val_if_fail (request != NULL, GFTP_EFATAL); |
1133 g_return_val_if_fail (request->protonum == GFTP_FTP_NUM, GFTP_EFATAL); | |
1134 g_return_val_if_fail (filename != NULL, GFTP_EFATAL); | |
169 | 1135 g_return_val_if_fail (request->datafd > 0, GFTP_EFATAL); |
1 | 1136 |
169 | 1137 parms = request->protocol_data; |
58 | 1138 if (fd > 0) |
169 | 1139 fd = parms->data_connection; |
1 | 1140 |
309 | 1141 if ((ret = rfc959_set_data_type (request, filename)) < 0) |
1142 return (ret); | |
122 | 1143 |
169 | 1144 if (parms->data_connection < 0 && |
1 | 1145 (ret = rfc959_data_connection_new (request)) < 0) |
1146 return (ret); | |
1147 | |
169 | 1148 if ((ret = gftp_fd_set_sockblocking (request, parms->data_connection, 1)) < 0) |
84 | 1149 return (ret); |
1 | 1150 |
1151 if (startsize > 0) | |
1152 { | |
14
83090328581e
* More largefile support. Hopefully all that is left is the configure stuff
masneyb
parents:
7
diff
changeset
|
1153 #if defined (_LARGEFILE_SOURCE) |
372 | 1154 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
|
1155 #else |
83090328581e
* More largefile support. Hopefully all that is left is the configure stuff
masneyb
parents:
7
diff
changeset
|
1156 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
|
1157 #endif |
292 | 1158 resp = rfc959_send_command (request, command, 1); |
1 | 1159 g_free (command); |
1160 if (resp != '3') | |
1161 { | |
169 | 1162 close (parms->data_connection); |
1163 parms->data_connection = -1; | |
84 | 1164 return (GFTP_ERETRYABLE); |
1 | 1165 } |
1166 } | |
1167 | |
1168 tempstr = g_strconcat ("STOR ", filename, "\r\n", NULL); | |
292 | 1169 ret = rfc959_send_command (request, tempstr, 1); |
1 | 1170 g_free (tempstr); |
1171 if (ret != '1') | |
58 | 1172 { |
169 | 1173 close (parms->data_connection); |
1174 parms->data_connection = -1; | |
84 | 1175 return (GFTP_ERETRYABLE); |
58 | 1176 } |
1 | 1177 |
122 | 1178 gftp_lookup_request_option (request, "passive_transfer", &passive_transfer); |
1179 if (!passive_transfer && | |
1 | 1180 (ret = rfc959_accept_active_connection (request)) < 0) |
1181 return (ret); | |
1182 | |
1183 return (0); | |
1184 } | |
1185 | |
58 | 1186 |
1 | 1187 static long |
1188 rfc959_transfer_file (gftp_request *fromreq, const char *fromfile, | |
1189 off_t fromsize, gftp_request *toreq, | |
1190 const char *tofile, off_t tosize) | |
1191 { | |
1192 char *tempstr, *pos, *endpos; | |
84 | 1193 int ret; |
1 | 1194 |
84 | 1195 g_return_val_if_fail (fromreq != NULL, GFTP_EFATAL); |
1196 g_return_val_if_fail (fromfile != NULL, GFTP_EFATAL); | |
1197 g_return_val_if_fail (toreq != NULL, GFTP_EFATAL); | |
1198 g_return_val_if_fail (tofile != NULL, GFTP_EFATAL); | |
169 | 1199 g_return_val_if_fail (fromreq->datafd > 0, GFTP_EFATAL); |
1200 g_return_val_if_fail (toreq->datafd > 0, GFTP_EFATAL); | |
1 | 1201 |
122 | 1202 gftp_set_request_option (fromreq, "passive_transfer", GINT_TO_POINTER(1)); |
1203 gftp_set_request_option (toreq, "passive_transfer", GINT_TO_POINTER(0)); | |
1 | 1204 |
292 | 1205 if ((ret = rfc959_send_command (fromreq, "PASV\r\n", 1)) != '2') |
84 | 1206 return (ret); |
1 | 1207 |
1208 pos = fromreq->last_ftp_response + 4; | |
1209 while (!isdigit ((int) *pos) && *pos != '\0') | |
1210 pos++; | |
1211 if (*pos == '\0') | |
84 | 1212 return (GFTP_EFATAL); |
1 | 1213 |
1214 endpos = pos; | |
1215 while (*endpos != ')' && *endpos != '\0') | |
1216 endpos++; | |
1217 if (*endpos == ')') | |
1218 *endpos = '\0'; | |
1219 | |
1220 tempstr = g_strconcat ("PORT ", pos, "\r\n", NULL); | |
292 | 1221 if ((ret = rfc959_send_command (toreq, tempstr, 1)) != '2') |
15
82fabd6ef1c4
FXP fixes (from Tobias Gruetzmacher <tobias@portfolio16.de>)
masneyb
parents:
14
diff
changeset
|
1222 { |
82fabd6ef1c4
FXP fixes (from Tobias Gruetzmacher <tobias@portfolio16.de>)
masneyb
parents:
14
diff
changeset
|
1223 g_free (tempstr); |
84 | 1224 return (ret); |
15
82fabd6ef1c4
FXP fixes (from Tobias Gruetzmacher <tobias@portfolio16.de>)
masneyb
parents:
14
diff
changeset
|
1225 } |
1 | 1226 g_free (tempstr); |
1227 | |
1228 tempstr = g_strconcat ("RETR ", fromfile, "\r\n", NULL); | |
390 | 1229 if ((ret = rfc959_send_command (fromreq, tempstr, 0)) < 0) |
58 | 1230 { |
1231 g_free (tempstr); | |
84 | 1232 return (ret); |
58 | 1233 } |
1 | 1234 g_free (tempstr); |
1235 | |
1236 tempstr = g_strconcat ("STOR ", tofile, "\r\n", NULL); | |
390 | 1237 if ((ret = rfc959_send_command (toreq, tempstr, 0)) < 0) |
58 | 1238 { |
1239 g_free (tempstr); | |
84 | 1240 return (ret); |
58 | 1241 } |
1 | 1242 g_free (tempstr); |
1243 | |
292 | 1244 if ((ret = rfc959_read_response (fromreq, 1)) < 0) |
84 | 1245 return (ret); |
1246 | |
292 | 1247 if ((ret = rfc959_read_response (toreq, 1)) < 0) |
84 | 1248 return (ret); |
1 | 1249 |
1250 return (0); | |
1251 } | |
1252 | |
1253 | |
1254 static int | |
1255 rfc959_end_transfer (gftp_request * request) | |
1256 { | |
169 | 1257 rfc959_parms * parms; |
84 | 1258 int ret; |
1259 | |
1260 g_return_val_if_fail (request != NULL, GFTP_EFATAL); | |
1261 g_return_val_if_fail (request->protonum == GFTP_FTP_NUM, GFTP_EFATAL); | |
169 | 1262 g_return_val_if_fail (request->datafd > 0, GFTP_EFATAL); |
1 | 1263 |
169 | 1264 parms = request->protocol_data; |
292 | 1265 parms->sent_retr = 0; |
1266 | |
169 | 1267 if (parms->data_connection > 0) |
1 | 1268 { |
169 | 1269 close (parms->data_connection); |
1270 parms->data_connection = -1; | |
1 | 1271 } |
84 | 1272 |
292 | 1273 ret = rfc959_read_response (request, 1); |
84 | 1274 |
1275 if (ret < 0) | |
1276 return (ret); | |
1277 else if (ret == '2') | |
1278 return (0); | |
1279 else | |
1280 return (GFTP_ERETRYABLE); | |
1 | 1281 } |
1282 | |
1283 | |
1284 static int | |
40 | 1285 rfc959_abort_transfer (gftp_request * request) |
1286 { | |
169 | 1287 rfc959_parms * parms; |
40 | 1288 int ret; |
1289 | |
84 | 1290 g_return_val_if_fail (request != NULL, GFTP_EFATAL); |
1291 g_return_val_if_fail (request->protonum == GFTP_FTP_NUM, GFTP_EFATAL); | |
169 | 1292 g_return_val_if_fail (request->datafd > 0, GFTP_EFATAL); |
40 | 1293 |
169 | 1294 parms = request->protocol_data; |
254 | 1295 |
292 | 1296 if ((ret = rfc959_send_command (request, "ABOR\r\n", 0)) < 0) |
1297 return (ret); | |
1298 | |
169 | 1299 if (parms->data_connection > 0) |
40 | 1300 { |
169 | 1301 close (parms->data_connection); |
1302 parms->data_connection = -1; | |
40 | 1303 } |
1304 | |
169 | 1305 if (request->datafd > 0) |
40 | 1306 { |
292 | 1307 if ((ret = rfc959_read_response (request, 0)) < 0) |
40 | 1308 gftp_disconnect (request); |
1309 } | |
292 | 1310 |
40 | 1311 return (0); |
1312 } | |
1313 | |
1314 | |
1315 static int | |
1 | 1316 rfc959_list_files (gftp_request * request) |
1317 { | |
325 | 1318 int ret; |
1319 intptr_t show_hidden_files, resolve_symlinks, passive_transfer; | |
1 | 1320 char *tempstr, parms[3]; |
1321 | |
84 | 1322 g_return_val_if_fail (request != NULL, GFTP_EFATAL); |
1323 g_return_val_if_fail (request->protonum == GFTP_FTP_NUM, GFTP_EFATAL); | |
169 | 1324 g_return_val_if_fail (request->datafd > 0, GFTP_EFATAL); |
1 | 1325 |
1326 if ((ret = rfc959_data_connection_new (request)) < 0) | |
1327 return (ret); | |
1328 | |
122 | 1329 gftp_lookup_request_option (request, "show_hidden_files", &show_hidden_files); |
1330 gftp_lookup_request_option (request, "resolve_symlinks", &resolve_symlinks); | |
1331 gftp_lookup_request_option (request, "passive_transfer", &passive_transfer); | |
1332 | |
1 | 1333 *parms = '\0'; |
1334 strcat (parms, show_hidden_files ? "a" : ""); | |
1335 strcat (parms, resolve_symlinks ? "L" : ""); | |
1336 tempstr = g_strconcat ("LIST", *parms != '\0' ? " -" : "", parms, "\r\n", | |
1337 NULL); | |
1338 | |
292 | 1339 ret = rfc959_send_command (request, tempstr, 1); |
1 | 1340 g_free (tempstr); |
1341 | |
1342 if (ret != '1') | |
84 | 1343 return (GFTP_ERETRYABLE); |
1 | 1344 |
1345 ret = 0; | |
122 | 1346 if (!passive_transfer) |
1 | 1347 ret = rfc959_accept_active_connection (request); |
1348 | |
1349 return (ret); | |
1350 } | |
1351 | |
1352 | |
122 | 1353 static ssize_t |
1354 rfc959_get_next_file_chunk (gftp_request * request, char *buf, size_t size) | |
1355 { | |
301 | 1356 ssize_t num_read, ret; |
169 | 1357 rfc959_parms * parms; |
299 | 1358 int i, j; |
122 | 1359 |
169 | 1360 parms = request->protocol_data; |
299 | 1361 |
390 | 1362 num_read = parms->data_conn_read (request, buf, size, parms->data_connection); |
122 | 1363 if (num_read < 0) |
1364 return (num_read); | |
1365 | |
301 | 1366 ret = num_read; |
299 | 1367 if (parms->is_ascii_transfer) |
122 | 1368 { |
1369 for (i = 0, j = 0; i < num_read; i++) | |
1370 { | |
1371 if (buf[i] != '\r') | |
1372 buf[j++] = buf[i]; | |
1373 else | |
301 | 1374 ret--; |
122 | 1375 } |
1376 } | |
1377 | |
301 | 1378 return (ret); |
122 | 1379 } |
1380 | |
1381 | |
1382 static ssize_t | |
1383 rfc959_put_next_file_chunk (gftp_request * request, char *buf, size_t size) | |
1384 { | |
169 | 1385 rfc959_parms * parms; |
122 | 1386 ssize_t num_wrote; |
1387 char *tempstr; | |
1388 size_t rsize; | |
299 | 1389 int i, j; |
122 | 1390 |
1391 if (size == 0) | |
1392 return (0); | |
1393 | |
169 | 1394 parms = request->protocol_data; |
1395 | |
299 | 1396 if (parms->is_ascii_transfer) |
122 | 1397 { |
1398 rsize = 0; | |
1399 for (i = 0; i < size; i++) | |
1400 { | |
1401 rsize++; | |
1402 if (i > 0 && buf[i] == '\n' && buf[i - 1] != '\r') | |
1403 rsize++; | |
1404 } | |
1405 | |
1406 if (rsize != size) | |
1407 { | |
1408 tempstr = g_malloc (rsize); | |
1409 | |
1410 for (i = 0, j = 0; i < size; i++) | |
1411 { | |
1412 if (i > 0 && buf[i] == '\n' && buf[i - 1] != '\r') | |
1413 tempstr[j++] = '\r'; | |
1414 tempstr[j++] = buf[i]; | |
1415 } | |
1416 } | |
1417 else | |
1418 tempstr = buf; | |
1419 } | |
1420 else | |
1421 { | |
1422 rsize = size; | |
1423 tempstr = buf; | |
1424 } | |
1425 | |
390 | 1426 num_wrote = parms->data_conn_write (request, tempstr, rsize, |
1427 parms->data_connection); | |
122 | 1428 |
1429 if (tempstr != buf) | |
1430 g_free (tempstr); | |
1431 | |
1432 return (num_wrote); | |
1433 } | |
1434 | |
1435 | |
1 | 1436 int |
58 | 1437 rfc959_get_next_file (gftp_request * request, gftp_file * fle, int fd) |
1 | 1438 { |
389 | 1439 ssize_t (*oldread_func) (gftp_request * request, void *ptr, size_t size, |
1440 int fd); | |
58 | 1441 rfc959_parms * parms; |
249 | 1442 char tempstr[1024]; |
58 | 1443 ssize_t len; |
1 | 1444 |
84 | 1445 g_return_val_if_fail (request != NULL, GFTP_EFATAL); |
1446 g_return_val_if_fail (request->protonum == GFTP_FTP_NUM, GFTP_EFATAL); | |
1447 g_return_val_if_fail (fle != NULL, GFTP_EFATAL); | |
1448 g_return_val_if_fail (fd > 0, GFTP_EFATAL); | |
1 | 1449 |
1450 if (request->last_dir_entry) | |
1451 { | |
1452 g_free (request->last_dir_entry); | |
1453 request->last_dir_entry = NULL; | |
1454 } | |
58 | 1455 |
1456 parms = request->protocol_data; | |
1457 | |
169 | 1458 if (fd == request->datafd) |
1459 fd = parms->data_connection; | |
1460 | |
1 | 1461 do |
1462 { | |
389 | 1463 oldread_func = request->read_function; |
390 | 1464 request->read_function = parms->data_conn_read; |
389 | 1465 len = gftp_get_line (request, &parms->dataconn_rbuf, tempstr, |
1466 sizeof (tempstr), fd); | |
1467 request->read_function = oldread_func; | |
1468 | |
1469 if (len <= 0) | |
1 | 1470 { |
1471 gftp_file_destroy (fle); | |
58 | 1472 return ((int) len); |
1 | 1473 } |
1474 | |
91 | 1475 if (gftp_parse_ls (request, tempstr, fle) != 0) |
1 | 1476 { |
58 | 1477 if (strncmp (tempstr, "total", strlen ("total")) != 0 && |
1478 strncmp (tempstr, _("total"), strlen (_("total"))) != 0) | |
186 | 1479 request->logging_function (gftp_logging_error, request, |
1 | 1480 _("Warning: Cannot parse listing %s\n"), |
1481 tempstr); | |
1482 gftp_file_destroy (fle); | |
1483 continue; | |
1484 } | |
1485 else | |
1486 break; | |
1487 } | |
1488 while (1); | |
1489 | |
1490 len = strlen (tempstr); | |
1491 if (!request->cached) | |
1492 { | |
60 | 1493 request->last_dir_entry = g_strdup_printf ("%s\n", tempstr); |
168 | 1494 request->last_dir_entry_len = strlen (tempstr) + 1; |
1 | 1495 } |
1496 return (len); | |
1497 } | |
1498 | |
1499 | |
1500 static off_t | |
1501 rfc959_get_file_size (gftp_request * request, const char *filename) | |
1502 { | |
1503 char *tempstr; | |
1504 int ret; | |
1505 | |
1506 g_return_val_if_fail (request != NULL, 0); | |
84 | 1507 g_return_val_if_fail (request->protonum == GFTP_FTP_NUM, GFTP_EFATAL); |
1 | 1508 g_return_val_if_fail (filename != NULL, 0); |
169 | 1509 g_return_val_if_fail (request->datafd > 0, 0); |
1 | 1510 |
1511 tempstr = g_strconcat ("SIZE ", filename, "\r\n", NULL); | |
292 | 1512 ret = rfc959_send_command (request, tempstr, 1); |
1 | 1513 g_free (tempstr); |
1514 if (ret < 0) | |
84 | 1515 return (ret); |
1 | 1516 |
1517 if (*request->last_ftp_response != '2') | |
1518 return (0); | |
1519 return (strtol (request->last_ftp_response + 4, NULL, 10)); | |
1520 } | |
1521 | |
1522 | |
1523 static int | |
1524 rfc959_rmdir (gftp_request * request, const char *directory) | |
1525 { | |
1526 char *tempstr, ret; | |
1527 | |
84 | 1528 g_return_val_if_fail (request != NULL, GFTP_EFATAL); |
1529 g_return_val_if_fail (request->protonum == GFTP_FTP_NUM, GFTP_EFATAL); | |
1530 g_return_val_if_fail (directory != NULL, GFTP_EFATAL); | |
169 | 1531 g_return_val_if_fail (request->datafd > 0, GFTP_EFATAL); |
1 | 1532 |
1533 tempstr = g_strconcat ("RMD ", directory, "\r\n", NULL); | |
292 | 1534 ret = rfc959_send_command (request, tempstr, 1); |
1 | 1535 g_free (tempstr); |
84 | 1536 |
1537 if (ret < 0) | |
1538 return (ret); | |
1539 else if (ret == '2') | |
1540 return (0); | |
1541 else | |
1542 return (GFTP_ERETRYABLE); | |
1 | 1543 } |
1544 | |
1545 | |
1546 static int | |
1547 rfc959_rmfile (gftp_request * request, const char *file) | |
1548 { | |
1549 char *tempstr, ret; | |
1550 | |
84 | 1551 g_return_val_if_fail (request != NULL, GFTP_EFATAL); |
1552 g_return_val_if_fail (request->protonum == GFTP_FTP_NUM, GFTP_EFATAL); | |
1553 g_return_val_if_fail (file != NULL, GFTP_EFATAL); | |
169 | 1554 g_return_val_if_fail (request->datafd > 0, GFTP_EFATAL); |
1 | 1555 |
1556 tempstr = g_strconcat ("DELE ", file, "\r\n", NULL); | |
292 | 1557 ret = rfc959_send_command (request, tempstr, 1); |
1 | 1558 g_free (tempstr); |
84 | 1559 |
1560 if (ret < 0) | |
1561 return (ret); | |
1562 else if (ret == '2') | |
1563 return (0); | |
1564 else | |
1565 return (GFTP_ERETRYABLE); | |
1 | 1566 } |
1567 | |
1568 | |
1569 static int | |
1570 rfc959_mkdir (gftp_request * request, const char *directory) | |
1571 { | |
1572 char *tempstr, ret; | |
1573 | |
84 | 1574 g_return_val_if_fail (request != NULL, GFTP_EFATAL); |
1575 g_return_val_if_fail (request->protonum == GFTP_FTP_NUM, GFTP_EFATAL); | |
1576 g_return_val_if_fail (directory != NULL, GFTP_EFATAL); | |
169 | 1577 g_return_val_if_fail (request->datafd > 0, GFTP_EFATAL); |
1 | 1578 |
1579 tempstr = g_strconcat ("MKD ", directory, "\r\n", NULL); | |
292 | 1580 ret = rfc959_send_command (request, tempstr, 1); |
1 | 1581 g_free (tempstr); |
84 | 1582 |
1583 if (ret < 0) | |
1584 return (ret); | |
1585 else if (ret == '2') | |
1586 return (0); | |
1587 else | |
1588 return (GFTP_ERETRYABLE); | |
1 | 1589 } |
1590 | |
1591 | |
1592 static int | |
1593 rfc959_rename (gftp_request * request, const char *oldname, | |
1594 const char *newname) | |
1595 { | |
1596 char *tempstr, ret; | |
1597 | |
84 | 1598 g_return_val_if_fail (request != NULL, GFTP_EFATAL); |
1599 g_return_val_if_fail (request->protonum == GFTP_FTP_NUM, GFTP_EFATAL); | |
1600 g_return_val_if_fail (oldname != NULL, GFTP_EFATAL); | |
1601 g_return_val_if_fail (newname != NULL, GFTP_EFATAL); | |
169 | 1602 g_return_val_if_fail (request->datafd > 0, GFTP_EFATAL); |
1 | 1603 |
1604 tempstr = g_strconcat ("RNFR ", oldname, "\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); | |
278 | 1610 else if (ret != '3') |
84 | 1611 return (GFTP_ERETRYABLE); |
1 | 1612 |
1613 tempstr = g_strconcat ("RNTO ", newname, "\r\n", NULL); | |
292 | 1614 ret = rfc959_send_command (request, tempstr, 1); |
1 | 1615 g_free (tempstr); |
84 | 1616 |
1617 if (ret < 0) | |
1618 return (ret); | |
1619 else if (ret == '2') | |
1620 return (0); | |
1621 else | |
1622 return (GFTP_ERETRYABLE); | |
1 | 1623 } |
1624 | |
1625 | |
1626 static int | |
1627 rfc959_chmod (gftp_request * request, const char *file, int mode) | |
1628 { | |
1629 char *tempstr, ret; | |
1630 | |
84 | 1631 g_return_val_if_fail (request != NULL, GFTP_EFATAL); |
1632 g_return_val_if_fail (request->protonum == GFTP_FTP_NUM, GFTP_EFATAL); | |
1633 g_return_val_if_fail (file != NULL, GFTP_EFATAL); | |
169 | 1634 g_return_val_if_fail (request->datafd > 0, GFTP_EFATAL); |
1 | 1635 |
1636 tempstr = g_malloc (strlen (file) + (mode / 10) + 16); | |
1637 sprintf (tempstr, "SITE CHMOD %d %s\r\n", mode, file); | |
292 | 1638 ret = rfc959_send_command (request, tempstr, 1); |
1 | 1639 g_free (tempstr); |
84 | 1640 |
1641 if (ret < 0) | |
1642 return (ret); | |
1643 else if (ret == '2') | |
1644 return (0); | |
1645 else | |
1646 return (GFTP_ERETRYABLE); | |
1 | 1647 } |
1648 | |
1649 | |
1650 static int | |
1651 rfc959_site (gftp_request * request, const char *command) | |
1652 { | |
1653 char *tempstr, ret; | |
1654 | |
84 | 1655 g_return_val_if_fail (request != NULL, GFTP_EFATAL); |
1656 g_return_val_if_fail (request->protonum == GFTP_FTP_NUM, GFTP_EFATAL); | |
1657 g_return_val_if_fail (command != NULL, GFTP_EFATAL); | |
169 | 1658 g_return_val_if_fail (request->datafd > 0, GFTP_EFATAL); |
1 | 1659 |
1660 tempstr = g_strconcat ("SITE ", command, "\r\n", NULL); | |
292 | 1661 ret = rfc959_send_command (request, tempstr, 1); |
1 | 1662 g_free (tempstr); |
84 | 1663 |
1664 if (ret < 0) | |
1665 return (ret); | |
1666 else if (ret == '2') | |
1667 return (0); | |
1668 else | |
1669 return (GFTP_ERETRYABLE); | |
58 | 1670 } |
1671 | |
1672 | |
177 | 1673 static int |
58 | 1674 rfc959_set_config_options (gftp_request * request) |
1675 { | |
122 | 1676 char *proxy_config; |
177 | 1677 int ret; |
58 | 1678 |
122 | 1679 gftp_lookup_request_option (request, "proxy_config", &proxy_config); |
1680 if (strcmp (proxy_config, "http") == 0) | |
58 | 1681 { |
177 | 1682 if ((ret = gftp_protocols[GFTP_HTTP_NUM].init (request)) < 0) |
1683 return (ret); | |
173 | 1684 |
122 | 1685 gftp_set_request_option (request, "proxy_config", "ftp"); |
58 | 1686 } |
177 | 1687 |
1688 return (0); | |
122 | 1689 } |
58 | 1690 |
1691 | |
122 | 1692 void |
1693 rfc959_register_module (void) | |
1694 { | |
1695 gftp_register_config_vars (config_vars); | |
1 | 1696 } |
1697 | |
1698 | |
201 | 1699 void |
1700 rfc959_request_destroy (gftp_request * request) | |
1701 { | |
1702 rfc959_parms * parms; | |
1703 | |
1704 parms = request->protocol_data; | |
1705 | |
1706 if (parms->datafd_rbuf != NULL) | |
1707 gftp_free_getline_buffer (&parms->datafd_rbuf); | |
1708 | |
1709 if (parms->dataconn_rbuf != NULL) | |
1710 gftp_free_getline_buffer (&parms->dataconn_rbuf); | |
1711 } | |
1712 | |
1713 | |
309 | 1714 void |
1715 rfc959_copy_param_options (gftp_request * dest_request, | |
1716 gftp_request * src_request) | |
1717 { | |
1718 rfc959_parms * dparms, * sparms; | |
1719 | |
1720 dparms = dest_request->protocol_data; | |
1721 sparms = src_request->protocol_data; | |
1722 | |
1723 dparms->is_ascii_transfer = sparms->is_ascii_transfer; | |
1724 } | |
1725 | |
1726 | |
173 | 1727 int |
48 | 1728 rfc959_init (gftp_request * request) |
1 | 1729 { |
169 | 1730 rfc959_parms * parms; |
227 | 1731 struct hostent *hent; |
1732 struct utsname unme; | |
1733 struct passwd *pw; | |
1734 char *tempstr; | |
169 | 1735 |
173 | 1736 g_return_val_if_fail (request != NULL, GFTP_EFATAL); |
1 | 1737 |
227 | 1738 gftp_lookup_global_option ("email", &tempstr); |
1739 if (tempstr == NULL || *tempstr == '\0') | |
1740 { | |
1741 /* If there is no email address specified, then we'll just use the | |
1742 currentuser@currenthost */ | |
1743 uname (&unme); | |
1744 pw = getpwuid (geteuid ()); | |
1745 hent = gethostbyname (unme.nodename); | |
1746 if (strchr (unme.nodename, '.') == NULL && hent != NULL) | |
1747 tempstr = g_strconcat (pw->pw_name, "@", hent->h_name, NULL); | |
1748 else | |
1749 tempstr = g_strconcat (pw->pw_name, "@", unme.nodename, NULL); | |
1750 gftp_set_global_option ("email", tempstr); | |
1751 g_free (tempstr); | |
1752 } | |
1753 | |
48 | 1754 request->protonum = GFTP_FTP_NUM; |
1755 request->init = rfc959_init; | |
309 | 1756 request->copy_param_options = rfc959_copy_param_options; |
201 | 1757 request->destroy = rfc959_request_destroy; |
168 | 1758 request->read_function = gftp_fd_read; |
1759 request->write_function = gftp_fd_write; | |
48 | 1760 request->connect = rfc959_connect; |
168 | 1761 request->post_connect = NULL; |
48 | 1762 request->disconnect = rfc959_disconnect; |
1763 request->get_file = rfc959_get_file; | |
1764 request->put_file = rfc959_put_file; | |
1765 request->transfer_file = rfc959_transfer_file; | |
122 | 1766 request->get_next_file_chunk = rfc959_get_next_file_chunk; |
1767 request->put_next_file_chunk = rfc959_put_next_file_chunk; | |
48 | 1768 request->end_transfer = rfc959_end_transfer; |
1769 request->abort_transfer = rfc959_abort_transfer; | |
1770 request->list_files = rfc959_list_files; | |
1771 request->get_next_file = rfc959_get_next_file; | |
1772 request->get_file_size = rfc959_get_file_size; | |
1773 request->chdir = rfc959_chdir; | |
1774 request->rmdir = rfc959_rmdir; | |
1775 request->rmfile = rfc959_rmfile; | |
1776 request->mkdir = rfc959_mkdir; | |
1777 request->rename = rfc959_rename; | |
1778 request->chmod = rfc959_chmod; | |
1779 request->set_file_time = NULL; | |
1780 request->site = rfc959_site; | |
1781 request->parse_url = NULL; | |
63 | 1782 request->swap_socks = NULL; |
58 | 1783 request->set_config_options = rfc959_set_config_options; |
48 | 1784 request->url_prefix = "ftp"; |
1785 request->need_hostport = 1; | |
1786 request->need_userpass = 1; | |
1787 request->use_cache = 1; | |
1788 request->always_connected = 0; | |
169 | 1789 |
58 | 1790 request->protocol_data = g_malloc0 (sizeof (rfc959_parms)); |
169 | 1791 parms = request->protocol_data; |
1792 parms->data_connection = -1; | |
389 | 1793 parms->auth_tls_start = NULL; |
390 | 1794 parms->data_conn_read = gftp_fd_read; |
1795 parms->data_conn_write = gftp_fd_write; | |
169 | 1796 |
177 | 1797 return (gftp_set_config_options (request)); |
1 | 1798 } |
1799 |