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