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