evolution-3.6.4/e-util/e-mktemp.c

No issues found

Incomplete coverage

Tool Failure ID Location Function Message Data
clang-analyzer no-output-found e-mktemp.c Message(text='Unable to locate XML output from invoke-clang-analyzer') None
clang-analyzer no-output-found e-mktemp.c Message(text='Unable to locate XML output from invoke-clang-analyzer') None
Failure running clang-analyzer ('no-output-found')
Message
Unable to locate XML output from invoke-clang-analyzer
Failure running clang-analyzer ('no-output-found')
Message
Unable to locate XML output from invoke-clang-analyzer
  1 /*
  2  * This program is free software; you can redistribute it and/or
  3  * modify it under the terms of the GNU Lesser General Public
  4  * License as published by the Free Software Foundation; either
  5  * version 2 of the License, or (at your option) version 3.
  6  *
  7  * This program is distributed in the hope that it will be useful,
  8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 10  * Lesser General Public License for more details.
 11  *
 12  * You should have received a copy of the GNU Lesser General Public
 13  * License along with the program; if not, see <http://www.gnu.org/licenses/>
 14  *
 15  *
 16  * Authors:
 17  *		Jeffrey Stedfast <fejj@ximian.com>
 18  *
 19  * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
 20  *
 21  */
 22 
 23 #ifdef HAVE_CONFIG_H
 24 #include <config.h>
 25 #endif
 26 
 27 #include <glib/gstdio.h>
 28 #include <sys/stat.h>
 29 #include <sys/types.h>
 30 #include <stdlib.h>
 31 #include <string.h>
 32 #include <fcntl.h>
 33 #include <unistd.h>
 34 #include <errno.h>
 35 #include <stdio.h>
 36 #include <time.h>
 37 
 38 #include "e-util.h"
 39 #include "e-mktemp.h"
 40 
 41 #define d(x)
 42 
 43 /* define to put temporary files in ~/evolution/cache/tmp */
 44 #define TEMP_HOME (1)
 45 
 46 /* how old things need to be to expire */
 47 #define TEMP_EXPIRE (60*60*2)
 48 /* dont scan more often than this */
 49 #define TEMP_SCAN (60)
 50 
 51 static gint
 52 expire_dir_rec (const gchar *base,
 53                 time_t now)
 54 {
 55 	GDir *dir;
 56 	const gchar *d;
 57 	GString *path;
 58 	gsize len;
 59 	struct stat st;
 60 	gint count = 0;
 61 
 62 	d (printf ("expire dir '%s'\n", base));
 63 
 64 	dir = g_dir_open (base, 0, NULL);
 65 	if (dir == NULL)
 66 		return 0;
 67 
 68 	path = g_string_new (base);
 69 	len = path->len;
 70 
 71 	while ((d = g_dir_read_name (dir))) {
 72 		g_string_truncate (path, len);
 73 		g_string_append_printf (path, "/%s", d);
 74 		d (printf ("Checking '%s' for expiry\n", path->str));
 75 
 76 		if (g_stat (path->str, &st) == 0
 77 		    && st.st_atime + TEMP_EXPIRE < now) {
 78 			if (S_ISDIR (st.st_mode)) {
 79 				if (expire_dir_rec (path->str, now) == 0) {
 80 					d (printf ("Removing dir '%s'\n", path->str));
 81 					g_rmdir (path->str);
 82 				} else {
 83 					count++;
 84 				}
 85 			} else if (g_unlink (path->str) == -1) {
 86 				d (printf ("expiry failed: %s\n", g_strerror (errno)));
 87 				count++;
 88 			} else {
 89 				d (printf ("expired %s\n", path->str));
 90 			}
 91 		} else {
 92 			count++;
 93 		}
 94 	}
 95 	g_string_free (path, TRUE);
 96 	g_dir_close (dir);
 97 
 98 	d (printf ("expire dir '%s' %d remaining files\n", base, count));
 99 
100 	return count;
101 }
102 
103 static GString *
104 get_dir (gboolean make)
105 {
106 	GString *path;
107 	time_t now = time (NULL);
108 	static time_t last = 0;
109 
110 #ifdef TEMP_HOME
111 	const gchar *user_cache_dir;
112 	gchar *tmpdir;
113 
114 	user_cache_dir = e_get_user_cache_dir ();
115 	tmpdir = g_build_filename (user_cache_dir, "tmp", NULL);
116 	path = g_string_new (tmpdir);
117 	if (make && g_mkdir_with_parents (tmpdir, 0777) == -1) {
118 		g_string_free (path, TRUE);
119 		path = NULL;
120 	}
121 	g_free (tmpdir);
122 #else
123 	path = g_string_new ("/tmp/evolution-");
124 	g_string_append_printf (path, "%d", (gint) getuid ());
125 	if (make) {
126 		gint ret;
127 
128 		/* shoot now, ask questions later */
129 		ret = g_mkdir (path->str, S_IRWXU);
130 		if (ret == -1) {
131 			if (errno == EEXIST) {
132 				struct stat st;
133 
134 				if (g_stat (path->str, &st) == -1) {
135 					/* reset errno */
136 					errno = EEXIST;
137 					g_string_free (path, TRUE);
138 					return NULL;
139 				}
140 
141 				/* make sure this is a directory and
142 				 * belongs to us... */
143 				if (!S_ISDIR (st.st_mode) || st.st_uid != getuid ()) {
144 					/* eek! this is bad... */
145 					g_string_free (path, TRUE);
146 					return NULL;
147 				}
148 			} else {
149 				/* some other error...do not pass go,
150 				 * do not collect $200 */
151 				g_string_free (path, TRUE);
152 				return NULL;
153 			}
154 		}
155 	}
156 #endif
157 
158 	d (printf ("temp dir '%s'\n", path ? path->str : "(null)"));
159 
160 	/* fire off an expiry attempt no more often than TEMP_SCAN seconds */
161 	if (path && (last + TEMP_SCAN) < now) {
162 		last = now;
163 		expire_dir_rec (path->str, now);
164 	}
165 
166 	return path;
167 }
168 
169 gchar *
170 e_mktemp (const gchar *template)
171 {
172 	GString *path;
173 	gint fd;
174 
175 	path = get_dir (TRUE);
176 	if (!path)
177 		return NULL;
178 
179 	g_string_append_c (path, '/');
180 	if (template)
181 		g_string_append (path, template);
182 	else
183 		g_string_append (path, "unknown-XXXXXX");
184 
185 	fd = g_mkstemp (path->str);
186 
187 	if (fd != -1) {
188 		close (fd);
189 		g_unlink (path->str);
190 	}
191 
192 	return g_string_free (path, fd == -1);
193 }
194 
195 gint
196 e_mkstemp (const gchar *template)
197 {
198 	GString *path;
199 	gint fd;
200 
201 	path = get_dir (TRUE);
202 	if (!path)
203 		return -1;
204 
205 	g_string_append_c (path, '/');
206 	if (template)
207 		g_string_append (path, template);
208 	else
209 		g_string_append (path, "unknown-XXXXXX");
210 
211 	fd = g_mkstemp (path->str);
212 	g_string_free (path, TRUE);
213 
214 	return fd;
215 }
216 
217 gchar *
218 e_mkdtemp (const gchar *template)
219 {
220 	GString *path;
221 	gchar *tmpdir;
222 
223 	path = get_dir (TRUE);
224 	if (!path)
225 		return NULL;
226 
227 	g_string_append_c (path, '/');
228 	if (template)
229 		g_string_append (path, template);
230 	else
231 		g_string_append (path, "unknown-XXXXXX");
232 
233 #ifdef HAVE_MKDTEMP
234 	tmpdir = mkdtemp (path->str);
235 #else
236 	{
237 		gint fd = g_mkstemp (path->str);
238 		if (fd == -1) {
239 			tmpdir = NULL;
240 		} else {
241 			close (fd);
242 			tmpdir = path->str;
243 			g_unlink (tmpdir);
244 		}
245 	}
246 
247 	if (tmpdir) {
248 		if (g_mkdir (tmpdir, S_IRWXU) == -1)
249 			tmpdir = NULL;
250 	}
251 #endif
252 	g_string_free (path, tmpdir == NULL);
253 
254 	return tmpdir;
255 }