put old m_snsubst into file.c as m_file_fmt.
authorPierre Habouzit <madcoder@debian.org>
Fri, 24 Nov 2006 15:31:33 +0000 (16:31 +0100)
committerPierre Habouzit <madcoder@debian.org>
Fri, 24 Nov 2006 15:31:33 +0000 (16:31 +0100)
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 <madcoder@debian.org>
globals.h
lib-lib/file.c
lib-lib/file.h
lib-lib/str.c
lib-lib/str.h
lib-mime/rfc1524.c
lib-mx/mbox.c
lib-mx/mh.c
muttlib.c
pattern.c
protos.h

index 1eb9b1c..a115c19 100644 (file)
--- 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;
index 66a2028..978895a 100644 (file)
@@ -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+");
+}
index c73f78e..91a2d2a 100644 (file)
@@ -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 */
index 6537746..7b57305 100644 (file)
@@ -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);
-    }
-}
index d62dc0a..a5791c3 100644 (file)
@@ -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 */
index 576f212..08090e0 100644 (file)
@@ -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 */
 
 
index 79658fa..03c8d27 100644 (file)
@@ -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);
index bfaaab2..2d79be8 100644 (file)
@@ -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];
index 4b13526..185a878 100644 (file)
--- a/muttlib.c
+++ b/muttlib.c
  */
 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 */
index 40600b6..3233a92 100644 (file)
--- 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);
     }
   }
 }
index 5b5395d..570166c 100644 (file)
--- 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 *);