X-Git-Url: https://git.llucax.com/software/mutt-debian.git/blobdiff_plain/14c29200cb58d3c4a0830265f2433849781858d0..ee66c1452ad6f627879c9ec8156342f5e90c2253:/lib.c diff --git a/lib.c b/lib.c index 4dfd5db..17cc516 100644 --- a/lib.c +++ b/lib.c @@ -1,6 +1,6 @@ /* - * Copyright (C) 1996-2000 Michael R. Elkins - * Copyright (C) 1999-2000 Thomas Roessler + * Copyright (C) 1996-2000,2007 Michael R. Elkins + * Copyright (C) 1999-2004,2006-7 Thomas Roessler * * This program is free software; you can redistribute it * and/or modify it under the terms of the GNU General Public @@ -41,6 +41,8 @@ #include #include #include +#include +#include #ifdef HAVE_SYSEXITS_H #include @@ -209,6 +211,24 @@ int safe_fclose (FILE **f) return r; } +int safe_fsync_close (FILE **f) +{ + int r = 0; + + if (*f) + { + if (fflush (*f) || fsync (fileno (*f))) + { + r = -1; + safe_fclose (f); + } + else + r = safe_fclose (f); + } + + return r; +} + char *safe_strdup (const char *s) { char *p; @@ -324,7 +344,7 @@ void mutt_unlink (const char *s) fwrite (buf, 1, MIN (sizeof (buf), sb.st_size), f); sb.st_size -= MIN (sizeof (buf), sb.st_size); } - fclose (f); + safe_fclose (&f); } } } @@ -522,7 +542,7 @@ int safe_rename (const char *src, const char *target) /* Create a temporary directory next to a file name */ -int mutt_mkwrapdir (const char *path, char *newfile, size_t nflen, +static int mutt_mkwrapdir (const char *path, char *newfile, size_t nflen, char *newdir, size_t ndlen) { const char *basename; @@ -557,7 +577,47 @@ int mutt_mkwrapdir (const char *path, char *newfile, size_t nflen, return 0; } -int mutt_put_file_in_place (const char *path, const char *safe_file, const char *safe_dir) +/* remove a directory and everything under it */ +int mutt_rmtree (const char* path) +{ + DIR* dirp; + struct dirent* de; + char cur[_POSIX_PATH_MAX]; + struct stat statbuf; + int rc = 0; + + if (!(dirp = opendir (path))) + { + dprint (1, (debugfile, "mutt_rmtree: error opening directory %s\n", path)); + return -1; + } + while ((de = readdir (dirp))) + { + if (!strcmp (".", de->d_name) || !strcmp ("..", de->d_name)) + continue; + + snprintf (cur, sizeof (cur), "%s/%s", path, de->d_name); + /* XXX make nonrecursive version */ + + if (stat(cur, &statbuf) == -1) + { + rc = 1; + continue; + } + + if (S_ISDIR (statbuf.st_mode)) + rc |= mutt_rmtree (cur); + else + rc |= unlink (cur); + } + closedir (dirp); + + rc |= rmdir (path); + + return rc; +} + +static int mutt_put_file_in_place (const char *path, const char *safe_file, const char *safe_dir) { int rv; @@ -678,7 +738,7 @@ int mutt_rx_sanitize_string (char *dest, size_t destlen, const char *src) * If a line ends with "\", this char and the linefeed is removed, * and the next line is read too. */ -char *mutt_read_line (char *s, size_t *size, FILE *fp, int *line) +char *mutt_read_line (char *s, size_t *size, FILE *fp, int *line, int flags) { size_t offset = 0; char *ch; @@ -698,11 +758,14 @@ char *mutt_read_line (char *s, size_t *size, FILE *fp, int *line) } if ((ch = strchr (s + offset, '\n')) != NULL) { - (*line)++; + if (line) + (*line)++; + if (flags & M_EOL) + return s; *ch = 0; if (ch > s && *(ch - 1) == '\r') *--ch = 0; - if (ch == s || *(ch - 1) != '\\') + if (!(flags & M_CONT) || ch == s || *(ch - 1) != '\\') return s; offset = ch - s - 1; } @@ -717,7 +780,8 @@ char *mutt_read_line (char *s, size_t *size, FILE *fp, int *line) if (c == EOF) { /* The last line of fp isn't \n terminated */ - (*line)++; + if (line) + (*line)++; return s; } else @@ -944,3 +1008,77 @@ mutt_strsysexit(int e) return sysexits_h[i].str; } + +void mutt_debug (FILE *fp, const char *fmt, ...) +{ + va_list ap; + time_t now = time (NULL); + static char buf[23] = ""; + static time_t last = 0; + + if (now > last) + { + strftime (buf, sizeof (buf), "%Y-%m-%d %H:%M:%S", localtime (&now)); + last = now; + } + fprintf (fp, "[%s] ", buf); + va_start (ap, fmt); + vfprintf (fp, fmt, ap); + va_end (ap); +} + +int mutt_atos (const char *str, short *dst) +{ + int rc; + long res; + short tmp; + short *t = dst ? dst : &tmp; + + *t = 0; + + if ((rc = mutt_atol (str, &res)) < 0) + return rc; + if ((short) res != res) + return -2; + + *t = (short) res; + return 0; +} + +int mutt_atoi (const char *str, int *dst) +{ + int rc; + long res; + int tmp; + int *t = dst ? dst : &tmp; + + *t = 0; + + if ((rc = mutt_atol (str, &res)) < 0) + return rc; + if ((int) res != res) + return -2; + + *t = (int) res; + return 0; +} + +int mutt_atol (const char *str, long *dst) +{ + long r; + long *res = dst ? dst : &r; + char *e = NULL; + + /* no input: 0 */ + if (!str || !*str) + { + *res = 0; + return 0; + } + + *res = strtol (str, &e, 10); + if ((*res == LONG_MAX && errno == ERANGE) || + (e && *e != '\0')) + return -1; + return 0; +}