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