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