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
|
885
|
155 logging_function (gftp_logging_misc, logdata, "%s, Copyright (C) 1998-2007 Brian Masney <", gftp_version);
|
341
|
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
|
879
|
653 if (request->refreshing)
|
|
654 cdata->dont_refresh = 1;
|
|
655
|
775
|
656 gftpui_show_busy (TRUE);
|
367
|
657 gftpui_common_run_callback_function (cdata);
|
775
|
658 gftpui_show_busy (FALSE);
|
367
|
659
|
|
660 g_free (cdata);
|
356
|
661
|
|
662 return (1);
|
|
663 }
|
|
664
|
|
665
|
|
666 static int
|
374
|
667 gftpui_common_cmd_set (void *uidata, gftp_request * request,
|
377
|
668 void *other_uidata, gftp_request * other_request,
|
374
|
669 const char *command)
|
341
|
670 {
|
387
|
671 char *pos, *backpos, buf[256];
|
341
|
672 gftp_config_vars * cv, newcv;
|
|
673 GList * templist;
|
|
674 int i;
|
|
675
|
|
676 if (command == NULL || *command == '\0')
|
|
677 {
|
|
678 for (templist = gftp_options_list;
|
|
679 templist != NULL;
|
|
680 templist = templist->next)
|
|
681 {
|
|
682 cv = templist->data;
|
|
683
|
|
684 for (i=0; cv[i].key != NULL; i++)
|
|
685 {
|
|
686 if (!(cv[i].ports_shown & GFTP_PORT_TEXT))
|
|
687 continue;
|
|
688
|
|
689 if (*cv[i].key == '\0' ||
|
|
690 gftp_option_types[cv[i].otype].write_function == NULL)
|
|
691 continue;
|
|
692
|
387
|
693 gftp_option_types[cv[i].otype].write_function (&cv[i], buf,
|
|
694 sizeof (buf), 0);
|
|
695
|
|
696 gftpui_common_logfunc (gftp_logging_misc_nolog, request,
|
|
697 "%s = %s\n", cv[i].key, buf);
|
341
|
698 }
|
|
699 }
|
|
700 }
|
|
701 else
|
|
702 {
|
|
703 if ((pos = strchr (command, '=')) == NULL)
|
|
704 {
|
374
|
705 gftpui_common_logfunc (gftp_logging_error, request,
|
|
706 _("usage: set [variable = value]\n"));
|
341
|
707 return (1);
|
|
708 }
|
|
709 *pos = '\0';
|
|
710
|
|
711 for (backpos = pos - 1;
|
|
712 (*backpos == ' ' || *backpos == '\t') && backpos > command;
|
|
713 backpos--)
|
|
714 *backpos = '\0';
|
|
715 for (++pos; *pos == ' ' || *pos == '\t'; pos++);
|
|
716
|
|
717 if ((cv = g_hash_table_lookup (gftp_global_options_htable, command)) == NULL)
|
|
718 {
|
374
|
719 gftpui_common_logfunc (gftp_logging_error, request,
|
|
720 _("Error: Variable %s is not a valid configuration variable.\n"), command);
|
341
|
721 return (1);
|
|
722 }
|
|
723
|
|
724 if (!(cv->ports_shown & GFTP_PORT_TEXT))
|
|
725 {
|
374
|
726 gftpui_common_logfunc (gftp_logging_error, request,
|
|
727 _("Error: Variable %s is not available in the text port of gFTP\n"), command);
|
341
|
728 return (1);
|
|
729 }
|
|
730
|
|
731 if (gftp_option_types[cv->otype].read_function != NULL)
|
|
732 {
|
|
733 memcpy (&newcv, cv, sizeof (newcv));
|
|
734 newcv.flags &= ~GFTP_CVARS_FLAGS_DYNMEM;
|
|
735
|
|
736 gftp_option_types[cv->otype].read_function (pos, &newcv, 1);
|
|
737
|
|
738 gftp_set_global_option (command, newcv.value);
|
|
739
|
387
|
740 gftp_option_types[newcv.otype].write_function (&newcv, buf,
|
|
741 sizeof (buf), 0);
|
|
742
|
|
743 gftpui_common_logfunc (gftp_logging_misc_nolog, request,
|
|
744 "%s = %s\n", newcv.key, buf);
|
|
745
|
341
|
746 if (newcv.flags & GFTP_CVARS_FLAGS_DYNMEM)
|
|
747 g_free (newcv.value);
|
574
|
748
|
|
749 gftp_configuration_changed = 1;
|
341
|
750 }
|
|
751 }
|
|
752
|
|
753 return (1);
|
|
754 }
|
|
755
|
|
756
|
|
757 static int
|
374
|
758 gftpui_common_cmd_help (void *uidata, gftp_request * request,
|
377
|
759 void *other_uidata, gftp_request * other_request,
|
374
|
760 const char *command)
|
341
|
761 {
|
374
|
762 int i, j, ele, numrows, numcols = 6, handled, number_commands, cmdlen,
|
|
763 found;
|
387
|
764 char commands[128], cmdstr[30];
|
374
|
765 const char *pos;
|
341
|
766
|
|
767 for (number_commands=0;
|
|
768 gftpui_common_commands[number_commands].command != NULL;
|
|
769 number_commands++);
|
|
770
|
|
771 if (command != NULL && *command != '\0')
|
|
772 {
|
|
773 for (pos = command; *pos != ' ' && *pos != '\0'; pos++);
|
374
|
774 cmdlen = pos - command;
|
341
|
775
|
|
776 for (i=0; gftpui_common_commands[i].command != NULL; i++)
|
|
777 {
|
374
|
778 if (strncmp (gftpui_common_commands[i].command, command, cmdlen) == 0)
|
341
|
779 break;
|
|
780 }
|
|
781
|
|
782 if (gftpui_common_commands[i].cmd_description != NULL)
|
|
783 {
|
374
|
784 found = 1;
|
|
785
|
|
786 if (*pos != '\0' && *(pos + 1) != '\0' &&
|
|
787 gftpui_common_commands[i].subhelp_func != NULL)
|
|
788 handled = gftpui_common_commands[i].subhelp_func (pos + 1);
|
341
|
789 else
|
|
790 handled = 0;
|
|
791
|
|
792 if (!handled)
|
387
|
793 gftpui_common_logfunc (gftp_logging_misc_nolog, request, "%s\n",
|
|
794 _(gftpui_common_commands[i].cmd_description));
|
341
|
795 }
|
|
796 else
|
374
|
797 found = 0;
|
341
|
798 }
|
374
|
799 else
|
|
800 found = 0;
|
341
|
801
|
374
|
802 if (!found)
|
341
|
803 {
|
|
804 numrows = number_commands / numcols;
|
|
805 if (number_commands % numcols != 0)
|
|
806 numrows++;
|
|
807
|
387
|
808 gftpui_common_logfunc (gftp_logging_misc_nolog, request,
|
|
809 _("Supported commands:\n\n"));
|
|
810
|
341
|
811 for (i=0; i<numrows; i++)
|
|
812 {
|
387
|
813 strncpy (commands, "\t", sizeof (commands));
|
970
|
814 size_t cmd_len = sizeof(commands) - strlen (commands);
|
387
|
815
|
341
|
816 for (j=0; j<numcols; j++)
|
|
817 {
|
|
818 ele = i + j * numrows;
|
|
819 if (ele >= number_commands)
|
|
820 break;
|
387
|
821
|
|
822 g_snprintf (cmdstr, sizeof (cmdstr), "%-10s",
|
|
823 gftpui_common_commands[ele].command);
|
970
|
824 strncat (commands, cmdstr, cmd_len);
|
|
825 cmd_len -= strlen(cmdstr);
|
341
|
826 }
|
387
|
827 gftpui_common_logfunc (gftp_logging_misc_nolog, request, "%s\n",
|
|
828 commands);
|
341
|
829 }
|
|
830 }
|
|
831 return (1);
|
|
832 }
|
|
833
|
|
834
|
377
|
835 static void
|
825
|
836 _gftpui_common_cmd_transfer_files (void *fromuidata, gftp_request * fromrequest,
|
|
837 void *touidata, gftp_request * torequest,
|
|
838 const char *cmd, const char *filespec)
|
377
|
839 {
|
|
840 gftp_transfer * tdata;
|
|
841 gftp_file * fle;
|
|
842
|
|
843 if (!GFTP_IS_CONNECTED (fromrequest) ||
|
|
844 !GFTP_IS_CONNECTED (torequest))
|
|
845 {
|
|
846 fromrequest->logging_function (gftp_logging_error, fromrequest,
|
|
847 _("Error: Not connected to a remote site\n"));
|
|
848 return;
|
|
849 }
|
|
850
|
|
851 if (*filespec == '\0')
|
|
852 {
|
|
853 fromrequest->logging_function (gftp_logging_error, fromrequest,
|
|
854 _("usage: %s <filespec>\n"), cmd);
|
|
855 return;
|
|
856 }
|
|
857
|
|
858 tdata = gftp_tdata_new ();
|
|
859 tdata->fromreq = fromrequest;
|
|
860 tdata->toreq = torequest;
|
|
861
|
|
862 if (gftp_list_files (tdata->fromreq) != 0)
|
|
863 {
|
|
864 tdata->fromreq = tdata->toreq = NULL;
|
|
865 free_tdata (tdata);
|
|
866 return;
|
|
867 }
|
|
868
|
|
869 fle = g_malloc0 (sizeof (*fle));
|
|
870 while (gftp_get_next_file (tdata->fromreq, filespec, fle) > 0)
|
|
871 {
|
|
872 if (strcmp (fle->file, ".") == 0 || strcmp (fle->file, "..") == 0)
|
|
873 {
|
598
|
874 gftp_file_destroy (fle, 0);
|
377
|
875 continue;
|
|
876 }
|
|
877
|
|
878 tdata->files = g_list_append (tdata->files, fle);
|
941
|
879 fle = g_malloc0 (sizeof (*fle));
|
377
|
880 }
|
|
881
|
|
882 g_free (fle);
|
|
883
|
|
884 gftp_end_transfer (tdata->fromreq);
|
|
885
|
|
886 if (tdata->files == NULL)
|
|
887 {
|
|
888 tdata->fromreq = tdata->toreq = NULL;
|
|
889 free_tdata (tdata);
|
|
890 return;
|
|
891 }
|
|
892
|
|
893 if (gftp_get_all_subdirs (tdata, NULL) != 0)
|
|
894 {
|
|
895 tdata->fromreq = tdata->toreq = NULL;
|
|
896 free_tdata (tdata);
|
|
897 return;
|
|
898 }
|
|
899
|
|
900 if (tdata->files == NULL)
|
|
901 {
|
|
902 tdata->fromreq = tdata->toreq = NULL;
|
|
903 free_tdata (tdata);
|
|
904 return;
|
|
905 }
|
|
906
|
|
907 gftpui_common_add_file_transfer (tdata->fromreq, tdata->toreq,
|
|
908 fromuidata, touidata, tdata->files);
|
|
909
|
|
910 g_free (tdata);
|
|
911
|
|
912 return;
|
|
913 }
|
|
914
|
|
915
|
|
916 int
|
|
917 gftpui_common_cmd_mget_file (void *uidata, gftp_request * request,
|
|
918 void *other_uidata, gftp_request * other_request,
|
|
919 const char *command)
|
|
920 {
|
825
|
921 _gftpui_common_cmd_transfer_files (uidata, request, other_uidata,
|
|
922 other_request, "mget", command);
|
377
|
923 return (1);
|
|
924 }
|
|
925
|
|
926
|
|
927 int
|
|
928 gftpui_common_cmd_mput_file (void *uidata, gftp_request * request,
|
|
929 void *other_uidata, gftp_request * other_request,
|
|
930 const char *command)
|
|
931 {
|
825
|
932 _gftpui_common_cmd_transfer_files (other_uidata, other_request, uidata,
|
|
933 request, "mput", command);
|
377
|
934 return (1);
|
|
935 }
|
|
936
|
|
937
|
341
|
938 gftpui_common_methods gftpui_common_commands[] = {
|
|
939 {N_("about"), 2, gftpui_common_cmd_about, gftpui_common_request_none,
|
|
940 N_("Shows gFTP information"), NULL},
|
|
941 {N_("ascii"), 2, gftpui_common_cmd_ascii, gftpui_common_request_remote,
|
|
942 N_("Sets the current file transfer mode to Ascii (only for FTP)"), NULL},
|
|
943 {N_("binary"), 1, gftpui_common_cmd_binary, gftpui_common_request_remote,
|
|
944 N_("Sets the current file transfer mode to Binary (only for FTP)"), NULL},
|
|
945 {N_("cd"), 2, gftpui_common_cmd_chdir, gftpui_common_request_remote,
|
|
946 N_("Changes the remote working directory"), NULL},
|
|
947 {N_("chdir"), 3, gftpui_common_cmd_chdir, gftpui_common_request_remote,
|
|
948 N_("Changes the remote working directory"), NULL},
|
|
949 {N_("chmod"), 3, gftpui_common_cmd_chmod, gftpui_common_request_remote,
|
|
950 N_("Changes the permissions of a remote file"), NULL},
|
|
951 {N_("clear"), 3, gftpui_common_cmd_clear, gftpui_common_request_none,
|
|
952 N_("Available options: cache"), gftpui_common_clear_show_subhelp},
|
|
953 {N_("close"), 3, gftpui_common_cmd_close, gftpui_common_request_remote,
|
|
954 N_("Disconnects from the remote site"), NULL},
|
350
|
955 {N_("delete"), 1, gftpui_common_cmd_delete, gftpui_common_request_remote,
|
341
|
956 N_("Removes a remote file"), NULL},
|
651
|
957 {N_("dir"), 3, gftpui_common_cmd_ls, gftpui_common_request_remote,
|
|
958 N_("Shows the directory listing for the current remote directory"), NULL},
|
377
|
959 {N_("get"), 1, gftpui_common_cmd_mget_file, gftpui_common_request_remote,
|
341
|
960 N_("Downloads remote file(s)"), NULL},
|
|
961 {N_("help"), 1, gftpui_common_cmd_help, gftpui_common_request_none,
|
|
962 N_("Shows this help screen"), NULL},
|
|
963 {N_("lcd"), 3, gftpui_common_cmd_chdir, gftpui_common_request_local,
|
|
964 N_("Changes the local working directory"), NULL},
|
|
965 {N_("lchdir"), 4, gftpui_common_cmd_chdir, gftpui_common_request_local,
|
|
966 N_("Changes the local working directory"), NULL},
|
|
967 {N_("lchmod"), 4, gftpui_common_cmd_chmod, gftpui_common_request_local,
|
|
968 N_("Changes the permissions of a local file"), NULL},
|
|
969 {N_("ldelete"), 2, gftpui_common_cmd_delete, gftpui_common_request_local,
|
|
970 N_("Removes a local file"), NULL},
|
651
|
971 {N_("ldir"), 4, gftpui_common_cmd_ls, gftpui_common_request_local,
|
|
972 N_("Shows the directory listing for the current local directory"), NULL},
|
341
|
973 {N_("lls"), 2, gftpui_common_cmd_ls, gftpui_common_request_local,
|
|
974 N_("Shows the directory listing for the current local directory"), NULL},
|
|
975 {N_("lmkdir"), 2, gftpui_common_cmd_mkdir, gftpui_common_request_local,
|
|
976 N_("Creates a local directory"), NULL},
|
|
977 {N_("lpwd"), 2, gftpui_common_cmd_pwd, gftpui_common_request_local,
|
|
978 N_("Show current local directory"), NULL},
|
|
979 {N_("lrename"), 3, gftpui_common_cmd_rename, gftpui_common_request_local,
|
|
980 N_("Rename a local file"), NULL},
|
|
981 {N_("lrmdir"), 3, gftpui_common_cmd_rmdir, gftpui_common_request_local,
|
|
982 N_("Remove a local directory"), NULL},
|
|
983 {N_("ls"), 2, gftpui_common_cmd_ls, gftpui_common_request_remote,
|
|
984 N_("Shows the directory listing for the current remote directory"), NULL},
|
377
|
985 {N_("mget"), 2, gftpui_common_cmd_mget_file, gftpui_common_request_remote,
|
341
|
986 N_("Downloads remote file(s)"), NULL},
|
377
|
987 {N_("mkdir"), 2, gftpui_common_cmd_mkdir, gftpui_common_request_remote,
|
341
|
988 N_("Creates a remote directory"), NULL},
|
377
|
989 {N_("mput"), 2, gftpui_common_cmd_mput_file, gftpui_common_request_remote,
|
341
|
990 N_("Uploads local file(s)"), NULL},
|
356
|
991 {N_("open"), 1, gftpui_common_cmd_open, gftpui_common_request_remote,
|
341
|
992 N_("Opens a connection to a remote site"), NULL},
|
377
|
993 {N_("put"), 2, gftpui_common_cmd_mput_file, gftpui_common_request_remote,
|
341
|
994 N_("Uploads local file(s)"), NULL},
|
|
995 {N_("pwd"), 2, gftpui_common_cmd_pwd, gftpui_common_request_remote,
|
|
996 N_("Show current remote directory"), NULL},
|
|
997 {N_("quit"), 1, gftpui_common_cmd_quit, gftpui_common_request_none,
|
|
998 N_("Exit from gFTP"), NULL},
|
|
999 {N_("rename"), 2, gftpui_common_cmd_rename, gftpui_common_request_remote,
|
|
1000 N_("Rename a remote file"), NULL},
|
|
1001 {N_("rmdir"), 2, gftpui_common_cmd_rmdir, gftpui_common_request_remote,
|
|
1002 N_("Remove a remote directory"), NULL},
|
|
1003 {N_("set"), 1, gftpui_common_cmd_set, gftpui_common_request_none,
|
377
|
1004 N_("Show configuration file variables. You can also set variables by set var=val"),
|
|
1005 gftpui_common_set_show_subhelp},
|
350
|
1006 {N_("site"), 2, gftpui_common_cmd_site, gftpui_common_request_remote,
|
|
1007 N_("Run a site specific command"), NULL},
|
341
|
1008 {NULL, 0, NULL, gftpui_common_request_none,
|
|
1009 NULL, NULL}};
|
|
1010
|
|
1011
|
|
1012 int
|
374
|
1013 gftpui_common_process_command (void *locui, gftp_request * locreq,
|
|
1014 void *remui, gftp_request * remreq,
|
|
1015 const char *command)
|
341
|
1016 {
|
377
|
1017 gftp_request * request, * other_request;
|
|
1018 void *uidata, *other_uidata;
|
341
|
1019 char *pos, *newstr;
|
377
|
1020 const char *stpos;
|
341
|
1021 size_t cmdlen;
|
|
1022 int ret, i;
|
|
1023 size_t len;
|
|
1024
|
|
1025 for (stpos = command; *stpos == ' ' || *stpos == '\t'; stpos++);
|
|
1026
|
|
1027 newstr = g_strdup (stpos);
|
|
1028 len = strlen (newstr);
|
|
1029
|
|
1030 if (len > 0 && newstr[len - 1] == '\n')
|
|
1031 newstr[--len] = '\0';
|
|
1032 if (len > 0 && newstr[len - 1] == '\r')
|
|
1033 newstr[--len] = '\0';
|
|
1034
|
|
1035 for (pos = newstr + len - 1;
|
841
|
1036 (*pos == ' ' || *pos == '\t') && pos > newstr;
|
|
1037 *pos-- = '\0');
|
341
|
1038
|
841
|
1039 if (*newstr == '\0')
|
341
|
1040 {
|
|
1041 g_free (newstr);
|
|
1042 return (1);
|
|
1043 }
|
|
1044
|
|
1045 if ((pos = strchr (newstr, ' ')) != NULL)
|
|
1046 *pos = '\0';
|
|
1047
|
|
1048 cmdlen = strlen (newstr);
|
|
1049 for (i=0; gftpui_common_commands[i].command != NULL; i++)
|
|
1050 {
|
|
1051 if (strcmp (gftpui_common_commands[i].command, newstr) == 0)
|
|
1052 break;
|
|
1053 else if (cmdlen >= gftpui_common_commands[i].minlen &&
|
|
1054 strncmp (gftpui_common_commands[i].command, newstr, cmdlen) == 0)
|
|
1055 break;
|
|
1056 }
|
|
1057
|
|
1058 if (pos != NULL)
|
|
1059 pos++;
|
|
1060 else
|
|
1061 pos = "";
|
|
1062
|
374
|
1063 if (gftpui_common_commands[i].reqtype == gftpui_common_request_local)
|
|
1064 {
|
|
1065 request = locreq;
|
|
1066 uidata = locui;
|
377
|
1067
|
|
1068 other_request = remreq;
|
|
1069 other_uidata = remui;
|
374
|
1070 }
|
|
1071 else if (gftpui_common_commands[i].reqtype == gftpui_common_request_remote)
|
|
1072 {
|
|
1073 request = remreq;
|
|
1074 uidata = remui;
|
377
|
1075
|
|
1076 other_request = locreq;
|
|
1077 other_uidata = locui;
|
374
|
1078 }
|
|
1079 else
|
|
1080 {
|
377
|
1081 request = other_request = NULL;
|
|
1082 uidata = other_uidata = NULL;
|
374
|
1083 }
|
|
1084
|
341
|
1085 if (gftpui_common_commands[i].command != NULL)
|
|
1086 {
|
377
|
1087 ret = gftpui_common_commands[i].func (uidata, request,
|
|
1088 other_uidata, other_request, pos);
|
380
|
1089
|
387
|
1090 if (request != NULL && !GFTP_IS_CONNECTED (request))
|
380
|
1091 gftpui_disconnect (uidata);
|
341
|
1092 }
|
|
1093 else
|
|
1094 {
|
374
|
1095 gftpui_common_logfunc (gftp_logging_error, request,
|
|
1096 _("Error: Command not recognized\n"));
|
341
|
1097 ret = 1;
|
|
1098 }
|
|
1099
|
|
1100 g_free (newstr);
|
|
1101 return (ret);
|
|
1102 }
|
|
1103
|
367
|
1104
|
|
1105 gftp_transfer *
|
|
1106 gftpui_common_add_file_transfer (gftp_request * fromreq, gftp_request * toreq,
|
|
1107 void *fromuidata, void *touidata,
|
|
1108 GList * files)
|
|
1109 {
|
795
|
1110 intptr_t append_transfers, one_transfer, overwrite_default;
|
367
|
1111 GList * templist, *curfle;
|
|
1112 gftp_transfer * tdata;
|
|
1113 gftp_file * tempfle;
|
|
1114 int show_dialog;
|
|
1115
|
795
|
1116 gftp_lookup_request_option (fromreq, "overwrite_default", &overwrite_default);
|
|
1117 gftp_lookup_request_option (fromreq, "append_transfers", &append_transfers);
|
|
1118 gftp_lookup_request_option (fromreq, "one_transfer", &one_transfer);
|
|
1119
|
|
1120 if (!overwrite_default)
|
|
1121 {
|
|
1122 for (templist = files; templist != NULL; templist = templist->next)
|
|
1123 {
|
|
1124 tempfle = templist->data;
|
918
|
1125 if (tempfle->startsize > 0 && !S_ISDIR (tempfle->st_mode))
|
795
|
1126 break;
|
|
1127 }
|
|
1128
|
|
1129 show_dialog = templist != NULL;
|
367
|
1130 }
|
795
|
1131 else
|
|
1132 show_dialog = 0;
|
367
|
1133
|
|
1134 tdata = NULL;
|
|
1135 if (append_transfers && one_transfer && !show_dialog)
|
|
1136 {
|
|
1137 if (g_thread_supported ())
|
|
1138 g_static_mutex_lock (&gftpui_common_transfer_mutex);
|
|
1139
|
|
1140 for (templist = gftp_file_transfers;
|
|
1141 templist != NULL;
|
|
1142 templist = templist->next)
|
|
1143 {
|
|
1144 tdata = templist->data;
|
|
1145
|
|
1146 if (g_thread_supported ())
|
|
1147 g_static_mutex_lock (&tdata->structmutex);
|
|
1148
|
|
1149 if (!compare_request (tdata->fromreq, fromreq, 0) ||
|
|
1150 !compare_request (tdata->toreq, toreq, 0) ||
|
|
1151 tdata->curfle == NULL)
|
|
1152 {
|
|
1153 if (g_thread_supported ())
|
|
1154 g_static_mutex_unlock (&tdata->structmutex);
|
|
1155
|
|
1156 continue;
|
|
1157 }
|
|
1158
|
|
1159 tdata->files = g_list_concat (tdata->files, files);
|
|
1160
|
|
1161 for (curfle = files; curfle != NULL; curfle = curfle->next)
|
|
1162 {
|
|
1163 tempfle = curfle->data;
|
|
1164
|
499
|
1165 if (S_ISDIR (tempfle->st_mode))
|
367
|
1166 tdata->numdirs++;
|
|
1167 else
|
|
1168 tdata->numfiles++;
|
|
1169
|
|
1170 if (tempfle->transfer_action != GFTP_TRANS_ACTION_SKIP)
|
|
1171 tdata->total_bytes += tempfle->size;
|
|
1172
|
397
|
1173 gftpui_add_file_to_transfer (tdata, curfle);
|
367
|
1174 }
|
|
1175
|
|
1176 if (g_thread_supported ())
|
|
1177 g_static_mutex_unlock (&tdata->structmutex);
|
|
1178
|
|
1179 break;
|
|
1180 }
|
|
1181
|
|
1182 if (g_thread_supported ())
|
|
1183 g_static_mutex_unlock (&gftpui_common_transfer_mutex);
|
|
1184 }
|
|
1185 else
|
|
1186 templist = NULL;
|
|
1187
|
|
1188 if (templist == NULL)
|
|
1189 {
|
|
1190 tdata = gftp_tdata_new ();
|
368
|
1191 tdata->fromreq = gftp_copy_request (fromreq);
|
|
1192 tdata->toreq = gftp_copy_request (toreq);
|
367
|
1193
|
|
1194 tdata->fromwdata = fromuidata;
|
|
1195 tdata->towdata = touidata;
|
|
1196
|
|
1197 if (!show_dialog)
|
|
1198 tdata->show = tdata->ready = 1;
|
|
1199
|
|
1200 tdata->files = files;
|
|
1201 for (curfle = files; curfle != NULL; curfle = curfle->next)
|
|
1202 {
|
|
1203 tempfle = curfle->data;
|
499
|
1204 if (S_ISDIR (tempfle->st_mode))
|
367
|
1205 tdata->numdirs++;
|
|
1206 else
|
|
1207 tdata->numfiles++;
|
|
1208
|
|
1209 if (tempfle->transfer_action != GFTP_TRANS_ACTION_SKIP)
|
|
1210 tdata->total_bytes += tempfle->size;
|
|
1211 }
|
|
1212
|
|
1213 if (g_thread_supported ())
|
|
1214 g_static_mutex_lock (&gftpui_common_transfer_mutex);
|
|
1215
|
|
1216 gftp_file_transfers = g_list_append (gftp_file_transfers, tdata);
|
|
1217
|
|
1218 if (g_thread_supported ())
|
|
1219 g_static_mutex_unlock (&gftpui_common_transfer_mutex);
|
|
1220
|
|
1221 if (show_dialog)
|
|
1222 gftpui_ask_transfer (tdata);
|
|
1223 }
|
|
1224
|
377
|
1225 gftpui_start_transfer (tdata);
|
367
|
1226 return (tdata);
|
|
1227 }
|
|
1228
|
|
1229
|
862
|
1230 static ssize_t
|
|
1231 _do_transfer_block (gftp_transfer * tdata, gftp_file * curfle, char *buf,
|
|
1232 size_t trans_blksize)
|
|
1233 {
|
|
1234 ssize_t num_read, num_wrote, ret;
|
|
1235 char *bufpos;
|
|
1236
|
|
1237 num_read = gftp_get_next_file_chunk (tdata->fromreq, buf, trans_blksize);
|
|
1238 if (num_read < 0)
|
|
1239 return (num_read);
|
|
1240
|
|
1241 bufpos = buf;
|
|
1242 num_wrote = 0;
|
|
1243 while (num_wrote < num_read)
|
|
1244 {
|
|
1245 if ((ret = gftp_put_next_file_chunk (tdata->toreq, bufpos,
|
|
1246 num_read - num_wrote)) <= 0)
|
|
1247 return (ret);
|
|
1248
|
|
1249 num_wrote += ret;
|
|
1250 bufpos += ret;
|
|
1251 }
|
|
1252
|
|
1253 return (num_read);
|
|
1254 }
|
|
1255
|
|
1256
|
367
|
1257 int
|
825
|
1258 _gftpui_common_do_transfer_file (gftp_transfer * tdata, gftp_file * curfle)
|
367
|
1259 {
|
377
|
1260 struct timeval updatetime;
|
811
|
1261 intptr_t trans_blksize;
|
862
|
1262 ssize_t num_trans;
|
|
1263 char *buf;
|
|
1264 int ret;
|
527
|
1265
|
|
1266 gftp_lookup_request_option (tdata->fromreq, "trans_blksize", &trans_blksize);
|
941
|
1267 buf = g_malloc0 (trans_blksize);
|
367
|
1268
|
811
|
1269 memset (&updatetime, 0, sizeof (updatetime));
|
|
1270 gftpui_start_current_file_in_transfer (tdata);
|
|
1271
|
862
|
1272 num_trans = 0;
|
811
|
1273 while (!tdata->cancel &&
|
862
|
1274 (num_trans = _do_transfer_block (tdata, curfle, buf,
|
|
1275 trans_blksize)) > 0)
|
811
|
1276 {
|
862
|
1277 gftp_calc_kbs (tdata, num_trans);
|
|
1278
|
811
|
1279 if (tdata->lasttime.tv_sec - updatetime.tv_sec >= 1 ||
|
|
1280 tdata->curtrans >= tdata->tot_file_trans)
|
|
1281 {
|
|
1282 gftpui_update_current_file_in_transfer (tdata);
|
|
1283 memcpy (&updatetime, &tdata->lasttime, sizeof (updatetime));
|
|
1284
|
862
|
1285 if (tdata->current_file_retries > 0)
|
|
1286 tdata->current_file_retries = 0;
|
811
|
1287 }
|
|
1288 }
|
|
1289
|
862
|
1290 if (num_trans == GFTP_ENOTRANS)
|
|
1291 num_trans = 0;
|
811
|
1292
|
|
1293 g_free (buf);
|
|
1294 gftpui_finish_current_file_in_transfer (tdata);
|
|
1295
|
862
|
1296 if ((int) num_trans == 0)
|
825
|
1297 {
|
|
1298 if ((ret = gftp_end_transfer (tdata->fromreq)) < 0)
|
|
1299 return (ret);
|
|
1300
|
|
1301 if ((ret = gftp_end_transfer (tdata->toreq)) < 0)
|
|
1302 return (ret);
|
|
1303
|
|
1304 tdata->fromreq->logging_function (gftp_logging_misc,
|
|
1305 tdata->fromreq,
|
|
1306 _("Successfully transferred %s at %.2f KB/s\n"),
|
|
1307 curfle->file, tdata->kbs);
|
|
1308
|
|
1309 return (0);
|
|
1310 }
|
|
1311 else
|
862
|
1312 return ((int) num_trans);
|
811
|
1313 }
|
|
1314
|
|
1315
|
819
|
1316 void
|
|
1317 gftpui_common_skip_file_transfer (gftp_transfer * tdata, gftp_file * curfle)
|
|
1318 {
|
|
1319 g_static_mutex_lock (&tdata->structmutex);
|
|
1320
|
|
1321 if (tdata->started && !(curfle->transfer_action & GFTP_TRANS_ACTION_SKIP))
|
|
1322 {
|
|
1323 curfle->transfer_action = GFTP_TRANS_ACTION_SKIP;
|
|
1324 if (tdata->curfle != NULL && curfle == tdata->curfle->data)
|
|
1325 {
|
876
|
1326 gftpui_cancel_file_transfer (tdata);
|
819
|
1327 tdata->skip_file = 1;
|
|
1328 }
|
|
1329 else if (!curfle->transfer_done)
|
|
1330 tdata->total_bytes -= curfle->size;
|
|
1331 }
|
|
1332
|
|
1333 g_static_mutex_unlock (&tdata->structmutex);
|
|
1334
|
|
1335 if (curfle != NULL)
|
|
1336 tdata->fromreq->logging_function (gftp_logging_misc, tdata->fromreq,
|
|
1337 _("Skipping file %s on host %s\n"),
|
|
1338 curfle->file, tdata->toreq->hostname);
|
|
1339 }
|
|
1340
|
|
1341
|
|
1342 void
|
|
1343 gftpui_common_cancel_file_transfer (gftp_transfer * tdata)
|
|
1344 {
|
|
1345 g_static_mutex_lock (&tdata->structmutex);
|
|
1346
|
|
1347 if (tdata->started)
|
|
1348 {
|
876
|
1349 gftpui_cancel_file_transfer (tdata);
|
819
|
1350 tdata->skip_file = 0;
|
|
1351 }
|
|
1352 else
|
|
1353 tdata->done = 1;
|
|
1354
|
|
1355 tdata->fromreq->stopable = 0;
|
|
1356 tdata->toreq->stopable = 0;
|
|
1357
|
|
1358 g_static_mutex_unlock (&tdata->structmutex);
|
|
1359
|
|
1360 tdata->fromreq->logging_function (gftp_logging_misc, tdata->fromreq,
|
|
1361 _("Stopping the transfer on host %s\n"),
|
|
1362 tdata->toreq->hostname);
|
|
1363 }
|
|
1364
|
|
1365
|
838
|
1366 static void
|
825
|
1367 _gftpui_common_next_file_in_trans (gftp_transfer * tdata)
|
|
1368 {
|
|
1369 gftp_file * curfle;
|
|
1370
|
|
1371 if (g_thread_supported ())
|
|
1372 g_static_mutex_lock (&tdata->structmutex);
|
|
1373
|
|
1374 tdata->curtrans = 0;
|
|
1375 tdata->next_file = 1;
|
|
1376
|
|
1377 curfle = tdata->curfle->data;
|
|
1378 curfle->transfer_done = 1;
|
|
1379 tdata->curfle = tdata->curfle->next;
|
|
1380
|
|
1381 if (g_thread_supported ())
|
|
1382 g_static_mutex_unlock (&tdata->structmutex);
|
|
1383 }
|
|
1384
|
|
1385
|
|
1386 static int
|
|
1387 _gftpui_common_preserve_perm_time (gftp_transfer * tdata, gftp_file * curfle)
|
811
|
1388 {
|
|
1389 intptr_t preserve_permissions, preserve_time;
|
825
|
1390 int ret, tmpret;
|
367
|
1391
|
774
|
1392 gftp_lookup_request_option (tdata->fromreq, "preserve_permissions",
|
|
1393 &preserve_permissions);
|
|
1394 gftp_lookup_request_option (tdata->fromreq, "preserve_time",
|
|
1395 &preserve_time);
|
|
1396
|
825
|
1397 ret = 0;
|
|
1398 if (GFTP_IS_CONNECTED (tdata->toreq) && preserve_permissions &&
|
|
1399 curfle->st_mode != 0)
|
367
|
1400 {
|
825
|
1401 tmpret = gftp_chmod (tdata->toreq, curfle->destfile,
|
|
1402 curfle->st_mode & (S_IRWXU | S_IRWXG | S_IRWXO));
|
|
1403 if (tmpret < 0)
|
|
1404 ret = tmpret;
|
|
1405 }
|
367
|
1406
|
825
|
1407 if (GFTP_IS_CONNECTED (tdata->toreq) && preserve_time &&
|
|
1408 curfle->datetime != 0)
|
|
1409 {
|
|
1410 tmpret = gftp_set_file_time (tdata->toreq, curfle->destfile,
|
|
1411 curfle->datetime);
|
|
1412 if (tmpret < 0)
|
|
1413 ret = tmpret;
|
|
1414 }
|
367
|
1415
|
825
|
1416 if (!GFTP_IS_CONNECTED (tdata->toreq))
|
|
1417 return (ret);
|
|
1418 else
|
|
1419 return (0);
|
|
1420 }
|
|
1421
|
367
|
1422
|
825
|
1423 static int
|
|
1424 _gftpui_common_trans_file_or_dir (gftp_transfer * tdata)
|
|
1425 {
|
862
|
1426 gftp_file * curfle;
|
894
|
1427 int ret;
|
825
|
1428
|
|
1429 if (g_thread_supported ())
|
|
1430 g_static_mutex_lock (&tdata->structmutex);
|
367
|
1431
|
825
|
1432 curfle = tdata->curfle->data;
|
|
1433 tdata->current_file_number++;
|
|
1434
|
|
1435 if (g_thread_supported ())
|
|
1436 g_static_mutex_unlock (&tdata->structmutex);
|
|
1437
|
|
1438 if (curfle->transfer_action == GFTP_TRANS_ACTION_SKIP)
|
|
1439 {
|
|
1440 tdata->tot_file_trans = 0;
|
|
1441 return (0);
|
|
1442 }
|
|
1443
|
|
1444 if ((ret = gftp_connect (tdata->fromreq)) < 0)
|
|
1445 return (ret);
|
|
1446
|
|
1447 if ((ret = gftp_connect (tdata->toreq)) < 0)
|
|
1448 return (ret);
|
367
|
1449
|
825
|
1450 if (S_ISDIR (curfle->st_mode))
|
|
1451 {
|
|
1452 tdata->tot_file_trans = 0;
|
918
|
1453 if (curfle->startsize > 0)
|
|
1454 ret = 1;
|
|
1455 else
|
|
1456 ret = gftp_make_directory (tdata->toreq, curfle->destfile);
|
825
|
1457 }
|
|
1458 else
|
|
1459 {
|
|
1460 if (curfle->size == 0)
|
|
1461 {
|
|
1462 curfle->size = gftp_get_file_size (tdata->fromreq, curfle->file);
|
862
|
1463 if (curfle->size < 0)
|
|
1464 return ((int) curfle->size);
|
377
|
1465
|
825
|
1466 tdata->total_bytes += curfle->size;
|
367
|
1467 }
|
|
1468
|
862
|
1469 if (curfle->retry_transfer)
|
|
1470 {
|
|
1471 curfle->transfer_action = GFTP_TRANS_ACTION_RESUME;
|
|
1472 curfle->startsize = gftp_get_file_size (tdata->toreq, curfle->destfile);
|
|
1473 if (curfle->startsize < 0)
|
|
1474 return ((int) curfle->startsize);
|
|
1475 }
|
|
1476
|
825
|
1477 tdata->tot_file_trans = gftp_transfer_file (tdata->fromreq, curfle->file,
|
|
1478 curfle->transfer_action == GFTP_TRANS_ACTION_RESUME ?
|
|
1479 curfle->startsize : 0,
|
895
|
1480 tdata->toreq, curfle->destfile,
|
825
|
1481 curfle->transfer_action == GFTP_TRANS_ACTION_RESUME ?
|
|
1482 curfle->startsize : 0);
|
|
1483 if (tdata->tot_file_trans < 0)
|
|
1484 ret = tdata->tot_file_trans;
|
367
|
1485 else
|
|
1486 {
|
|
1487 if (g_thread_supported ())
|
|
1488 g_static_mutex_lock (&tdata->structmutex);
|
|
1489
|
|
1490 tdata->curtrans = 0;
|
|
1491 tdata->curresumed = curfle->transfer_action == GFTP_TRANS_ACTION_RESUME ? curfle->startsize : 0;
|
|
1492 tdata->resumed_bytes += tdata->curresumed;
|
|
1493
|
|
1494 if (g_thread_supported ())
|
|
1495 g_static_mutex_unlock (&tdata->structmutex);
|
|
1496
|
825
|
1497 ret = _gftpui_common_do_transfer_file (tdata, curfle);
|
367
|
1498 }
|
825
|
1499 }
|
|
1500
|
|
1501 if (ret == 0)
|
894
|
1502 ret = _gftpui_common_preserve_perm_time (tdata, curfle);
|
825
|
1503 else
|
862
|
1504 {
|
|
1505 curfle->retry_transfer = 1;
|
|
1506 tdata->fromreq->logging_function (gftp_logging_error, tdata->fromreq,
|
|
1507 _("Could not download %s from %s\n"),
|
|
1508 curfle->file, tdata->fromreq->hostname);
|
|
1509 }
|
825
|
1510
|
|
1511 return (ret);
|
|
1512 }
|
|
1513
|
|
1514
|
|
1515 int
|
|
1516 gftpui_common_transfer_files (gftp_transfer * tdata)
|
|
1517 {
|
858
|
1518 int ret, skipped_files;
|
825
|
1519
|
|
1520 tdata->curfle = tdata->files;
|
876
|
1521 gftpui_common_num_child_threads++;
|
|
1522
|
825
|
1523 gettimeofday (&tdata->starttime, NULL);
|
|
1524 memcpy (&tdata->lasttime, &tdata->starttime, sizeof (tdata->lasttime));
|
|
1525
|
858
|
1526 skipped_files = 0;
|
825
|
1527 while (tdata->curfle != NULL)
|
|
1528 {
|
|
1529 ret = _gftpui_common_trans_file_or_dir (tdata);
|
367
|
1530 if (tdata->cancel)
|
|
1531 {
|
825
|
1532 if (gftp_abort_transfer (tdata->toreq) != 0)
|
|
1533 gftp_disconnect (tdata->toreq);
|
|
1534
|
367
|
1535 if (gftp_abort_transfer (tdata->fromreq) != 0)
|
|
1536 gftp_disconnect (tdata->fromreq);
|
|
1537 }
|
858
|
1538 else if (ret == GFTP_EFATAL)
|
|
1539 skipped_files++;
|
811
|
1540 else if (ret < 0)
|
367
|
1541 {
|
811
|
1542 if (gftp_get_transfer_status (tdata, ret) == GFTP_ERETRYABLE)
|
367
|
1543 continue;
|
|
1544
|
|
1545 break;
|
|
1546 }
|
|
1547
|
825
|
1548 _gftpui_common_next_file_in_trans (tdata);
|
367
|
1549
|
825
|
1550 if (tdata->cancel)
|
367
|
1551 {
|
825
|
1552 if (!tdata->skip_file)
|
|
1553 break;
|
367
|
1554
|
825
|
1555 tdata->cancel = 0;
|
|
1556 tdata->fromreq->cancel = 0;
|
|
1557 tdata->toreq->cancel = 0;
|
|
1558 }
|
367
|
1559 }
|
527
|
1560
|
858
|
1561 if (skipped_files)
|
|
1562 tdata->fromreq->logging_function (gftp_logging_error, tdata->fromreq,
|
|
1563 _("There were %d files or directories that could not be transferred. Check the log for which items were not properly transferred."),
|
|
1564 skipped_files);
|
|
1565
|
367
|
1566 tdata->done = 1;
|
876
|
1567 gftpui_common_num_child_threads--;
|
|
1568
|
387
|
1569 return (1);
|
367
|
1570 }
|
|
1571
|
469
|
1572
|
|
1573 void
|
|
1574 gftpui_protocol_update_timeout (gftp_request * request)
|
|
1575 {
|
|
1576 intptr_t network_timeout;
|
|
1577
|
|
1578 gftp_lookup_request_option (request, "network_timeout", &network_timeout);
|
|
1579
|
|
1580 if (network_timeout > 0)
|
|
1581 alarm (network_timeout);
|
|
1582 }
|
|
1583
|