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