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