]>
git.sthu.org Git - pgp-tools.git/blob - keyanalyze/pgpring/lib.c
2 * Copyright (C) 1996-2000 Michael R. Elkins <me@cs.hmc.edu>
3 * Copyright (C) 1999-2000 Thomas Roessler <roessler@guug.de>
5 * This program is free software; you can redistribute it
6 * and/or modify it under the terms of the GNU General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later
11 * This program is distributed in the hope that it will be
12 * useful, but WITHOUT ANY WARRANTY; without even the implied
13 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14 * PURPOSE. See the GNU General Public License for more
17 * You should have received a copy of the GNU General Public
18 * License along with this program; if not, write to the Free
19 * Software Foundation, Inc., 59 Temple Place - Suite 330,
20 * Boston, MA 02111, USA.
24 * This file used to contain some more functions, namely those
25 * which are now in muttlib.c. They have been removed, so we have
26 * some of our "standard" functions in external programs, too.
41 void mutt_nocurses_error (const char *fmt
, ...)
46 vfprintf (stderr
, fmt
, ap
);
51 void *safe_calloc (size_t nmemb
, size_t size
)
57 if (!(p
= calloc (nmemb
, size
)))
59 mutt_error
_("Out of memory!");
66 void *safe_malloc (size_t siz
)
72 if ((p
= (void *) malloc (siz
)) == 0) /* __MEM_CHECKED__ */
74 mutt_error
_("Out of memory!");
81 void safe_realloc (void *p2
, size_t siz
)
83 void **p
= (void **)p2
;
90 free (*p
); /* __MEM_CHECKED__ */
97 r
= (void *) realloc (*p
, siz
); /* __MEM_CHECKED__ */
100 /* realloc(NULL, nbytes) doesn't seem to work under SunOS 4.1.x --- __MEM_CHECKED__ */
101 r
= (void *) malloc (siz
); /* __MEM_CHECKED__ */
106 mutt_error
_("Out of memory!");
114 void safe_free (void *p2
)
116 void **p
= (void **)p2
;
119 free (*p
); /* __MEM_CHECKED__ */
124 int safe_fclose (FILE **f
)
135 char *safe_strdup (const char *s
)
143 p
= (char *)safe_malloc (l
);
148 void mutt_str_replace (char **p
, const char *s
)
151 *p
= safe_strdup (s
);
154 void mutt_str_adjust (char **p
)
156 if (!p
|| !*p
) return;
157 safe_realloc ((void **) p
, strlen (*p
) + 1);
160 /* convert all characters in the string to lowercase */
161 char *mutt_strlower (char *s
)
174 void mutt_unlink (const char *s
)
180 if (stat (s
, &sb
) == 0)
182 if ((f
= fopen (s
, "r+")))
185 memset (buf
, 0, sizeof (buf
));
186 while (sb
.st_size
> 0)
188 fwrite (buf
, 1, sizeof (buf
), f
);
189 sb
.st_size
-= sizeof (buf
);
196 int mutt_copy_bytes (FILE *in
, FILE *out
, size_t size
)
203 chunk
= (size
> sizeof (buf
)) ? sizeof (buf
) : size
;
204 if ((chunk
= fread (buf
, 1, chunk
, in
)) < 1)
206 if (fwrite (buf
, 1, chunk
, out
) != chunk
)
208 /* dprint (1, (debugfile, "mutt_copy_bytes(): fwrite() returned short byte count\n")); */
217 int mutt_copy_stream (FILE *fin
, FILE *fout
)
220 char buf
[LONG_STRING
];
222 while ((l
= fread (buf
, 1, sizeof (buf
), fin
)) > 0)
224 if (fwrite (buf
, 1, l
, fout
) != l
)
232 compare_stat (struct stat
*osb
, struct stat
*nsb
)
234 if (osb
->st_dev
!= nsb
->st_dev
|| osb
->st_ino
!= nsb
->st_ino
||
235 osb
->st_rdev
!= nsb
->st_rdev
)
243 int safe_symlink(const char *oldpath
, const char *newpath
)
245 struct stat osb
, nsb
;
247 if(!oldpath
|| !newpath
)
250 if(unlink(newpath
) == -1 && errno
!= ENOENT
)
253 if (oldpath
[0] == '/')
255 if (symlink (oldpath
, newpath
) == -1)
260 char abs_oldpath
[_POSIX_PATH_MAX
];
262 if ((getcwd (abs_oldpath
, sizeof abs_oldpath
) == NULL
) ||
263 (strlen (abs_oldpath
) + 1 + strlen (oldpath
) + 1 > sizeof abs_oldpath
))
266 strcat (abs_oldpath
, "/"); /* __STRCAT_CHECKED__ */
267 strcat (abs_oldpath
, oldpath
); /* __STRCAT_CHECKED__ */
268 if (symlink (abs_oldpath
, newpath
) == -1)
272 if(stat(oldpath
, &osb
) == -1 || stat(newpath
, &nsb
) == -1
273 || compare_stat(&osb
, &nsb
) == -1)
283 * This function is supposed to do nfs-safe renaming of files.
285 * Warning: We don't check whether src and target are equal.
288 int safe_rename (const char *src
, const char *target
)
290 struct stat ssb
, tsb
;
295 if (link (src
, target
) != 0)
299 * Coda does not allow cross-directory links, but tells
300 * us it's a cross-filesystem linking attempt.
302 * However, the Coda rename call is allegedly safe to use.
304 * With other file systems, rename should just fail when
305 * the files reside on different file systems, so it's safe
311 return rename (src
, target
);
317 * Stat both links and check if they are equal.
320 if (stat (src
, &ssb
) == -1)
325 if (stat (target
, &tsb
) == -1)
331 * pretend that the link failed because the target file
335 if (compare_stat (&ssb
, &tsb
) == -1)
342 * Unlink the original link. Should we really ignore the return
351 int safe_open (const char *path
, int flags
)
353 struct stat osb
, nsb
;
356 if ((fd
= open (path
, flags
, 0600)) < 0)
359 /* make sure the file is not symlink */
360 if (lstat (path
, &osb
) < 0 || fstat (fd
, &nsb
) < 0 ||
361 compare_stat(&osb
, &nsb
) == -1)
363 /* dprint (1, (debugfile, "safe_open(): %s is a symlink!\n", path)); */
371 /* when opening files for writing, make sure the file doesn't already exist
372 * to avoid race conditions.
374 FILE *safe_fopen (const char *path
, const char *mode
)
379 int flags
= O_CREAT
| O_EXCL
;
390 if ((fd
= safe_open (path
, flags
)) < 0)
393 return (fdopen (fd
, mode
));
396 return (fopen (path
, mode
));
399 static char safe_chars
[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+@{}._-:%/";
401 void mutt_sanitize_filename (char *f
, short slash
)
407 if ((slash
&& *f
== '/') || !strchr (safe_chars
, *f
))
412 /* these characters must be escaped in regular expressions */
414 static char rx_special_chars
[] = "^.[$()|*+?{\\";
416 int mutt_rx_sanitize_string (char *dest
, size_t destlen
, const char *src
)
418 while (*src
&& --destlen
> 2)
420 if (strchr (rx_special_chars
, *src
))
436 /* Read a line from ``fp'' into the dynamically allocated ``s'',
437 * increasing ``s'' if necessary. The ending "\n" or "\r\n" is removed.
438 * If a line ends with "\", this char and the linefeed is removed,
439 * and the next line is read too.
441 char *mutt_read_line (char *s
, size_t *size
, FILE *fp
, int *line
)
448 s
= safe_malloc (STRING
);
454 if (fgets (s
+ offset
, *size
- offset
, fp
) == NULL
)
459 if ((ch
= strchr (s
+ offset
, '\n')) != NULL
)
463 if (ch
> s
&& *(ch
- 1) == '\r')
465 if (ch
== s
|| *(ch
- 1) != '\\')
472 c
= getc (fp
); /* This is kind of a hack. We want to know if the
473 char at the current point in the input stream is EOF.
474 feof() will only tell us if we've already hit EOF, not
475 if the next character is EOF. So, we need to read in
476 the next character and manually check if it is EOF. */
479 /* The last line of fp isn't \n terminated */
485 ungetc (c
, fp
); /* undo our dammage */
486 /* There wasn't room for the line -- increase ``s'' */
487 offset
= *size
- 1; /* overwrite the terminating 0 */
489 safe_realloc (&s
, *size
);
496 mutt_substrcpy (char *dest
, const char *beg
, const char *end
, size_t destlen
)
501 if (len
> destlen
- 1)
503 memcpy (dest
, beg
, len
);
508 char *mutt_substrdup (const char *begin
, const char *end
)
516 len
= strlen (begin
);
518 p
= safe_malloc (len
+ 1);
519 memcpy (p
, begin
, len
);
524 /* prepare a file name to survive the shell's quoting rules.
525 * From the Unix programming FAQ by way of Liviu.
528 size_t mutt_quote_filename (char *d
, size_t l
, const char *f
)
538 /* leave some space for the trailing characters. */
543 for(i
= 0; j
< l
&& f
[i
]; i
++)
545 if(f
[i
] == '\'' || f
[i
] == '`')
562 /* NULL-pointer aware string comparison functions */
564 int mutt_strcmp(const char *a
, const char *b
)
566 return strcmp(NONULL(a
), NONULL(b
));
569 int mutt_strcasecmp(const char *a
, const char *b
)
571 return strcasecmp(NONULL(a
), NONULL(b
));
574 int mutt_strncmp(const char *a
, const char *b
, size_t l
)
576 return strncmp(NONULL(a
), NONULL(b
), l
);
579 int mutt_strncasecmp(const char *a
, const char *b
, size_t l
)
581 return strncasecmp(NONULL(a
), NONULL(b
), l
);
584 size_t mutt_strlen(const char *a
)
586 return a
? strlen (a
) : 0;
589 const char *mutt_stristr (const char *haystack
, const char *needle
)
598 while (*(p
= haystack
))
600 for (q
= needle
; *p
&& *q
&& tolower (*p
) == tolower (*q
); p
++, q
++)
609 char *mutt_skip_whitespace (char *p
)
615 void mutt_remove_trailing_ws (char *s
)
619 for (p
= s
+ mutt_strlen (s
) - 1 ; p
>= s
&& ISSPACE (*p
) ; p
--)