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