BSD 4_4_Lite2 release
[unix-history] / usr / src / usr.sbin / lpr / common_source / aux.c
CommitLineData
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__
49snprintf(char *str, size_t n, const char *fmt, ...)
50#else
51snprintf(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
73vsnprintf(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
89char *
90strerror(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
120char *
121strdup(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
143int
144daemon(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
177int
178setsid()
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
201vsyslog(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 */
241int
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 */
323static int
324chksize(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
363static char *
364find_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 */