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
|
811
|
1294 _do_transfer_file (gftp_transfer * tdata)
|
367
|
1295 {
|
377
|
1296 struct timeval updatetime;
|
811
|
1297 intptr_t trans_blksize;
|
377
|
1298 ssize_t num_read, ret;
|
811
|
1299 char *buf, *bufpos;
|
527
|
1300
|
|
1301 gftp_lookup_request_option (tdata->fromreq, "trans_blksize", &trans_blksize);
|
|
1302 buf = g_malloc (trans_blksize);
|
367
|
1303
|
811
|
1304 memset (&updatetime, 0, sizeof (updatetime));
|
|
1305 gftpui_start_current_file_in_transfer (tdata);
|
|
1306
|
|
1307 while (!tdata->cancel &&
|
|
1308 (num_read = gftp_get_next_file_chunk (tdata->fromreq, buf,
|
|
1309 trans_blksize)) > 0)
|
|
1310 {
|
|
1311 gftp_calc_kbs (tdata, num_read);
|
|
1312 if (tdata->lasttime.tv_sec - updatetime.tv_sec >= 1 ||
|
|
1313 tdata->curtrans >= tdata->tot_file_trans)
|
|
1314 {
|
|
1315 gftpui_update_current_file_in_transfer (tdata);
|
|
1316 memcpy (&updatetime, &tdata->lasttime, sizeof (updatetime));
|
|
1317 }
|
|
1318
|
|
1319 bufpos = buf;
|
|
1320 while (num_read > 0)
|
|
1321 {
|
|
1322 if ((ret = gftp_put_next_file_chunk (tdata->toreq, bufpos,
|
|
1323 num_read)) <= 0)
|
|
1324 {
|
|
1325 num_read = ret;
|
|
1326 break;
|
|
1327 }
|
|
1328
|
|
1329 num_read -= ret;
|
|
1330 bufpos += ret;
|
|
1331 }
|
|
1332 }
|
|
1333
|
|
1334 if (num_read == GFTP_ENOTRANS)
|
|
1335 num_read = 0;
|
|
1336
|
|
1337 g_free (buf);
|
|
1338 gftpui_finish_current_file_in_transfer (tdata);
|
|
1339
|
|
1340 return ((int) num_read);
|
|
1341 }
|
|
1342
|
|
1343
|
|
1344 int
|
|
1345 gftpui_common_transfer_files (gftp_transfer * tdata)
|
|
1346 {
|
|
1347 intptr_t preserve_permissions, preserve_time;
|
|
1348 gftp_file * curfle;
|
|
1349 int tofd, fromfd;
|
|
1350 int ret;
|
|
1351
|
367
|
1352 tdata->curfle = tdata->files;
|
|
1353 gettimeofday (&tdata->starttime, NULL);
|
377
|
1354 memcpy (&tdata->lasttime, &tdata->starttime, sizeof (tdata->lasttime));
|
367
|
1355
|
774
|
1356 gftp_lookup_request_option (tdata->fromreq, "preserve_permissions",
|
|
1357 &preserve_permissions);
|
|
1358 gftp_lookup_request_option (tdata->fromreq, "preserve_time",
|
|
1359 &preserve_time);
|
|
1360
|
367
|
1361 while (tdata->curfle != NULL)
|
|
1362 {
|
811
|
1363 ret = -1;
|
367
|
1364
|
|
1365 if (g_thread_supported ())
|
|
1366 g_static_mutex_lock (&tdata->structmutex);
|
|
1367
|
|
1368 curfle = tdata->curfle->data;
|
|
1369 tdata->current_file_number++;
|
|
1370
|
|
1371 if (g_thread_supported ())
|
|
1372 g_static_mutex_unlock (&tdata->structmutex);
|
|
1373
|
|
1374 if (curfle->transfer_action == GFTP_TRANS_ACTION_SKIP)
|
|
1375 {
|
|
1376 if (g_thread_supported ())
|
|
1377 g_static_mutex_lock (&tdata->structmutex);
|
|
1378
|
|
1379 tdata->next_file = 1;
|
|
1380 tdata->curfle = tdata->curfle->next;
|
|
1381
|
|
1382 if (g_thread_supported ())
|
|
1383 g_static_mutex_unlock (&tdata->structmutex);
|
377
|
1384
|
367
|
1385 continue;
|
|
1386 }
|
|
1387
|
377
|
1388 tdata->tot_file_trans = -1;
|
367
|
1389 if (gftp_connect (tdata->fromreq) == 0 &&
|
|
1390 gftp_connect (tdata->toreq) == 0)
|
|
1391 {
|
499
|
1392 if (S_ISDIR (curfle->st_mode))
|
367
|
1393 {
|
|
1394 if (tdata->toreq->mkdir != NULL)
|
|
1395 {
|
|
1396 tdata->toreq->mkdir (tdata->toreq, curfle->destfile);
|
|
1397 if (!GFTP_IS_CONNECTED (tdata->toreq))
|
|
1398 break;
|
774
|
1399
|
|
1400 if (preserve_permissions && curfle->st_mode != 0)
|
|
1401 gftp_chmod (tdata->toreq, curfle->destfile,
|
|
1402 curfle->st_mode & (S_IRWXU | S_IRWXG | S_IRWXO));
|
|
1403
|
|
1404 if (preserve_time && curfle->datetime != 0)
|
|
1405 gftp_set_file_time (tdata->toreq, curfle->destfile,
|
|
1406 curfle->datetime);
|
367
|
1407 }
|
|
1408
|
|
1409 if (g_thread_supported ())
|
|
1410 g_static_mutex_lock (&tdata->structmutex);
|
|
1411
|
|
1412 tdata->next_file = 1;
|
|
1413 tdata->curfle = tdata->curfle->next;
|
|
1414
|
|
1415 if (g_thread_supported ())
|
|
1416 g_static_mutex_unlock (&tdata->structmutex);
|
|
1417 continue;
|
|
1418 }
|
|
1419
|
|
1420 _gftpui_common_setup_fds (tdata, curfle, &fromfd, &tofd);
|
|
1421
|
|
1422 if (curfle->size == 0)
|
|
1423 {
|
|
1424 curfle->size = gftp_get_file_size (tdata->fromreq, curfle->file);
|
|
1425 tdata->total_bytes += curfle->size;
|
|
1426 }
|
|
1427
|
|
1428 if (GFTP_IS_CONNECTED (tdata->fromreq) &&
|
|
1429 GFTP_IS_CONNECTED (tdata->toreq))
|
|
1430 {
|
377
|
1431 tdata->tot_file_trans = gftp_transfer_file (tdata->fromreq,
|
|
1432 curfle->file, fromfd,
|
367
|
1433 curfle->transfer_action == GFTP_TRANS_ACTION_RESUME ?
|
|
1434 curfle->startsize : 0,
|
|
1435 tdata->toreq, curfle->destfile, tofd,
|
|
1436 curfle->transfer_action == GFTP_TRANS_ACTION_RESUME ?
|
|
1437 curfle->startsize : 0);
|
|
1438 }
|
|
1439 }
|
|
1440
|
|
1441 if (!GFTP_IS_CONNECTED (tdata->fromreq) ||
|
|
1442 !GFTP_IS_CONNECTED (tdata->toreq))
|
|
1443 {
|
677
|
1444 tdata->fromreq->logging_function (gftp_logging_error,
|
367
|
1445 tdata->fromreq,
|
377
|
1446 _("Error: Remote site disconnected after trying to transfer file\n"));
|
367
|
1447 }
|
377
|
1448 else if (tdata->tot_file_trans < 0)
|
367
|
1449 {
|
|
1450 if (g_thread_supported ())
|
|
1451 g_static_mutex_lock (&tdata->structmutex);
|
|
1452
|
|
1453 curfle->transfer_action = GFTP_TRANS_ACTION_SKIP;
|
|
1454 tdata->next_file = 1;
|
|
1455 tdata->curfle = tdata->curfle->next;
|
|
1456
|
|
1457 if (g_thread_supported ())
|
|
1458 g_static_mutex_unlock (&tdata->structmutex);
|
|
1459 continue;
|
|
1460 }
|
|
1461 else
|
|
1462 {
|
|
1463 if (g_thread_supported ())
|
|
1464 g_static_mutex_lock (&tdata->structmutex);
|
|
1465
|
|
1466 tdata->curtrans = 0;
|
|
1467 tdata->curresumed = curfle->transfer_action == GFTP_TRANS_ACTION_RESUME ? curfle->startsize : 0;
|
|
1468 tdata->resumed_bytes += tdata->curresumed;
|
|
1469
|
|
1470 if (g_thread_supported ())
|
|
1471 g_static_mutex_unlock (&tdata->structmutex);
|
|
1472
|
811
|
1473 ret = _do_transfer_file (tdata);
|
367
|
1474 }
|
|
1475
|
|
1476 if (tdata->cancel)
|
|
1477 {
|
|
1478 if (gftp_abort_transfer (tdata->fromreq) != 0)
|
|
1479 gftp_disconnect (tdata->fromreq);
|
|
1480
|
|
1481 if (gftp_abort_transfer (tdata->toreq) != 0)
|
|
1482 gftp_disconnect (tdata->toreq);
|
|
1483 }
|
811
|
1484 else if (ret < 0)
|
367
|
1485 {
|
677
|
1486 tdata->fromreq->logging_function (gftp_logging_error,
|
367
|
1487 tdata->fromreq,
|
|
1488 _("Could not download %s from %s\n"),
|
|
1489 curfle->file,
|
|
1490 tdata->fromreq->hostname);
|
|
1491
|
811
|
1492 if (gftp_get_transfer_status (tdata, ret) == GFTP_ERETRYABLE)
|
367
|
1493 continue;
|
|
1494
|
|
1495 break;
|
|
1496 }
|
|
1497 else
|
|
1498 {
|
|
1499 _gftpui_common_done_with_fds (tdata, curfle);
|
|
1500 if (gftp_end_transfer (tdata->fromreq) != 0)
|
|
1501 {
|
|
1502 if (gftp_get_transfer_status (tdata, -1) == GFTP_ERETRYABLE)
|
|
1503 continue;
|
|
1504
|
|
1505 break;
|
|
1506 }
|
|
1507
|
652
|
1508 if (gftp_end_transfer (tdata->toreq) == 0)
|
|
1509 {
|
|
1510 tdata->fromreq->logging_function (gftp_logging_misc,
|
|
1511 tdata->fromreq,
|
|
1512 _("Successfully transferred %s at %.2f KB/s\n"),
|
|
1513 curfle->file, tdata->kbs);
|
|
1514 }
|
|
1515 else
|
|
1516 {
|
|
1517 tdata->fromreq->logging_function (gftp_logging_error,
|
|
1518 tdata->fromreq,
|
|
1519 _("There was an error transfering the file %s"),
|
|
1520 curfle->file);
|
|
1521 }
|
367
|
1522 }
|
|
1523
|
560
|
1524 if (!curfle->is_fd)
|
367
|
1525 {
|
560
|
1526 if (preserve_permissions && curfle->st_mode != 0)
|
504
|
1527 gftp_chmod (tdata->toreq, curfle->destfile,
|
|
1528 curfle->st_mode & (S_IRWXU | S_IRWXG | S_IRWXO));
|
367
|
1529
|
560
|
1530 if (preserve_time && curfle->datetime != 0)
|
367
|
1531 gftp_set_file_time (tdata->toreq, curfle->destfile,
|
|
1532 curfle->datetime);
|
|
1533 }
|
|
1534
|
|
1535 if (g_thread_supported ())
|
|
1536 g_static_mutex_lock (&tdata->structmutex);
|
|
1537
|
|
1538 tdata->curtrans = 0;
|
|
1539 tdata->next_file = 1;
|
|
1540 curfle->transfer_done = 1;
|
|
1541 tdata->curfle = tdata->curfle->next;
|
|
1542
|
|
1543 if (g_thread_supported ())
|
|
1544 g_static_mutex_unlock (&tdata->structmutex);
|
|
1545
|
|
1546 if (tdata->cancel && !tdata->skip_file)
|
|
1547 break;
|
|
1548 tdata->cancel = 0;
|
|
1549 tdata->fromreq->cancel = 0;
|
|
1550 tdata->toreq->cancel = 0;
|
|
1551 }
|
527
|
1552
|
367
|
1553 tdata->done = 1;
|
|
1554
|
387
|
1555 return (1);
|
367
|
1556 }
|
|
1557
|
469
|
1558
|
|
1559 void
|
|
1560 gftpui_protocol_update_timeout (gftp_request * request)
|
|
1561 {
|
|
1562 intptr_t network_timeout;
|
|
1563
|
|
1564 gftp_lookup_request_option (request, "network_timeout", &network_timeout);
|
|
1565
|
|
1566 if (network_timeout > 0)
|
|
1567 alarm (network_timeout);
|
|
1568 }
|
|
1569
|