I'm such a fool
[apps/madmutt.git] / lib-lib / file.c
index 66a2028..de3c75b 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_RDWR | 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+");
+}