341
|
1 /*****************************************************************************/
|
|
2 /* gftpui.c - UI related functions for gFTP */
|
|
3 /* Copyright (C) 1998-2003 Brian Masney <masneyb@gftp.org> */
|
|
4 /* */
|
|
5 /* This program is free software; you can redistribute it and/or modify */
|
|
6 /* it under the terms of the GNU General Public License as published by */
|
|
7 /* the Free Software Foundation; either version 2 of the License, or */
|
|
8 /* (at your option) any later version. */
|
|
9 /* */
|
|
10 /* This program is distributed in the hope that it will be useful, */
|
|
11 /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
|
|
12 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
|
|
13 /* GNU General Public License for more details. */
|
|
14 /* */
|
|
15 /* You should have received a copy of the GNU General Public License */
|
|
16 /* along with this program; if not, write to the Free Software */
|
|
17 /* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA */
|
|
18 /*****************************************************************************/
|
|
19
|
|
20 #include "gftpui.h"
|
|
21 static const char cvsid[] = "$Id$";
|
|
22
|
|
23 sigjmp_buf gftpui_common_jmp_environment;
|
|
24 volatile int gftpui_common_use_jmp_environment = 0;
|
|
25
|
367
|
26 GStaticMutex gftpui_common_transfer_mutex = G_STATIC_MUTEX_INIT;
|
374
|
27 volatile sig_atomic_t gftpui_common_child_process_done = 0;
|
518
|
28 static gftp_logging_func gftpui_common_logfunc;
|
341
|
29
|
|
30
|
510
|
31 static int
|
|
32 _gftpui_cb_connect (gftpui_callback_data * cdata)
|
|
33 {
|
|
34 if (cdata->connect_function != NULL)
|
|
35 return (cdata->connect_function (cdata));
|
|
36 else
|
|
37 return (gftp_connect (cdata->request));
|
|
38 }
|
|
39
|
|
40
|
|
41 static void
|
|
42 _gftpui_cb_disconnect (gftpui_callback_data * cdata)
|
|
43 {
|
|
44 if (cdata->connect_function != NULL)
|
|
45 cdata->disconnect_function (cdata);
|
|
46 else
|
|
47 gftp_disconnect (cdata->request);
|
|
48 }
|
|
49
|
|
50
|
341
|
51 static void *
|
|
52 _gftpui_common_thread_callback (void * data)
|
|
53 {
|
367
|
54 intptr_t network_timeout, sleep_time;
|
341
|
55 gftpui_callback_data * cdata;
|
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--;
|
677
|
90 cdata->request->logging_function (gftp_logging_error, cdata->request,
|
367
|
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)
|
766
|
139 exit (EXIT_FAILURE);
|
341
|
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)
|
766
|
176 exit (EXIT_FAILURE);
|
374
|
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 {
|
555
|
476 tempstr = gftp_build_path (request, request->directory, command,
|
|
477 NULL);
|
|
478 newdir = gftp_expand_path (request, tempstr);
|
341
|
479 g_free (tempstr);
|
|
480 }
|
|
481 else
|
555
|
482 newdir = gftp_expand_path (request, command);
|
341
|
483
|
|
484 if (newdir == NULL)
|
|
485 {
|
|
486 request->logging_function (gftp_logging_error, request,
|
|
487 _("usage: chdir <directory>\n"));
|
|
488 return (1);
|
|
489 }
|
|
490 }
|
|
491
|
350
|
492 cdata = g_malloc0 (sizeof (*cdata));
|
|
493 cdata->request = request;
|
|
494 cdata->uidata = uidata;
|
374
|
495 cdata->input_string = newdir != NULL ? newdir : (char *) command;
|
350
|
496 cdata->run_function = gftpui_common_run_chdir;
|
514
|
497 cdata->dont_clear_cache = 1;
|
350
|
498
|
|
499 gftpui_common_run_callback_function (cdata);
|
|
500
|
|
501 g_free (cdata);
|
341
|
502
|
|
503 if (newdir != NULL)
|
|
504 g_free (newdir);
|
|
505
|
|
506 return (1);
|
|
507 }
|
|
508
|
|
509
|
|
510 static int
|
374
|
511 gftpui_common_cmd_close (void *uidata, gftp_request * request,
|
377
|
512 void *other_uidata, gftp_request * other_request,
|
374
|
513 const char *command)
|
341
|
514 {
|
|
515 gftp_disconnect (request);
|
|
516 return (1);
|
|
517 }
|
|
518
|
|
519
|
|
520 static int
|
374
|
521 gftpui_common_cmd_pwd (void *uidata, gftp_request * request,
|
377
|
522 void *other_uidata, gftp_request * other_request,
|
374
|
523 const char *command)
|
341
|
524 {
|
|
525 if (!GFTP_IS_CONNECTED (request))
|
|
526 {
|
|
527 request->logging_function (gftp_logging_error, request,
|
|
528 _("Error: Not connected to a remote site\n"));
|
|
529 return (1);
|
|
530 }
|
|
531
|
|
532 request->logging_function (gftp_logging_misc, request,
|
|
533 "%s\n", request->directory);
|
|
534
|
|
535 return (1);
|
|
536 }
|
|
537
|
|
538
|
|
539 static int
|
374
|
540 gftpui_common_cmd_quit (void *uidata, gftp_request * request,
|
377
|
541 void *other_uidata, gftp_request * other_request,
|
374
|
542 const char *command)
|
341
|
543 {
|
|
544 gftp_shutdown();
|
|
545
|
|
546 return (0);
|
|
547 }
|
|
548
|
|
549
|
|
550 static int
|
374
|
551 gftpui_common_cmd_clear (void *uidata, gftp_request * request,
|
377
|
552 void *other_uidata, gftp_request * other_request,
|
374
|
553 const char *command)
|
341
|
554 {
|
|
555 if (strcasecmp (command, "cache") == 0)
|
|
556 gftp_clear_cache_files ();
|
|
557 else
|
|
558 {
|
374
|
559 gftpui_common_logfunc (gftp_logging_error, request,
|
|
560 _("Invalid argument\n"));
|
341
|
561 }
|
|
562
|
|
563 return (1);
|
|
564 }
|
|
565
|
|
566
|
|
567 static int
|
374
|
568 gftpui_common_clear_show_subhelp (const char *topic)
|
341
|
569 {
|
|
570 if (strcmp (topic, "cache") == 0)
|
|
571 {
|
374
|
572 gftpui_common_logfunc (gftp_logging_misc, NULL,
|
|
573 _("Clear the directory cache\n"));
|
341
|
574 return (1);
|
|
575 }
|
|
576
|
|
577 return (0);
|
|
578 }
|
|
579
|
|
580
|
|
581 static int
|
374
|
582 gftpui_common_set_show_subhelp (const char *topic)
|
341
|
583 {
|
|
584 gftp_config_vars * cv;
|
|
585
|
|
586 if ((cv = g_hash_table_lookup (gftp_global_options_htable, topic)) != NULL)
|
|
587 {
|
374
|
588 gftpui_common_logfunc (gftp_logging_misc, NULL, "%s\n", cv->comment);
|
341
|
589 return (1);
|
|
590 }
|
|
591
|
|
592 return (0);
|
|
593 }
|
|
594
|
|
595
|
355
|
596 static int
|
374
|
597 gftpui_common_cmd_ls (void *uidata, gftp_request * request,
|
377
|
598 void *other_uidata, gftp_request * other_request,
|
374
|
599 const char *command)
|
341
|
600 {
|
355
|
601 char *startcolor, *endcolor, *tempstr;
|
|
602 gftpui_callback_data * cdata;
|
|
603 GList * templist;
|
341
|
604 gftp_file * fle;
|
|
605
|
|
606 if (!GFTP_IS_CONNECTED (request))
|
|
607 {
|
|
608 request->logging_function (gftp_logging_error, request,
|
|
609 _("Error: Not connected to a remote site\n"));
|
|
610 return (1);
|
|
611 }
|
|
612
|
355
|
613 cdata = g_malloc0 (sizeof (*cdata));
|
|
614 cdata->request = request;
|
|
615 cdata->uidata = uidata;
|
374
|
616 cdata->source_string = *command != '\0' ? (char *) command : NULL;
|
355
|
617 cdata->run_function = gftpui_common_run_ls;
|
511
|
618 cdata->dont_refresh = 1;
|
341
|
619
|
355
|
620 gftpui_common_run_callback_function (cdata);
|
341
|
621
|
355
|
622 templist = cdata->files;
|
|
623 while (templist != NULL)
|
341
|
624 {
|
|
625 fle = templist->data;
|
|
626
|
|
627 gftpui_lookup_file_colors (fle, &startcolor, &endcolor);
|
|
628 tempstr = gftp_gen_ls_string (fle, startcolor, endcolor);
|
573
|
629 request->logging_function (gftp_logging_misc_nolog, request, "%s\n",
|
354
|
630 tempstr);
|
341
|
631 g_free (tempstr);
|
|
632
|
355
|
633 templist = templist->next;
|
598
|
634 gftp_file_destroy (fle, 1);
|
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
|
553
|
670 if (gftp_need_username (request))
|
|
671 gftpui_prompt_username (uidata, request);
|
356
|
672
|
553
|
673 if (gftp_need_password (request))
|
|
674 gftpui_prompt_password (uidata, request);
|
356
|
675
|
367
|
676 gftp_lookup_request_option (request, "retries", &retries);
|
|
677
|
|
678 cdata = g_malloc0 (sizeof (*cdata));
|
|
679 cdata->request = request;
|
|
680 cdata->uidata = uidata;
|
|
681 cdata->run_function = gftpui_common_run_connect;
|
|
682 cdata->retries = retries;
|
451
|
683 cdata->dont_check_connection = 1;
|
367
|
684
|
775
|
685 gftpui_show_busy (TRUE);
|
367
|
686 gftpui_common_run_callback_function (cdata);
|
775
|
687 gftpui_show_busy (FALSE);
|
367
|
688
|
|
689 g_free (cdata);
|
356
|
690
|
|
691 return (1);
|
|
692 }
|
|
693
|
|
694
|
|
695 static int
|
374
|
696 gftpui_common_cmd_set (void *uidata, gftp_request * request,
|
377
|
697 void *other_uidata, gftp_request * other_request,
|
374
|
698 const char *command)
|
341
|
699 {
|
387
|
700 char *pos, *backpos, buf[256];
|
341
|
701 gftp_config_vars * cv, newcv;
|
|
702 GList * templist;
|
|
703 int i;
|
|
704
|
|
705 if (command == NULL || *command == '\0')
|
|
706 {
|
|
707 for (templist = gftp_options_list;
|
|
708 templist != NULL;
|
|
709 templist = templist->next)
|
|
710 {
|
|
711 cv = templist->data;
|
|
712
|
|
713 for (i=0; cv[i].key != NULL; i++)
|
|
714 {
|
|
715 if (!(cv[i].ports_shown & GFTP_PORT_TEXT))
|
|
716 continue;
|
|
717
|
|
718 if (*cv[i].key == '\0' ||
|
|
719 gftp_option_types[cv[i].otype].write_function == NULL)
|
|
720 continue;
|
|
721
|
387
|
722 gftp_option_types[cv[i].otype].write_function (&cv[i], buf,
|
|
723 sizeof (buf), 0);
|
|
724
|
|
725 gftpui_common_logfunc (gftp_logging_misc_nolog, request,
|
|
726 "%s = %s\n", cv[i].key, buf);
|
341
|
727 }
|
|
728 }
|
|
729 }
|
|
730 else
|
|
731 {
|
|
732 if ((pos = strchr (command, '=')) == NULL)
|
|
733 {
|
374
|
734 gftpui_common_logfunc (gftp_logging_error, request,
|
|
735 _("usage: set [variable = value]\n"));
|
341
|
736 return (1);
|
|
737 }
|
|
738 *pos = '\0';
|
|
739
|
|
740 for (backpos = pos - 1;
|
|
741 (*backpos == ' ' || *backpos == '\t') && backpos > command;
|
|
742 backpos--)
|
|
743 *backpos = '\0';
|
|
744 for (++pos; *pos == ' ' || *pos == '\t'; pos++);
|
|
745
|
|
746 if ((cv = g_hash_table_lookup (gftp_global_options_htable, command)) == NULL)
|
|
747 {
|
374
|
748 gftpui_common_logfunc (gftp_logging_error, request,
|
|
749 _("Error: Variable %s is not a valid configuration variable.\n"), command);
|
341
|
750 return (1);
|
|
751 }
|
|
752
|
|
753 if (!(cv->ports_shown & GFTP_PORT_TEXT))
|
|
754 {
|
374
|
755 gftpui_common_logfunc (gftp_logging_error, request,
|
|
756 _("Error: Variable %s is not available in the text port of gFTP\n"), command);
|
341
|
757 return (1);
|
|
758 }
|
|
759
|
|
760 if (gftp_option_types[cv->otype].read_function != NULL)
|
|
761 {
|
|
762 memcpy (&newcv, cv, sizeof (newcv));
|
|
763 newcv.flags &= ~GFTP_CVARS_FLAGS_DYNMEM;
|
|
764
|
|
765 gftp_option_types[cv->otype].read_function (pos, &newcv, 1);
|
|
766
|
|
767 gftp_set_global_option (command, newcv.value);
|
|
768
|
387
|
769 gftp_option_types[newcv.otype].write_function (&newcv, buf,
|
|
770 sizeof (buf), 0);
|
|
771
|
|
772 gftpui_common_logfunc (gftp_logging_misc_nolog, request,
|
|
773 "%s = %s\n", newcv.key, buf);
|
|
774
|
341
|
775 if (newcv.flags & GFTP_CVARS_FLAGS_DYNMEM)
|
|
776 g_free (newcv.value);
|
574
|
777
|
|
778 gftp_configuration_changed = 1;
|
341
|
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 {
|
598
|
901 gftp_file_destroy (fle, 0);
|
377
|
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},
|
651
|
984 {N_("dir"), 3, gftpui_common_cmd_ls, gftpui_common_request_remote,
|
|
985 N_("Shows the directory listing for the current remote directory"), NULL},
|
377
|
986 {N_("get"), 1, gftpui_common_cmd_mget_file, gftpui_common_request_remote,
|
341
|
987 N_("Downloads remote file(s)"), NULL},
|
|
988 {N_("help"), 1, gftpui_common_cmd_help, gftpui_common_request_none,
|
|
989 N_("Shows this help screen"), NULL},
|
|
990 {N_("lcd"), 3, gftpui_common_cmd_chdir, gftpui_common_request_local,
|
|
991 N_("Changes the local working directory"), NULL},
|
|
992 {N_("lchdir"), 4, gftpui_common_cmd_chdir, gftpui_common_request_local,
|
|
993 N_("Changes the local working directory"), NULL},
|
|
994 {N_("lchmod"), 4, gftpui_common_cmd_chmod, gftpui_common_request_local,
|
|
995 N_("Changes the permissions of a local file"), NULL},
|
|
996 {N_("ldelete"), 2, gftpui_common_cmd_delete, gftpui_common_request_local,
|
|
997 N_("Removes a local file"), NULL},
|
651
|
998 {N_("ldir"), 4, gftpui_common_cmd_ls, gftpui_common_request_local,
|
|
999 N_("Shows the directory listing for the current local directory"), NULL},
|
341
|
1000 {N_("lls"), 2, gftpui_common_cmd_ls, gftpui_common_request_local,
|
|
1001 N_("Shows the directory listing for the current local directory"), NULL},
|
|
1002 {N_("lmkdir"), 2, gftpui_common_cmd_mkdir, gftpui_common_request_local,
|
|
1003 N_("Creates a local directory"), NULL},
|
|
1004 {N_("lpwd"), 2, gftpui_common_cmd_pwd, gftpui_common_request_local,
|
|
1005 N_("Show current local directory"), NULL},
|
|
1006 {N_("lrename"), 3, gftpui_common_cmd_rename, gftpui_common_request_local,
|
|
1007 N_("Rename a local file"), NULL},
|
|
1008 {N_("lrmdir"), 3, gftpui_common_cmd_rmdir, gftpui_common_request_local,
|
|
1009 N_("Remove a local directory"), NULL},
|
|
1010 {N_("ls"), 2, gftpui_common_cmd_ls, gftpui_common_request_remote,
|
|
1011 N_("Shows the directory listing for the current remote directory"), NULL},
|
377
|
1012 {N_("mget"), 2, gftpui_common_cmd_mget_file, gftpui_common_request_remote,
|
341
|
1013 N_("Downloads remote file(s)"), NULL},
|
377
|
1014 {N_("mkdir"), 2, gftpui_common_cmd_mkdir, gftpui_common_request_remote,
|
341
|
1015 N_("Creates a remote directory"), NULL},
|
377
|
1016 {N_("mput"), 2, gftpui_common_cmd_mput_file, gftpui_common_request_remote,
|
341
|
1017 N_("Uploads local file(s)"), NULL},
|
356
|
1018 {N_("open"), 1, gftpui_common_cmd_open, gftpui_common_request_remote,
|
341
|
1019 N_("Opens a connection to a remote site"), NULL},
|
377
|
1020 {N_("put"), 2, gftpui_common_cmd_mput_file, gftpui_common_request_remote,
|
341
|
1021 N_("Uploads local file(s)"), NULL},
|
|
1022 {N_("pwd"), 2, gftpui_common_cmd_pwd, gftpui_common_request_remote,
|
|
1023 N_("Show current remote directory"), NULL},
|
|
1024 {N_("quit"), 1, gftpui_common_cmd_quit, gftpui_common_request_none,
|
|
1025 N_("Exit from gFTP"), NULL},
|
|
1026 {N_("rename"), 2, gftpui_common_cmd_rename, gftpui_common_request_remote,
|
|
1027 N_("Rename a remote file"), NULL},
|
|
1028 {N_("rmdir"), 2, gftpui_common_cmd_rmdir, gftpui_common_request_remote,
|
|
1029 N_("Remove a remote directory"), NULL},
|
|
1030 {N_("set"), 1, gftpui_common_cmd_set, gftpui_common_request_none,
|
377
|
1031 N_("Show configuration file variables. You can also set variables by set var=val"),
|
|
1032 gftpui_common_set_show_subhelp},
|
350
|
1033 {N_("site"), 2, gftpui_common_cmd_site, gftpui_common_request_remote,
|
|
1034 N_("Run a site specific command"), NULL},
|
341
|
1035 {NULL, 0, NULL, gftpui_common_request_none,
|
|
1036 NULL, NULL}};
|
|
1037
|
|
1038
|
|
1039 int
|
374
|
1040 gftpui_common_process_command (void *locui, gftp_request * locreq,
|
|
1041 void *remui, gftp_request * remreq,
|
|
1042 const char *command)
|
341
|
1043 {
|
377
|
1044 gftp_request * request, * other_request;
|
|
1045 void *uidata, *other_uidata;
|
341
|
1046 char *pos, *newstr;
|
377
|
1047 const char *stpos;
|
341
|
1048 size_t cmdlen;
|
|
1049 int ret, i;
|
|
1050 size_t len;
|
|
1051
|
|
1052 for (stpos = command; *stpos == ' ' || *stpos == '\t'; stpos++);
|
|
1053
|
|
1054 newstr = g_strdup (stpos);
|
|
1055 len = strlen (newstr);
|
|
1056
|
|
1057 if (len > 0 && newstr[len - 1] == '\n')
|
|
1058 newstr[--len] = '\0';
|
|
1059 if (len > 0 && newstr[len - 1] == '\r')
|
|
1060 newstr[--len] = '\0';
|
|
1061
|
|
1062 for (pos = newstr + len - 1;
|
|
1063 (*pos == ' ' || *pos == '\t') && pos > newstr;
|
|
1064 pos--)
|
|
1065 *pos = '\0';
|
|
1066
|
|
1067 if (*stpos == '\0')
|
|
1068 {
|
|
1069 g_free (newstr);
|
|
1070 return (1);
|
|
1071 }
|
|
1072
|
|
1073 if ((pos = strchr (newstr, ' ')) != NULL)
|
|
1074 *pos = '\0';
|
|
1075
|
|
1076 cmdlen = strlen (newstr);
|
|
1077 for (i=0; gftpui_common_commands[i].command != NULL; i++)
|
|
1078 {
|
|
1079 if (strcmp (gftpui_common_commands[i].command, newstr) == 0)
|
|
1080 break;
|
|
1081 else if (cmdlen >= gftpui_common_commands[i].minlen &&
|
|
1082 strncmp (gftpui_common_commands[i].command, newstr, cmdlen) == 0)
|
|
1083 break;
|
|
1084 }
|
|
1085
|
|
1086 if (pos != NULL)
|
|
1087 pos++;
|
|
1088 else
|
|
1089 pos = "";
|
|
1090
|
374
|
1091 if (gftpui_common_commands[i].reqtype == gftpui_common_request_local)
|
|
1092 {
|
|
1093 request = locreq;
|
|
1094 uidata = locui;
|
377
|
1095
|
|
1096 other_request = remreq;
|
|
1097 other_uidata = remui;
|
374
|
1098 }
|
|
1099 else if (gftpui_common_commands[i].reqtype == gftpui_common_request_remote)
|
|
1100 {
|
|
1101 request = remreq;
|
|
1102 uidata = remui;
|
377
|
1103
|
|
1104 other_request = locreq;
|
|
1105 other_uidata = locui;
|
374
|
1106 }
|
|
1107 else
|
|
1108 {
|
377
|
1109 request = other_request = NULL;
|
|
1110 uidata = other_uidata = NULL;
|
374
|
1111 }
|
|
1112
|
341
|
1113 if (gftpui_common_commands[i].command != NULL)
|
|
1114 {
|
377
|
1115 ret = gftpui_common_commands[i].func (uidata, request,
|
|
1116 other_uidata, other_request, pos);
|
380
|
1117
|
387
|
1118 if (request != NULL && !GFTP_IS_CONNECTED (request))
|
380
|
1119 gftpui_disconnect (uidata);
|
341
|
1120 }
|
|
1121 else
|
|
1122 {
|
374
|
1123 gftpui_common_logfunc (gftp_logging_error, request,
|
|
1124 _("Error: Command not recognized\n"));
|
341
|
1125 ret = 1;
|
|
1126 }
|
|
1127
|
|
1128 g_free (newstr);
|
|
1129 return (ret);
|
|
1130 }
|
|
1131
|
367
|
1132
|
|
1133 gftp_transfer *
|
|
1134 gftpui_common_add_file_transfer (gftp_request * fromreq, gftp_request * toreq,
|
|
1135 void *fromuidata, void *touidata,
|
|
1136 GList * files)
|
|
1137 {
|
|
1138 intptr_t append_transfers, one_transfer;
|
|
1139 GList * templist, *curfle;
|
|
1140 gftp_transfer * tdata;
|
|
1141 gftp_file * tempfle;
|
|
1142 int show_dialog;
|
|
1143
|
|
1144 for (templist = files; templist != NULL; templist = templist->next)
|
|
1145 {
|
|
1146 tempfle = templist->data;
|
|
1147 if (tempfle->startsize > 0)
|
|
1148 break;
|
|
1149 }
|
|
1150 show_dialog = templist != NULL;
|
|
1151
|
|
1152 gftp_lookup_request_option (fromreq, "append_transfers",
|
|
1153 &append_transfers);
|
|
1154 gftp_lookup_request_option (fromreq, "one_transfer",
|
|
1155 &one_transfer);
|
|
1156
|
|
1157 tdata = NULL;
|
|
1158 if (append_transfers && one_transfer && !show_dialog)
|
|
1159 {
|
|
1160 if (g_thread_supported ())
|
|
1161 g_static_mutex_lock (&gftpui_common_transfer_mutex);
|
|
1162
|
|
1163 for (templist = gftp_file_transfers;
|
|
1164 templist != NULL;
|
|
1165 templist = templist->next)
|
|
1166 {
|
|
1167 tdata = templist->data;
|
|
1168
|
|
1169 if (g_thread_supported ())
|
|
1170 g_static_mutex_lock (&tdata->structmutex);
|
|
1171
|
|
1172 if (!compare_request (tdata->fromreq, fromreq, 0) ||
|
|
1173 !compare_request (tdata->toreq, toreq, 0) ||
|
|
1174 tdata->curfle == NULL)
|
|
1175 {
|
|
1176 if (g_thread_supported ())
|
|
1177 g_static_mutex_unlock (&tdata->structmutex);
|
|
1178
|
|
1179 continue;
|
|
1180 }
|
|
1181
|
|
1182 tdata->files = g_list_concat (tdata->files, files);
|
|
1183
|
|
1184 for (curfle = files; curfle != NULL; curfle = curfle->next)
|
|
1185 {
|
|
1186 tempfle = curfle->data;
|
|
1187
|
499
|
1188 if (S_ISDIR (tempfle->st_mode))
|
367
|
1189 tdata->numdirs++;
|
|
1190 else
|
|
1191 tdata->numfiles++;
|
|
1192
|
|
1193 if (tempfle->transfer_action != GFTP_TRANS_ACTION_SKIP)
|
|
1194 tdata->total_bytes += tempfle->size;
|
|
1195
|
397
|
1196 gftpui_add_file_to_transfer (tdata, curfle);
|
367
|
1197 }
|
|
1198
|
|
1199 if (g_thread_supported ())
|
|
1200 g_static_mutex_unlock (&tdata->structmutex);
|
|
1201
|
|
1202 break;
|
|
1203 }
|
|
1204
|
|
1205 if (g_thread_supported ())
|
|
1206 g_static_mutex_unlock (&gftpui_common_transfer_mutex);
|
|
1207 }
|
|
1208 else
|
|
1209 templist = NULL;
|
|
1210
|
|
1211 if (templist == NULL)
|
|
1212 {
|
|
1213 tdata = gftp_tdata_new ();
|
368
|
1214 tdata->fromreq = gftp_copy_request (fromreq);
|
|
1215 tdata->toreq = gftp_copy_request (toreq);
|
367
|
1216
|
|
1217 tdata->fromwdata = fromuidata;
|
|
1218 tdata->towdata = touidata;
|
|
1219
|
|
1220 if (!show_dialog)
|
|
1221 tdata->show = tdata->ready = 1;
|
|
1222
|
|
1223 tdata->files = files;
|
|
1224 for (curfle = files; curfle != NULL; curfle = curfle->next)
|
|
1225 {
|
|
1226 tempfle = curfle->data;
|
499
|
1227 if (S_ISDIR (tempfle->st_mode))
|
367
|
1228 tdata->numdirs++;
|
|
1229 else
|
|
1230 tdata->numfiles++;
|
|
1231
|
|
1232 if (tempfle->transfer_action != GFTP_TRANS_ACTION_SKIP)
|
|
1233 tdata->total_bytes += tempfle->size;
|
|
1234 }
|
|
1235
|
|
1236 if (g_thread_supported ())
|
|
1237 g_static_mutex_lock (&gftpui_common_transfer_mutex);
|
|
1238
|
|
1239 gftp_file_transfers = g_list_append (gftp_file_transfers, tdata);
|
|
1240
|
|
1241 if (g_thread_supported ())
|
|
1242 g_static_mutex_unlock (&gftpui_common_transfer_mutex);
|
|
1243
|
|
1244 if (show_dialog)
|
|
1245 gftpui_ask_transfer (tdata);
|
|
1246 }
|
|
1247
|
377
|
1248 gftpui_start_transfer (tdata);
|
367
|
1249 return (tdata);
|
|
1250 }
|
|
1251
|
|
1252
|
|
1253 static void
|
|
1254 _gftpui_common_setup_fds (gftp_transfer * tdata, gftp_file * curfle,
|
|
1255 int *fromfd, int *tofd)
|
|
1256 {
|
|
1257 *tofd = -1;
|
|
1258 *fromfd = -1;
|
|
1259
|
|
1260 if (curfle->is_fd)
|
|
1261 {
|
|
1262 if (tdata->toreq->protonum == GFTP_LOCAL_NUM)
|
|
1263 *tofd = curfle->fd;
|
|
1264 else if (tdata->fromreq->protonum == GFTP_LOCAL_NUM)
|
|
1265 *fromfd = curfle->fd;
|
|
1266 }
|
|
1267 }
|
|
1268
|
|
1269
|
|
1270 static void
|
|
1271 _gftpui_common_done_with_fds (gftp_transfer * tdata, gftp_file * curfle)
|
|
1272 {
|
|
1273 if (curfle->is_fd)
|
|
1274 {
|
|
1275 if (tdata->toreq->protonum == GFTP_LOCAL_NUM)
|
|
1276 tdata->toreq->datafd = -1;
|
|
1277 else
|
|
1278 tdata->fromreq->datafd = -1;
|
|
1279 }
|
|
1280 }
|
|
1281
|
|
1282
|
|
1283 int
|
|
1284 gftpui_common_transfer_files (gftp_transfer * tdata)
|
|
1285 {
|
560
|
1286 intptr_t preserve_permissions, preserve_time, trans_blksize;
|
377
|
1287 struct timeval updatetime;
|
|
1288 ssize_t num_read, ret;
|
|
1289 gftp_file * curfle;
|
517
|
1290 int tofd, fromfd;
|
527
|
1291 char *buf;
|
|
1292
|
|
1293 gftp_lookup_request_option (tdata->fromreq, "trans_blksize", &trans_blksize);
|
|
1294 buf = g_malloc (trans_blksize);
|
367
|
1295
|
|
1296 tdata->curfle = tdata->files;
|
|
1297 gettimeofday (&tdata->starttime, NULL);
|
377
|
1298 memcpy (&tdata->lasttime, &tdata->starttime, sizeof (tdata->lasttime));
|
367
|
1299
|
774
|
1300 gftp_lookup_request_option (tdata->fromreq, "preserve_permissions",
|
|
1301 &preserve_permissions);
|
|
1302 gftp_lookup_request_option (tdata->fromreq, "preserve_time",
|
|
1303 &preserve_time);
|
|
1304
|
367
|
1305 while (tdata->curfle != NULL)
|
|
1306 {
|
|
1307 num_read = -1;
|
|
1308
|
|
1309 if (g_thread_supported ())
|
|
1310 g_static_mutex_lock (&tdata->structmutex);
|
|
1311
|
|
1312 curfle = tdata->curfle->data;
|
|
1313 tdata->current_file_number++;
|
|
1314
|
|
1315 if (g_thread_supported ())
|
|
1316 g_static_mutex_unlock (&tdata->structmutex);
|
|
1317
|
|
1318 if (curfle->transfer_action == GFTP_TRANS_ACTION_SKIP)
|
|
1319 {
|
|
1320 if (g_thread_supported ())
|
|
1321 g_static_mutex_lock (&tdata->structmutex);
|
|
1322
|
|
1323 tdata->next_file = 1;
|
|
1324 tdata->curfle = tdata->curfle->next;
|
|
1325
|
|
1326 if (g_thread_supported ())
|
|
1327 g_static_mutex_unlock (&tdata->structmutex);
|
377
|
1328
|
367
|
1329 continue;
|
|
1330 }
|
|
1331
|
377
|
1332 tdata->tot_file_trans = -1;
|
367
|
1333 if (gftp_connect (tdata->fromreq) == 0 &&
|
|
1334 gftp_connect (tdata->toreq) == 0)
|
|
1335 {
|
499
|
1336 if (S_ISDIR (curfle->st_mode))
|
367
|
1337 {
|
|
1338 if (tdata->toreq->mkdir != NULL)
|
|
1339 {
|
|
1340 tdata->toreq->mkdir (tdata->toreq, curfle->destfile);
|
|
1341 if (!GFTP_IS_CONNECTED (tdata->toreq))
|
|
1342 break;
|
774
|
1343
|
|
1344 if (preserve_permissions && curfle->st_mode != 0)
|
|
1345 gftp_chmod (tdata->toreq, curfle->destfile,
|
|
1346 curfle->st_mode & (S_IRWXU | S_IRWXG | S_IRWXO));
|
|
1347
|
|
1348 if (preserve_time && curfle->datetime != 0)
|
|
1349 gftp_set_file_time (tdata->toreq, curfle->destfile,
|
|
1350 curfle->datetime);
|
367
|
1351 }
|
|
1352
|
|
1353 if (g_thread_supported ())
|
|
1354 g_static_mutex_lock (&tdata->structmutex);
|
|
1355
|
|
1356 tdata->next_file = 1;
|
|
1357 tdata->curfle = tdata->curfle->next;
|
|
1358
|
|
1359 if (g_thread_supported ())
|
|
1360 g_static_mutex_unlock (&tdata->structmutex);
|
|
1361 continue;
|
|
1362 }
|
|
1363
|
|
1364 _gftpui_common_setup_fds (tdata, curfle, &fromfd, &tofd);
|
|
1365
|
|
1366 if (curfle->size == 0)
|
|
1367 {
|
|
1368 curfle->size = gftp_get_file_size (tdata->fromreq, curfle->file);
|
|
1369 tdata->total_bytes += curfle->size;
|
|
1370 }
|
|
1371
|
|
1372 if (GFTP_IS_CONNECTED (tdata->fromreq) &&
|
|
1373 GFTP_IS_CONNECTED (tdata->toreq))
|
|
1374 {
|
377
|
1375 tdata->tot_file_trans = gftp_transfer_file (tdata->fromreq,
|
|
1376 curfle->file, fromfd,
|
367
|
1377 curfle->transfer_action == GFTP_TRANS_ACTION_RESUME ?
|
|
1378 curfle->startsize : 0,
|
|
1379 tdata->toreq, curfle->destfile, tofd,
|
|
1380 curfle->transfer_action == GFTP_TRANS_ACTION_RESUME ?
|
|
1381 curfle->startsize : 0);
|
|
1382 }
|
|
1383 }
|
|
1384
|
|
1385 if (!GFTP_IS_CONNECTED (tdata->fromreq) ||
|
|
1386 !GFTP_IS_CONNECTED (tdata->toreq))
|
|
1387 {
|
677
|
1388 tdata->fromreq->logging_function (gftp_logging_error,
|
367
|
1389 tdata->fromreq,
|
377
|
1390 _("Error: Remote site disconnected after trying to transfer file\n"));
|
367
|
1391 }
|
377
|
1392 else if (tdata->tot_file_trans < 0)
|
367
|
1393 {
|
|
1394 if (g_thread_supported ())
|
|
1395 g_static_mutex_lock (&tdata->structmutex);
|
|
1396
|
|
1397 curfle->transfer_action = GFTP_TRANS_ACTION_SKIP;
|
|
1398 tdata->next_file = 1;
|
|
1399 tdata->curfle = tdata->curfle->next;
|
|
1400
|
|
1401 if (g_thread_supported ())
|
|
1402 g_static_mutex_unlock (&tdata->structmutex);
|
|
1403 continue;
|
|
1404 }
|
|
1405 else
|
|
1406 {
|
|
1407 if (g_thread_supported ())
|
|
1408 g_static_mutex_lock (&tdata->structmutex);
|
|
1409
|
|
1410 tdata->curtrans = 0;
|
|
1411 tdata->curresumed = curfle->transfer_action == GFTP_TRANS_ACTION_RESUME ? curfle->startsize : 0;
|
|
1412 tdata->resumed_bytes += tdata->curresumed;
|
|
1413
|
|
1414 if (g_thread_supported ())
|
|
1415 g_static_mutex_unlock (&tdata->structmutex);
|
|
1416
|
377
|
1417 memset (&updatetime, 0, sizeof (updatetime));
|
|
1418 gftpui_start_current_file_in_transfer (tdata);
|
|
1419
|
367
|
1420 while (!tdata->cancel &&
|
|
1421 (num_read = gftp_get_next_file_chunk (tdata->fromreq,
|
527
|
1422 buf, trans_blksize)) > 0)
|
367
|
1423 {
|
|
1424 gftp_calc_kbs (tdata, num_read);
|
377
|
1425 if (tdata->lasttime.tv_sec - updatetime.tv_sec >= 1 ||
|
|
1426 tdata->curtrans >= tdata->tot_file_trans)
|
|
1427 {
|
|
1428 gftpui_update_current_file_in_transfer (tdata);
|
|
1429 memcpy (&updatetime, &tdata->lasttime, sizeof (updatetime));
|
|
1430 }
|
367
|
1431
|
|
1432 if ((ret = gftp_put_next_file_chunk (tdata->toreq, buf,
|
|
1433 num_read)) < 0)
|
|
1434 {
|
|
1435 num_read = (int) ret;
|
|
1436 break;
|
|
1437 }
|
|
1438 }
|
377
|
1439
|
426
|
1440 if (num_read == GFTP_ENOTRANS)
|
|
1441 num_read = 0;
|
|
1442
|
377
|
1443 gftpui_finish_current_file_in_transfer (tdata);
|
367
|
1444 }
|
|
1445
|
|
1446 if (tdata->cancel)
|
|
1447 {
|
|
1448 if (gftp_abort_transfer (tdata->fromreq) != 0)
|
|
1449 gftp_disconnect (tdata->fromreq);
|
|
1450
|
|
1451 if (gftp_abort_transfer (tdata->toreq) != 0)
|
|
1452 gftp_disconnect (tdata->toreq);
|
|
1453 }
|
|
1454 else if (num_read < 0)
|
|
1455 {
|
677
|
1456 tdata->fromreq->logging_function (gftp_logging_error,
|
367
|
1457 tdata->fromreq,
|
|
1458 _("Could not download %s from %s\n"),
|
|
1459 curfle->file,
|
|
1460 tdata->fromreq->hostname);
|
|
1461
|
|
1462 if (gftp_get_transfer_status (tdata, num_read) == GFTP_ERETRYABLE)
|
|
1463 continue;
|
|
1464
|
|
1465 break;
|
|
1466 }
|
|
1467 else
|
|
1468 {
|
|
1469 _gftpui_common_done_with_fds (tdata, curfle);
|
|
1470 if (gftp_end_transfer (tdata->fromreq) != 0)
|
|
1471 {
|
|
1472 if (gftp_get_transfer_status (tdata, -1) == GFTP_ERETRYABLE)
|
|
1473 continue;
|
|
1474
|
|
1475 break;
|
|
1476 }
|
|
1477
|
652
|
1478 if (gftp_end_transfer (tdata->toreq) == 0)
|
|
1479 {
|
|
1480 tdata->fromreq->logging_function (gftp_logging_misc,
|
|
1481 tdata->fromreq,
|
|
1482 _("Successfully transferred %s at %.2f KB/s\n"),
|
|
1483 curfle->file, tdata->kbs);
|
|
1484 }
|
|
1485 else
|
|
1486 {
|
|
1487 tdata->fromreq->logging_function (gftp_logging_error,
|
|
1488 tdata->fromreq,
|
|
1489 _("There was an error transfering the file %s"),
|
|
1490 curfle->file);
|
|
1491 }
|
367
|
1492 }
|
|
1493
|
560
|
1494 if (!curfle->is_fd)
|
367
|
1495 {
|
560
|
1496 if (preserve_permissions && curfle->st_mode != 0)
|
504
|
1497 gftp_chmod (tdata->toreq, curfle->destfile,
|
|
1498 curfle->st_mode & (S_IRWXU | S_IRWXG | S_IRWXO));
|
367
|
1499
|
560
|
1500 if (preserve_time && curfle->datetime != 0)
|
367
|
1501 gftp_set_file_time (tdata->toreq, curfle->destfile,
|
|
1502 curfle->datetime);
|
|
1503 }
|
|
1504
|
|
1505 if (g_thread_supported ())
|
|
1506 g_static_mutex_lock (&tdata->structmutex);
|
|
1507
|
|
1508 tdata->curtrans = 0;
|
|
1509 tdata->next_file = 1;
|
|
1510 curfle->transfer_done = 1;
|
|
1511 tdata->curfle = tdata->curfle->next;
|
|
1512
|
|
1513 if (g_thread_supported ())
|
|
1514 g_static_mutex_unlock (&tdata->structmutex);
|
|
1515
|
|
1516 if (tdata->cancel && !tdata->skip_file)
|
|
1517 break;
|
|
1518 tdata->cancel = 0;
|
|
1519 tdata->fromreq->cancel = 0;
|
|
1520 tdata->toreq->cancel = 0;
|
|
1521 }
|
527
|
1522
|
367
|
1523 tdata->done = 1;
|
527
|
1524 g_free (buf);
|
367
|
1525
|
387
|
1526 return (1);
|
367
|
1527 }
|
|
1528
|
469
|
1529
|
|
1530 void
|
|
1531 gftpui_protocol_update_timeout (gftp_request * request)
|
|
1532 {
|
|
1533 intptr_t network_timeout;
|
|
1534
|
|
1535 gftp_lookup_request_option (request, "network_timeout", &network_timeout);
|
|
1536
|
|
1537 if (network_timeout > 0)
|
|
1538 alarm (network_timeout);
|
|
1539 }
|
|
1540
|