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