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