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