extern unsigned char QuadOptions[];
#endif
-WHERE unsigned short Counter INITVAL (0);
-
#ifdef USE_NNTP
WHERE short NewsPollTimeout;
WHERE short NntpContext;
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+");
+}
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 */
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);
- }
-}
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 */
m_strcpy(newfile, nflen, oldfile);
}
else if (!oldfile) {
- m_snsubst(newfile, nflen, nametemplate, "mutt");
+ m_file_fmt(newfile, nflen, nametemplate, "mutt");
} else { /* oldfile && nametemplate */
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);
static int mh_mkstemp (CONTEXT * dest, FILE ** fp, char **tgt)
{
+ static int Counter = 0;
int fd;
char path[_POSIX_PATH_MAX];
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];
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];
*/
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" */
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 */
{
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 */
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);
}
}
}
* 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 *,
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 *);
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 *);