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