Commit | Line | Data |
---|---|---|
fe7974eb | 1 | /* |
6073de20 TF |
2 | * Copyright (c) 1995 |
3 | * The Regents of the University of California. All rights reserved. | |
fe7974eb | 4 | * |
fd88f5c5 C |
5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions | |
7 | * are met: | |
8 | * 1. Redistributions of source code must retain the above copyright | |
9 | * notice, this list of conditions and the following disclaimer. | |
10 | * 2. Redistributions in binary form must reproduce the above copyright | |
11 | * notice, this list of conditions and the following disclaimer in the | |
12 | * documentation and/or other materials provided with the distribution. | |
13 | * 3. All advertising materials mentioning features or use of this software | |
14 | * must display the following acknowledgement: | |
15 | * This product includes software developed by the University of | |
16 | * California, Berkeley and its contributors. | |
17 | * 4. Neither the name of the University nor the names of its contributors | |
18 | * may be used to endorse or promote products derived from this software | |
19 | * without specific prior written permission. | |
20 | * | |
21 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | |
22 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
23 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
24 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | |
25 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
26 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
27 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
28 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
29 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
30 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
31 | * SUCH DAMAGE. | |
fe7974eb TF |
32 | */ |
33 | ||
6073de20 TF |
34 | /* |
35 | * Auxillary functions to aid portability to other systems. | |
36 | * These are 4.4BSD routines that are often not found on other systems. | |
fe7974eb | 37 | * |
6073de20 | 38 | * !!!USE THIS FILE ONLY IF YOU ARE NOT RUNNING 4.4BSD!!! |
fe7974eb TF |
39 | */ |
40 | ||
6073de20 TF |
41 | #if __STDC__ |
42 | #include <stdarg.h> | |
43 | #else | |
44 | #include <varargs.h> | |
45 | #endif | |
46 | ||
fe7974eb TF |
47 | #ifdef NO_SNPRINTF |
48 | #if __STDC__ | |
49 | snprintf(char *str, size_t n, const char *fmt, ...) | |
50 | #else | |
51 | snprintf(str, n, fmt, va_alist) | |
52 | char *str; | |
53 | size_t n; | |
54 | char *fmt; | |
55 | va_dcl | |
56 | #endif | |
57 | { | |
58 | int ret; | |
59 | va_list ap; | |
60 | ||
61 | #if __STDC__ | |
62 | va_start(ap, fmt); | |
63 | #else | |
64 | va_start(ap); | |
65 | #endif | |
66 | ret = vsprintf(str, fmt, ap); | |
67 | va_end(ap); | |
68 | if (strlen(str) > n) | |
69 | fatal("memory corrupted"); | |
70 | return (ret); | |
71 | } | |
72 | ||
73 | vsnprintf(str, n, fmt, ap) | |
74 | char *str; | |
75 | size_t n; | |
76 | char *fmt; | |
77 | va_list ap; | |
78 | { | |
79 | int ret; | |
80 | ||
81 | ret = vsprintf(str, fmt, ap); | |
82 | if (strlen(str) > n) | |
83 | fatal("memory corrupted"); | |
84 | return (ret); | |
85 | } | |
86 | #endif | |
87 | ||
88 | #ifdef NO_STRERROR | |
89 | char * | |
90 | strerror(num) | |
91 | int num; | |
92 | { | |
93 | extern int sys_nerr; | |
94 | extern char *sys_errlist[]; | |
95 | #define UPREFIX "Unknown error: " | |
96 | static char ebuf[40] = UPREFIX; /* 64-bit number + slop */ | |
97 | register unsigned int errnum; | |
98 | register char *p, *t; | |
99 | char tmp[40]; | |
100 | ||
101 | errnum = num; /* convert to unsigned */ | |
102 | if (errnum < sys_nerr) | |
103 | return(sys_errlist[errnum]); | |
104 | ||
105 | /* Do this by hand, so we don't include stdio(3). */ | |
106 | t = tmp; | |
107 | do { | |
108 | *t++ = "0123456789"[errnum % 10]; | |
109 | } while (errnum /= 10); | |
110 | for (p = ebuf + sizeof(UPREFIX) - 1;;) { | |
111 | *p++ = *--t; | |
112 | if (t <= tmp) | |
113 | break; | |
114 | } | |
115 | return(ebuf); | |
116 | } | |
117 | #endif | |
118 | ||
119 | #ifdef NO_STRDUP | |
120 | char * | |
121 | strdup(str) | |
122 | char *str; | |
123 | { | |
124 | int n; | |
125 | char *sp; | |
126 | ||
127 | n = strlen(str) + 1; | |
128 | if (sp = (char *) malloc(n)) | |
129 | memcpy(sp, str, n); | |
130 | return (sp); | |
131 | } | |
132 | #endif | |
133 | ||
134 | #ifdef NO_DAEMON | |
135 | #include <fcntl.h> | |
136 | #include <paths.h> | |
137 | #include <unistd.h> | |
138 | #include <sgtty.h> | |
139 | #define STDIN_FILENO 0 | |
140 | #define STDOUT_FILENO 1 | |
141 | #define STDERR_FILENO 2 | |
142 | ||
143 | int | |
144 | daemon(nochdir, noclose) | |
145 | int nochdir, noclose; | |
146 | { | |
147 | int fd; | |
148 | ||
149 | switch (fork()) { | |
150 | case -1: | |
151 | return (-1); | |
152 | case 0: | |
153 | break; | |
154 | default: | |
155 | _exit(0); | |
156 | } | |
157 | ||
158 | if (setsid() == -1) | |
159 | return (-1); | |
160 | ||
161 | if (!nochdir) | |
162 | (void)chdir("/"); | |
163 | ||
164 | if (!noclose && (fd = open(_PATH_DEVNULL, O_RDWR, 0)) != -1) { | |
165 | (void)dup2(fd, STDIN_FILENO); | |
166 | (void)dup2(fd, STDOUT_FILENO); | |
167 | (void)dup2(fd, STDERR_FILENO); | |
168 | if (fd > 2) | |
169 | (void)close (fd); | |
170 | } | |
171 | return (0); | |
172 | } | |
173 | #endif | |
174 | ||
175 | ||
176 | #ifdef NO_SETSID | |
177 | int | |
178 | setsid() | |
179 | { | |
180 | int f; | |
181 | ||
182 | f = open("/dev/tty", O_RDWR); | |
183 | if (f > 0) { | |
184 | ioctl(f, TIOCNOTTY, 0); | |
185 | (void) close(f); | |
186 | } | |
187 | return f; | |
188 | } | |
189 | #endif | |
190 | ||
191 | ||
192 | #ifdef NO_VSYSLOG | |
193 | #include <stdio.h> | |
194 | #include <errno.h> | |
195 | #if __STDC__ | |
196 | #include <stdarg.h> | |
197 | #else | |
198 | #include <varargs.h> | |
199 | #endif | |
200 | ||
201 | vsyslog(pri, fmt, ap) | |
202 | int pri; | |
203 | const char *fmt; | |
204 | va_list ap; | |
205 | { | |
206 | char buf[2048], fmt_cpy[1024]; | |
207 | ||
208 | /* substitute error message for %m */ | |
209 | { | |
210 | register char ch, *t1, *t2; | |
211 | char *strerror(); | |
212 | ||
213 | for (t1 = fmt_cpy; ch = *fmt; ++fmt) | |
214 | if (ch == '%' && fmt[1] == 'm') { | |
215 | ++fmt; | |
216 | for (t2 = strerror(errno); | |
217 | *t1 = *t2++; ++t1); | |
218 | } | |
219 | else | |
220 | *t1++ = ch; | |
221 | *t1 = '\0'; | |
222 | } | |
223 | vsprintf(buf, fmt_cpy, ap); | |
224 | syslog(pri, "%s", buf); | |
225 | } | |
226 | #endif | |
227 | ||
228 | ||
229 | #ifdef NO_IVALIDUSER | |
230 | #include <stdio.h> | |
231 | #include <ctype.h> | |
232 | #include <netdb.h> | |
233 | #include <netinet/in.h> | |
234 | #include <sys/types.h> | |
235 | #include <sys/param.h> | |
236 | #include "pathnames.h" | |
237 | ||
238 | /* | |
239 | * Returns 0 if ok, -1 if not ok. | |
240 | */ | |
241 | int | |
242 | __ivaliduser(hostf, raddr, luser, ruser) | |
243 | FILE *hostf; | |
244 | struct in_addr raddr; | |
245 | const char *luser, *ruser; | |
246 | { | |
247 | register char *user, *p; | |
248 | int ch; | |
249 | char buf[MAXHOSTNAMELEN + 128]; /* host + login */ | |
250 | ||
251 | while (fgets(buf, sizeof(buf), hostf)) { | |
252 | p = buf; | |
253 | /* Skip lines that are too long. */ | |
254 | if (strchr(p, '\n') == NULL) { | |
255 | while ((ch = getc(hostf)) != '\n' && ch != EOF); | |
256 | continue; | |
257 | } | |
258 | while (*p != '\n' && *p != ' ' && *p != '\t' && *p != '\0') { | |
259 | *p = isupper(*p) ? tolower(*p) : *p; | |
260 | p++; | |
261 | } | |
262 | if (*p == ' ' || *p == '\t') { | |
263 | *p++ = '\0'; | |
264 | while (*p == ' ' || *p == '\t') | |
265 | p++; | |
266 | user = p; | |
267 | while (*p != '\n' && *p != ' ' && | |
268 | *p != '\t' && *p != '\0') | |
269 | p++; | |
270 | } else | |
271 | user = p; | |
272 | *p = '\0'; | |
273 | if (__icheckhost(raddr, buf) && | |
274 | strcmp(ruser, *user ? user : luser) == 0) { | |
275 | return (0); | |
276 | } | |
277 | } | |
278 | return (-1); | |
279 | } | |
280 | ||
281 | /* | |
282 | * Returns "true" if match, 0 if no match. | |
283 | */ | |
284 | __icheckhost(raddr, lhost) | |
285 | struct in_addr raddr; | |
286 | register char *lhost; | |
287 | { | |
288 | register struct hostent *hp; | |
289 | struct in_addr laddr; | |
290 | register char **pp; | |
291 | ||
292 | /* Try for raw ip address first. */ | |
293 | if (isdigit(*lhost) && (laddr.s_addr = inet_addr(lhost)) != INADDR_NONE) | |
294 | return (raddr.s_addr == laddr.s_addr); | |
295 | ||
296 | /* Better be a hostname. */ | |
297 | if ((hp = gethostbyname(lhost)) == NULL) | |
298 | return (0); | |
299 | ||
300 | /* Spin through ip addresses. */ | |
301 | for (pp = hp->h_addr_list; *pp; ++pp) | |
302 | if (!bcmp(&raddr, *pp, sizeof(struct in_addr))) | |
303 | return (1); | |
304 | ||
305 | /* No match. */ | |
306 | return (0); | |
307 | } | |
308 | #endif /* NO_IVALIDUSER */ | |
309 | ||
310 | ||
311 | #ifdef NO_STATFS | |
312 | #include <sys/types.h> | |
313 | #include <sys/file.h> | |
314 | #include <sys/stat.h> | |
315 | #include <sys/dir.h> | |
316 | #include <sys/param.h> | |
317 | #include <ufs/fs.h> | |
318 | ||
319 | /* | |
320 | * Check to see if there is enough space on the disk for size bytes. | |
321 | * 1 == OK, 0 == Not OK. | |
322 | */ | |
323 | static int | |
324 | chksize(size) | |
325 | int size; | |
326 | { | |
327 | struct stat stb; | |
328 | int spacefree; | |
329 | struct fs fs; | |
330 | static int dfd; | |
331 | static char *find_dev(); | |
332 | ||
333 | #ifndef SBOFF | |
334 | #define SBOFF ((off_t)(BBSIZE)) | |
335 | #endif | |
336 | if (dfd <= 0) { | |
337 | char *ddev; | |
338 | ||
339 | if (stat(".", &stb) < 0) { | |
340 | syslog(LOG_ERR, "%s: %m", "statfs(\".\")"); | |
341 | return (1); | |
342 | } | |
343 | ddev = find_dev(stb.st_dev, S_IFBLK); | |
344 | if ((dfd = open(ddev, O_RDONLY)) < 0) { | |
345 | syslog(LOG_WARNING, "%s: %s: %m", printer, ddev); | |
346 | return (1); | |
347 | } | |
348 | } | |
349 | if (lseek(dfd, (off_t)(SBOFF), 0) < 0) | |
350 | return(1); | |
351 | if (read(dfd, (char *)&fs, sizeof fs) != sizeof fs | |
352 | || fs.fs_magic != FS_MAGIC) { | |
353 | syslog(LOG_ERR, "Can't calculate free space on spool device"); | |
354 | return(1); | |
355 | } | |
356 | spacefree = freespace(&fs, fs.fs_minfree) * fs.fs_fsize / 512; | |
357 | size = (size + 511) / 512; | |
358 | if (minfree + size > spacefree) | |
359 | return(0); | |
360 | return(1); | |
361 | } | |
362 | ||
363 | static char * | |
364 | find_dev(dev, type) | |
365 | register dev_t dev; | |
366 | register int type; | |
367 | { | |
368 | register DIR *dfd; | |
369 | struct direct *dir; | |
370 | struct stat stb; | |
371 | char devname[MAXNAMLEN+6]; | |
372 | char *dp; | |
373 | int n; | |
374 | ||
375 | strcpy(devname, "/dev/dsk"); | |
376 | if ((dfd = opendir(devname)) == NULL) { | |
377 | strcpy(devname, "/dev"); | |
378 | dfd = opendir(devname); | |
379 | } | |
380 | strcat(devname, "/"); | |
381 | n = strlen(devname); | |
382 | ||
383 | while ((dir = readdir(dfd))) { | |
384 | strcpy(devname + n, dir->d_name); | |
385 | if (stat(devname, &stb)) | |
386 | continue; | |
387 | if ((stb.st_mode & S_IFMT) != type) | |
388 | continue; | |
389 | if (dev == stb.st_rdev) { | |
390 | closedir(dfd); | |
391 | dp = (char *)malloc(strlen(devname)+1); | |
392 | strcpy(dp, devname); | |
393 | return(dp); | |
394 | } | |
395 | } | |
396 | closedir(dfd); | |
397 | frecverr("cannot find device %d, %d", major(dev), minor(dev)); | |
398 | /*NOTREACHED*/ | |
399 | } | |
400 | #endif /* NOSTATFS */ |