341
|
1 /*****************************************************************************/
|
|
2 /* gftpui.c - UI related functions for gFTP */
|
|
3 /* Copyright (C) 1998-2003 Brian Masney <masneyb@gftp.org> */
|
|
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 "gftpui.h"
|
|
21 static const char cvsid[] = "$Id$";
|
|
22
|
|
23 sigjmp_buf gftpui_common_jmp_environment;
|
|
24 volatile int gftpui_common_use_jmp_environment = 0;
|
|
25
|
367
|
26 GStaticMutex gftpui_common_transfer_mutex = G_STATIC_MUTEX_INIT;
|
374
|
27 volatile sig_atomic_t gftpui_common_child_process_done = 0;
|
|
28 gftp_logging_func gftpui_common_logfunc;
|
341
|
29
|
|
30
|
|
31 static void *
|
|
32 _gftpui_common_thread_callback (void * data)
|
|
33 {
|
367
|
34 intptr_t network_timeout, sleep_time;
|
341
|
35 gftpui_callback_data * cdata;
|
|
36 int success, sj;
|
|
37
|
|
38 cdata = data;
|
|
39 gftp_lookup_request_option (cdata->request, "network_timeout",
|
|
40 &network_timeout);
|
367
|
41 gftp_lookup_request_option (cdata->request, "sleep_time",
|
|
42 &sleep_time);
|
341
|
43
|
|
44 sj = sigsetjmp (gftpui_common_jmp_environment, 1);
|
|
45 gftpui_common_use_jmp_environment = 1;
|
|
46
|
367
|
47 success = GFTP_ERETRYABLE;
|
341
|
48 if (sj == 0)
|
|
49 {
|
367
|
50 while (1)
|
|
51 {
|
|
52 if (network_timeout > 0)
|
|
53 alarm (network_timeout);
|
|
54 success = cdata->run_function (cdata);
|
|
55 alarm (0);
|
341
|
56
|
367
|
57 if (success == GFTP_EFATAL || success == 0 || cdata->retries == 0)
|
|
58 break;
|
341
|
59
|
367
|
60 cdata->request->logging_function (gftp_logging_misc, cdata->request,
|
|
61 _("Waiting %d seconds until trying to connect again\n"),
|
|
62 sleep_time);
|
|
63 alarm (sleep_time);
|
|
64 pause ();
|
|
65 cdata->retries--;
|
|
66 }
|
341
|
67 }
|
|
68 else
|
|
69 {
|
|
70 gftp_disconnect (cdata->request);
|
|
71 cdata->request->logging_function (gftp_logging_error, cdata->request,
|
|
72 _("Operation canceled\n"));
|
|
73 }
|
|
74
|
|
75 gftpui_common_use_jmp_environment = 0;
|
|
76 cdata->request->stopable = 0;
|
|
77
|
|
78 return (GINT_TO_POINTER (success));
|
|
79 }
|
|
80
|
|
81
|
|
82 int
|
|
83 gftpui_common_run_callback_function (gftpui_callback_data * cdata)
|
|
84 {
|
|
85 int ret;
|
|
86
|
|
87 if (gftpui_check_reconnect (cdata) < 0)
|
|
88 return (0);
|
|
89
|
|
90 if (gftp_protocols[cdata->request->protonum].use_threads)
|
|
91 ret = GPOINTER_TO_INT (gftpui_generic_thread (_gftpui_common_thread_callback, cdata));
|
|
92 else
|
|
93 ret = GPOINTER_TO_INT (cdata->run_function (cdata));
|
|
94
|
367
|
95 if (ret == 0 && cdata->run_function != gftpui_common_run_ls)
|
341
|
96 gftpui_refresh (cdata->uidata);
|
|
97
|
367
|
98 return (ret == 0);
|
341
|
99 }
|
|
100
|
|
101
|
374
|
102 static RETSIGTYPE
|
341
|
103 gftpui_common_signal_handler (int signo)
|
|
104 {
|
|
105 signal (signo, gftpui_common_signal_handler);
|
|
106
|
|
107 if (gftpui_common_use_jmp_environment)
|
|
108 siglongjmp (gftpui_common_jmp_environment, signo == SIGINT ? 1 : 2);
|
|
109 else if (signo == SIGINT)
|
|
110 exit (1);
|
|
111 }
|
|
112
|
|
113
|
374
|
114 static RETSIGTYPE
|
|
115 gftpui_common_sig_child (int signo)
|
|
116 {
|
|
117 gftpui_common_child_process_done = 1;
|
|
118 }
|
|
119
|
|
120
|
|
121 void
|
|
122 gftpui_common_init (int *argc, char ***argv, gftp_logging_func logfunc)
|
|
123 {
|
|
124 gftp_locale_init ();
|
|
125
|
|
126 signal (SIGCHLD, gftpui_common_sig_child);
|
|
127 signal (SIGPIPE, SIG_IGN);
|
|
128 signal (SIGALRM, gftpui_common_signal_handler);
|
|
129 signal (SIGINT, gftpui_common_signal_handler);
|
|
130
|
|
131 gftp_read_config_file (SHARE_DIR);
|
|
132 if (gftp_parse_command_line (argc, argv) != 0)
|
|
133 exit (0);
|
|
134
|
|
135 gftpui_common_logfunc = logfunc;
|
|
136 }
|
|
137
|
|
138
|
341
|
139 void
|
|
140 gftpui_common_about (gftp_logging_func logging_function, gpointer logdata)
|
|
141 {
|
|
142 char *str;
|
|
143
|
|
144 logging_function (gftp_logging_misc, logdata, "%s, Copyright (C) 1998-2003 Brian Masney <", gftp_version);
|
|
145 logging_function (gftp_logging_recv, logdata, "masneyb@gftp.org");
|
|
146 logging_function (gftp_logging_misc, logdata, _(">. If you have any questions, comments, or suggestions about this program, please feel free to email them to me. You can always find out the latest news about gFTP from my website at http://www.gftp.org/\n"));
|
|
147 logging_function (gftp_logging_misc, logdata, _("gFTP comes with ABSOLUTELY NO WARRANTY; for details, see the COPYING file. This is free software, and you are welcome to redistribute it under certain conditions; for details, see the COPYING file\n"));
|
|
148
|
|
149 str = _("Translated by");
|
|
150 if (strcmp (str, "Translated by") != 0)
|
|
151 logging_function (gftp_logging_misc, logdata, "%s\n", str);
|
|
152 }
|
|
153
|
|
154
|
|
155 static int
|
374
|
156 gftpui_common_cmd_about (void *uidata, gftp_request * request,
|
|
157 const char *command)
|
341
|
158 {
|
374
|
159 gftpui_common_about (gftpui_common_logfunc, NULL);
|
341
|
160 return (1);
|
|
161 }
|
|
162
|
|
163
|
|
164 static int
|
374
|
165 gftpui_common_cmd_ascii (void *uidata, gftp_request * request,
|
|
166 const char *command)
|
341
|
167 {
|
350
|
168 gftp_set_global_option ("ascii_transfers", GINT_TO_POINTER(1));
|
341
|
169 return (1);
|
|
170 }
|
|
171
|
|
172
|
|
173 static int
|
374
|
174 gftpui_common_cmd_binary (void *uidata, gftp_request * request,
|
|
175 const char *command)
|
341
|
176 {
|
350
|
177 gftp_set_global_option ("ascii_transfers", GINT_TO_POINTER(0));
|
341
|
178 return (1);
|
|
179 }
|
|
180
|
|
181
|
|
182 static int
|
374
|
183 gftpui_common_cmd_chmod (void *uidata, gftp_request * request,
|
|
184 const char *command)
|
341
|
185 {
|
350
|
186 gftpui_callback_data * cdata;
|
341
|
187 char *pos;
|
|
188
|
|
189 if (!GFTP_IS_CONNECTED (request))
|
|
190 {
|
|
191 request->logging_function (gftp_logging_error, request,
|
|
192 _("Error: Not connected to a remote site\n"));
|
|
193
|
|
194 return (1);
|
|
195 }
|
|
196
|
|
197 if ((pos = strchr (command, ' ')) != NULL)
|
|
198 *pos++ = '\0';
|
|
199
|
|
200 if (*command == '\0' || pos == NULL || *pos == '\0')
|
|
201 {
|
|
202 request->logging_function (gftp_logging_error, request,
|
|
203 _("usage: chmod <mode> <file>\n"));
|
|
204 }
|
|
205 else
|
|
206 {
|
350
|
207 cdata = g_malloc0 (sizeof (*cdata));
|
|
208 cdata->request = request;
|
|
209 cdata->uidata = uidata;
|
374
|
210 cdata->input_string = (char *) command;
|
350
|
211 cdata->source_string = pos;
|
|
212 cdata->run_function = gftpui_common_run_chmod;
|
|
213
|
|
214 gftpui_common_run_callback_function (cdata);
|
|
215
|
|
216 g_free (cdata);
|
341
|
217 }
|
|
218
|
|
219 return (1);
|
|
220 }
|
|
221
|
|
222
|
|
223 static int
|
374
|
224 gftpui_common_cmd_rename (void *uidata, gftp_request * request,
|
|
225 const char *command)
|
341
|
226 {
|
350
|
227 gftpui_callback_data * cdata;
|
341
|
228 char *pos;
|
|
229
|
|
230 if (!GFTP_IS_CONNECTED (request))
|
|
231 {
|
|
232 request->logging_function (gftp_logging_error, request,
|
|
233 _("Error: Not connected to a remote site\n"));
|
|
234 return (1);
|
|
235 }
|
|
236
|
|
237 if ((pos = strchr (command, ' ')) != NULL)
|
|
238 *pos++ = '\0';
|
|
239
|
|
240 if (*command == '\0' || pos == NULL || *pos == '\0')
|
|
241 {
|
|
242 request->logging_function (gftp_logging_error, request,
|
|
243 _("usage: rename <old name> <new name>\n"));
|
|
244 }
|
|
245 else
|
|
246 {
|
350
|
247 cdata = g_malloc0 (sizeof (*cdata));
|
|
248 cdata->request = request;
|
|
249 cdata->uidata = uidata;
|
374
|
250 cdata->source_string = (char *) command;
|
350
|
251 cdata->input_string = pos;
|
|
252 cdata->run_function = gftpui_common_run_rename;
|
|
253
|
|
254 gftpui_common_run_callback_function (cdata);
|
|
255
|
|
256 g_free (cdata);
|
341
|
257 }
|
|
258
|
|
259 return (1);
|
|
260 }
|
|
261
|
|
262
|
|
263 static int
|
374
|
264 gftpui_common_cmd_delete (void *uidata, gftp_request * request,
|
|
265 const char *command)
|
341
|
266 {
|
350
|
267 gftpui_callback_data * cdata;
|
|
268
|
341
|
269 if (!GFTP_IS_CONNECTED (request))
|
|
270 {
|
|
271 request->logging_function (gftp_logging_error, request,
|
|
272 _("Error: Not connected to a remote site\n"));
|
|
273 return (1);
|
|
274 }
|
|
275 else if (*command == '\0')
|
|
276 {
|
|
277 request->logging_function (gftp_logging_error, request,
|
|
278 _("usage: delete <file>\n"));
|
|
279 }
|
|
280 else
|
|
281 {
|
350
|
282 cdata = g_malloc0 (sizeof (*cdata));
|
|
283 cdata->request = request;
|
|
284 cdata->uidata = uidata;
|
374
|
285 cdata->input_string = (char *) command;
|
350
|
286 cdata->run_function = gftpui_common_run_delete;
|
|
287
|
|
288 gftpui_common_run_callback_function (cdata);
|
|
289
|
|
290 g_free (cdata);
|
341
|
291 }
|
|
292
|
|
293 return (1);
|
|
294 }
|
|
295
|
|
296
|
|
297 static int
|
374
|
298 gftpui_common_cmd_rmdir (void *uidata, gftp_request * request,
|
|
299 const char *command)
|
341
|
300 {
|
350
|
301 gftpui_callback_data * cdata;
|
|
302
|
341
|
303 if (!GFTP_IS_CONNECTED (request))
|
|
304 {
|
|
305 request->logging_function (gftp_logging_error, request,
|
|
306 _("Error: Not connected to a remote site\n"));
|
|
307 return (1);
|
|
308 }
|
|
309 else if (*command == '\0')
|
|
310 {
|
|
311 request->logging_function (gftp_logging_error, request,
|
|
312 _("usage: rmdir <directory>\n"));
|
|
313 }
|
|
314 else
|
|
315 {
|
350
|
316 cdata = g_malloc0 (sizeof (*cdata));
|
|
317 cdata->request = request;
|
|
318 cdata->uidata = uidata;
|
374
|
319 cdata->input_string = (char *) command;
|
350
|
320 cdata->run_function = gftpui_common_run_rmdir;
|
|
321
|
|
322 gftpui_common_run_callback_function (cdata);
|
|
323
|
|
324 g_free (cdata);
|
|
325 }
|
|
326
|
|
327 return (1);
|
|
328 }
|
|
329
|
|
330
|
|
331 static int
|
374
|
332 gftpui_common_cmd_site (void *uidata, gftp_request * request,
|
|
333 const char *command)
|
350
|
334 {
|
|
335 gftpui_callback_data * cdata;
|
|
336
|
|
337 if (!GFTP_IS_CONNECTED (request))
|
|
338 {
|
|
339 request->logging_function (gftp_logging_error, request,
|
|
340 _("Error: Not connected to a remote site\n"));
|
|
341 return (1);
|
|
342 }
|
|
343 else if (*command == '\0')
|
|
344 {
|
|
345 request->logging_function (gftp_logging_error, request,
|
|
346 _("usage: site <site command>\n"));
|
|
347 }
|
|
348 else
|
|
349 {
|
|
350 cdata = g_malloc0 (sizeof (*cdata));
|
|
351 cdata->request = request;
|
|
352 cdata->uidata = uidata;
|
374
|
353 cdata->input_string = (char *) command;
|
350
|
354 cdata->run_function = gftpui_common_run_site;
|
|
355
|
|
356 gftpui_common_run_callback_function (cdata);
|
|
357
|
|
358 g_free (cdata);
|
341
|
359 }
|
|
360
|
|
361 return (1);
|
|
362 }
|
|
363
|
|
364
|
|
365 static int
|
374
|
366 gftpui_common_cmd_mkdir (void *uidata, gftp_request * request,
|
|
367 const char *command)
|
341
|
368 {
|
|
369 gftpui_callback_data * cdata;
|
|
370
|
|
371 if (!GFTP_IS_CONNECTED (request))
|
|
372 {
|
|
373 request->logging_function (gftp_logging_error, request,
|
|
374 _("Error: Not connected to a remote site\n"));
|
|
375 return (1);
|
|
376 }
|
|
377 else if (*command == '\0')
|
|
378 {
|
|
379 request->logging_function (gftp_logging_error, request,
|
|
380 _("usage: mkdir <new directory>\n"));
|
|
381 }
|
|
382 else
|
|
383 {
|
|
384 cdata = g_malloc0 (sizeof (*cdata));
|
|
385 cdata->request = request;
|
|
386 cdata->uidata = uidata;
|
374
|
387 cdata->input_string = (char *) command;
|
341
|
388 cdata->run_function = gftpui_common_run_mkdir;
|
|
389
|
|
390 gftpui_common_run_callback_function (cdata);
|
|
391
|
|
392 g_free (cdata);
|
|
393 }
|
|
394
|
|
395 return (1);
|
|
396 }
|
|
397
|
|
398
|
|
399 static int
|
374
|
400 gftpui_common_cmd_chdir (void *uidata, gftp_request * request,
|
|
401 const char *command)
|
341
|
402 {
|
350
|
403 gftpui_callback_data * cdata;
|
341
|
404 char *tempstr, *newdir = NULL;
|
|
405
|
|
406 if (!GFTP_IS_CONNECTED (request))
|
|
407 {
|
|
408 request->logging_function (gftp_logging_error, request,
|
|
409 _("Error: Not connected to a remote site\n"));
|
|
410 return (1);
|
|
411 }
|
|
412 else if (*command == '\0')
|
|
413 {
|
|
414 request->logging_function (gftp_logging_error, request,
|
|
415 _("usage: chdir <directory>\n"));
|
|
416 return (1);
|
|
417 }
|
|
418 else if (request->protonum == GFTP_LOCAL_NUM)
|
|
419 {
|
|
420 if (*command != '/' && request->directory != NULL)
|
|
421 {
|
350
|
422 tempstr = gftp_build_path (request->directory, command, NULL);
|
341
|
423 newdir = expand_path (tempstr);
|
|
424 g_free (tempstr);
|
|
425 }
|
|
426 else
|
|
427 newdir = expand_path (command);
|
|
428
|
|
429 if (newdir == NULL)
|
|
430 {
|
|
431 request->logging_function (gftp_logging_error, request,
|
|
432 _("usage: chdir <directory>\n"));
|
|
433 return (1);
|
|
434 }
|
|
435 }
|
|
436
|
350
|
437 cdata = g_malloc0 (sizeof (*cdata));
|
|
438 cdata->request = request;
|
|
439 cdata->uidata = uidata;
|
374
|
440 cdata->input_string = newdir != NULL ? newdir : (char *) command;
|
350
|
441 cdata->run_function = gftpui_common_run_chdir;
|
|
442
|
|
443 gftpui_common_run_callback_function (cdata);
|
|
444
|
|
445 g_free (cdata);
|
341
|
446
|
|
447 if (newdir != NULL)
|
|
448 g_free (newdir);
|
|
449
|
|
450 return (1);
|
|
451 }
|
|
452
|
|
453
|
|
454 static int
|
374
|
455 gftpui_common_cmd_close (void *uidata, gftp_request * request,
|
|
456 const char *command)
|
341
|
457 {
|
|
458 gftp_disconnect (request);
|
|
459 return (1);
|
|
460 }
|
|
461
|
|
462
|
|
463 static int
|
374
|
464 gftpui_common_cmd_pwd (void *uidata, gftp_request * request,
|
|
465 const char *command)
|
341
|
466 {
|
|
467 if (!GFTP_IS_CONNECTED (request))
|
|
468 {
|
|
469 request->logging_function (gftp_logging_error, request,
|
|
470 _("Error: Not connected to a remote site\n"));
|
|
471 return (1);
|
|
472 }
|
|
473
|
|
474 request->logging_function (gftp_logging_misc, request,
|
|
475 "%s\n", request->directory);
|
|
476
|
|
477 return (1);
|
|
478 }
|
|
479
|
|
480
|
|
481 static int
|
374
|
482 gftpui_common_cmd_quit (void *uidata, gftp_request * request,
|
|
483 const char *command)
|
341
|
484 {
|
|
485 gftp_shutdown();
|
|
486
|
|
487 return (0);
|
|
488 }
|
|
489
|
|
490
|
|
491 static int
|
374
|
492 gftpui_common_cmd_clear (void *uidata, gftp_request * request,
|
|
493 const char *command)
|
341
|
494 {
|
|
495 if (strcasecmp (command, "cache") == 0)
|
|
496 gftp_clear_cache_files ();
|
|
497 else
|
|
498 {
|
374
|
499 gftpui_common_logfunc (gftp_logging_error, request,
|
|
500 _("Invalid argument\n"));
|
341
|
501 }
|
|
502
|
|
503 return (1);
|
|
504 }
|
|
505
|
|
506
|
|
507 static int
|
374
|
508 gftpui_common_clear_show_subhelp (const char *topic)
|
341
|
509 {
|
|
510 if (strcmp (topic, "cache") == 0)
|
|
511 {
|
374
|
512 gftpui_common_logfunc (gftp_logging_misc, NULL,
|
|
513 _("Clear the directory cache\n"));
|
341
|
514 return (1);
|
|
515 }
|
|
516
|
|
517 return (0);
|
|
518 }
|
|
519
|
|
520
|
|
521 static int
|
374
|
522 gftpui_common_set_show_subhelp (const char *topic)
|
341
|
523 {
|
|
524 gftp_config_vars * cv;
|
|
525
|
|
526 if ((cv = g_hash_table_lookup (gftp_global_options_htable, topic)) != NULL)
|
|
527 {
|
374
|
528 gftpui_common_logfunc (gftp_logging_misc, NULL, "%s\n", cv->comment);
|
341
|
529 return (1);
|
|
530 }
|
|
531
|
|
532 return (0);
|
|
533 }
|
|
534
|
|
535
|
355
|
536 static int
|
374
|
537 gftpui_common_cmd_ls (void *uidata, gftp_request * request,
|
|
538 const char *command)
|
341
|
539 {
|
355
|
540 char *startcolor, *endcolor, *tempstr;
|
|
541 gftpui_callback_data * cdata;
|
|
542 GList * templist;
|
341
|
543 gftp_file * fle;
|
|
544
|
|
545 if (!GFTP_IS_CONNECTED (request))
|
|
546 {
|
|
547 request->logging_function (gftp_logging_error, request,
|
|
548 _("Error: Not connected to a remote site\n"));
|
|
549 return (1);
|
|
550 }
|
|
551
|
355
|
552 cdata = g_malloc0 (sizeof (*cdata));
|
|
553 cdata->request = request;
|
|
554 cdata->uidata = uidata;
|
374
|
555 cdata->source_string = *command != '\0' ? (char *) command : NULL;
|
355
|
556 cdata->run_function = gftpui_common_run_ls;
|
341
|
557
|
355
|
558 gftpui_common_run_callback_function (cdata);
|
341
|
559
|
355
|
560 templist = cdata->files;
|
|
561 while (templist != NULL)
|
341
|
562 {
|
|
563 fle = templist->data;
|
|
564
|
|
565 gftpui_lookup_file_colors (fle, &startcolor, &endcolor);
|
|
566 tempstr = gftp_gen_ls_string (fle, startcolor, endcolor);
|
354
|
567 request->logging_function (gftp_logging_misc_nolog, request, "%s\n",
|
|
568 tempstr);
|
341
|
569 g_free (tempstr);
|
|
570
|
355
|
571 templist = templist->next;
|
|
572 gftp_file_destroy (fle);
|
|
573 g_free (fle);
|
341
|
574 }
|
|
575
|
|
576
|
355
|
577 if (cdata->files != NULL)
|
|
578 g_list_free (cdata->files);
|
|
579 g_free (cdata);
|
341
|
580
|
|
581 return (1);
|
|
582 }
|
|
583
|
|
584
|
367
|
585 int
|
374
|
586 gftpui_common_cmd_open (void *uidata, gftp_request * request,
|
|
587 const char *command)
|
356
|
588 {
|
367
|
589 gftpui_callback_data * cdata;
|
|
590 intptr_t retries;
|
356
|
591 char *tempstr;
|
|
592
|
|
593 if (GFTP_IS_CONNECTED (request))
|
|
594 {
|
|
595 gftp_disconnect (request); /* FIXME */
|
|
596 }
|
|
597
|
367
|
598 if (command != NULL)
|
356
|
599 {
|
367
|
600 if (*command == '\0')
|
|
601 {
|
|
602 request->logging_function (gftp_logging_error, request,
|
|
603 _("usage: open " GFTP_URL_USAGE "\n"));
|
|
604 return (1);
|
|
605 }
|
|
606
|
|
607 if (gftp_parse_url (request, command) < 0)
|
|
608 return (1);
|
356
|
609 }
|
|
610
|
|
611 if (request->need_userpass)
|
|
612 {
|
|
613 if (request->username == NULL || *request->username == '\0')
|
|
614 {
|
|
615 if ((tempstr = gftpui_prompt_username (uidata, request)) != NULL)
|
|
616 {
|
|
617 gftp_set_username (request, tempstr);
|
|
618 gftp_set_password (request, NULL);
|
|
619 g_free (tempstr);
|
|
620 }
|
|
621 }
|
|
622
|
|
623 if (request->username != NULL &&
|
|
624 strcmp (request->username, "anonymous") != 0 &&
|
|
625 (request->password == NULL || *request->password == '\0'))
|
|
626 {
|
|
627 if ((tempstr = gftpui_prompt_password (uidata, request)) != NULL)
|
|
628 {
|
|
629 gftp_set_password (request, tempstr);
|
|
630 g_free (tempstr);
|
|
631 }
|
|
632 }
|
|
633 }
|
|
634
|
367
|
635 gftp_lookup_request_option (request, "retries", &retries);
|
|
636
|
|
637 cdata = g_malloc0 (sizeof (*cdata));
|
|
638 cdata->request = request;
|
|
639 cdata->uidata = uidata;
|
|
640 cdata->run_function = gftpui_common_run_connect;
|
|
641 cdata->retries = retries;
|
|
642
|
|
643 gftpui_common_run_callback_function (cdata);
|
|
644
|
|
645 g_free (cdata);
|
356
|
646
|
|
647 return (1);
|
|
648 }
|
|
649
|
|
650
|
|
651 static int
|
374
|
652 gftpui_common_cmd_set (void *uidata, gftp_request * request,
|
|
653 const char *command)
|
341
|
654 {
|
|
655 gftp_config_vars * cv, newcv;
|
|
656 char *pos, *backpos;
|
|
657 GList * templist;
|
|
658 int i;
|
|
659
|
|
660 if (command == NULL || *command == '\0')
|
|
661 {
|
|
662 for (templist = gftp_options_list;
|
|
663 templist != NULL;
|
|
664 templist = templist->next)
|
|
665 {
|
|
666 cv = templist->data;
|
|
667
|
|
668 for (i=0; cv[i].key != NULL; i++)
|
|
669 {
|
|
670 if (!(cv[i].ports_shown & GFTP_PORT_TEXT))
|
|
671 continue;
|
|
672
|
|
673 if (*cv[i].key == '\0' ||
|
|
674 gftp_option_types[cv[i].otype].write_function == NULL)
|
|
675 continue;
|
|
676
|
|
677 printf ("%s = ", cv[i].key);
|
|
678 gftp_option_types[cv[i].otype].write_function (&cv[i], stdout, 0);
|
|
679 printf ("\n");
|
|
680 }
|
|
681 }
|
|
682 }
|
|
683 else
|
|
684 {
|
|
685 if ((pos = strchr (command, '=')) == NULL)
|
|
686 {
|
374
|
687 gftpui_common_logfunc (gftp_logging_error, request,
|
|
688 _("usage: set [variable = value]\n"));
|
341
|
689 return (1);
|
|
690 }
|
|
691 *pos = '\0';
|
|
692
|
|
693 for (backpos = pos - 1;
|
|
694 (*backpos == ' ' || *backpos == '\t') && backpos > command;
|
|
695 backpos--)
|
|
696 *backpos = '\0';
|
|
697 for (++pos; *pos == ' ' || *pos == '\t'; pos++);
|
|
698
|
|
699 if ((cv = g_hash_table_lookup (gftp_global_options_htable, command)) == NULL)
|
|
700 {
|
374
|
701 gftpui_common_logfunc (gftp_logging_error, request,
|
|
702 _("Error: Variable %s is not a valid configuration variable.\n"), command);
|
341
|
703 return (1);
|
|
704 }
|
|
705
|
|
706 if (!(cv->ports_shown & GFTP_PORT_TEXT))
|
|
707 {
|
374
|
708 gftpui_common_logfunc (gftp_logging_error, request,
|
|
709 _("Error: Variable %s is not available in the text port of gFTP\n"), command);
|
341
|
710 return (1);
|
|
711 }
|
|
712
|
|
713 if (gftp_option_types[cv->otype].read_function != NULL)
|
|
714 {
|
|
715 memcpy (&newcv, cv, sizeof (newcv));
|
|
716 newcv.flags &= ~GFTP_CVARS_FLAGS_DYNMEM;
|
|
717
|
|
718 gftp_option_types[cv->otype].read_function (pos, &newcv, 1);
|
|
719
|
|
720 gftp_set_global_option (command, newcv.value);
|
|
721
|
|
722 if (newcv.flags & GFTP_CVARS_FLAGS_DYNMEM)
|
|
723 g_free (newcv.value);
|
|
724 }
|
|
725 }
|
|
726
|
|
727 return (1);
|
|
728 }
|
|
729
|
|
730
|
|
731 static int
|
374
|
732 gftpui_common_cmd_help (void *uidata, gftp_request * request,
|
|
733 const char *command)
|
341
|
734 {
|
374
|
735 int i, j, ele, numrows, numcols = 6, handled, number_commands, cmdlen,
|
|
736 found;
|
|
737 const char *pos;
|
341
|
738
|
|
739 for (number_commands=0;
|
|
740 gftpui_common_commands[number_commands].command != NULL;
|
|
741 number_commands++);
|
|
742
|
|
743 if (command != NULL && *command != '\0')
|
|
744 {
|
|
745 for (pos = command; *pos != ' ' && *pos != '\0'; pos++);
|
374
|
746 cmdlen = pos - command;
|
341
|
747
|
|
748 for (i=0; gftpui_common_commands[i].command != NULL; i++)
|
|
749 {
|
374
|
750 if (strncmp (gftpui_common_commands[i].command, command, cmdlen) == 0)
|
341
|
751 break;
|
|
752 }
|
|
753
|
|
754 if (gftpui_common_commands[i].cmd_description != NULL)
|
|
755 {
|
374
|
756 found = 1;
|
|
757
|
|
758 if (*pos != '\0' && *(pos + 1) != '\0' &&
|
|
759 gftpui_common_commands[i].subhelp_func != NULL)
|
|
760 handled = gftpui_common_commands[i].subhelp_func (pos + 1);
|
341
|
761 else
|
|
762 handled = 0;
|
|
763
|
|
764 if (!handled)
|
|
765 printf ("%s\n", _(gftpui_common_commands[i].cmd_description));
|
|
766 }
|
|
767 else
|
374
|
768 found = 0;
|
341
|
769 }
|
374
|
770 else
|
|
771 found = 0;
|
341
|
772
|
374
|
773 if (!found)
|
341
|
774 {
|
|
775 numrows = number_commands / numcols;
|
|
776 if (number_commands % numcols != 0)
|
|
777 numrows++;
|
|
778
|
|
779 printf (_("Supported commands:\n\n"));
|
|
780 for (i=0; i<numrows; i++)
|
|
781 {
|
|
782 printf (" ");
|
|
783 for (j=0; j<numcols; j++)
|
|
784 {
|
|
785 ele = i + j * numrows;
|
|
786 if (ele >= number_commands)
|
|
787 break;
|
|
788 printf ("%-10s", gftpui_common_commands[ele].command);
|
|
789 }
|
|
790 printf ("\n");
|
|
791 }
|
|
792
|
|
793 printf ("\n");
|
|
794 }
|
|
795 return (1);
|
|
796 }
|
|
797
|
|
798
|
|
799 gftpui_common_methods gftpui_common_commands[] = {
|
|
800 {N_("about"), 2, gftpui_common_cmd_about, gftpui_common_request_none,
|
|
801 N_("Shows gFTP information"), NULL},
|
|
802 {N_("ascii"), 2, gftpui_common_cmd_ascii, gftpui_common_request_remote,
|
|
803 N_("Sets the current file transfer mode to Ascii (only for FTP)"), NULL},
|
|
804 {N_("binary"), 1, gftpui_common_cmd_binary, gftpui_common_request_remote,
|
|
805 N_("Sets the current file transfer mode to Binary (only for FTP)"), NULL},
|
|
806 {N_("cd"), 2, gftpui_common_cmd_chdir, gftpui_common_request_remote,
|
|
807 N_("Changes the remote working directory"), NULL},
|
|
808 {N_("chdir"), 3, gftpui_common_cmd_chdir, gftpui_common_request_remote,
|
|
809 N_("Changes the remote working directory"), NULL},
|
|
810 {N_("chmod"), 3, gftpui_common_cmd_chmod, gftpui_common_request_remote,
|
|
811 N_("Changes the permissions of a remote file"), NULL},
|
|
812 {N_("clear"), 3, gftpui_common_cmd_clear, gftpui_common_request_none,
|
|
813 N_("Available options: cache"), gftpui_common_clear_show_subhelp},
|
|
814 {N_("close"), 3, gftpui_common_cmd_close, gftpui_common_request_remote,
|
|
815 N_("Disconnects from the remote site"), NULL},
|
350
|
816 {N_("delete"), 1, gftpui_common_cmd_delete, gftpui_common_request_remote,
|
341
|
817 N_("Removes a remote file"), NULL},
|
|
818 /* FIXME
|
|
819 {N_("get"), 1, gftp_text_mget_file, gftpui_common_request_none,
|
|
820 N_("Downloads remote file(s)"), NULL},
|
|
821 */
|
|
822 {N_("help"), 1, gftpui_common_cmd_help, gftpui_common_request_none,
|
|
823 N_("Shows this help screen"), NULL},
|
|
824 {N_("lcd"), 3, gftpui_common_cmd_chdir, gftpui_common_request_local,
|
|
825 N_("Changes the local working directory"), NULL},
|
|
826 {N_("lchdir"), 4, gftpui_common_cmd_chdir, gftpui_common_request_local,
|
|
827 N_("Changes the local working directory"), NULL},
|
|
828 {N_("lchmod"), 4, gftpui_common_cmd_chmod, gftpui_common_request_local,
|
|
829 N_("Changes the permissions of a local file"), NULL},
|
|
830 {N_("ldelete"), 2, gftpui_common_cmd_delete, gftpui_common_request_local,
|
|
831 N_("Removes a local file"), NULL},
|
|
832 {N_("lls"), 2, gftpui_common_cmd_ls, gftpui_common_request_local,
|
|
833 N_("Shows the directory listing for the current local directory"), NULL},
|
|
834 {N_("lmkdir"), 2, gftpui_common_cmd_mkdir, gftpui_common_request_local,
|
|
835 N_("Creates a local directory"), NULL},
|
|
836 {N_("lpwd"), 2, gftpui_common_cmd_pwd, gftpui_common_request_local,
|
|
837 N_("Show current local directory"), NULL},
|
|
838 {N_("lrename"), 3, gftpui_common_cmd_rename, gftpui_common_request_local,
|
|
839 N_("Rename a local file"), NULL},
|
|
840 {N_("lrmdir"), 3, gftpui_common_cmd_rmdir, gftpui_common_request_local,
|
|
841 N_("Remove a local directory"), NULL},
|
|
842 {N_("ls"), 2, gftpui_common_cmd_ls, gftpui_common_request_remote,
|
|
843 N_("Shows the directory listing for the current remote directory"), NULL},
|
|
844 /* FIXME
|
|
845 {N_("mget"), 2, gftp_text_mget_file, gftpui_common_request_none,
|
|
846 N_("Downloads remote file(s)"), NULL},
|
|
847 */
|
|
848 {N_("mkdir"), 2, gftpui_common_cmd_mkdir, gftpui_common_request_remote,
|
|
849 N_("Creates a remote directory"), NULL},
|
|
850 /* FIXME
|
|
851 {N_("mput"), 2, gftp_text_mput_file, gftpui_common_request_none,
|
|
852 N_("Uploads local file(s)"), NULL},
|
356
|
853 */
|
|
854 {N_("open"), 1, gftpui_common_cmd_open, gftpui_common_request_remote,
|
341
|
855 N_("Opens a connection to a remote site"), NULL},
|
356
|
856 /* FIXME
|
341
|
857 {N_("put"), 2, gftp_text_mput_file, gftpui_common_request_none,
|
|
858 N_("Uploads local file(s)"), NULL},
|
|
859 */
|
|
860 {N_("pwd"), 2, gftpui_common_cmd_pwd, gftpui_common_request_remote,
|
|
861 N_("Show current remote directory"), NULL},
|
|
862 {N_("quit"), 1, gftpui_common_cmd_quit, gftpui_common_request_none,
|
|
863 N_("Exit from gFTP"), NULL},
|
|
864 {N_("rename"), 2, gftpui_common_cmd_rename, gftpui_common_request_remote,
|
|
865 N_("Rename a remote file"), NULL},
|
|
866 {N_("rmdir"), 2, gftpui_common_cmd_rmdir, gftpui_common_request_remote,
|
|
867 N_("Remove a remote directory"), NULL},
|
|
868 {N_("set"), 1, gftpui_common_cmd_set, gftpui_common_request_none,
|
|
869 N_("Show configuration file variables. You can also set variables by set var=val"), gftpui_common_set_show_subhelp},
|
350
|
870 {N_("site"), 2, gftpui_common_cmd_site, gftpui_common_request_remote,
|
|
871 N_("Run a site specific command"), NULL},
|
341
|
872 {NULL, 0, NULL, gftpui_common_request_none,
|
|
873 NULL, NULL}};
|
|
874
|
|
875
|
|
876 int
|
374
|
877 gftpui_common_process_command (void *locui, gftp_request * locreq,
|
|
878 void *remui, gftp_request * remreq,
|
|
879 const char *command)
|
341
|
880 {
|
374
|
881 gftp_request * request;
|
341
|
882 const char *stpos;
|
|
883 char *pos, *newstr;
|
|
884 size_t cmdlen;
|
|
885 void *uidata;
|
|
886 int ret, i;
|
|
887 size_t len;
|
|
888
|
|
889 for (stpos = command; *stpos == ' ' || *stpos == '\t'; stpos++);
|
|
890
|
|
891 newstr = g_strdup (stpos);
|
|
892 len = strlen (newstr);
|
|
893
|
|
894 if (len > 0 && newstr[len - 1] == '\n')
|
|
895 newstr[--len] = '\0';
|
|
896 if (len > 0 && newstr[len - 1] == '\r')
|
|
897 newstr[--len] = '\0';
|
|
898
|
|
899 for (pos = newstr + len - 1;
|
|
900 (*pos == ' ' || *pos == '\t') && pos > newstr;
|
|
901 pos--)
|
|
902 *pos = '\0';
|
|
903
|
|
904 if (*stpos == '\0')
|
|
905 {
|
|
906 g_free (newstr);
|
|
907 return (1);
|
|
908 }
|
|
909
|
|
910 if ((pos = strchr (newstr, ' ')) != NULL)
|
|
911 *pos = '\0';
|
|
912
|
|
913 cmdlen = strlen (newstr);
|
|
914 for (i=0; gftpui_common_commands[i].command != NULL; i++)
|
|
915 {
|
|
916 if (strcmp (gftpui_common_commands[i].command, newstr) == 0)
|
|
917 break;
|
|
918 else if (cmdlen >= gftpui_common_commands[i].minlen &&
|
|
919 strncmp (gftpui_common_commands[i].command, newstr, cmdlen) == 0)
|
|
920 break;
|
|
921 }
|
|
922
|
|
923 if (pos != NULL)
|
|
924 pos++;
|
|
925 else
|
|
926 pos = "";
|
|
927
|
374
|
928 if (gftpui_common_commands[i].reqtype == gftpui_common_request_local)
|
|
929 {
|
|
930 request = locreq;
|
|
931 uidata = locui;
|
|
932 }
|
|
933 else if (gftpui_common_commands[i].reqtype == gftpui_common_request_remote)
|
|
934 {
|
|
935 request = remreq;
|
|
936 uidata = remui;
|
|
937 }
|
|
938 else
|
|
939 {
|
|
940 request = NULL;
|
|
941 uidata = NULL;
|
|
942 }
|
|
943
|
341
|
944 if (gftpui_common_commands[i].command != NULL)
|
|
945 {
|
|
946 ret = gftpui_common_commands[i].func (uidata, request, pos);
|
|
947 }
|
|
948 else
|
|
949 {
|
374
|
950 gftpui_common_logfunc (gftp_logging_error, request,
|
|
951 _("Error: Command not recognized\n"));
|
341
|
952 ret = 1;
|
|
953 }
|
|
954
|
|
955 g_free (newstr);
|
|
956 return (ret);
|
|
957 }
|
|
958
|
367
|
959
|
|
960 gftp_transfer *
|
|
961 gftpui_common_add_file_transfer (gftp_request * fromreq, gftp_request * toreq,
|
|
962 void *fromuidata, void *touidata,
|
|
963 GList * files)
|
|
964 {
|
|
965 intptr_t append_transfers, one_transfer;
|
|
966 GList * templist, *curfle;
|
|
967 gftp_transfer * tdata;
|
|
968 gftp_file * tempfle;
|
|
969 int show_dialog;
|
|
970 char *pos;
|
|
971
|
|
972 for (templist = files; templist != NULL; templist = templist->next)
|
|
973 {
|
|
974 tempfle = templist->data;
|
|
975 if (tempfle->startsize > 0)
|
|
976 break;
|
|
977 }
|
|
978 show_dialog = templist != NULL;
|
|
979
|
|
980 gftp_lookup_request_option (fromreq, "append_transfers",
|
|
981 &append_transfers);
|
|
982 gftp_lookup_request_option (fromreq, "one_transfer",
|
|
983 &one_transfer);
|
|
984
|
|
985 tdata = NULL;
|
|
986 if (append_transfers && one_transfer && !show_dialog)
|
|
987 {
|
|
988 if (g_thread_supported ())
|
|
989 g_static_mutex_lock (&gftpui_common_transfer_mutex);
|
|
990
|
|
991 for (templist = gftp_file_transfers;
|
|
992 templist != NULL;
|
|
993 templist = templist->next)
|
|
994 {
|
|
995 tdata = templist->data;
|
|
996
|
|
997 if (g_thread_supported ())
|
|
998 g_static_mutex_lock (&tdata->structmutex);
|
|
999
|
|
1000 if (!compare_request (tdata->fromreq, fromreq, 0) ||
|
|
1001 !compare_request (tdata->toreq, toreq, 0) ||
|
|
1002 tdata->curfle == NULL)
|
|
1003 {
|
|
1004 if (g_thread_supported ())
|
|
1005 g_static_mutex_unlock (&tdata->structmutex);
|
|
1006
|
|
1007 continue;
|
|
1008 }
|
|
1009
|
|
1010 tdata->files = g_list_concat (tdata->files, files);
|
|
1011
|
|
1012 for (curfle = files; curfle != NULL; curfle = curfle->next)
|
|
1013 {
|
|
1014 tempfle = curfle->data;
|
|
1015
|
|
1016 if (tempfle->isdir)
|
|
1017 tdata->numdirs++;
|
|
1018 else
|
|
1019 tdata->numfiles++;
|
|
1020
|
|
1021 if (tempfle->transfer_action != GFTP_TRANS_ACTION_SKIP)
|
|
1022 tdata->total_bytes += tempfle->size;
|
|
1023
|
|
1024 if ((pos = strrchr (tempfle->file, '/')) == NULL)
|
|
1025 pos = tempfle->file;
|
|
1026 else
|
|
1027 pos++;
|
|
1028
|
|
1029 gftpui_add_file_to_transfer (tdata, curfle, pos);
|
|
1030 }
|
|
1031
|
|
1032 if (g_thread_supported ())
|
|
1033 g_static_mutex_unlock (&tdata->structmutex);
|
|
1034
|
|
1035 break;
|
|
1036 }
|
|
1037
|
|
1038 if (g_thread_supported ())
|
|
1039 g_static_mutex_unlock (&gftpui_common_transfer_mutex);
|
|
1040 }
|
|
1041 else
|
|
1042 templist = NULL;
|
|
1043
|
|
1044 if (templist == NULL)
|
|
1045 {
|
|
1046 tdata = gftp_tdata_new ();
|
368
|
1047 tdata->fromreq = gftp_copy_request (fromreq);
|
|
1048 tdata->toreq = gftp_copy_request (toreq);
|
367
|
1049
|
|
1050 tdata->fromwdata = fromuidata;
|
|
1051 tdata->towdata = touidata;
|
|
1052
|
|
1053 if (!show_dialog)
|
|
1054 tdata->show = tdata->ready = 1;
|
|
1055
|
|
1056 tdata->files = files;
|
|
1057 for (curfle = files; curfle != NULL; curfle = curfle->next)
|
|
1058 {
|
|
1059 tempfle = curfle->data;
|
|
1060 if (tempfle->isdir)
|
|
1061 tdata->numdirs++;
|
|
1062 else
|
|
1063 tdata->numfiles++;
|
|
1064
|
|
1065 if (tempfle->transfer_action != GFTP_TRANS_ACTION_SKIP)
|
|
1066 tdata->total_bytes += tempfle->size;
|
|
1067 }
|
|
1068
|
|
1069 if (g_thread_supported ())
|
|
1070 g_static_mutex_lock (&gftpui_common_transfer_mutex);
|
|
1071
|
|
1072 gftp_file_transfers = g_list_append (gftp_file_transfers, tdata);
|
|
1073
|
|
1074 if (g_thread_supported ())
|
|
1075 g_static_mutex_unlock (&gftpui_common_transfer_mutex);
|
|
1076
|
|
1077 if (show_dialog)
|
|
1078 gftpui_ask_transfer (tdata);
|
|
1079 }
|
|
1080
|
|
1081 return (tdata);
|
|
1082 }
|
|
1083
|
|
1084
|
|
1085 static void
|
|
1086 _gftpui_common_setup_fds (gftp_transfer * tdata, gftp_file * curfle,
|
|
1087 int *fromfd, int *tofd)
|
|
1088 {
|
|
1089 *tofd = -1;
|
|
1090 *fromfd = -1;
|
|
1091
|
|
1092 if (curfle->is_fd)
|
|
1093 {
|
|
1094 if (tdata->toreq->protonum == GFTP_LOCAL_NUM)
|
|
1095 *tofd = curfle->fd;
|
|
1096 else if (tdata->fromreq->protonum == GFTP_LOCAL_NUM)
|
|
1097 *fromfd = curfle->fd;
|
|
1098 }
|
|
1099 }
|
|
1100
|
|
1101
|
|
1102 static void
|
|
1103 _gftpui_common_done_with_fds (gftp_transfer * tdata, gftp_file * curfle)
|
|
1104 {
|
|
1105 if (curfle->is_fd)
|
|
1106 {
|
|
1107 if (tdata->toreq->protonum == GFTP_LOCAL_NUM)
|
|
1108 tdata->toreq->datafd = -1;
|
|
1109 else
|
|
1110 tdata->fromreq->datafd = -1;
|
|
1111 }
|
|
1112 }
|
|
1113
|
|
1114
|
|
1115 int
|
|
1116 gftpui_common_transfer_files (gftp_transfer * tdata)
|
|
1117 {
|
|
1118 int i, mode, tofd, fromfd;
|
|
1119 intptr_t preserve_permissions;
|
|
1120 char buf[8192];
|
|
1121 off_t fromsize, total;
|
|
1122 gftp_file * curfle;
|
|
1123 ssize_t num_read, ret;
|
|
1124
|
|
1125 tdata->curfle = tdata->files;
|
|
1126 gettimeofday (&tdata->starttime, NULL);
|
|
1127 memcpy (&tdata->lasttime, &tdata->starttime,
|
|
1128 sizeof (tdata->lasttime));
|
|
1129
|
|
1130 gftp_lookup_request_option (tdata->fromreq, "preserve_permissions",
|
|
1131 &preserve_permissions);
|
|
1132
|
|
1133 while (tdata->curfle != NULL)
|
|
1134 {
|
|
1135 num_read = -1;
|
|
1136
|
|
1137 if (g_thread_supported ())
|
|
1138 g_static_mutex_lock (&tdata->structmutex);
|
|
1139
|
|
1140 curfle = tdata->curfle->data;
|
|
1141 tdata->current_file_number++;
|
|
1142
|
|
1143 if (g_thread_supported ())
|
|
1144 g_static_mutex_unlock (&tdata->structmutex);
|
|
1145
|
|
1146 if (curfle->transfer_action == GFTP_TRANS_ACTION_SKIP)
|
|
1147 {
|
|
1148 if (g_thread_supported ())
|
|
1149 g_static_mutex_lock (&tdata->structmutex);
|
|
1150
|
|
1151 tdata->next_file = 1;
|
|
1152 tdata->curfle = tdata->curfle->next;
|
|
1153
|
|
1154 if (g_thread_supported ())
|
|
1155 g_static_mutex_unlock (&tdata->structmutex);
|
|
1156 continue;
|
|
1157 }
|
|
1158
|
|
1159 fromsize = -1;
|
|
1160 if (gftp_connect (tdata->fromreq) == 0 &&
|
|
1161 gftp_connect (tdata->toreq) == 0)
|
|
1162 {
|
|
1163 if (curfle->isdir)
|
|
1164 {
|
|
1165 if (tdata->toreq->mkdir != NULL)
|
|
1166 {
|
|
1167 tdata->toreq->mkdir (tdata->toreq, curfle->destfile);
|
|
1168 if (!GFTP_IS_CONNECTED (tdata->toreq))
|
|
1169 break;
|
|
1170 }
|
|
1171
|
|
1172 if (g_thread_supported ())
|
|
1173 g_static_mutex_lock (&tdata->structmutex);
|
|
1174
|
|
1175 tdata->next_file = 1;
|
|
1176 tdata->curfle = tdata->curfle->next;
|
|
1177
|
|
1178 if (g_thread_supported ())
|
|
1179 g_static_mutex_unlock (&tdata->structmutex);
|
|
1180 continue;
|
|
1181 }
|
|
1182
|
|
1183 _gftpui_common_setup_fds (tdata, curfle, &fromfd, &tofd);
|
|
1184
|
|
1185 if (curfle->size == 0)
|
|
1186 {
|
|
1187 curfle->size = gftp_get_file_size (tdata->fromreq, curfle->file);
|
|
1188 tdata->total_bytes += curfle->size;
|
|
1189 }
|
|
1190
|
|
1191 if (GFTP_IS_CONNECTED (tdata->fromreq) &&
|
|
1192 GFTP_IS_CONNECTED (tdata->toreq))
|
|
1193 {
|
|
1194 fromsize = gftp_transfer_file (tdata->fromreq, curfle->file,
|
|
1195 fromfd,
|
|
1196 curfle->transfer_action == GFTP_TRANS_ACTION_RESUME ?
|
|
1197 curfle->startsize : 0,
|
|
1198 tdata->toreq, curfle->destfile, tofd,
|
|
1199 curfle->transfer_action == GFTP_TRANS_ACTION_RESUME ?
|
|
1200 curfle->startsize : 0);
|
|
1201 }
|
|
1202 }
|
|
1203
|
|
1204 if (!GFTP_IS_CONNECTED (tdata->fromreq) ||
|
|
1205 !GFTP_IS_CONNECTED (tdata->toreq))
|
|
1206 {
|
|
1207 tdata->fromreq->logging_function (gftp_logging_misc,
|
|
1208 tdata->fromreq,
|
|
1209 _("Error: Remote site disconnected after trying to tdata file\n"));
|
|
1210 }
|
|
1211 else if (fromsize < 0)
|
|
1212 {
|
|
1213 if (g_thread_supported ())
|
|
1214 g_static_mutex_lock (&tdata->structmutex);
|
|
1215
|
|
1216 curfle->transfer_action = GFTP_TRANS_ACTION_SKIP;
|
|
1217 tdata->next_file = 1;
|
|
1218 tdata->curfle = tdata->curfle->next;
|
|
1219
|
|
1220 if (g_thread_supported ())
|
|
1221 g_static_mutex_unlock (&tdata->structmutex);
|
|
1222 continue;
|
|
1223 }
|
|
1224 else
|
|
1225 {
|
|
1226 if (g_thread_supported ())
|
|
1227 g_static_mutex_lock (&tdata->structmutex);
|
|
1228
|
|
1229 tdata->curtrans = 0;
|
|
1230 tdata->curresumed = curfle->transfer_action == GFTP_TRANS_ACTION_RESUME ? curfle->startsize : 0;
|
|
1231 tdata->resumed_bytes += tdata->curresumed;
|
|
1232
|
|
1233 if (g_thread_supported ())
|
|
1234 g_static_mutex_unlock (&tdata->structmutex);
|
|
1235
|
|
1236 total = 0;
|
|
1237 i = 0;
|
|
1238 while (!tdata->cancel &&
|
|
1239 (num_read = gftp_get_next_file_chunk (tdata->fromreq,
|
|
1240 buf, sizeof (buf))) > 0)
|
|
1241 {
|
|
1242 total += num_read;
|
|
1243 gftp_calc_kbs (tdata, num_read);
|
|
1244
|
|
1245 if ((ret = gftp_put_next_file_chunk (tdata->toreq, buf,
|
|
1246 num_read)) < 0)
|
|
1247 {
|
|
1248 num_read = (int) ret;
|
|
1249 break;
|
|
1250 }
|
|
1251 }
|
|
1252 }
|
|
1253
|
|
1254 if (tdata->cancel)
|
|
1255 {
|
|
1256 if (gftp_abort_transfer (tdata->fromreq) != 0)
|
|
1257 gftp_disconnect (tdata->fromreq);
|
|
1258
|
|
1259 if (gftp_abort_transfer (tdata->toreq) != 0)
|
|
1260 gftp_disconnect (tdata->toreq);
|
|
1261 }
|
|
1262 else if (num_read < 0)
|
|
1263 {
|
|
1264 tdata->fromreq->logging_function (gftp_logging_misc,
|
|
1265 tdata->fromreq,
|
|
1266 _("Could not download %s from %s\n"),
|
|
1267 curfle->file,
|
|
1268 tdata->fromreq->hostname);
|
|
1269
|
|
1270 if (gftp_get_transfer_status (tdata, num_read) == GFTP_ERETRYABLE)
|
|
1271 continue;
|
|
1272
|
|
1273 break;
|
|
1274 }
|
|
1275 else
|
|
1276 {
|
|
1277 _gftpui_common_done_with_fds (tdata, curfle);
|
|
1278 if (gftp_end_transfer (tdata->fromreq) != 0)
|
|
1279 {
|
|
1280 if (gftp_get_transfer_status (tdata, -1) == GFTP_ERETRYABLE)
|
|
1281 continue;
|
|
1282
|
|
1283 break;
|
|
1284 }
|
|
1285 gftp_end_transfer (tdata->toreq);
|
|
1286
|
|
1287 tdata->fromreq->logging_function (gftp_logging_misc,
|
|
1288 tdata->fromreq,
|
|
1289 _("Successfully tdatared %s at %.2f KB/s\n"),
|
|
1290 curfle->file, tdata->kbs);
|
|
1291 }
|
|
1292
|
|
1293 if (!curfle->is_fd && preserve_permissions)
|
|
1294 {
|
|
1295 if (curfle->attribs)
|
|
1296 {
|
|
1297 mode = gftp_parse_attribs (curfle->attribs);
|
|
1298 if (mode != 0)
|
|
1299 gftp_chmod (tdata->toreq, curfle->destfile, mode);
|
|
1300 }
|
|
1301
|
|
1302 if (curfle->datetime != 0)
|
|
1303 gftp_set_file_time (tdata->toreq, curfle->destfile,
|
|
1304 curfle->datetime);
|
|
1305 }
|
|
1306
|
|
1307 if (g_thread_supported ())
|
|
1308 g_static_mutex_lock (&tdata->structmutex);
|
|
1309
|
|
1310 tdata->curtrans = 0;
|
|
1311 tdata->next_file = 1;
|
|
1312 curfle->transfer_done = 1;
|
|
1313 tdata->curfle = tdata->curfle->next;
|
|
1314
|
|
1315 if (g_thread_supported ())
|
|
1316 g_static_mutex_unlock (&tdata->structmutex);
|
|
1317
|
|
1318 if (tdata->cancel && !tdata->skip_file)
|
|
1319 break;
|
|
1320 tdata->cancel = 0;
|
|
1321 tdata->fromreq->cancel = 0;
|
|
1322 tdata->toreq->cancel = 0;
|
|
1323 }
|
|
1324 tdata->done = 1;
|
|
1325
|
|
1326 return (1); /* FIXME */
|
|
1327 }
|
|
1328
|