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