Annotation of 43BSDTahoe/usr.lib/lpr/recvjob.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.