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