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