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