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