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