Annotation of 43BSDReno/usr.sbin/lpr/lpd/recvjob.c, revision 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.