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);
|
830
|
624 tempstr = gftp_gen_ls_string (request, 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;
|
841
|
1059 (*pos == ' ' || *pos == '\t') && pos > newstr;
|
|
1060 *pos-- = '\0');
|
341
|
1061
|
841
|
1062 if (*newstr == '\0')
|
341
|
1063 {
|
|
1064 g_free (newstr);
|
|
1065 return (1);
|
|
1066 }
|
|
1067
|
|
1068 if ((pos = strchr (newstr, ' ')) != NULL)
|
|
1069 *pos = '\0';
|
|
1070
|
|
1071 cmdlen = strlen (newstr);
|
|
1072 for (i=0; gftpui_common_commands[i].command != NULL; i++)
|
|
1073 {
|
|
1074 if (strcmp (gftpui_common_commands[i].command, newstr) == 0)
|
|
1075 break;
|
|
1076 else if (cmdlen >= gftpui_common_commands[i].minlen &&
|
|
1077 strncmp (gftpui_common_commands[i].command, newstr, cmdlen) == 0)
|
|
1078 break;
|
|
1079 }
|
|
1080
|
|
1081 if (pos != NULL)
|
|
1082 pos++;
|
|
1083 else
|
|
1084 pos = "";
|
|
1085
|
374
|
1086 if (gftpui_common_commands[i].reqtype == gftpui_common_request_local)
|
|
1087 {
|
|
1088 request = locreq;
|
|
1089 uidata = locui;
|
377
|
1090
|
|
1091 other_request = remreq;
|
|
1092 other_uidata = remui;
|
374
|
1093 }
|
|
1094 else if (gftpui_common_commands[i].reqtype == gftpui_common_request_remote)
|
|
1095 {
|
|
1096 request = remreq;
|
|
1097 uidata = remui;
|
377
|
1098
|
|
1099 other_request = locreq;
|
|
1100 other_uidata = locui;
|
374
|
1101 }
|
|
1102 else
|
|
1103 {
|
377
|
1104 request = other_request = NULL;
|
|
1105 uidata = other_uidata = NULL;
|
374
|
1106 }
|
|
1107
|
341
|
1108 if (gftpui_common_commands[i].command != NULL)
|
|
1109 {
|
377
|
1110 ret = gftpui_common_commands[i].func (uidata, request,
|
|
1111 other_uidata, other_request, pos);
|
380
|
1112
|
387
|
1113 if (request != NULL && !GFTP_IS_CONNECTED (request))
|
380
|
1114 gftpui_disconnect (uidata);
|
341
|
1115 }
|
|
1116 else
|
|
1117 {
|
374
|
1118 gftpui_common_logfunc (gftp_logging_error, request,
|
|
1119 _("Error: Command not recognized\n"));
|
341
|
1120 ret = 1;
|
|
1121 }
|
|
1122
|
|
1123 g_free (newstr);
|
|
1124 return (ret);
|
|
1125 }
|
|
1126
|
367
|
1127
|
|
1128 gftp_transfer *
|
|
1129 gftpui_common_add_file_transfer (gftp_request * fromreq, gftp_request * toreq,
|
|
1130 void *fromuidata, void *touidata,
|
|
1131 GList * files)
|
|
1132 {
|
795
|
1133 intptr_t append_transfers, one_transfer, overwrite_default;
|
367
|
1134 GList * templist, *curfle;
|
|
1135 gftp_transfer * tdata;
|
|
1136 gftp_file * tempfle;
|
|
1137 int show_dialog;
|
|
1138
|
795
|
1139 gftp_lookup_request_option (fromreq, "overwrite_default", &overwrite_default);
|
|
1140 gftp_lookup_request_option (fromreq, "append_transfers", &append_transfers);
|
|
1141 gftp_lookup_request_option (fromreq, "one_transfer", &one_transfer);
|
|
1142
|
|
1143 if (!overwrite_default)
|
|
1144 {
|
|
1145 for (templist = files; templist != NULL; templist = templist->next)
|
|
1146 {
|
|
1147 tempfle = templist->data;
|
|
1148 if (tempfle->startsize > 0)
|
|
1149 break;
|
|
1150 }
|
|
1151
|
|
1152 show_dialog = templist != NULL;
|
367
|
1153 }
|
795
|
1154 else
|
|
1155 show_dialog = 0;
|
367
|
1156
|
|
1157 tdata = NULL;
|
|
1158 if (append_transfers && one_transfer && !show_dialog)
|
|
1159 {
|
|
1160 if (g_thread_supported ())
|
|
1161 g_static_mutex_lock (&gftpui_common_transfer_mutex);
|
|
1162
|
|
1163 for (templist = gftp_file_transfers;
|
|
1164 templist != NULL;
|
|
1165 templist = templist->next)
|
|
1166 {
|
|
1167 tdata = templist->data;
|
|
1168
|
|
1169 if (g_thread_supported ())
|
|
1170 g_static_mutex_lock (&tdata->structmutex);
|
|
1171
|
|
1172 if (!compare_request (tdata->fromreq, fromreq, 0) ||
|
|
1173 !compare_request (tdata->toreq, toreq, 0) ||
|
|
1174 tdata->curfle == NULL)
|
|
1175 {
|
|
1176 if (g_thread_supported ())
|
|
1177 g_static_mutex_unlock (&tdata->structmutex);
|
|
1178
|
|
1179 continue;
|
|
1180 }
|
|
1181
|
|
1182 tdata->files = g_list_concat (tdata->files, files);
|
|
1183
|
|
1184 for (curfle = files; curfle != NULL; curfle = curfle->next)
|
|
1185 {
|
|
1186 tempfle = curfle->data;
|
|
1187
|
499
|
1188 if (S_ISDIR (tempfle->st_mode))
|
367
|
1189 tdata->numdirs++;
|
|
1190 else
|
|
1191 tdata->numfiles++;
|
|
1192
|
|
1193 if (tempfle->transfer_action != GFTP_TRANS_ACTION_SKIP)
|
|
1194 tdata->total_bytes += tempfle->size;
|
|
1195
|
397
|
1196 gftpui_add_file_to_transfer (tdata, curfle);
|
367
|
1197 }
|
|
1198
|
|
1199 if (g_thread_supported ())
|
|
1200 g_static_mutex_unlock (&tdata->structmutex);
|
|
1201
|
|
1202 break;
|
|
1203 }
|
|
1204
|
|
1205 if (g_thread_supported ())
|
|
1206 g_static_mutex_unlock (&gftpui_common_transfer_mutex);
|
|
1207 }
|
|
1208 else
|
|
1209 templist = NULL;
|
|
1210
|
|
1211 if (templist == NULL)
|
|
1212 {
|
|
1213 tdata = gftp_tdata_new ();
|
368
|
1214 tdata->fromreq = gftp_copy_request (fromreq);
|
|
1215 tdata->toreq = gftp_copy_request (toreq);
|
367
|
1216
|
|
1217 tdata->fromwdata = fromuidata;
|
|
1218 tdata->towdata = touidata;
|
|
1219
|
|
1220 if (!show_dialog)
|
|
1221 tdata->show = tdata->ready = 1;
|
|
1222
|
|
1223 tdata->files = files;
|
|
1224 for (curfle = files; curfle != NULL; curfle = curfle->next)
|
|
1225 {
|
|
1226 tempfle = curfle->data;
|
499
|
1227 if (S_ISDIR (tempfle->st_mode))
|
367
|
1228 tdata->numdirs++;
|
|
1229 else
|
|
1230 tdata->numfiles++;
|
|
1231
|
|
1232 if (tempfle->transfer_action != GFTP_TRANS_ACTION_SKIP)
|
|
1233 tdata->total_bytes += tempfle->size;
|
|
1234 }
|
|
1235
|
|
1236 if (g_thread_supported ())
|
|
1237 g_static_mutex_lock (&gftpui_common_transfer_mutex);
|
|
1238
|
|
1239 gftp_file_transfers = g_list_append (gftp_file_transfers, tdata);
|
|
1240
|
|
1241 if (g_thread_supported ())
|
|
1242 g_static_mutex_unlock (&gftpui_common_transfer_mutex);
|
|
1243
|
|
1244 if (show_dialog)
|
|
1245 gftpui_ask_transfer (tdata);
|
|
1246 }
|
|
1247
|
377
|
1248 gftpui_start_transfer (tdata);
|
367
|
1249 return (tdata);
|
|
1250 }
|
|
1251
|
|
1252
|
|
1253 static void
|
|
1254 _gftpui_common_setup_fds (gftp_transfer * tdata, gftp_file * curfle,
|
|
1255 int *fromfd, int *tofd)
|
|
1256 {
|
|
1257 *tofd = -1;
|
|
1258 *fromfd = -1;
|
|
1259
|
|
1260 if (curfle->is_fd)
|
|
1261 {
|
|
1262 if (tdata->toreq->protonum == GFTP_LOCAL_NUM)
|
|
1263 *tofd = curfle->fd;
|
|
1264 else if (tdata->fromreq->protonum == GFTP_LOCAL_NUM)
|
|
1265 *fromfd = curfle->fd;
|
|
1266 }
|
|
1267 }
|
|
1268
|
|
1269
|
|
1270 static void
|
|
1271 _gftpui_common_done_with_fds (gftp_transfer * tdata, gftp_file * curfle)
|
|
1272 {
|
|
1273 if (curfle->is_fd)
|
|
1274 {
|
|
1275 if (tdata->toreq->protonum == GFTP_LOCAL_NUM)
|
|
1276 tdata->toreq->datafd = -1;
|
|
1277 else
|
|
1278 tdata->fromreq->datafd = -1;
|
|
1279 }
|
|
1280 }
|
|
1281
|
|
1282
|
862
|
1283 static ssize_t
|
|
1284 _do_transfer_block (gftp_transfer * tdata, gftp_file * curfle, char *buf,
|
|
1285 size_t trans_blksize)
|
|
1286 {
|
|
1287 ssize_t num_read, num_wrote, ret;
|
|
1288 char *bufpos;
|
|
1289
|
|
1290 num_read = gftp_get_next_file_chunk (tdata->fromreq, buf, trans_blksize);
|
|
1291 if (num_read < 0)
|
|
1292 return (num_read);
|
|
1293
|
|
1294 bufpos = buf;
|
|
1295 num_wrote = 0;
|
|
1296 while (num_wrote < num_read)
|
|
1297 {
|
|
1298 if ((ret = gftp_put_next_file_chunk (tdata->toreq, bufpos,
|
|
1299 num_read - num_wrote)) <= 0)
|
|
1300 return (ret);
|
|
1301
|
|
1302 num_wrote += ret;
|
|
1303 bufpos += ret;
|
|
1304 }
|
|
1305
|
|
1306 return (num_read);
|
|
1307 }
|
|
1308
|
|
1309
|
367
|
1310 int
|
825
|
1311 _gftpui_common_do_transfer_file (gftp_transfer * tdata, gftp_file * curfle)
|
367
|
1312 {
|
377
|
1313 struct timeval updatetime;
|
811
|
1314 intptr_t trans_blksize;
|
862
|
1315 ssize_t num_trans;
|
|
1316 char *buf;
|
|
1317 int ret;
|
527
|
1318
|
|
1319 gftp_lookup_request_option (tdata->fromreq, "trans_blksize", &trans_blksize);
|
|
1320 buf = g_malloc (trans_blksize);
|
367
|
1321
|
811
|
1322 memset (&updatetime, 0, sizeof (updatetime));
|
|
1323 gftpui_start_current_file_in_transfer (tdata);
|
|
1324
|
862
|
1325 num_trans = 0;
|
811
|
1326 while (!tdata->cancel &&
|
862
|
1327 (num_trans = _do_transfer_block (tdata, curfle, buf,
|
|
1328 trans_blksize)) > 0)
|
811
|
1329 {
|
862
|
1330 gftp_calc_kbs (tdata, num_trans);
|
|
1331
|
811
|
1332 if (tdata->lasttime.tv_sec - updatetime.tv_sec >= 1 ||
|
|
1333 tdata->curtrans >= tdata->tot_file_trans)
|
|
1334 {
|
|
1335 gftpui_update_current_file_in_transfer (tdata);
|
|
1336 memcpy (&updatetime, &tdata->lasttime, sizeof (updatetime));
|
|
1337
|
862
|
1338 if (tdata->current_file_retries > 0)
|
|
1339 tdata->current_file_retries = 0;
|
811
|
1340 }
|
|
1341 }
|
|
1342
|
862
|
1343 if (num_trans == GFTP_ENOTRANS)
|
|
1344 num_trans = 0;
|
811
|
1345
|
|
1346 g_free (buf);
|
|
1347 gftpui_finish_current_file_in_transfer (tdata);
|
|
1348
|
862
|
1349 if ((int) num_trans == 0)
|
825
|
1350 {
|
|
1351 if ((ret = gftp_end_transfer (tdata->fromreq)) < 0)
|
|
1352 return (ret);
|
|
1353
|
|
1354 if ((ret = gftp_end_transfer (tdata->toreq)) < 0)
|
|
1355 return (ret);
|
|
1356
|
|
1357 tdata->fromreq->logging_function (gftp_logging_misc,
|
|
1358 tdata->fromreq,
|
|
1359 _("Successfully transferred %s at %.2f KB/s\n"),
|
|
1360 curfle->file, tdata->kbs);
|
|
1361
|
|
1362 return (0);
|
|
1363 }
|
|
1364 else
|
862
|
1365 return ((int) num_trans);
|
811
|
1366 }
|
|
1367
|
|
1368
|
819
|
1369 void
|
|
1370 gftpui_common_skip_file_transfer (gftp_transfer * tdata, gftp_file * curfle)
|
|
1371 {
|
|
1372 g_static_mutex_lock (&tdata->structmutex);
|
|
1373
|
|
1374 if (tdata->started && !(curfle->transfer_action & GFTP_TRANS_ACTION_SKIP))
|
|
1375 {
|
|
1376 curfle->transfer_action = GFTP_TRANS_ACTION_SKIP;
|
|
1377 if (tdata->curfle != NULL && curfle == tdata->curfle->data)
|
|
1378 {
|
|
1379 tdata->cancel = 1;
|
|
1380 tdata->fromreq->cancel = 1;
|
|
1381 tdata->toreq->cancel = 1;
|
|
1382 tdata->skip_file = 1;
|
|
1383 }
|
|
1384 else if (!curfle->transfer_done)
|
|
1385 tdata->total_bytes -= curfle->size;
|
|
1386 }
|
|
1387
|
|
1388 g_static_mutex_unlock (&tdata->structmutex);
|
|
1389
|
|
1390 if (curfle != NULL)
|
|
1391 tdata->fromreq->logging_function (gftp_logging_misc, tdata->fromreq,
|
|
1392 _("Skipping file %s on host %s\n"),
|
|
1393 curfle->file, tdata->toreq->hostname);
|
|
1394 }
|
|
1395
|
|
1396
|
|
1397 void
|
|
1398 gftpui_common_cancel_file_transfer (gftp_transfer * tdata)
|
|
1399 {
|
|
1400 g_static_mutex_lock (&tdata->structmutex);
|
|
1401
|
|
1402 if (tdata->started)
|
|
1403 {
|
|
1404 tdata->cancel = 1;
|
|
1405 tdata->fromreq->cancel = 1;
|
|
1406 tdata->toreq->cancel = 1;
|
|
1407 tdata->skip_file = 0;
|
|
1408 }
|
|
1409 else
|
|
1410 tdata->done = 1;
|
|
1411
|
|
1412 tdata->fromreq->stopable = 0;
|
|
1413 tdata->toreq->stopable = 0;
|
|
1414
|
|
1415 g_static_mutex_unlock (&tdata->structmutex);
|
|
1416
|
|
1417 tdata->fromreq->logging_function (gftp_logging_misc, tdata->fromreq,
|
|
1418 _("Stopping the transfer on host %s\n"),
|
|
1419 tdata->toreq->hostname);
|
|
1420 }
|
|
1421
|
|
1422
|
838
|
1423 static void
|
825
|
1424 _gftpui_common_next_file_in_trans (gftp_transfer * tdata)
|
|
1425 {
|
|
1426 gftp_file * curfle;
|
|
1427
|
|
1428 if (g_thread_supported ())
|
|
1429 g_static_mutex_lock (&tdata->structmutex);
|
|
1430
|
|
1431 tdata->curtrans = 0;
|
|
1432 tdata->next_file = 1;
|
|
1433
|
|
1434 curfle = tdata->curfle->data;
|
|
1435 curfle->transfer_done = 1;
|
|
1436 tdata->curfle = tdata->curfle->next;
|
|
1437
|
|
1438 if (g_thread_supported ())
|
|
1439 g_static_mutex_unlock (&tdata->structmutex);
|
|
1440 }
|
|
1441
|
|
1442
|
|
1443 static int
|
|
1444 _gftpui_common_preserve_perm_time (gftp_transfer * tdata, gftp_file * curfle)
|
811
|
1445 {
|
|
1446 intptr_t preserve_permissions, preserve_time;
|
825
|
1447 int ret, tmpret;
|
367
|
1448
|
774
|
1449 gftp_lookup_request_option (tdata->fromreq, "preserve_permissions",
|
|
1450 &preserve_permissions);
|
|
1451 gftp_lookup_request_option (tdata->fromreq, "preserve_time",
|
|
1452 &preserve_time);
|
|
1453
|
825
|
1454 ret = 0;
|
|
1455 if (GFTP_IS_CONNECTED (tdata->toreq) && preserve_permissions &&
|
|
1456 curfle->st_mode != 0)
|
367
|
1457 {
|
825
|
1458 tmpret = gftp_chmod (tdata->toreq, curfle->destfile,
|
|
1459 curfle->st_mode & (S_IRWXU | S_IRWXG | S_IRWXO));
|
|
1460 if (tmpret < 0)
|
|
1461 ret = tmpret;
|
|
1462 }
|
367
|
1463
|
825
|
1464 if (GFTP_IS_CONNECTED (tdata->toreq) && preserve_time &&
|
|
1465 curfle->datetime != 0)
|
|
1466 {
|
|
1467 tmpret = gftp_set_file_time (tdata->toreq, curfle->destfile,
|
|
1468 curfle->datetime);
|
|
1469 if (tmpret < 0)
|
|
1470 ret = tmpret;
|
|
1471 }
|
367
|
1472
|
825
|
1473 if (!GFTP_IS_CONNECTED (tdata->toreq))
|
|
1474 return (ret);
|
|
1475 else
|
|
1476 return (0);
|
|
1477 }
|
|
1478
|
367
|
1479
|
825
|
1480 static int
|
|
1481 _gftpui_common_trans_file_or_dir (gftp_transfer * tdata)
|
|
1482 {
|
858
|
1483 int tofd, fromfd, ret;
|
862
|
1484 gftp_file * curfle;
|
825
|
1485
|
|
1486 if (g_thread_supported ())
|
|
1487 g_static_mutex_lock (&tdata->structmutex);
|
367
|
1488
|
825
|
1489 curfle = tdata->curfle->data;
|
|
1490 tdata->current_file_number++;
|
|
1491
|
|
1492 if (g_thread_supported ())
|
|
1493 g_static_mutex_unlock (&tdata->structmutex);
|
|
1494
|
|
1495 if (curfle->transfer_action == GFTP_TRANS_ACTION_SKIP)
|
|
1496 {
|
|
1497 tdata->tot_file_trans = 0;
|
|
1498 return (0);
|
|
1499 }
|
|
1500
|
|
1501 if ((ret = gftp_connect (tdata->fromreq)) < 0)
|
|
1502 return (ret);
|
|
1503
|
|
1504 if ((ret = gftp_connect (tdata->toreq)) < 0)
|
|
1505 return (ret);
|
367
|
1506
|
825
|
1507 if (S_ISDIR (curfle->st_mode))
|
|
1508 {
|
|
1509 tdata->tot_file_trans = 0;
|
862
|
1510 ret = gftp_make_directory (tdata->toreq, curfle->destfile);
|
825
|
1511 }
|
|
1512 else
|
|
1513 {
|
|
1514 _gftpui_common_setup_fds (tdata, curfle, &fromfd, &tofd);
|
367
|
1515
|
825
|
1516 if (curfle->size == 0)
|
|
1517 {
|
|
1518 curfle->size = gftp_get_file_size (tdata->fromreq, curfle->file);
|
862
|
1519 if (curfle->size < 0)
|
|
1520 return ((int) curfle->size);
|
377
|
1521
|
825
|
1522 tdata->total_bytes += curfle->size;
|
367
|
1523 }
|
|
1524
|
862
|
1525 if (curfle->retry_transfer)
|
|
1526 {
|
|
1527 curfle->transfer_action = GFTP_TRANS_ACTION_RESUME;
|
|
1528 curfle->startsize = gftp_get_file_size (tdata->toreq, curfle->destfile);
|
|
1529 if (curfle->startsize < 0)
|
|
1530 return ((int) curfle->startsize);
|
|
1531 }
|
|
1532
|
825
|
1533 tdata->tot_file_trans = gftp_transfer_file (tdata->fromreq, curfle->file,
|
|
1534 fromfd,
|
|
1535 curfle->transfer_action == GFTP_TRANS_ACTION_RESUME ?
|
|
1536 curfle->startsize : 0,
|
|
1537 tdata->toreq, curfle->destfile, tofd,
|
|
1538 curfle->transfer_action == GFTP_TRANS_ACTION_RESUME ?
|
|
1539 curfle->startsize : 0);
|
|
1540 if (tdata->tot_file_trans < 0)
|
|
1541 ret = tdata->tot_file_trans;
|
367
|
1542 else
|
|
1543 {
|
|
1544 if (g_thread_supported ())
|
|
1545 g_static_mutex_lock (&tdata->structmutex);
|
|
1546
|
|
1547 tdata->curtrans = 0;
|
|
1548 tdata->curresumed = curfle->transfer_action == GFTP_TRANS_ACTION_RESUME ? curfle->startsize : 0;
|
|
1549 tdata->resumed_bytes += tdata->curresumed;
|
|
1550
|
|
1551 if (g_thread_supported ())
|
|
1552 g_static_mutex_unlock (&tdata->structmutex);
|
|
1553
|
825
|
1554 ret = _gftpui_common_do_transfer_file (tdata, curfle);
|
367
|
1555 }
|
|
1556
|
825
|
1557 _gftpui_common_done_with_fds (tdata, curfle);
|
|
1558 }
|
|
1559
|
|
1560 if (ret == 0)
|
|
1561 {
|
|
1562 if (!curfle->is_fd)
|
|
1563 ret = _gftpui_common_preserve_perm_time (tdata, curfle);
|
|
1564 }
|
|
1565 else
|
862
|
1566 {
|
|
1567 curfle->retry_transfer = 1;
|
|
1568 tdata->fromreq->logging_function (gftp_logging_error, tdata->fromreq,
|
|
1569 _("Could not download %s from %s\n"),
|
|
1570 curfle->file, tdata->fromreq->hostname);
|
|
1571 }
|
825
|
1572
|
|
1573 return (ret);
|
|
1574 }
|
|
1575
|
|
1576
|
|
1577 int
|
|
1578 gftpui_common_transfer_files (gftp_transfer * tdata)
|
|
1579 {
|
858
|
1580 int ret, skipped_files;
|
825
|
1581
|
|
1582 tdata->curfle = tdata->files;
|
|
1583 gettimeofday (&tdata->starttime, NULL);
|
|
1584 memcpy (&tdata->lasttime, &tdata->starttime, sizeof (tdata->lasttime));
|
|
1585
|
858
|
1586 skipped_files = 0;
|
825
|
1587 while (tdata->curfle != NULL)
|
|
1588 {
|
|
1589 ret = _gftpui_common_trans_file_or_dir (tdata);
|
367
|
1590 if (tdata->cancel)
|
|
1591 {
|
825
|
1592 if (gftp_abort_transfer (tdata->toreq) != 0)
|
|
1593 gftp_disconnect (tdata->toreq);
|
|
1594
|
367
|
1595 if (gftp_abort_transfer (tdata->fromreq) != 0)
|
|
1596 gftp_disconnect (tdata->fromreq);
|
|
1597 }
|
858
|
1598 else if (ret == GFTP_EFATAL)
|
|
1599 skipped_files++;
|
811
|
1600 else if (ret < 0)
|
367
|
1601 {
|
811
|
1602 if (gftp_get_transfer_status (tdata, ret) == GFTP_ERETRYABLE)
|
367
|
1603 continue;
|
|
1604
|
|
1605 break;
|
|
1606 }
|
|
1607
|
825
|
1608 _gftpui_common_next_file_in_trans (tdata);
|
367
|
1609
|
825
|
1610 if (tdata->cancel)
|
367
|
1611 {
|
825
|
1612 if (!tdata->skip_file)
|
|
1613 break;
|
367
|
1614
|
825
|
1615 tdata->cancel = 0;
|
|
1616 tdata->fromreq->cancel = 0;
|
|
1617 tdata->toreq->cancel = 0;
|
|
1618 }
|
367
|
1619 }
|
527
|
1620
|
858
|
1621 if (skipped_files)
|
|
1622 tdata->fromreq->logging_function (gftp_logging_error, tdata->fromreq,
|
|
1623 _("There were %d files or directories that could not be transferred. Check the log for which items were not properly transferred."),
|
|
1624 skipped_files);
|
|
1625
|
367
|
1626 tdata->done = 1;
|
387
|
1627 return (1);
|
367
|
1628 }
|
|
1629
|
469
|
1630
|
|
1631 void
|
|
1632 gftpui_protocol_update_timeout (gftp_request * request)
|
|
1633 {
|
|
1634 intptr_t network_timeout;
|
|
1635
|
|
1636 gftp_lookup_request_option (request, "network_timeout", &network_timeout);
|
|
1637
|
|
1638 if (network_timeout > 0)
|
|
1639 alarm (network_timeout);
|
|
1640 }
|
|
1641
|