|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1983 Regents of the University of California. ! 3: * All rights reserved. The Berkeley software License Agreement ! 4: * specifies the terms and conditions for redistribution. ! 5: */ ! 6: ! 7: #ifndef lint ! 8: static char sccsid[] = "@(#)recvjob.c 5.4 (Berkeley) 6/6/86"; ! 9: #endif not lint ! 10: ! 11: /* ! 12: * Receive printer jobs from the network, queue them and ! 13: * start the printer daemon. ! 14: */ ! 15: ! 16: #include "lp.h" ! 17: #include <sys/fs.h> ! 18: ! 19: char *sp = ""; ! 20: #define ack() (void) write(1, sp, 1); ! 21: ! 22: char tfname[40]; /* tmp copy of cf before linking */ ! 23: char dfname[40]; /* data files */ ! 24: int minfree; /* keep at least minfree blocks available */ ! 25: char *ddev; /* disk device (for checking free space) */ ! 26: int dfd; /* file system device descriptor */ ! 27: ! 28: char *find_dev(); ! 29: ! 30: recvjob() ! 31: { ! 32: struct stat stb; ! 33: char *bp = pbuf; ! 34: int status, rcleanup(); ! 35: ! 36: /* ! 37: * Perform lookup for printer name or abbreviation ! 38: */ ! 39: if ((status = pgetent(line, printer)) < 0) ! 40: frecverr("cannot open printer description file"); ! 41: else if (status == 0) ! 42: frecverr("unknown printer %s", printer); ! 43: if ((LF = pgetstr("lf", &bp)) == NULL) ! 44: LF = DEFLOGF; ! 45: if ((SD = pgetstr("sd", &bp)) == NULL) ! 46: SD = DEFSPOOL; ! 47: if ((LO = pgetstr("lo", &bp)) == NULL) ! 48: LO = DEFLOCK; ! 49: ! 50: (void) close(2); /* set up log file */ ! 51: if (open(LF, O_WRONLY|O_APPEND, 0664) < 0) { ! 52: syslog(LOG_ERR, "%s: %m", LF); ! 53: (void) open("/dev/null", O_WRONLY); ! 54: } ! 55: ! 56: if (chdir(SD) < 0) ! 57: frecverr("%s: %s: %m", printer, SD); ! 58: if (stat(LO, &stb) == 0) { ! 59: if (stb.st_mode & 010) { ! 60: /* queue is disabled */ ! 61: putchar('\1'); /* return error code */ ! 62: exit(1); ! 63: } ! 64: } else if (stat(SD, &stb) < 0) ! 65: frecverr("%s: %s: %m", printer, SD); ! 66: minfree = read_number("minfree"); ! 67: ddev = find_dev(stb.st_dev, S_IFBLK); ! 68: if ((dfd = open(ddev, O_RDONLY)) < 0) ! 69: syslog(LOG_WARNING, "%s: %s: %m", printer, ddev); ! 70: signal(SIGTERM, rcleanup); ! 71: signal(SIGPIPE, rcleanup); ! 72: ! 73: if (readjob()) ! 74: printjob(); ! 75: } ! 76: ! 77: char * ! 78: find_dev(dev, type) ! 79: register dev_t dev; ! 80: register int type; ! 81: { ! 82: register DIR *dfd = opendir("/dev"); ! 83: struct direct *dir; ! 84: struct stat stb; ! 85: char devname[MAXNAMLEN+6]; ! 86: char *dp; ! 87: ! 88: strcpy(devname, "/dev/"); ! 89: while ((dir = readdir(dfd))) { ! 90: strcpy(devname + 5, dir->d_name); ! 91: if (stat(devname, &stb)) ! 92: continue; ! 93: if ((stb.st_mode & S_IFMT) != type) ! 94: continue; ! 95: if (dev == stb.st_rdev) { ! 96: closedir(dfd); ! 97: dp = (char *)malloc(strlen(devname)+1); ! 98: strcpy(dp, devname); ! 99: return(dp); ! 100: } ! 101: } ! 102: closedir(dfd); ! 103: frecverr("cannot find device %d, %d", major(dev), minor(dev)); ! 104: /*NOTREACHED*/ ! 105: } ! 106: ! 107: /* ! 108: * Read printer jobs sent by lpd and copy them to the spooling directory. ! 109: * Return the number of jobs successfully transfered. ! 110: */ ! 111: readjob() ! 112: { ! 113: register int size, nfiles; ! 114: register char *cp; ! 115: ! 116: ack(); ! 117: nfiles = 0; ! 118: for (;;) { ! 119: /* ! 120: * Read a command to tell us what to do ! 121: */ ! 122: cp = line; ! 123: do { ! 124: if ((size = read(1, cp, 1)) != 1) { ! 125: if (size < 0) ! 126: frecverr("%s: Lost connection",printer); ! 127: return(nfiles); ! 128: } ! 129: } while (*cp++ != '\n'); ! 130: *--cp = '\0'; ! 131: cp = line; ! 132: switch (*cp++) { ! 133: case '\1': /* cleanup because data sent was bad */ ! 134: rcleanup(); ! 135: continue; ! 136: ! 137: case '\2': /* read cf file */ ! 138: size = 0; ! 139: while (*cp >= '0' && *cp <= '9') ! 140: size = size * 10 + (*cp++ - '0'); ! 141: if (*cp++ != ' ') ! 142: break; ! 143: /* ! 144: * host name has been authenticated, we use our ! 145: * view of the host name since we may be passed ! 146: * something different than what gethostbyaddr() ! 147: * returns ! 148: */ ! 149: strcpy(cp + 6, from); ! 150: strcpy(tfname, cp); ! 151: tfname[0] = 't'; ! 152: if (!chksize(size)) { ! 153: (void) write(1, "\2", 1); ! 154: continue; ! 155: } ! 156: if (!readfile(tfname, size)) { ! 157: rcleanup(); ! 158: continue; ! 159: } ! 160: if (link(tfname, cp) < 0) ! 161: frecverr("%s: %m", tfname); ! 162: (void) unlink(tfname); ! 163: tfname[0] = '\0'; ! 164: nfiles++; ! 165: continue; ! 166: ! 167: case '\3': /* read df file */ ! 168: size = 0; ! 169: while (*cp >= '0' && *cp <= '9') ! 170: size = size * 10 + (*cp++ - '0'); ! 171: if (*cp++ != ' ') ! 172: break; ! 173: if (!chksize(size)) { ! 174: (void) write(1, "\2", 1); ! 175: continue; ! 176: } ! 177: strcpy(dfname, cp); ! 178: (void) readfile(dfname, size); ! 179: continue; ! 180: } ! 181: frecverr("protocol screwup"); ! 182: } ! 183: } ! 184: ! 185: /* ! 186: * Read files send by lpd and copy them to the spooling directory. ! 187: */ ! 188: readfile(file, size) ! 189: char *file; ! 190: int size; ! 191: { ! 192: register char *cp; ! 193: char buf[BUFSIZ]; ! 194: register int i, j, amt; ! 195: int fd, err; ! 196: ! 197: fd = open(file, O_WRONLY|O_CREAT, FILMOD); ! 198: if (fd < 0) ! 199: frecverr("%s: %m", file); ! 200: ack(); ! 201: err = 0; ! 202: for (i = 0; i < size; i += BUFSIZ) { ! 203: amt = BUFSIZ; ! 204: cp = buf; ! 205: if (i + amt > size) ! 206: amt = size - i; ! 207: do { ! 208: j = read(1, cp, amt); ! 209: if (j <= 0) ! 210: frecverr("Lost connection"); ! 211: amt -= j; ! 212: cp += j; ! 213: } while (amt > 0); ! 214: amt = BUFSIZ; ! 215: if (i + amt > size) ! 216: amt = size - i; ! 217: if (write(fd, buf, amt) != amt) { ! 218: err++; ! 219: break; ! 220: } ! 221: } ! 222: (void) close(fd); ! 223: if (err) ! 224: frecverr("%s: write error", file); ! 225: if (noresponse()) { /* file sent had bad data in it */ ! 226: (void) unlink(file); ! 227: return(0); ! 228: } ! 229: ack(); ! 230: return(1); ! 231: } ! 232: ! 233: noresponse() ! 234: { ! 235: char resp; ! 236: ! 237: if (read(1, &resp, 1) != 1) ! 238: frecverr("Lost connection"); ! 239: if (resp == '\0') ! 240: return(0); ! 241: return(1); ! 242: } ! 243: ! 244: /* ! 245: * Check to see if there is enough space on the disk for size bytes. ! 246: * 1 == OK, 0 == Not OK. ! 247: */ ! 248: chksize(size) ! 249: int size; ! 250: { ! 251: struct stat stb; ! 252: register char *ddev; ! 253: int spacefree; ! 254: struct fs fs; ! 255: ! 256: if (dfd < 0 || lseek(dfd, (long)(SBLOCK * DEV_BSIZE), 0) < 0) ! 257: return(1); ! 258: if (read(dfd, (char *)&fs, sizeof fs) != sizeof fs) ! 259: return(1); ! 260: spacefree = (fs.fs_cstotal.cs_nbfree * fs.fs_frag + ! 261: fs.fs_cstotal.cs_nffree - fs.fs_dsize * fs.fs_minfree / 100) * ! 262: fs.fs_fsize / 1024; ! 263: size = (size + 1023) / 1024; ! 264: if (minfree + size > spacefree) ! 265: return(0); ! 266: return(1); ! 267: } ! 268: ! 269: read_number(fn) ! 270: char *fn; ! 271: { ! 272: char lin[80]; ! 273: register FILE *fp; ! 274: ! 275: if ((fp = fopen(fn, "r")) == NULL) ! 276: return (0); ! 277: if (fgets(lin, 80, fp) == NULL) { ! 278: fclose(fp); ! 279: return (0); ! 280: } ! 281: fclose(fp); ! 282: return (atoi(lin)); ! 283: } ! 284: ! 285: /* ! 286: * Remove all the files associated with the current job being transfered. ! 287: */ ! 288: rcleanup() ! 289: { ! 290: ! 291: if (tfname[0]) ! 292: (void) unlink(tfname); ! 293: if (dfname[0]) ! 294: do { ! 295: do ! 296: (void) unlink(dfname); ! 297: while (dfname[2]-- != 'A'); ! 298: dfname[2] = 'z'; ! 299: } while (dfname[0]-- != 'd'); ! 300: dfname[0] = '\0'; ! 301: } ! 302: ! 303: frecverr(msg, a1, a2) ! 304: char *msg; ! 305: { ! 306: rcleanup(); ! 307: syslog(LOG_ERR, msg, a1, a2); ! 308: putchar('\1'); /* return error code */ ! 309: exit(1); ! 310: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.