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