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
|
|
1283 int
|
825
|
1284 _gftpui_common_do_transfer_file (gftp_transfer * tdata, gftp_file * curfle)
|
367
|
1285 {
|
377
|
1286 struct timeval updatetime;
|
811
|
1287 intptr_t trans_blksize;
|
377
|
1288 ssize_t num_read, ret;
|
811
|
1289 char *buf, *bufpos;
|
527
|
1290
|
|
1291 gftp_lookup_request_option (tdata->fromreq, "trans_blksize", &trans_blksize);
|
|
1292 buf = g_malloc (trans_blksize);
|
367
|
1293
|
811
|
1294 memset (&updatetime, 0, sizeof (updatetime));
|
|
1295 gftpui_start_current_file_in_transfer (tdata);
|
|
1296
|
838
|
1297 num_read = 0;
|
811
|
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
|
838
|
1405 static void
|
825
|
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 {
|
858
|
1465 int tofd, fromfd, ret;
|
825
|
1466 gftp_file * curfle;
|
|
1467
|
|
1468 if (g_thread_supported ())
|
|
1469 g_static_mutex_lock (&tdata->structmutex);
|
367
|
1470
|
825
|
1471 curfle = tdata->curfle->data;
|
|
1472 tdata->current_file_number++;
|
|
1473
|
|
1474 if (g_thread_supported ())
|
|
1475 g_static_mutex_unlock (&tdata->structmutex);
|
|
1476
|
|
1477 if (curfle->transfer_action == GFTP_TRANS_ACTION_SKIP)
|
|
1478 {
|
|
1479 tdata->tot_file_trans = 0;
|
|
1480 return (0);
|
|
1481 }
|
|
1482
|
|
1483 if ((ret = gftp_connect (tdata->fromreq)) < 0)
|
|
1484 return (ret);
|
|
1485
|
|
1486 if ((ret = gftp_connect (tdata->toreq)) < 0)
|
|
1487 return (ret);
|
367
|
1488
|
825
|
1489 if (S_ISDIR (curfle->st_mode))
|
|
1490 {
|
|
1491 tdata->tot_file_trans = 0;
|
|
1492 if (tdata->toreq->mkdir != NULL)
|
|
1493 ret = tdata->toreq->mkdir (tdata->toreq, curfle->destfile);
|
|
1494 else
|
|
1495 ret = GFTP_EFATAL;
|
|
1496 }
|
|
1497 else
|
|
1498 {
|
|
1499 _gftpui_common_setup_fds (tdata, curfle, &fromfd, &tofd);
|
367
|
1500
|
825
|
1501 if (curfle->size == 0)
|
|
1502 {
|
|
1503 curfle->size = gftp_get_file_size (tdata->fromreq, curfle->file);
|
|
1504 if (!GFTP_IS_CONNECTED (tdata->fromreq))
|
|
1505 return (curfle->size);
|
377
|
1506
|
825
|
1507 tdata->total_bytes += curfle->size;
|
367
|
1508 }
|
|
1509
|
825
|
1510 tdata->tot_file_trans = gftp_transfer_file (tdata->fromreq, curfle->file,
|
|
1511 fromfd,
|
|
1512 curfle->transfer_action == GFTP_TRANS_ACTION_RESUME ?
|
|
1513 curfle->startsize : 0,
|
|
1514 tdata->toreq, curfle->destfile, tofd,
|
|
1515 curfle->transfer_action == GFTP_TRANS_ACTION_RESUME ?
|
|
1516 curfle->startsize : 0);
|
|
1517 if (tdata->tot_file_trans < 0)
|
|
1518 ret = tdata->tot_file_trans;
|
367
|
1519 else
|
|
1520 {
|
|
1521 if (g_thread_supported ())
|
|
1522 g_static_mutex_lock (&tdata->structmutex);
|
|
1523
|
|
1524 tdata->curtrans = 0;
|
|
1525 tdata->curresumed = curfle->transfer_action == GFTP_TRANS_ACTION_RESUME ? curfle->startsize : 0;
|
|
1526 tdata->resumed_bytes += tdata->curresumed;
|
|
1527
|
|
1528 if (g_thread_supported ())
|
|
1529 g_static_mutex_unlock (&tdata->structmutex);
|
|
1530
|
825
|
1531 ret = _gftpui_common_do_transfer_file (tdata, curfle);
|
367
|
1532 }
|
|
1533
|
825
|
1534 _gftpui_common_done_with_fds (tdata, curfle);
|
|
1535 }
|
|
1536
|
|
1537 if (ret == 0)
|
|
1538 {
|
|
1539 if (!curfle->is_fd)
|
|
1540 ret = _gftpui_common_preserve_perm_time (tdata, curfle);
|
|
1541 }
|
|
1542 else
|
|
1543 tdata->fromreq->logging_function (gftp_logging_error, tdata->fromreq,
|
|
1544 _("Could not download %s from %s\n"),
|
|
1545 curfle->file, tdata->fromreq->hostname);
|
|
1546
|
|
1547 return (ret);
|
|
1548 }
|
|
1549
|
|
1550
|
|
1551 int
|
|
1552 gftpui_common_transfer_files (gftp_transfer * tdata)
|
|
1553 {
|
858
|
1554 int ret, skipped_files;
|
825
|
1555
|
|
1556 tdata->curfle = tdata->files;
|
|
1557 gettimeofday (&tdata->starttime, NULL);
|
|
1558 memcpy (&tdata->lasttime, &tdata->starttime, sizeof (tdata->lasttime));
|
|
1559
|
858
|
1560 skipped_files = 0;
|
825
|
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 }
|
858
|
1572 else if (ret == GFTP_EFATAL)
|
|
1573 skipped_files++;
|
811
|
1574 else if (ret < 0)
|
367
|
1575 {
|
811
|
1576 if (gftp_get_transfer_status (tdata, ret) == GFTP_ERETRYABLE)
|
367
|
1577 continue;
|
|
1578
|
|
1579 break;
|
|
1580 }
|
|
1581
|
825
|
1582 _gftpui_common_next_file_in_trans (tdata);
|
367
|
1583
|
825
|
1584 if (tdata->cancel)
|
367
|
1585 {
|
825
|
1586 if (!tdata->skip_file)
|
|
1587 break;
|
367
|
1588
|
825
|
1589 tdata->cancel = 0;
|
|
1590 tdata->fromreq->cancel = 0;
|
|
1591 tdata->toreq->cancel = 0;
|
|
1592 }
|
367
|
1593 }
|
527
|
1594
|
858
|
1595 if (skipped_files)
|
|
1596 tdata->fromreq->logging_function (gftp_logging_error, tdata->fromreq,
|
|
1597 _("There were %d files or directories that could not be transferred. Check the log for which items were not properly transferred."),
|
|
1598 skipped_files);
|
|
1599
|
367
|
1600 tdata->done = 1;
|
387
|
1601 return (1);
|
367
|
1602 }
|
|
1603
|
469
|
1604
|
|
1605 void
|
|
1606 gftpui_protocol_update_timeout (gftp_request * request)
|
|
1607 {
|
|
1608 intptr_t network_timeout;
|
|
1609
|
|
1610 gftp_lookup_request_option (request, "network_timeout", &network_timeout);
|
|
1611
|
|
1612 if (network_timeout > 0)
|
|
1613 alarm (network_timeout);
|
|
1614 }
|
|
1615
|