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

unix.superglobalmegacorp.com

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