1 /*
2  * Heirloom mailx - a mail user agent derived from Berkeley Mail.
3  *
4  * Copyright (c) 2000-2004 Gunnar Ritter, Freiburg i. Br., Germany.
5  */
6 /*
7  * Copyright (c) 1980, 1993
8  *	The Regents of the University of California.  All rights reserved.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  * 3. All advertising materials mentioning features or use of this software
19  *    must display the following acknowledgement:
20  *	This product includes software developed by the University of
21  *	California, Berkeley and its contributors.
22  * 4. Neither the name of the University nor the names of its contributors
23  *    may be used to endorse or promote products derived from this software
24  *    without specific prior written permission.
25  *
26  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36  * SUCH DAMAGE.
37  */
38 
39 #ifndef lint
40 #ifdef	DOSCCS
41 static char sccsid[] = "@(#)temp.c	2.8 (gritter) 3/4/06";
42 #endif
43 #endif /* not lint */
44 
45 #include "rcv.h"
46 #include "extern.h"
47 #include <errno.h>
48 #include <sys/stat.h>
49 #include <fcntl.h>
50 
51 /*
52  * Mail -- a mail program
53  *
54  * Temporary file handling.
55  */
56 
57 static char	*tmpdir;
58 
59 /*
60  * Create a temporary file in tmpdir, use prefix for its name,
61  * store the unique name in fn, and return a stdio FILE pointer
62  * with access mode.
63  * The permissions for the newly created file are given in bits.
64  */
65 FILE *
Ftemp(char ** fn,char * prefix,char * mode,int bits,int register_file)66 Ftemp(char **fn, char *prefix, char *mode, int bits, int register_file)
67 {
68 	FILE *fp;
69 	int fd;
70 
71 	*fn = smalloc(strlen(tmpdir) + strlen(prefix) + 8);
72 	strcpy(*fn, tmpdir);
73 	strcat(*fn, "/");
74 	strcat(*fn, prefix);
75 	strcat(*fn, "XXXXXX");
76 #ifdef	HAVE_MKSTEMP
77 	if ((fd = mkstemp(*fn)) < 0)
78 		goto Ftemperr;
79 	if (fchmod(fd, bits) < 0)
80 		goto Ftemperr;
81 #else	/* !HAVE_MKSTEMP */
82 	if (mktemp(*fn) == NULL)
83 		goto Ftemperr;
84 	if ((fd = open(*fn, O_CREAT|O_EXCL|O_RDWR, bits)) < 0)
85 		goto Ftemperr;
86 #endif	/* !HAVE_MKSTEMP */
87 	if (register_file)
88 		fp = Fdopen(fd, mode);
89 	else {
90 		fp = fdopen(fd, mode);
91 		fcntl(fd, F_SETFD, FD_CLOEXEC);
92 	}
93 	return fp;
94 Ftemperr:
95 	Ftfree(fn);
96 	return NULL;
97 }
98 
99 /*
100  * Free the resources associated with the given filename. To be
101  * called after unlink().
102  * Since this function can be called after receiving a signal,
103  * the variable must be made NULL first and then free()d, to avoid
104  * more than one free() call in all circumstances.
105  */
106 void
Ftfree(char ** fn)107 Ftfree(char **fn)
108 {
109 	char *cp = *fn;
110 
111 	*fn = NULL;
112 	free(cp);
113 }
114 
115 void
tinit(void)116 tinit(void)
117 {
118 	char *cp;
119 
120 	if ((cp = getenv("TMPDIR")) != NULL) {
121 		tmpdir = smalloc(strlen(cp) + 1);
122 		strcpy(tmpdir, cp);
123 	} else {
124 		tmpdir = "/tmp";
125 	}
126 	if (myname != NULL) {
127 		if (getuserid(myname) < 0) {
128 			printf(catgets(catd, CATSET, 198,
129 				"\"%s\" is not a user of this system\n"),
130 			    myname);
131 			exit(1);
132 		}
133 	} else {
134 		if ((cp = username()) == NULL) {
135 			myname = "nobody";
136 			if (rcvmode)
137 				exit(1);
138 		} else {
139 			myname = smalloc(strlen(cp) + 1);
140 			strcpy(myname, cp);
141 		}
142 	}
143 	if ((cp = getenv("HOME")) == NULL)
144 		cp = ".";
145 	homedir = smalloc(strlen(cp) + 1);
146 	strcpy(homedir, cp);
147 	if (debug || value("debug"))
148 		printf(catgets(catd, CATSET, 199,
149 			"user = %s, homedir = %s\n"), myname, homedir);
150 }
151