]> git.ipfire.org Git - people/ms/dma.git/blame - util.c
load_queue: use stat(2) instead of de->d_type
[people/ms/dma.git] / util.c
CommitLineData
de13a881
SS
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>
9b921550
SS
36#include <sys/file.h>
37
de13a881
SS
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
48const char *
49hostname(void)
50{
51 static char name[MAXHOSTNAMELEN+1];
3b322ad4 52 static int initialized = 0;
de13a881 53 FILE *fp;
3b322ad4 54 char *res;
de13a881
SS
55 size_t len;
56
57 if (initialized)
58 return (name);
59
a0c4afa6
SS
60 if (config.mailname != NULL && config.mailname[0] != '\0') {
61 snprintf(name, sizeof(name), "%s", config.mailname);
de13a881
SS
62 initialized = 1;
63 return (name);
64 }
a0c4afa6
SS
65 if (config.mailnamefile != NULL && config.mailnamefile[0] != '\0') {
66 fp = fopen(config.mailnamefile, "r");
de13a881 67 if (fp != NULL) {
3b322ad4
PP
68 res = fgets(name, sizeof(name), fp);
69 fclose(fp);
70 if (res != NULL) {
de13a881
SS
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 }
de13a881
SS
81 }
82 }
83 if (gethostname(name, sizeof(name)) != 0)
84 strcpy(name, "(unknown hostname)");
85 initialized = 1;
86 return name;
87}
88
89void
90setlogident(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);
4ffb8581
PP
99 if (vasprintf(&sufx, fmt, ap) != -1 && sufx != NULL) {
100 if (asprintf(&tag, "%s[%s]", logident_base, sufx) == -1)
101 tag = NULL;
de13a881
SS
102 free(sufx);
103 }
104 va_end(ap);
105 }
106 closelog();
107 openlog(tag != NULL ? tag : logident_base, 0, LOG_MAIL);
108}
109
110void
111errlog(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);
4ffb8581
PP
119 if (vasprintf(&outs, fmt, ap) == -1)
120 outs = NULL;
de13a881
SS
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
135void
136errlogx(int exitcode, const char *fmt, ...)
137{
138 va_list ap;
139 char *outs = NULL;
140
141 if (fmt != NULL) {
142 va_start(ap, fmt);
4ffb8581
PP
143 if (vasprintf(&outs, fmt, ap) == -1)
144 outs = NULL;
de13a881
SS
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
159static const char *
160check_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
172void
173set_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 }
4ffb8581
PP
198 if (asprintf(__DECONST(void *, &username), "%ld", (long)uid) != -1 &&
199 username != NULL)
de13a881
SS
200 return;
201 username = "unknown-or-invalid-username";
202}
203
204void
205deltmp(void)
206{
207 struct stritem *t;
208
209 SLIST_FOREACH(t, &tmpfs, next) {
210 unlink(t->str);
211 }
212}
213
214int
215open_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
244char *
245rfc822date(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
259int
260strprefixcmp(const char *str, const char *prefix)
261{
262 return (strncasecmp(str, prefix, strlen(prefix)));
263}
264