From fcaada9d60ee8f52bbc8503c06fe061ca9e2fa68 Mon Sep 17 00:00:00 2001 From: Pierre Habouzit Date: Fri, 24 Nov 2006 16:31:33 +0100 Subject: [PATCH] put old m_snsubst into file.c as m_file_fmt. implement m_temp{fd,file} functions to replace mutt_(adv_)mktemp, that work like that: m_tempFOO(dst, dstlen, tmpdir, fmt). it returns either a fd or a FILE* (check it's properly >= 0 or !NULL !!!) and put the chose name in the buffer dst of size dstlen. tmpdir is the directory where to create files. fmp is a file format, where we strip any directory part, then use the remains like that: - if there is a %s specifier, fmt is used as a simple file format specifier, and %s is substituted with a temporary file name. - if there is no %s specifier, fmt is supposed to be a file name we want to take as model, meaning we just want to copy its extension. So if you pass "foo.jpg" as a fmt, the resulting file name will end in .jpg mark mutt_(adv_)?mktemp functions as obsolete, and currently reimplement them with m_temp* functions as a proof of concept. Signed-off-by: Pierre Habouzit --- globals.h | 2 -- lib-lib/file.c | 84 ++++++++++++++++++++++++++++++++++++++++++++++ lib-lib/file.h | 5 +++ lib-lib/str.c | 27 --------------- lib-lib/str.h | 8 ----- lib-mime/rfc1524.c | 2 +- lib-mx/mbox.c | 5 ++- lib-mx/mh.c | 3 ++ muttlib.c | 51 ++++++++++------------------ pattern.c | 2 +- protos.h | 7 ++-- 11 files changed, 118 insertions(+), 78 deletions(-) diff --git a/globals.h b/globals.h index 1eb9b1c..a115c19 100644 --- a/globals.h +++ b/globals.h @@ -200,8 +200,6 @@ unsigned char QuadOptions[(OPT_MAX * 2 + 7) / 8]; extern unsigned char QuadOptions[]; #endif -WHERE unsigned short Counter INITVAL (0); - #ifdef USE_NNTP WHERE short NewsPollTimeout; WHERE short NntpContext; diff --git a/lib-lib/file.c b/lib-lib/file.c index 66a2028..978895a 100644 --- a/lib-lib/file.c +++ b/lib-lib/file.c @@ -439,3 +439,87 @@ ssize_t mutt_quote_filename(char *d, ssize_t l, const char *s) return j; } + +ssize_t m_file_fmt(char *dst, ssize_t n, const char *fmt, const char *src) +{ + ssize_t pos = 0; + const char *p; + int hadfname = 0; + + for (p = strchr(fmt, '%'); p; p = strchr(fmt, '%')) { + if (p[1] == 's') { + pos += m_strncpy(dst + pos, n - pos, fmt, p - fmt); + pos += m_strcpy(dst + pos, n - pos, src); + fmt = p + 2; + hadfname = 1; + } else { + pos += m_strncpy(dst + pos, n - pos, fmt, p + 1 - fmt); + fmt = p + 1 + (p[1] == '%'); + } + } + pos += m_strcpy(dst + pos, n - pos, fmt); + + if (!hadfname) + pos += snprintf(dst + pos, n - pos, " %s", src); + + return pos; +} + +static ssize_t +m_tempftplize(char *dst, ssize_t dlen, const char *fmt, const char *s) +{ + const char *p; + + while ((p = strchr(fmt, '/'))) { + fmt = p + 1; + } + + if (!*fmt) + return m_strcpy(dst, dlen, s); + + for (p = strchr(fmt, '%'); p; p = strchr(p, '%')) { + if (p[1] == 's') + return m_file_fmt(dst, dlen, fmt, s); + + p += 1 + (p[1] == '%'); + } + + p = strrchr(fmt, '.'); + if (p) { + return snprintf(dst, dlen, "%s%s", s, p); + } else { + return snprintf(dst, dlen, "%s.%s", s, fmt); + } +} + +int m_tempfd(char *dst, ssize_t n, const char *dir, const char *fmt) +{ + char raw[_POSIX_PATH_MAX], tpl[_POSIX_PATH_MAX]; + const char *path = fmt ? tpl : raw; + int fd; + + rand_again: + snprintf(raw, sizeof(raw), "%s/madmutt-%04x-%04x-%08x", + dir, (int)getuid(), (int)getpid(), (int)rand()); + + if (fmt) { + m_tempftplize(tpl, sizeof(tpl), fmt, raw); + } + + fd = open(path, O_CREAT | O_EXCL | O_WRONLY | O_NOFOLLOW, 0600); + + if (fd < 0) { + if (errno == EEXIST) + goto rand_again; + return -1; + } + + m_strcpy(dst, n, path); + return fd; +} + +FILE *m_tempfile(char *dst, ssize_t n, const char *dir, const char *fmt) +{ + int fd = m_tempfd(dst, n, dir, fmt); + return fd < 0 ? NULL : fdopen(fd, "w+"); +} diff --git a/lib-lib/file.h b/lib-lib/file.h index c73f78e..91a2d2a 100644 --- a/lib-lib/file.h +++ b/lib-lib/file.h @@ -65,4 +65,9 @@ char *mutt_concat_path(char *, ssize_t, const char *, const char *); void mutt_sanitize_filename(char *, short); ssize_t mutt_quote_filename(char *, ssize_t, const char *); +/* replace any %s with src, or appends " $src" */ +ssize_t m_file_fmt(char *dst, ssize_t n, const char *fmt, const char *src); +int m_tempfd(char *dst, ssize_t n, const char *dir, const char *fmt); +FILE *m_tempfile(char *dst, ssize_t n, const char *dir, const char *fmt); + #endif /* MUTT_LIB_LIB_FILE_H */ diff --git a/lib-lib/str.c b/lib-lib/str.c index 6537746..7b57305 100644 --- a/lib-lib/str.c +++ b/lib-lib/str.c @@ -178,30 +178,3 @@ int ascii_strncasecmp (const char *a, const char *b, ssize_t n) return 0; } - -ssize_t m_snsubst(char *dst, ssize_t n, const char *fmt, const char *src) -{ - ssize_t pos = 0; - const char *p; - - p = strchr(fmt, '%'); - if (!p) - return snprintf(dst, n, "%s %s", fmt, src); - - for (;;) { - if (p[1] == 's') { - pos += m_strncpy(dst + pos, n - pos, fmt, p - fmt); - pos += m_strcpy(dst + pos, n - pos, src); - fmt = p + 2; - } else { - pos += m_strncpy(dst + pos, n - pos, fmt, p + 1 - fmt); - fmt = p + 1; - if (p[1] == '%') - p++; - } - - p = strchr(fmt, '%'); - if (!p) - return pos + m_strcpy(dst + pos, n - pos, fmt); - } -} diff --git a/lib-lib/str.h b/lib-lib/str.h index d62dc0a..a5791c3 100644 --- a/lib-lib/str.h +++ b/lib-lib/str.h @@ -181,12 +181,4 @@ m_stristr(const char *haystack, const char *needle) { return m_stristrn(haystack, needle, m_strlen(needle)); } - -/****************************************************************************/ -/* misc functions */ -/****************************************************************************/ - -/* replace any %s with src, or appends " $src" */ -ssize_t m_snsubst(char *dst, ssize_t n, const char *fmt, const char *src); - #endif /* MUTT_LIB_LIB_STR_H */ diff --git a/lib-mime/rfc1524.c b/lib-mime/rfc1524.c index 576f212..08090e0 100644 --- a/lib-mime/rfc1524.c +++ b/lib-mime/rfc1524.c @@ -437,7 +437,7 @@ int rfc1524_expand_filename (char *nametemplate, m_strcpy(newfile, nflen, oldfile); } else if (!oldfile) { - m_snsubst(newfile, nflen, nametemplate, "mutt"); + m_file_fmt(newfile, nflen, nametemplate, "mutt"); } else { /* oldfile && nametemplate */ diff --git a/lib-mx/mbox.c b/lib-mx/mbox.c index 79658fa..03c8d27 100644 --- a/lib-mx/mbox.c +++ b/lib-mx/mbox.c @@ -727,9 +727,8 @@ static int mbox_sync_mailbox (CONTEXT * ctx, int unused __attribute__ ((unused)) char savefile[_POSIX_PATH_MAX]; - snprintf (savefile, sizeof (savefile), "%s/mutt.%s-%s-%u", - NONULL (Tempdir), NONULL (Username), NONULL (Hostname), - (unsigned int) getpid ()); + snprintf(savefile, sizeof (savefile), "%s/mutt.%s-%u", + NONULL(Tempdir), NONULL(Username), (unsigned int)getpid()); rename (tempfile, savefile); mutt_unblock_signals (); mx_fastclose_mailbox (ctx); diff --git a/lib-mx/mh.c b/lib-mx/mh.c index bfaaab2..2d79be8 100644 --- a/lib-mx/mh.c +++ b/lib-mx/mh.c @@ -171,6 +171,7 @@ int mh_buffy (const char *path) static int mh_mkstemp (CONTEXT * dest, FILE ** fp, char **tgt) { + static int Counter = 0; int fd; char path[_POSIX_PATH_MAX]; @@ -905,6 +906,7 @@ static void maildir_flags (char *dest, ssize_t destlen, HEADER * hdr) static int maildir_open_new_message (MESSAGE * msg, CONTEXT * dest, HEADER * hdr) { + static int Counter = 0; int fd; char path[_POSIX_PATH_MAX]; char suffix[16]; @@ -979,6 +981,7 @@ static int maildir_open_new_message (MESSAGE * msg, CONTEXT * dest, HEADER * hdr static int maildir_commit_message (MESSAGE * msg, CONTEXT * ctx, HEADER * hdr) { + static int Counter = 0; char subdir[4]; char suffix[16]; char path[_POSIX_PATH_MAX]; diff --git a/muttlib.c b/muttlib.c index 4b13526..185a878 100644 --- a/muttlib.c +++ b/muttlib.c @@ -40,34 +40,15 @@ */ void mutt_adv_mktemp (const char* dir, char *s, ssize_t l) { - char buf[_POSIX_PATH_MAX]; - char tmp[_POSIX_PATH_MAX]; - char *period; - ssize_t sl; - struct stat sb; - - m_strcpy(buf, sizeof(buf), m_strisempty(dir) ? NONULL(Tempdir) : dir); - mutt_expand_path (buf, sizeof (buf)); - if (s[0] == '\0') { - snprintf (s, l, "%s/muttXXXXXX", buf); - mktemp (s); - } - else { - m_strcpy(tmp, sizeof(tmp), s); - mutt_sanitize_filename (tmp, 1); - snprintf (s, l, "%s/%s", buf, tmp); - if (lstat (s, &sb) == -1 && errno == ENOENT) - return; - if ((period = strrchr (tmp, '.')) != NULL) - *period = 0; - snprintf (s, l, "%s/%s.XXXXXX", buf, tmp); - mktemp (s); - if (period != NULL) { - *period = '.'; - sl = m_strlen(s); - m_strcpy(s + sl, l - sl, period); + int fd; + + fd = m_tempfd(s, l, m_strisempty(dir) ? NONULL(Tempdir) : dir, s); + if (fd < 0) { + *s = '\0'; + } else { + close(fd); + unlink(s); } - } } /* returns true if the header contained in "s" is in list "t" */ @@ -190,13 +171,15 @@ ssize_t _mutt_expand_path(char *s, ssize_t slen, int rx) return m_strcpy(s, slen, tmp); } -void mutt_mktemp (char *s) +void mutt_mktemp(char *s) { - - snprintf (s, _POSIX_PATH_MAX, "%s/madmutt-%s-%d-%d-%d-%x%x", NONULL (Tempdir), - NONULL (Hostname), (int) getuid (), (int) getpid (), Counter++, - (unsigned int) rand(), (unsigned int) rand()); - unlink (s); + int fd = m_tempfd(s, _POSIX_PATH_MAX, NONULL(Tempdir), NULL); + if (fd < 0) { + *s = '\0'; + } else { + close(fd); + unlink(s); + } } /* collapse the pathname using ~ or = when possible */ @@ -255,7 +238,7 @@ mutt_expand_file_fmt(char *dst, ssize_t n, const char *fmt, const char *src) { char tmp[LONG_STRING]; mutt_quote_filename(tmp, sizeof(tmp), src); - m_snsubst(dst, n, fmt, tmp); + m_file_fmt(dst, n, fmt, tmp); } /* return 0 on success, -1 on abort, 1 on error */ diff --git a/pattern.c b/pattern.c index 40600b6..3233a92 100644 --- a/pattern.c +++ b/pattern.c @@ -1141,7 +1141,7 @@ void mutt_check_simple (char *s, ssize_t len, const char *simple) m_strcpy(s, len, "~U"); else { quote_simple (tmp, sizeof (tmp), s); - m_snsubst(s, len, simple, tmp); + m_file_fmt(s, len, simple, tmp); } } } diff --git a/protos.h b/protos.h index 5b5395d..570166c 100644 --- a/protos.h +++ b/protos.h @@ -7,6 +7,11 @@ * please see the file GPL in the top level source directory. */ + +/* use the m_temp{fd,file} functions instead */ +void mutt_adv_mktemp (const char*, char*, ssize_t) __attribute__((deprecated)); +void mutt_mktemp (char *) __attribute__((deprecated)); + #define MoreArgs(p) (*p->dptr && *p->dptr != ';' && *p->dptr != '#') typedef const char *format_t (char *, ssize_t, char, const char *, @@ -55,7 +60,6 @@ const char *mutt_fqdn (short); void mutt_account_hook (const char *url); void mutt_add_to_reference_headers (ENVELOPE * env, ENVELOPE * curenv, string_list_t *** pp, string_list_t *** qq); -void mutt_adv_mktemp (const char*, char*, ssize_t); int mutt_bounce_message (FILE * fp, HEADER *, address_t *); void mutt_check_rescore (CONTEXT *); void mutt_default_save (char *, ssize_t, const HEADER *); @@ -79,7 +83,6 @@ void mutt_make_misc_reply_headers (ENVELOPE * env, CONTEXT * ctx, void mutt_make_post_indent (CONTEXT * ctx, HEADER * cur, FILE * out); void mutt_message_to_7bit (BODY *, FILE *); -void mutt_mktemp (char *); void mutt_prepare_envelope (ENVELOPE *, int); void mutt_unprepare_envelope (ENVELOPE *); void mutt_pretty_mailbox (char *); -- 2.20.1