]> git.ipfire.org Git - people/ms/dma.git/blob - util.c
properly randomize the message id
[people/ms/dma.git] / util.c
1 /*
2 * Copyright (c) 2008 The DragonFly Project. All rights reserved.
3 *
4 * This code is derived from software contributed to The DragonFly Project
5 * by Simon 'corecode' Schubert <corecode@fs.ei.tum.de>.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
16 * distribution.
17 * 3. Neither the name of The DragonFly Project nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific, prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
31 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 */
34
35 #include <sys/param.h>
36 #include <sys/file.h>
37
38 #include <errno.h>
39 #include <fcntl.h>
40 #include <netdb.h>
41 #include <pwd.h>
42 #include <stdio.h>
43 #include <syslog.h>
44 #include <unistd.h>
45
46 #include "dma.h"
47
48 const char *
49 hostname(void)
50 {
51 static char name[MAXHOSTNAMELEN+1];
52 static int initialized = 0;
53 FILE *fp;
54 char *res;
55 size_t len;
56
57 if (initialized)
58 return (name);
59
60 if (config.mailname != NULL && config.mailname[0] != '\0') {
61 snprintf(name, sizeof(name), "%s", config.mailname);
62 initialized = 1;
63 return (name);
64 }
65 if (config.mailnamefile != NULL && config.mailnamefile[0] != '\0') {
66 fp = fopen(config.mailnamefile, "r");
67 if (fp != NULL) {
68 res = fgets(name, sizeof(name), fp);
69 fclose(fp);
70 if (res != NULL) {
71 len = strlen(name);
72 while (len > 0 &&
73 (name[len - 1] == '\r' ||
74 name[len - 1] == '\n'))
75 name[--len] = '\0';
76 if (name[0] != '\0') {
77 initialized = 1;
78 return (name);
79 }
80 }
81 }
82 }
83 if (gethostname(name, sizeof(name)) != 0)
84 strcpy(name, "(unknown hostname)");
85 initialized = 1;
86 return name;
87 }
88
89 void
90 setlogident(const char *fmt, ...)
91 {
92 char *tag = NULL;
93
94 if (fmt != NULL) {
95 va_list ap;
96 char *sufx;
97
98 va_start(ap, fmt);
99 if (vasprintf(&sufx, fmt, ap) != -1 && sufx != NULL) {
100 if (asprintf(&tag, "%s[%s]", logident_base, sufx) == -1)
101 tag = NULL;
102 free(sufx);
103 }
104 va_end(ap);
105 }
106 closelog();
107 openlog(tag != NULL ? tag : logident_base, 0, LOG_MAIL);
108 }
109
110 void
111 errlog(int exitcode, const char *fmt, ...)
112 {
113 int oerrno = errno;
114 va_list ap;
115 char *outs = NULL;
116
117 if (fmt != NULL) {
118 va_start(ap, fmt);
119 if (vasprintf(&outs, fmt, ap) == -1)
120 outs = NULL;
121 va_end(ap);
122 }
123
124 if (outs != NULL) {
125 syslog(LOG_ERR, "%s: %m", outs);
126 fprintf(stderr, "%s: %s: %s\n", getprogname(), outs, strerror(oerrno));
127 } else {
128 syslog(LOG_ERR, "%m");
129 fprintf(stderr, "%s: %s\n", getprogname(), strerror(oerrno));
130 }
131
132 exit(exitcode);
133 }
134
135 void
136 errlogx(int exitcode, const char *fmt, ...)
137 {
138 va_list ap;
139 char *outs = NULL;
140
141 if (fmt != NULL) {
142 va_start(ap, fmt);
143 if (vasprintf(&outs, fmt, ap) == -1)
144 outs = NULL;
145 va_end(ap);
146 }
147
148 if (outs != NULL) {
149 syslog(LOG_ERR, "%s", outs);
150 fprintf(stderr, "%s: %s\n", getprogname(), outs);
151 } else {
152 syslog(LOG_ERR, "Unknown error");
153 fprintf(stderr, "%s: Unknown error\n", getprogname());
154 }
155
156 exit(exitcode);
157 }
158
159 static const char *
160 check_username(const char *name, uid_t ckuid)
161 {
162 struct passwd *pwd;
163
164 if (name == NULL)
165 return (NULL);
166 pwd = getpwnam(name);
167 if (pwd == NULL || pwd->pw_uid != ckuid)
168 return (NULL);
169 return (name);
170 }
171
172 void
173 set_username(void)
174 {
175 struct passwd *pwd;
176 char *u = NULL;
177 uid_t uid;
178
179 uid = getuid();
180 username = check_username(getlogin(), uid);
181 if (username != NULL)
182 return;
183 username = check_username(getenv("LOGNAME"), uid);
184 if (username != NULL)
185 return;
186 username = check_username(getenv("USER"), uid);
187 if (username != NULL)
188 return;
189 pwd = getpwuid(uid);
190 if (pwd != NULL && pwd->pw_name != NULL && pwd->pw_name[0] != '\0' &&
191 (u = strdup(pwd->pw_name)) != NULL) {
192 username = check_username(u, uid);
193 if (username != NULL)
194 return;
195 else
196 free(u);
197 }
198 if (asprintf(__DECONST(void *, &username), "%ld", (long)uid) != -1 &&
199 username != NULL)
200 return;
201 username = "unknown-or-invalid-username";
202 }
203
204 void
205 deltmp(void)
206 {
207 struct stritem *t;
208
209 SLIST_FOREACH(t, &tmpfs, next) {
210 unlink(t->str);
211 }
212 }
213
214 int
215 open_locked(const char *fname, int flags, ...)
216 {
217 int mode = 0;
218
219 if (flags & O_CREAT) {
220 va_list ap;
221 va_start(ap, flags);
222 mode = va_arg(ap, int);
223 va_end(ap);
224 }
225
226 #ifndef O_EXLOCK
227 int fd, save_errno;
228
229 fd = open(fname, flags, mode);
230 if (fd < 0)
231 return(fd);
232 if (flock(fd, LOCK_EX|((flags & O_NONBLOCK)? LOCK_NB: 0)) < 0) {
233 save_errno = errno;
234 close(fd);
235 errno = save_errno;
236 return(-1);
237 }
238 return(fd);
239 #else
240 return(open(fname, flags|O_EXLOCK, mode));
241 #endif
242 }
243
244 char *
245 rfc822date(void)
246 {
247 static char str[50];
248 size_t error;
249 time_t now;
250
251 now = time(NULL);
252 error = strftime(str, sizeof(str), "%a, %d %b %Y %T %z",
253 localtime(&now));
254 if (error == 0)
255 strcpy(str, "(date fail)");
256 return (str);
257 }
258
259 int
260 strprefixcmp(const char *str, const char *prefix)
261 {
262 return (strncasecmp(str, prefix, strlen(prefix)));
263 }
264
265 void
266 init_random(void)
267 {
268 unsigned int seed;
269 int rf;
270
271 rf = open("/dev/urandom", O_RDONLY);
272 if (rf == -1)
273 rf = open("/dev/random", O_RDONLY);
274
275 if (!(rf != -1 && read(rf, &seed, sizeof(seed)) == sizeof(seed)))
276 seed = (time(NULL) ^ getpid()) + (uintptr_t)&seed;
277
278 srandom(seed);
279
280 if (rf != -1)
281 close(rf);
282 }