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)
|
514
|
125 gftpui_refresh (cdata->uidata, !cdata->dont_clear_cache);
|
341
|
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;
|
514
|
496 cdata->dont_clear_cache = 1;
|
350
|
497
|
|
498 gftpui_common_run_callback_function (cdata);
|
|
499
|
|
500 g_free (cdata);
|
341
|
501
|
|
502 if (newdir != NULL)
|
|
503 g_free (newdir);
|
|
504
|
|
505 return (1);
|
|
506 }
|
|
507
|
|
508
|
|
509 static int
|
374
|
510 gftpui_common_cmd_close (void *uidata, gftp_request * request,
|
377
|
511 void *other_uidata, gftp_request * other_request,
|
374
|
512 const char *command)
|
341
|
513 {
|
|
514 gftp_disconnect (request);
|
|
515 return (1);
|
|
516 }
|
|
517
|
|
518
|
|
519 static int
|
374
|
520 gftpui_common_cmd_pwd (void *uidata, gftp_request * request,
|
377
|
521 void *other_uidata, gftp_request * other_request,
|
374
|
522 const char *command)
|
341
|
523 {
|
|
524 if (!GFTP_IS_CONNECTED (request))
|
|
525 {
|
|
526 request->logging_function (gftp_logging_error, request,
|
|
527 _("Error: Not connected to a remote site\n"));
|
|
528 return (1);
|
|
529 }
|
|
530
|
|
531 request->logging_function (gftp_logging_misc, request,
|
|
532 "%s\n", request->directory);
|
|
533
|
|
534 return (1);
|
|
535 }
|
|
536
|
|
537
|
|
538 static int
|
374
|
539 gftpui_common_cmd_quit (void *uidata, gftp_request * request,
|
377
|
540 void *other_uidata, gftp_request * other_request,
|
374
|
541 const char *command)
|
341
|
542 {
|
|
543 gftp_shutdown();
|
|
544
|
|
545 return (0);
|
|
546 }
|
|
547
|
|
548
|
|
549 static int
|
374
|
550 gftpui_common_cmd_clear (void *uidata, gftp_request * request,
|
377
|
551 void *other_uidata, gftp_request * other_request,
|
374
|
552 const char *command)
|
341
|
553 {
|
|
554 if (strcasecmp (command, "cache") == 0)
|
|
555 gftp_clear_cache_files ();
|
|
556 else
|
|
557 {
|
374
|
558 gftpui_common_logfunc (gftp_logging_error, request,
|
|
559 _("Invalid argument\n"));
|
341
|
560 }
|
|
561
|
|
562 return (1);
|
|
563 }
|
|
564
|
|
565
|
|
566 static int
|
374
|
567 gftpui_common_clear_show_subhelp (const char *topic)
|
341
|
568 {
|
|
569 if (strcmp (topic, "cache") == 0)
|
|
570 {
|
374
|
571 gftpui_common_logfunc (gftp_logging_misc, NULL,
|
|
572 _("Clear the directory cache\n"));
|
341
|
573 return (1);
|
|
574 }
|
|
575
|
|
576 return (0);
|
|
577 }
|
|
578
|
|
579
|
|
580 static int
|
374
|
581 gftpui_common_set_show_subhelp (const char *topic)
|
341
|
582 {
|
|
583 gftp_config_vars * cv;
|
|
584
|
|
585 if ((cv = g_hash_table_lookup (gftp_global_options_htable, topic)) != NULL)
|
|
586 {
|
374
|
587 gftpui_common_logfunc (gftp_logging_misc, NULL, "%s\n", cv->comment);
|
341
|
588 return (1);
|
|
589 }
|
|
590
|
|
591 return (0);
|
|
592 }
|
|
593
|
|
594
|
355
|
595 static int
|
374
|
596 gftpui_common_cmd_ls (void *uidata, gftp_request * request,
|
377
|
597 void *other_uidata, gftp_request * other_request,
|
374
|
598 const char *command)
|
341
|
599 {
|
355
|
600 char *startcolor, *endcolor, *tempstr;
|
|
601 gftpui_callback_data * cdata;
|
|
602 GList * templist;
|
341
|
603 gftp_file * fle;
|
|
604
|
|
605 if (!GFTP_IS_CONNECTED (request))
|
|
606 {
|
|
607 request->logging_function (gftp_logging_error, request,
|
|
608 _("Error: Not connected to a remote site\n"));
|
|
609 return (1);
|
|
610 }
|
|
611
|
355
|
612 cdata = g_malloc0 (sizeof (*cdata));
|
|
613 cdata->request = request;
|
|
614 cdata->uidata = uidata;
|
374
|
615 cdata->source_string = *command != '\0' ? (char *) command : NULL;
|
355
|
616 cdata->run_function = gftpui_common_run_ls;
|
511
|
617 cdata->dont_refresh = 1;
|
341
|
618
|
355
|
619 gftpui_common_run_callback_function (cdata);
|
341
|
620
|
355
|
621 templist = cdata->files;
|
|
622 while (templist != NULL)
|
341
|
623 {
|
|
624 fle = templist->data;
|
|
625
|
|
626 gftpui_lookup_file_colors (fle, &startcolor, &endcolor);
|
|
627 tempstr = gftp_gen_ls_string (fle, startcolor, endcolor);
|
422
|
628 request->logging_function (gftp_logging_misc_nolog, request, "%s",
|
354
|
629 tempstr);
|
341
|
630 g_free (tempstr);
|
|
631
|
355
|
632 templist = templist->next;
|
|
633 gftp_file_destroy (fle);
|
|
634 g_free (fle);
|
341
|
635 }
|
|
636
|
|
637
|
355
|
638 if (cdata->files != NULL)
|
|
639 g_list_free (cdata->files);
|
|
640 g_free (cdata);
|
341
|
641
|
|
642 return (1);
|
|
643 }
|
|
644
|
|
645
|
367
|
646 int
|
374
|
647 gftpui_common_cmd_open (void *uidata, gftp_request * request,
|
377
|
648 void *other_uidata, gftp_request * other_request,
|
374
|
649 const char *command)
|
356
|
650 {
|
367
|
651 gftpui_callback_data * cdata;
|
|
652 intptr_t retries;
|
356
|
653
|
|
654 if (GFTP_IS_CONNECTED (request))
|
387
|
655 gftpui_disconnect (uidata);
|
356
|
656
|
367
|
657 if (command != NULL)
|
356
|
658 {
|
367
|
659 if (*command == '\0')
|
|
660 {
|
|
661 request->logging_function (gftp_logging_error, request,
|
|
662 _("usage: open " GFTP_URL_USAGE "\n"));
|
|
663 return (1);
|
|
664 }
|
|
665
|
|
666 if (gftp_parse_url (request, command) < 0)
|
|
667 return (1);
|
356
|
668 }
|
|
669
|
|
670 if (request->need_userpass)
|
|
671 {
|
|
672 if (request->username == NULL || *request->username == '\0')
|
380
|
673 gftpui_prompt_username (uidata, request);
|
356
|
674
|
|
675 if (request->username != NULL &&
|
|
676 strcmp (request->username, "anonymous") != 0 &&
|
|
677 (request->password == NULL || *request->password == '\0'))
|
380
|
678 gftpui_prompt_password (uidata, request);
|
356
|
679 }
|
|
680
|
367
|
681 gftp_lookup_request_option (request, "retries", &retries);
|
|
682
|
|
683 cdata = g_malloc0 (sizeof (*cdata));
|
|
684 cdata->request = request;
|
|
685 cdata->uidata = uidata;
|
|
686 cdata->run_function = gftpui_common_run_connect;
|
|
687 cdata->retries = retries;
|
451
|
688 cdata->dont_check_connection = 1;
|
367
|
689
|
|
690 gftpui_common_run_callback_function (cdata);
|
|
691
|
|
692 g_free (cdata);
|
356
|
693
|
|
694 return (1);
|
|
695 }
|
|
696
|
|
697
|
|
698 static int
|
374
|
699 gftpui_common_cmd_set (void *uidata, gftp_request * request,
|
377
|
700 void *other_uidata, gftp_request * other_request,
|
374
|
701 const char *command)
|
341
|
702 {
|
387
|
703 char *pos, *backpos, buf[256];
|
341
|
704 gftp_config_vars * cv, newcv;
|
|
705 GList * templist;
|
|
706 int i;
|
|
707
|
|
708 if (command == NULL || *command == '\0')
|
|
709 {
|
|
710 for (templist = gftp_options_list;
|
|
711 templist != NULL;
|
|
712 templist = templist->next)
|
|
713 {
|
|
714 cv = templist->data;
|
|
715
|
|
716 for (i=0; cv[i].key != NULL; i++)
|
|
717 {
|
|
718 if (!(cv[i].ports_shown & GFTP_PORT_TEXT))
|
|
719 continue;
|
|
720
|
|
721 if (*cv[i].key == '\0' ||
|
|
722 gftp_option_types[cv[i].otype].write_function == NULL)
|
|
723 continue;
|
|
724
|
387
|
725 gftp_option_types[cv[i].otype].write_function (&cv[i], buf,
|
|
726 sizeof (buf), 0);
|
|
727
|
|
728 gftpui_common_logfunc (gftp_logging_misc_nolog, request,
|
|
729 "%s = %s\n", cv[i].key, buf);
|
341
|
730 }
|
|
731 }
|
|
732 }
|
|
733 else
|
|
734 {
|
|
735 if ((pos = strchr (command, '=')) == NULL)
|
|
736 {
|
374
|
737 gftpui_common_logfunc (gftp_logging_error, request,
|
|
738 _("usage: set [variable = value]\n"));
|
341
|
739 return (1);
|
|
740 }
|
|
741 *pos = '\0';
|
|
742
|
|
743 for (backpos = pos - 1;
|
|
744 (*backpos == ' ' || *backpos == '\t') && backpos > command;
|
|
745 backpos--)
|
|
746 *backpos = '\0';
|
|
747 for (++pos; *pos == ' ' || *pos == '\t'; pos++);
|
|
748
|
|
749 if ((cv = g_hash_table_lookup (gftp_global_options_htable, command)) == NULL)
|
|
750 {
|
374
|
751 gftpui_common_logfunc (gftp_logging_error, request,
|
|
752 _("Error: Variable %s is not a valid configuration variable.\n"), command);
|
341
|
753 return (1);
|
|
754 }
|
|
755
|
|
756 if (!(cv->ports_shown & GFTP_PORT_TEXT))
|
|
757 {
|
374
|
758 gftpui_common_logfunc (gftp_logging_error, request,
|
|
759 _("Error: Variable %s is not available in the text port of gFTP\n"), command);
|
341
|
760 return (1);
|
|
761 }
|
|
762
|
|
763 if (gftp_option_types[cv->otype].read_function != NULL)
|
|
764 {
|
|
765 memcpy (&newcv, cv, sizeof (newcv));
|
|
766 newcv.flags &= ~GFTP_CVARS_FLAGS_DYNMEM;
|
|
767
|
|
768 gftp_option_types[cv->otype].read_function (pos, &newcv, 1);
|
|
769
|
|
770 gftp_set_global_option (command, newcv.value);
|
|
771
|
387
|
772 gftp_option_types[newcv.otype].write_function (&newcv, buf,
|
|
773 sizeof (buf), 0);
|
|
774
|
|
775 gftpui_common_logfunc (gftp_logging_misc_nolog, request,
|
|
776 "%s = %s\n", newcv.key, buf);
|
|
777
|
341
|
778 if (newcv.flags & GFTP_CVARS_FLAGS_DYNMEM)
|
|
779 g_free (newcv.value);
|
|
780 }
|
|
781 }
|
|
782
|
|
783 return (1);
|
|
784 }
|
|
785
|
|
786
|
|
787 static int
|
374
|
788 gftpui_common_cmd_help (void *uidata, gftp_request * request,
|
377
|
789 void *other_uidata, gftp_request * other_request,
|
374
|
790 const char *command)
|
341
|
791 {
|
374
|
792 int i, j, ele, numrows, numcols = 6, handled, number_commands, cmdlen,
|
|
793 found;
|
387
|
794 char commands[128], cmdstr[30];
|
374
|
795 const char *pos;
|
341
|
796
|
|
797 for (number_commands=0;
|
|
798 gftpui_common_commands[number_commands].command != NULL;
|
|
799 number_commands++);
|
|
800
|
|
801 if (command != NULL && *command != '\0')
|
|
802 {
|
|
803 for (pos = command; *pos != ' ' && *pos != '\0'; pos++);
|
374
|
804 cmdlen = pos - command;
|
341
|
805
|
|
806 for (i=0; gftpui_common_commands[i].command != NULL; i++)
|
|
807 {
|
374
|
808 if (strncmp (gftpui_common_commands[i].command, command, cmdlen) == 0)
|
341
|
809 break;
|
|
810 }
|
|
811
|
|
812 if (gftpui_common_commands[i].cmd_description != NULL)
|
|
813 {
|
374
|
814 found = 1;
|
|
815
|
|
816 if (*pos != '\0' && *(pos + 1) != '\0' &&
|
|
817 gftpui_common_commands[i].subhelp_func != NULL)
|
|
818 handled = gftpui_common_commands[i].subhelp_func (pos + 1);
|
341
|
819 else
|
|
820 handled = 0;
|
|
821
|
|
822 if (!handled)
|
387
|
823 gftpui_common_logfunc (gftp_logging_misc_nolog, request, "%s\n",
|
|
824 _(gftpui_common_commands[i].cmd_description));
|
341
|
825 }
|
|
826 else
|
374
|
827 found = 0;
|
341
|
828 }
|
374
|
829 else
|
|
830 found = 0;
|
341
|
831
|
374
|
832 if (!found)
|
341
|
833 {
|
|
834 numrows = number_commands / numcols;
|
|
835 if (number_commands % numcols != 0)
|
|
836 numrows++;
|
|
837
|
387
|
838 gftpui_common_logfunc (gftp_logging_misc_nolog, request,
|
|
839 _("Supported commands:\n\n"));
|
|
840
|
341
|
841 for (i=0; i<numrows; i++)
|
|
842 {
|
387
|
843 strncpy (commands, "\t", sizeof (commands));
|
|
844
|
341
|
845 for (j=0; j<numcols; j++)
|
|
846 {
|
|
847 ele = i + j * numrows;
|
|
848 if (ele >= number_commands)
|
|
849 break;
|
387
|
850
|
|
851 g_snprintf (cmdstr, sizeof (cmdstr), "%-10s",
|
|
852 gftpui_common_commands[ele].command);
|
|
853 strncat (commands, cmdstr, sizeof (commands));
|
341
|
854 }
|
387
|
855 gftpui_common_logfunc (gftp_logging_misc_nolog, request, "%s\n",
|
|
856 commands);
|
341
|
857 }
|
|
858 }
|
|
859 return (1);
|
|
860 }
|
|
861
|
|
862
|
377
|
863 static void
|
|
864 _gftpui_common_transfer_files (void *fromuidata, gftp_request * fromrequest,
|
|
865 void *touidata, gftp_request * torequest,
|
|
866 const char *cmd, const char *filespec)
|
|
867 {
|
|
868 gftp_transfer * tdata;
|
|
869 gftp_file * fle;
|
|
870
|
|
871 if (!GFTP_IS_CONNECTED (fromrequest) ||
|
|
872 !GFTP_IS_CONNECTED (torequest))
|
|
873 {
|
|
874 fromrequest->logging_function (gftp_logging_error, fromrequest,
|
|
875 _("Error: Not connected to a remote site\n"));
|
|
876 return;
|
|
877 }
|
|
878
|
|
879 if (*filespec == '\0')
|
|
880 {
|
|
881 fromrequest->logging_function (gftp_logging_error, fromrequest,
|
|
882 _("usage: %s <filespec>\n"), cmd);
|
|
883 return;
|
|
884 }
|
|
885
|
|
886 tdata = gftp_tdata_new ();
|
|
887 tdata->fromreq = fromrequest;
|
|
888 tdata->toreq = torequest;
|
|
889
|
|
890 if (gftp_list_files (tdata->fromreq) != 0)
|
|
891 {
|
|
892 tdata->fromreq = tdata->toreq = NULL;
|
|
893 free_tdata (tdata);
|
|
894 return;
|
|
895 }
|
|
896
|
|
897 fle = g_malloc0 (sizeof (*fle));
|
|
898 while (gftp_get_next_file (tdata->fromreq, filespec, fle) > 0)
|
|
899 {
|
|
900 if (strcmp (fle->file, ".") == 0 || strcmp (fle->file, "..") == 0)
|
|
901 {
|
|
902 gftp_file_destroy (fle);
|
|
903 continue;
|
|
904 }
|
|
905
|
|
906 tdata->files = g_list_append (tdata->files, fle);
|
|
907 fle = g_malloc (sizeof (*fle));
|
|
908 }
|
|
909
|
|
910 g_free (fle);
|
|
911
|
|
912 gftp_end_transfer (tdata->fromreq);
|
|
913
|
|
914 if (tdata->files == NULL)
|
|
915 {
|
|
916 tdata->fromreq = tdata->toreq = NULL;
|
|
917 free_tdata (tdata);
|
|
918 return;
|
|
919 }
|
|
920
|
|
921 if (gftp_get_all_subdirs (tdata, NULL) != 0)
|
|
922 {
|
|
923 tdata->fromreq = tdata->toreq = NULL;
|
|
924 free_tdata (tdata);
|
|
925 return;
|
|
926 }
|
|
927
|
|
928 if (tdata->files == NULL)
|
|
929 {
|
|
930 tdata->fromreq = tdata->toreq = NULL;
|
|
931 free_tdata (tdata);
|
|
932 return;
|
|
933 }
|
|
934
|
|
935 gftpui_common_add_file_transfer (tdata->fromreq, tdata->toreq,
|
|
936 fromuidata, touidata, tdata->files);
|
|
937
|
|
938 g_free (tdata);
|
|
939
|
|
940 return;
|
|
941 }
|
|
942
|
|
943
|
|
944 int
|
|
945 gftpui_common_cmd_mget_file (void *uidata, gftp_request * request,
|
|
946 void *other_uidata, gftp_request * other_request,
|
|
947 const char *command)
|
|
948 {
|
|
949 _gftpui_common_transfer_files (uidata, request, other_uidata, other_request,
|
|
950 "mget", command);
|
|
951 return (1);
|
|
952 }
|
|
953
|
|
954
|
|
955 int
|
|
956 gftpui_common_cmd_mput_file (void *uidata, gftp_request * request,
|
|
957 void *other_uidata, gftp_request * other_request,
|
|
958 const char *command)
|
|
959 {
|
|
960 _gftpui_common_transfer_files (other_uidata, other_request, uidata, request,
|
|
961 "mput", command);
|
|
962 return (1);
|
|
963 }
|
|
964
|
|
965
|
341
|
966 gftpui_common_methods gftpui_common_commands[] = {
|
|
967 {N_("about"), 2, gftpui_common_cmd_about, gftpui_common_request_none,
|
|
968 N_("Shows gFTP information"), NULL},
|
|
969 {N_("ascii"), 2, gftpui_common_cmd_ascii, gftpui_common_request_remote,
|
|
970 N_("Sets the current file transfer mode to Ascii (only for FTP)"), NULL},
|
|
971 {N_("binary"), 1, gftpui_common_cmd_binary, gftpui_common_request_remote,
|
|
972 N_("Sets the current file transfer mode to Binary (only for FTP)"), NULL},
|
|
973 {N_("cd"), 2, gftpui_common_cmd_chdir, gftpui_common_request_remote,
|
|
974 N_("Changes the remote working directory"), NULL},
|
|
975 {N_("chdir"), 3, gftpui_common_cmd_chdir, gftpui_common_request_remote,
|
|
976 N_("Changes the remote working directory"), NULL},
|
|
977 {N_("chmod"), 3, gftpui_common_cmd_chmod, gftpui_common_request_remote,
|
|
978 N_("Changes the permissions of a remote file"), NULL},
|
|
979 {N_("clear"), 3, gftpui_common_cmd_clear, gftpui_common_request_none,
|
|
980 N_("Available options: cache"), gftpui_common_clear_show_subhelp},
|
|
981 {N_("close"), 3, gftpui_common_cmd_close, gftpui_common_request_remote,
|
|
982 N_("Disconnects from the remote site"), NULL},
|
350
|
983 {N_("delete"), 1, gftpui_common_cmd_delete, gftpui_common_request_remote,
|
341
|
984 N_("Removes a remote file"), NULL},
|
377
|
985 {N_("get"), 1, gftpui_common_cmd_mget_file, gftpui_common_request_remote,
|
341
|
986 N_("Downloads remote file(s)"), NULL},
|
|
987 {N_("help"), 1, gftpui_common_cmd_help, gftpui_common_request_none,
|
|
988 N_("Shows this help screen"), NULL},
|
|
989 {N_("lcd"), 3, gftpui_common_cmd_chdir, gftpui_common_request_local,
|
|
990 N_("Changes the local working directory"), NULL},
|
|
991 {N_("lchdir"), 4, gftpui_common_cmd_chdir, gftpui_common_request_local,
|
|
992 N_("Changes the local working directory"), NULL},
|
|
993 {N_("lchmod"), 4, gftpui_common_cmd_chmod, gftpui_common_request_local,
|
|
994 N_("Changes the permissions of a local file"), NULL},
|
|
995 {N_("ldelete"), 2, gftpui_common_cmd_delete, gftpui_common_request_local,
|
|
996 N_("Removes a local file"), NULL},
|
|
997 {N_("lls"), 2, gftpui_common_cmd_ls, gftpui_common_request_local,
|
|
998 N_("Shows the directory listing for the current local directory"), NULL},
|
|
999 {N_("lmkdir"), 2, gftpui_common_cmd_mkdir, gftpui_common_request_local,
|
|
1000 N_("Creates a local directory"), NULL},
|
|
1001 {N_("lpwd"), 2, gftpui_common_cmd_pwd, gftpui_common_request_local,
|
|
1002 N_("Show current local directory"), NULL},
|
|
1003 {N_("lrename"), 3, gftpui_common_cmd_rename, gftpui_common_request_local,
|
|
1004 N_("Rename a local file"), NULL},
|
|
1005 {N_("lrmdir"), 3, gftpui_common_cmd_rmdir, gftpui_common_request_local,
|
|
1006 N_("Remove a local directory"), NULL},
|
|
1007 {N_("ls"), 2, gftpui_common_cmd_ls, gftpui_common_request_remote,
|
|
1008 N_("Shows the directory listing for the current remote directory"), NULL},
|
377
|
1009 {N_("mget"), 2, gftpui_common_cmd_mget_file, gftpui_common_request_remote,
|
341
|
1010 N_("Downloads remote file(s)"), NULL},
|
377
|
1011 {N_("mkdir"), 2, gftpui_common_cmd_mkdir, gftpui_common_request_remote,
|
341
|
1012 N_("Creates a remote directory"), NULL},
|
377
|
1013 {N_("mput"), 2, gftpui_common_cmd_mput_file, gftpui_common_request_remote,
|
341
|
1014 N_("Uploads local file(s)"), NULL},
|
356
|
1015 {N_("open"), 1, gftpui_common_cmd_open, gftpui_common_request_remote,
|
341
|
1016 N_("Opens a connection to a remote site"), NULL},
|
377
|
1017 {N_("put"), 2, gftpui_common_cmd_mput_file, gftpui_common_request_remote,
|
341
|
1018 N_("Uploads local file(s)"), NULL},
|
|
1019 {N_("pwd"), 2, gftpui_common_cmd_pwd, gftpui_common_request_remote,
|
|
1020 N_("Show current remote directory"), NULL},
|
|
1021 {N_("quit"), 1, gftpui_common_cmd_quit, gftpui_common_request_none,
|
|
1022 N_("Exit from gFTP"), NULL},
|
|
1023 {N_("rename"), 2, gftpui_common_cmd_rename, gftpui_common_request_remote,
|
|
1024 N_("Rename a remote file"), NULL},
|
|
1025 {N_("rmdir"), 2, gftpui_common_cmd_rmdir, gftpui_common_request_remote,
|
|
1026 N_("Remove a remote directory"), NULL},
|
|
1027 {N_("set"), 1, gftpui_common_cmd_set, gftpui_common_request_none,
|
377
|
1028 N_("Show configuration file variables. You can also set variables by set var=val"),
|
|
1029 gftpui_common_set_show_subhelp},
|
350
|
1030 {N_("site"), 2, gftpui_common_cmd_site, gftpui_common_request_remote,
|
|
1031 N_("Run a site specific command"), NULL},
|
341
|
1032 {NULL, 0, NULL, gftpui_common_request_none,
|
|
1033 NULL, NULL}};
|
|
1034
|
|
1035
|
|
1036 int
|
374
|
1037 gftpui_common_process_command (void *locui, gftp_request * locreq,
|
|
1038 void *remui, gftp_request * remreq,
|
|
1039 const char *command)
|
341
|
1040 {
|
377
|
1041 gftp_request * request, * other_request;
|
|
1042 void *uidata, *other_uidata;
|
341
|
1043 char *pos, *newstr;
|
377
|
1044 const char *stpos;
|
341
|
1045 size_t cmdlen;
|
|
1046 int ret, i;
|
|
1047 size_t len;
|
|
1048
|
|
1049 for (stpos = command; *stpos == ' ' || *stpos == '\t'; stpos++);
|
|
1050
|
|
1051 newstr = g_strdup (stpos);
|
|
1052 len = strlen (newstr);
|
|
1053
|
|
1054 if (len > 0 && newstr[len - 1] == '\n')
|
|
1055 newstr[--len] = '\0';
|
|
1056 if (len > 0 && newstr[len - 1] == '\r')
|
|
1057 newstr[--len] = '\0';
|
|
1058
|
|
1059 for (pos = newstr + len - 1;
|
|
1060 (*pos == ' ' || *pos == '\t') && pos > newstr;
|
|
1061 pos--)
|
|
1062 *pos = '\0';
|
|
1063
|
|
1064 if (*stpos == '\0')
|
|
1065 {
|
|
1066 g_free (newstr);
|
|
1067 return (1);
|
|
1068 }
|
|
1069
|
|
1070 if ((pos = strchr (newstr, ' ')) != NULL)
|
|
1071 *pos = '\0';
|
|
1072
|
|
1073 cmdlen = strlen (newstr);
|
|
1074 for (i=0; gftpui_common_commands[i].command != NULL; i++)
|
|
1075 {
|
|
1076 if (strcmp (gftpui_common_commands[i].command, newstr) == 0)
|
|
1077 break;
|
|
1078 else if (cmdlen >= gftpui_common_commands[i].minlen &&
|
|
1079 strncmp (gftpui_common_commands[i].command, newstr, cmdlen) == 0)
|
|
1080 break;
|
|
1081 }
|
|
1082
|
|
1083 if (pos != NULL)
|
|
1084 pos++;
|
|
1085 else
|
|
1086 pos = "";
|
|
1087
|
374
|
1088 if (gftpui_common_commands[i].reqtype == gftpui_common_request_local)
|
|
1089 {
|
|
1090 request = locreq;
|
|
1091 uidata = locui;
|
377
|
1092
|
|
1093 other_request = remreq;
|
|
1094 other_uidata = remui;
|
374
|
1095 }
|
|
1096 else if (gftpui_common_commands[i].reqtype == gftpui_common_request_remote)
|
|
1097 {
|
|
1098 request = remreq;
|
|
1099 uidata = remui;
|
377
|
1100
|
|
1101 other_request = locreq;
|
|
1102 other_uidata = locui;
|
374
|
1103 }
|
|
1104 else
|
|
1105 {
|
377
|
1106 request = other_request = NULL;
|
|
1107 uidata = other_uidata = NULL;
|
374
|
1108 }
|
|
1109
|
341
|
1110 if (gftpui_common_commands[i].command != NULL)
|
|
1111 {
|
377
|
1112 ret = gftpui_common_commands[i].func (uidata, request,
|
|
1113 other_uidata, other_request, pos);
|
380
|
1114
|
387
|
1115 if (request != NULL && !GFTP_IS_CONNECTED (request))
|
380
|
1116 gftpui_disconnect (uidata);
|
341
|
1117 }
|
|
1118 else
|
|
1119 {
|
374
|
1120 gftpui_common_logfunc (gftp_logging_error, request,
|
|
1121 _("Error: Command not recognized\n"));
|
341
|
1122 ret = 1;
|
|
1123 }
|
|
1124
|
|
1125 g_free (newstr);
|
|
1126 return (ret);
|
|
1127 }
|
|
1128
|
367
|
1129
|
|
1130 gftp_transfer *
|
|
1131 gftpui_common_add_file_transfer (gftp_request * fromreq, gftp_request * toreq,
|
|
1132 void *fromuidata, void *touidata,
|
|
1133 GList * files)
|
|
1134 {
|
|
1135 intptr_t append_transfers, one_transfer;
|
|
1136 GList * templist, *curfle;
|
|
1137 gftp_transfer * tdata;
|
|
1138 gftp_file * tempfle;
|
|
1139 int show_dialog;
|
|
1140
|
|
1141 for (templist = files; templist != NULL; templist = templist->next)
|
|
1142 {
|
|
1143 tempfle = templist->data;
|
|
1144 if (tempfle->startsize > 0)
|
|
1145 break;
|
|
1146 }
|
|
1147 show_dialog = templist != NULL;
|
|
1148
|
|
1149 gftp_lookup_request_option (fromreq, "append_transfers",
|
|
1150 &append_transfers);
|
|
1151 gftp_lookup_request_option (fromreq, "one_transfer",
|
|
1152 &one_transfer);
|
|
1153
|
|
1154 tdata = NULL;
|
|
1155 if (append_transfers && one_transfer && !show_dialog)
|
|
1156 {
|
|
1157 if (g_thread_supported ())
|
|
1158 g_static_mutex_lock (&gftpui_common_transfer_mutex);
|
|
1159
|
|
1160 for (templist = gftp_file_transfers;
|
|
1161 templist != NULL;
|
|
1162 templist = templist->next)
|
|
1163 {
|
|
1164 tdata = templist->data;
|
|
1165
|
|
1166 if (g_thread_supported ())
|
|
1167 g_static_mutex_lock (&tdata->structmutex);
|
|
1168
|
|
1169 if (!compare_request (tdata->fromreq, fromreq, 0) ||
|
|
1170 !compare_request (tdata->toreq, toreq, 0) ||
|
|
1171 tdata->curfle == NULL)
|
|
1172 {
|
|
1173 if (g_thread_supported ())
|
|
1174 g_static_mutex_unlock (&tdata->structmutex);
|
|
1175
|
|
1176 continue;
|
|
1177 }
|
|
1178
|
|
1179 tdata->files = g_list_concat (tdata->files, files);
|
|
1180
|
|
1181 for (curfle = files; curfle != NULL; curfle = curfle->next)
|
|
1182 {
|
|
1183 tempfle = curfle->data;
|
|
1184
|
499
|
1185 if (S_ISDIR (tempfle->st_mode))
|
367
|
1186 tdata->numdirs++;
|
|
1187 else
|
|
1188 tdata->numfiles++;
|
|
1189
|
|
1190 if (tempfle->transfer_action != GFTP_TRANS_ACTION_SKIP)
|
|
1191 tdata->total_bytes += tempfle->size;
|
|
1192
|
397
|
1193 gftpui_add_file_to_transfer (tdata, curfle);
|
367
|
1194 }
|
|
1195
|
|
1196 if (g_thread_supported ())
|
|
1197 g_static_mutex_unlock (&tdata->structmutex);
|
|
1198
|
|
1199 break;
|
|
1200 }
|
|
1201
|
|
1202 if (g_thread_supported ())
|
|
1203 g_static_mutex_unlock (&gftpui_common_transfer_mutex);
|
|
1204 }
|
|
1205 else
|
|
1206 templist = NULL;
|
|
1207
|
|
1208 if (templist == NULL)
|
|
1209 {
|
|
1210 tdata = gftp_tdata_new ();
|
368
|
1211 tdata->fromreq = gftp_copy_request (fromreq);
|
|
1212 tdata->toreq = gftp_copy_request (toreq);
|
367
|
1213
|
|
1214 tdata->fromwdata = fromuidata;
|
|
1215 tdata->towdata = touidata;
|
|
1216
|
|
1217 if (!show_dialog)
|
|
1218 tdata->show = tdata->ready = 1;
|
|
1219
|
|
1220 tdata->files = files;
|
|
1221 for (curfle = files; curfle != NULL; curfle = curfle->next)
|
|
1222 {
|
|
1223 tempfle = curfle->data;
|
499
|
1224 if (S_ISDIR (tempfle->st_mode))
|
367
|
1225 tdata->numdirs++;
|
|
1226 else
|
|
1227 tdata->numfiles++;
|
|
1228
|
|
1229 if (tempfle->transfer_action != GFTP_TRANS_ACTION_SKIP)
|
|
1230 tdata->total_bytes += tempfle->size;
|
|
1231 }
|
|
1232
|
|
1233 if (g_thread_supported ())
|
|
1234 g_static_mutex_lock (&gftpui_common_transfer_mutex);
|
|
1235
|
|
1236 gftp_file_transfers = g_list_append (gftp_file_transfers, tdata);
|
|
1237
|
|
1238 if (g_thread_supported ())
|
|
1239 g_static_mutex_unlock (&gftpui_common_transfer_mutex);
|
|
1240
|
|
1241 if (show_dialog)
|
|
1242 gftpui_ask_transfer (tdata);
|
|
1243 }
|
|
1244
|
377
|
1245 gftpui_start_transfer (tdata);
|
367
|
1246 return (tdata);
|
|
1247 }
|
|
1248
|
|
1249
|
|
1250 static void
|
|
1251 _gftpui_common_setup_fds (gftp_transfer * tdata, gftp_file * curfle,
|
|
1252 int *fromfd, int *tofd)
|
|
1253 {
|
|
1254 *tofd = -1;
|
|
1255 *fromfd = -1;
|
|
1256
|
|
1257 if (curfle->is_fd)
|
|
1258 {
|
|
1259 if (tdata->toreq->protonum == GFTP_LOCAL_NUM)
|
|
1260 *tofd = curfle->fd;
|
|
1261 else if (tdata->fromreq->protonum == GFTP_LOCAL_NUM)
|
|
1262 *fromfd = curfle->fd;
|
|
1263 }
|
|
1264 }
|
|
1265
|
|
1266
|
|
1267 static void
|
|
1268 _gftpui_common_done_with_fds (gftp_transfer * tdata, gftp_file * curfle)
|
|
1269 {
|
|
1270 if (curfle->is_fd)
|
|
1271 {
|
|
1272 if (tdata->toreq->protonum == GFTP_LOCAL_NUM)
|
|
1273 tdata->toreq->datafd = -1;
|
|
1274 else
|
|
1275 tdata->fromreq->datafd = -1;
|
|
1276 }
|
|
1277 }
|
|
1278
|
|
1279
|
|
1280 int
|
|
1281 gftpui_common_transfer_files (gftp_transfer * tdata)
|
|
1282 {
|
377
|
1283 intptr_t preserve_permissions;
|
|
1284 struct timeval updatetime;
|
|
1285 ssize_t num_read, ret;
|
499
|
1286 int i, tofd, fromfd;
|
377
|
1287 gftp_file * curfle;
|
367
|
1288 char buf[8192];
|
|
1289
|
|
1290 tdata->curfle = tdata->files;
|
|
1291 gettimeofday (&tdata->starttime, NULL);
|
377
|
1292 memcpy (&tdata->lasttime, &tdata->starttime, sizeof (tdata->lasttime));
|
367
|
1293
|
|
1294 while (tdata->curfle != NULL)
|
|
1295 {
|
|
1296 num_read = -1;
|
|
1297
|
|
1298 if (g_thread_supported ())
|
|
1299 g_static_mutex_lock (&tdata->structmutex);
|
|
1300
|
|
1301 curfle = tdata->curfle->data;
|
|
1302 tdata->current_file_number++;
|
|
1303
|
|
1304 if (g_thread_supported ())
|
|
1305 g_static_mutex_unlock (&tdata->structmutex);
|
|
1306
|
|
1307 if (curfle->transfer_action == GFTP_TRANS_ACTION_SKIP)
|
|
1308 {
|
|
1309 if (g_thread_supported ())
|
|
1310 g_static_mutex_lock (&tdata->structmutex);
|
|
1311
|
|
1312 tdata->next_file = 1;
|
|
1313 tdata->curfle = tdata->curfle->next;
|
|
1314
|
|
1315 if (g_thread_supported ())
|
|
1316 g_static_mutex_unlock (&tdata->structmutex);
|
377
|
1317
|
367
|
1318 continue;
|
|
1319 }
|
|
1320
|
377
|
1321 tdata->tot_file_trans = -1;
|
367
|
1322 if (gftp_connect (tdata->fromreq) == 0 &&
|
|
1323 gftp_connect (tdata->toreq) == 0)
|
|
1324 {
|
499
|
1325 if (S_ISDIR (curfle->st_mode))
|
367
|
1326 {
|
|
1327 if (tdata->toreq->mkdir != NULL)
|
|
1328 {
|
|
1329 tdata->toreq->mkdir (tdata->toreq, curfle->destfile);
|
|
1330 if (!GFTP_IS_CONNECTED (tdata->toreq))
|
|
1331 break;
|
|
1332 }
|
|
1333
|
|
1334 if (g_thread_supported ())
|
|
1335 g_static_mutex_lock (&tdata->structmutex);
|
|
1336
|
|
1337 tdata->next_file = 1;
|
|
1338 tdata->curfle = tdata->curfle->next;
|
|
1339
|
|
1340 if (g_thread_supported ())
|
|
1341 g_static_mutex_unlock (&tdata->structmutex);
|
|
1342 continue;
|
|
1343 }
|
|
1344
|
|
1345 _gftpui_common_setup_fds (tdata, curfle, &fromfd, &tofd);
|
|
1346
|
|
1347 if (curfle->size == 0)
|
|
1348 {
|
|
1349 curfle->size = gftp_get_file_size (tdata->fromreq, curfle->file);
|
|
1350 tdata->total_bytes += curfle->size;
|
|
1351 }
|
|
1352
|
|
1353 if (GFTP_IS_CONNECTED (tdata->fromreq) &&
|
|
1354 GFTP_IS_CONNECTED (tdata->toreq))
|
|
1355 {
|
377
|
1356 tdata->tot_file_trans = gftp_transfer_file (tdata->fromreq,
|
|
1357 curfle->file, fromfd,
|
367
|
1358 curfle->transfer_action == GFTP_TRANS_ACTION_RESUME ?
|
|
1359 curfle->startsize : 0,
|
|
1360 tdata->toreq, curfle->destfile, tofd,
|
|
1361 curfle->transfer_action == GFTP_TRANS_ACTION_RESUME ?
|
|
1362 curfle->startsize : 0);
|
|
1363 }
|
|
1364 }
|
|
1365
|
|
1366 if (!GFTP_IS_CONNECTED (tdata->fromreq) ||
|
|
1367 !GFTP_IS_CONNECTED (tdata->toreq))
|
|
1368 {
|
|
1369 tdata->fromreq->logging_function (gftp_logging_misc,
|
|
1370 tdata->fromreq,
|
377
|
1371 _("Error: Remote site disconnected after trying to transfer file\n"));
|
367
|
1372 }
|
377
|
1373 else if (tdata->tot_file_trans < 0)
|
367
|
1374 {
|
|
1375 if (g_thread_supported ())
|
|
1376 g_static_mutex_lock (&tdata->structmutex);
|
|
1377
|
|
1378 curfle->transfer_action = GFTP_TRANS_ACTION_SKIP;
|
|
1379 tdata->next_file = 1;
|
|
1380 tdata->curfle = tdata->curfle->next;
|
|
1381
|
|
1382 if (g_thread_supported ())
|
|
1383 g_static_mutex_unlock (&tdata->structmutex);
|
|
1384 continue;
|
|
1385 }
|
|
1386 else
|
|
1387 {
|
|
1388 if (g_thread_supported ())
|
|
1389 g_static_mutex_lock (&tdata->structmutex);
|
|
1390
|
|
1391 tdata->curtrans = 0;
|
|
1392 tdata->curresumed = curfle->transfer_action == GFTP_TRANS_ACTION_RESUME ? curfle->startsize : 0;
|
|
1393 tdata->resumed_bytes += tdata->curresumed;
|
|
1394
|
|
1395 if (g_thread_supported ())
|
|
1396 g_static_mutex_unlock (&tdata->structmutex);
|
|
1397
|
377
|
1398 memset (&updatetime, 0, sizeof (updatetime));
|
|
1399 gftpui_start_current_file_in_transfer (tdata);
|
|
1400
|
367
|
1401 i = 0;
|
|
1402 while (!tdata->cancel &&
|
|
1403 (num_read = gftp_get_next_file_chunk (tdata->fromreq,
|
|
1404 buf, sizeof (buf))) > 0)
|
|
1405 {
|
|
1406 gftp_calc_kbs (tdata, num_read);
|
377
|
1407 if (tdata->lasttime.tv_sec - updatetime.tv_sec >= 1 ||
|
|
1408 tdata->curtrans >= tdata->tot_file_trans)
|
|
1409 {
|
|
1410 gftpui_update_current_file_in_transfer (tdata);
|
|
1411 memcpy (&updatetime, &tdata->lasttime, sizeof (updatetime));
|
|
1412 }
|
367
|
1413
|
|
1414 if ((ret = gftp_put_next_file_chunk (tdata->toreq, buf,
|
|
1415 num_read)) < 0)
|
|
1416 {
|
|
1417 num_read = (int) ret;
|
|
1418 break;
|
|
1419 }
|
|
1420 }
|
377
|
1421
|
426
|
1422 if (num_read == GFTP_ENOTRANS)
|
|
1423 num_read = 0;
|
|
1424
|
377
|
1425 gftpui_finish_current_file_in_transfer (tdata);
|
367
|
1426 }
|
|
1427
|
|
1428 if (tdata->cancel)
|
|
1429 {
|
|
1430 if (gftp_abort_transfer (tdata->fromreq) != 0)
|
|
1431 gftp_disconnect (tdata->fromreq);
|
|
1432
|
|
1433 if (gftp_abort_transfer (tdata->toreq) != 0)
|
|
1434 gftp_disconnect (tdata->toreq);
|
|
1435 }
|
|
1436 else if (num_read < 0)
|
|
1437 {
|
|
1438 tdata->fromreq->logging_function (gftp_logging_misc,
|
|
1439 tdata->fromreq,
|
|
1440 _("Could not download %s from %s\n"),
|
|
1441 curfle->file,
|
|
1442 tdata->fromreq->hostname);
|
|
1443
|
|
1444 if (gftp_get_transfer_status (tdata, num_read) == GFTP_ERETRYABLE)
|
|
1445 continue;
|
|
1446
|
|
1447 break;
|
|
1448 }
|
|
1449 else
|
|
1450 {
|
|
1451 _gftpui_common_done_with_fds (tdata, curfle);
|
|
1452 if (gftp_end_transfer (tdata->fromreq) != 0)
|
|
1453 {
|
|
1454 if (gftp_get_transfer_status (tdata, -1) == GFTP_ERETRYABLE)
|
|
1455 continue;
|
|
1456
|
|
1457 break;
|
|
1458 }
|
|
1459 gftp_end_transfer (tdata->toreq);
|
|
1460
|
|
1461 tdata->fromreq->logging_function (gftp_logging_misc,
|
|
1462 tdata->fromreq,
|
377
|
1463 _("Successfully transferred %s at %.2f KB/s\n"),
|
367
|
1464 curfle->file, tdata->kbs);
|
|
1465 }
|
|
1466
|
377
|
1467 gftp_lookup_request_option (tdata->fromreq, "preserve_permissions",
|
|
1468 &preserve_permissions);
|
|
1469
|
367
|
1470 if (!curfle->is_fd && preserve_permissions)
|
|
1471 {
|
499
|
1472 if (curfle->st_mode != 0)
|
504
|
1473 gftp_chmod (tdata->toreq, curfle->destfile,
|
|
1474 curfle->st_mode & (S_IRWXU | S_IRWXG | S_IRWXO));
|
367
|
1475
|
|
1476 if (curfle->datetime != 0)
|
|
1477 gftp_set_file_time (tdata->toreq, curfle->destfile,
|
|
1478 curfle->datetime);
|
|
1479 }
|
|
1480
|
|
1481 if (g_thread_supported ())
|
|
1482 g_static_mutex_lock (&tdata->structmutex);
|
|
1483
|
|
1484 tdata->curtrans = 0;
|
|
1485 tdata->next_file = 1;
|
|
1486 curfle->transfer_done = 1;
|
|
1487 tdata->curfle = tdata->curfle->next;
|
|
1488
|
|
1489 if (g_thread_supported ())
|
|
1490 g_static_mutex_unlock (&tdata->structmutex);
|
|
1491
|
|
1492 if (tdata->cancel && !tdata->skip_file)
|
|
1493 break;
|
|
1494 tdata->cancel = 0;
|
|
1495 tdata->fromreq->cancel = 0;
|
|
1496 tdata->toreq->cancel = 0;
|
|
1497 }
|
|
1498 tdata->done = 1;
|
|
1499
|
387
|
1500 return (1);
|
367
|
1501 }
|
|
1502
|
469
|
1503
|
|
1504 void
|
|
1505 gftpui_protocol_update_timeout (gftp_request * request)
|
|
1506 {
|
|
1507 intptr_t network_timeout;
|
|
1508
|
|
1509 gftp_lookup_request_option (request, "network_timeout", &network_timeout);
|
|
1510
|
|
1511 if (network_timeout > 0)
|
|
1512 alarm (network_timeout);
|
|
1513 }
|
|
1514
|