No issues found
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 |
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 }