Mercurial > gftp.yaz
annotate lib/misc.c @ 303:3b9d5797050f
2003-11-2 Brian Masney <masneyb@gftp.org>
* lib/rfc2068.c (rfc2068_chunked_read) - more improvements to this
function so that it will parse more chunked file transfers correctly.
* lib/misc.c lib/gftp.h lib/rfc2068.c src/gtk/bookmarks.c
src/gtk/dnd.c - removed remove_double_slashes(). Call gftp_build_path()
to build the paths. This now allows Novell directory listings with
//server
* lib/protocols.c src/gtk/transfer.c lib/gftp.h - added variable
conn_error_no_timeout to gftp_transfer structure. If this is enabled,
if the remote connection to the server timed out, don't wait and
immediately reconnect. So far, the only time this is used is when the
user was editing a file and it is to be uploaded back to the server.
* src/gtk/gftp-gtk.h src/gtk/transfer.c - add_file_transfer() now
returns the struct gftp_transfer that was just added.
* src/gtk/misc-gtk.c (update_directory_download_progress) - don't
make the window a popup and remove the window decorations
* src/text/gftp-text.c - don't populate the transfer_direction variable
in struct gftp_transfer. This is only needed by the GTK+ port and will
hopefully be taken out soon.
* lib/gftp.h - remove gftp_transfer_type enum. It wasn't used anymore.
author | masneyb |
---|---|
date | Mon, 03 Nov 2003 02:14:05 +0000 |
parents | 51725086634d |
children | 76c912483d1d |
rev | line source |
---|---|
1 | 1 /*****************************************************************************/ |
2 /* misc.c - general purpose routines */ | |
122 | 3 /* Copyright (C) 1998-2003 Brian Masney <masneyb@gftp.org> */ |
1 | 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 | |
102 | 20 static const char cvsid[] = "$Id$"; |
21 | |
1 | 22 #include "gftp.h" |
23 #include "options.h" | |
24 | |
289 | 25 #ifdef _GNU_SOURCE |
26 | |
27 char * | |
28 insert_commas (off_t number, char *dest_str, size_t dest_len) | |
29 { | |
30 if (dest_str != NULL) | |
31 { | |
32 #if defined (_LARGEFILE_SOURCE) | |
33 g_snprintf (dest_str, dest_len, "%'lld", number); | |
34 #else | |
35 g_snprintf (dest_str, dest_len, "%'ld", number); | |
36 #endif | |
37 } | |
38 else | |
39 { | |
40 #if defined (_LARGEFILE_SOURCE) | |
41 dest_str = g_strdup_printf ("%'lld", number); | |
42 #else | |
43 dest_str = g_strdup_printf ("%'ld", number); | |
44 #endif | |
45 } | |
46 | |
47 return (dest_str); | |
48 } | |
49 | |
50 #else | |
51 | |
1 | 52 char * |
14
83090328581e
* More largefile support. Hopefully all that is left is the configure stuff
masneyb
parents:
13
diff
changeset
|
53 insert_commas (off_t number, char *dest_str, size_t dest_len) |
1 | 54 { |
55 char *frompos, *topos, src[50], *dest; | |
56 int len, num, rem, i; | |
57 | |
220 | 58 #if defined (_LARGEFILE_SOURCE) |
59 g_snprintf (src, sizeof (src), "%lld", number); | |
60 #else | |
61 g_snprintf (src, sizeof (src), "%ld", number); | |
62 #endif | |
63 | |
1 | 64 if (dest_str != NULL) |
65 *dest_str = '\0'; | |
66 | |
220 | 67 len = strlen (src); |
68 if (len == 0) | |
1 | 69 { |
70 if (dest_str != NULL) | |
249 | 71 { |
72 strncpy (dest_str, "0", dest_len); | |
73 dest_str[dest_len - 1] = '\0'; | |
74 } | |
1 | 75 else |
56 | 76 dest_str = g_strdup ("0"); |
1 | 77 return (dest_str); |
78 } | |
79 | |
80 len += len / 3; | |
220 | 81 |
1 | 82 if (dest_str != NULL && len > dest_len) |
83 { | |
84 | |
85 for (i=0; i<dest_len - 1; i++) | |
86 dest_str[i] = 'X'; | |
87 dest_str[dest_len - 1] = '\0'; | |
88 return (dest_str); | |
89 } | |
90 | |
91 if (dest_str == NULL) | |
92 dest = g_malloc0 (len); | |
93 else | |
94 dest = dest_str; | |
95 | |
96 num = strlen (src) / 3 - 1; | |
97 rem = strlen (src) % 3; | |
98 frompos = src; | |
99 topos = dest; | |
100 for (i = 0; i < rem; i++) | |
101 *topos++ = *frompos++; | |
102 | |
103 if (*frompos != '\0') | |
104 { | |
105 if (rem != 0) | |
106 *topos++ = ','; | |
107 while (num > 0) | |
108 { | |
109 for (i = 0; i < 3; i++) | |
110 *topos++ = *frompos++; | |
111 *topos++ = ','; | |
112 num--; | |
113 } | |
114 for (i = 0; i < 3; i++) | |
115 *topos++ = *frompos++; | |
116 } | |
117 *topos = '\0'; | |
118 return (dest); | |
119 } | |
120 | |
289 | 121 #endif |
1 | 122 |
123 char * | |
124 alltrim (char *str) | |
125 { | |
126 char *pos, *newpos; | |
127 int diff; | |
128 | |
129 pos = str + strlen (str) - 1; | |
87 | 130 while (pos >= str && (*pos == ' ' || *pos == '\t')) |
1 | 131 *pos-- = '\0'; |
132 | |
133 pos = str; | |
134 diff = 0; | |
135 while (*pos++ == ' ') | |
136 diff++; | |
137 | |
138 if (diff == 0) | |
139 return (str); | |
140 | |
141 pos = str + diff; | |
142 newpos = str; | |
143 while (*pos != '\0') | |
144 *newpos++ = *pos++; | |
145 *newpos = '\0'; | |
146 | |
147 return (str); | |
148 } | |
149 | |
150 | |
151 char * | |
152 expand_path (const char *src) | |
153 { | |
154 char *str, *pos, *endpos, *prevpos, *newstr, *tempstr, tempchar; | |
155 struct passwd *pw; | |
156 | |
157 pw = NULL; | |
124 | 158 str = g_strdup (src); |
1 | 159 |
160 if (*str == '~') | |
161 { | |
162 if (*(str + 1) == '/' || *(str + 1) == '\0') | |
163 pw = getpwuid (geteuid ()); | |
164 else | |
165 { | |
166 if ((pos = strchr (str, '/')) != NULL) | |
167 *pos = '\0'; | |
168 | |
169 pw = getpwnam (str + 1); | |
170 | |
171 if (pos != NULL) | |
172 *pos = '/'; | |
173 } | |
174 } | |
175 | |
176 endpos = str; | |
177 newstr = NULL; | |
178 while ((pos = strchr (endpos, '/')) != NULL) | |
179 { | |
180 pos++; | |
181 while (*pos == '/') | |
182 pos++; | |
204 | 183 |
1 | 184 if ((endpos = strchr (pos, '/')) == NULL) |
185 endpos = pos + strlen (pos); | |
204 | 186 |
1 | 187 tempchar = *endpos; |
188 *endpos = '\0'; | |
204 | 189 |
1 | 190 if (strcmp (pos, "..") == 0) |
191 { | |
192 *(pos - 1) = '\0'; | |
193 if (newstr != NULL && (prevpos = strrchr (newstr, '/')) != NULL) | |
194 *prevpos = '\0'; | |
195 } | |
196 else if (strcmp (pos, ".") != 0) | |
197 { | |
198 if (newstr == NULL) | |
56 | 199 newstr = g_strdup (pos - 1); |
1 | 200 else |
201 { | |
202 tempstr = g_strconcat (newstr, pos - 1, NULL); | |
203 g_free (newstr); | |
204 newstr = tempstr; | |
205 } | |
206 } | |
204 | 207 |
1 | 208 *endpos = tempchar; |
209 if (*endpos == '\0') | |
210 break; | |
204 | 211 |
1 | 212 endpos = pos + 1; |
213 } | |
214 | |
204 | 215 if (endpos != NULL && *endpos != '\0' && newstr == NULL) |
216 { | |
217 if (strcmp (endpos, "..") == 0) | |
218 newstr = g_malloc0 (1); | |
219 else | |
220 newstr = g_strdup (endpos); | |
221 } | |
222 | |
1 | 223 if (newstr == NULL || *newstr == '\0') |
224 { | |
225 if (newstr != NULL) | |
226 g_free (newstr); | |
204 | 227 |
247 | 228 newstr = g_strdup ("/"); |
1 | 229 } |
230 | |
231 g_free (str); | |
232 | |
233 if (pw != NULL) | |
234 { | |
235 if ((pos = strchr (newstr, '/')) == NULL) | |
124 | 236 str = g_strdup (pw->pw_dir); |
1 | 237 else |
247 | 238 str = gftp_build_path (pw->pw_dir, pos, NULL); |
1 | 239 |
240 g_free (newstr); | |
241 newstr = str; | |
242 } | |
243 | |
244 return (newstr); | |
245 } | |
246 | |
247 | |
248 void | |
249 make_nonnull (char **str) | |
250 { | |
251 if (*str == NULL) | |
252 *str = g_malloc0 (1); | |
253 } | |
254 | |
255 | |
256 int | |
257 copyfile (char *source, char *dest) | |
258 { | |
58 | 259 int srcfd, destfd; |
1 | 260 char buf[8192]; |
58 | 261 ssize_t n; |
1 | 262 |
182 | 263 if ((srcfd = gftp_fd_open (NULL, source, O_RDONLY, 0)) == -1) |
58 | 264 { |
265 printf (_("Error: Cannot open local file %s: %s\n"), | |
266 source, g_strerror (errno)); | |
267 exit (1); | |
268 } | |
1 | 269 |
182 | 270 if ((destfd = gftp_fd_open (NULL, dest, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR)) == -1) |
1 | 271 { |
58 | 272 printf (_("Error: Cannot open local file %s: %s\n"), |
273 dest, g_strerror (errno)); | |
274 close (srcfd); | |
275 exit (1); | |
1 | 276 } |
277 | |
58 | 278 while ((n = read (srcfd, buf, sizeof (buf))) > 0) |
279 { | |
280 if (write (destfd, buf, n) == -1) | |
281 { | |
282 printf (_("Error: Could not write to socket: %s\n"), | |
283 g_strerror (errno)); | |
284 exit (1); | |
285 } | |
286 } | |
1 | 287 |
58 | 288 if (n == -1) |
289 { | |
290 printf (_("Error: Could not read from socket: %s\n"), g_strerror (errno)); | |
291 exit (1); | |
292 } | |
293 | |
87 | 294 if (close (srcfd) == -1) |
295 { | |
296 printf (_("Error closing file descriptor: %s\n"), g_strerror (errno)); | |
297 exit (1); | |
298 } | |
299 | |
300 if (close (destfd) == -1) | |
301 { | |
302 printf (_("Error closing file descriptor: %s\n"), g_strerror (errno)); | |
303 exit (1); | |
304 } | |
1 | 305 |
306 return (1); | |
307 } | |
308 | |
309 | |
87 | 310 /* FIXME - is there a replacement for this */ |
1 | 311 int |
312 gftp_match_filespec (char *filename, char *filespec) | |
313 { | |
314 char *filepos, *wcpos, *pos, *newpos, search_str[20]; | |
315 size_t len, curlen; | |
316 | |
317 if (filename == NULL || *filename == '\0' || | |
318 filespec == NULL || *filespec == '\0') | |
319 return(1); | |
320 | |
321 filepos = filename; | |
322 wcpos = filespec; | |
323 while(1) | |
324 { | |
325 if (*wcpos == '\0') | |
326 return (1); | |
327 else if (*filepos == '\0') | |
328 return(0); | |
329 else if(*wcpos == '?') | |
330 { | |
331 wcpos++; | |
332 filepos++; | |
333 } | |
334 else if(*wcpos == '*' && *(wcpos+1) == '\0') | |
335 return(1); | |
336 else if(*wcpos == '*') | |
337 { | |
338 len = sizeof (search_str); | |
339 for (pos = wcpos + 1, newpos = search_str, curlen = 0; | |
340 *pos != '*' && *pos != '?' && *pos != '\0' && curlen < len; | |
341 curlen++, *newpos++ = *pos++); | |
342 *newpos = '\0'; | |
343 | |
344 if ((filepos = strstr (filepos, search_str)) == NULL) | |
345 return(0); | |
346 wcpos += curlen + 1; | |
347 filepos += curlen; | |
348 } | |
349 else if(*wcpos++ != *filepos++) | |
350 return(0); | |
351 } | |
352 return (1); | |
353 } | |
354 | |
355 | |
243 | 356 static void |
357 gftp_info (void) | |
358 { | |
260 | 359 int i; |
360 | |
243 | 361 printf ("%s\n", gftp_version); |
362 | |
289 | 363 #ifdef _GNU_SOURCE |
364 printf ("#define _GNU_SOURCE\n"); | |
365 #endif | |
366 | |
243 | 367 #ifdef _LARGEFILE_SOURCE |
260 | 368 printf ("#define _LARGEFILE_SOURCE\n"); |
243 | 369 #endif |
370 | |
371 #ifdef _FILE_OFFSET_BITS | |
372 printf ("#define _FILE_OFFSET_BITS %d\n", _FILE_OFFSET_BITS); | |
373 #endif | |
374 | |
375 printf ("sizeof (off_t) = %d\n", sizeof (off_t)); | |
376 | |
377 #ifdef HAVE_GETADDRINFO | |
378 printf ("#define HAVE_GETADDRINFO\n"); | |
379 #endif | |
380 | |
381 #ifdef HAVE_GAI_STRERROR | |
382 printf ("#define HAVE_GAI_STRERROR\n"); | |
383 #endif | |
384 | |
385 #ifdef HAVE_GETDTABLESIZE | |
386 printf ("#define HAVE_GETDTABLESIZE\n"); | |
387 #endif | |
388 | |
389 #ifdef G_HAVE_GINT64 | |
390 printf ("#define G_HAVE_GINT64\n"); | |
391 #endif | |
392 | |
393 #ifdef HAVE_LIBREADLINE | |
394 printf ("#define HAVE_LIBREADLINE\n"); | |
395 #endif | |
396 | |
397 #ifdef ENABLE_NLS | |
398 printf ("#define ENABLE_NLS\n"); | |
399 #endif | |
400 | |
401 #ifdef HAVE_GETTEXT | |
402 printf ("#define HAVE_GETTEXT\n"); | |
403 #endif | |
404 | |
405 printf ("glib version: %d.%d.%d\n", GLIB_MAJOR_VERSION, GLIB_MINOR_VERSION, | |
406 GLIB_MICRO_VERSION); | |
407 | |
408 printf ("PTY implementation: %s\n", gftp_get_pty_impl ()); | |
409 | |
410 #ifdef USE_SSL | |
411 printf ("OpenSSL version: 0x%lx\n", OPENSSL_VERSION_NUMBER); | |
412 #endif | |
260 | 413 |
414 printf ("Enabled protocols: "); | |
415 for (i=0; gftp_protocols[i].name != NULL; i++) | |
416 { | |
417 printf ("%s ", gftp_protocols[i].name); | |
418 } | |
419 printf ("\n"); | |
243 | 420 } |
421 | |
422 | |
1 | 423 int |
424 gftp_parse_command_line (int *argc, char ***argv) | |
425 { | |
426 if (*argc > 1) | |
427 { | |
87 | 428 if (strcmp (argv[0][1], "--help") == 0 || |
429 strcmp (argv[0][1], "-h") == 0) | |
1 | 430 gftp_usage (); |
87 | 431 else if (strcmp (argv[0][1], "--version") == 0 || |
432 strcmp (argv[0][1], "-v") == 0) | |
1 | 433 { |
122 | 434 printf ("%s\n", gftp_version); |
1 | 435 exit (0); |
436 } | |
243 | 437 else if (strcmp (argv[0][1], "--info") == 0) |
438 { | |
439 gftp_info (); | |
440 exit (0); | |
441 } | |
1 | 442 } |
443 return (0); | |
444 } | |
445 | |
446 | |
447 void | |
448 gftp_usage (void) | |
449 { | |
162 | 450 printf (_("usage: gftp [[protocol://][user[:pass]@]site[:port][/directory]]\n")); |
1 | 451 exit (0); |
452 } | |
453 | |
454 | |
455 gint | |
456 string_hash_compare (gconstpointer path1, gconstpointer path2) | |
457 { | |
458 return (strcmp ((char *) path1, (char *) path2) == 0); | |
459 } | |
460 | |
461 | |
462 guint | |
463 string_hash_function (gconstpointer key) | |
464 { | |
59 | 465 guint ret; |
466 int i; | |
467 | |
468 ret = 0; | |
87 | 469 for (i=0; ((char *) key)[i] != '\0' && i < 3; i++) |
59 | 470 ret += ((char *) key)[i]; |
471 | |
472 return (ret); | |
1 | 473 } |
474 | |
475 | |
476 void | |
477 free_file_list (GList * filelist) | |
478 { | |
479 gftp_file * tempfle; | |
480 GList * templist; | |
481 | |
482 templist = filelist; | |
483 while (templist != NULL) | |
484 { | |
485 tempfle = templist->data; | |
486 free_fdata (tempfle); | |
487 templist = templist->next; | |
488 } | |
489 g_list_free (filelist); | |
490 } | |
491 | |
492 | |
493 void | |
494 free_fdata (gftp_file * fle) | |
495 { | |
496 if (fle->file) | |
497 g_free (fle->file); | |
184 | 498 if (fle->utf8_file) |
499 g_free (fle->utf8_file); | |
1 | 500 if (fle->user) |
501 g_free (fle->user); | |
502 if (fle->group) | |
503 g_free (fle->group); | |
504 if (fle->attribs) | |
505 g_free (fle->attribs); | |
506 if (fle->destfile) | |
507 g_free (fle->destfile); | |
58 | 508 if (fle->fd > 0) |
102 | 509 close (fle->fd); |
1 | 510 g_free (fle); |
511 } | |
512 | |
513 | |
514 gftp_file * | |
515 copy_fdata (gftp_file * fle) | |
516 { | |
517 gftp_file * newfle; | |
518 | |
519 newfle = g_malloc0 (sizeof (*newfle)); | |
520 memcpy (newfle, fle, sizeof (*newfle)); | |
521 | |
522 if (fle->file) | |
87 | 523 newfle->file = g_strdup (fle->file); |
1 | 524 |
243 | 525 if (fle->utf8_file) |
526 newfle->utf8_file = g_strdup (fle->utf8_file); | |
527 | |
1 | 528 if (fle->user) |
87 | 529 newfle->user = g_strdup (fle->user); |
1 | 530 |
531 if (fle->group) | |
87 | 532 newfle->group = g_strdup (fle->group); |
1 | 533 |
534 if (fle->attribs) | |
87 | 535 newfle->attribs = g_strdup (fle->attribs); |
1 | 536 |
537 if (fle->destfile) | |
87 | 538 newfle->destfile = g_strdup (fle->destfile); |
539 | |
1 | 540 return (newfle); |
541 } | |
542 | |
543 | |
544 int | |
545 compare_request (gftp_request * request1, gftp_request * request2, | |
546 int compare_dirs) | |
547 { | |
548 char *strarr[3][2]; | |
549 int i, ret; | |
550 | |
551 ret = 1; | |
87 | 552 if (request1->protonum == request2->protonum && |
1 | 553 request1->port == request2->port) |
554 { | |
555 strarr[0][0] = request1->hostname; | |
556 strarr[0][1] = request2->hostname; | |
557 strarr[1][0] = request1->username; | |
558 strarr[1][1] = request2->username; | |
559 if (compare_dirs) | |
560 { | |
561 strarr[2][0] = request1->directory; | |
562 strarr[2][1] = request2->directory; | |
563 } | |
564 else | |
565 strarr[2][0] = strarr[2][1] = ""; | |
566 | |
567 for (i = 0; i < 3; i++) | |
568 { | |
569 if ((strarr[i][0] && !strarr[i][1]) || | |
570 (!strarr[i][0] && strarr[i][1])) | |
571 { | |
572 ret = 0; | |
573 break; | |
574 } | |
575 | |
576 if (strarr[i][0] && strarr[i][1] && | |
577 strcmp (strarr[i][0], strarr[i][1]) != 0) | |
578 { | |
579 ret = 0; | |
580 break; | |
581 } | |
582 } | |
583 } | |
584 else | |
585 ret = 0; | |
586 return (ret); | |
587 } | |
588 | |
589 | |
129 | 590 gftp_transfer * |
591 gftp_tdata_new (void) | |
592 { | |
227 | 593 #if GLIB_MAJOR_VERSION == 1 |
594 static GStaticMutex init_mutex = G_STATIC_MUTEX_INIT; | |
595 #endif | |
129 | 596 gftp_transfer * tdata; |
597 | |
598 tdata = g_malloc0 (sizeof (*tdata)); | |
227 | 599 |
600 #if GLIB_MAJOR_VERSION == 1 | |
601 tdata->statmutex = init_mutex; | |
602 tdata->structmutex = init_mutex; | |
603 #else | |
168 | 604 g_static_mutex_init (&tdata->statmutex); |
605 g_static_mutex_init (&tdata->structmutex); | |
227 | 606 #endif |
607 | |
129 | 608 return (tdata); |
609 } | |
610 | |
611 | |
1 | 612 void |
613 free_tdata (gftp_transfer * tdata) | |
614 { | |
615 if (tdata->fromreq != NULL) | |
67 | 616 gftp_request_destroy (tdata->fromreq, 1); |
1 | 617 if (tdata->toreq != NULL) |
67 | 618 gftp_request_destroy (tdata->toreq, 1); |
1 | 619 free_file_list (tdata->files); |
620 g_free (tdata); | |
621 } | |
622 | |
623 | |
624 gftp_request * | |
151 | 625 copy_request (gftp_request * req, int copy_local_options) |
1 | 626 { |
627 gftp_request * newreq; | |
628 | |
66 | 629 newreq = gftp_request_new (); |
1 | 630 |
631 if (req->hostname) | |
56 | 632 newreq->hostname = g_strdup (req->hostname); |
1 | 633 if (req->username) |
56 | 634 newreq->username = g_strdup (req->username); |
1 | 635 if (req->password) |
56 | 636 newreq->password = g_strdup (req->password); |
1 | 637 if (req->account) |
56 | 638 newreq->account = g_strdup (req->account); |
1 | 639 if (req->directory) |
56 | 640 newreq->directory = g_strdup (req->directory); |
66 | 641 newreq->port = req->port; |
642 newreq->use_proxy = req->use_proxy; | |
643 newreq->logging_function = req->logging_function; | |
151 | 644 newreq->free_hostp = 0; |
296 | 645 newreq->hostp = NULL; |
151 | 646 |
647 if (copy_local_options) | |
199 | 648 gftp_copy_local_options (&newreq->local_options_vars, |
649 &newreq->local_options_hash, | |
650 req->local_options_vars, | |
651 req->num_local_options_vars); | |
1 | 652 |
173 | 653 if (req->init (newreq) < 0) |
654 { | |
655 gftp_request_destroy (newreq, 1); | |
656 return (NULL); | |
657 } | |
1 | 658 |
659 return (newreq); | |
660 } | |
661 | |
662 | |
16 | 663 static gint |
664 gftp_file_sort_function_as (gconstpointer a, gconstpointer b) | |
665 { | |
666 const gftp_file * f1, * f2; | |
667 | |
668 f1 = a; | |
669 f2 = b; | |
670 return (strcmp (f1->file, f2->file)); | |
671 } | |
672 | |
673 | |
674 static gint | |
675 gftp_file_sort_function_ds (gconstpointer a, gconstpointer b) | |
676 { | |
677 const gftp_file * f1, * f2; | |
678 gint ret; | |
679 | |
680 f1 = a; | |
681 f2 = b; | |
682 ret = strcmp (f1->file, f2->file); | |
84 | 683 return (ret * -1); |
16 | 684 } |
685 | |
686 | |
687 static gint | |
688 gftp_user_sort_function_as (gconstpointer a, gconstpointer b) | |
689 { | |
690 const gftp_file * f1, * f2; | |
691 | |
692 f1 = a; | |
693 f2 = b; | |
694 return (strcmp (f1->user, f2->user)); | |
695 } | |
696 | |
697 | |
698 static gint | |
699 gftp_user_sort_function_ds (gconstpointer a, gconstpointer b) | |
700 { | |
701 const gftp_file * f1, * f2; | |
702 gint ret; | |
703 | |
704 f1 = a; | |
705 f2 = b; | |
706 ret = strcmp (f1->user, f2->user); | |
84 | 707 return (ret * -1); |
16 | 708 } |
709 | |
710 | |
711 static gint | |
712 gftp_group_sort_function_as (gconstpointer a, gconstpointer b) | |
713 { | |
714 const gftp_file * f1, * f2; | |
715 | |
716 f1 = a; | |
717 f2 = b; | |
718 return (strcmp (f1->group, f2->group)); | |
719 } | |
720 | |
721 | |
722 static gint | |
723 gftp_group_sort_function_ds (gconstpointer a, gconstpointer b) | |
724 { | |
725 const gftp_file * f1, * f2; | |
726 gint ret; | |
727 | |
728 f1 = a; | |
729 f2 = b; | |
730 ret = strcmp (f1->group, f2->group); | |
84 | 731 return (ret * -1); |
16 | 732 } |
733 | |
734 | |
735 static gint | |
736 gftp_attribs_sort_function_as (gconstpointer a, gconstpointer b) | |
737 { | |
738 const gftp_file * f1, * f2; | |
739 | |
740 f1 = a; | |
741 f2 = b; | |
742 return (strcmp (f1->attribs, f2->attribs)); | |
743 } | |
744 | |
745 | |
746 static gint | |
747 gftp_attribs_sort_function_ds (gconstpointer a, gconstpointer b) | |
748 { | |
749 const gftp_file * f1, * f2; | |
750 gint ret; | |
751 | |
752 f1 = a; | |
753 f2 = b; | |
754 ret = strcmp (f1->attribs, f2->attribs); | |
84 | 755 return (ret * -1); |
16 | 756 } |
757 | |
758 | |
759 static gint | |
760 gftp_size_sort_function_as (gconstpointer a, gconstpointer b) | |
761 { | |
762 const gftp_file * f1, * f2; | |
763 | |
764 f1 = a; | |
765 f2 = b; | |
766 if (f1->size < f2->size) | |
767 return (-1); | |
768 else if (f1->size == f2->size) | |
769 return (0); | |
770 else | |
771 return (1); | |
772 } | |
773 | |
774 | |
775 static gint | |
776 gftp_size_sort_function_ds (gconstpointer a, gconstpointer b) | |
777 { | |
778 const gftp_file * f1, * f2; | |
779 | |
780 f1 = a; | |
781 f2 = b; | |
782 if (f1->size < f2->size) | |
783 return (1); | |
784 else if (f1->size == f2->size) | |
785 return (0); | |
786 else | |
787 return (-1); | |
788 } | |
789 | |
790 | |
791 static gint | |
792 gftp_datetime_sort_function_as (gconstpointer a, gconstpointer b) | |
793 { | |
794 const gftp_file * f1, * f2; | |
795 | |
796 f1 = a; | |
797 f2 = b; | |
798 if (f1->datetime < f2->datetime) | |
799 return (-1); | |
800 else if (f1->datetime == f2->datetime) | |
801 return (0); | |
802 else | |
803 return (1); | |
804 } | |
805 | |
806 | |
807 static gint | |
808 gftp_datetime_sort_function_ds (gconstpointer a, gconstpointer b) | |
809 { | |
810 const gftp_file * f1, * f2; | |
811 | |
812 f1 = a; | |
813 f2 = b; | |
814 if (f1->datetime < f2->datetime) | |
815 return (1); | |
816 else if (f1->datetime == f2->datetime) | |
817 return (0); | |
818 else | |
819 return (-1); | |
820 } | |
821 | |
822 | |
823 GList * | |
824 gftp_sort_filelist (GList * filelist, int column, int asds) | |
825 { | |
826 GList * files, * dirs, * dotdot, * tempitem, * insitem; | |
827 GCompareFunc sortfunc; | |
828 gftp_file * tempfle; | |
122 | 829 int sort_dirs_first; |
16 | 830 |
831 files = dirs = dotdot = NULL; | |
832 | |
833 if (column == GFTP_SORT_COL_FILE) | |
834 sortfunc = asds ? gftp_file_sort_function_as : gftp_file_sort_function_ds; | |
835 else if (column == GFTP_SORT_COL_SIZE) | |
836 sortfunc = asds ? gftp_size_sort_function_as : gftp_size_sort_function_ds; | |
837 else if (column == GFTP_SORT_COL_USER) | |
838 sortfunc = asds ? gftp_user_sort_function_as : gftp_user_sort_function_ds; | |
839 else if (column == GFTP_SORT_COL_GROUP) | |
840 sortfunc = asds ? | |
841 gftp_group_sort_function_as : gftp_group_sort_function_ds; | |
842 else if (column == GFTP_SORT_COL_DATETIME) | |
843 sortfunc = asds ? | |
122 | 844 gftp_datetime_sort_function_as : gftp_datetime_sort_function_ds; |
845 else if (column == GFTP_SORT_COL_ATTRIBS) | |
16 | 846 sortfunc = asds ? |
847 gftp_attribs_sort_function_as : gftp_attribs_sort_function_ds; | |
122 | 848 else /* Don't sort */ |
849 return (filelist); | |
850 | |
851 sort_dirs_first = 1; | |
852 gftp_lookup_global_option ("sort_dirs_first", &sort_dirs_first); | |
16 | 853 |
854 for (tempitem = filelist; tempitem != NULL; ) | |
855 { | |
856 tempfle = tempitem->data; | |
857 insitem = tempitem; | |
858 tempitem = tempitem->next; | |
859 insitem->next = NULL; | |
860 | |
861 if (dotdot == NULL && strcmp (tempfle->file, "..") == 0) | |
862 dotdot = insitem; | |
863 else if (sort_dirs_first && tempfle->isdir) | |
864 { | |
865 insitem->next = dirs; | |
866 dirs = insitem; | |
867 } | |
868 else | |
869 { | |
870 insitem->next = files; | |
871 files = insitem; | |
872 } | |
873 } | |
874 | |
875 if (dirs != NULL) | |
876 dirs = g_list_sort (dirs, sortfunc); | |
877 if (files != NULL) | |
878 files = g_list_sort (files, sortfunc); | |
879 | |
880 filelist = dotdot; | |
881 | |
882 if (filelist == NULL) | |
883 filelist = dirs; | |
884 else | |
885 filelist = g_list_concat (filelist, dirs); | |
886 | |
887 if (filelist == NULL) | |
888 filelist = files; | |
889 else | |
890 filelist = g_list_concat (filelist, files); | |
891 | |
39 | 892 /* I haven't check this, but I'm pretty sure some older versions of glib |
893 had a bug that the prev pointer wasn't being sent to NULL */ | |
894 filelist->prev = NULL; | |
16 | 895 return (filelist); |
896 } | |
897 | |
125 | 898 |
899 mode_t | |
900 gftp_parse_attribs (char *attribs) | |
901 { | |
902 mode_t mode; | |
903 int cur; | |
904 | |
905 cur = 0; | |
906 if (attribs[1] == 'r') | |
907 cur += 4; | |
908 if (attribs[2] == 'w') | |
909 cur += 2; | |
910 if (attribs[3] == 'x' || | |
911 attribs[3] == 's') | |
912 cur += 1; | |
913 mode = cur; | |
914 | |
915 cur = 0; | |
916 if (attribs[4] == 'r') | |
917 cur += 4; | |
918 if (attribs[5] == 'w') | |
919 cur += 2; | |
920 if (attribs[6] == 'x' || | |
921 attribs[6] == 's') | |
922 cur += 1; | |
923 mode = (mode * 10) + cur; | |
924 | |
925 cur = 0; | |
926 if (attribs[7] == 'r') | |
927 cur += 4; | |
928 if (attribs[8] == 'w') | |
929 cur += 2; | |
930 if (attribs[9] == 'x' || | |
931 attribs[9] == 's') | |
932 cur += 1; | |
933 mode = (mode * 10) + cur; | |
934 | |
935 return (mode); | |
936 } | |
937 | |
938 | |
131 | 939 char * |
940 gftp_gen_ls_string (gftp_file * fle, char *file_prefixstr, char *file_suffixstr) | |
941 { | |
942 char *tempstr1, *tempstr2, *ret, tstr[50]; | |
943 struct tm *lt; | |
944 time_t t; | |
945 | |
946 lt = localtime (&fle->datetime); | |
947 | |
948 tempstr1 = g_strdup_printf ("%10s %8s %8s", fle->attribs, fle->user, | |
949 fle->group); | |
950 | |
951 if (fle->attribs && (*fle->attribs == 'b' || *fle->attribs == 'c')) | |
952 tempstr2 = g_strdup_printf ("%d, %d", major (fle->size), minor (fle->size)); | |
953 else | |
954 { | |
955 #if defined (_LARGEFILE_SOURCE) | |
956 tempstr2 = g_strdup_printf ("%11lld", fle->size); | |
957 #else | |
958 tempstr2 = g_strdup_printf ("%11ld", fle->size); | |
959 #endif | |
960 } | |
961 | |
962 time (&t); | |
963 | |
964 if (fle->datetime > t || t - 3600*24*90 > fle->datetime) | |
965 strftime (tstr, sizeof (tstr), "%b %d %Y", lt); | |
966 else | |
967 strftime (tstr, sizeof (tstr), "%b %d %H:%M", lt); | |
968 | |
969 if (file_prefixstr == NULL) | |
970 file_prefixstr = ""; | |
971 if (file_suffixstr == NULL) | |
972 file_suffixstr = ""; | |
973 | |
974 ret = g_strdup_printf ("%s %s %s %s%s%s", tempstr1, tempstr2, tstr, | |
184 | 975 file_prefixstr, |
976 fle->utf8_file != NULL ? fle->utf8_file : fle->file, | |
977 file_suffixstr); | |
131 | 978 |
979 g_free (tempstr1); | |
980 g_free (tempstr2); | |
981 | |
982 return (ret); | |
983 } | |
984 | |
985 | |
125 | 986 #if !defined (HAVE_GETADDRINFO) || !defined (HAVE_GAI_STRERROR) |
987 | |
988 struct hostent * | |
989 r_gethostbyname (const char *name, struct hostent *result_buf, int *h_errnop) | |
990 { | |
991 static GStaticMutex hostfunclock = G_STATIC_MUTEX_INIT; | |
992 struct hostent *hent; | |
993 | |
994 if (g_thread_supported ()) | |
995 g_static_mutex_lock (&hostfunclock); | |
996 | |
997 if ((hent = gethostbyname (name)) == NULL) | |
998 { | |
999 if (h_errnop) | |
1000 *h_errnop = h_errno; | |
1001 } | |
1002 else | |
1003 { | |
1004 *result_buf = *hent; | |
1005 hent = result_buf; | |
1006 } | |
1007 | |
1008 if (g_thread_supported ()) | |
1009 g_static_mutex_unlock (&hostfunclock); | |
1010 | |
1011 return (hent); | |
1012 } | |
1013 | |
1014 #endif /* !HAVE_GETADDRINFO */ | |
1015 | |
1016 struct servent * | |
1017 r_getservbyname (const char *name, const char *proto, | |
1018 struct servent *result_buf, int *h_errnop) | |
1019 { | |
1020 static GStaticMutex servfunclock = G_STATIC_MUTEX_INIT; | |
1021 struct servent *sent; | |
1022 | |
1023 if (g_thread_supported ()) | |
1024 g_static_mutex_lock (&servfunclock); | |
1025 | |
1026 if ((sent = getservbyname (name, proto)) == NULL) | |
1027 { | |
1028 if (h_errnop) | |
1029 *h_errnop = h_errno; | |
1030 } | |
1031 else | |
1032 { | |
1033 *result_buf = *sent; | |
1034 sent = result_buf; | |
1035 } | |
1036 | |
1037 if (g_thread_supported ()) | |
1038 g_static_mutex_unlock (&servfunclock); | |
1039 return (sent); | |
1040 } | |
1041 | |
168 | 1042 |
1043 char * | |
1044 base64_encode (char *str) | |
1045 { | |
1046 | |
1047 /* The standard to Base64 encoding can be found in RFC2045 */ | |
1048 | |
1049 char *newstr, *newpos, *fillpos, *pos; | |
1050 unsigned char table[64], encode[3]; | |
1051 int i, num; | |
1052 | |
1053 for (i = 0; i < 26; i++) | |
1054 { | |
1055 table[i] = 'A' + i; | |
1056 table[i + 26] = 'a' + i; | |
1057 } | |
1058 | |
1059 for (i = 0; i < 10; i++) | |
1060 table[i + 52] = '0' + i; | |
1061 | |
1062 table[62] = '+'; | |
207 | 1063 table[63] = '/'; |
168 | 1064 |
1065 num = strlen (str) / 3; | |
1066 if (strlen (str) % 3 > 0) | |
1067 num++; | |
1068 newstr = g_malloc (num * 4 + 1); | |
1069 newstr[num * 4] = '\0'; | |
1070 newpos = newstr; | |
1071 | |
1072 pos = str; | |
1073 while (*pos != '\0') | |
1074 { | |
1075 memset (encode, 0, sizeof (encode)); | |
1076 for (i = 0; i < 3 && *pos != '\0'; i++) | |
1077 encode[i] = *pos++; | |
1078 | |
1079 fillpos = newpos; | |
1080 *newpos++ = table[encode[0] >> 2]; | |
1081 *newpos++ = table[(encode[0] & 3) << 4 | encode[1] >> 4]; | |
1082 *newpos++ = table[(encode[1] & 0xF) << 2 | encode[2] >> 6]; | |
1083 *newpos++ = table[encode[2] & 0x3F]; | |
1084 while (i < 3) | |
1085 fillpos[++i] = '='; | |
1086 } | |
1087 return (newstr); | |
1088 } | |
1089 | |
199 | 1090 |
1091 void | |
1092 gftp_free_bookmark (gftp_bookmarks_var * entry) | |
1093 { | |
1094 if (entry->hostname) | |
1095 g_free (entry->hostname); | |
1096 if (entry->remote_dir) | |
1097 g_free (entry->remote_dir); | |
1098 if (entry->local_dir) | |
1099 g_free (entry->local_dir); | |
1100 if (entry->user) | |
1101 g_free (entry->user); | |
1102 if (entry->pass) | |
1103 g_free (entry->pass); | |
1104 if (entry->acct) | |
1105 g_free (entry->acct); | |
1106 if (entry->protocol) | |
1107 g_free (entry->protocol); | |
1108 | |
1109 if (entry->local_options_vars != NULL) | |
1110 { | |
201 | 1111 gftp_config_free_options (entry->local_options_vars, |
1112 entry->local_options_hash, | |
1113 entry->num_local_options_vars); | |
1114 | |
199 | 1115 entry->local_options_vars = NULL; |
201 | 1116 entry->local_options_hash = NULL; |
199 | 1117 entry->num_local_options_vars = 0; |
1118 } | |
1119 } | |
1120 | |
201 | 1121 |
1122 void | |
1123 gftp_shutdown (void) | |
1124 { | |
203 | 1125 #ifdef WITH_DMALLOC |
201 | 1126 gftp_config_vars * cv; |
1127 GList * templist; | |
203 | 1128 #endif |
201 | 1129 |
1130 if (gftp_logfd != NULL) | |
1131 fclose (gftp_logfd); | |
1132 | |
1133 gftp_clear_cache_files (); | |
1134 | |
1135 if (gftp_configuration_changed) | |
1136 gftp_write_config_file (); | |
1137 | |
1138 #ifdef WITH_DMALLOC | |
1139 if (gftp_global_options_htable != NULL) | |
1140 g_hash_table_destroy (gftp_global_options_htable); | |
1141 | |
1142 if (gftp_config_list_htable != NULL) | |
1143 g_hash_table_destroy (gftp_config_list_htable); | |
1144 | |
1145 if (gftp_bookmarks_htable != NULL) | |
1146 g_hash_table_destroy (gftp_bookmarks_htable); | |
1147 | |
1148 for (templist = gftp_options_list; | |
1149 templist != NULL; | |
1150 templist = templist->next) | |
1151 { | |
1152 cv = templist->data; | |
1153 gftp_config_free_options (cv, NULL, -1); | |
1154 } | |
1155 | |
1156 gftp_bookmarks_destroy (gftp_bookmarks); | |
1157 | |
1158 dmalloc_shutdown (); | |
1159 #endif | |
1160 | |
1161 exit (0); | |
1162 } | |
1163 | |
207 | 1164 |
1165 GList * | |
1166 get_next_selection (GList * selection, GList ** list, int *curnum) | |
1167 { | |
1168 gftp_file * tempfle; | |
1169 int i, newpos; | |
1170 | |
1171 newpos = GPOINTER_TO_INT (selection->data); | |
1172 i = *curnum - newpos; | |
1173 | |
1174 if (i < 0) | |
1175 { | |
1176 while (i != 0) | |
1177 { | |
1178 tempfle = (*list)->data; | |
1179 if (tempfle->shown) | |
1180 { | |
1181 ++*curnum; | |
1182 i++; | |
1183 } | |
1184 *list = (*list)->next; | |
1185 } | |
1186 } | |
1187 else if (i > 0) | |
1188 { | |
1189 while (i != 0) | |
1190 { | |
1191 tempfle = (*list)->data; | |
1192 if (tempfle->shown) | |
1193 { | |
1194 --*curnum; | |
1195 i--; | |
1196 } | |
1197 *list = (*list)->prev; | |
1198 } | |
1199 } | |
1200 | |
1201 tempfle = (*list)->data; | |
1202 while ((*list)->next && !tempfle->shown) | |
1203 { | |
1204 *list = (*list)->next; | |
1205 tempfle = (*list)->data; | |
1206 } | |
1207 return (selection->next); | |
1208 } | |
1209 | |
1210 | |
227 | 1211 char * |
245 | 1212 gftp_build_path (const char *first_element, ...) |
227 | 1213 { |
1214 const char *element; | |
1215 size_t len, retlen; | |
1216 int add_separator; | |
1217 va_list args; | |
1218 char *ret; | |
1219 | |
245 | 1220 g_return_val_if_fail (first_element != NULL, NULL); |
227 | 1221 |
247 | 1222 ret = g_strdup (first_element); |
1223 retlen = strlen (ret); | |
227 | 1224 |
1225 va_start (args, first_element); | |
247 | 1226 for (element = va_arg (args, char *); |
227 | 1227 element != NULL; |
1228 element = va_arg (args, char *)) | |
1229 { | |
1230 len = strlen (element); | |
1231 | |
245 | 1232 if (len > 0 && element[len - 1] == '/') |
227 | 1233 add_separator = 0; |
1234 else | |
1235 { | |
1236 add_separator = 1; | |
1237 len++; | |
1238 } | |
1239 | |
1240 retlen += len; | |
1241 ret = g_realloc (ret, retlen + 1); | |
1242 | |
1243 if (add_separator) | |
245 | 1244 strncat (ret, "/", retlen); |
1245 | |
1246 strncat (ret, element, retlen); | |
227 | 1247 } |
1248 | |
1249 return (ret); | |
1250 } | |
1251 | |
244 | 1252 |
1253 off_t | |
1254 gftp_parse_file_size (char *str) | |
1255 { | |
1256 #if defined (_LARGEFILE_SOURCE) | |
1257 return (strtoll (str, NULL, 10)); | |
1258 #else | |
1259 return (strtol (str, NULL, 10)); | |
1260 #endif | |
1261 } | |
1262 | |
290 | 1263 |
1264 void | |
1265 gftp_locale_init (void) | |
1266 { | |
1267 #ifdef HAVE_GETTEXT | |
1268 | |
1269 setlocale (LC_ALL, ""); | |
1270 textdomain ("gftp"); | |
1271 | |
1272 #if GLIB_MAJOR_VERSION > 1 | |
1273 bind_textdomain_codeset ("gftp", "UTF-8"); | |
1274 #endif | |
1275 | |
1276 textdomain ("gftp"); | |
1277 | |
1278 #endif | |
1279 } | |
1280 |