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