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