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