xref: /dragonfly/libexec/dma/util.c (revision 92fc8b5c)
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 
46 const char *
47 hostname(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 
85 void
86 setlogident(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 
106 void
107 errlog(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 
130 void
131 errlogx(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 
153 static const char *
154 check_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 
166 void
167 set_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 
198 void
199 deltmp(void)
200 {
201 	struct stritem *t;
202 
203 	SLIST_FOREACH(t, &tmpfs, next) {
204 		unlink(t->str);
205 	}
206 }
207 
208 int
209 open_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 
238 char *
239 rfc822date(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 
253 int
254 strprefixcmp(const char *str, const char *prefix)
255 {
256 	return (strncasecmp(str, prefix, strlen(prefix)));
257 }
258 
259