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