# 2.11BSD#431 - /usr/src/usr.sbin/lpr/recvjob.c

##### Functions

    chksize           X
    find_dev          X
    frecverr          X
    noresponse        X
    rcleanup          X
    read_number       X
    readfile          X
    readjob           X
    recvjob           X

##### Variables

    ddev              X
    dfd               X
    dfname            X
    minfree           X
    sp                X
    tfname            X

##### Macros

    ack               X

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

#### Defined functions

chksize defined in line 251; used 2 times

- in line 154, 175

find_dev defined in line 78; used 2 times

- in line 28, 68

frecverr defined in line 311; used 12 times

- in line 41-43(2), 58, 66, 104, 128, 163, 183, 202, 213, 227, 241

noresponse defined in line 236; used 1 times

- in line 228

rcleanup defined in line 296; used 6 times

- in line 35, 71-72(2), 136, 159, 314

read_number defined in line 276; used 2 times

- in line 29, 67

readfile defined in line 190; used 2 times

- in line 158, 180

readjob defined in line 112; used 1 times

- in line 74

recvjob defined in line 31; used 1 times

- in /usr/src/usr.sbin/lpr/lpd.c line 298

#### Defined variables

ddev defined in line 25; used 4 times

- in line 68-70(3), 255

dfd defined in line 26; used 8 times

- in line 69, 83, 90, 97, 103, 259-261(3)

dfname defined in line 23; used 8 times

- in line 179-180(2), 301-308(6)

minfree defined in line 24; used 2 times

- in line 67, 271

sccsid defined in line 8; never used
sp defined in line 19; used 1 times

- in line 20

tfname defined in line 22; used 9 times

- in line 152-165(7), 299-300(2)

#### Defined macros

ack defined in line 20; used 3 times

- in line 118, 203, 232

Last modified: 1994-01-11 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 1964 |