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