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
|
367
|
23 GStaticMutex gftpui_common_transfer_mutex = G_STATIC_MUTEX_INIT;
|
374
|
24 volatile sig_atomic_t gftpui_common_child_process_done = 0;
|
873
|
25 volatile sig_atomic_t gftpui_common_num_child_threads = 0;
|
518
|
26 static gftp_logging_func gftpui_common_logfunc;
|
341
|
27
|
|
28 static void *
|
|
29 _gftpui_common_thread_callback (void * data)
|
|
30 {
|
367
|
31 intptr_t network_timeout, sleep_time;
|
341
|
32 gftpui_callback_data * cdata;
|
783
|
33 struct timespec ts;
|
873
|
34 int success;
|
341
|
35
|
|
36 cdata = data;
|
873
|
37 gftpui_common_num_child_threads++;
|
|
38
|
341
|
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
|
367
|
44 success = GFTP_ERETRYABLE;
|
873
|
45 while (1)
|
341
|
46 {
|
873
|
47 if (network_timeout > 0)
|
|
48 alarm (network_timeout);
|
341
|
49
|
873
|
50 success = cdata->run_function (cdata);
|
|
51 alarm (0);
|
341
|
52
|
873
|
53 if (cdata->request->cancel)
|
|
54 {
|
677
|
55 cdata->request->logging_function (gftp_logging_error, cdata->request,
|
873
|
56 _("Operation canceled\n"));
|
|
57 break;
|
|
58 }
|
|
59
|
|
60 if (success == GFTP_EFATAL || success == 0 || cdata->retries == 0)
|
|
61 break;
|
783
|
62
|
873
|
63 cdata->retries--;
|
341
|
64 cdata->request->logging_function (gftp_logging_error, cdata->request,
|
873
|
65 _("Waiting %d seconds until trying to connect again\n"),
|
|
66 sleep_time);
|
|
67
|
|
68 ts.tv_sec = sleep_time;
|
|
69 ts.tv_nsec = 0;
|
|
70 nanosleep (&ts, NULL);
|
341
|
71 }
|
|
72
|
|
73 cdata->request->stopable = 0;
|
873
|
74 gftpui_common_num_child_threads--;
|
341
|
75
|
|
76 return (GINT_TO_POINTER (success));
|
|
77 }
|
|
78
|
|
79
|
|
80 int
|
|
81 gftpui_common_run_callback_function (gftpui_callback_data * cdata)
|
|
82 {
|
|
83 int ret;
|
|
84
|
451
|
85 if (!cdata->dont_check_connection && gftpui_check_reconnect (cdata) < 0)
|
341
|
86 return (0);
|
|
87
|
|
88 if (gftp_protocols[cdata->request->protonum].use_threads)
|
|
89 ret = GPOINTER_TO_INT (gftpui_generic_thread (_gftpui_common_thread_callback, cdata));
|
|
90 else
|
|
91 ret = GPOINTER_TO_INT (cdata->run_function (cdata));
|
|
92
|
511
|
93 if (ret == 0 && !cdata->dont_refresh)
|
514
|
94 gftpui_refresh (cdata->uidata, !cdata->dont_clear_cache);
|
341
|
95
|
367
|
96 return (ret == 0);
|
341
|
97 }
|
|
98
|
|
99
|
374
|
100 static RETSIGTYPE
|
341
|
101 gftpui_common_signal_handler (int signo)
|
|
102 {
|
|
103 signal (signo, gftpui_common_signal_handler);
|
|
104
|
873
|
105 if (!gftpui_common_num_child_threads && signo == SIGINT)
|
766
|
106 exit (EXIT_FAILURE);
|
341
|
107 }
|
|
108
|
|
109
|
374
|
110 static RETSIGTYPE
|
|
111 gftpui_common_sig_child (int signo)
|
|
112 {
|
498
|
113 int ret;
|
|
114
|
|
115 if (gftpui_common_child_process_done == -1)
|
|
116 {
|
|
117 /* Running from text port */
|
|
118 while (waitpid (-1, &ret, WNOHANG) > 0)
|
|
119 {
|
|
120 /* Nothing */
|
|
121 }
|
|
122 }
|
|
123 else
|
|
124 gftpui_common_child_process_done = 1;
|
374
|
125 }
|
|
126
|
|
127
|
|
128 void
|
|
129 gftpui_common_init (int *argc, char ***argv, gftp_logging_func logfunc)
|
|
130 {
|
483
|
131 char *share_dir;
|
|
132
|
374
|
133 gftp_locale_init ();
|
|
134
|
|
135 signal (SIGCHLD, gftpui_common_sig_child);
|
|
136 signal (SIGPIPE, SIG_IGN);
|
|
137 signal (SIGALRM, gftpui_common_signal_handler);
|
|
138 signal (SIGINT, gftpui_common_signal_handler);
|
|
139
|
483
|
140 share_dir = gftp_get_share_dir ();
|
|
141 gftp_read_config_file (share_dir);
|
374
|
142 if (gftp_parse_command_line (argc, argv) != 0)
|
766
|
143 exit (EXIT_FAILURE);
|
374
|
144
|
|
145 gftpui_common_logfunc = logfunc;
|
498
|
146 gftpui_common_child_process_done = -1;
|
374
|
147 }
|
|
148
|
|
149
|
341
|
150 void
|
|
151 gftpui_common_about (gftp_logging_func logging_function, gpointer logdata)
|
|
152 {
|
|
153 char *str;
|
|
154
|
|
155 logging_function (gftp_logging_misc, logdata, "%s, Copyright (C) 1998-2003 Brian Masney <", gftp_version);
|
|
156 logging_function (gftp_logging_recv, logdata, "masneyb@gftp.org");
|
|
157 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"));
|
|
158 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"));
|
|
159
|
|
160 str = _("Translated by");
|
|
161 if (strcmp (str, "Translated by") != 0)
|
|
162 logging_function (gftp_logging_misc, logdata, "%s\n", str);
|
|
163 }
|
|
164
|
|
165
|
|
166 static int
|
374
|
167 gftpui_common_cmd_about (void *uidata, gftp_request * request,
|
377
|
168 void *other_uidata, gftp_request * other_request,
|
374
|
169 const char *command)
|
341
|
170 {
|
374
|
171 gftpui_common_about (gftpui_common_logfunc, NULL);
|
341
|
172 return (1);
|
|
173 }
|
|
174
|
|
175
|
|
176 static int
|
374
|
177 gftpui_common_cmd_ascii (void *uidata, gftp_request * request,
|
377
|
178 void *other_uidata, gftp_request * other_request,
|
374
|
179 const char *command)
|
341
|
180 {
|
350
|
181 gftp_set_global_option ("ascii_transfers", GINT_TO_POINTER(1));
|
341
|
182 return (1);
|
|
183 }
|
|
184
|
|
185
|
|
186 static int
|
374
|
187 gftpui_common_cmd_binary (void *uidata, gftp_request * request,
|
377
|
188 void *other_uidata, gftp_request * other_request,
|
374
|
189 const char *command)
|
341
|
190 {
|
350
|
191 gftp_set_global_option ("ascii_transfers", GINT_TO_POINTER(0));
|
341
|
192 return (1);
|
|
193 }
|
|
194
|
|
195
|
|
196 static int
|
374
|
197 gftpui_common_cmd_chmod (void *uidata, gftp_request * request,
|
377
|
198 void *other_uidata, gftp_request * other_request,
|
374
|
199 const char *command)
|
341
|
200 {
|
350
|
201 gftpui_callback_data * cdata;
|
341
|
202 char *pos;
|
|
203
|
|
204 if (!GFTP_IS_CONNECTED (request))
|
|
205 {
|
|
206 request->logging_function (gftp_logging_error, request,
|
|
207 _("Error: Not connected to a remote site\n"));
|
|
208
|
|
209 return (1);
|
|
210 }
|
|
211
|
|
212 if ((pos = strchr (command, ' ')) != NULL)
|
|
213 *pos++ = '\0';
|
|
214
|
|
215 if (*command == '\0' || pos == NULL || *pos == '\0')
|
|
216 {
|
|
217 request->logging_function (gftp_logging_error, request,
|
|
218 _("usage: chmod <mode> <file>\n"));
|
|
219 }
|
|
220 else
|
|
221 {
|
350
|
222 cdata = g_malloc0 (sizeof (*cdata));
|
|
223 cdata->request = request;
|
|
224 cdata->uidata = uidata;
|
374
|
225 cdata->input_string = (char *) command;
|
350
|
226 cdata->source_string = pos;
|
|
227 cdata->run_function = gftpui_common_run_chmod;
|
|
228
|
|
229 gftpui_common_run_callback_function (cdata);
|
|
230
|
|
231 g_free (cdata);
|
341
|
232 }
|
|
233
|
|
234 return (1);
|
|
235 }
|
|
236
|
|
237
|
|
238 static int
|
374
|
239 gftpui_common_cmd_rename (void *uidata, gftp_request * request,
|
377
|
240 void *other_uidata, gftp_request * other_request,
|
|
241 const char *command)
|
341
|
242 {
|
350
|
243 gftpui_callback_data * cdata;
|
341
|
244 char *pos;
|
|
245
|
|
246 if (!GFTP_IS_CONNECTED (request))
|
|
247 {
|
|
248 request->logging_function (gftp_logging_error, request,
|
|
249 _("Error: Not connected to a remote site\n"));
|
|
250 return (1);
|
|
251 }
|
|
252
|
|
253 if ((pos = strchr (command, ' ')) != NULL)
|
|
254 *pos++ = '\0';
|
|
255
|
|
256 if (*command == '\0' || pos == NULL || *pos == '\0')
|
|
257 {
|
|
258 request->logging_function (gftp_logging_error, request,
|
|
259 _("usage: rename <old name> <new name>\n"));
|
|
260 }
|
|
261 else
|
|
262 {
|
350
|
263 cdata = g_malloc0 (sizeof (*cdata));
|
|
264 cdata->request = request;
|
|
265 cdata->uidata = uidata;
|
374
|
266 cdata->source_string = (char *) command;
|
350
|
267 cdata->input_string = pos;
|
|
268 cdata->run_function = gftpui_common_run_rename;
|
|
269
|
|
270 gftpui_common_run_callback_function (cdata);
|
|
271
|
|
272 g_free (cdata);
|
341
|
273 }
|
|
274
|
|
275 return (1);
|
|
276 }
|
|
277
|
|
278
|
|
279 static int
|
374
|
280 gftpui_common_cmd_delete (void *uidata, gftp_request * request,
|
377
|
281 void *other_uidata, gftp_request * other_request,
|
|
282 const char *command)
|
341
|
283 {
|
350
|
284 gftpui_callback_data * cdata;
|
|
285
|
341
|
286 if (!GFTP_IS_CONNECTED (request))
|
|
287 {
|
|
288 request->logging_function (gftp_logging_error, request,
|
|
289 _("Error: Not connected to a remote site\n"));
|
|
290 return (1);
|
|
291 }
|
|
292 else if (*command == '\0')
|
|
293 {
|
|
294 request->logging_function (gftp_logging_error, request,
|
|
295 _("usage: delete <file>\n"));
|
|
296 }
|
|
297 else
|
|
298 {
|
350
|
299 cdata = g_malloc0 (sizeof (*cdata));
|
|
300 cdata->request = request;
|
|
301 cdata->uidata = uidata;
|
374
|
302 cdata->input_string = (char *) command;
|
350
|
303 cdata->run_function = gftpui_common_run_delete;
|
|
304
|
|
305 gftpui_common_run_callback_function (cdata);
|
|
306
|
|
307 g_free (cdata);
|
341
|
308 }
|
|
309
|
|
310 return (1);
|
|
311 }
|
|
312
|
|
313
|
|
314 static int
|
374
|
315 gftpui_common_cmd_rmdir (void *uidata, gftp_request * request,
|
377
|
316 void *other_uidata, gftp_request * other_request,
|
374
|
317 const char *command)
|
341
|
318 {
|
350
|
319 gftpui_callback_data * cdata;
|
|
320
|
341
|
321 if (!GFTP_IS_CONNECTED (request))
|
|
322 {
|
|
323 request->logging_function (gftp_logging_error, request,
|
|
324 _("Error: Not connected to a remote site\n"));
|
|
325 return (1);
|
|
326 }
|
|
327 else if (*command == '\0')
|
|
328 {
|
|
329 request->logging_function (gftp_logging_error, request,
|
|
330 _("usage: rmdir <directory>\n"));
|
|
331 }
|
|
332 else
|
|
333 {
|
350
|
334 cdata = g_malloc0 (sizeof (*cdata));
|
|
335 cdata->request = request;
|
|
336 cdata->uidata = uidata;
|
374
|
337 cdata->input_string = (char *) command;
|
350
|
338 cdata->run_function = gftpui_common_run_rmdir;
|
|
339
|
|
340 gftpui_common_run_callback_function (cdata);
|
|
341
|
|
342 g_free (cdata);
|
|
343 }
|
|
344
|
|
345 return (1);
|
|
346 }
|
|
347
|
|
348
|
|
349 static int
|
374
|
350 gftpui_common_cmd_site (void *uidata, gftp_request * request,
|
377
|
351 void *other_uidata, gftp_request * other_request,
|
374
|
352 const char *command)
|
350
|
353 {
|
|
354 gftpui_callback_data * cdata;
|
|
355
|
|
356 if (!GFTP_IS_CONNECTED (request))
|
|
357 {
|
|
358 request->logging_function (gftp_logging_error, request,
|
|
359 _("Error: Not connected to a remote site\n"));
|
|
360 return (1);
|
|
361 }
|
|
362 else if (*command == '\0')
|
|
363 {
|
|
364 request->logging_function (gftp_logging_error, request,
|
|
365 _("usage: site <site command>\n"));
|
|
366 }
|
|
367 else
|
|
368 {
|
|
369 cdata = g_malloc0 (sizeof (*cdata));
|
|
370 cdata->request = request;
|
|
371 cdata->uidata = uidata;
|
374
|
372 cdata->input_string = (char *) command;
|
350
|
373 cdata->run_function = gftpui_common_run_site;
|
806
|
374 cdata->toggled = 1;
|
350
|
375
|
|
376 gftpui_common_run_callback_function (cdata);
|
|
377
|
|
378 g_free (cdata);
|
341
|
379 }
|
|
380
|
|
381 return (1);
|
|
382 }
|
|
383
|
|
384
|
|
385 static int
|
374
|
386 gftpui_common_cmd_mkdir (void *uidata, gftp_request * request,
|
377
|
387 void *other_uidata, gftp_request * other_request,
|
374
|
388 const char *command)
|
341
|
389 {
|
|
390 gftpui_callback_data * cdata;
|
|
391
|
|
392 if (!GFTP_IS_CONNECTED (request))
|
|
393 {
|
|
394 request->logging_function (gftp_logging_error, request,
|
|
395 _("Error: Not connected to a remote site\n"));
|
|
396 return (1);
|
|
397 }
|
|
398 else if (*command == '\0')
|
|
399 {
|
|
400 request->logging_function (gftp_logging_error, request,
|
|
401 _("usage: mkdir <new directory>\n"));
|
|
402 }
|
|
403 else
|
|
404 {
|
|
405 cdata = g_malloc0 (sizeof (*cdata));
|
|
406 cdata->request = request;
|
|
407 cdata->uidata = uidata;
|
374
|
408 cdata->input_string = (char *) command;
|
341
|
409 cdata->run_function = gftpui_common_run_mkdir;
|
|
410
|
|
411 gftpui_common_run_callback_function (cdata);
|
|
412
|
|
413 g_free (cdata);
|
|
414 }
|
|
415
|
|
416 return (1);
|
|
417 }
|
|
418
|
|
419
|
|
420 static int
|
374
|
421 gftpui_common_cmd_chdir (void *uidata, gftp_request * request,
|
377
|
422 void *other_uidata, gftp_request * other_request,
|
374
|
423 const char *command)
|
341
|
424 {
|
350
|
425 gftpui_callback_data * cdata;
|
341
|
426 char *tempstr, *newdir = NULL;
|
|
427
|
|
428 if (!GFTP_IS_CONNECTED (request))
|
|
429 {
|
|
430 request->logging_function (gftp_logging_error, request,
|
|
431 _("Error: Not connected to a remote site\n"));
|
|
432 return (1);
|
|
433 }
|
|
434 else if (*command == '\0')
|
|
435 {
|
|
436 request->logging_function (gftp_logging_error, request,
|
|
437 _("usage: chdir <directory>\n"));
|
|
438 return (1);
|
|
439 }
|
|
440 else if (request->protonum == GFTP_LOCAL_NUM)
|
|
441 {
|
|
442 if (*command != '/' && request->directory != NULL)
|
|
443 {
|
555
|
444 tempstr = gftp_build_path (request, request->directory, command,
|
|
445 NULL);
|
|
446 newdir = gftp_expand_path (request, tempstr);
|
341
|
447 g_free (tempstr);
|
|
448 }
|
|
449 else
|
555
|
450 newdir = gftp_expand_path (request, command);
|
341
|
451
|
|
452 if (newdir == NULL)
|
|
453 {
|
|
454 request->logging_function (gftp_logging_error, request,
|
|
455 _("usage: chdir <directory>\n"));
|
|
456 return (1);
|
|
457 }
|
|
458 }
|
|
459
|
350
|
460 cdata = g_malloc0 (sizeof (*cdata));
|
|
461 cdata->request = request;
|
|
462 cdata->uidata = uidata;
|
374
|
463 cdata->input_string = newdir != NULL ? newdir : (char *) command;
|
350
|
464 cdata->run_function = gftpui_common_run_chdir;
|
514
|
465 cdata->dont_clear_cache = 1;
|
350
|
466
|
|
467 gftpui_common_run_callback_function (cdata);
|
|
468
|
|
469 g_free (cdata);
|
341
|
470
|
|
471 if (newdir != NULL)
|
|
472 g_free (newdir);
|
|
473
|
|
474 return (1);
|
|
475 }
|
|
476
|
|
477
|
|
478 static int
|
374
|
479 gftpui_common_cmd_close (void *uidata, gftp_request * request,
|
377
|
480 void *other_uidata, gftp_request * other_request,
|
374
|
481 const char *command)
|
341
|
482 {
|
|
483 gftp_disconnect (request);
|
|
484 return (1);
|
|
485 }
|
|
486
|
|
487
|
|
488 static int
|
374
|
489 gftpui_common_cmd_pwd (void *uidata, gftp_request * request,
|
377
|
490 void *other_uidata, gftp_request * other_request,
|
374
|
491 const char *command)
|
341
|
492 {
|
|
493 if (!GFTP_IS_CONNECTED (request))
|
|
494 {
|
|
495 request->logging_function (gftp_logging_error, request,
|
|
496 _("Error: Not connected to a remote site\n"));
|
|
497 return (1);
|
|
498 }
|
|
499
|
|
500 request->logging_function (gftp_logging_misc, request,
|
|
501 "%s\n", request->directory);
|
|
502
|
|
503 return (1);
|
|
504 }
|
|
505
|
|
506
|
|
507 static int
|
374
|
508 gftpui_common_cmd_quit (void *uidata, gftp_request * request,
|
377
|
509 void *other_uidata, gftp_request * other_request,
|
374
|
510 const char *command)
|
341
|
511 {
|
|
512 gftp_shutdown();
|
|
513
|
|
514 return (0);
|
|
515 }
|
|
516
|
|
517
|
|
518 static int
|
374
|
519 gftpui_common_cmd_clear (void *uidata, gftp_request * request,
|
377
|
520 void *other_uidata, gftp_request * other_request,
|
374
|
521 const char *command)
|
341
|
522 {
|
|
523 if (strcasecmp (command, "cache") == 0)
|
|
524 gftp_clear_cache_files ();
|
|
525 else
|
|
526 {
|
374
|
527 gftpui_common_logfunc (gftp_logging_error, request,
|
|
528 _("Invalid argument\n"));
|
341
|
529 }
|
|
530
|
|
531 return (1);
|
|
532 }
|
|
533
|
|
534
|
|
535 static int
|
374
|
536 gftpui_common_clear_show_subhelp (const char *topic)
|
341
|
537 {
|
|
538 if (strcmp (topic, "cache") == 0)
|
|
539 {
|
374
|
540 gftpui_common_logfunc (gftp_logging_misc, NULL,
|
|
541 _("Clear the directory cache\n"));
|
341
|
542 return (1);
|
|
543 }
|
|
544
|
|
545 return (0);
|
|
546 }
|
|
547
|
|
548
|
|
549 static int
|
374
|
550 gftpui_common_set_show_subhelp (const char *topic)
|
341
|
551 {
|
|
552 gftp_config_vars * cv;
|
|
553
|
|
554 if ((cv = g_hash_table_lookup (gftp_global_options_htable, topic)) != NULL)
|
|
555 {
|
374
|
556 gftpui_common_logfunc (gftp_logging_misc, NULL, "%s\n", cv->comment);
|
341
|
557 return (1);
|
|
558 }
|
|
559
|
|
560 return (0);
|
|
561 }
|
|
562
|
|
563
|
355
|
564 static int
|
374
|
565 gftpui_common_cmd_ls (void *uidata, gftp_request * request,
|
377
|
566 void *other_uidata, gftp_request * other_request,
|
374
|
567 const char *command)
|
341
|
568 {
|
355
|
569 char *startcolor, *endcolor, *tempstr;
|
|
570 gftpui_callback_data * cdata;
|
|
571 GList * templist;
|
341
|
572 gftp_file * fle;
|
|
573
|
|
574 if (!GFTP_IS_CONNECTED (request))
|
|
575 {
|
|
576 request->logging_function (gftp_logging_error, request,
|
|
577 _("Error: Not connected to a remote site\n"));
|
|
578 return (1);
|
|
579 }
|
|
580
|
355
|
581 cdata = g_malloc0 (sizeof (*cdata));
|
|
582 cdata->request = request;
|
|
583 cdata->uidata = uidata;
|
374
|
584 cdata->source_string = *command != '\0' ? (char *) command : NULL;
|
355
|
585 cdata->run_function = gftpui_common_run_ls;
|
511
|
586 cdata->dont_refresh = 1;
|
341
|
587
|
355
|
588 gftpui_common_run_callback_function (cdata);
|
341
|
589
|
355
|
590 templist = cdata->files;
|
|
591 while (templist != NULL)
|
341
|
592 {
|
|
593 fle = templist->data;
|
|
594
|
|
595 gftpui_lookup_file_colors (fle, &startcolor, &endcolor);
|
830
|
596 tempstr = gftp_gen_ls_string (request, fle, startcolor, endcolor);
|
573
|
597 request->logging_function (gftp_logging_misc_nolog, request, "%s\n",
|
354
|
598 tempstr);
|
341
|
599 g_free (tempstr);
|
|
600
|
355
|
601 templist = templist->next;
|
598
|
602 gftp_file_destroy (fle, 1);
|
341
|
603 }
|
|
604
|
|
605
|
355
|
606 if (cdata->files != NULL)
|
|
607 g_list_free (cdata->files);
|
|
608 g_free (cdata);
|
341
|
609
|
|
610 return (1);
|
|
611 }
|
|
612
|
|
613
|
367
|
614 int
|
374
|
615 gftpui_common_cmd_open (void *uidata, gftp_request * request,
|
377
|
616 void *other_uidata, gftp_request * other_request,
|
374
|
617 const char *command)
|
356
|
618 {
|
367
|
619 gftpui_callback_data * cdata;
|
|
620 intptr_t retries;
|
356
|
621
|
|
622 if (GFTP_IS_CONNECTED (request))
|
387
|
623 gftpui_disconnect (uidata);
|
356
|
624
|
367
|
625 if (command != NULL)
|
356
|
626 {
|
367
|
627 if (*command == '\0')
|
|
628 {
|
|
629 request->logging_function (gftp_logging_error, request,
|
|
630 _("usage: open " GFTP_URL_USAGE "\n"));
|
|
631 return (1);
|
|
632 }
|
|
633
|
|
634 if (gftp_parse_url (request, command) < 0)
|
|
635 return (1);
|
356
|
636 }
|
|
637
|
553
|
638 if (gftp_need_username (request))
|
|
639 gftpui_prompt_username (uidata, request);
|
356
|
640
|
553
|
641 if (gftp_need_password (request))
|
|
642 gftpui_prompt_password (uidata, request);
|
356
|
643
|
367
|
644 gftp_lookup_request_option (request, "retries", &retries);
|
|
645
|
|
646 cdata = g_malloc0 (sizeof (*cdata));
|
|
647 cdata->request = request;
|
|
648 cdata->uidata = uidata;
|
|
649 cdata->run_function = gftpui_common_run_connect;
|
|
650 cdata->retries = retries;
|
451
|
651 cdata->dont_check_connection = 1;
|
367
|
652
|
775
|
653 gftpui_show_busy (TRUE);
|
367
|
654 gftpui_common_run_callback_function (cdata);
|
775
|
655 gftpui_show_busy (FALSE);
|
367
|
656
|
|
657 g_free (cdata);
|
356
|
658
|
|
659 return (1);
|
|
660 }
|
|
661
|
|
662
|
|
663 static int
|
374
|
664 gftpui_common_cmd_set (void *uidata, gftp_request * request,
|
377
|
665 void *other_uidata, gftp_request * other_request,
|
374
|
666 const char *command)
|
341
|
667 {
|
387
|
668 char *pos, *backpos, buf[256];
|
341
|
669 gftp_config_vars * cv, newcv;
|
|
670 GList * templist;
|
|
671 int i;
|
|
672
|
|
673 if (command == NULL || *command == '\0')
|
|
674 {
|
|
675 for (templist = gftp_options_list;
|
|
676 templist != NULL;
|
|
677 templist = templist->next)
|
|
678 {
|
|
679 cv = templist->data;
|
|
680
|
|
681 for (i=0; cv[i].key != NULL; i++)
|
|
682 {
|
|
683 if (!(cv[i].ports_shown & GFTP_PORT_TEXT))
|
|
684 continue;
|
|
685
|
|
686 if (*cv[i].key == '\0' ||
|
|
687 gftp_option_types[cv[i].otype].write_function == NULL)
|
|
688 continue;
|
|
689
|
387
|
690 gftp_option_types[cv[i].otype].write_function (&cv[i], buf,
|
|
691 sizeof (buf), 0);
|
|
692
|
|
693 gftpui_common_logfunc (gftp_logging_misc_nolog, request,
|
|
694 "%s = %s\n", cv[i].key, buf);
|
341
|
695 }
|
|
696 }
|
|
697 }
|
|
698 else
|
|
699 {
|
|
700 if ((pos = strchr (command, '=')) == NULL)
|
|
701 {
|
374
|
702 gftpui_common_logfunc (gftp_logging_error, request,
|
|
703 _("usage: set [variable = value]\n"));
|
341
|
704 return (1);
|
|
705 }
|
|
706 *pos = '\0';
|
|
707
|
|
708 for (backpos = pos - 1;
|
|
709 (*backpos == ' ' || *backpos == '\t') && backpos > command;
|
|
710 backpos--)
|
|
711 *backpos = '\0';
|
|
712 for (++pos; *pos == ' ' || *pos == '\t'; pos++);
|
|
713
|
|
714 if ((cv = g_hash_table_lookup (gftp_global_options_htable, command)) == NULL)
|
|
715 {
|
374
|
716 gftpui_common_logfunc (gftp_logging_error, request,
|
|
717 _("Error: Variable %s is not a valid configuration variable.\n"), command);
|
341
|
718 return (1);
|
|
719 }
|
|
720
|
|
721 if (!(cv->ports_shown & GFTP_PORT_TEXT))
|
|
722 {
|
374
|
723 gftpui_common_logfunc (gftp_logging_error, request,
|
|
724 _("Error: Variable %s is not available in the text port of gFTP\n"), command);
|
341
|
725 return (1);
|
|
726 }
|
|
727
|
|
728 if (gftp_option_types[cv->otype].read_function != NULL)
|
|
729 {
|
|
730 memcpy (&newcv, cv, sizeof (newcv));
|
|
731 newcv.flags &= ~GFTP_CVARS_FLAGS_DYNMEM;
|
|
732
|
|
733 gftp_option_types[cv->otype].read_function (pos, &newcv, 1);
|
|
734
|
|
735 gftp_set_global_option (command, newcv.value);
|
|
736
|
387
|
737 gftp_option_types[newcv.otype].write_function (&newcv, buf,
|
|
738 sizeof (buf), 0);
|
|
739
|
|
740 gftpui_common_logfunc (gftp_logging_misc_nolog, request,
|
|
741 "%s = %s\n", newcv.key, buf);
|
|
742
|
341
|
743 if (newcv.flags & GFTP_CVARS_FLAGS_DYNMEM)
|
|
744 g_free (newcv.value);
|
574
|
745
|
|
746 gftp_configuration_changed = 1;
|
341
|
747 }
|
|
748 }
|
|
749
|
|
750 return (1);
|
|
751 }
|
|
752
|
|
753
|
|
754 static int
|
374
|
755 gftpui_common_cmd_help (void *uidata, gftp_request * request,
|
377
|
756 void *other_uidata, gftp_request * other_request,
|
374
|
757 const char *command)
|
341
|
758 {
|
374
|
759 int i, j, ele, numrows, numcols = 6, handled, number_commands, cmdlen,
|
|
760 found;
|
387
|
761 char commands[128], cmdstr[30];
|
374
|
762 const char *pos;
|
341
|
763
|
|
764 for (number_commands=0;
|
|
765 gftpui_common_commands[number_commands].command != NULL;
|
|
766 number_commands++);
|
|
767
|
|
768 if (command != NULL && *command != '\0')
|
|
769 {
|
|
770 for (pos = command; *pos != ' ' && *pos != '\0'; pos++);
|
374
|
771 cmdlen = pos - command;
|
341
|
772
|
|
773 for (i=0; gftpui_common_commands[i].command != NULL; i++)
|
|
774 {
|
374
|
775 if (strncmp (gftpui_common_commands[i].command, command, cmdlen) == 0)
|
341
|
776 break;
|
|
777 }
|
|
778
|
|
779 if (gftpui_common_commands[i].cmd_description != NULL)
|
|
780 {
|
374
|
781 found = 1;
|
|
782
|
|
783 if (*pos != '\0' && *(pos + 1) != '\0' &&
|
|
784 gftpui_common_commands[i].subhelp_func != NULL)
|
|
785 handled = gftpui_common_commands[i].subhelp_func (pos + 1);
|
341
|
786 else
|
|
787 handled = 0;
|
|
788
|
|
789 if (!handled)
|
387
|
790 gftpui_common_logfunc (gftp_logging_misc_nolog, request, "%s\n",
|
|
791 _(gftpui_common_commands[i].cmd_description));
|
341
|
792 }
|
|
793 else
|
374
|
794 found = 0;
|
341
|
795 }
|
374
|
796 else
|
|
797 found = 0;
|
341
|
798
|
374
|
799 if (!found)
|
341
|
800 {
|
|
801 numrows = number_commands / numcols;
|
|
802 if (number_commands % numcols != 0)
|
|
803 numrows++;
|
|
804
|
387
|
805 gftpui_common_logfunc (gftp_logging_misc_nolog, request,
|
|
806 _("Supported commands:\n\n"));
|
|
807
|
341
|
808 for (i=0; i<numrows; i++)
|
|
809 {
|
387
|
810 strncpy (commands, "\t", sizeof (commands));
|
|
811
|
341
|
812 for (j=0; j<numcols; j++)
|
|
813 {
|
|
814 ele = i + j * numrows;
|
|
815 if (ele >= number_commands)
|
|
816 break;
|
387
|
817
|
|
818 g_snprintf (cmdstr, sizeof (cmdstr), "%-10s",
|
|
819 gftpui_common_commands[ele].command);
|
|
820 strncat (commands, cmdstr, sizeof (commands));
|
341
|
821 }
|
387
|
822 gftpui_common_logfunc (gftp_logging_misc_nolog, request, "%s\n",
|
|
823 commands);
|
341
|
824 }
|
|
825 }
|
|
826 return (1);
|
|
827 }
|
|
828
|
|
829
|
377
|
830 static void
|
825
|
831 _gftpui_common_cmd_transfer_files (void *fromuidata, gftp_request * fromrequest,
|
|
832 void *touidata, gftp_request * torequest,
|
|
833 const char *cmd, const char *filespec)
|
377
|
834 {
|
|
835 gftp_transfer * tdata;
|
|
836 gftp_file * fle;
|
|
837
|
|
838 if (!GFTP_IS_CONNECTED (fromrequest) ||
|
|
839 !GFTP_IS_CONNECTED (torequest))
|
|
840 {
|
|
841 fromrequest->logging_function (gftp_logging_error, fromrequest,
|
|
842 _("Error: Not connected to a remote site\n"));
|
|
843 return;
|
|
844 }
|
|
845
|
|
846 if (*filespec == '\0')
|
|
847 {
|
|
848 fromrequest->logging_function (gftp_logging_error, fromrequest,
|
|
849 _("usage: %s <filespec>\n"), cmd);
|
|
850 return;
|
|
851 }
|
|
852
|
|
853 tdata = gftp_tdata_new ();
|
|
854 tdata->fromreq = fromrequest;
|
|
855 tdata->toreq = torequest;
|
|
856
|
|
857 if (gftp_list_files (tdata->fromreq) != 0)
|
|
858 {
|
|
859 tdata->fromreq = tdata->toreq = NULL;
|
|
860 free_tdata (tdata);
|
|
861 return;
|
|
862 }
|
|
863
|
|
864 fle = g_malloc0 (sizeof (*fle));
|
|
865 while (gftp_get_next_file (tdata->fromreq, filespec, fle) > 0)
|
|
866 {
|
|
867 if (strcmp (fle->file, ".") == 0 || strcmp (fle->file, "..") == 0)
|
|
868 {
|
598
|
869 gftp_file_destroy (fle, 0);
|
377
|
870 continue;
|
|
871 }
|
|
872
|
|
873 tdata->files = g_list_append (tdata->files, fle);
|
|
874 fle = g_malloc (sizeof (*fle));
|
|
875 }
|
|
876
|
|
877 g_free (fle);
|
|
878
|
|
879 gftp_end_transfer (tdata->fromreq);
|
|
880
|
|
881 if (tdata->files == NULL)
|
|
882 {
|
|
883 tdata->fromreq = tdata->toreq = NULL;
|
|
884 free_tdata (tdata);
|
|
885 return;
|
|
886 }
|
|
887
|
|
888 if (gftp_get_all_subdirs (tdata, NULL) != 0)
|
|
889 {
|
|
890 tdata->fromreq = tdata->toreq = NULL;
|
|
891 free_tdata (tdata);
|
|
892 return;
|
|
893 }
|
|
894
|
|
895 if (tdata->files == NULL)
|
|
896 {
|
|
897 tdata->fromreq = tdata->toreq = NULL;
|
|
898 free_tdata (tdata);
|
|
899 return;
|
|
900 }
|
|
901
|
|
902 gftpui_common_add_file_transfer (tdata->fromreq, tdata->toreq,
|
|
903 fromuidata, touidata, tdata->files);
|
|
904
|
|
905 g_free (tdata);
|
|
906
|
|
907 return;
|
|
908 }
|
|
909
|
|
910
|
|
911 int
|
|
912 gftpui_common_cmd_mget_file (void *uidata, gftp_request * request,
|
|
913 void *other_uidata, gftp_request * other_request,
|
|
914 const char *command)
|
|
915 {
|
825
|
916 _gftpui_common_cmd_transfer_files (uidata, request, other_uidata,
|
|
917 other_request, "mget", command);
|
377
|
918 return (1);
|
|
919 }
|
|
920
|
|
921
|
|
922 int
|
|
923 gftpui_common_cmd_mput_file (void *uidata, gftp_request * request,
|
|
924 void *other_uidata, gftp_request * other_request,
|
|
925 const char *command)
|
|
926 {
|
825
|
927 _gftpui_common_cmd_transfer_files (other_uidata, other_request, uidata,
|
|
928 request, "mput", command);
|
377
|
929 return (1);
|
|
930 }
|
|
931
|
|
932
|
341
|
933 gftpui_common_methods gftpui_common_commands[] = {
|
|
934 {N_("about"), 2, gftpui_common_cmd_about, gftpui_common_request_none,
|
|
935 N_("Shows gFTP information"), NULL},
|
|
936 {N_("ascii"), 2, gftpui_common_cmd_ascii, gftpui_common_request_remote,
|
|
937 N_("Sets the current file transfer mode to Ascii (only for FTP)"), NULL},
|
|
938 {N_("binary"), 1, gftpui_common_cmd_binary, gftpui_common_request_remote,
|
|
939 N_("Sets the current file transfer mode to Binary (only for FTP)"), NULL},
|
|
940 {N_("cd"), 2, gftpui_common_cmd_chdir, gftpui_common_request_remote,
|
|
941 N_("Changes the remote working directory"), NULL},
|
|
942 {N_("chdir"), 3, gftpui_common_cmd_chdir, gftpui_common_request_remote,
|
|
943 N_("Changes the remote working directory"), NULL},
|
|
944 {N_("chmod"), 3, gftpui_common_cmd_chmod, gftpui_common_request_remote,
|
|
945 N_("Changes the permissions of a remote file"), NULL},
|
|
946 {N_("clear"), 3, gftpui_common_cmd_clear, gftpui_common_request_none,
|
|
947 N_("Available options: cache"), gftpui_common_clear_show_subhelp},
|
|
948 {N_("close"), 3, gftpui_common_cmd_close, gftpui_common_request_remote,
|
|
949 N_("Disconnects from the remote site"), NULL},
|
350
|
950 {N_("delete"), 1, gftpui_common_cmd_delete, gftpui_common_request_remote,
|
341
|
951 N_("Removes a remote file"), NULL},
|
651
|
952 {N_("dir"), 3, gftpui_common_cmd_ls, gftpui_common_request_remote,
|
|
953 N_("Shows the directory listing for the current remote directory"), NULL},
|
377
|
954 {N_("get"), 1, gftpui_common_cmd_mget_file, gftpui_common_request_remote,
|
341
|
955 N_("Downloads remote file(s)"), NULL},
|
|
956 {N_("help"), 1, gftpui_common_cmd_help, gftpui_common_request_none,
|
|
957 N_("Shows this help screen"), NULL},
|
|
958 {N_("lcd"), 3, gftpui_common_cmd_chdir, gftpui_common_request_local,
|
|
959 N_("Changes the local working directory"), NULL},
|
|
960 {N_("lchdir"), 4, gftpui_common_cmd_chdir, gftpui_common_request_local,
|
|
961 N_("Changes the local working directory"), NULL},
|
|
962 {N_("lchmod"), 4, gftpui_common_cmd_chmod, gftpui_common_request_local,
|
|
963 N_("Changes the permissions of a local file"), NULL},
|
|
964 {N_("ldelete"), 2, gftpui_common_cmd_delete, gftpui_common_request_local,
|
|
965 N_("Removes a local file"), NULL},
|
651
|
966 {N_("ldir"), 4, gftpui_common_cmd_ls, gftpui_common_request_local,
|
|
967 N_("Shows the directory listing for the current local directory"), NULL},
|
341
|
968 {N_("lls"), 2, gftpui_common_cmd_ls, gftpui_common_request_local,
|
|
969 N_("Shows the directory listing for the current local directory"), NULL},
|
|
970 {N_("lmkdir"), 2, gftpui_common_cmd_mkdir, gftpui_common_request_local,
|
|
971 N_("Creates a local directory"), NULL},
|
|
972 {N_("lpwd"), 2, gftpui_common_cmd_pwd, gftpui_common_request_local,
|
|
973 N_("Show current local directory"), NULL},
|
|
974 {N_("lrename"), 3, gftpui_common_cmd_rename, gftpui_common_request_local,
|
|
975 N_("Rename a local file"), NULL},
|
|
976 {N_("lrmdir"), 3, gftpui_common_cmd_rmdir, gftpui_common_request_local,
|
|
977 N_("Remove a local directory"), NULL},
|
|
978 {N_("ls"), 2, gftpui_common_cmd_ls, gftpui_common_request_remote,
|
|
979 N_("Shows the directory listing for the current remote directory"), NULL},
|
377
|
980 {N_("mget"), 2, gftpui_common_cmd_mget_file, gftpui_common_request_remote,
|
341
|
981 N_("Downloads remote file(s)"), NULL},
|
377
|
982 {N_("mkdir"), 2, gftpui_common_cmd_mkdir, gftpui_common_request_remote,
|
341
|
983 N_("Creates a remote directory"), NULL},
|
377
|
984 {N_("mput"), 2, gftpui_common_cmd_mput_file, gftpui_common_request_remote,
|
341
|
985 N_("Uploads local file(s)"), NULL},
|
356
|
986 {N_("open"), 1, gftpui_common_cmd_open, gftpui_common_request_remote,
|
341
|
987 N_("Opens a connection to a remote site"), NULL},
|
377
|
988 {N_("put"), 2, gftpui_common_cmd_mput_file, gftpui_common_request_remote,
|
341
|
989 N_("Uploads local file(s)"), NULL},
|
|
990 {N_("pwd"), 2, gftpui_common_cmd_pwd, gftpui_common_request_remote,
|
|
991 N_("Show current remote directory"), NULL},
|
|
992 {N_("quit"), 1, gftpui_common_cmd_quit, gftpui_common_request_none,
|
|
993 N_("Exit from gFTP"), NULL},
|
|
994 {N_("rename"), 2, gftpui_common_cmd_rename, gftpui_common_request_remote,
|
|
995 N_("Rename a remote file"), NULL},
|
|
996 {N_("rmdir"), 2, gftpui_common_cmd_rmdir, gftpui_common_request_remote,
|
|
997 N_("Remove a remote directory"), NULL},
|
|
998 {N_("set"), 1, gftpui_common_cmd_set, gftpui_common_request_none,
|
377
|
999 N_("Show configuration file variables. You can also set variables by set var=val"),
|
|
1000 gftpui_common_set_show_subhelp},
|
350
|
1001 {N_("site"), 2, gftpui_common_cmd_site, gftpui_common_request_remote,
|
|
1002 N_("Run a site specific command"), NULL},
|
341
|
1003 {NULL, 0, NULL, gftpui_common_request_none,
|
|
1004 NULL, NULL}};
|
|
1005
|
|
1006
|
|
1007 int
|
374
|
1008 gftpui_common_process_command (void *locui, gftp_request * locreq,
|
|
1009 void *remui, gftp_request * remreq,
|
|
1010 const char *command)
|
341
|
1011 {
|
377
|
1012 gftp_request * request, * other_request;
|
|
1013 void *uidata, *other_uidata;
|
341
|
1014 char *pos, *newstr;
|
377
|
1015 const char *stpos;
|
341
|
1016 size_t cmdlen;
|
|
1017 int ret, i;
|
|
1018 size_t len;
|
|
1019
|
|
1020 for (stpos = command; *stpos == ' ' || *stpos == '\t'; stpos++);
|
|
1021
|
|
1022 newstr = g_strdup (stpos);
|
|
1023 len = strlen (newstr);
|
|
1024
|
|
1025 if (len > 0 && newstr[len - 1] == '\n')
|
|
1026 newstr[--len] = '\0';
|
|
1027 if (len > 0 && newstr[len - 1] == '\r')
|
|
1028 newstr[--len] = '\0';
|
|
1029
|
|
1030 for (pos = newstr + len - 1;
|
841
|
1031 (*pos == ' ' || *pos == '\t') && pos > newstr;
|
|
1032 *pos-- = '\0');
|
341
|
1033
|
841
|
1034 if (*newstr == '\0')
|
341
|
1035 {
|
|
1036 g_free (newstr);
|
|
1037 return (1);
|
|
1038 }
|
|
1039
|
|
1040 if ((pos = strchr (newstr, ' ')) != NULL)
|
|
1041 *pos = '\0';
|
|
1042
|
|
1043 cmdlen = strlen (newstr);
|
|
1044 for (i=0; gftpui_common_commands[i].command != NULL; i++)
|
|
1045 {
|
|
1046 if (strcmp (gftpui_common_commands[i].command, newstr) == 0)
|
|
1047 break;
|
|
1048 else if (cmdlen >= gftpui_common_commands[i].minlen &&
|
|
1049 strncmp (gftpui_common_commands[i].command, newstr, cmdlen) == 0)
|
|
1050 break;
|
|
1051 }
|
|
1052
|
|
1053 if (pos != NULL)
|
|
1054 pos++;
|
|
1055 else
|
|
1056 pos = "";
|
|
1057
|
374
|
1058 if (gftpui_common_commands[i].reqtype == gftpui_common_request_local)
|
|
1059 {
|
|
1060 request = locreq;
|
|
1061 uidata = locui;
|
377
|
1062
|
|
1063 other_request = remreq;
|
|
1064 other_uidata = remui;
|
374
|
1065 }
|
|
1066 else if (gftpui_common_commands[i].reqtype == gftpui_common_request_remote)
|
|
1067 {
|
|
1068 request = remreq;
|
|
1069 uidata = remui;
|
377
|
1070
|
|
1071 other_request = locreq;
|
|
1072 other_uidata = locui;
|
374
|
1073 }
|
|
1074 else
|
|
1075 {
|
377
|
1076 request = other_request = NULL;
|
|
1077 uidata = other_uidata = NULL;
|
374
|
1078 }
|
|
1079
|
341
|
1080 if (gftpui_common_commands[i].command != NULL)
|
|
1081 {
|
377
|
1082 ret = gftpui_common_commands[i].func (uidata, request,
|
|
1083 other_uidata, other_request, pos);
|
380
|
1084
|
387
|
1085 if (request != NULL && !GFTP_IS_CONNECTED (request))
|
380
|
1086 gftpui_disconnect (uidata);
|
341
|
1087 }
|
|
1088 else
|
|
1089 {
|
374
|
1090 gftpui_common_logfunc (gftp_logging_error, request,
|
|
1091 _("Error: Command not recognized\n"));
|
341
|
1092 ret = 1;
|
|
1093 }
|
|
1094
|
|
1095 g_free (newstr);
|
|
1096 return (ret);
|
|
1097 }
|
|
1098
|
367
|
1099
|
|
1100 gftp_transfer *
|
|
1101 gftpui_common_add_file_transfer (gftp_request * fromreq, gftp_request * toreq,
|
|
1102 void *fromuidata, void *touidata,
|
|
1103 GList * files)
|
|
1104 {
|
795
|
1105 intptr_t append_transfers, one_transfer, overwrite_default;
|
367
|
1106 GList * templist, *curfle;
|
|
1107 gftp_transfer * tdata;
|
|
1108 gftp_file * tempfle;
|
|
1109 int show_dialog;
|
|
1110
|
795
|
1111 gftp_lookup_request_option (fromreq, "overwrite_default", &overwrite_default);
|
|
1112 gftp_lookup_request_option (fromreq, "append_transfers", &append_transfers);
|
|
1113 gftp_lookup_request_option (fromreq, "one_transfer", &one_transfer);
|
|
1114
|
|
1115 if (!overwrite_default)
|
|
1116 {
|
|
1117 for (templist = files; templist != NULL; templist = templist->next)
|
|
1118 {
|
|
1119 tempfle = templist->data;
|
|
1120 if (tempfle->startsize > 0)
|
|
1121 break;
|
|
1122 }
|
|
1123
|
|
1124 show_dialog = templist != NULL;
|
367
|
1125 }
|
795
|
1126 else
|
|
1127 show_dialog = 0;
|
367
|
1128
|
|
1129 tdata = NULL;
|
|
1130 if (append_transfers && one_transfer && !show_dialog)
|
|
1131 {
|
|
1132 if (g_thread_supported ())
|
|
1133 g_static_mutex_lock (&gftpui_common_transfer_mutex);
|
|
1134
|
|
1135 for (templist = gftp_file_transfers;
|
|
1136 templist != NULL;
|
|
1137 templist = templist->next)
|
|
1138 {
|
|
1139 tdata = templist->data;
|
|
1140
|
|
1141 if (g_thread_supported ())
|
|
1142 g_static_mutex_lock (&tdata->structmutex);
|
|
1143
|
|
1144 if (!compare_request (tdata->fromreq, fromreq, 0) ||
|
|
1145 !compare_request (tdata->toreq, toreq, 0) ||
|
|
1146 tdata->curfle == NULL)
|
|
1147 {
|
|
1148 if (g_thread_supported ())
|
|
1149 g_static_mutex_unlock (&tdata->structmutex);
|
|
1150
|
|
1151 continue;
|
|
1152 }
|
|
1153
|
|
1154 tdata->files = g_list_concat (tdata->files, files);
|
|
1155
|
|
1156 for (curfle = files; curfle != NULL; curfle = curfle->next)
|
|
1157 {
|
|
1158 tempfle = curfle->data;
|
|
1159
|
499
|
1160 if (S_ISDIR (tempfle->st_mode))
|
367
|
1161 tdata->numdirs++;
|
|
1162 else
|
|
1163 tdata->numfiles++;
|
|
1164
|
|
1165 if (tempfle->transfer_action != GFTP_TRANS_ACTION_SKIP)
|
|
1166 tdata->total_bytes += tempfle->size;
|
|
1167
|
397
|
1168 gftpui_add_file_to_transfer (tdata, curfle);
|
367
|
1169 }
|
|
1170
|
|
1171 if (g_thread_supported ())
|
|
1172 g_static_mutex_unlock (&tdata->structmutex);
|
|
1173
|
|
1174 break;
|
|
1175 }
|
|
1176
|
|
1177 if (g_thread_supported ())
|
|
1178 g_static_mutex_unlock (&gftpui_common_transfer_mutex);
|
|
1179 }
|
|
1180 else
|
|
1181 templist = NULL;
|
|
1182
|
|
1183 if (templist == NULL)
|
|
1184 {
|
|
1185 tdata = gftp_tdata_new ();
|
368
|
1186 tdata->fromreq = gftp_copy_request (fromreq);
|
|
1187 tdata->toreq = gftp_copy_request (toreq);
|
367
|
1188
|
|
1189 tdata->fromwdata = fromuidata;
|
|
1190 tdata->towdata = touidata;
|
|
1191
|
|
1192 if (!show_dialog)
|
|
1193 tdata->show = tdata->ready = 1;
|
|
1194
|
|
1195 tdata->files = files;
|
|
1196 for (curfle = files; curfle != NULL; curfle = curfle->next)
|
|
1197 {
|
|
1198 tempfle = curfle->data;
|
499
|
1199 if (S_ISDIR (tempfle->st_mode))
|
367
|
1200 tdata->numdirs++;
|
|
1201 else
|
|
1202 tdata->numfiles++;
|
|
1203
|
|
1204 if (tempfle->transfer_action != GFTP_TRANS_ACTION_SKIP)
|
|
1205 tdata->total_bytes += tempfle->size;
|
|
1206 }
|
|
1207
|
|
1208 if (g_thread_supported ())
|
|
1209 g_static_mutex_lock (&gftpui_common_transfer_mutex);
|
|
1210
|
|
1211 gftp_file_transfers = g_list_append (gftp_file_transfers, tdata);
|
|
1212
|
|
1213 if (g_thread_supported ())
|
|
1214 g_static_mutex_unlock (&gftpui_common_transfer_mutex);
|
|
1215
|
|
1216 if (show_dialog)
|
|
1217 gftpui_ask_transfer (tdata);
|
|
1218 }
|
|
1219
|
377
|
1220 gftpui_start_transfer (tdata);
|
367
|
1221 return (tdata);
|
|
1222 }
|
|
1223
|
|
1224
|
|
1225 static void
|
|
1226 _gftpui_common_setup_fds (gftp_transfer * tdata, gftp_file * curfle,
|
|
1227 int *fromfd, int *tofd)
|
|
1228 {
|
|
1229 *tofd = -1;
|
|
1230 *fromfd = -1;
|
|
1231
|
|
1232 if (curfle->is_fd)
|
|
1233 {
|
|
1234 if (tdata->toreq->protonum == GFTP_LOCAL_NUM)
|
|
1235 *tofd = curfle->fd;
|
|
1236 else if (tdata->fromreq->protonum == GFTP_LOCAL_NUM)
|
|
1237 *fromfd = curfle->fd;
|
|
1238 }
|
|
1239 }
|
|
1240
|
|
1241
|
|
1242 static void
|
|
1243 _gftpui_common_done_with_fds (gftp_transfer * tdata, gftp_file * curfle)
|
|
1244 {
|
|
1245 if (curfle->is_fd)
|
|
1246 {
|
|
1247 if (tdata->toreq->protonum == GFTP_LOCAL_NUM)
|
|
1248 tdata->toreq->datafd = -1;
|
|
1249 else
|
|
1250 tdata->fromreq->datafd = -1;
|
|
1251 }
|
|
1252 }
|
|
1253
|
|
1254
|
862
|
1255 static ssize_t
|
|
1256 _do_transfer_block (gftp_transfer * tdata, gftp_file * curfle, char *buf,
|
|
1257 size_t trans_blksize)
|
|
1258 {
|
|
1259 ssize_t num_read, num_wrote, ret;
|
|
1260 char *bufpos;
|
|
1261
|
|
1262 num_read = gftp_get_next_file_chunk (tdata->fromreq, buf, trans_blksize);
|
|
1263 if (num_read < 0)
|
|
1264 return (num_read);
|
|
1265
|
|
1266 bufpos = buf;
|
|
1267 num_wrote = 0;
|
|
1268 while (num_wrote < num_read)
|
|
1269 {
|
|
1270 if ((ret = gftp_put_next_file_chunk (tdata->toreq, bufpos,
|
|
1271 num_read - num_wrote)) <= 0)
|
|
1272 return (ret);
|
|
1273
|
|
1274 num_wrote += ret;
|
|
1275 bufpos += ret;
|
|
1276 }
|
|
1277
|
|
1278 return (num_read);
|
|
1279 }
|
|
1280
|
|
1281
|
367
|
1282 int
|
825
|
1283 _gftpui_common_do_transfer_file (gftp_transfer * tdata, gftp_file * curfle)
|
367
|
1284 {
|
377
|
1285 struct timeval updatetime;
|
811
|
1286 intptr_t trans_blksize;
|
862
|
1287 ssize_t num_trans;
|
|
1288 char *buf;
|
|
1289 int ret;
|
527
|
1290
|
|
1291 gftp_lookup_request_option (tdata->fromreq, "trans_blksize", &trans_blksize);
|
|
1292 buf = g_malloc (trans_blksize);
|
367
|
1293
|
811
|
1294 memset (&updatetime, 0, sizeof (updatetime));
|
|
1295 gftpui_start_current_file_in_transfer (tdata);
|
|
1296
|
862
|
1297 num_trans = 0;
|
811
|
1298 while (!tdata->cancel &&
|
862
|
1299 (num_trans = _do_transfer_block (tdata, curfle, buf,
|
|
1300 trans_blksize)) > 0)
|
811
|
1301 {
|
862
|
1302 gftp_calc_kbs (tdata, num_trans);
|
|
1303
|
811
|
1304 if (tdata->lasttime.tv_sec - updatetime.tv_sec >= 1 ||
|
|
1305 tdata->curtrans >= tdata->tot_file_trans)
|
|
1306 {
|
|
1307 gftpui_update_current_file_in_transfer (tdata);
|
|
1308 memcpy (&updatetime, &tdata->lasttime, sizeof (updatetime));
|
|
1309
|
862
|
1310 if (tdata->current_file_retries > 0)
|
|
1311 tdata->current_file_retries = 0;
|
811
|
1312 }
|
|
1313 }
|
|
1314
|
862
|
1315 if (num_trans == GFTP_ENOTRANS)
|
|
1316 num_trans = 0;
|
811
|
1317
|
|
1318 g_free (buf);
|
|
1319 gftpui_finish_current_file_in_transfer (tdata);
|
|
1320
|
862
|
1321 if ((int) num_trans == 0)
|
825
|
1322 {
|
|
1323 if ((ret = gftp_end_transfer (tdata->fromreq)) < 0)
|
|
1324 return (ret);
|
|
1325
|
|
1326 if ((ret = gftp_end_transfer (tdata->toreq)) < 0)
|
|
1327 return (ret);
|
|
1328
|
|
1329 tdata->fromreq->logging_function (gftp_logging_misc,
|
|
1330 tdata->fromreq,
|
|
1331 _("Successfully transferred %s at %.2f KB/s\n"),
|
|
1332 curfle->file, tdata->kbs);
|
|
1333
|
|
1334 return (0);
|
|
1335 }
|
|
1336 else
|
862
|
1337 return ((int) num_trans);
|
811
|
1338 }
|
|
1339
|
|
1340
|
819
|
1341 void
|
|
1342 gftpui_common_skip_file_transfer (gftp_transfer * tdata, gftp_file * curfle)
|
|
1343 {
|
|
1344 g_static_mutex_lock (&tdata->structmutex);
|
|
1345
|
|
1346 if (tdata->started && !(curfle->transfer_action & GFTP_TRANS_ACTION_SKIP))
|
|
1347 {
|
|
1348 curfle->transfer_action = GFTP_TRANS_ACTION_SKIP;
|
|
1349 if (tdata->curfle != NULL && curfle == tdata->curfle->data)
|
|
1350 {
|
876
|
1351 gftpui_cancel_file_transfer (tdata);
|
819
|
1352 tdata->skip_file = 1;
|
|
1353 }
|
|
1354 else if (!curfle->transfer_done)
|
|
1355 tdata->total_bytes -= curfle->size;
|
|
1356 }
|
|
1357
|
|
1358 g_static_mutex_unlock (&tdata->structmutex);
|
|
1359
|
|
1360 if (curfle != NULL)
|
|
1361 tdata->fromreq->logging_function (gftp_logging_misc, tdata->fromreq,
|
|
1362 _("Skipping file %s on host %s\n"),
|
|
1363 curfle->file, tdata->toreq->hostname);
|
|
1364 }
|
|
1365
|
|
1366
|
|
1367 void
|
|
1368 gftpui_common_cancel_file_transfer (gftp_transfer * tdata)
|
|
1369 {
|
|
1370 g_static_mutex_lock (&tdata->structmutex);
|
|
1371
|
|
1372 if (tdata->started)
|
|
1373 {
|
876
|
1374 gftpui_cancel_file_transfer (tdata);
|
819
|
1375 tdata->skip_file = 0;
|
|
1376 }
|
|
1377 else
|
|
1378 tdata->done = 1;
|
|
1379
|
|
1380 tdata->fromreq->stopable = 0;
|
|
1381 tdata->toreq->stopable = 0;
|
|
1382
|
|
1383 g_static_mutex_unlock (&tdata->structmutex);
|
|
1384
|
|
1385 tdata->fromreq->logging_function (gftp_logging_misc, tdata->fromreq,
|
|
1386 _("Stopping the transfer on host %s\n"),
|
|
1387 tdata->toreq->hostname);
|
|
1388 }
|
|
1389
|
|
1390
|
838
|
1391 static void
|
825
|
1392 _gftpui_common_next_file_in_trans (gftp_transfer * tdata)
|
|
1393 {
|
|
1394 gftp_file * curfle;
|
|
1395
|
|
1396 if (g_thread_supported ())
|
|
1397 g_static_mutex_lock (&tdata->structmutex);
|
|
1398
|
|
1399 tdata->curtrans = 0;
|
|
1400 tdata->next_file = 1;
|
|
1401
|
|
1402 curfle = tdata->curfle->data;
|
|
1403 curfle->transfer_done = 1;
|
|
1404 tdata->curfle = tdata->curfle->next;
|
|
1405
|
|
1406 if (g_thread_supported ())
|
|
1407 g_static_mutex_unlock (&tdata->structmutex);
|
|
1408 }
|
|
1409
|
|
1410
|
|
1411 static int
|
|
1412 _gftpui_common_preserve_perm_time (gftp_transfer * tdata, gftp_file * curfle)
|
811
|
1413 {
|
|
1414 intptr_t preserve_permissions, preserve_time;
|
825
|
1415 int ret, tmpret;
|
367
|
1416
|
774
|
1417 gftp_lookup_request_option (tdata->fromreq, "preserve_permissions",
|
|
1418 &preserve_permissions);
|
|
1419 gftp_lookup_request_option (tdata->fromreq, "preserve_time",
|
|
1420 &preserve_time);
|
|
1421
|
825
|
1422 ret = 0;
|
|
1423 if (GFTP_IS_CONNECTED (tdata->toreq) && preserve_permissions &&
|
|
1424 curfle->st_mode != 0)
|
367
|
1425 {
|
825
|
1426 tmpret = gftp_chmod (tdata->toreq, curfle->destfile,
|
|
1427 curfle->st_mode & (S_IRWXU | S_IRWXG | S_IRWXO));
|
|
1428 if (tmpret < 0)
|
|
1429 ret = tmpret;
|
|
1430 }
|
367
|
1431
|
825
|
1432 if (GFTP_IS_CONNECTED (tdata->toreq) && preserve_time &&
|
|
1433 curfle->datetime != 0)
|
|
1434 {
|
|
1435 tmpret = gftp_set_file_time (tdata->toreq, curfle->destfile,
|
|
1436 curfle->datetime);
|
|
1437 if (tmpret < 0)
|
|
1438 ret = tmpret;
|
|
1439 }
|
367
|
1440
|
825
|
1441 if (!GFTP_IS_CONNECTED (tdata->toreq))
|
|
1442 return (ret);
|
|
1443 else
|
|
1444 return (0);
|
|
1445 }
|
|
1446
|
367
|
1447
|
825
|
1448 static int
|
|
1449 _gftpui_common_trans_file_or_dir (gftp_transfer * tdata)
|
|
1450 {
|
858
|
1451 int tofd, fromfd, ret;
|
862
|
1452 gftp_file * curfle;
|
825
|
1453
|
|
1454 if (g_thread_supported ())
|
|
1455 g_static_mutex_lock (&tdata->structmutex);
|
367
|
1456
|
825
|
1457 curfle = tdata->curfle->data;
|
|
1458 tdata->current_file_number++;
|
|
1459
|
|
1460 if (g_thread_supported ())
|
|
1461 g_static_mutex_unlock (&tdata->structmutex);
|
|
1462
|
|
1463 if (curfle->transfer_action == GFTP_TRANS_ACTION_SKIP)
|
|
1464 {
|
|
1465 tdata->tot_file_trans = 0;
|
|
1466 return (0);
|
|
1467 }
|
|
1468
|
|
1469 if ((ret = gftp_connect (tdata->fromreq)) < 0)
|
|
1470 return (ret);
|
|
1471
|
|
1472 if ((ret = gftp_connect (tdata->toreq)) < 0)
|
|
1473 return (ret);
|
367
|
1474
|
825
|
1475 if (S_ISDIR (curfle->st_mode))
|
|
1476 {
|
|
1477 tdata->tot_file_trans = 0;
|
862
|
1478 ret = gftp_make_directory (tdata->toreq, curfle->destfile);
|
825
|
1479 }
|
|
1480 else
|
|
1481 {
|
|
1482 _gftpui_common_setup_fds (tdata, curfle, &fromfd, &tofd);
|
367
|
1483
|
825
|
1484 if (curfle->size == 0)
|
|
1485 {
|
|
1486 curfle->size = gftp_get_file_size (tdata->fromreq, curfle->file);
|
862
|
1487 if (curfle->size < 0)
|
|
1488 return ((int) curfle->size);
|
377
|
1489
|
825
|
1490 tdata->total_bytes += curfle->size;
|
367
|
1491 }
|
|
1492
|
862
|
1493 if (curfle->retry_transfer)
|
|
1494 {
|
|
1495 curfle->transfer_action = GFTP_TRANS_ACTION_RESUME;
|
|
1496 curfle->startsize = gftp_get_file_size (tdata->toreq, curfle->destfile);
|
|
1497 if (curfle->startsize < 0)
|
|
1498 return ((int) curfle->startsize);
|
|
1499 }
|
|
1500
|
825
|
1501 tdata->tot_file_trans = gftp_transfer_file (tdata->fromreq, curfle->file,
|
|
1502 fromfd,
|
|
1503 curfle->transfer_action == GFTP_TRANS_ACTION_RESUME ?
|
|
1504 curfle->startsize : 0,
|
|
1505 tdata->toreq, curfle->destfile, tofd,
|
|
1506 curfle->transfer_action == GFTP_TRANS_ACTION_RESUME ?
|
|
1507 curfle->startsize : 0);
|
|
1508 if (tdata->tot_file_trans < 0)
|
|
1509 ret = tdata->tot_file_trans;
|
367
|
1510 else
|
|
1511 {
|
|
1512 if (g_thread_supported ())
|
|
1513 g_static_mutex_lock (&tdata->structmutex);
|
|
1514
|
|
1515 tdata->curtrans = 0;
|
|
1516 tdata->curresumed = curfle->transfer_action == GFTP_TRANS_ACTION_RESUME ? curfle->startsize : 0;
|
|
1517 tdata->resumed_bytes += tdata->curresumed;
|
|
1518
|
|
1519 if (g_thread_supported ())
|
|
1520 g_static_mutex_unlock (&tdata->structmutex);
|
|
1521
|
825
|
1522 ret = _gftpui_common_do_transfer_file (tdata, curfle);
|
367
|
1523 }
|
|
1524
|
825
|
1525 _gftpui_common_done_with_fds (tdata, curfle);
|
|
1526 }
|
|
1527
|
|
1528 if (ret == 0)
|
|
1529 {
|
|
1530 if (!curfle->is_fd)
|
|
1531 ret = _gftpui_common_preserve_perm_time (tdata, curfle);
|
|
1532 }
|
|
1533 else
|
862
|
1534 {
|
|
1535 curfle->retry_transfer = 1;
|
|
1536 tdata->fromreq->logging_function (gftp_logging_error, tdata->fromreq,
|
|
1537 _("Could not download %s from %s\n"),
|
|
1538 curfle->file, tdata->fromreq->hostname);
|
|
1539 }
|
825
|
1540
|
|
1541 return (ret);
|
|
1542 }
|
|
1543
|
|
1544
|
|
1545 int
|
|
1546 gftpui_common_transfer_files (gftp_transfer * tdata)
|
|
1547 {
|
858
|
1548 int ret, skipped_files;
|
825
|
1549
|
|
1550 tdata->curfle = tdata->files;
|
876
|
1551 gftpui_common_num_child_threads++;
|
|
1552
|
825
|
1553 gettimeofday (&tdata->starttime, NULL);
|
|
1554 memcpy (&tdata->lasttime, &tdata->starttime, sizeof (tdata->lasttime));
|
|
1555
|
858
|
1556 skipped_files = 0;
|
825
|
1557 while (tdata->curfle != NULL)
|
|
1558 {
|
|
1559 ret = _gftpui_common_trans_file_or_dir (tdata);
|
367
|
1560 if (tdata->cancel)
|
|
1561 {
|
825
|
1562 if (gftp_abort_transfer (tdata->toreq) != 0)
|
|
1563 gftp_disconnect (tdata->toreq);
|
|
1564
|
367
|
1565 if (gftp_abort_transfer (tdata->fromreq) != 0)
|
|
1566 gftp_disconnect (tdata->fromreq);
|
|
1567 }
|
858
|
1568 else if (ret == GFTP_EFATAL)
|
|
1569 skipped_files++;
|
811
|
1570 else if (ret < 0)
|
367
|
1571 {
|
811
|
1572 if (gftp_get_transfer_status (tdata, ret) == GFTP_ERETRYABLE)
|
367
|
1573 continue;
|
|
1574
|
|
1575 break;
|
|
1576 }
|
|
1577
|
825
|
1578 _gftpui_common_next_file_in_trans (tdata);
|
367
|
1579
|
825
|
1580 if (tdata->cancel)
|
367
|
1581 {
|
825
|
1582 if (!tdata->skip_file)
|
|
1583 break;
|
367
|
1584
|
825
|
1585 tdata->cancel = 0;
|
|
1586 tdata->fromreq->cancel = 0;
|
|
1587 tdata->toreq->cancel = 0;
|
|
1588 }
|
367
|
1589 }
|
527
|
1590
|
858
|
1591 if (skipped_files)
|
|
1592 tdata->fromreq->logging_function (gftp_logging_error, tdata->fromreq,
|
|
1593 _("There were %d files or directories that could not be transferred. Check the log for which items were not properly transferred."),
|
|
1594 skipped_files);
|
|
1595
|
367
|
1596 tdata->done = 1;
|
876
|
1597 gftpui_common_num_child_threads--;
|
|
1598
|
387
|
1599 return (1);
|
367
|
1600 }
|
|
1601
|
469
|
1602
|
|
1603 void
|
|
1604 gftpui_protocol_update_timeout (gftp_request * request)
|
|
1605 {
|
|
1606 intptr_t network_timeout;
|
|
1607
|
|
1608 gftp_lookup_request_option (request, "network_timeout", &network_timeout);
|
|
1609
|
|
1610 if (network_timeout > 0)
|
|
1611 alarm (network_timeout);
|
|
1612 }
|
|
1613
|