X-Git-Url: http://git.madism.org/?a=blobdiff_plain;f=lib-lib%2Ffile.c;h=978895af0734b9c6f356b1d13ca3c12b6b40f1c0;hb=9faa4e03a4cf3204d1b4a8d622d33dd9c4596ca7;hp=66a2028b90986f49566a8675566009ea6a00ce0d;hpb=1ee89902de184a640c171ae3285bff6882a791bd;p=apps%2Fmadmutt.git 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+"); +}