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