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