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