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