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