Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/dma/util.c
39475 views
1
/*
2
* Copyright (c) 2008-2014, Simon Schubert <[email protected]>.
3
* Copyright (c) 2008 The DragonFly Project. All rights reserved.
4
*
5
* This code is derived from software contributed to The DragonFly Project
6
* by Simon Schubert <[email protected]>.
7
*
8
* Redistribution and use in source and binary forms, with or without
9
* modification, are permitted provided that the following conditions
10
* are met:
11
*
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
17
* distribution.
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.
21
*
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
33
* SUCH DAMAGE.
34
*/
35
36
#include <sys/param.h>
37
#include <sys/file.h>
38
39
#include <ctype.h>
40
#include <errno.h>
41
#include <fcntl.h>
42
#include <netdb.h>
43
#include <pwd.h>
44
#include <setjmp.h>
45
#include <signal.h>
46
#include <stdio.h>
47
#include <strings.h>
48
#include <string.h>
49
#include <syslog.h>
50
#include <unistd.h>
51
52
#include "dma.h"
53
54
const char *
55
hostname(void)
56
{
57
#ifndef HOST_NAME_MAX
58
#define HOST_NAME_MAX 255
59
#endif
60
static char name[HOST_NAME_MAX+1];
61
static int initialized = 0;
62
char *s;
63
64
if (initialized)
65
return (name);
66
67
if (config.mailname == NULL || !*config.mailname)
68
goto local;
69
70
if (config.mailname[0] == '/') {
71
/*
72
* If the mailname looks like an absolute path,
73
* treat it as a file.
74
*/
75
FILE *fp;
76
77
fp = fopen(config.mailname, "r");
78
if (fp == NULL)
79
goto local;
80
81
s = fgets(name, sizeof(name), fp);
82
fclose(fp);
83
if (s == NULL)
84
goto local;
85
86
for (s = name; *s != 0 && (isalnum(*s) || strchr("_.-", *s)); ++s)
87
/* NOTHING */;
88
*s = 0;
89
90
if (!*name)
91
goto local;
92
93
initialized = 1;
94
return (name);
95
} else {
96
snprintf(name, sizeof(name), "%s", config.mailname);
97
initialized = 1;
98
return (name);
99
}
100
101
local:
102
snprintf(name, sizeof(name), "%s", systemhostname());
103
104
initialized = 1;
105
return (name);
106
}
107
108
const char *
109
systemhostname(void)
110
{
111
#ifndef HOST_NAME_MAX
112
#define HOST_NAME_MAX 255
113
#endif
114
static char name[HOST_NAME_MAX+1];
115
static int initialized = 0;
116
char *s;
117
118
if (initialized)
119
return (name);
120
121
if (gethostname(name, sizeof(name)) != 0)
122
*name = 0;
123
/*
124
* gethostname() is allowed to truncate name without NUL-termination
125
* and at the same time not return an error.
126
*/
127
name[sizeof(name) - 1] = 0;
128
129
for (s = name; *s != 0 && (isalnum(*s) || strchr("_.-", *s)); ++s)
130
/* NOTHING */;
131
*s = 0;
132
133
if (!*name)
134
snprintf(name, sizeof(name), "unknown-hostname");
135
136
initialized = 1;
137
return (name);
138
}
139
140
void
141
setlogident(const char *fmt, ...)
142
{
143
static char tag[50];
144
145
snprintf(tag, sizeof(tag), "%s", logident_base);
146
if (fmt != NULL) {
147
va_list ap;
148
char sufx[50];
149
150
va_start(ap, fmt);
151
vsnprintf(sufx, sizeof(sufx), fmt, ap);
152
va_end(ap);
153
snprintf(tag, sizeof(tag), "%s[%s]", logident_base, sufx);
154
}
155
closelog();
156
openlog(tag, 0, LOG_MAIL);
157
}
158
159
void
160
errlog(int exitcode, const char *fmt, ...)
161
{
162
int oerrno = errno;
163
va_list ap;
164
char outs[ERRMSG_SIZE];
165
166
outs[0] = 0;
167
if (fmt != NULL) {
168
va_start(ap, fmt);
169
vsnprintf(outs, sizeof(outs), fmt, ap);
170
va_end(ap);
171
}
172
173
errno = oerrno;
174
if (*outs != 0) {
175
syslog(LOG_ERR, "%s: %m", outs);
176
fprintf(stderr, "%s: %s: %s\n", getprogname(), outs, strerror(oerrno));
177
} else {
178
syslog(LOG_ERR, "%m");
179
fprintf(stderr, "%s: %s\n", getprogname(), strerror(oerrno));
180
}
181
182
exit(exitcode);
183
}
184
185
void
186
errlogx(int exitcode, const char *fmt, ...)
187
{
188
va_list ap;
189
char outs[ERRMSG_SIZE];
190
191
outs[0] = 0;
192
if (fmt != NULL) {
193
va_start(ap, fmt);
194
vsnprintf(outs, sizeof(outs), fmt, ap);
195
va_end(ap);
196
}
197
198
if (*outs != 0) {
199
syslog(LOG_ERR, "%s", outs);
200
fprintf(stderr, "%s: %s\n", getprogname(), outs);
201
} else {
202
syslog(LOG_ERR, "Unknown error");
203
fprintf(stderr, "%s: Unknown error\n", getprogname());
204
}
205
206
exit(exitcode);
207
}
208
209
static int
210
check_username(const char *name, uid_t ckuid)
211
{
212
struct passwd *pwd;
213
214
if (name == NULL)
215
return (0);
216
pwd = getpwnam(name);
217
if (pwd == NULL || pwd->pw_uid != ckuid)
218
return (0);
219
snprintf(username, sizeof(username), "%s", name);
220
return (1);
221
}
222
223
void
224
set_username(void)
225
{
226
struct passwd *pwd;
227
228
useruid = getuid();
229
if (check_username(getlogin(), useruid))
230
return;
231
if (check_username(getenv("LOGNAME"), useruid))
232
return;
233
if (check_username(getenv("USER"), useruid))
234
return;
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))
238
return;
239
}
240
snprintf(username, sizeof(username), "uid=%ld", (long)useruid);
241
}
242
243
void
244
deltmp(void)
245
{
246
struct stritem *t;
247
248
SLIST_FOREACH(t, &tmpfs, next) {
249
unlink(t->str);
250
}
251
}
252
253
static sigjmp_buf sigbuf;
254
static int sigbuf_valid;
255
256
static void
257
sigalrm_handler(int signo)
258
{
259
(void)signo; /* so that gcc doesn't complain */
260
if (sigbuf_valid)
261
siglongjmp(sigbuf, 1);
262
}
263
264
int
265
do_timeout(int timeout, int dojmp)
266
{
267
struct sigaction act;
268
int ret = 0;
269
270
sigemptyset(&act.sa_mask);
271
act.sa_flags = 0;
272
273
if (timeout) {
274
act.sa_handler = sigalrm_handler;
275
if (sigaction(SIGALRM, &act, NULL) != 0)
276
syslog(LOG_WARNING, "can not set signal handler: %m");
277
if (dojmp) {
278
ret = sigsetjmp(sigbuf, 1);
279
if (ret)
280
goto disable;
281
/* else just programmed */
282
sigbuf_valid = 1;
283
}
284
285
alarm(timeout);
286
} else {
287
disable:
288
alarm(0);
289
290
act.sa_handler = SIG_IGN;
291
if (sigaction(SIGALRM, &act, NULL) != 0)
292
syslog(LOG_WARNING, "can not remove signal handler: %m");
293
sigbuf_valid = 0;
294
}
295
296
return (ret);
297
}
298
299
int
300
open_locked(const char *fname, int flags, ...)
301
{
302
int mode = 0;
303
304
if (flags & O_CREAT) {
305
va_list ap;
306
va_start(ap, flags);
307
mode = va_arg(ap, int);
308
va_end(ap);
309
}
310
311
#ifndef O_EXLOCK
312
int fd, save_errno;
313
314
fd = open(fname, flags, mode);
315
if (fd < 0)
316
return(fd);
317
if (flock(fd, LOCK_EX|((flags & O_NONBLOCK)? LOCK_NB: 0)) < 0) {
318
save_errno = errno;
319
close(fd);
320
errno = save_errno;
321
return(-1);
322
}
323
return(fd);
324
#else
325
return(open(fname, flags|O_EXLOCK, mode));
326
#endif
327
}
328
329
char *
330
rfc822date(void)
331
{
332
static char str[50];
333
size_t error;
334
time_t now;
335
336
now = time(NULL);
337
error = strftime(str, sizeof(str), "%a, %d %b %Y %T %z",
338
localtime(&now));
339
if (error == 0)
340
strcpy(str, "(date fail)");
341
return (str);
342
}
343
344
int
345
strprefixcmp(const char *str, const char *prefix)
346
{
347
return (strncasecmp(str, prefix, strlen(prefix)));
348
}
349
350
void
351
init_random(void)
352
{
353
unsigned int seed;
354
int rf;
355
356
rf = open("/dev/urandom", O_RDONLY);
357
if (rf == -1)
358
rf = open("/dev/random", O_RDONLY);
359
360
if (!(rf != -1 && read(rf, &seed, sizeof(seed)) == sizeof(seed)))
361
seed = (time(NULL) ^ getpid()) + (uintptr_t)&seed;
362
363
srandom(seed);
364
365
if (rf != -1)
366
close(rf);
367
}
368
369