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
find_dev defined in line 78; used 2 times
frecverr defined in line 311; used 12 times
noresponse defined in line 236; used 1 times
rcleanup defined in line 296; used 6 times
read_number defined in line 276; used 2 times
readfile defined in line 190; used 2 times
readjob defined in line 112; used 1 times
  • in line 74
recvjob defined in line 31; used 1 times

Defined variables

ddev defined in line 25; used 4 times
dfd defined in line 26; used 8 times
dfname defined in line 23; used 8 times
minfree defined in line 24; used 2 times
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

Defined macros

ack defined in line 20; used 3 times
Last modified: 1994-01-11
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 4077
Valid CSS Valid XHTML 1.0 Strict