]> diplodocus.org Git - nmh/blob - sbr/m_mktemp.c
Removed temporary probes added in commit
[nmh] / sbr / m_mktemp.c
1 /*
2 * m_mktemp.c -- Construct a temporary file.
3 *
4 * This code is Copyright (c) 2010, by the authors of nmh. See the
5 * COPYRIGHT file in the root directory of the nmh distribution for
6 * complete copyright information.
7 */
8
9 #include <h/mh.h>
10
11 static char *get_temp_dir();
12
13 /* Create a temporary file. If pfx_in is null, the temporary file
14 * will be created in the temporary directory (more on that later).
15 * If pfx_in is not null, then the temporary file location will be
16 * defined by the value pfx_in.
17 *
18 * The file created will be at the pathname specified appended with
19 * 6 random (we hope :) characters.
20 *
21 * The return value will be the pathname to the file created.
22 *
23 * CAUTION: The return pointer references static data. If
24 * you need to modify, or save, the return string, make a copy of it
25 * first.
26 *
27 * When pfx_in is null, the temporary directory is determined as
28 * follows, in order:
29 *
30 * MHTMPDIR envvar
31 * TMPDIR envvar
32 * TMP envvar
33 * User's mail directory.
34 *
35 * NOTE: One will probably use m_mktemp2() instead of this function.
36 * For example, if you want to create a temp file in the defined
37 * temporary directory, but with a custom basename prefix, do
38 * something like the following:
39 *
40 * char *tmp_pathname = m_mktemp2(NULL, "mypre", ...);
41 */
42 char *
43 m_mktemp (
44 const char *pfx_in, /* Pathname prefix for temporary file. */
45 int *fd_ret, /* (return,optional) File descriptor to temp file. */
46 FILE **fp_ret /* (return,optional) FILE pointer to temp file. */
47 )
48 {
49 static char tmpfil[BUFSIZ];
50 int fd = -1;
51 int keep_open = 0;
52 mode_t oldmode = umask(077);
53
54 if (pfx_in == NULL) {
55 snprintf(tmpfil, sizeof(tmpfil), "%s/nmhXXXXXX", get_temp_dir());
56 } else {
57 snprintf(tmpfil, sizeof(tmpfil), "%sXXXXXX", pfx_in);
58 }
59
60 fd = mkstemp(tmpfil);
61 if (fd < 0) {
62 umask(oldmode);
63 return NULL;
64 }
65 if (fd_ret != NULL) {
66 *fd_ret = fd;
67 keep_open = 1;
68 }
69 if (fp_ret != NULL) {
70 FILE *fp = fdopen(fd, "w+");
71 if (fp == NULL) {
72 int olderr = errno;
73 unlink(tmpfil);
74 close(fd);
75 errno = olderr;
76 umask(oldmode);
77 return NULL;
78 }
79 *fp_ret = fp;
80 keep_open = 1;
81 }
82 if (!keep_open) {
83 close(fd);
84 }
85 umask(oldmode);
86 return tmpfil;
87 }
88
89 /* This version allows one to specify the directory the temp file should
90 * by created based on a given pathname. Although m_mktemp() technically
91 * supports this, this version is when the directory is defined by
92 * a separate variable from the prefix, eliminating the caller from having
93 * to do string manipulation to generate the desired. pathname prefix.
94 *
95 * The pfx_in parameter specifies a basename prefix for the file. If dir_in
96 * is NULL, then the defined temporary directory (see comments to m_mktemp()
97 * above) is used to create the temp file.
98 */
99 char *
100 m_mktemp2 (
101 const char *dir_in, /* Directory to place temp file. */
102 const char *pfx_in, /* Basename prefix for temp file. */
103 int *fd_ret, /* (return,optional) File descriptor to temp file. */
104 FILE **fp_ret /* (return,optional) FILE pointer to temp file. */
105 )
106 {
107 static char buffer[BUFSIZ];
108 char *cp;
109 int n;
110
111 if (dir_in == NULL) {
112 if (pfx_in == NULL) {
113 return m_mktemp(NULL, fd_ret, fp_ret);
114 }
115 snprintf(buffer, sizeof(buffer), "%s/%s", get_temp_dir(), pfx_in);
116 return m_mktemp(buffer, fd_ret, fp_ret);
117 }
118
119 if ((cp = r1bindex ((char *)dir_in, '/')) == dir_in) {
120 /* No directory component */
121 return m_mktemp(pfx_in, fd_ret, fp_ret);
122 }
123 n = (int)(cp-dir_in); /* Length of dir component */
124 snprintf(buffer, sizeof(buffer), "%.*s%s", n, dir_in, pfx_in);
125 return m_mktemp(buffer, fd_ret, fp_ret);
126 }
127
128
129 static char *
130 get_temp_dir()
131 {
132 /* Ignore envvars if we are setuid */
133 if ((getuid()==geteuid()) && (getgid()==getegid())) {
134 char *tmpdir = NULL;
135 tmpdir = getenv("MHTMPDIR");
136 if (tmpdir != NULL && *tmpdir != '\0') return tmpdir;
137
138 tmpdir = getenv("TMPDIR");
139 if (tmpdir != NULL && *tmpdir != '\0') return tmpdir;
140
141 tmpdir = getenv("TMP");
142 if (tmpdir != NULL && *tmpdir != '\0') return tmpdir;
143 }
144 return m_maildir("");
145 }