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.
12 static char *get_temp_dir();
14 /* Create a temporary file. If pfx_in is null, the temporary file
15 ** will be created in the temporary directory (more on that later).
16 ** If pfx_in is not null, then the temporary file location will be
17 ** defined by the value pfx_in.
19 ** The file created will be at the pathname specified appended with
20 ** 6 random (we hope :) characters.
22 ** The return value will be the pathname to the file created.
24 ** CAUTION: The return pointer references static data. If
25 ** you need to modify, or save, the return string, make a copy of it
28 ** When pfx_in is null, the temporary directory is determined as
34 ** User's mail directory.
36 ** NOTE: One will probably use m_mktemp2() instead of this function.
37 ** For example, if you want to create a temp file in the defined
38 ** temporary directory, but with a custom basename prefix, do
39 ** something like the following:
41 ** char *tmp_pathname = m_mktemp2(NULL, "mypre", ...);
45 const char *pfx_in, /* Pathname prefix for temporary file. */
46 int *fd_ret, /* (return,opt.) File descriptor to temp file. */
47 FILE **fp_ret /* (return,opt.) FILE pointer to temp file. */
50 static char tmpfil[BUFSIZ];
53 mode_t oldmode = umask(077);
56 snprintf(tmpfil, sizeof(tmpfil), "%s/nmhXXXXXX",
59 snprintf(tmpfil, sizeof(tmpfil), "%sXXXXXX", pfx_in);
72 FILE *fp = fdopen(fd, "w+");
92 ** This version allows one to specify the directory the temp file should
93 ** by created based on a given pathname. Although m_mktemp() technically
94 ** supports this, this version is when the directory is defined by
95 ** a separate variable from the prefix, eliminating the caller from having
96 ** to do string manipulation to generate the desired. pathname prefix.
98 ** The pfx_in parameter specifies a basename prefix for the file. If dir_in
99 ** is NULL, then the defined temporary directory (see comments to m_mktemp()
100 ** above) is used to create the temp file.
104 const char *dir_in, /* Directory to place temp file. */
105 const char *pfx_in, /* Basename prefix for temp file. */
106 int *fd_ret, /* (return,opt.) File descriptor to temp file. */
107 FILE **fp_ret /* (return,opt.) FILE pointer to temp file. */
110 static char buffer[BUFSIZ];
114 if (dir_in == NULL) {
115 if (pfx_in == NULL) {
116 return m_mktemp(NULL, fd_ret, fp_ret);
118 snprintf(buffer, sizeof(buffer), "%s/%s", get_temp_dir(), pfx_in);
119 return m_mktemp(buffer, fd_ret, fp_ret);
122 if ((cp = mhbasename((char *)dir_in)) == dir_in) {
123 /* No directory component */
124 return m_mktemp(pfx_in, fd_ret, fp_ret);
126 n = (int)(cp-dir_in-1); /* Length of dir component */
127 snprintf(buffer, sizeof(buffer), "%.*s/%s", n, dir_in, pfx_in);
128 return m_mktemp(buffer, fd_ret, fp_ret);
135 /* Ignore envvars if we are setuid */
136 if ((getuid()==geteuid()) && (getgid()==getegid())) {
138 tmpdir = getenv("MHTMPDIR");
139 if (tmpdir != NULL && *tmpdir != '\0') return tmpdir;
141 tmpdir = getenv("TMPDIR");
142 if (tmpdir != NULL && *tmpdir != '\0') return tmpdir;
144 tmpdir = getenv("TMP");
145 if (tmpdir != NULL && *tmpdir != '\0') return tmpdir;
147 return toabsdir("+");