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);
|
422
|
629 request->logging_function (gftp_logging_misc_nolog, request, "%s",
|
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);
|
|
776 }
|
|
777 }
|
|
778
|
|
779 return (1);
|
|
780 }
|
|
781
|
|
782
|
|
783 static int
|
374
|
784 gftpui_common_cmd_help (void *uidata, gftp_request * request,
|
377
|
785 void *other_uidata, gftp_request * other_request,
|
374
|
786 const char *command)
|
341
|
787 {
|
374
|
788 int i, j, ele, numrows, numcols = 6, handled, number_commands, cmdlen,
|
|
789 found;
|
387
|
790 char commands[128], cmdstr[30];
|
374
|
791 const char *pos;
|
341
|
792
|
|
793 for (number_commands=0;
|
|
794 gftpui_common_commands[number_commands].command != NULL;
|
|
795 number_commands++);
|
|
796
|
|
797 if (command != NULL && *command != '\0')
|
|
798 {
|
|
799 for (pos = command; *pos != ' ' && *pos != '\0'; pos++);
|
374
|
800 cmdlen = pos - command;
|
341
|
801
|
|
802 for (i=0; gftpui_common_commands[i].command != NULL; i++)
|
|
803 {
|
374
|
804 if (strncmp (gftpui_common_commands[i].command, command, cmdlen) == 0)
|
341
|
805 break;
|
|
806 }
|
|
807
|
|
808 if (gftpui_common_commands[i].cmd_description != NULL)
|
|
809 {
|
374
|
810 found = 1;
|
|
811
|
|
812 if (*pos != '\0' && *(pos + 1) != '\0' &&
|
|
813 gftpui_common_commands[i].subhelp_func != NULL)
|
|
814 handled = gftpui_common_commands[i].subhelp_func (pos + 1);
|
341
|
815 else
|
|
816 handled = 0;
|
|
817
|
|
818 if (!handled)
|
387
|
819 gftpui_common_logfunc (gftp_logging_misc_nolog, request, "%s\n",
|
|
820 _(gftpui_common_commands[i].cmd_description));
|
341
|
821 }
|
|
822 else
|
374
|
823 found = 0;
|
341
|
824 }
|
374
|
825 else
|
|
826 found = 0;
|
341
|
827
|
374
|
828 if (!found)
|
341
|
829 {
|
|
830 numrows = number_commands / numcols;
|
|
831 if (number_commands % numcols != 0)
|
|
832 numrows++;
|
|
833
|
387
|
834 gftpui_common_logfunc (gftp_logging_misc_nolog, request,
|
|
835 _("Supported commands:\n\n"));
|
|
836
|
341
|
837 for (i=0; i<numrows; i++)
|
|
838 {
|
387
|
839 strncpy (commands, "\t", sizeof (commands));
|
|
840
|
341
|
841 for (j=0; j<numcols; j++)
|
|
842 {
|
|
843 ele = i + j * numrows;
|
|
844 if (ele >= number_commands)
|
|
845 break;
|
387
|
846
|
|
847 g_snprintf (cmdstr, sizeof (cmdstr), "%-10s",
|
|
848 gftpui_common_commands[ele].command);
|
|
849 strncat (commands, cmdstr, sizeof (commands));
|
341
|
850 }
|
387
|
851 gftpui_common_logfunc (gftp_logging_misc_nolog, request, "%s\n",
|
|
852 commands);
|
341
|
853 }
|
|
854 }
|
|
855 return (1);
|
|
856 }
|
|
857
|
|
858
|
377
|
859 static void
|
|
860 _gftpui_common_transfer_files (void *fromuidata, gftp_request * fromrequest,
|
|
861 void *touidata, gftp_request * torequest,
|
|
862 const char *cmd, const char *filespec)
|
|
863 {
|
|
864 gftp_transfer * tdata;
|
|
865 gftp_file * fle;
|
|
866
|
|
867 if (!GFTP_IS_CONNECTED (fromrequest) ||
|
|
868 !GFTP_IS_CONNECTED (torequest))
|
|
869 {
|
|
870 fromrequest->logging_function (gftp_logging_error, fromrequest,
|
|
871 _("Error: Not connected to a remote site\n"));
|
|
872 return;
|
|
873 }
|
|
874
|
|
875 if (*filespec == '\0')
|
|
876 {
|
|
877 fromrequest->logging_function (gftp_logging_error, fromrequest,
|
|
878 _("usage: %s <filespec>\n"), cmd);
|
|
879 return;
|
|
880 }
|
|
881
|
|
882 tdata = gftp_tdata_new ();
|
|
883 tdata->fromreq = fromrequest;
|
|
884 tdata->toreq = torequest;
|
|
885
|
|
886 if (gftp_list_files (tdata->fromreq) != 0)
|
|
887 {
|
|
888 tdata->fromreq = tdata->toreq = NULL;
|
|
889 free_tdata (tdata);
|
|
890 return;
|
|
891 }
|
|
892
|
|
893 fle = g_malloc0 (sizeof (*fle));
|
|
894 while (gftp_get_next_file (tdata->fromreq, filespec, fle) > 0)
|
|
895 {
|
|
896 if (strcmp (fle->file, ".") == 0 || strcmp (fle->file, "..") == 0)
|
|
897 {
|
|
898 gftp_file_destroy (fle);
|
|
899 continue;
|
|
900 }
|
|
901
|
|
902 tdata->files = g_list_append (tdata->files, fle);
|
|
903 fle = g_malloc (sizeof (*fle));
|
|
904 }
|
|
905
|
|
906 g_free (fle);
|
|
907
|
|
908 gftp_end_transfer (tdata->fromreq);
|
|
909
|
|
910 if (tdata->files == NULL)
|
|
911 {
|
|
912 tdata->fromreq = tdata->toreq = NULL;
|
|
913 free_tdata (tdata);
|
|
914 return;
|
|
915 }
|
|
916
|
|
917 if (gftp_get_all_subdirs (tdata, NULL) != 0)
|
|
918 {
|
|
919 tdata->fromreq = tdata->toreq = NULL;
|
|
920 free_tdata (tdata);
|
|
921 return;
|
|
922 }
|
|
923
|
|
924 if (tdata->files == NULL)
|
|
925 {
|
|
926 tdata->fromreq = tdata->toreq = NULL;
|
|
927 free_tdata (tdata);
|
|
928 return;
|
|
929 }
|
|
930
|
|
931 gftpui_common_add_file_transfer (tdata->fromreq, tdata->toreq,
|
|
932 fromuidata, touidata, tdata->files);
|
|
933
|
|
934 g_free (tdata);
|
|
935
|
|
936 return;
|
|
937 }
|
|
938
|
|
939
|
|
940 int
|
|
941 gftpui_common_cmd_mget_file (void *uidata, gftp_request * request,
|
|
942 void *other_uidata, gftp_request * other_request,
|
|
943 const char *command)
|
|
944 {
|
|
945 _gftpui_common_transfer_files (uidata, request, other_uidata, other_request,
|
|
946 "mget", command);
|
|
947 return (1);
|
|
948 }
|
|
949
|
|
950
|
|
951 int
|
|
952 gftpui_common_cmd_mput_file (void *uidata, gftp_request * request,
|
|
953 void *other_uidata, gftp_request * other_request,
|
|
954 const char *command)
|
|
955 {
|
|
956 _gftpui_common_transfer_files (other_uidata, other_request, uidata, request,
|
|
957 "mput", command);
|
|
958 return (1);
|
|
959 }
|
|
960
|
|
961
|
341
|
962 gftpui_common_methods gftpui_common_commands[] = {
|
|
963 {N_("about"), 2, gftpui_common_cmd_about, gftpui_common_request_none,
|
|
964 N_("Shows gFTP information"), NULL},
|
|
965 {N_("ascii"), 2, gftpui_common_cmd_ascii, gftpui_common_request_remote,
|
|
966 N_("Sets the current file transfer mode to Ascii (only for FTP)"), NULL},
|
|
967 {N_("binary"), 1, gftpui_common_cmd_binary, gftpui_common_request_remote,
|
|
968 N_("Sets the current file transfer mode to Binary (only for FTP)"), NULL},
|
|
969 {N_("cd"), 2, gftpui_common_cmd_chdir, gftpui_common_request_remote,
|
|
970 N_("Changes the remote working directory"), NULL},
|
|
971 {N_("chdir"), 3, gftpui_common_cmd_chdir, gftpui_common_request_remote,
|
|
972 N_("Changes the remote working directory"), NULL},
|
|
973 {N_("chmod"), 3, gftpui_common_cmd_chmod, gftpui_common_request_remote,
|
|
974 N_("Changes the permissions of a remote file"), NULL},
|
|
975 {N_("clear"), 3, gftpui_common_cmd_clear, gftpui_common_request_none,
|
|
976 N_("Available options: cache"), gftpui_common_clear_show_subhelp},
|
|
977 {N_("close"), 3, gftpui_common_cmd_close, gftpui_common_request_remote,
|
|
978 N_("Disconnects from the remote site"), NULL},
|
350
|
979 {N_("delete"), 1, gftpui_common_cmd_delete, gftpui_common_request_remote,
|
341
|
980 N_("Removes a remote file"), NULL},
|
377
|
981 {N_("get"), 1, gftpui_common_cmd_mget_file, gftpui_common_request_remote,
|
341
|
982 N_("Downloads remote file(s)"), NULL},
|
|
983 {N_("help"), 1, gftpui_common_cmd_help, gftpui_common_request_none,
|
|
984 N_("Shows this help screen"), NULL},
|
|
985 {N_("lcd"), 3, gftpui_common_cmd_chdir, gftpui_common_request_local,
|
|
986 N_("Changes the local working directory"), NULL},
|
|
987 {N_("lchdir"), 4, gftpui_common_cmd_chdir, gftpui_common_request_local,
|
|
988 N_("Changes the local working directory"), NULL},
|
|
989 {N_("lchmod"), 4, gftpui_common_cmd_chmod, gftpui_common_request_local,
|
|
990 N_("Changes the permissions of a local file"), NULL},
|
|
991 {N_("ldelete"), 2, gftpui_common_cmd_delete, gftpui_common_request_local,
|
|
992 N_("Removes a local file"), NULL},
|
|
993 {N_("lls"), 2, gftpui_common_cmd_ls, gftpui_common_request_local,
|
|
994 N_("Shows the directory listing for the current local directory"), NULL},
|
|
995 {N_("lmkdir"), 2, gftpui_common_cmd_mkdir, gftpui_common_request_local,
|
|
996 N_("Creates a local directory"), NULL},
|
|
997 {N_("lpwd"), 2, gftpui_common_cmd_pwd, gftpui_common_request_local,
|
|
998 N_("Show current local directory"), NULL},
|
|
999 {N_("lrename"), 3, gftpui_common_cmd_rename, gftpui_common_request_local,
|
|
1000 N_("Rename a local file"), NULL},
|
|
1001 {N_("lrmdir"), 3, gftpui_common_cmd_rmdir, gftpui_common_request_local,
|
|
1002 N_("Remove a local directory"), NULL},
|
|
1003 {N_("ls"), 2, gftpui_common_cmd_ls, gftpui_common_request_remote,
|
|
1004 N_("Shows the directory listing for the current remote directory"), NULL},
|
377
|
1005 {N_("mget"), 2, gftpui_common_cmd_mget_file, gftpui_common_request_remote,
|
341
|
1006 N_("Downloads remote file(s)"), NULL},
|
377
|
1007 {N_("mkdir"), 2, gftpui_common_cmd_mkdir, gftpui_common_request_remote,
|
341
|
1008 N_("Creates a remote directory"), NULL},
|
377
|
1009 {N_("mput"), 2, gftpui_common_cmd_mput_file, gftpui_common_request_remote,
|
341
|
1010 N_("Uploads local file(s)"), NULL},
|
356
|
1011 {N_("open"), 1, gftpui_common_cmd_open, gftpui_common_request_remote,
|
341
|
1012 N_("Opens a connection to a remote site"), NULL},
|
377
|
1013 {N_("put"), 2, gftpui_common_cmd_mput_file, gftpui_common_request_remote,
|
341
|
1014 N_("Uploads local file(s)"), NULL},
|
|
1015 {N_("pwd"), 2, gftpui_common_cmd_pwd, gftpui_common_request_remote,
|
|
1016 N_("Show current remote directory"), NULL},
|
|
1017 {N_("quit"), 1, gftpui_common_cmd_quit, gftpui_common_request_none,
|
|
1018 N_("Exit from gFTP"), NULL},
|
|
1019 {N_("rename"), 2, gftpui_common_cmd_rename, gftpui_common_request_remote,
|
|
1020 N_("Rename a remote file"), NULL},
|
|
1021 {N_("rmdir"), 2, gftpui_common_cmd_rmdir, gftpui_common_request_remote,
|
|
1022 N_("Remove a remote directory"), NULL},
|
|
1023 {N_("set"), 1, gftpui_common_cmd_set, gftpui_common_request_none,
|
377
|
1024 N_("Show configuration file variables. You can also set variables by set var=val"),
|
|
1025 gftpui_common_set_show_subhelp},
|
350
|
1026 {N_("site"), 2, gftpui_common_cmd_site, gftpui_common_request_remote,
|
|
1027 N_("Run a site specific command"), NULL},
|
341
|
1028 {NULL, 0, NULL, gftpui_common_request_none,
|
|
1029 NULL, NULL}};
|
|
1030
|
|
1031
|
|
1032 int
|
374
|
1033 gftpui_common_process_command (void *locui, gftp_request * locreq,
|
|
1034 void *remui, gftp_request * remreq,
|
|
1035 const char *command)
|
341
|
1036 {
|
377
|
1037 gftp_request * request, * other_request;
|
|
1038 void *uidata, *other_uidata;
|
341
|
1039 char *pos, *newstr;
|
377
|
1040 const char *stpos;
|
341
|
1041 size_t cmdlen;
|
|
1042 int ret, i;
|
|
1043 size_t len;
|
|
1044
|
|
1045 for (stpos = command; *stpos == ' ' || *stpos == '\t'; stpos++);
|
|
1046
|
|
1047 newstr = g_strdup (stpos);
|
|
1048 len = strlen (newstr);
|
|
1049
|
|
1050 if (len > 0 && newstr[len - 1] == '\n')
|
|
1051 newstr[--len] = '\0';
|
|
1052 if (len > 0 && newstr[len - 1] == '\r')
|
|
1053 newstr[--len] = '\0';
|
|
1054
|
|
1055 for (pos = newstr + len - 1;
|
|
1056 (*pos == ' ' || *pos == '\t') && pos > newstr;
|
|
1057 pos--)
|
|
1058 *pos = '\0';
|
|
1059
|
|
1060 if (*stpos == '\0')
|
|
1061 {
|
|
1062 g_free (newstr);
|
|
1063 return (1);
|
|
1064 }
|
|
1065
|
|
1066 if ((pos = strchr (newstr, ' ')) != NULL)
|
|
1067 *pos = '\0';
|
|
1068
|
|
1069 cmdlen = strlen (newstr);
|
|
1070 for (i=0; gftpui_common_commands[i].command != NULL; i++)
|
|
1071 {
|
|
1072 if (strcmp (gftpui_common_commands[i].command, newstr) == 0)
|
|
1073 break;
|
|
1074 else if (cmdlen >= gftpui_common_commands[i].minlen &&
|
|
1075 strncmp (gftpui_common_commands[i].command, newstr, cmdlen) == 0)
|
|
1076 break;
|
|
1077 }
|
|
1078
|
|
1079 if (pos != NULL)
|
|
1080 pos++;
|
|
1081 else
|
|
1082 pos = "";
|
|
1083
|
374
|
1084 if (gftpui_common_commands[i].reqtype == gftpui_common_request_local)
|
|
1085 {
|
|
1086 request = locreq;
|
|
1087 uidata = locui;
|
377
|
1088
|
|
1089 other_request = remreq;
|
|
1090 other_uidata = remui;
|
374
|
1091 }
|
|
1092 else if (gftpui_common_commands[i].reqtype == gftpui_common_request_remote)
|
|
1093 {
|
|
1094 request = remreq;
|
|
1095 uidata = remui;
|
377
|
1096
|
|
1097 other_request = locreq;
|
|
1098 other_uidata = locui;
|
374
|
1099 }
|
|
1100 else
|
|
1101 {
|
377
|
1102 request = other_request = NULL;
|
|
1103 uidata = other_uidata = NULL;
|
374
|
1104 }
|
|
1105
|
341
|
1106 if (gftpui_common_commands[i].command != NULL)
|
|
1107 {
|
377
|
1108 ret = gftpui_common_commands[i].func (uidata, request,
|
|
1109 other_uidata, other_request, pos);
|
380
|
1110
|
387
|
1111 if (request != NULL && !GFTP_IS_CONNECTED (request))
|
380
|
1112 gftpui_disconnect (uidata);
|
341
|
1113 }
|
|
1114 else
|
|
1115 {
|
374
|
1116 gftpui_common_logfunc (gftp_logging_error, request,
|
|
1117 _("Error: Command not recognized\n"));
|
341
|
1118 ret = 1;
|
|
1119 }
|
|
1120
|
|
1121 g_free (newstr);
|
|
1122 return (ret);
|
|
1123 }
|
|
1124
|
367
|
1125
|
|
1126 gftp_transfer *
|
|
1127 gftpui_common_add_file_transfer (gftp_request * fromreq, gftp_request * toreq,
|
|
1128 void *fromuidata, void *touidata,
|
|
1129 GList * files)
|
|
1130 {
|
|
1131 intptr_t append_transfers, one_transfer;
|
|
1132 GList * templist, *curfle;
|
|
1133 gftp_transfer * tdata;
|
|
1134 gftp_file * tempfle;
|
|
1135 int show_dialog;
|
|
1136
|
|
1137 for (templist = files; templist != NULL; templist = templist->next)
|
|
1138 {
|
|
1139 tempfle = templist->data;
|
|
1140 if (tempfle->startsize > 0)
|
|
1141 break;
|
|
1142 }
|
|
1143 show_dialog = templist != NULL;
|
|
1144
|
|
1145 gftp_lookup_request_option (fromreq, "append_transfers",
|
|
1146 &append_transfers);
|
|
1147 gftp_lookup_request_option (fromreq, "one_transfer",
|
|
1148 &one_transfer);
|
|
1149
|
|
1150 tdata = NULL;
|
|
1151 if (append_transfers && one_transfer && !show_dialog)
|
|
1152 {
|
|
1153 if (g_thread_supported ())
|
|
1154 g_static_mutex_lock (&gftpui_common_transfer_mutex);
|
|
1155
|
|
1156 for (templist = gftp_file_transfers;
|
|
1157 templist != NULL;
|
|
1158 templist = templist->next)
|
|
1159 {
|
|
1160 tdata = templist->data;
|
|
1161
|
|
1162 if (g_thread_supported ())
|
|
1163 g_static_mutex_lock (&tdata->structmutex);
|
|
1164
|
|
1165 if (!compare_request (tdata->fromreq, fromreq, 0) ||
|
|
1166 !compare_request (tdata->toreq, toreq, 0) ||
|
|
1167 tdata->curfle == NULL)
|
|
1168 {
|
|
1169 if (g_thread_supported ())
|
|
1170 g_static_mutex_unlock (&tdata->structmutex);
|
|
1171
|
|
1172 continue;
|
|
1173 }
|
|
1174
|
|
1175 tdata->files = g_list_concat (tdata->files, files);
|
|
1176
|
|
1177 for (curfle = files; curfle != NULL; curfle = curfle->next)
|
|
1178 {
|
|
1179 tempfle = curfle->data;
|
|
1180
|
499
|
1181 if (S_ISDIR (tempfle->st_mode))
|
367
|
1182 tdata->numdirs++;
|
|
1183 else
|
|
1184 tdata->numfiles++;
|
|
1185
|
|
1186 if (tempfle->transfer_action != GFTP_TRANS_ACTION_SKIP)
|
|
1187 tdata->total_bytes += tempfle->size;
|
|
1188
|
397
|
1189 gftpui_add_file_to_transfer (tdata, curfle);
|
367
|
1190 }
|
|
1191
|
|
1192 if (g_thread_supported ())
|
|
1193 g_static_mutex_unlock (&tdata->structmutex);
|
|
1194
|
|
1195 break;
|
|
1196 }
|
|
1197
|
|
1198 if (g_thread_supported ())
|
|
1199 g_static_mutex_unlock (&gftpui_common_transfer_mutex);
|
|
1200 }
|
|
1201 else
|
|
1202 templist = NULL;
|
|
1203
|
|
1204 if (templist == NULL)
|
|
1205 {
|
|
1206 tdata = gftp_tdata_new ();
|
368
|
1207 tdata->fromreq = gftp_copy_request (fromreq);
|
|
1208 tdata->toreq = gftp_copy_request (toreq);
|
367
|
1209
|
|
1210 tdata->fromwdata = fromuidata;
|
|
1211 tdata->towdata = touidata;
|
|
1212
|
|
1213 if (!show_dialog)
|
|
1214 tdata->show = tdata->ready = 1;
|
|
1215
|
|
1216 tdata->files = files;
|
|
1217 for (curfle = files; curfle != NULL; curfle = curfle->next)
|
|
1218 {
|
|
1219 tempfle = curfle->data;
|
499
|
1220 if (S_ISDIR (tempfle->st_mode))
|
367
|
1221 tdata->numdirs++;
|
|
1222 else
|
|
1223 tdata->numfiles++;
|
|
1224
|
|
1225 if (tempfle->transfer_action != GFTP_TRANS_ACTION_SKIP)
|
|
1226 tdata->total_bytes += tempfle->size;
|
|
1227 }
|
|
1228
|
|
1229 if (g_thread_supported ())
|
|
1230 g_static_mutex_lock (&gftpui_common_transfer_mutex);
|
|
1231
|
|
1232 gftp_file_transfers = g_list_append (gftp_file_transfers, tdata);
|
|
1233
|
|
1234 if (g_thread_supported ())
|
|
1235 g_static_mutex_unlock (&gftpui_common_transfer_mutex);
|
|
1236
|
|
1237 if (show_dialog)
|
|
1238 gftpui_ask_transfer (tdata);
|
|
1239 }
|
|
1240
|
377
|
1241 gftpui_start_transfer (tdata);
|
367
|
1242 return (tdata);
|
|
1243 }
|
|
1244
|
|
1245
|
|
1246 static void
|
|
1247 _gftpui_common_setup_fds (gftp_transfer * tdata, gftp_file * curfle,
|
|
1248 int *fromfd, int *tofd)
|
|
1249 {
|
|
1250 *tofd = -1;
|
|
1251 *fromfd = -1;
|
|
1252
|
|
1253 if (curfle->is_fd)
|
|
1254 {
|
|
1255 if (tdata->toreq->protonum == GFTP_LOCAL_NUM)
|
|
1256 *tofd = curfle->fd;
|
|
1257 else if (tdata->fromreq->protonum == GFTP_LOCAL_NUM)
|
|
1258 *fromfd = curfle->fd;
|
|
1259 }
|
|
1260 }
|
|
1261
|
|
1262
|
|
1263 static void
|
|
1264 _gftpui_common_done_with_fds (gftp_transfer * tdata, gftp_file * curfle)
|
|
1265 {
|
|
1266 if (curfle->is_fd)
|
|
1267 {
|
|
1268 if (tdata->toreq->protonum == GFTP_LOCAL_NUM)
|
|
1269 tdata->toreq->datafd = -1;
|
|
1270 else
|
|
1271 tdata->fromreq->datafd = -1;
|
|
1272 }
|
|
1273 }
|
|
1274
|
|
1275
|
|
1276 int
|
|
1277 gftpui_common_transfer_files (gftp_transfer * tdata)
|
|
1278 {
|
560
|
1279 intptr_t preserve_permissions, preserve_time, trans_blksize;
|
377
|
1280 struct timeval updatetime;
|
|
1281 ssize_t num_read, ret;
|
|
1282 gftp_file * curfle;
|
517
|
1283 int tofd, fromfd;
|
527
|
1284 char *buf;
|
|
1285
|
|
1286 gftp_lookup_request_option (tdata->fromreq, "trans_blksize", &trans_blksize);
|
|
1287 buf = g_malloc (trans_blksize);
|
367
|
1288
|
|
1289 tdata->curfle = tdata->files;
|
|
1290 gettimeofday (&tdata->starttime, NULL);
|
377
|
1291 memcpy (&tdata->lasttime, &tdata->starttime, sizeof (tdata->lasttime));
|
367
|
1292
|
|
1293 while (tdata->curfle != NULL)
|
|
1294 {
|
|
1295 num_read = -1;
|
|
1296
|
|
1297 if (g_thread_supported ())
|
|
1298 g_static_mutex_lock (&tdata->structmutex);
|
|
1299
|
|
1300 curfle = tdata->curfle->data;
|
|
1301 tdata->current_file_number++;
|
|
1302
|
|
1303 if (g_thread_supported ())
|
|
1304 g_static_mutex_unlock (&tdata->structmutex);
|
|
1305
|
|
1306 if (curfle->transfer_action == GFTP_TRANS_ACTION_SKIP)
|
|
1307 {
|
|
1308 if (g_thread_supported ())
|
|
1309 g_static_mutex_lock (&tdata->structmutex);
|
|
1310
|
|
1311 tdata->next_file = 1;
|
|
1312 tdata->curfle = tdata->curfle->next;
|
|
1313
|
|
1314 if (g_thread_supported ())
|
|
1315 g_static_mutex_unlock (&tdata->structmutex);
|
377
|
1316
|
367
|
1317 continue;
|
|
1318 }
|
|
1319
|
377
|
1320 tdata->tot_file_trans = -1;
|
367
|
1321 if (gftp_connect (tdata->fromreq) == 0 &&
|
|
1322 gftp_connect (tdata->toreq) == 0)
|
|
1323 {
|
499
|
1324 if (S_ISDIR (curfle->st_mode))
|
367
|
1325 {
|
|
1326 if (tdata->toreq->mkdir != NULL)
|
|
1327 {
|
|
1328 tdata->toreq->mkdir (tdata->toreq, curfle->destfile);
|
|
1329 if (!GFTP_IS_CONNECTED (tdata->toreq))
|
|
1330 break;
|
|
1331 }
|
|
1332
|
|
1333 if (g_thread_supported ())
|
|
1334 g_static_mutex_lock (&tdata->structmutex);
|
|
1335
|
|
1336 tdata->next_file = 1;
|
|
1337 tdata->curfle = tdata->curfle->next;
|
|
1338
|
|
1339 if (g_thread_supported ())
|
|
1340 g_static_mutex_unlock (&tdata->structmutex);
|
|
1341 continue;
|
|
1342 }
|
|
1343
|
|
1344 _gftpui_common_setup_fds (tdata, curfle, &fromfd, &tofd);
|
|
1345
|
|
1346 if (curfle->size == 0)
|
|
1347 {
|
|
1348 curfle->size = gftp_get_file_size (tdata->fromreq, curfle->file);
|
|
1349 tdata->total_bytes += curfle->size;
|
|
1350 }
|
|
1351
|
|
1352 if (GFTP_IS_CONNECTED (tdata->fromreq) &&
|
|
1353 GFTP_IS_CONNECTED (tdata->toreq))
|
|
1354 {
|
377
|
1355 tdata->tot_file_trans = gftp_transfer_file (tdata->fromreq,
|
|
1356 curfle->file, fromfd,
|
367
|
1357 curfle->transfer_action == GFTP_TRANS_ACTION_RESUME ?
|
|
1358 curfle->startsize : 0,
|
|
1359 tdata->toreq, curfle->destfile, tofd,
|
|
1360 curfle->transfer_action == GFTP_TRANS_ACTION_RESUME ?
|
|
1361 curfle->startsize : 0);
|
|
1362 }
|
|
1363 }
|
|
1364
|
|
1365 if (!GFTP_IS_CONNECTED (tdata->fromreq) ||
|
|
1366 !GFTP_IS_CONNECTED (tdata->toreq))
|
|
1367 {
|
|
1368 tdata->fromreq->logging_function (gftp_logging_misc,
|
|
1369 tdata->fromreq,
|
377
|
1370 _("Error: Remote site disconnected after trying to transfer file\n"));
|
367
|
1371 }
|
377
|
1372 else if (tdata->tot_file_trans < 0)
|
367
|
1373 {
|
|
1374 if (g_thread_supported ())
|
|
1375 g_static_mutex_lock (&tdata->structmutex);
|
|
1376
|
|
1377 curfle->transfer_action = GFTP_TRANS_ACTION_SKIP;
|
|
1378 tdata->next_file = 1;
|
|
1379 tdata->curfle = tdata->curfle->next;
|
|
1380
|
|
1381 if (g_thread_supported ())
|
|
1382 g_static_mutex_unlock (&tdata->structmutex);
|
|
1383 continue;
|
|
1384 }
|
|
1385 else
|
|
1386 {
|
|
1387 if (g_thread_supported ())
|
|
1388 g_static_mutex_lock (&tdata->structmutex);
|
|
1389
|
|
1390 tdata->curtrans = 0;
|
|
1391 tdata->curresumed = curfle->transfer_action == GFTP_TRANS_ACTION_RESUME ? curfle->startsize : 0;
|
|
1392 tdata->resumed_bytes += tdata->curresumed;
|
|
1393
|
|
1394 if (g_thread_supported ())
|
|
1395 g_static_mutex_unlock (&tdata->structmutex);
|
|
1396
|
377
|
1397 memset (&updatetime, 0, sizeof (updatetime));
|
|
1398 gftpui_start_current_file_in_transfer (tdata);
|
|
1399
|
367
|
1400 while (!tdata->cancel &&
|
|
1401 (num_read = gftp_get_next_file_chunk (tdata->fromreq,
|
527
|
1402 buf, trans_blksize)) > 0)
|
367
|
1403 {
|
|
1404 gftp_calc_kbs (tdata, num_read);
|
377
|
1405 if (tdata->lasttime.tv_sec - updatetime.tv_sec >= 1 ||
|
|
1406 tdata->curtrans >= tdata->tot_file_trans)
|
|
1407 {
|
|
1408 gftpui_update_current_file_in_transfer (tdata);
|
|
1409 memcpy (&updatetime, &tdata->lasttime, sizeof (updatetime));
|
|
1410 }
|
367
|
1411
|
|
1412 if ((ret = gftp_put_next_file_chunk (tdata->toreq, buf,
|
|
1413 num_read)) < 0)
|
|
1414 {
|
|
1415 num_read = (int) ret;
|
|
1416 break;
|
|
1417 }
|
|
1418 }
|
377
|
1419
|
426
|
1420 if (num_read == GFTP_ENOTRANS)
|
|
1421 num_read = 0;
|
|
1422
|
377
|
1423 gftpui_finish_current_file_in_transfer (tdata);
|
367
|
1424 }
|
|
1425
|
|
1426 if (tdata->cancel)
|
|
1427 {
|
|
1428 if (gftp_abort_transfer (tdata->fromreq) != 0)
|
|
1429 gftp_disconnect (tdata->fromreq);
|
|
1430
|
|
1431 if (gftp_abort_transfer (tdata->toreq) != 0)
|
|
1432 gftp_disconnect (tdata->toreq);
|
|
1433 }
|
|
1434 else if (num_read < 0)
|
|
1435 {
|
|
1436 tdata->fromreq->logging_function (gftp_logging_misc,
|
|
1437 tdata->fromreq,
|
|
1438 _("Could not download %s from %s\n"),
|
|
1439 curfle->file,
|
|
1440 tdata->fromreq->hostname);
|
|
1441
|
|
1442 if (gftp_get_transfer_status (tdata, num_read) == GFTP_ERETRYABLE)
|
|
1443 continue;
|
|
1444
|
|
1445 break;
|
|
1446 }
|
|
1447 else
|
|
1448 {
|
|
1449 _gftpui_common_done_with_fds (tdata, curfle);
|
|
1450 if (gftp_end_transfer (tdata->fromreq) != 0)
|
|
1451 {
|
|
1452 if (gftp_get_transfer_status (tdata, -1) == GFTP_ERETRYABLE)
|
|
1453 continue;
|
|
1454
|
|
1455 break;
|
|
1456 }
|
|
1457 gftp_end_transfer (tdata->toreq);
|
|
1458
|
|
1459 tdata->fromreq->logging_function (gftp_logging_misc,
|
|
1460 tdata->fromreq,
|
377
|
1461 _("Successfully transferred %s at %.2f KB/s\n"),
|
367
|
1462 curfle->file, tdata->kbs);
|
|
1463 }
|
|
1464
|
377
|
1465 gftp_lookup_request_option (tdata->fromreq, "preserve_permissions",
|
|
1466 &preserve_permissions);
|
560
|
1467 gftp_lookup_request_option (tdata->fromreq, "preserve_time",
|
|
1468 &preserve_time);
|
377
|
1469
|
560
|
1470 if (!curfle->is_fd)
|
367
|
1471 {
|
560
|
1472 if (preserve_permissions && curfle->st_mode != 0)
|
504
|
1473 gftp_chmod (tdata->toreq, curfle->destfile,
|
|
1474 curfle->st_mode & (S_IRWXU | S_IRWXG | S_IRWXO));
|
367
|
1475
|
560
|
1476 if (preserve_time && curfle->datetime != 0)
|
367
|
1477 gftp_set_file_time (tdata->toreq, curfle->destfile,
|
|
1478 curfle->datetime);
|
|
1479 }
|
|
1480
|
|
1481 if (g_thread_supported ())
|
|
1482 g_static_mutex_lock (&tdata->structmutex);
|
|
1483
|
|
1484 tdata->curtrans = 0;
|
|
1485 tdata->next_file = 1;
|
|
1486 curfle->transfer_done = 1;
|
|
1487 tdata->curfle = tdata->curfle->next;
|
|
1488
|
|
1489 if (g_thread_supported ())
|
|
1490 g_static_mutex_unlock (&tdata->structmutex);
|
|
1491
|
|
1492 if (tdata->cancel && !tdata->skip_file)
|
|
1493 break;
|
|
1494 tdata->cancel = 0;
|
|
1495 tdata->fromreq->cancel = 0;
|
|
1496 tdata->toreq->cancel = 0;
|
|
1497 }
|
527
|
1498
|
367
|
1499 tdata->done = 1;
|
527
|
1500 g_free (buf);
|
367
|
1501
|
387
|
1502 return (1);
|
367
|
1503 }
|
|
1504
|
469
|
1505
|
|
1506 void
|
|
1507 gftpui_protocol_update_timeout (gftp_request * request)
|
|
1508 {
|
|
1509 intptr_t network_timeout;
|
|
1510
|
|
1511 gftp_lookup_request_option (request, "network_timeout", &network_timeout);
|
|
1512
|
|
1513 if (network_timeout > 0)
|
|
1514 alarm (network_timeout);
|
|
1515 }
|
|
1516
|