2 * Copyright (c) 2008-2014, Simon Schubert <2@0x2c.org>.
3 * Copyright (c) 2008 The DragonFly Project. All rights reserved.
5 * This code is derived from software contributed to The DragonFly Project
6 * by Simon Schubert <2@0x2c.org>.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in
16 * the documentation and/or other materials provided with the
18 * 3. Neither the name of The DragonFly Project nor the names of its
19 * contributors may be used to endorse or promote products derived
20 * from this software without specific, prior written permission.
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
27 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
28 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
30 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
31 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
32 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 #include <sys/param.h>
58 #define HOST_NAME_MAX 255
60 static char name[HOST_NAME_MAX+1];
61 static int initialized = 0;
67 if (config.mailname == NULL || !*config.mailname)
70 if (config.mailname[0] == '/') {
72 * If the mailname looks like an absolute path,
77 fp = fopen(config.mailname, "r");
81 s = fgets(name, sizeof(name), fp);
86 for (s = name; *s != 0 && (isalnum(*s) || strchr("_.-", *s)); ++s)
96 snprintf(name, sizeof(name), "%s", config.mailname);
102 snprintf(name, sizeof(name), "%s", systemhostname());
111 #ifndef HOST_NAME_MAX
112 #define HOST_NAME_MAX 255
114 static char name[HOST_NAME_MAX+1];
115 static int initialized = 0;
121 if (gethostname(name, sizeof(name)) != 0)
124 * gethostname() is allowed to truncate name without NUL-termination
125 * and at the same time not return an error.
127 name[sizeof(name) - 1] = 0;
129 for (s = name; *s != 0 && (isalnum(*s) || strchr("_.-", *s)); ++s)
134 snprintf(name, sizeof(name), "unknown-hostname");
141 setlogident(const char *fmt, ...)
145 snprintf(tag, sizeof(tag), "%s", logident_base);
151 vsnprintf(sufx, sizeof(sufx), fmt, ap);
153 snprintf(tag, sizeof(tag), "%s[%s]", logident_base, sufx);
156 openlog(tag, 0, LOG_MAIL);
160 errlog(int exitcode, const char *fmt, ...)
164 char outs[ERRMSG_SIZE];
169 vsnprintf(outs, sizeof(outs), fmt, ap);
175 syslog(LOG_ERR, "%s: %m", outs);
176 fprintf(stderr, "%s: %s: %s\n", getprogname(), outs, strerror(oerrno));
178 syslog(LOG_ERR, "%m");
179 fprintf(stderr, "%s: %s\n", getprogname(), strerror(oerrno));
186 errlogx(int exitcode, const char *fmt, ...)
189 char outs[ERRMSG_SIZE];
194 vsnprintf(outs, sizeof(outs), fmt, ap);
199 syslog(LOG_ERR, "%s", outs);
200 fprintf(stderr, "%s: %s\n", getprogname(), outs);
202 syslog(LOG_ERR, "Unknown error");
203 fprintf(stderr, "%s: Unknown error\n", getprogname());
210 check_username(const char *name, uid_t ckuid)
216 pwd = getpwnam(name);
217 if (pwd == NULL || pwd->pw_uid != ckuid)
219 snprintf(username, sizeof(username), "%s", name);
229 if (check_username(getlogin(), useruid))
231 if (check_username(getenv("LOGNAME"), useruid))
233 if (check_username(getenv("USER"), useruid))
235 pwd = getpwuid(useruid);
236 if (pwd != NULL && pwd->pw_name != NULL && pwd->pw_name[0] != '\0') {
237 if (check_username(pwd->pw_name, useruid))
240 snprintf(username, sizeof(username), "uid=%ld", (long)useruid);
248 SLIST_FOREACH(t, &tmpfs, next) {
253 static sigjmp_buf sigbuf;
254 static int sigbuf_valid;
257 sigalrm_handler(int signo)
259 (void)signo; /* so that gcc doesn't complain */
261 siglongjmp(sigbuf, 1);
265 do_timeout(int timeout, int dojmp)
267 struct sigaction act;
270 sigemptyset(&act.sa_mask);
274 act.sa_handler = sigalrm_handler;
275 if (sigaction(SIGALRM, &act, NULL) != 0)
276 syslog(LOG_WARNING, "can not set signal handler: %m");
278 ret = sigsetjmp(sigbuf, 1);
281 /* else just programmed */
290 act.sa_handler = SIG_IGN;
291 if (sigaction(SIGALRM, &act, NULL) != 0)
292 syslog(LOG_WARNING, "can not remove signal handler: %m");
300 open_locked(const char *fname, int flags, ...)
304 if (flags & O_CREAT) {
307 mode = va_arg(ap, int);
314 fd = open(fname, flags, mode);
317 if (flock(fd, LOCK_EX|((flags & O_NONBLOCK)? LOCK_NB: 0)) < 0) {
325 return(open(fname, flags|O_EXLOCK, mode));
337 error = strftime(str, sizeof(str), "%a, %d %b %Y %T %z",
340 strcpy(str, "(date fail)");
345 strprefixcmp(const char *str, const char *prefix)
347 return (strncasecmp(str, prefix, strlen(prefix)));
356 rf = open("/dev/urandom", O_RDONLY);
358 rf = open("/dev/random", O_RDONLY);
360 if (!(rf != -1 && read(rf, &seed, sizeof(seed)) == sizeof(seed)))
361 seed = (time(NULL) ^ getpid()) + (uintptr_t)&seed;