2 ** m_mktemp.c -- Construct a temporary file.
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.
14 static char *get_temp_dir();
16 /* Create a temporary file. If pfx_in is null, the temporary file
17 ** will be created in the temporary directory (more on that later).
18 ** If pfx_in is not null, then the temporary file location will be
19 ** defined by the value pfx_in.
21 ** The file created will be at the pathname specified appended with
22 ** 6 random (we hope :) characters.
24 ** The return value will be the pathname to the file created.
26 ** CAUTION: The return pointer references static data. If
27 ** you need to modify, or save, the return string, make a copy of it
30 ** When pfx_in is null, the temporary directory is determined as
36 ** User's mail directory.
38 ** NOTE: One will probably use m_mktemp2() instead of this function.
39 ** For example, if you want to create a temp file in the defined
40 ** temporary directory, but with a custom basename prefix, do
41 ** something like the following:
43 ** char *tmp_pathname = m_mktemp2(NULL, "mypre", ...);
47 const char *pfx_in, /* Pathname prefix for temporary file. */
48 int *fd_ret, /* (return,opt.) File descriptor to temp file. */
49 FILE **fp_ret /* (return,opt.) FILE pointer to temp file. */
52 static char tmpfil[BUFSIZ];
55 mode_t oldmode = umask(077);
58 snprintf(tmpfil, sizeof(tmpfil), "%s/nmhXXXXXX",
61 snprintf(tmpfil, sizeof(tmpfil), "%sXXXXXX", pfx_in);
74 FILE *fp = fdopen(fd, "w+");
94 ** This version allows one to specify the directory the temp file should
95 ** by created based on a given pathname. Although m_mktemp() technically
96 ** supports this, this version is when the directory is defined by
97 ** a separate variable from the prefix, eliminating the caller from having
98 ** to do string manipulation to generate the desired. pathname prefix.
100 ** The pfx_in parameter specifies a basename prefix for the file. If dir_in
101 ** is NULL, then the defined temporary directory (see comments to m_mktemp()
102 ** above) is used to create the temp file.
106 const char *dir_in, /* Directory to place temp file. */
107 const char *pfx_in, /* Basename prefix for temp file. */
108 int *fd_ret, /* (return,opt.) File descriptor to temp file. */
109 FILE **fp_ret /* (return,opt.) FILE pointer to temp file. */
112 static char buffer[BUFSIZ];
116 if (dir_in == NULL) {
117 if (pfx_in == NULL) {
118 return m_mktemp(NULL, fd_ret, fp_ret);
120 snprintf(buffer, sizeof(buffer), "%s/%s", get_temp_dir(), pfx_in);
121 return m_mktemp(buffer, fd_ret, fp_ret);
124 if ((cp = mhbasename((char *)dir_in)) == dir_in) {
125 /* No directory component */
126 return m_mktemp(pfx_in, fd_ret, fp_ret);
128 n = (int)(cp-dir_in-1); /* Length of dir component */
129 snprintf(buffer, sizeof(buffer), "%.*s/%s", n, dir_in, pfx_in);
130 return m_mktemp(buffer, fd_ret, fp_ret);
137 /* Ignore envvars if we are setuid */
138 if ((getuid()==geteuid()) && (getgid()==getegid())) {
140 tmpdir = getenv("MHTMPDIR");
141 if (tmpdir != NULL && *tmpdir != '\0') return tmpdir;
143 tmpdir = getenv("TMPDIR");
144 if (tmpdir != NULL && *tmpdir != '\0') return tmpdir;
146 tmpdir = getenv("TMP");
147 if (tmpdir != NULL && *tmpdir != '\0') return tmpdir;
149 return toabsdir("+");