dma: add TODO
[dragonfly.git] / libexec / dma / util.c
CommitLineData
1da0a9f2
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>
36#include <errno.h>
37#include <fcntl.h>
38#include <netdb.h>
39#include <pwd.h>
40#include <stdio.h>
41#include <syslog.h>
42#include <unistd.h>
43
44#include "dma.h"
45
46const char *
47hostname(void)
48{
49 static char name[MAXHOSTNAMELEN+1];
50 int initialized = 0;
51 FILE *fp;
52 size_t len;
53
54 if (initialized)
55 return (name);
56
57 if (config->mailname != NULL && config->mailname[0] != '\0') {
58 snprintf(name, sizeof(name), "%s", config->mailname);
59 initialized = 1;
60 return (name);
61 }
62 if (config->mailnamefile != NULL && config->mailnamefile[0] != '\0') {
63 fp = fopen(config->mailnamefile, "r");
64 if (fp != NULL) {
65 if (fgets(name, sizeof(name), fp) != NULL) {
66 len = strlen(name);
67 while (len > 0 &&
68 (name[len - 1] == '\r' ||
69 name[len - 1] == '\n'))
70 name[--len] = '\0';
71 if (name[0] != '\0') {
72 initialized = 1;
73 return (name);
74 }
75 }
76 fclose(fp);
77 }
78 }
79 if (gethostname(name, sizeof(name)) != 0)
80 strcpy(name, "(unknown hostname)");
81 initialized = 1;
82 return name;
83}
84
85void
86setlogident(const char *fmt, ...)
87{
88 char *tag = NULL;
89
90 if (fmt != NULL) {
91 va_list ap;
92 char *sufx;
93
94 va_start(ap, fmt);
95 vasprintf(&sufx, fmt, ap);
96 if (sufx != NULL) {
97 asprintf(&tag, "%s[%s]", logident_base, sufx);
98 free(sufx);
99 }
100 va_end(ap);
101 }
102 closelog();
103 openlog(tag != NULL ? tag : logident_base, 0, LOG_MAIL);
104}
105
106void
107errlog(int exitcode, const char *fmt, ...)
108{
109 int oerrno = errno;
110 va_list ap;
111 char *outs = NULL;
112
113 if (fmt != NULL) {
114 va_start(ap, fmt);
115 vasprintf(&outs, fmt, ap);
116 va_end(ap);
117 }
118
119 if (outs != NULL) {
120 syslog(LOG_ERR, "%s: %m", outs);
121 fprintf(stderr, "%s: %s: %s\n", getprogname(), outs, strerror(oerrno));
122 } else {
123 syslog(LOG_ERR, "%m");
124 fprintf(stderr, "%s: %s\n", getprogname(), strerror(oerrno));
125 }
126
127 exit(exitcode);
128}
129
130void
131errlogx(int exitcode, const char *fmt, ...)
132{
133 va_list ap;
134 char *outs = NULL;
135
136 if (fmt != NULL) {
137 va_start(ap, fmt);
138 vasprintf(&outs, fmt, ap);
139 va_end(ap);
140 }
141
142 if (outs != NULL) {
143 syslog(LOG_ERR, "%s", outs);
144 fprintf(stderr, "%s: %s\n", getprogname(), outs);
145 } else {
146 syslog(LOG_ERR, "Unknown error");
147 fprintf(stderr, "%s: Unknown error\n", getprogname());
148 }
149
150 exit(exitcode);
151}
152
153static const char *
154check_username(const char *name, uid_t ckuid)
155{
156 struct passwd *pwd;
157
158 if (name == NULL)
159 return (NULL);
160 pwd = getpwnam(name);
161 if (pwd == NULL || pwd->pw_uid != ckuid)
162 return (NULL);
163 return (name);
164}
165
166void
167set_username(void)
168{
169 struct passwd *pwd;
170 char *u = NULL;
171 uid_t uid;
172
173 uid = getuid();
174 username = check_username(getlogin(), uid);
175 if (username != NULL)
176 return;
177 username = check_username(getenv("LOGNAME"), uid);
178 if (username != NULL)
179 return;
180 username = check_username(getenv("USER"), uid);
181 if (username != NULL)
182 return;
183 pwd = getpwuid(uid);
184 if (pwd != NULL && pwd->pw_name != NULL && pwd->pw_name[0] != '\0' &&
185 (u = strdup(pwd->pw_name)) != NULL) {
186 username = check_username(u, uid);
187 if (username != NULL)
188 return;
189 else
190 free(u);
191 }
192 asprintf(__DECONST(void *, &username), "%ld", (long)uid);
193 if (username != NULL)
194 return;
195 username = "unknown-or-invalid-username";
196}
197
198void
199deltmp(void)
200{
201 struct stritem *t;
202
203 SLIST_FOREACH(t, &tmpfs, next) {
204 unlink(t->str);
205 }
206}
207
208int
209open_locked(const char *fname, int flags, ...)
210{
211 int mode = 0;
212
213 if (flags & O_CREAT) {
214 va_list ap;
215 va_start(ap, flags);
216 mode = va_arg(ap, int);
217 va_end(ap);
218 }
219
220#ifndef O_EXLOCK
221 int fd, save_errno;
222
223 fd = open(fname, flags, mode);
224 if (fd < 0)
225 return(fd);
226 if (flock(fd, LOCK_EX|((flags & O_NONBLOCK)? LOCK_NB: 0)) < 0) {
227 save_errno = errno;
228 close(fd);
229 errno = save_errno;
230 return(-1);
231 }
232 return(fd);
233#else
234 return(open(fname, flags|O_EXLOCK, mode));
235#endif
236}
237
238char *
239rfc822date(void)
240{
241 static char str[50];
242 size_t error;
243 time_t now;
244
245 now = time(NULL);
246 error = strftime(str, sizeof(str), "%a, %d %b %Y %T %z",
247 localtime(&now));
248 if (error == 0)
249 strcpy(str, "(date fail)");
250 return (str);
251}
252
253int
254strprefixcmp(const char *str, const char *prefix)
255{
256 return (strncasecmp(str, prefix, strlen(prefix)));
257}
258