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