Mercurial > gftp.yaz
annotate src/gtk/transfer.c @ 37:5a178bd04ca5
2002-10-13 Brian Masney <masneyb@gftp.org>
* lib/gftp.h (struct gftp_config_vars_tag) - remove shown flag and
added ports_shown flag. Added GFTP_PORTS_TEXT, GFTP_PORTS_GTK,
and GFTP_PORTS_ALL flags
* lib/config_file.c - update to use new fields.
* lib/config_file.c, lib/options.h, lib/gftp.h - added new global
options: local_sortcol, local_sortasds, remote_sortcol, remote_sortasds
* src/gtk/gftp-gtk.c - sort based on parameters above. Also, if a url
was given on the command line, don't connect to it until the local side
has been setup
* src/gtk/options_dialog.c - only show variables that have GFTP_PORT_GTK
set
* src/text/gftp-text.c - add help screen for set command. Added command
clear cache. Sort the filelist based on the configuration options.
* configure.in - update to version 2.0.14
* cvsclean - clean up the Makefile.am file better
author | masneyb |
---|---|
date | Mon, 14 Oct 2002 02:46:14 +0000 |
parents | bc9473ba9a90 |
children | 66c064fd05bc |
rev | line source |
---|---|
1 | 1 /*****************************************************************************/ |
2 /* transfer.c - functions to handle transfering files */ | |
3 /* Copyright (C) 1998-2002 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ | |
18 /*****************************************************************************/ | |
19 | |
20 #include <gftp-gtk.h> | |
33 | 21 static const char cvsid[] = "$Id$"; |
1 | 22 |
23 static void *getdir_thread ( void *data ); | |
24 static void *connect_thread ( void *data ); | |
25 static void on_next_transfer ( gftp_transfer * tdata ); | |
26 static void show_transfer ( gftp_transfer * tdata ); | |
27 static void transfer_done ( GList * node ); | |
28 static void create_transfer ( gftp_transfer * tdata ); | |
29 static void update_file_status ( gftp_transfer * tdata ); | |
30 static void trans_selectall ( GtkWidget * widget, | |
31 gpointer data ); | |
32 static void trans_unselectall ( GtkWidget * widget, | |
33 gpointer data ); | |
34 static void overwrite ( GtkWidget * widget, | |
35 gpointer data ); | |
36 static void resume ( GtkWidget * widget, | |
37 gpointer data ); | |
38 static void skip ( GtkWidget * widget, | |
39 gpointer data ); | |
40 static void ok ( GtkWidget * widget, | |
41 gpointer data ); | |
42 static void cancel ( GtkWidget * widget, | |
43 gpointer data ); | |
44 static void gftp_gtk_calc_kbs ( gftp_transfer * tdata, | |
45 ssize_t num_read ); | |
46 static void check_done_process ( void ); | |
19 | 47 static void do_upload ( gftp_viewedit_data * ve_proc, |
48 gftp_dialog_data * ddata ); | |
49 static void dont_upload ( gftp_viewedit_data * ve_proc, | |
50 gftp_dialog_data * ddata ); | |
51 static void free_edit_data ( gftp_viewedit_data *ve_proc ); | |
1 | 52 static int get_status ( gftp_transfer * tdata, |
53 ssize_t num_read ); | |
54 static void wakeup_main_thread ( gpointer data, | |
55 gint source, | |
56 GdkInputCondition condition ); | |
57 static gint setup_wakeup_main_thread ( gftp_request * request ); | |
58 static void teardown_wakeup_main_thread ( gftp_request * request, | |
59 gint handler ); | |
60 static mode_t parse_attribs ( char *attribs ); | |
61 static void remove_file ( char *filename ); | |
62 static RETSIGTYPE sig_connquit ( int signo ); | |
63 | |
64 static sigjmp_buf connenvir; | |
65 static GtkWidget * dialog; | |
66 | |
67 int | |
68 ftp_list_files (gftp_window_data * wdata, int usecache) | |
69 { | |
70 guint handler; | |
71 void *success; | |
72 | |
73 gtk_label_set (GTK_LABEL (wdata->hoststxt), _("Receiving file names...")); | |
33 | 74 if (gftp_is_started) |
75 fix_display (); | |
76 | |
1 | 77 wdata->show_selected = 0; |
78 if (wdata->files == NULL) | |
79 { | |
80 if (check_reconnect (wdata) < 0) | |
81 return (0); | |
82 | |
83 gtk_clist_freeze (GTK_CLIST (wdata->listbox)); | |
84 wdata->request->stopable = 1; | |
85 if (wdata->request->use_threads) | |
86 { | |
87 gtk_widget_set_sensitive (stop_btn, 1); | |
88 | |
89 handler = setup_wakeup_main_thread (wdata->request); | |
90 pthread_create (&wdata->tid, NULL, getdir_thread, wdata->request); | |
91 while (wdata->request->stopable) | |
31 | 92 { |
33 | 93 GDK_THREADS_LEAVE (); |
31 | 94 g_main_iteration (TRUE); |
95 } | |
1 | 96 teardown_wakeup_main_thread (wdata->request, handler); |
97 | |
98 pthread_join (wdata->tid, &success); | |
99 gtk_widget_set_sensitive (stop_btn, 0); | |
100 } | |
101 else | |
102 success = getdir_thread (wdata->request); | |
103 wdata->files = success; | |
104 gtk_clist_thaw (GTK_CLIST (wdata->listbox)); | |
105 memset (&wdata->tid, 0, sizeof (wdata->tid)); | |
106 } | |
107 | |
108 if (wdata->files == NULL || !GFTP_IS_CONNECTED (wdata->request)) | |
109 { | |
110 disconnect (wdata); | |
111 return (0); | |
112 } | |
113 | |
114 wdata->sorted = 0; | |
37 | 115 sortrows (GTK_CLIST (wdata->listbox), *wdata->sortcol, (gpointer) wdata); |
1 | 116 if (IS_NONE_SELECTED (wdata)) |
117 gtk_clist_select_row (GTK_CLIST (wdata->listbox), 0, 0); | |
118 return (1); | |
119 } | |
120 | |
121 | |
122 static void * | |
123 getdir_thread (void * data) | |
124 { | |
125 int sj, havedotdot, got; | |
126 gftp_request * request; | |
127 gftp_file * fle; | |
128 GList * files; | |
129 | |
130 request = data; | |
131 request->user_data = (void *) 0x1; | |
132 | |
133 if (request->use_threads) | |
134 { | |
135 sj = sigsetjmp (connenvir, 1); | |
136 signal (SIGINT, sig_connquit); | |
137 signal (SIGALRM, sig_connquit); | |
138 } | |
139 else | |
140 sj = 0; | |
141 | |
142 files = NULL; | |
143 if (sj == 0 || sj == 2) | |
144 { | |
145 if (gftp_list_files (request) != 0 || !GFTP_IS_CONNECTED (request)) | |
146 { | |
147 if (request->use_threads) | |
148 { | |
149 signal (SIGINT, SIG_DFL); | |
150 signal (SIGALRM, SIG_IGN); | |
151 } | |
152 request->user_data = NULL; | |
153 request->stopable = 0; | |
154 if (request->wakeup_main_thread[1] > 0) | |
155 write (request->wakeup_main_thread[1], " ", 1); | |
156 return (NULL); | |
157 } | |
158 | |
159 request->gotbytes = 0; | |
160 havedotdot = 0; | |
161 fle = g_malloc0 (sizeof (*fle)); | |
162 while ((got = gftp_get_next_file (request, NULL, fle)) > 0) | |
163 { | |
164 request->gotbytes += got; | |
165 if (strcmp (fle->file, ".") == 0) | |
166 { | |
167 gftp_file_destroy (fle); | |
168 continue; | |
169 } | |
170 else if (strcmp (fle->file, "..") == 0) | |
171 havedotdot = 1; | |
172 | |
173 files = g_list_append (files, fle); | |
174 fle = g_malloc0 (sizeof (*fle)); | |
175 } | |
176 g_free (fle); | |
177 | |
178 if (!GFTP_IS_CONNECTED (request)) | |
179 { | |
180 if (request->use_threads) | |
181 { | |
182 signal (SIGINT, SIG_DFL); | |
183 signal (SIGALRM, SIG_IGN); | |
184 } | |
185 request->user_data = NULL; | |
186 request->stopable = 0; | |
187 if (request->wakeup_main_thread[1] > 0) | |
188 write (request->wakeup_main_thread[1], " ", 1); | |
189 return (NULL); | |
190 } | |
191 | |
192 gftp_end_transfer (request); | |
193 request->gotbytes = -1; | |
194 | |
195 if (!havedotdot) | |
196 { | |
197 fle = g_malloc0 (sizeof (*fle)); | |
198 fle->file = g_malloc (3); | |
199 strcpy (fle->file, ".."); | |
200 fle->user = g_malloc0 (1); | |
201 fle->group = g_malloc0 (1); | |
202 fle->attribs = g_malloc0 (1); | |
203 *fle->attribs = '\0'; | |
204 fle->isdir = 1; | |
205 files = g_list_prepend (files, fle); | |
206 } | |
207 } | |
208 | |
209 request->user_data = NULL; | |
210 if (request->use_threads) | |
211 { | |
212 signal (SIGINT, SIG_DFL); | |
213 signal (SIGALRM, SIG_IGN); | |
214 } | |
215 request->stopable = 0; | |
216 if (request->wakeup_main_thread[1] > 0) | |
217 write (request->wakeup_main_thread[1], " ", 1); | |
218 return (files); | |
219 } | |
220 | |
221 | |
19 | 222 static void |
223 try_connect_again (gftp_request * request, gftp_dialog_data * ddata) | |
224 { | |
225 gftp_set_password (request, gtk_entry_get_text (GTK_ENTRY (ddata->edit))); | |
226 request->stopable = 0; | |
227 } | |
228 | |
229 | |
230 static void | |
231 dont_connect_again (gftp_request * request, gftp_dialog_data * ddata) | |
232 { | |
233 request->stopable = 0; | |
234 } | |
235 | |
236 | |
1 | 237 int |
238 ftp_connect (gftp_window_data * wdata, gftp_request * request, int getdir) | |
239 { | |
240 int success; | |
241 guint handler; | |
242 void *ret; | |
243 | |
244 ret = 0; | |
245 if (wdata->request == request) | |
246 { | |
247 gtk_label_set (GTK_LABEL (wdata->hoststxt), _("Connecting...")); | |
248 } | |
249 | |
7 | 250 if (request->need_userpass && request->username != NULL && |
251 *request->username != '\0' && | |
252 (request->password == NULL || *request->password == '\0')) | |
1 | 253 { |
254 if (wdata && wdata->request == request) | |
255 { | |
256 request->stopable = 1; | |
257 MakeEditDialog (_("Enter Password"), | |
258 _("Please enter your password for this site"), NULL, | |
19 | 259 0, NULL, gftp_dialog_button_connect, |
260 try_connect_again, request, | |
261 dont_connect_again, request); | |
31 | 262 |
1 | 263 while (request->stopable) |
31 | 264 { |
33 | 265 GDK_THREADS_LEAVE (); |
31 | 266 g_main_iteration (TRUE); |
267 } | |
1 | 268 |
269 if (GFTP_GET_PASSWORD (request) == NULL || | |
270 *GFTP_GET_PASSWORD (request) == '\0') | |
271 return (0); | |
272 } | |
273 else | |
274 gftp_set_password (request, ""); | |
275 } | |
276 | |
277 if (wdata && wdata->request == request && request->use_threads) | |
278 { | |
279 request->stopable = 1; | |
280 if (wdata) | |
281 gtk_clist_freeze (GTK_CLIST (wdata->listbox)); | |
282 gtk_widget_set_sensitive (stop_btn, 1); | |
283 pthread_create (&wdata->tid, NULL, connect_thread, request); | |
284 | |
285 handler = setup_wakeup_main_thread (wdata->request); | |
286 while (request->stopable) | |
31 | 287 { |
33 | 288 GDK_THREADS_LEAVE (); |
31 | 289 g_main_iteration (TRUE); |
290 } | |
1 | 291 pthread_join (wdata->tid, &ret); |
292 teardown_wakeup_main_thread (wdata->request, handler); | |
293 | |
294 gtk_widget_set_sensitive (stop_btn, 0); | |
295 if (wdata) | |
296 gtk_clist_thaw (GTK_CLIST (wdata->listbox)); | |
297 } | |
298 else | |
299 ret = connect_thread (request); | |
300 success = (int) ret; | |
301 memset (&wdata->tid, 0, sizeof (wdata->tid)); | |
302 | |
303 if (!GFTP_IS_CONNECTED (wdata->request)) | |
304 disconnect (wdata); | |
305 else if (success) | |
306 { | |
307 ftp_list_files (wdata, 1); | |
308 if (!GFTP_IS_CONNECTED (wdata->request)) | |
309 disconnect (wdata); | |
310 } | |
311 | |
312 return (success); | |
313 } | |
314 | |
315 | |
316 static void * | |
317 connect_thread (void *data) | |
318 { | |
319 static int conn_num; | |
320 gftp_request * request; | |
321 int ret, sj; | |
322 | |
323 request = data; | |
324 request->user_data = (void *) 0x1; | |
325 | |
326 conn_num = 0; | |
327 if (request->use_threads) | |
328 { | |
329 sj = sigsetjmp (connenvir, 1); | |
330 signal (SIGINT, sig_connquit); | |
331 signal (SIGALRM, sig_connquit); | |
332 } | |
333 else | |
334 sj = 0; | |
335 | |
336 ret = 0; | |
337 if (sj != 0) | |
338 { | |
339 ret = 0; | |
340 gftp_disconnect (request); | |
341 } | |
342 | |
343 while (sj != 1 && (request->retries == 0 || conn_num < request->retries)) | |
344 { | |
345 conn_num++; | |
346 if (request->network_timeout > 0) | |
347 alarm (request->network_timeout); | |
348 ret = gftp_connect (request) == 0; | |
349 alarm (0); | |
350 | |
351 if (ret) | |
352 break; | |
353 else if (request->retries == 0 || conn_num < request->retries) | |
354 { | |
355 request->logging_function (gftp_logging_misc, request->user_data, | |
356 _("Waiting %d seconds until trying to connect again\n"), | |
357 request->sleep_time); | |
358 alarm (request->sleep_time); | |
359 pause (); | |
360 } | |
361 } | |
362 | |
363 if (request->use_threads) | |
364 { | |
365 signal (SIGINT, SIG_DFL); | |
366 signal (SIGALRM, SIG_IGN); | |
367 } | |
368 | |
369 request->user_data = NULL; | |
370 request->stopable = 0; | |
371 if (request->wakeup_main_thread[1] > 0) | |
372 write (request->wakeup_main_thread[1], " ", 1); | |
373 return ((void *) ret); | |
374 } | |
375 | |
376 | |
377 void | |
378 get_files (gpointer data) | |
379 { | |
380 transfer_window_files (&window2, &window1); | |
381 } | |
382 | |
383 | |
384 void | |
385 put_files (gpointer data) | |
386 { | |
387 transfer_window_files (&window1, &window2); | |
388 } | |
389 | |
390 | |
391 void | |
392 transfer_window_files (gftp_window_data * fromwdata, gftp_window_data * towdata) | |
393 { | |
394 gftp_file * tempfle, * newfle; | |
395 GList * templist, * filelist; | |
396 gftp_transfer * transfer; | |
397 guint timeout_num; | |
398 void *ret; | |
399 int num; | |
400 | |
401 if (!check_status (_("Transfer Files"), fromwdata, 1, 0, 1, | |
402 towdata->request->put_file != NULL && fromwdata->request->get_file != NULL)) | |
403 return; | |
404 | |
405 if (!GFTP_IS_CONNECTED (fromwdata->request) || | |
406 !GFTP_IS_CONNECTED (towdata->request)) | |
407 { | |
408 ftp_log (gftp_logging_misc, NULL, | |
409 _("Retrieve Files: Not connected to a remote site\n")); | |
410 return; | |
411 } | |
412 | |
413 if (check_reconnect (fromwdata) < 0 || check_reconnect (towdata) < 0) | |
414 return; | |
415 | |
416 transfer = g_malloc0 (sizeof (*transfer)); | |
417 transfer->fromreq = copy_request (fromwdata->request); | |
418 transfer->toreq = copy_request (towdata->request); | |
419 transfer->transfer_direction = fromwdata == &window2 ? | |
420 GFTP_DIRECTION_DOWNLOAD : GFTP_DIRECTION_UPLOAD; | |
421 transfer->fromwdata = fromwdata; | |
422 transfer->towdata = towdata; | |
423 | |
424 num = 0; | |
425 templist = GTK_CLIST (fromwdata->listbox)->selection; | |
426 filelist = fromwdata->files; | |
427 while (templist != NULL) | |
428 { | |
429 templist = get_next_selection (templist, &filelist, &num); | |
430 tempfle = filelist->data; | |
431 if (strcmp (tempfle->file, "..") != 0) | |
432 { | |
433 newfle = copy_fdata (tempfle); | |
434 transfer->files = g_list_append (transfer->files, newfle); | |
435 } | |
436 } | |
437 | |
438 if (transfer->files != NULL) | |
439 { | |
440 swap_socks (transfer->fromreq, fromwdata->request); | |
441 swap_socks (transfer->toreq, towdata->request); | |
442 | |
443 if (transfer->fromreq->use_threads || | |
444 (transfer->toreq && transfer->toreq->use_threads)) | |
445 { | |
446 transfer->fromreq->stopable = 1; | |
447 pthread_create (&fromwdata->tid, NULL, do_getdir_thread, transfer); | |
448 | |
449 timeout_num = gtk_timeout_add (100, progress_timeout, transfer); | |
450 | |
451 while (transfer->fromreq->stopable) | |
31 | 452 { |
33 | 453 GDK_THREADS_LEAVE (); |
31 | 454 g_main_iteration (TRUE); |
455 } | |
1 | 456 |
457 gtk_timeout_remove (timeout_num); | |
458 transfer->numfiles = transfer->numdirs = -1; | |
459 update_directory_download_progress (transfer); | |
460 | |
461 pthread_join (fromwdata->tid, &ret); | |
462 } | |
463 else | |
464 ret = do_getdir_thread (transfer); | |
465 | |
466 if (!GFTP_IS_CONNECTED (transfer->fromreq)) | |
467 { | |
468 disconnect (fromwdata); | |
469 return; | |
470 } | |
471 | |
472 if (!GFTP_IS_CONNECTED (transfer->toreq)) | |
473 { | |
474 disconnect (towdata); | |
475 return; | |
476 } | |
477 | |
478 swap_socks (fromwdata->request, transfer->fromreq); | |
479 swap_socks (towdata->request, transfer->toreq); | |
480 } | |
481 | |
482 if (transfer->files != NULL) | |
483 { | |
484 add_file_transfer (transfer->fromreq, transfer->toreq, | |
485 transfer->fromwdata, transfer->towdata, | |
486 transfer->files, 0); | |
487 g_free (transfer); | |
488 } | |
489 else | |
490 { | |
491 if (transfer->statmutex) | |
492 pthread_mutex_destroy (transfer->statmutex); | |
493 if (transfer->structmutex) | |
494 pthread_mutex_destroy (transfer->structmutex); | |
495 free_tdata (transfer); | |
496 } | |
497 } | |
498 | |
499 void * | |
500 do_getdir_thread (void * data) | |
501 { | |
502 gftp_transfer * transfer; | |
503 int success, sj; | |
504 | |
505 transfer = data; | |
506 transfer->fromreq->user_data = (void *) 0x01; | |
507 if (transfer->toreq) | |
508 transfer->toreq->user_data = (void *) 0x01; | |
509 | |
510 if (transfer->fromreq->use_threads || | |
511 (transfer->toreq && transfer->toreq->use_threads)) | |
512 { | |
513 sj = sigsetjmp (connenvir, 1); | |
514 signal (SIGINT, sig_connquit); | |
515 signal (SIGALRM, sig_connquit); | |
516 } | |
517 else | |
518 sj = 0; | |
519 | |
520 success = 0; | |
521 if (sj == 0) | |
522 success = gftp_get_all_subdirs (transfer, NULL) == 0; | |
523 else | |
524 { | |
525 gftp_disconnect (transfer->fromreq); | |
526 if (transfer->toreq) | |
527 gftp_disconnect (transfer->toreq); | |
528 transfer->fromreq->logging_function (gftp_logging_error, | |
529 transfer->fromreq->user_data, | |
530 _("Operation canceled\n")); | |
531 } | |
532 | |
533 if (transfer->fromreq->use_threads || | |
534 (transfer->toreq && transfer->toreq->use_threads)) | |
535 { | |
536 signal (SIGINT, SIG_DFL); | |
537 signal (SIGALRM, SIG_IGN); | |
538 } | |
539 | |
540 transfer->fromreq->user_data = NULL; | |
541 if (transfer->toreq) | |
542 transfer->toreq->user_data = NULL; | |
543 transfer->fromreq->stopable = 0; | |
544 return ((void *) success); | |
545 } | |
546 | |
547 | |
548 | |
549 void * | |
550 gftp_gtk_transfer_files (void *data) | |
551 { | |
552 gftp_transfer * transfer; | |
553 char *tempstr, buf[8192]; | |
554 FILE * tofd, * fromfd; | |
555 off_t fromsize, total; | |
556 gftp_file * curfle; | |
557 ssize_t num_read; | |
558 int i, mode; | |
559 | |
560 pthread_detach (pthread_self ()); | |
561 transfer = data; | |
562 transfer->fromreq->user_data = (void *) 0x1; | |
563 transfer->toreq->user_data = (void *) 0x1; | |
564 transfer->curfle = transfer->files; | |
565 gettimeofday (&transfer->starttime, NULL); | |
566 memcpy (&transfer->lasttime, &transfer->starttime, | |
567 sizeof (transfer->lasttime)); | |
568 while (transfer->curfle != NULL) | |
569 { | |
570 pthread_mutex_lock (transfer->structmutex); | |
571 curfle = transfer->curfle->data; | |
572 transfer->current_file_number++; | |
573 pthread_mutex_unlock (transfer->structmutex); | |
574 | |
575 if (curfle->transfer_action == GFTP_TRANS_ACTION_SKIP) | |
576 { | |
577 pthread_mutex_lock (transfer->structmutex); | |
578 transfer->next_file = 1; | |
579 transfer->curfle = transfer->curfle->next; | |
580 pthread_mutex_unlock (transfer->structmutex); | |
581 continue; | |
582 } | |
583 | |
584 fromsize = -1; | |
585 if (gftp_connect (transfer->fromreq) == 0 && | |
586 gftp_connect (transfer->toreq) == 0) | |
587 { | |
588 if (curfle->isdir) | |
589 { | |
590 if (transfer->toreq->mkdir != NULL) | |
591 { | |
592 transfer->toreq->mkdir (transfer->toreq, curfle->destfile); | |
593 if (!GFTP_IS_CONNECTED (transfer->toreq)) | |
594 break; | |
595 } | |
596 | |
597 pthread_mutex_lock (transfer->structmutex); | |
598 transfer->next_file = 1; | |
599 transfer->curfle = transfer->curfle->next; | |
600 pthread_mutex_unlock (transfer->structmutex); | |
601 continue; | |
602 } | |
603 | |
604 if (transfer->fromreq->maxkbs > 0) | |
605 { | |
606 transfer->fromreq->logging_function (gftp_logging_misc, | |
607 transfer->fromreq->user_data, | |
608 _("File transfer will be throttled to %.2f KB/s\n"), | |
609 transfer->fromreq->maxkbs); | |
610 } | |
611 | |
612 if (curfle->is_fd) | |
613 { | |
614 if (transfer->transfer_direction == GFTP_DIRECTION_DOWNLOAD) | |
615 { | |
616 tofd = curfle->fd; | |
617 fromfd = NULL; | |
618 } | |
619 else | |
620 { | |
621 tofd = NULL; | |
622 fromfd = curfle->fd; | |
623 } | |
624 } | |
625 else | |
626 { | |
627 tofd = NULL; | |
628 fromfd = NULL; | |
629 } | |
630 | |
631 if (curfle->size == 0) | |
632 { | |
633 curfle->size = gftp_get_file_size (transfer->fromreq, curfle->file); | |
634 transfer->total_bytes += curfle->size; | |
635 } | |
636 | |
637 if (GFTP_IS_CONNECTED (transfer->fromreq) && | |
638 GFTP_IS_CONNECTED (transfer->toreq)) | |
639 { | |
640 fromsize = gftp_transfer_file (transfer->fromreq, curfle->file, | |
641 fromfd, | |
642 curfle->transfer_action == GFTP_TRANS_ACTION_RESUME ? | |
643 curfle->startsize : 0, | |
644 transfer->toreq, curfle->destfile, tofd, | |
645 curfle->transfer_action == GFTP_TRANS_ACTION_RESUME ? | |
646 curfle->startsize : 0); | |
647 } | |
648 } | |
649 | |
650 if (!GFTP_IS_CONNECTED (transfer->fromreq) || | |
651 !GFTP_IS_CONNECTED (transfer->toreq)) | |
652 { | |
653 transfer->fromreq->logging_function (gftp_logging_misc, | |
654 transfer->fromreq->user_data, | |
655 _("Error: Remote site disconnected after trying to transfer file\n")); | |
656 num_read = -1; | |
657 } | |
658 else if (fromsize < 0) | |
659 { | |
660 if (curfle->is_fd) | |
661 { | |
662 if (transfer->transfer_direction == GFTP_DIRECTION_DOWNLOAD) | |
663 transfer->toreq->datafd = NULL; | |
664 else | |
665 transfer->fromreq->datafd = NULL; | |
666 } | |
667 | |
668 pthread_mutex_lock (transfer->structmutex); | |
669 curfle->transfer_action = GFTP_TRANS_ACTION_SKIP; | |
670 transfer->next_file = 1; | |
671 transfer->curfle = transfer->curfle->next; | |
672 pthread_mutex_unlock (transfer->structmutex); | |
673 continue; | |
674 } | |
675 else | |
676 { | |
677 pthread_mutex_lock (transfer->structmutex); | |
678 transfer->curtrans = 0; | |
679 transfer->curresumed = curfle->transfer_action == GFTP_TRANS_ACTION_RESUME ? curfle->startsize : 0; | |
680 transfer->resumed_bytes += transfer->curresumed; | |
681 pthread_mutex_unlock (transfer->structmutex); | |
682 | |
683 total = 0; | |
684 i = 0; | |
685 while (!transfer->cancel && | |
686 (num_read = gftp_get_next_file_chunk (transfer->fromreq, | |
687 buf, sizeof (buf))) > 0) | |
688 { | |
689 total += num_read; | |
690 gftp_gtk_calc_kbs (transfer, num_read); | |
691 | |
692 if (GFTP_GET_DATA_TYPE (transfer->fromreq) == GFTP_TYPE_ASCII) | |
693 tempstr = gftp_convert_ascii (buf, &num_read, 1); | |
694 else | |
695 tempstr = buf; | |
696 | |
697 if (gftp_put_next_file_chunk (transfer->toreq, tempstr, | |
698 num_read) < 0) | |
699 { | |
700 num_read = -1; | |
701 break; | |
702 } | |
703 | |
704 /* We don't have to free tempstr for a download because new | |
705 memory is not allocated for it in that case */ | |
706 if (GFTP_GET_DATA_TYPE (transfer->fromreq) == GFTP_TYPE_ASCII && | |
707 transfer->transfer_direction == GFTP_DIRECTION_UPLOAD) | |
708 g_free (tempstr); | |
709 } | |
710 } | |
711 | |
712 if (num_read < 0 || transfer->cancel) | |
713 { | |
714 transfer->fromreq->logging_function (gftp_logging_misc, | |
715 transfer->fromreq->user_data, | |
716 _("Could not download %s from %s\n"), | |
717 curfle->file, | |
718 transfer->fromreq->hostname); | |
719 | |
720 if (get_status (transfer, num_read) == 1) | |
721 { | |
722 transfer->cancel = 0; | |
723 continue; | |
724 } | |
725 break; | |
726 } | |
727 else | |
728 { | |
729 /* FIXME - this needs cleaned up. NOTE: view/edit file will be broken if the file hsa to be resumed */ | |
730 if (curfle->is_fd) | |
731 { | |
732 if (transfer->transfer_direction == GFTP_DIRECTION_DOWNLOAD) | |
733 transfer->toreq->datafd = NULL; | |
734 else | |
735 transfer->fromreq->datafd = NULL; | |
736 } | |
737 | |
738 if (gftp_end_transfer (transfer->fromreq) != 0) | |
739 { | |
740 if (get_status (transfer, -1) == 1) | |
741 { | |
742 transfer->cancel = 0; | |
743 continue; | |
744 } | |
745 break; | |
746 } | |
747 gftp_end_transfer (transfer->toreq); | |
748 | |
749 transfer->fromreq->logging_function (gftp_logging_misc, | |
750 transfer->fromreq->user_data, | |
751 _("Successfully transferred %s at %.2f KB/s\n"), | |
752 curfle->file, transfer->kbs); | |
753 } | |
754 | |
755 if (!curfle->is_fd) | |
756 { | |
757 if (curfle->attribs) | |
758 { | |
759 mode = parse_attribs (curfle->attribs); | |
760 if (mode != 0) | |
761 gftp_chmod (transfer->toreq, curfle->destfile, | |
762 parse_attribs (curfle->attribs)); | |
763 } | |
764 | |
765 if (curfle->datetime != 0) | |
766 gftp_set_file_time (transfer->toreq, curfle->destfile, | |
767 curfle->datetime); | |
768 } | |
769 | |
770 pthread_mutex_lock (transfer->structmutex); | |
771 transfer->next_file = 1; | |
772 curfle->transfer_done = 1; | |
773 transfer->curfle = transfer->curfle->next; | |
774 pthread_mutex_unlock (transfer->structmutex); | |
775 | |
776 if (transfer->cancel && !transfer->skip_file) | |
777 break; | |
778 transfer->cancel = 0; | |
779 } | |
780 transfer->done = 1; | |
781 transfer->fromreq->user_data = NULL; | |
782 transfer->toreq->user_data = NULL; | |
783 return (NULL); | |
784 } | |
785 | |
786 | |
787 void | |
788 add_file_transfer (gftp_request * fromreq, gftp_request * toreq, | |
789 gftp_window_data * fromwdata, gftp_window_data * towdata, | |
790 GList * files, int copy_req) | |
791 { | |
792 gftp_curtrans_data * transdata; | |
793 GList * templist, *curfle; | |
794 gftp_transfer * tdata; | |
795 gftp_file * tempfle; | |
796 char *pos, *text[2]; | |
797 int dialog; | |
798 | |
799 for (templist = files; templist != NULL; templist = templist->next) | |
800 { | |
801 tempfle = templist->data; | |
802 if (tempfle->startsize > 0) | |
803 break; | |
804 } | |
805 dialog = templist != NULL; | |
806 | |
807 if (append_file_transfers) | |
808 { | |
809 pthread_mutex_lock (&transfer_mutex); | |
810 for (templist = file_transfers; templist != NULL; templist = templist->next) | |
811 { | |
812 tdata = templist->data; | |
813 pthread_mutex_lock (tdata->structmutex); | |
814 if (compare_request (tdata->fromreq, fromreq, 0) && | |
815 compare_request (tdata->toreq, toreq, 0) && | |
816 tdata->curfle != NULL) | |
817 { | |
818 if (!copy_req) | |
819 { | |
820 gftp_request_destroy (fromreq); | |
821 gftp_request_destroy (toreq); | |
822 } | |
823 fromreq = NULL; | |
824 toreq = NULL; | |
825 | |
826 for (curfle = tdata->curfle; | |
827 curfle != NULL && curfle->next != NULL; | |
828 curfle = curfle->next); | |
829 if (curfle == NULL) | |
830 { | |
831 curfle = files; | |
832 files->prev = NULL; | |
833 } | |
834 else | |
835 { | |
836 curfle->next = files; | |
837 files->prev = curfle; | |
838 } | |
839 | |
840 for (curfle = files; curfle != NULL; curfle = curfle->next) | |
841 { | |
842 tempfle = curfle->data; | |
843 if (tempfle->isdir) | |
844 tdata->numdirs++; | |
845 else | |
846 tdata->numfiles++; | |
847 if ((pos = strrchr (tempfle->file, '/')) == NULL) | |
848 pos = tempfle->file; | |
849 else | |
850 pos++; | |
851 | |
852 text[0] = pos; | |
853 if (tempfle->transfer_action == GFTP_TRANS_ACTION_SKIP) | |
854 text[1] = _("Skipped"); | |
855 else | |
856 { | |
857 tdata->total_bytes += tempfle->size; | |
858 text[1] = _("Waiting..."); | |
859 } | |
860 | |
861 tempfle->node = gtk_ctree_insert_node (GTK_CTREE (dlwdw), | |
862 tdata->node, NULL, text, 5, | |
863 NULL, NULL, NULL, NULL, | |
864 FALSE, FALSE); | |
865 transdata = g_malloc (sizeof (*transdata)); | |
866 transdata->transfer = tdata; | |
867 transdata->curfle = curfle; | |
868 gtk_ctree_node_set_row_data (GTK_CTREE (dlwdw), tempfle->node, | |
869 transdata); | |
870 } | |
871 pthread_mutex_unlock (tdata->structmutex); | |
872 break; | |
873 } | |
874 pthread_mutex_unlock (tdata->structmutex); | |
875 } | |
876 pthread_mutex_unlock (&transfer_mutex); | |
877 } | |
878 else | |
879 templist = NULL; | |
880 | |
881 if (templist == NULL) | |
882 { | |
883 tdata = g_malloc0 (sizeof (*tdata)); | |
884 if (copy_req) | |
885 { | |
886 tdata->fromreq = copy_request (fromreq); | |
887 tdata->toreq = copy_request (toreq); | |
888 } | |
889 else | |
890 { | |
891 tdata->fromreq = fromreq; | |
892 tdata->toreq = toreq; | |
893 } | |
894 tdata->transfer_direction = fromwdata && fromwdata == &window1 ? | |
895 GFTP_DIRECTION_UPLOAD : GFTP_DIRECTION_DOWNLOAD; | |
896 tdata->fromwdata = fromwdata; | |
897 tdata->towdata = towdata; | |
898 if (!dialog) | |
899 tdata->show = tdata->ready = 1; | |
900 tdata->files = files; | |
901 for (curfle = files; curfle != NULL; curfle = curfle->next) | |
902 { | |
903 tempfle = curfle->data; | |
904 if (tempfle->isdir) | |
905 tdata->numdirs++; | |
906 else | |
907 tdata->numfiles++; | |
908 } | |
909 tdata->structmutex = g_malloc (sizeof (pthread_mutex_t)); | |
910 pthread_mutex_init (tdata->structmutex, NULL); | |
911 tdata->statmutex = g_malloc (sizeof (pthread_mutex_t)); | |
912 pthread_mutex_init (tdata->statmutex, NULL); | |
913 pthread_mutex_lock (&transfer_mutex); | |
914 file_transfers = g_list_append (file_transfers, tdata); | |
915 pthread_mutex_unlock (&transfer_mutex); | |
916 if (dialog) | |
917 gftp_gtk_ask_transfer (tdata); | |
918 } | |
919 } | |
920 | |
921 | |
922 gint | |
923 update_downloads (gpointer data) | |
924 { | |
925 char tempstr[50], temp1str[127]; | |
926 GList * templist, * next; | |
927 gftp_transfer * tdata; | |
928 | |
929 if (file_transfer_logs != NULL) | |
930 display_cached_logs (); | |
931 | |
932 if (window2.request->gotbytes != 0) | |
933 { | |
934 if (window2.request->gotbytes == -1) | |
935 { | |
936 update_window_info (); | |
937 window2.request->gotbytes = 0; | |
938 } | |
939 else | |
940 { | |
941 insert_commas (window2.request->gotbytes, tempstr, sizeof (tempstr)); | |
942 g_snprintf (temp1str, sizeof (temp1str), | |
943 _("Retrieving file names...%s bytes"), tempstr); | |
944 gtk_label_set (GTK_LABEL (window2.hoststxt), temp1str); | |
945 } | |
946 } | |
947 | |
948 if (viewedit_process_done) | |
949 check_done_process (); | |
950 | |
951 for (templist = file_transfers; templist != NULL;) | |
952 { | |
953 tdata = templist->data; | |
954 if (tdata->ready) | |
955 { | |
956 pthread_mutex_lock (tdata->structmutex); | |
957 | |
958 if (tdata->next_file) | |
959 on_next_transfer (tdata); | |
960 else if (tdata->show) | |
961 show_transfer (tdata); | |
962 else if (tdata->done) | |
963 { | |
964 next = templist->next; | |
965 transfer_done (templist); | |
966 templist = next; | |
967 continue; | |
968 } | |
969 | |
970 if (tdata->curfle != NULL) | |
971 { | |
972 if (!tdata->started && start_file_transfers && | |
973 (transfer_in_progress == 0 || !do_one_transfer_at_a_time)) | |
974 create_transfer (tdata); | |
975 | |
976 if (tdata->started) | |
977 update_file_status (tdata); | |
978 } | |
979 pthread_mutex_unlock (tdata->structmutex); | |
980 } | |
981 templist = templist->next; | |
982 } | |
983 | |
984 gtk_timeout_add (500, update_downloads, NULL); | |
985 return (0); | |
986 } | |
987 | |
988 | |
989 static void | |
990 on_next_transfer (gftp_transfer * tdata) | |
991 { | |
992 gftp_file * tempfle; | |
993 int fd; | |
994 | |
995 tdata->next_file = 0; | |
996 for (; tdata->updfle != tdata->curfle; tdata->updfle = tdata->updfle->next) | |
997 { | |
998 tempfle = tdata->updfle->data; | |
999 | |
1000 if (tempfle->is_fd) | |
1001 fd = fileno (tempfle->fd); | |
1002 else | |
1003 fd = 0; | |
1004 | |
1005 if (tempfle->done_view) | |
1006 { | |
1007 if (tempfle->transfer_action != GFTP_TRANS_ACTION_SKIP) | |
1008 view_file (tempfle->destfile, fd, 1, tempfle->done_rm, 1, 0, | |
1009 tempfle->file, NULL); | |
1010 | |
1011 if (tempfle->is_fd) | |
1012 { | |
1013 fclose (tempfle->fd); | |
1014 tempfle->fd = NULL; | |
1015 } | |
1016 } | |
1017 else if (tempfle->done_edit) | |
1018 { | |
1019 if (tempfle->transfer_action != GFTP_TRANS_ACTION_SKIP) | |
1020 view_file (tempfle->destfile, fd, 0, tempfle->done_rm, 1, 0, | |
1021 tempfle->file, NULL); | |
1022 | |
1023 if (tempfle->is_fd) | |
1024 { | |
1025 fclose (tempfle->fd); | |
1026 tempfle->fd = NULL; | |
1027 } | |
1028 } | |
1029 else if (tempfle->done_rm) | |
1030 tdata->fromreq->rmfile (tdata->fromreq, tempfle->file); | |
1031 | |
1032 if (tempfle->transfer_action == GFTP_TRANS_ACTION_SKIP) | |
1033 gtk_ctree_node_set_text (GTK_CTREE (dlwdw), tempfle->node, 1, | |
1034 _("Skipped")); | |
1035 else | |
1036 gtk_ctree_node_set_text (GTK_CTREE (dlwdw), tempfle->node, 1, | |
1037 _("Finished")); | |
1038 } | |
1039 | |
1040 if (refresh_files && tdata->curfle && tdata->curfle->next && | |
1041 compare_request (tdata->toreq, | |
1042 ((gftp_window_data *) tdata->towdata)->request, 1)) | |
1043 refresh (tdata->towdata); | |
1044 } | |
1045 | |
1046 | |
1047 static void | |
19 | 1048 get_trans_password (gftp_request * request, gftp_dialog_data * ddata) |
1049 { | |
1050 gftp_set_password (request, gtk_entry_get_text (GTK_ENTRY (ddata->edit))); | |
1051 request->stopable = 0; | |
1052 } | |
1053 | |
1054 | |
1055 static void | |
1056 cancel_get_trans_password (gftp_transfer * tdata, gftp_dialog_data * ddata) | |
1057 { | |
1058 if (tdata->fromreq->stopable == 0) | |
1059 return; | |
1060 | |
1061 pthread_mutex_lock (tdata->structmutex); | |
1062 if (tdata->started) | |
1063 tdata->cancel = 1; | |
1064 else | |
1065 tdata->done = 1; | |
1066 | |
1067 tdata->fromreq->stopable = 0; | |
1068 tdata->toreq->stopable = 0; | |
1069 ftp_log (gftp_logging_misc, NULL, _("Stopping the transfer of %s\n"), | |
1070 ((gftp_file *) tdata->curfle->data)->file); | |
1071 pthread_mutex_unlock (tdata->structmutex); | |
1072 } | |
1073 | |
1074 | |
1075 static void | |
1 | 1076 show_transfer (gftp_transfer * tdata) |
1077 { | |
1078 GdkPixmap * closedir_pixmap, * opendir_pixmap; | |
1079 GdkBitmap * closedir_bitmap, * opendir_bitmap; | |
1080 gftp_curtrans_data * transdata; | |
1081 gftp_file * tempfle; | |
1082 char *pos, *text[2]; | |
1083 GList * templist; | |
1084 | |
1085 gftp_get_pixmap (dlwdw, "open_dir.xpm", &opendir_pixmap, &opendir_bitmap); | |
1086 gftp_get_pixmap (dlwdw, "dir.xpm", &closedir_pixmap, &closedir_bitmap); | |
1087 | |
1088 text[0] = GFTP_GET_HOSTNAME (tdata->fromreq); | |
1089 text[1] = _("Waiting..."); | |
1090 tdata->node = gtk_ctree_insert_node (GTK_CTREE (dlwdw), NULL, NULL, text, 5, | |
1091 closedir_pixmap, closedir_bitmap, | |
1092 opendir_pixmap, opendir_bitmap, | |
1093 FALSE, | |
1094 tdata->numdirs + tdata->numfiles < 50); | |
1095 transdata = g_malloc (sizeof (*transdata)); | |
1096 transdata->transfer = tdata; | |
1097 transdata->curfle = NULL; | |
1098 gtk_ctree_node_set_row_data (GTK_CTREE (dlwdw), tdata->node, transdata); | |
1099 tdata->show = 0; | |
1100 tdata->curfle = tdata->updfle = tdata->files; | |
1101 | |
1102 tdata->total_bytes = 0; | |
1103 for (templist = tdata->files; templist != NULL; templist = templist->next) | |
1104 { | |
1105 tempfle = templist->data; | |
1106 if ((pos = strrchr (tempfle->file, '/')) == NULL) | |
1107 pos = tempfle->file; | |
1108 else | |
1109 pos++; | |
1110 text[0] = pos; | |
1111 if (tempfle->transfer_action == GFTP_TRANS_ACTION_SKIP) | |
1112 text[1] = _("Skipped"); | |
1113 else | |
1114 { | |
1115 tdata->total_bytes += tempfle->size; | |
1116 text[1] = _("Waiting..."); | |
1117 } | |
1118 | |
1119 tempfle->node = gtk_ctree_insert_node (GTK_CTREE (dlwdw), tdata->node, | |
1120 NULL, text, 5, NULL, NULL, NULL, | |
1121 NULL, FALSE, FALSE); | |
1122 transdata = g_malloc (sizeof (*transdata)); | |
1123 transdata->transfer = tdata; | |
1124 transdata->curfle = templist; | |
1125 gtk_ctree_node_set_row_data (GTK_CTREE (dlwdw), tempfle->node, transdata); | |
1126 } | |
1127 | |
1128 if (!tdata->toreq->stopable && tdata->toreq->need_userpass && | |
1129 (tdata->toreq->password == NULL || *tdata->toreq->password == '\0')) | |
1130 { | |
1131 tdata->toreq->stopable = 1; | |
1132 MakeEditDialog (_("Enter Password"), | |
1133 _("Please enter your password for this site"), NULL, 0, | |
19 | 1134 NULL, gftp_dialog_button_connect, |
1135 get_trans_password, tdata->toreq, | |
1136 cancel_get_trans_password, tdata); | |
1 | 1137 } |
1138 | |
1139 if (!tdata->fromreq->stopable && tdata->fromreq->need_userpass && | |
1140 (tdata->fromreq->password == NULL || *tdata->fromreq->password == '\0')) | |
1141 { | |
1142 tdata->fromreq->stopable = 1; | |
1143 MakeEditDialog (_("Enter Password"), | |
1144 _("Please enter your password for this site"), NULL, 0, | |
19 | 1145 NULL, gftp_dialog_button_connect, |
1146 get_trans_password, tdata->fromreq, | |
1147 cancel_get_trans_password, tdata); | |
1 | 1148 } |
1149 } | |
1150 | |
1151 | |
1152 static void | |
1153 transfer_done (GList * node) | |
1154 { | |
1155 gftp_curtrans_data * transdata; | |
1156 gftp_request * fromreq; | |
1157 gftp_transfer * tdata; | |
1158 gftp_file * tempfle; | |
1159 GList * templist; | |
1160 | |
1161 tdata = node->data; | |
1162 if (tdata->started) | |
1163 { | |
1164 fromreq = ((gftp_window_data *) tdata->fromwdata)->request; | |
1165 if (!tdata->fromreq->stopable && tdata->fromwdata && | |
1166 ((fromreq->sockfd == NULL && fromreq->cached) || | |
1167 fromreq->always_connected) && tdata->fromreq->sockfd != NULL && | |
1168 compare_request (tdata->fromreq, fromreq, 0)) | |
1169 { | |
1170 swap_socks (((gftp_window_data *) tdata->towdata)->request, | |
1171 tdata->toreq); | |
1172 swap_socks (((gftp_window_data *) tdata->fromwdata)->request, | |
1173 tdata->fromreq); | |
1174 } | |
1175 else | |
1176 { | |
1177 gftp_disconnect (tdata->fromreq); | |
1178 gftp_disconnect (tdata->toreq); | |
1179 } | |
1180 | |
1181 if (tdata->towdata != NULL && compare_request (tdata->toreq, | |
1182 ((gftp_window_data *) tdata->towdata)->request, 1)) | |
1183 refresh (tdata->towdata); | |
1184 | |
1185 transfer_in_progress--; | |
1186 } | |
1187 | |
2
a171df6764a7
* Fixed crash if you was already transfering a file, and you started another
masneyb
parents:
1
diff
changeset
|
1188 if (!tdata->show && tdata->started) |
1 | 1189 { |
1190 transdata = gtk_ctree_node_get_row_data (GTK_CTREE (dlwdw), tdata->node); | |
1191 if (transdata != NULL) | |
1192 g_free (transdata); | |
1193 | |
1194 for (templist = tdata->files; templist != NULL; templist = templist->next) | |
1195 { | |
1196 tempfle = templist->data; | |
1197 transdata = gtk_ctree_node_get_row_data (GTK_CTREE (dlwdw), tempfle->node); | |
1198 if (transdata != NULL) | |
1199 g_free (transdata); | |
1200 } | |
1201 | |
1202 gtk_ctree_remove_node (GTK_CTREE (dlwdw), tdata->node); | |
1203 } | |
1204 pthread_mutex_lock (&transfer_mutex); | |
1205 file_transfers = g_list_remove_link (file_transfers, node); | |
1206 pthread_mutex_unlock (&transfer_mutex); | |
1207 pthread_mutex_destroy (tdata->structmutex); | |
1208 pthread_mutex_destroy (tdata->statmutex); | |
1209 free_tdata (tdata); | |
1210 } | |
1211 | |
1212 | |
1213 static void | |
1214 create_transfer (gftp_transfer * tdata) | |
1215 { | |
1216 pthread_t tid; | |
1217 | |
1218 if (!tdata->fromreq->stopable) | |
1219 { | |
1220 if (tdata->fromwdata && | |
1221 ((gftp_window_data *) tdata->fromwdata)->request->sockfd != NULL && | |
1222 !((gftp_window_data *) tdata->fromwdata)->request->stopable && | |
1223 compare_request (tdata->fromreq, ((gftp_window_data *) tdata->fromwdata)->request, 0)) | |
1224 { | |
1225 swap_socks (tdata->toreq, | |
1226 ((gftp_window_data *) tdata->towdata)->request); | |
1227 swap_socks (tdata->fromreq, | |
1228 ((gftp_window_data *) tdata->fromwdata)->request); | |
1229 update_window_info (); | |
1230 } | |
1231 transfer_in_progress++; | |
1232 tdata->started = 1; | |
1233 tdata->stalled = 1; | |
1234 gtk_ctree_node_set_text (GTK_CTREE (dlwdw), tdata->node, 1, | |
1235 _("Connecting...")); | |
1236 pthread_create (&tid, NULL, gftp_gtk_transfer_files, tdata); | |
1237 } | |
1238 } | |
1239 | |
1240 | |
1241 static void | |
1242 update_file_status (gftp_transfer * tdata) | |
1243 { | |
1244 char totstr[100], dlstr[100], gotstr[50], ofstr[50]; | |
1245 int hours, mins, secs, pcent, st; | |
1246 double remaining; | |
1247 gftp_file * tempfle; | |
1248 struct timeval tv; | |
1249 | |
1250 pthread_mutex_lock (tdata->statmutex); | |
1251 tempfle = tdata->curfle->data; | |
1252 | |
1253 gettimeofday (&tv, NULL); | |
1254 if ((remaining = (double) (tv.tv_sec - tdata->starttime.tv_sec) + ((double) (tv.tv_usec - tdata->starttime.tv_usec) / 1000000.0)) == 0) | |
1255 remaining = 1.0; | |
1256 | |
1257 remaining = ((double) (tdata->total_bytes - tdata->trans_bytes - tdata->resumed_bytes)) / 1024.0 / tdata->kbs; | |
1258 hours = (off_t) remaining / 3600; | |
1259 remaining -= hours * 3600; | |
1260 mins = (off_t) remaining / 60; | |
1261 remaining -= mins * 60; | |
1262 secs = (off_t) remaining; | |
1263 | |
1264 if (hours < 0 || mins < 0 || secs < 0) | |
1265 { | |
1266 pthread_mutex_unlock (tdata->statmutex); | |
1267 return; | |
1268 } | |
1269 | |
1270 pcent = (int) ((double) (tdata->trans_bytes + tdata->resumed_bytes) / (double) tdata->total_bytes * 100.0); | |
1271 if (pcent < 0 || pcent > 100) | |
1272 pcent = 0; | |
1273 | |
1274 g_snprintf (totstr, sizeof (totstr), | |
14
83090328581e
* More largefile support. Hopefully all that is left is the configure stuff
masneyb
parents:
7
diff
changeset
|
1275 _("%d%% complete, %02d:%02d:%02d est. time remaining. (File %ld of %ld)"), |
1 | 1276 pcent, hours, mins, secs, tdata->current_file_number, |
1277 tdata->numdirs + tdata->numfiles); | |
1278 | |
1279 *dlstr = '\0'; | |
1280 if (!tdata->stalled) | |
1281 { | |
1282 insert_commas (tdata->curtrans + tdata->curresumed, gotstr, sizeof (gotstr)); | |
1283 insert_commas (tempfle->size, ofstr, sizeof (ofstr)); | |
1284 st = 1; | |
1285 if (tv.tv_sec - tdata->lasttime.tv_sec <= 5) | |
1286 { | |
1287 if (tdata->curfle->next != NULL) | |
1288 { | |
1289 remaining = ((double) (tempfle->size - tdata->curtrans - tdata->curresumed)) / 1024.0 / tdata->kbs; | |
1290 hours = (off_t) remaining / 3600; | |
1291 remaining -= hours * 3600; | |
1292 mins = (off_t) remaining / 60; | |
1293 remaining -= mins * 60; | |
1294 secs = (off_t) remaining; | |
1295 } | |
1296 | |
1297 if (!(hours < 0 || mins < 0 || secs < 0)) | |
1298 { | |
1299 g_snprintf (dlstr, sizeof (dlstr), | |
1300 _("Recv %s of %s at %.2fKB/s, %02d:%02d:%02d est. time remaining"), gotstr, ofstr, tdata->kbs, hours, mins, secs); | |
1301 st = 0; | |
1302 } | |
1303 } | |
1304 | |
1305 if (st) | |
1306 { | |
1307 tdata->stalled = 1; | |
1308 g_snprintf (dlstr, sizeof (dlstr), | |
1309 _("Recv %s of %s, transfer stalled, unknown time remaining"), | |
1310 gotstr, ofstr); | |
1311 } | |
1312 } | |
1313 | |
1314 pthread_mutex_unlock (tdata->statmutex); | |
1315 | |
1316 gtk_ctree_node_set_text (GTK_CTREE (dlwdw), tdata->node, 1, totstr); | |
1317 | |
1318 if (*dlstr != '\0') | |
1319 gtk_ctree_node_set_text (GTK_CTREE (dlwdw), tempfle->node, 1, dlstr); | |
1320 } | |
1321 | |
1322 | |
1323 void | |
1324 start_transfer (gpointer data) | |
1325 { | |
1326 gftp_curtrans_data * transdata; | |
1327 GtkCTreeNode * node; | |
1328 | |
1329 if (GTK_CLIST (dlwdw)->selection == NULL) | |
1330 { | |
1331 ftp_log (gftp_logging_misc, NULL, | |
1332 _("There are no file transfers selected\n")); | |
1333 return; | |
1334 } | |
1335 node = GTK_CLIST (dlwdw)->selection->data; | |
1336 transdata = gtk_ctree_node_get_row_data (GTK_CTREE (dlwdw), node); | |
1337 | |
1338 pthread_mutex_lock (transdata->transfer->structmutex); | |
1339 if (!transdata->transfer->started) | |
1340 create_transfer (transdata->transfer); | |
1341 pthread_mutex_unlock (transdata->transfer->structmutex); | |
1342 } | |
1343 | |
1344 | |
1345 void | |
1346 stop_transfer (gpointer data) | |
1347 { | |
1348 gftp_curtrans_data * transdata; | |
1349 GtkCTreeNode * node; | |
1350 | |
1351 if (GTK_CLIST (dlwdw)->selection == NULL) | |
1352 { | |
1353 ftp_log (gftp_logging_misc, NULL, | |
1354 _("There are no file transfers selected\n")); | |
1355 return; | |
1356 } | |
1357 node = GTK_CLIST (dlwdw)->selection->data; | |
1358 transdata = gtk_ctree_node_get_row_data (GTK_CTREE (dlwdw), node); | |
1359 | |
1360 pthread_mutex_lock (transdata->transfer->structmutex); | |
1361 if (transdata->transfer->started) | |
1362 { | |
1363 transdata->transfer->cancel = 1; | |
1364 transdata->transfer->skip_file = 0; | |
1365 } | |
1366 else | |
1367 transdata->transfer->done = 1; | |
1368 ftp_log (gftp_logging_misc, NULL, _("Stopping the transfer on host %s\n"), | |
1369 transdata->transfer->fromreq->hostname); | |
1370 pthread_mutex_unlock (transdata->transfer->structmutex); | |
1371 } | |
1372 | |
1373 | |
1374 void | |
1375 skip_transfer (gpointer data) | |
1376 { | |
1377 gftp_curtrans_data * transdata; | |
1378 GtkCTreeNode * node; | |
1379 gftp_file * curfle; | |
1380 | |
1381 if (GTK_CLIST (dlwdw)->selection == NULL) | |
1382 { | |
1383 ftp_log (gftp_logging_misc, NULL, | |
1384 _("There are no file transfers selected\n")); | |
1385 return; | |
1386 } | |
1387 node = GTK_CLIST (dlwdw)->selection->data; | |
1388 transdata = gtk_ctree_node_get_row_data (GTK_CTREE (dlwdw), node); | |
1389 | |
1390 pthread_mutex_lock (transdata->transfer->structmutex); | |
1391 if (transdata->transfer->curfle != NULL) | |
1392 { | |
1393 curfle = transdata->transfer->curfle->data; | |
1394 if (transdata->transfer->started) | |
1395 { | |
1396 transdata->transfer->cancel = 1; | |
1397 transdata->transfer->skip_file = 1; | |
1398 } | |
1399 | |
1400 curfle->transfer_action = GFTP_TRANS_ACTION_SKIP; | |
1401 ftp_log (gftp_logging_misc, NULL, _("Skipping file %s on host %s\n"), | |
1402 curfle->file, transdata->transfer->fromreq->hostname); | |
1403 } | |
1404 pthread_mutex_unlock (transdata->transfer->structmutex); | |
1405 } | |
1406 | |
1407 | |
1408 void | |
1409 remove_file_transfer (gpointer data) | |
1410 { | |
1411 gftp_curtrans_data * transdata; | |
1412 GtkCTreeNode * node; | |
1413 gftp_file * curfle; | |
1414 | |
1415 if (GTK_CLIST (dlwdw)->selection == NULL) | |
1416 { | |
1417 ftp_log (gftp_logging_misc, NULL, | |
1418 _("There are no file transfers selected\n")); | |
1419 return; | |
1420 } | |
1421 | |
1422 node = GTK_CLIST (dlwdw)->selection->data; | |
1423 transdata = gtk_ctree_node_get_row_data (GTK_CTREE (dlwdw), node); | |
1424 | |
1425 | |
1426 if (transdata->curfle == NULL || transdata->curfle->data == NULL) | |
1427 return; | |
1428 | |
1429 curfle = transdata->curfle->data; | |
1430 | |
1431 if (curfle->transfer_action & GFTP_TRANS_ACTION_SKIP) | |
1432 return; | |
1433 | |
1434 pthread_mutex_lock (transdata->transfer->structmutex); | |
1435 | |
1436 curfle->transfer_action = GFTP_TRANS_ACTION_SKIP; | |
1437 | |
1438 if (transdata->transfer->started && | |
1439 transdata->curfle == transdata->transfer->curfle) | |
1440 { | |
1441 transdata->transfer->cancel = 1; | |
1442 transdata->transfer->skip_file = 1; | |
1443 } | |
1444 else if (transdata->curfle != transdata->transfer->curfle && | |
1445 !curfle->transfer_done) | |
1446 { | |
1447 gtk_ctree_node_set_text (GTK_CTREE (dlwdw), curfle->node, 1, | |
1448 _("Skipped")); | |
1449 transdata->transfer->total_bytes -= curfle->size; | |
1450 } | |
1451 | |
1452 ftp_log (gftp_logging_misc, NULL, _("Skipping file %s on host %s\n"), | |
1453 curfle->file, transdata->transfer->fromreq->hostname); | |
1454 | |
1455 pthread_mutex_unlock (transdata->transfer->structmutex); | |
1456 } | |
1457 | |
1458 | |
1459 void | |
1460 move_transfer_up (gpointer data) | |
1461 { | |
1462 GList * firstentry, * secentry, * lastentry; | |
1463 gftp_curtrans_data * transdata; | |
1464 GtkCTreeNode * node; | |
1465 | |
1466 if (GTK_CLIST (dlwdw)->selection == NULL) | |
1467 { | |
1468 ftp_log (gftp_logging_misc, NULL, | |
1469 _("There are no file transfers selected\n")); | |
1470 return; | |
1471 } | |
1472 node = GTK_CLIST (dlwdw)->selection->data; | |
1473 transdata = gtk_ctree_node_get_row_data (GTK_CTREE (dlwdw), node); | |
1474 | |
1475 if (transdata->curfle == NULL) | |
1476 return; | |
1477 | |
1478 pthread_mutex_lock (transdata->transfer->structmutex); | |
1479 if (transdata->curfle->prev != NULL && (!transdata->transfer->started || | |
1480 (transdata->transfer->curfle != transdata->curfle && | |
1481 transdata->transfer->curfle != transdata->curfle->prev))) | |
1482 { | |
1483 if (transdata->curfle->prev->prev == NULL) | |
1484 { | |
1485 firstentry = transdata->curfle->prev; | |
1486 lastentry = transdata->curfle->next; | |
1487 transdata->transfer->files = transdata->curfle; | |
1488 transdata->curfle->next = firstentry; | |
1489 transdata->transfer->files->prev = NULL; | |
1490 firstentry->prev = transdata->curfle; | |
1491 firstentry->next = lastentry; | |
1492 if (lastentry != NULL) | |
1493 lastentry->prev = firstentry; | |
1494 } | |
1495 else | |
1496 { | |
1497 firstentry = transdata->curfle->prev->prev; | |
1498 secentry = transdata->curfle->prev; | |
1499 lastentry = transdata->curfle->next; | |
1500 firstentry->next = transdata->curfle; | |
1501 transdata->curfle->prev = firstentry; | |
1502 transdata->curfle->next = secentry; | |
1503 secentry->prev = transdata->curfle; | |
1504 secentry->next = lastentry; | |
1505 if (lastentry != NULL) | |
1506 lastentry->prev = secentry; | |
1507 } | |
1508 | |
1509 gtk_ctree_move (GTK_CTREE (dlwdw), | |
1510 ((gftp_file *) transdata->curfle->data)->node, | |
1511 transdata->transfer->node, | |
1512 transdata->curfle->next != NULL ? | |
1513 ((gftp_file *) transdata->curfle->next->data)->node : | |
1514 NULL); | |
1515 } | |
1516 pthread_mutex_unlock (transdata->transfer->structmutex); | |
1517 } | |
1518 | |
1519 void | |
1520 move_transfer_down (gpointer data) | |
1521 { | |
1522 GList * firstentry, * secentry, * lastentry; | |
1523 gftp_curtrans_data * transdata; | |
1524 GtkCTreeNode * node; | |
1525 | |
1526 if (GTK_CLIST (dlwdw)->selection == NULL) | |
1527 { | |
1528 ftp_log (gftp_logging_misc, NULL, | |
1529 _("There are no file transfers selected\n")); | |
1530 return; | |
1531 } | |
1532 node = GTK_CLIST (dlwdw)->selection->data; | |
1533 transdata = gtk_ctree_node_get_row_data (GTK_CTREE (dlwdw), node); | |
1534 | |
1535 if (transdata->curfle == NULL) | |
1536 return; | |
1537 | |
1538 pthread_mutex_lock (transdata->transfer->structmutex); | |
1539 if (transdata->curfle->next != NULL && (!transdata->transfer->started || | |
1540 (transdata->transfer->curfle != transdata->curfle && | |
1541 transdata->transfer->curfle != transdata->curfle->next))) | |
1542 { | |
1543 if (transdata->curfle->prev == NULL) | |
1544 { | |
1545 firstentry = transdata->curfle->next; | |
1546 lastentry = transdata->curfle->next->next; | |
1547 transdata->transfer->files = firstentry; | |
1548 transdata->transfer->files->prev = NULL; | |
1549 transdata->transfer->files->next = transdata->curfle; | |
1550 transdata->curfle->prev = transdata->transfer->files; | |
1551 transdata->curfle->next = lastentry; | |
1552 if (lastentry != NULL) | |
1553 lastentry->prev = transdata->curfle; | |
1554 } | |
1555 else | |
1556 { | |
1557 firstentry = transdata->curfle->prev; | |
1558 secentry = transdata->curfle->next; | |
1559 lastentry = transdata->curfle->next->next; | |
1560 firstentry->next = secentry; | |
1561 secentry->prev = firstentry; | |
1562 secentry->next = transdata->curfle; | |
1563 transdata->curfle->prev = secentry; | |
1564 transdata->curfle->next = lastentry; | |
1565 if (lastentry != NULL) | |
1566 lastentry->prev = transdata->curfle; | |
1567 } | |
1568 | |
1569 gtk_ctree_move (GTK_CTREE (dlwdw), | |
1570 ((gftp_file *) transdata->curfle->data)->node, | |
1571 transdata->transfer->node, | |
1572 transdata->curfle->next != NULL ? | |
1573 ((gftp_file *) transdata->curfle->next->data)->node : | |
1574 NULL); | |
1575 } | |
1576 pthread_mutex_unlock (transdata->transfer->structmutex); | |
1577 } | |
1578 | |
1579 | |
1580 void | |
1581 gftp_gtk_ask_transfer (gftp_transfer * tdata) | |
1582 { | |
1583 char *dltitles[4], *add_data[4] = { NULL, NULL, NULL, NULL }, | |
1584 tempstr[50], temp1str[50]; | |
1585 GtkWidget * tempwid, * scroll, * hbox; | |
1586 gftp_file * tempfle; | |
1587 GList * templist; | |
1588 size_t len; | |
1589 char *pos; | |
1590 int i; | |
1591 | |
1592 dltitles[0] = _("Filename"); | |
1593 dltitles[1] = _("Local Size"); | |
1594 dltitles[2] = _("Remote Size"); | |
1595 dltitles[3] = _("Action"); | |
19 | 1596 dialog = gtk_dialog_new (); /* FIXME - gtk+ 2.0 stock icons */ |
1 | 1597 gtk_grab_add (dialog); |
1598 gtk_window_set_title (GTK_WINDOW (dialog), | |
1599 tdata->transfer_direction == GFTP_DIRECTION_DOWNLOAD ? | |
1600 _("Download Files") : _("Upload Files")); | |
1601 gtk_window_set_wmclass (GTK_WINDOW(dialog), "transfer", "gFTP"); | |
1602 gtk_container_border_width (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), 10); | |
1603 gtk_container_border_width (GTK_CONTAINER | |
1604 (GTK_DIALOG (dialog)->action_area), 5); | |
1605 gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dialog)->vbox), 5); | |
1606 gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dialog)->action_area), 35); | |
1607 gtk_box_set_homogeneous (GTK_BOX (GTK_DIALOG (dialog)->action_area), TRUE); | |
1608 gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_MOUSE); | |
1609 gtk_signal_connect_object (GTK_OBJECT (dialog), "delete_event", | |
1610 GTK_SIGNAL_FUNC (gtk_widget_destroy), | |
1611 GTK_OBJECT (dialog)); | |
1612 | |
1613 tempwid = gtk_label_new (_("The following file(s) exist on both the local and remote computer\nPlease select what you would like to do")); | |
1614 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), tempwid, FALSE, | |
1615 FALSE, 0); | |
1616 gtk_widget_show (tempwid); | |
1617 | |
1618 scroll = gtk_scrolled_window_new (NULL, NULL); | |
1619 gtk_widget_set_size_request (scroll, 450, 200); | |
1620 | |
1621 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll), | |
1622 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); | |
1623 tdata->clist = gtk_clist_new_with_titles (4, dltitles); | |
1624 gtk_container_add (GTK_CONTAINER (scroll), tdata->clist); | |
1625 | |
1626 #if GTK_MAJOR_VERSION == 1 && GTK_MINOR_VERSION == 2 | |
1627 gtk_clist_set_selection_mode (GTK_CLIST (tdata->clist), | |
1628 GTK_SELECTION_EXTENDED); | |
1629 #else | |
1630 gtk_clist_set_selection_mode (GTK_CLIST (tdata->clist), | |
1631 GTK_SELECTION_MULTIPLE); | |
1632 #endif | |
1633 gtk_clist_set_column_width (GTK_CLIST (tdata->clist), 0, 100); | |
1634 gtk_clist_set_column_justification (GTK_CLIST (tdata->clist), 1, | |
1635 GTK_JUSTIFY_RIGHT); | |
1636 gtk_clist_set_column_width (GTK_CLIST (tdata->clist), 1, 85); | |
1637 gtk_clist_set_column_justification (GTK_CLIST (tdata->clist), 2, | |
1638 GTK_JUSTIFY_RIGHT); | |
1639 gtk_clist_set_column_width (GTK_CLIST (tdata->clist), 2, 85); | |
1640 gtk_clist_set_column_width (GTK_CLIST (tdata->clist), 3, 85); | |
1641 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), scroll, TRUE, TRUE, | |
1642 0); | |
1643 gtk_widget_show (tdata->clist); | |
1644 gtk_widget_show (scroll); | |
1645 | |
1646 for (templist = tdata->files; templist != NULL; | |
1647 templist = templist->next) | |
1648 { | |
1649 tempfle = templist->data; | |
1650 if (tempfle->startsize == 0 || tempfle->isdir) | |
1651 { | |
1652 tempfle->shown = 0; | |
1653 continue; | |
1654 } | |
1655 tempfle->shown = 1; | |
1656 | |
1657 pos = tempfle->destfile; | |
1658 len = strlen (GFTP_GET_DIRECTORY (tdata->toreq)); | |
1659 if (strncmp (pos, GFTP_GET_DIRECTORY (tdata->toreq), len) == 0) | |
1660 pos = tempfle->destfile + len + 1; | |
1661 add_data[0] = pos; | |
1662 | |
1663 if (overwrite_by_default) | |
1664 add_data[3] = _("Overwrite"); | |
1665 else | |
1666 { | |
1667 if (tempfle->startsize >= tempfle->size) | |
1668 { | |
1669 add_data[3] = _("Skip"); | |
1670 tempfle->transfer_action = GFTP_TRANS_ACTION_SKIP; | |
1671 } | |
1672 else | |
1673 { | |
1674 add_data[3] = _("Resume"); | |
1675 tempfle->transfer_action = GFTP_TRANS_ACTION_RESUME; | |
1676 } | |
1677 } | |
1678 | |
1679 if (tdata->transfer_direction == GFTP_DIRECTION_DOWNLOAD) | |
1680 { | |
1681 add_data[2] = insert_commas (tempfle->size, tempstr, | |
1682 sizeof (tempstr)); | |
1683 add_data[1] = insert_commas (tempfle->startsize, temp1str, | |
1684 sizeof (temp1str)); | |
1685 } | |
1686 else | |
1687 { | |
1688 add_data[1] = insert_commas (tempfle->size, tempstr, | |
1689 sizeof (tempstr)); | |
1690 add_data[2] = insert_commas (tempfle->startsize, temp1str, | |
1691 sizeof (temp1str)); | |
1692 } | |
1693 i = gtk_clist_append (GTK_CLIST (tdata->clist), add_data); | |
1694 gtk_clist_set_row_data (GTK_CLIST (tdata->clist), i, tempfle); | |
1695 } | |
1696 | |
1697 gtk_clist_select_all (GTK_CLIST (tdata->clist)); | |
1698 | |
1699 hbox = gtk_hbox_new (TRUE, 20); | |
1700 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), hbox, TRUE, TRUE, 0); | |
1701 gtk_widget_show (hbox); | |
1702 | |
1703 tempwid = gtk_button_new_with_label (_("Overwrite")); | |
1704 gtk_box_pack_start (GTK_BOX (hbox), tempwid, TRUE, TRUE, 0); | |
1705 gtk_signal_connect (GTK_OBJECT (tempwid), "clicked", | |
1706 GTK_SIGNAL_FUNC (overwrite), (gpointer) tdata); | |
1707 gtk_widget_show (tempwid); | |
1708 | |
1709 tempwid = gtk_button_new_with_label (_("Resume")); | |
1710 gtk_box_pack_start (GTK_BOX (hbox), tempwid, TRUE, TRUE, 0); | |
1711 gtk_signal_connect (GTK_OBJECT (tempwid), "clicked", | |
1712 GTK_SIGNAL_FUNC (resume), (gpointer) tdata); | |
1713 gtk_widget_show (tempwid); | |
1714 | |
1715 tempwid = gtk_button_new_with_label (_("Skip File")); | |
1716 gtk_box_pack_start (GTK_BOX (hbox), tempwid, TRUE, TRUE, 0); | |
1717 gtk_signal_connect (GTK_OBJECT (tempwid), "clicked", GTK_SIGNAL_FUNC (skip), | |
1718 (gpointer) tdata); | |
1719 gtk_widget_show (tempwid); | |
1720 | |
1721 hbox = gtk_hbox_new (TRUE, 20); | |
1722 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), hbox, TRUE, TRUE, 0); | |
1723 gtk_widget_show (hbox); | |
1724 | |
1725 tempwid = gtk_button_new_with_label (_("Select All")); | |
1726 gtk_box_pack_start (GTK_BOX (hbox), tempwid, TRUE, TRUE, 0); | |
1727 gtk_signal_connect (GTK_OBJECT (tempwid), "clicked", | |
1728 GTK_SIGNAL_FUNC (trans_selectall), (gpointer) tdata); | |
1729 gtk_widget_show (tempwid); | |
1730 | |
1731 tempwid = gtk_button_new_with_label (_("Deselect All")); | |
1732 gtk_box_pack_start (GTK_BOX (hbox), tempwid, TRUE, TRUE, 0); | |
1733 gtk_signal_connect (GTK_OBJECT (tempwid), "clicked", | |
1734 GTK_SIGNAL_FUNC (trans_unselectall), (gpointer) tdata); | |
1735 gtk_widget_show (tempwid); | |
1736 | |
1737 tempwid = gtk_button_new_with_label (_("OK")); | |
1738 GTK_WIDGET_SET_FLAGS (tempwid, GTK_CAN_DEFAULT); | |
1739 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->action_area), tempwid, | |
1740 TRUE, TRUE, 0); | |
1741 gtk_signal_connect (GTK_OBJECT (tempwid), "clicked", GTK_SIGNAL_FUNC (ok), | |
1742 (gpointer) tdata); | |
1743 gtk_signal_connect_object (GTK_OBJECT (tempwid), "clicked", | |
1744 GTK_SIGNAL_FUNC (gtk_widget_destroy), | |
1745 GTK_OBJECT (dialog)); | |
1746 gtk_widget_grab_default (tempwid); | |
1747 gtk_widget_show (tempwid); | |
1748 | |
1749 tempwid = gtk_button_new_with_label (_(" Cancel ")); | |
1750 GTK_WIDGET_SET_FLAGS (tempwid, GTK_CAN_DEFAULT); | |
1751 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->action_area), tempwid, | |
1752 TRUE, TRUE, 0); | |
1753 gtk_signal_connect (GTK_OBJECT (tempwid), "clicked", | |
1754 GTK_SIGNAL_FUNC (cancel), (gpointer) tdata); | |
1755 gtk_signal_connect_object (GTK_OBJECT (tempwid), "clicked", | |
1756 GTK_SIGNAL_FUNC (gtk_widget_destroy), | |
1757 GTK_OBJECT (dialog)); | |
1758 gtk_widget_show (tempwid); | |
1759 | |
1760 gtk_widget_show (dialog); | |
1761 dialog = NULL; | |
1762 } | |
1763 | |
1764 | |
1765 static void | |
1766 trans_selectall (GtkWidget * widget, gpointer data) | |
1767 { | |
1768 gftp_transfer * tdata; | |
1769 tdata = data; | |
1770 | |
1771 gtk_clist_select_all (GTK_CLIST (tdata->clist)); | |
1772 } | |
1773 | |
1774 | |
1775 static void | |
1776 trans_unselectall (GtkWidget * widget, gpointer data) | |
1777 { | |
1778 gftp_transfer * tdata; | |
1779 tdata = data; | |
1780 | |
1781 gtk_clist_unselect_all (GTK_CLIST (tdata->clist)); | |
1782 } | |
1783 | |
1784 | |
1785 static void | |
1786 overwrite (GtkWidget * widget, gpointer data) | |
1787 { | |
1788 GList * templist, * filelist; | |
1789 gftp_transfer * tdata; | |
1790 gftp_file * tempfle; | |
1791 int curpos; | |
1792 | |
1793 tdata = data; | |
1794 curpos = 0; | |
1795 filelist = tdata->files; | |
1796 templist = GTK_CLIST (tdata->clist)->selection; | |
1797 while (templist != NULL) | |
1798 { | |
1799 templist = get_next_selection (templist, &filelist, &curpos); | |
1800 tempfle = filelist->data; | |
1801 tempfle->transfer_action = GFTP_TRANS_ACTION_OVERWRITE; | |
1802 gtk_clist_set_text (GTK_CLIST (tdata->clist), curpos, 3, _("Overwrite")); | |
1803 } | |
1804 } | |
1805 | |
1806 | |
1807 static void | |
1808 resume (GtkWidget * widget, gpointer data) | |
1809 { | |
1810 GList * templist, * filelist; | |
1811 gftp_transfer * tdata; | |
1812 gftp_file * tempfle; | |
1813 int curpos; | |
1814 | |
1815 tdata = data; | |
1816 curpos = 0; | |
1817 filelist = tdata->files; | |
1818 templist = GTK_CLIST (tdata->clist)->selection; | |
1819 while (templist != NULL) | |
1820 { | |
1821 templist = get_next_selection (templist, &filelist, &curpos); | |
1822 tempfle = filelist->data; | |
1823 tempfle->transfer_action = GFTP_TRANS_ACTION_RESUME; | |
1824 gtk_clist_set_text (GTK_CLIST (tdata->clist), curpos, 3, _("Resume")); | |
1825 } | |
1826 } | |
1827 | |
1828 | |
1829 static void | |
1830 skip (GtkWidget * widget, gpointer data) | |
1831 { | |
1832 GList * templist, * filelist; | |
1833 gftp_transfer * tdata; | |
1834 gftp_file * tempfle; | |
1835 int curpos; | |
1836 | |
1837 tdata = data; | |
1838 curpos = 0; | |
1839 filelist = tdata->files; | |
1840 templist = GTK_CLIST (tdata->clist)->selection; | |
1841 while (templist != NULL) | |
1842 { | |
1843 templist = get_next_selection (templist, &filelist, &curpos); | |
1844 tempfle = filelist->data; | |
1845 tempfle->transfer_action = GFTP_TRANS_ACTION_SKIP; | |
1846 gtk_clist_set_text (GTK_CLIST (tdata->clist), curpos, 3, _("Skip")); | |
1847 } | |
1848 } | |
1849 | |
1850 | |
1851 static void | |
1852 ok (GtkWidget * widget, gpointer data) | |
1853 { | |
1854 gftp_transfer * tdata; | |
1855 gftp_file * tempfle; | |
1856 GList * templist; | |
1857 | |
1858 tdata = data; | |
1859 pthread_mutex_lock ((pthread_mutex_t *) tdata->structmutex); | |
1860 for (templist = tdata->files; templist != NULL; templist = templist->next) | |
1861 { | |
1862 tempfle = templist->data; | |
1863 if (tempfle->transfer_action != GFTP_TRANS_ACTION_SKIP) | |
1864 break; | |
1865 } | |
1866 | |
1867 if (templist == NULL) | |
1868 { | |
1869 tdata->show = 0; | |
1870 tdata->ready = tdata->done = 1; | |
1871 } | |
1872 else | |
1873 tdata->show = tdata->ready = 1; | |
1874 pthread_mutex_unlock ((pthread_mutex_t *) tdata->structmutex); | |
1875 } | |
1876 | |
1877 | |
1878 static void | |
1879 cancel (GtkWidget * widget, gpointer data) | |
1880 { | |
1881 gftp_transfer * tdata; | |
1882 | |
1883 tdata = data; | |
1884 pthread_mutex_lock ((pthread_mutex_t *) tdata->structmutex); | |
1885 tdata->show = 0; | |
1886 tdata->done = tdata->ready = 1; | |
1887 pthread_mutex_unlock ((pthread_mutex_t *) tdata->structmutex); | |
1888 } | |
1889 | |
1890 | |
1891 static void | |
1892 gftp_gtk_calc_kbs (gftp_transfer * tdata, ssize_t num_read) | |
1893 { | |
1894 unsigned long waitusecs; | |
1895 double difftime, curkbs; | |
1896 gftp_file * tempfle; | |
1897 struct timeval tv; | |
1898 unsigned long toadd; | |
1899 | |
1900 gettimeofday (&tv, NULL); | |
1901 pthread_mutex_lock (tdata->statmutex); | |
1902 | |
1903 tempfle = tdata->curfle->data; | |
1904 tdata->trans_bytes += num_read; | |
1905 tdata->curtrans += num_read; | |
1906 tdata->stalled = 0; | |
1907 | |
1908 difftime = (tv.tv_sec - tdata->starttime.tv_sec) + ((double) (tv.tv_usec - tdata->starttime.tv_usec) / 1000000.0); | |
19 | 1909 if (difftime <= 0) |
1 | 1910 tdata->kbs = (double) tdata->trans_bytes / 1024.0; |
1911 else | |
1912 tdata->kbs = (double) tdata->trans_bytes / 1024.0 / difftime; | |
1913 | |
1914 difftime = (tv.tv_sec - tdata->lasttime.tv_sec) + ((double) (tv.tv_usec - tdata->lasttime.tv_usec) / 1000000.0); | |
1915 | |
1916 if (difftime <= 0) | |
1917 curkbs = (double) (num_read / 1024.0); | |
1918 else | |
1919 curkbs = (double) (num_read / 1024.0 / difftime); | |
1920 | |
1921 if (tdata->fromreq->maxkbs > 0 && | |
1922 curkbs > tdata->fromreq->maxkbs) | |
1923 { | |
1924 waitusecs = (double) num_read / 1024.0 / tdata->fromreq->maxkbs * 1000000.0 - difftime; | |
1925 | |
1926 if (waitusecs > 0) | |
1927 { | |
1928 pthread_mutex_unlock (tdata->statmutex); | |
1929 difftime += ((double) waitusecs / 1000000.0); | |
1930 usleep (waitusecs); | |
1931 pthread_mutex_lock (tdata->statmutex); | |
1932 } | |
1933 } | |
1934 | |
1935 /* I don't call gettimeofday (&tdata->lasttime) here because this will use | |
1936 less system resources. This will be close enough for what we need */ | |
1937 difftime += tdata->lasttime.tv_usec / 1000000.0; | |
1938 toadd = (long) difftime; | |
1939 difftime -= toadd; | |
1940 tdata->lasttime.tv_sec += toadd; | |
1941 tdata->lasttime.tv_usec = difftime * 1000000.0; | |
1942 | |
1943 pthread_mutex_unlock (tdata->statmutex); | |
1944 } | |
1945 | |
1946 | |
1947 static void | |
1948 check_done_process (void) | |
1949 { | |
1950 gftp_viewedit_data * ve_proc; | |
1951 GList * curdata, *deldata; | |
1952 struct stat st; | |
1953 int ret; | |
1954 char *str; | |
1955 pid_t pid; | |
1956 | |
1957 viewedit_process_done = 0; | |
1958 while ((pid = waitpid (-1, &ret, WNOHANG)) > 0) | |
1959 { | |
1960 curdata = viewedit_processes; | |
1961 while (curdata != NULL) | |
1962 { | |
1963 ve_proc = curdata->data; | |
1964 deldata = curdata; | |
1965 curdata = curdata->next; | |
1966 if (ve_proc->pid == pid) | |
1967 { | |
1968 viewedit_processes = g_list_remove_link (viewedit_processes, | |
1969 deldata); | |
1970 if (ret != 0) | |
1971 ftp_log (gftp_logging_error, NULL, | |
1972 _("Error: Child %d returned %d\n"), pid, ret); | |
1973 else | |
1974 ftp_log (gftp_logging_misc, NULL, | |
1975 _("Child %d returned successfully\n"), pid); | |
1976 | |
1977 if (!ve_proc->view && !ve_proc->dontupload) | |
1978 { | |
1979 /* We was editing the file. Upload it */ | |
1980 if (stat (ve_proc->filename, &st) == -1) | |
1981 ftp_log (gftp_logging_error, NULL, | |
1982 _("Error: Cannot get information about file %s: %s\n"), | |
1983 ve_proc->filename, g_strerror (errno)); | |
1984 else if (st.st_mtime == ve_proc->st.st_mtime) | |
1985 { | |
1986 ftp_log (gftp_logging_misc, NULL, | |
1987 _("File %s was not changed\n"), | |
1988 ve_proc->filename); | |
1989 remove_file (ve_proc->filename); | |
1990 } | |
1991 else | |
1992 { | |
1993 memcpy (&ve_proc->st, &st, sizeof (ve_proc->st)); | |
1994 str = g_strdup_printf ( | |
19 | 1995 _("File %s has changed.\nWould you like to upload it?"), |
1 | 1996 ve_proc->remote_filename); |
1997 | |
19 | 1998 MakeYesNoDialog (_("Edit File"), str, |
1999 do_upload, ve_proc, | |
2000 dont_upload, ve_proc); | |
1 | 2001 g_free (str); |
2002 continue; | |
2003 } | |
2004 } | |
2005 | |
19 | 2006 free_edit_data (ve_proc); |
1 | 2007 continue; |
2008 } | |
2009 } | |
2010 } | |
2011 } | |
2012 | |
2013 | |
2014 static void | |
19 | 2015 do_upload (gftp_viewedit_data * ve_proc, gftp_dialog_data * ddata) |
1 | 2016 { |
2017 gftp_file * tempfle; | |
2018 GList * newfile; | |
2019 | |
2020 tempfle = g_malloc0 (sizeof (*tempfle)); | |
2021 tempfle->destfile = ve_proc->remote_filename; | |
2022 ve_proc->remote_filename = NULL; | |
2023 tempfle->file = ve_proc->filename; | |
2024 ve_proc->filename = NULL; | |
2025 tempfle->done_rm = 1; | |
2026 newfile = g_list_append (NULL, tempfle); | |
2027 add_file_transfer (ve_proc->fromwdata->request, ve_proc->towdata->request, | |
2028 ve_proc->fromwdata, ve_proc->towdata, newfile, 1); | |
19 | 2029 free_edit_data (ve_proc); |
1 | 2030 } |
2031 | |
2032 | |
2033 static void | |
19 | 2034 dont_upload (gftp_viewedit_data * ve_proc, gftp_dialog_data * ddata) |
1 | 2035 { |
2036 remove_file (ve_proc->filename); | |
19 | 2037 free_edit_data (ve_proc); |
1 | 2038 } |
2039 | |
2040 | |
2041 static void | |
19 | 2042 free_edit_data (gftp_viewedit_data * ve_proc) |
1 | 2043 { |
2044 int i; | |
2045 | |
2046 if (ve_proc->filename) | |
2047 g_free (ve_proc->filename); | |
2048 if (ve_proc->remote_filename) | |
2049 g_free (ve_proc->remote_filename); | |
2050 for (i = 0; ve_proc->argv[i] != NULL; i++) | |
2051 g_free (ve_proc->argv[i]); | |
2052 g_free (ve_proc->argv); | |
2053 g_free (ve_proc); | |
2054 } | |
2055 | |
2056 | |
2057 static int | |
2058 get_status (gftp_transfer * tdata, ssize_t num_read) | |
2059 { | |
2060 gftp_file * tempfle; | |
2061 struct timeval tv; | |
2062 | |
2063 pthread_mutex_lock (tdata->structmutex); | |
2064 if (tdata->curfle == NULL) | |
2065 { | |
2066 pthread_mutex_unlock (tdata->structmutex); | |
2067 return (-1); | |
2068 } | |
2069 tempfle = tdata->curfle->data; | |
2070 pthread_mutex_unlock (tdata->structmutex); | |
2071 | |
2072 gftp_disconnect (tdata->fromreq); | |
2073 gftp_disconnect (tdata->toreq); | |
2074 if (num_read < 0 || tdata->skip_file) | |
2075 { | |
2076 if (tdata->fromreq->retries != 0 && tdata->current_file_retries >= tdata->fromreq->retries) | |
2077 { | |
2078 tdata->fromreq->logging_function (gftp_logging_error, | |
2079 tdata->fromreq->user_data, | |
2080 _("Error: Remote site %s disconnected. Max retries reached...giving up\n"), | |
36 | 2081 tdata->fromreq->hostname != NULL ? |
2082 tdata->fromreq->hostname : tdata->toreq->hostname); | |
1 | 2083 return (-1); |
2084 } | |
2085 else | |
2086 { | |
2087 tdata->fromreq->logging_function (gftp_logging_error, | |
2088 tdata->fromreq->user_data, | |
2089 _("Error: Remote site %s disconnected. Will reconnect in %d seconds\n"), | |
36 | 2090 tdata->fromreq->hostname != NULL ? |
2091 tdata->fromreq->hostname : tdata->toreq->hostname, | |
2092 tdata->fromreq->sleep_time); | |
1 | 2093 } |
2094 | |
2095 while (tdata->fromreq->retries == 0 || | |
2096 tdata->current_file_retries <= tdata->fromreq->retries) | |
2097 { | |
2098 if (!tdata->skip_file) | |
2099 { | |
2100 tv.tv_sec = tdata->fromreq->sleep_time; | |
2101 tv.tv_usec = 0; | |
2102 select (0, NULL, NULL, NULL, &tv); | |
2103 } | |
2104 | |
2105 if (gftp_connect (tdata->fromreq) == 0 && | |
2106 gftp_connect (tdata->toreq) == 0) | |
2107 { | |
2108 pthread_mutex_lock (tdata->structmutex); | |
2109 tdata->resumed_bytes = tdata->resumed_bytes + tdata->trans_bytes - tdata->curresumed - tdata->curtrans; | |
2110 tdata->trans_bytes = 0; | |
2111 if (tdata->skip_file) | |
2112 { | |
2113 tdata->total_bytes -= tempfle->size; | |
2114 tdata->curtrans = 0; | |
2115 | |
2116 tdata->curfle = tdata->curfle->next; | |
2117 tdata->next_file = 1; | |
2118 tdata->skip_file = 0; | |
2119 tdata->cancel = 0; | |
2120 } | |
2121 else | |
2122 { | |
2123 tempfle->transfer_action = GFTP_TRANS_ACTION_RESUME; | |
2124 tempfle->startsize = tdata->curtrans + tdata->curresumed; | |
2125 /* We decrement this here because it will be incremented in | |
2126 the loop again */ | |
2127 tdata->curresumed = 0; | |
2128 tdata->current_file_number--; /* Decrement this because it | |
2129 will be incremented when we | |
2130 continue in the loop */ | |
2131 } | |
2132 gettimeofday (&tdata->starttime, NULL); | |
2133 pthread_mutex_unlock (tdata->structmutex); | |
2134 return (1); | |
2135 } | |
2136 else | |
2137 tdata->current_file_retries++; | |
2138 } | |
2139 } | |
2140 else if (tdata->cancel) | |
2141 return (-1); | |
2142 | |
2143 return (0); | |
2144 } | |
2145 | |
2146 | |
2147 static void | |
2148 wakeup_main_thread (gpointer data, gint source, GdkInputCondition condition) | |
2149 { | |
2150 gftp_request * request; | |
2151 char c; | |
2152 | |
2153 request = data; | |
2154 if (request->wakeup_main_thread[0] > 0) | |
2155 read (request->wakeup_main_thread[0], &c, 1); | |
2156 } | |
2157 | |
2158 | |
2159 static gint | |
2160 setup_wakeup_main_thread (gftp_request * request) | |
2161 { | |
2162 gint handler; | |
2163 | |
2164 if (socketpair (AF_UNIX, SOCK_STREAM, 0, request->wakeup_main_thread) == 0) | |
2165 { | |
2166 handler = gdk_input_add (request->wakeup_main_thread[0], | |
2167 GDK_INPUT_READ, wakeup_main_thread, request); | |
2168 } | |
2169 else | |
2170 { | |
2171 request->wakeup_main_thread[0] = 0; | |
2172 request->wakeup_main_thread[1] = 0; | |
2173 handler = 0; | |
2174 } | |
2175 return (handler); | |
2176 } | |
2177 | |
2178 | |
2179 static void | |
2180 teardown_wakeup_main_thread (gftp_request * request, gint handler) | |
2181 { | |
2182 if (request->wakeup_main_thread[0] > 0 && request->wakeup_main_thread[1] > 0) | |
2183 { | |
2184 gdk_input_remove (handler); | |
2185 close (request->wakeup_main_thread[0]); | |
2186 close (request->wakeup_main_thread[1]); | |
2187 request->wakeup_main_thread[0] = 0; | |
2188 request->wakeup_main_thread[1] = 0; | |
2189 } | |
2190 } | |
2191 | |
2192 | |
2193 static mode_t | |
2194 parse_attribs (char *attribs) | |
2195 { | |
2196 mode_t mode; | |
2197 int cur; | |
2198 | |
2199 cur = 0; | |
2200 if (attribs[1] == 'r') | |
2201 cur += 4; | |
2202 if (attribs[2] == 'w') | |
2203 cur += 2; | |
2204 if (attribs[3] == 'x' || | |
2205 attribs[3] == 's') | |
2206 cur += 1; | |
2207 mode = cur; | |
2208 | |
2209 cur = 0; | |
2210 if (attribs[4] == 'r') | |
2211 cur += 4; | |
2212 if (attribs[5] == 'w') | |
2213 cur += 2; | |
2214 if (attribs[6] == 'x' || | |
2215 attribs[6] == 's') | |
2216 cur += 1; | |
2217 mode = (mode * 10) + cur; | |
2218 | |
2219 cur = 0; | |
2220 if (attribs[7] == 'r') | |
2221 cur += 4; | |
2222 if (attribs[8] == 'w') | |
2223 cur += 2; | |
2224 if (attribs[9] == 'x' || | |
2225 attribs[9] == 's') | |
2226 cur += 1; | |
2227 mode = (mode * 10) + cur; | |
2228 | |
2229 return (mode); | |
2230 } | |
2231 | |
2232 | |
2233 static void | |
2234 remove_file (char *filename) | |
2235 { | |
2236 if (unlink (filename) == 0) | |
2237 ftp_log (gftp_logging_misc, NULL, _("Successfully removed %s\n"), | |
2238 filename); | |
2239 else | |
2240 ftp_log (gftp_logging_error, NULL, | |
2241 _("Error: Could not remove file %s: %s\n"), filename, | |
2242 g_strerror (errno)); | |
2243 } | |
2244 | |
2245 | |
2246 static RETSIGTYPE | |
2247 sig_connquit (int signo) | |
2248 { | |
2249 signal (signo, sig_connquit); | |
2250 siglongjmp (connenvir, signo == SIGINT ? 1 : 2); | |
2251 } | |
2252 |