Commit 8acde412 8acde412feee7235b342196182c69d0ed25fe1fc by Sergey Poznyakoff

Rewrite temporary file handling.

* include/mailutils/util.h (mu_make_file_name_suf): New proto.
(mu_make_file_name): Replace with a macro.
(MU_TEMPFILE_TMPDIR,MU_TEMPFILE_SUFFIX)
(MU_TEMPFILE_MKDIR): New flags.
(mu_tempfile_hints): New struct.
(mu_tempfile): Change signature.
* libmailutils/base/tempfile.c (mu_create_temp_file): New function.
(mu_tempfile): Rewrite from scratch.  Change signature.  All callers
changed.
* libmailutils/string/mkfilename.c (mu_make_file_name): Remove.
(mu_make_file_name_suf): New function.

* libmailutils/stream/streamcpy.c (mu_stream_copy): Don't return EIO
on EOF.
* libmailutils/stream/file_stream.c (mu_fd_stream_create): If
MU_STREAM_SEEK is set, position fd to 0.

* guimb/collect.c: Update calls to mu_tempfile.
* lib/mailcap.c: Likewise.
* libmailutils/base/amd.c (_amd_tempfile): Rewrite using mu_tempfile.

* libmailutils/tests/tempfile.c: New file.
* libmailutils/tests/Makefile.am (noinst_PROGRAMS): Add tempfile.
1 parent 80bb8b2f
...@@ -55,8 +55,7 @@ collect_open_mailbox_file () ...@@ -55,8 +55,7 @@ collect_open_mailbox_file ()
55 int fd; 55 int fd;
56 56
57 /* Create input mailbox */ 57 /* Create input mailbox */
58 fd = mu_tempfile (NULL, &temp_filename); 58 if (mu_tempfile (NULL, 0, &fd, &temp_filename))
59 if (fd == -1)
60 exit (1); 59 exit (1);
61 60
62 temp_file = fdopen (fd, "w"); 61 temp_file = fdopen (fd, "w");
......
...@@ -82,9 +82,27 @@ char *mu_tilde_expansion (const char *ref, const char *delim, ...@@ -82,9 +82,27 @@ char *mu_tilde_expansion (const char *ref, const char *delim,
82 int mu_readlink (const char *name, char **pbuf, size_t *psize, size_t *plen); 82 int mu_readlink (const char *name, char **pbuf, size_t *psize, size_t *plen);
83 int mu_unroll_symlink (const char *name, char **pout); 83 int mu_unroll_symlink (const char *name, char **pout);
84 char *mu_getcwd (void); 84 char *mu_getcwd (void);
85 int mu_tempfile (const char *tmpdir, char **namep); 85 char *mu_make_file_name_suf (const char *dir, const char *file,
86 const char *suf);
87 #define mu_make_file_name(dir, file) mu_make_file_name_suf (dir, file, NULL)
88
89 /* ------------------------ */
90 /* Temporary file creation. */
91 /* ------------------------ */
92 #define MU_TEMPFILE_TMPDIR 0x01 /* tmpdir is set */
93 #define MU_TEMPFILE_SUFFIX 0x02 /* suffix is set */
94 #define MU_TEMPFILE_MKDIR 0x04 /* create a directory, not a file */
95
96 struct mu_tempfile_hints
97 {
98 const char *tmpdir;
99 const char *suffix;
100 };
101
102 /*int mu_tempfile (const char *tmpdir, char **namep);*/
103 int mu_tempfile (struct mu_tempfile_hints *hints, int flags,
104 int *pfd, char **namep);
86 char *mu_tempname (const char *tmpdir); 105 char *mu_tempname (const char *tmpdir);
87 char *mu_make_file_name (const char *dir, const char *file);
88 106
89 /* ----------------------- */ 107 /* ----------------------- */
90 /* Current user email. */ 108 /* Current user email. */
......
...@@ -197,6 +197,7 @@ mime_context_get_content_type_value (struct mime_context *ctx, ...@@ -197,6 +197,7 @@ mime_context_get_content_type_value (struct mime_context *ctx,
197 return rc; 197 return rc;
198 } 198 }
199 199
200 /* FIXME: Rewrite via mu_stream_copy */
200 static void 201 static void
201 mime_context_write_input (struct mime_context *ctx, int fd) 202 mime_context_write_input (struct mime_context *ctx, int fd)
202 { 203 {
...@@ -219,8 +220,8 @@ mime_context_get_temp_file (struct mime_context *ctx, char **ptr) ...@@ -219,8 +220,8 @@ mime_context_get_temp_file (struct mime_context *ctx, char **ptr)
219 { 220 {
220 if (!ctx->temp_file) 221 if (!ctx->temp_file)
221 { 222 {
222 int fd = mu_tempfile (NULL, &ctx->temp_file); 223 int fd;
223 if (fd == -1) 224 if (mu_tempfile (NULL, 0, &fd, &ctx->temp_file))
224 return -1; 225 return -1;
225 mime_context_write_input (ctx, fd); 226 mime_context_write_input (ctx, fd);
226 close (fd); 227 close (fd);
......
...@@ -597,13 +597,18 @@ amd_quick_get_message (mu_mailbox_t mailbox, mu_message_qid_t qid, ...@@ -597,13 +597,18 @@ amd_quick_get_message (mu_mailbox_t mailbox, mu_message_qid_t qid,
597 return ENOSYS; 597 return ENOSYS;
598 } 598 }
599 599
600 static FILE * 600 static int
601 _amd_tempfile(struct _amd_data *amd, char **namep) 601 _amd_tempfile (struct _amd_data *amd, FILE **pfile, char **namep)
602 { 602 {
603 int fd = mu_tempfile (amd->name, namep); 603 struct mu_tempfile_hints hints;
604 if (fd == -1) 604 int fd, rc;
605 return NULL; 605
606 return fdopen (fd, "w"); 606 hints.tmpdir = amd->name;
607 rc = mu_tempfile (&hints, MU_TEMPFILE_TMPDIR, &fd, namep);
608 if (rc == 0)
609 if ((*pfile = fdopen (fd, "w")) == NULL)
610 rc = errno;
611 return rc;
607 } 612 }
608 613
609 static int 614 static int
...@@ -658,11 +663,11 @@ _amd_message_save (struct _amd_data *amd, struct _amd_message *mhm, ...@@ -658,11 +663,11 @@ _amd_message_save (struct _amd_data *amd, struct _amd_message *mhm,
658 return status; 663 return status;
659 } 664 }
660 665
661 fp = _amd_tempfile (mhm->amd, &name); 666 status = _amd_tempfile (mhm->amd, &fp, &name);
662 if (!fp) 667 if (status)
663 { 668 {
664 free (msg_name); 669 free (msg_name);
665 return errno; 670 return status;
666 } 671 }
667 672
668 /* Try to allocate large buffer */ 673 /* Try to allocate large buffer */
......
...@@ -22,6 +22,8 @@ ...@@ -22,6 +22,8 @@
22 22
23 #include <sys/types.h> 23 #include <sys/types.h>
24 #include <sys/stat.h> 24 #include <sys/stat.h>
25 #include <sys/time.h>
26 #include <fcntl.h>
25 #include <errno.h> 27 #include <errno.h>
26 #include <unistd.h> 28 #include <unistd.h>
27 #include <stdlib.h> 29 #include <stdlib.h>
...@@ -33,62 +35,177 @@ ...@@ -33,62 +35,177 @@
33 #include <mailutils/errno.h> 35 #include <mailutils/errno.h>
34 #include <mailutils/util.h> 36 #include <mailutils/util.h>
35 37
36 /* Create and open a temporary file. Be very careful about it, since we
37 may be running with extra privilege i.e setgid().
38 Returns file descriptor of the open file.
39 If namep is not NULL, the pointer to the malloced file name will
40 be stored there. Otherwise, the file is unlinked right after open,
41 i.e. it will disappear after close(fd). */
42
43 #ifndef P_tmpdir 38 #ifndef P_tmpdir
44 # define P_tmpdir "/tmp" 39 # define P_tmpdir "/tmp"
45 #endif 40 #endif
46 41
42 /* Lower level call.
43
44 Create a temporary file with the name according to the pattern FILENAME.
45 FILENAME must end with any amount of Xs, optionally followed by
46 SUFLEN other characters.
47
48 If ISDIR is not 0, create a directory (privileges 0700), otherwise
49 create a file (privileges 0600).
50
51 On success, return 0. If pfd is not NULL (and ISDIR is 0), open the
52 created file and store the descriptor in *PFD. Return actual file
53 name in FILENAME.
54
55 On error, return error code.
56 */
47 int 57 int
48 mu_tempfile (const char *tmpdir, char **namep) 58 mu_create_temp_file (char *filename, size_t suflen, int *pfd, int isdir)
49 { 59 {
50 char *filename; 60 int rc;
51 int fd; 61 size_t len;
62 char *carrybuf;
63 char *p, *cp, *start, *end;
64 struct stat st;
65 static int first_call;
66 static char randstate[256];
67 static const unsigned char alphabet[] =
68 "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
69
70 if (!first_call)
71 {
72 /* Initialize random number generator */
73 struct timeval tv;
74 gettimeofday (&tv, NULL);
75 initstate (((unsigned long) tv.tv_usec << 16) ^ tv.tv_sec,
76 randstate, sizeof (randstate));
77 first_call = 1;
78 }
79 setstate (randstate);
52 80
53 if (!tmpdir) 81 /* Start with the last filename character before suffix */
54 tmpdir = (getenv ("TMPDIR")) ? getenv ("TMPDIR") : P_tmpdir; 82 end = filename + strlen (filename) - suflen - 1;
55 83 /* Fill X's with random characters */
56 filename = mu_make_file_name (tmpdir, "muXXXXXX"); 84 for (p = end; p >= filename && *p == 'X'; p--)
57 if (!filename) 85 *p = alphabet[random () % (sizeof (alphabet) - 1)];
86 len = end - p;
87 if (len == 0)
88 return EINVAL;
89 start = p + 1;
90
91 carrybuf = malloc (len);
92 if (!carrybuf)
93 return ENOMEM;
94
95 /* Fill in the carry buffer */
96 memcpy (carrybuf, start, len);
97
98 for (;;)
58 { 99 {
59 mu_diag_funcall (MU_DIAG_ERROR, "mu_make_file_name", NULL, ENOMEM); 100 if (isdir)
60 return -1; 101 {
102 if (mkdir (filename, 0700) == 0)
103 {
104 rc = 0;
105 break;
106 }
107 }
108 else if (pfd)
109 {
110 if ((*pfd = open (filename, O_CREAT|O_EXCL|O_RDWR, 0600)) >= 0)
111 {
112 rc = 0;
113 break;
114 }
115 }
116 else if (lstat (filename, &st) && errno == ENOENT)
117 {
118 rc = 0;
119 break;
120 }
121
122 if (errno != EEXIST)
123 {
124 rc = errno;
125 break;
126 }
127
128 for (p = start, cp = carrybuf;; p++, cp++)
129 {
130 char *q;
131
132 if (p == end)
133 /* All permutation exhausted */
134 return EEXIST;
135 q = strchr ((char*)alphabet, *p);
136 if (!q)
137 abort (); /* should not happen */
138 *p = (q[1] == 0) ? alphabet[0] : q[1];
139 if (*p != *cp)
140 break;
141 }
61 } 142 }
143 free (carrybuf);
144 return rc;
145 }
62 146
63 #ifdef HAVE_MKSTEMP 147 /* Create a temporary file according to HINTS.
64 { 148
65 int save_mask = umask (077); 149 If MU_TEMPFILE_MKDIR flag is set, create a directory instead of file.
66 fd = mkstemp (filename); 150
67 umask (save_mask); 151 On success, return 0. If PFD is not NULL (and MU_TEMPFILE_MKDIR flag
68 } 152 is not set), open the file and store its descriptor in *PFD. If
69 #else 153 NAMEP is not NULL, store there a pointer to the allocated file name.
70 if (mktemp (filename)) 154 At least one of PFD and NAMEP must be set, otherwise EINVAL is returned.
71 fd = open (filename, O_CREAT|O_EXCL|O_RDWR, 0600);
72 else
73 fd = -1;
74 #endif
75 155
76 if (fd == -1) 156 On error, returns error code describing the problem.
157
158 If hints is NULL, any flags except MU_TEMPFILE_MKDIR are ignored.
159 Otherwise:
160
161 * If MU_TEMPFILE_TMPDIR is set, hints->tmpdir points to the name of
162 a directory where to create the temporary.
163 * If MU_TEMPFILE_SUFFIX is set, hints->suffix defines a suffix to
164 append to the created file name.
165 */
166 int
167 mu_tempfile (struct mu_tempfile_hints *hints, int flags,
168 int *pfd, char **namep)
169 {
170 char *filename;
171 const char *tmpdir = getenv ("TMPDIR");
172 const char *suf = NULL;
173 int create_dir = 0;
174 int rc;
175 struct stat st;
176
177 if (pfd == NULL && namep == NULL)
178 return EINVAL;
179 if (hints)
77 { 180 {
78 mu_error (_("cannot open temporary file: %s"), mu_strerror (errno)); 181 if (flags & MU_TEMPFILE_TMPDIR)
79 free (filename); 182 tmpdir = hints->tmpdir;
80 return -1; 183 if (flags & MU_TEMPFILE_SUFFIX)
184 suf = hints->suffix;
185 create_dir = flags & MU_TEMPFILE_MKDIR;
81 } 186 }
187
188 if (!tmpdir)
189 tmpdir = P_tmpdir;
190
191 /* First, see if tmpdir exists */
192 if (stat (tmpdir, &st))
193 return errno;
82 194
83 if (namep) 195 /* Create a name template */
84 *namep = filename; 196 filename = mu_make_file_name_suf (tmpdir, "muXXXXXX", suf);
85 else 197 rc = mu_create_temp_file (filename, suf ? strlen (suf) : 0, pfd, create_dir);
198 if (rc == 0)
86 { 199 {
87 unlink (filename); 200 if (namep)
88 free (filename); 201 *namep = filename;
202 else
203 {
204 unlink (filename);
205 free (filename);
206 }
89 } 207 }
90 208 return rc;
91 return fd;
92 } 209 }
93 210
94 /* Create a unique temporary file name in tmpdir. The function 211 /* Create a unique temporary file name in tmpdir. The function
...@@ -100,10 +217,13 @@ mu_tempfile (const char *tmpdir, char **namep) ...@@ -100,10 +217,13 @@ mu_tempfile (const char *tmpdir, char **namep)
100 char * 217 char *
101 mu_tempname (const char *tmpdir) 218 mu_tempname (const char *tmpdir)
102 { 219 {
220 struct mu_tempfile_hints hints;
103 char *filename = NULL; 221 char *filename = NULL;
104 int fd = mu_tempfile (tmpdir, &filename); 222 int fd;
223 hints.tmpdir = tmpdir;
224 if (mu_tempfile (&hints, MU_TEMPFILE_TMPDIR, &fd, &filename))
225 return NULL;
105 close (fd); 226 close (fd);
106 return filename; 227 return filename;
107 } 228 }
108 229
109
......
...@@ -388,9 +388,17 @@ int ...@@ -388,9 +388,17 @@ int
388 mu_fd_stream_create (mu_stream_t *pstream, char *filename, int fd, int flags) 388 mu_fd_stream_create (mu_stream_t *pstream, char *filename, int fd, int flags)
389 { 389 {
390 struct _mu_file_stream *fstr; 390 struct _mu_file_stream *fstr;
391 int rc = _mu_file_stream_create (&fstr, 391 int rc;
392 sizeof (struct _mu_file_stream), 392
393 filename, fd, flags|_MU_STR_OPEN); 393 if (flags & MU_STREAM_SEEK)
394 {
395 if (lseek (fd, 0, SEEK_SET))
396 return errno;
397 }
398
399 rc = _mu_file_stream_create (&fstr,
400 sizeof (struct _mu_file_stream),
401 filename, fd, flags|_MU_STR_OPEN);
394 if (rc == 0) 402 if (rc == 0)
395 { 403 {
396 mu_stream_t stream = (mu_stream_t) fstr; 404 mu_stream_t stream = (mu_stream_t) fstr;
......
...@@ -98,10 +98,7 @@ mu_stream_copy (mu_stream_t dst, mu_stream_t src, mu_off_t size, ...@@ -98,10 +98,7 @@ mu_stream_copy (mu_stream_t dst, mu_stream_t src, mu_off_t size,
98 if (status) 98 if (status)
99 break; 99 break;
100 if (n == 0) 100 if (n == 0)
101 { 101 break;
102 status = EIO;
103 break;
104 }
105 status = mu_stream_write (dst, buf, n, NULL); 102 status = mu_stream_write (dst, buf, n, NULL);
106 if (status) 103 if (status)
107 break; 104 break;
...@@ -120,6 +117,10 @@ mu_stream_copy (mu_stream_t dst, mu_stream_t src, mu_off_t size, ...@@ -120,6 +117,10 @@ mu_stream_copy (mu_stream_t dst, mu_stream_t src, mu_off_t size,
120 117
121 if (pcsz) 118 if (pcsz)
122 *pcsz = total; 119 *pcsz = total;
120 /* FIXME: When EOF error code is implemented:
121 else if (total == 0)
122 status = EIO;
123 */
123 free (buf); 124 free (buf);
124 return status; 125 return status;
125 } 126 }
......
...@@ -37,11 +37,10 @@ static int ...@@ -37,11 +37,10 @@ static int
37 fd_temp_open (struct _mu_stream *str) 37 fd_temp_open (struct _mu_stream *str)
38 { 38 {
39 struct _mu_file_stream *fstr = (struct _mu_file_stream *) str; 39 struct _mu_file_stream *fstr = (struct _mu_file_stream *) str;
40 int fd = mu_tempfile (fstr->filename, NULL); 40 struct mu_tempfile_hints hints;
41 if (fd == -1) 41
42 return errno; 42 hints.tmpdir = fstr->filename;
43 fstr->fd = fd; 43 return mu_tempfile (&hints, MU_TEMPFILE_TMPDIR, &fstr->fd, NULL);
44 return 0;
45 } 44 }
46 45
47 int 46 int
......
...@@ -25,22 +25,27 @@ ...@@ -25,22 +25,27 @@
25 #include <mailutils/util.h> 25 #include <mailutils/util.h>
26 26
27 char * 27 char *
28 mu_make_file_name (const char *dir, const char *file) 28 mu_make_file_name_suf (const char *dir, const char *file, const char *suf)
29 { 29 {
30 char *tmp; 30 char *tmp;
31 size_t dirlen = strlen (dir); 31 size_t dirlen = strlen (dir);
32 size_t suflen = suf ? strlen (suf) : 0;
33 size_t fillen = strlen (file);
32 size_t len; 34 size_t len;
33 35
34 while (dirlen > 0 && dir[dirlen-1] == '/') 36 while (dirlen > 0 && dir[dirlen-1] == '/')
35 dirlen--; 37 dirlen--;
36 38
37 len = dirlen + 1 + strlen (file); 39 len = dirlen + 1 + fillen + suflen;
38 tmp = mu_alloc (len + 1); 40 tmp = mu_alloc (len + 1);
39 if (tmp) 41 if (tmp)
40 { 42 {
41 memcpy (tmp, dir, dirlen); 43 memcpy (tmp, dir, dirlen);
42 tmp[dirlen++] = '/'; 44 tmp[dirlen++] = '/';
43 strcpy (tmp + dirlen, file); 45 memcpy (tmp + dirlen, file, fillen);
46 if (suf)
47 memcpy (tmp + dirlen + fillen, suf, suflen);
48 tmp[len] = 0;
44 } 49 }
45 return tmp; 50 return tmp;
46 } 51 }
......
...@@ -48,6 +48,7 @@ noinst_PROGRAMS = \ ...@@ -48,6 +48,7 @@ noinst_PROGRAMS = \
48 listop\ 48 listop\
49 mailcap\ 49 mailcap\
50 prop\ 50 prop\
51 tempfile\
51 url-parse\ 52 url-parse\
52 wicket\ 53 wicket\
53 wsp 54 wsp
......
1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 2005, 2007, 2009, 2010 Free Software Foundation, Inc.
3
4 GNU Mailutils is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 3, or (at your option)
7 any later version.
8
9 GNU Mailutils is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */
16
17 #ifdef HAVE_CONFIG_H
18 # include <config.h>
19 #endif
20 #include <unistd.h>
21 #include <stdlib.h>
22 #include <stdio.h>
23 #include <string.h>
24 #include <mailutils/util.h>
25 #include <mailutils/errno.h>
26 #include <mailutils/error.h>
27 #include <mailutils/stream.h>
28
29 char *progname;
30
31 void
32 usage (FILE *fp, int code)
33 {
34 fprintf (fp,
35 "usage: %s [-tmpdir=DIR] [-suffix=SUF] [-dry-run | -unlink] { file | dir }\n",
36 progname);
37 exit (code);
38 }
39
40 int
41 main (int argc, char **argv)
42 {
43 struct mu_tempfile_hints hints, *phints;
44 int flags = 0;
45 int fd;
46 int *pfd = &fd;
47 char *filename;
48 char **pname = &filename;
49 char *infile = NULL;
50 int verify = 0;
51 int verbose = 0;
52
53 progname = argv[0];
54
55 if (argc == 1)
56 usage (stdout, 0);
57
58 while (--argc)
59 {
60 char *arg = *++argv;
61
62 if (strncmp (arg, "-tmpdir=", 8) == 0)
63 {
64 hints.tmpdir = arg + 8;
65 flags |= MU_TEMPFILE_TMPDIR;
66 }
67 else if (strncmp (arg, "-suffix=", 8) == 0)
68 {
69 hints.suffix = arg + 8;
70 flags |= MU_TEMPFILE_SUFFIX;
71 }
72 else if (strcmp (arg, "-dry-run") == 0)
73 pfd = NULL;
74 else if (strcmp (arg, "-unlink") == 0)
75 pname = NULL;
76 else if (strncmp (arg, "-infile=", 8) == 0)
77 infile = arg + 8;
78 else if (strncmp (arg, "-verify", 7) == 0)
79 verify = 1;
80 else if (strncmp (arg, "-verbose", 8) == 0)
81 verbose = 1;
82 else
83 break;
84 }
85
86 if (argv[0] == NULL)
87 usage (stderr, 1);
88 if (strcmp (argv[0], "file") == 0)
89 /* nothing */;
90 else if (strcmp (argv[0], "dir") == 0)
91 flags |= MU_TEMPFILE_MKDIR;
92 else
93 usage (stderr, 1);
94
95 if (pname == NULL && pfd == NULL)
96 {
97 mu_error ("both -unlink and -dry-run given");
98 exit (1);
99 }
100
101 if (infile)
102 {
103 if (flags & MU_TEMPFILE_MKDIR)
104 {
105 mu_error ("-infile is useless with dir");
106 exit (1);
107 }
108 else if (pfd == NULL)
109 {
110 mu_error ("-infile is useless with -dry-run");
111 exit (1);
112 }
113 }
114
115 if (verify && pfd == NULL)
116 {
117 mu_error ("-verify is useless with -dry-run");
118 exit (1);
119 }
120
121 phints = flags ? &hints : NULL;
122
123 MU_ASSERT (mu_tempfile (phints, flags, pfd, pname));
124
125 if (filename)
126 printf ("created file name %s\n", filename);
127
128 if (!pfd)
129 return 0;
130
131 if (infile)
132 {
133 mu_stream_t in, out;
134 mu_off_t size;
135
136 if (strcmp (infile, "-") == 0)
137 MU_ASSERT (mu_stdio_stream_create (&in, MU_STDIN_FD, 0));
138 else
139 MU_ASSERT (mu_file_stream_create (&in, infile, MU_STREAM_READ));
140
141 MU_ASSERT (mu_fd_stream_create (&out, filename, fd, MU_STREAM_WRITE));
142 MU_ASSERT (mu_stream_copy (out, in, 0, &size));
143 if (verbose)
144 printf ("copied %lu bytes to the temporary\n", (unsigned long) size);
145 mu_stream_unref (out);
146 mu_stream_unref (in);
147 }
148
149 if (verify)
150 {
151 mu_stream_t in, out;
152 mu_off_t size;
153
154 MU_ASSERT (mu_stdio_stream_create (&out, MU_STDOUT_FD, 0));
155 MU_ASSERT (mu_fd_stream_create (&in, filename, fd,
156 MU_STREAM_READ|MU_STREAM_SEEK));
157 MU_ASSERT (mu_stream_copy (out, in, 0, &size));
158 if (verbose)
159 printf ("dumped %lu bytes\n", (unsigned long) size);
160 mu_stream_unref (out);
161 mu_stream_unref (in);
162 }
163
164 close (fd);
165
166 return 0;
167 }
168
169
...@@ -324,11 +324,19 @@ escape_run_editor (char *ed, int argc, char **argv, compose_env_t *env) ...@@ -324,11 +324,19 @@ escape_run_editor (char *ed, int argc, char **argv, compose_env_t *env)
324 if (!mailvar_get (NULL, "editheaders", mailvar_type_boolean, 0)) 324 if (!mailvar_get (NULL, "editheaders", mailvar_type_boolean, 0))
325 { 325 {
326 char *filename; 326 char *filename;
327 int fd = mu_tempfile (NULL, &filename); 327 int fd;
328 FILE *fp = fdopen (fd, "w+"); 328 FILE *fp;
329 char buffer[512]; 329 char buffer[512];
330 int rc; 330 int rc;
331 331
332 rc = mu_tempfile (NULL, 0, &fd, &filename);
333 if (rc)
334 {
335 mu_diag_funcall (MU_DIAG_ERROR, "mu_tempfile", NULL, rc);
336 return rc;
337 }
338
339 fp = fdopen (fd, "w+");
332 dump_headers (fp, env); 340 dump_headers (fp, env);
333 341
334 rewind (env->file); 342 rewind (env->file);
...@@ -639,8 +647,7 @@ escape_pipe (int argc, char **argv, compose_env_t *env) ...@@ -639,8 +647,7 @@ escape_pipe (int argc, char **argv, compose_env_t *env)
639 return 1; 647 return 1;
640 } 648 }
641 649
642 fd = mu_tempfile (NULL, NULL); 650 if (mu_tempfile (NULL, 0, &fd, NULL))
643 if (fd == -1)
644 return 1; 651 return 1;
645 652
646 if ((pid = fork ()) < 0) 653 if ((pid = fork ()) < 0)
......
...@@ -305,8 +305,18 @@ fill_body (mu_message_t msg, mu_stream_t instr) ...@@ -305,8 +305,18 @@ fill_body (mu_message_t msg, mu_stream_t instr)
305 mu_stream_t stream = NULL; 305 mu_stream_t stream = NULL;
306 mu_off_t n; 306 mu_off_t n;
307 307
308 mu_message_get_body (msg, &body); 308 rc = mu_message_get_body (msg, &body);
309 mu_body_get_streamref (body, &stream); 309 if (rc)
310 {
311 mu_error (_("cannot get message body: %s"), mu_strerror (rc));
312 return 1;
313 }
314 rc = mu_body_get_streamref (body, &stream);
315 if (rc)
316 {
317 mu_error (_("cannot get body: %s"), mu_strerror (rc));
318 return 1;
319 }
310 320
311 rc = mu_stream_copy (stream, instr, 0, &n); 321 rc = mu_stream_copy (stream, instr, 0, &n);
312 mu_stream_destroy (&stream); 322 mu_stream_destroy (&stream);
...@@ -428,16 +438,16 @@ int ...@@ -428,16 +438,16 @@ int
428 mail_send0 (compose_env_t * env, int save_to) 438 mail_send0 (compose_env_t * env, int save_to)
429 { 439 {
430 int done = 0; 440 int done = 0;
431 int fd; 441 int fd, rc;
432 char *filename; 442 char *filename;
433 char *savefile = NULL; 443 char *savefile = NULL;
434 int int_cnt; 444 int int_cnt;
435 char *escape; 445 char *escape;
436 446
437 fd = mu_tempfile (NULL, &filename); 447 rc = mu_tempfile (NULL, 0, &fd, &filename);
438 if (fd == -1) 448 if (rc)
439 { 449 {
440 util_error (_("Cannot open temporary file")); 450 util_error (_("Cannot open temporary file: %s"), mu_strerror (rc));
441 return 1; 451 return 1;
442 } 452 }
443 453
......