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