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