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

##### Functions

    abortpr           X
    banner            X
    dofork            X
    dropit            X
    init              X
    openpr            X
    print             X
    printit           X
    printjob          X
    response          X
    scan_out          X
    scnline           X
    sendfile          X
    sendit            X
    sendmail          X
    setty             X
    status            X

##### Variables

    bauds             X
    child             X
    class             X
    fdev              X
    fino              X
    fonts             X
    fromhost          X
    ifonts            X
    indent            X
    jobname           X
    length            X
    lfd               X
    logname           X
    ofd               X
    ofilter           X
    pfd               X
    pid               X
    prchild           X
    pxlength          X
    pxwidth           X
    remote            X
    title             X
    tmpfile           X
    tof               X
    width             X

##### Macros

    ACCESS            X
    DOABORT           X
    DORETURN          X
    ERROR             X
    FATALERR          X
    FILTERERR         X
    NOACCT            X
    OK                X
    REPRINT           X
    TRC               X

##### struct's

    bauds             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(lint) && defined(DOSCCS)
       8: static char sccsid[] = "@(#)printjob.c	5.2.3 (2.11BSD GTE) 1996/12/23";
       9: #endif
      10:
      11: /*
      12:  * printjob -- print jobs in the queue.
      13:  *
      14:  *	NOTE: the lock file is used to pass information to lpq and lprm.
      15:  *	it does not need to be removed because file locks are dynamic.
      16:  */
      17:
      18: #include "lp.h"
      19: #include <sys/time.h>
      20:
      21: #define DORETURN    0   /* absorb fork error */
      22: #define DOABORT     1   /* abort if dofork fails */
      23:
      24: /*
      25:  * Error tokens
      26:  */
      27: #define REPRINT     -2
      28: #define ERROR       -1
      29: #define OK      0
      30: #define FATALERR    1
      31: #define NOACCT      2
      32: #define FILTERERR   3
      33: #define ACCESS      4
      34:
      35: char    title[80];      /* ``pr'' title */
      36: FILE    *cfp;           /* control file */
      37: int pfd;            /* printer file descriptor */
      38: int ofd;            /* output filter file descriptor */
      39: int lfd;            /* lock file descriptor */
      40: int pid;            /* pid of lpd process */
      41: int prchild;        /* id of pr process */
      42: int child;          /* id of any filters */
      43: int ofilter;        /* id of output filter, if any */
      44: int tof;            /* true if at top of form */
      45: int remote;         /* true if sending files to remote */
      46: dev_t   fdev;           /* device of file pointed to by symlink */
      47: ino_t   fino;           /* inode of file pointed to by symlink */
      48:
      49: char    fromhost[64];       /* user's host machine */
      50: char    logname[32];        /* user's login name */
      51: char    jobname[100];       /* job or file name */
      52: char    class[32];      /* classification field */
      53: char    width[10] = "-w";   /* page width in characters */
      54: char    length[10] = "-l";  /* page length in lines */
      55: char    pxwidth[10] = "-x"; /* page width in pixels */
      56: char    pxlength[10] = "-y";    /* page length in pixels */
      57: char    indent[10] = "-i0"; /* indentation size in characters */
      58: char    tmpfile[] = "errsXXXXXX"; /* file name for filter output */
      59:
      60: printjob()
      61: {
      62:     struct stat stb;
      63:     register struct queue *q, **qp;
      64:     struct queue **queue;
      65:     register int i, nitems;
      66:     long pidoff;
      67:     int count = 0;
      68:     extern int abortpr();
      69:
      70:     init();                 /* set up capabilities */
      71:     (void) write(1, "", 1);         /* ack that daemon is started */
      72:     (void) close(2);            /* set up log file */
      73:     if (open(LF, O_WRONLY|O_APPEND, 0664) < 0) {
      74:         syslog(LOG_ERR, "%s: %m", LF);
      75:         (void) open("/dev/null", O_WRONLY);
      76:     }
      77:     setgid(getegid());
      78:     pid = getpid();             /* for use with lprm */
      79:     setpgrp(0, pid);
      80:     signal(SIGHUP, abortpr);
      81:     signal(SIGINT, abortpr);
      82:     signal(SIGQUIT, abortpr);
      83:     signal(SIGTERM, abortpr);
      84:
      85:     (void) mktemp(tmpfile);
      86:
      87:     /*
      88: 	 * uses short form file names
      89: 	 */
      90:     if (chdir(SD) < 0) {
      91:         syslog(LOG_ERR, "%s: %m", SD);
      92:         exit(1);
      93:     }
      94:     if (stat(LO, &stb) == 0 && (stb.st_mode & 0100))
      95:         exit(0);        /* printing disabled */
      96:     lfd = open(LO, O_WRONLY|O_CREAT, 0644);
      97:     if (lfd < 0) {
      98:         syslog(LOG_ERR, "%s: %s: %m", printer, LO);
      99:         exit(1);
     100:     }
     101:     if (flock(lfd, LOCK_EX|LOCK_NB) < 0) {
     102:         if (errno == EWOULDBLOCK)   /* active deamon present */
     103:             exit(0);
     104:         syslog(LOG_ERR, "%s: %s: %m", printer, LO);
     105:         exit(1);
     106:     }
     107:     ftruncate(lfd, 0L);
     108:     /*
     109: 	 * write process id for others to know
     110: 	 */
     111:     sprintf(line, "%u\n", pid);
     112:     pidoff = i = strlen(line);
     113:     if (write(lfd, line, i) != i) {
     114:         syslog(LOG_ERR, "%s: %s: %m", printer, LO);
     115:         exit(1);
     116:     }
     117:     /*
     118: 	 * search the spool directory for work and sort by queue order.
     119: 	 */
     120:     if ((nitems = getq(&queue)) < 0) {
     121:         syslog(LOG_ERR, "%s: can't scan %s", printer, SD);
     122:         exit(1);
     123:     }
     124:     if (nitems == 0)        /* no work to do */
     125:         exit(0);
     126:     if (stb.st_mode & 01) {     /* reset queue flag */
     127:         if (fchmod(lfd, stb.st_mode & 0776) < 0)
     128:             syslog(LOG_ERR, "%s: %s: %m", printer, LO);
     129:     }
     130:     openpr();           /* open printer or remote */
     131: again:
     132:     /*
     133: 	 * we found something to do now do it --
     134: 	 *    write the name of the current control file into the lock file
     135: 	 *    so the spool queue program can tell what we're working on
     136: 	 */
     137:     for (qp = queue; nitems--; free((char *) q)) {
     138:         q = *qp++;
     139:         if (stat(q->q_name, &stb) < 0)
     140:             continue;
     141:     restart:
     142:         (void) lseek(lfd, (off_t)pidoff, 0);
     143:         (void) sprintf(line, "%s\n", q->q_name);
     144:         i = strlen(line);
     145:         if (write(lfd, line, i) != i)
     146:             syslog(LOG_ERR, "%s: %s: %m", printer, LO);
     147:         if (!remote)
     148:             i = printit(q->q_name);
     149:         else
     150:             i = sendit(q->q_name);
     151:         /*
     152: 		 * Check to see if we are supposed to stop printing or
     153: 		 * if we are to rebuild the queue.
     154: 		 */
     155:         if (fstat(lfd, &stb) == 0) {
     156:             /* stop printing before starting next job? */
     157:             if (stb.st_mode & 0100)
     158:                 goto done;
     159:             /* rebuild queue (after lpc topq) */
     160:             if (stb.st_mode & 01) {
     161:                 for (free((char *) q); nitems--; free((char *) q))
     162:                     q = *qp++;
     163:                 if (fchmod(lfd, stb.st_mode & 0776) < 0)
     164:                     syslog(LOG_WARNING, "%s: %s: %m",
     165:                         printer, LO);
     166:                 break;
     167:             }
     168:         }
     169:         if (i == OK)        /* file ok and printed */
     170:             count++;
     171:         else if (i == REPRINT) { /* try reprinting the job */
     172:             syslog(LOG_INFO, "restarting %s", printer);
     173:             if (ofilter > 0) {
     174:                 kill(ofilter, SIGCONT); /* to be sure */
     175:                 (void) close(ofd);
     176:                 while ((i = wait(0)) > 0 && i != ofilter)
     177:                     ;
     178:                 ofilter = 0;
     179:             }
     180:             (void) close(pfd);  /* close printer */
     181:             if (ftruncate(lfd, (off_t)pidoff) < 0)
     182:                 syslog(LOG_WARNING, "%s: %s: %m", printer, LO);
     183:             openpr();       /* try to reopen printer */
     184:             goto restart;
     185:         }
     186:     }
     187:     free((char *) queue);
     188:     /*
     189: 	 * search the spool directory for more work.
     190: 	 */
     191:     if ((nitems = getq(&queue)) < 0) {
     192:         syslog(LOG_ERR, "%s: can't scan %s", printer, SD);
     193:         exit(1);
     194:     }
     195:     if (nitems == 0) {      /* no more work to do */
     196:     done:
     197:         if (count > 0) {    /* Files actually printed */
     198:             if (!SF && !tof)
     199:                 (void) write(ofd, FF, strlen(FF));
     200:             if (TR != NULL)     /* output trailer */
     201:                 (void) write(ofd, TR, strlen(TR));
     202:         }
     203:         (void) unlink(tmpfile);
     204:         exit(0);
     205:     }
     206:     goto again;
     207: }
     208:
     209: char    fonts[4][50];   /* fonts for troff */
     210:
     211: char *ifonts[4] = {
     212:     "/usr/share/vfont/R",
     213:     "/usr/share/vfont/I",
     214:     "/usr/share/vfont/B",
     215:     "/usr/share/vfont/S"
     216: };
     217:
     218: /*
     219:  * The remaining part is the reading of the control file (cf)
     220:  * and performing the various actions.
     221:  */
     222: printit(file)
     223:     char *file;
     224: {
     225:     register int i;
     226:     char *cp;
     227:     int bombed = OK;
     228:
     229:     /*
     230: 	 * open control file; ignore if no longer there.
     231: 	 */
     232:     if ((cfp = fopen(file, "r")) == NULL) {
     233:         syslog(LOG_INFO, "%s: %s: %m", printer, file);
     234:         return(OK);
     235:     }
     236:     /*
     237: 	 * Reset troff fonts.
     238: 	 */
     239:     for (i = 0; i < 4; i++)
     240:         strcpy(fonts[i], ifonts[i]);
     241:     sprintf(width+2, "%d", PW);
     242:     strcpy(indent+2, "0");
     243:
     244:     /*
     245: 	 *      read the control file for work to do
     246: 	 *
     247: 	 *      file format -- first character in the line is a command
     248: 	 *      rest of the line is the argument.
     249: 	 *      valid commands are:
     250: 	 *
     251: 	 *		S -- "stat info" for symbolic link protection
     252: 	 *		J -- "job name" on banner page
     253: 	 *		C -- "class name" on banner page
     254: 	 *              L -- "literal" user's name to print on banner
     255: 	 *		T -- "title" for pr
     256: 	 *		H -- "host name" of machine where lpr was done
     257: 	 *              P -- "person" user's login name
     258: 	 *              I -- "indent" amount to indent output
     259: 	 *              f -- "file name" name of text file to print
     260: 	 *		l -- "file name" text file with control chars
     261: 	 *		p -- "file name" text file to print with pr(1)
     262: 	 *		t -- "file name" troff(1) file to print
     263: 	 *		n -- "file name" ditroff(1) file to print
     264: 	 *		d -- "file name" dvi file to print
     265: 	 *		g -- "file name" plot(1G) file to print
     266: 	 *		v -- "file name" plain raster file to print
     267: 	 *		c -- "file name" cifplot file to print
     268: 	 *		1 -- "R font file" for troff
     269: 	 *		2 -- "I font file" for troff
     270: 	 *		3 -- "B font file" for troff
     271: 	 *		4 -- "S font file" for troff
     272: 	 *		N -- "name" of file (used by lpq)
     273: 	 *              U -- "unlink" name of file to remove
     274: 	 *                    (after we print it. (Pass 2 only)).
     275: 	 *		M -- "mail" to user when done printing
     276: 	 *
     277: 	 *      getline reads a line and expands tabs to blanks
     278: 	 */
     279:
     280:     /* pass 1 */
     281:
     282:     while (getline(cfp))
     283:         switch (line[0]) {
     284:         case 'H':
     285:             strcpy(fromhost, line+1);
     286:             if (class[0] == '\0')
     287:                 strncpy(class, line+1, sizeof(class)-1);
     288:             continue;
     289:
     290:         case 'P':
     291:             strncpy(logname, line+1, sizeof(logname)-1);
     292:             if (RS) {           /* restricted */
     293:                 if (getpwnam(logname) == (struct passwd *)0) {
     294:                     bombed = NOACCT;
     295:                     sendmail(line+1, bombed);
     296:                     goto pass2;
     297:                 }
     298:             }
     299:             continue;
     300:
     301:         case 'S':
     302:             cp = line+1;
     303:             i = 0;
     304:             while (*cp >= '0' && *cp <= '9')
     305:                 i = i * 10 + (*cp++ - '0');
     306:             fdev = i;
     307:             cp++;
     308:             i = 0;
     309:             while (*cp >= '0' && *cp <= '9')
     310:                 i = i * 10 + (*cp++ - '0');
     311:             fino = i;
     312:             continue;
     313:
     314:         case 'J':
     315:             if (line[1] != '\0')
     316:                 strncpy(jobname, line+1, sizeof(jobname)-1);
     317:             else
     318:                 strcpy(jobname, " ");
     319:             continue;
     320:
     321:         case 'C':
     322:             if (line[1] != '\0')
     323:                 strncpy(class, line+1, sizeof(class)-1);
     324:             else if (class[0] == '\0')
     325:                 gethostname(class, sizeof(class));
     326:             continue;
     327:
     328:         case 'T':   /* header title for pr */
     329:             strncpy(title, line+1, sizeof(title)-1);
     330:             continue;
     331:
     332:         case 'L':   /* identification line */
     333:             if (!SH && !HL)
     334:                 banner(line+1, jobname);
     335:             continue;
     336:
     337:         case '1':   /* troff fonts */
     338:         case '2':
     339:         case '3':
     340:         case '4':
     341:             if (line[1] != '\0')
     342:                 strcpy(fonts[line[0]-'1'], line+1);
     343:             continue;
     344:
     345:         case 'W':   /* page width */
     346:             strncpy(width+2, line+1, sizeof(width)-3);
     347:             continue;
     348:
     349:         case 'I':   /* indent amount */
     350:             strncpy(indent+2, line+1, sizeof(indent)-3);
     351:             continue;
     352:
     353:         default:    /* some file to print */
     354:             switch (i = print(line[0], line+1)) {
     355:             case ERROR:
     356:                 if (bombed == OK)
     357:                     bombed = FATALERR;
     358:                 break;
     359:             case REPRINT:
     360:                 (void) fclose(cfp);
     361:                 return(REPRINT);
     362:             case FILTERERR:
     363:             case ACCESS:
     364:                 bombed = i;
     365:                 sendmail(logname, bombed);
     366:             }
     367:             title[0] = '\0';
     368:             continue;
     369:
     370:         case 'N':
     371:         case 'U':
     372:         case 'M':
     373:             continue;
     374:         }
     375:
     376:     /* pass 2 */
     377:
     378: pass2:
     379:     fseek(cfp, 0L, 0);
     380:     while (getline(cfp))
     381:         switch (line[0]) {
     382:         case 'L':   /* identification line */
     383:             if (!SH && HL)
     384:                 banner(line+1, jobname);
     385:             continue;
     386:
     387:         case 'M':
     388:             if (bombed < NOACCT)    /* already sent if >= NOACCT */
     389:                 sendmail(line+1, bombed);
     390:             continue;
     391:
     392:         case 'U':
     393:             (void) unlink(line+1);
     394:         }
     395:     /*
     396: 	 * clean-up in case another control file exists
     397: 	 */
     398:     (void) fclose(cfp);
     399:     (void) unlink(file);
     400:     return(bombed == OK ? OK : ERROR);
     401: }
     402:
     403: /*
     404:  * Print a file.
     405:  * Set up the chain [ PR [ | {IF, OF} ] ] or {IF, RF, TF, NF, DF, CF, VF}.
     406:  * Return -1 if a non-recoverable error occured,
     407:  * 2 if the filter detected some errors (but printed the job anyway),
     408:  * 1 if we should try to reprint this job and
     409:  * 0 if all is well.
     410:  * Note: all filters take stdin as the file, stdout as the printer,
     411:  * stderr as the log file, and must not ignore SIGINT.
     412:  */
     413: print(format, file)
     414:     int format;
     415:     char *file;
     416: {
     417:     register int n;
     418:     register char *prog;
     419:     int fi, fo;
     420:     char *av[15], buf[BUFSIZ];
     421:     int pid, p[2], stopped = 0;
     422:     union wait status;
     423:     struct stat stb;
     424:
     425:     if (lstat(file, &stb) < 0 || (fi = open(file, O_RDONLY)) < 0)
     426:         return(ERROR);
     427:     /*
     428: 	 * Check to see if data file is a symbolic link. If so, it should
     429: 	 * still point to the same file or someone is trying to print
     430: 	 * something he shouldn't.
     431: 	 */
     432:     if ((stb.st_mode & S_IFMT) == S_IFLNK && fstat(fi, &stb) == 0 &&
     433:         (stb.st_dev != fdev || stb.st_ino != fino))
     434:         return(ACCESS);
     435:     if (!SF && !tof) {      /* start on a fresh page */
     436:         (void) write(ofd, FF, strlen(FF));
     437:         tof = 1;
     438:     }
     439:     if (IF == NULL && (format == 'f' || format == 'l')) {
     440:         tof = 0;
     441:         while ((n = read(fi, buf, BUFSIZ)) > 0)
     442:             if (write(ofd, buf, n) != n) {
     443:                 (void) close(fi);
     444:                 return(REPRINT);
     445:             }
     446:         (void) close(fi);
     447:         return(OK);
     448:     }
     449:     switch (format) {
     450:     case 'p':   /* print file using 'pr' */
     451:         if (IF == NULL) {   /* use output filter */
     452:             prog = PR;
     453:             av[0] = "pr";
     454:             av[1] = width;
     455:             av[2] = length;
     456:             av[3] = "-h";
     457:             av[4] = *title ? title : " ";
     458:             av[5] = 0;
     459:             fo = ofd;
     460:             goto start;
     461:         }
     462:         pipe(p);
     463:         if ((prchild = dofork(DORETURN)) == 0) {    /* child */
     464:             dup2(fi, 0);        /* file is stdin */
     465:             dup2(p[1], 1);      /* pipe is stdout */
     466:             for (n = 3; n < NOFILE; n++)
     467:                 (void) close(n);
     468:             execl(PR, "pr", width, length, "-h", *title ? title : " ", 0);
     469:             syslog(LOG_ERR, "cannot execl %s", PR);
     470:             exit(2);
     471:         }
     472:         (void) close(p[1]);     /* close output side */
     473:         (void) close(fi);
     474:         if (prchild < 0) {
     475:             prchild = 0;
     476:             (void) close(p[0]);
     477:             return(ERROR);
     478:         }
     479:         fi = p[0];          /* use pipe for input */
     480:     case 'f':   /* print plain text file */
     481:         prog = IF;
     482:         av[1] = width;
     483:         av[2] = length;
     484:         av[3] = indent;
     485:         n = 4;
     486:         break;
     487:     case 'l':   /* like 'f' but pass control characters */
     488:         prog = IF;
     489:         av[1] = "-c";
     490:         av[2] = width;
     491:         av[3] = length;
     492:         av[4] = indent;
     493:         n = 5;
     494:         break;
     495:     case 'r':   /* print a fortran text file */
     496:         prog = RF;
     497:         av[1] = width;
     498:         av[2] = length;
     499:         n = 3;
     500:         break;
     501:     case 't':   /* print troff output */
     502:     case 'n':   /* print ditroff output */
     503:     case 'd':   /* print tex output */
     504:         (void) unlink(".railmag");
     505:         if ((fo = creat(".railmag", FILMOD)) < 0) {
     506:             syslog(LOG_ERR, "%s: cannot create .railmag", printer);
     507:             (void) unlink(".railmag");
     508:         } else {
     509:             for (n = 0; n < 4; n++) {
     510:                 if (fonts[n][0] != '/')
     511:                     (void)write(fo, "/usr/share/vfont/",17);
     512:                 (void) write(fo, fonts[n], strlen(fonts[n]));
     513:                 (void) write(fo, "\n", 1);
     514:             }
     515:             (void) close(fo);
     516:         }
     517:         prog = (format == 't') ? TF : (format == 'n') ? NF : DF;
     518:         av[1] = pxwidth;
     519:         av[2] = pxlength;
     520:         n = 3;
     521:         break;
     522:     case 'c':   /* print cifplot output */
     523:         prog = CF;
     524:         av[1] = pxwidth;
     525:         av[2] = pxlength;
     526:         n = 3;
     527:         break;
     528:     case 'g':   /* print plot(1G) output */
     529:         prog = GF;
     530:         av[1] = pxwidth;
     531:         av[2] = pxlength;
     532:         n = 3;
     533:         break;
     534:     case 'v':   /* print raster output */
     535:         prog = VF;
     536:         av[1] = pxwidth;
     537:         av[2] = pxlength;
     538:         n = 3;
     539:         break;
     540:     default:
     541:         (void) close(fi);
     542:         syslog(LOG_ERR, "%s: illegal format character '%c'",
     543:             printer, format);
     544:         return(ERROR);
     545:     }
     546:     if ((av[0] = rindex(prog, '/')) != NULL)
     547:         av[0]++;
     548:     else
     549:         av[0] = prog;
     550:     av[n++] = "-n";
     551:     av[n++] = logname;
     552:     av[n++] = "-h";
     553:     av[n++] = fromhost;
     554:     av[n++] = AF;
     555:     av[n] = 0;
     556:     fo = pfd;
     557:     if (ofilter > 0) {      /* stop output filter */
     558:         write(ofd, "\031\1", 2);
     559:         while ((pid = wait3(&status, WUNTRACED, 0)) > 0 && pid != ofilter)
     560:             ;
     561:         if (status.w_stopval != WSTOPPED) {
     562:             (void) close(fi);
     563:             syslog(LOG_WARNING, "%s: output filter died (%d)",
     564:                 printer, status.w_retcode);
     565:             return(REPRINT);
     566:         }
     567:         stopped++;
     568:     }
     569: start:
     570:     if ((child = dofork(DORETURN)) == 0) {  /* child */
     571:         dup2(fi, 0);
     572:         dup2(fo, 1);
     573:         n = open(tmpfile, O_WRONLY|O_CREAT|O_TRUNC, 0664);
     574:         if (n >= 0)
     575:             dup2(n, 2);
     576:         for (n = 3; n < NOFILE; n++)
     577:             (void) close(n);
     578:         execv(prog, av);
     579:         syslog(LOG_ERR, "cannot execv %s", prog);
     580:         exit(2);
     581:     }
     582:     (void) close(fi);
     583:     if (child < 0)
     584:         status.w_retcode = 100;
     585:     else
     586:         while ((pid = wait(&status)) > 0 && pid != child)
     587:             ;
     588:     child = 0;
     589:     prchild = 0;
     590:     if (stopped) {      /* restart output filter */
     591:         if (kill(ofilter, SIGCONT) < 0) {
     592:             syslog(LOG_ERR, "cannot restart output filter");
     593:             exit(1);
     594:         }
     595:     }
     596:     tof = 0;
     597:     if (!WIFEXITED(status)) {
     598:         syslog(LOG_WARNING, "%s: Daemon filter '%c' terminated (%d)",
     599:             printer, format, status.w_termsig);
     600:         return(ERROR);
     601:     }
     602:     switch (status.w_retcode) {
     603:     case 0:
     604:         tof = 1;
     605:         return(OK);
     606:     case 1:
     607:         return(REPRINT);
     608:     default:
     609:         syslog(LOG_WARNING, "%s: Daemon filter '%c' exited (%d)",
     610:             printer, format, status.w_retcode);
     611:     case 2:
     612:         return(ERROR);
     613:     }
     614: }
     615:
     616: /*
     617:  * Send the daemon control file (cf) and any data files.
     618:  * Return -1 if a non-recoverable error occured, 1 if a recoverable error and
     619:  * 0 if all is well.
     620:  */
     621: sendit(file)
     622:     char *file;
     623: {
     624:     register int i, err = OK;
     625:     char *cp, last[BUFSIZ];
     626:
     627:     /*
     628: 	 * open control file
     629: 	 */
     630:     if ((cfp = fopen(file, "r")) == NULL)
     631:         return(OK);
     632:     /*
     633: 	 *      read the control file for work to do
     634: 	 *
     635: 	 *      file format -- first character in the line is a command
     636: 	 *      rest of the line is the argument.
     637: 	 *      commands of interest are:
     638: 	 *
     639: 	 *            a-z -- "file name" name of file to print
     640: 	 *              U -- "unlink" name of file to remove
     641: 	 *                    (after we print it. (Pass 2 only)).
     642: 	 */
     643:
     644:     /*
     645: 	 * pass 1
     646: 	 */
     647:     while (getline(cfp)) {
     648:     again:
     649:         if (line[0] == 'S') {
     650:             cp = line+1;
     651:             i = 0;
     652:             while (*cp >= '0' && *cp <= '9')
     653:                 i = i * 10 + (*cp++ - '0');
     654:             fdev = i;
     655:             cp++;
     656:             i = 0;
     657:             while (*cp >= '0' && *cp <= '9')
     658:                 i = i * 10 + (*cp++ - '0');
     659:             fino = i;
     660:             continue;
     661:         }
     662:         if (line[0] >= 'a' && line[0] <= 'z') {
     663:             strcpy(last, line);
     664:             while (i = getline(cfp))
     665:                 if (strcmp(last, line))
     666:                     break;
     667:             switch (sendfile('\3', last+1)) {
     668:             case OK:
     669:                 if (i)
     670:                     goto again;
     671:                 break;
     672:             case REPRINT:
     673:                 (void) fclose(cfp);
     674:                 return(REPRINT);
     675:             case ACCESS:
     676:                 sendmail(logname, ACCESS);
     677:             case ERROR:
     678:                 err = ERROR;
     679:             }
     680:             break;
     681:         }
     682:     }
     683:     if (err == OK && sendfile('\2', file) > 0) {
     684:         (void) fclose(cfp);
     685:         return(REPRINT);
     686:     }
     687:     /*
     688: 	 * pass 2
     689: 	 */
     690:     fseek(cfp, 0L, 0);
     691:     while (getline(cfp))
     692:         if (line[0] == 'U')
     693:             (void) unlink(line+1);
     694:     /*
     695: 	 * clean-up in case another control file exists
     696: 	 */
     697:     (void) fclose(cfp);
     698:     (void) unlink(file);
     699:     return(err);
     700: }
     701:
     702: /*
     703:  * Send a data file to the remote machine and spool it.
     704:  * Return positive if we should try resending.
     705:  */
     706: sendfile(type, file)
     707:     char type, *file;
     708: {
     709:     register int f, amt;
     710:     long i;
     711:     struct stat stb;
     712:     char buf[BUFSIZ];
     713:     int sizerr, resp;
     714:
     715:     if (lstat(file, &stb) < 0 || (f = open(file, O_RDONLY)) < 0)
     716:         return(ERROR);
     717:     /*
     718: 	 * Check to see if data file is a symbolic link. If so, it should
     719: 	 * still point to the same file or someone is trying to print something
     720: 	 * he shouldn't.
     721: 	 */
     722:     if ((stb.st_mode & S_IFMT) == S_IFLNK && fstat(f, &stb) == 0 &&
     723:         (stb.st_dev != fdev || stb.st_ino != fino))
     724:         return(ACCESS);
     725:     (void) sprintf(buf, "%c%ld %s\n", type, stb.st_size, file);
     726:     amt = strlen(buf);
     727:     for (i = 0;  ; i++) {
     728:         if (write(pfd, buf, amt) != amt ||
     729:             (resp = response()) < 0 || resp == '\1') {
     730:             (void) close(f);
     731:             return(REPRINT);
     732:         } else if (resp == '\0')
     733:             break;
     734:         if (i == 0)
     735:             status("no space on remote; waiting for queue to drain");
     736:         if (i == 10)
     737:             syslog(LOG_ALERT, "%s: can't send to %s; queue full",
     738:                 printer, RM);
     739:         sleep(5 * 60);
     740:     }
     741:     if (i)
     742:         status("sending to %s", RM);
     743:     sizerr = 0;
     744:     for (i = 0; i < stb.st_size; i += BUFSIZ) {
     745:         amt = BUFSIZ;
     746:         if (i + amt > stb.st_size)
     747:             amt = stb.st_size - i;
     748:         if (sizerr == 0 && read(f, buf, amt) != amt)
     749:             sizerr = 1;
     750:         if (write(pfd, buf, amt) != amt) {
     751:             (void) close(f);
     752:             return(REPRINT);
     753:         }
     754:     }
     755:     (void) close(f);
     756:     if (sizerr) {
     757:         syslog(LOG_INFO, "%s: %s: changed size", printer, file);
     758:         /* tell recvjob to ignore this file */
     759:         (void) write(pfd, "\1", 1);
     760:         return(ERROR);
     761:     }
     762:     if (write(pfd, "", 1) != 1 || response())
     763:         return(REPRINT);
     764:     return(OK);
     765: }
     766:
     767: /*
     768:  * Check to make sure there have been no errors and that both programs
     769:  * are in sync with eachother.
     770:  * Return non-zero if the connection was lost.
     771:  */
     772: response()
     773: {
     774:     char resp;
     775:
     776:     if (read(pfd, &resp, 1) != 1) {
     777:         syslog(LOG_INFO, "%s: lost connection", printer);
     778:         return(-1);
     779:     }
     780:     return(resp);
     781: }
     782:
     783: /*
     784:  * Banner printing stuff
     785:  */
     786: banner(name1, name2)
     787:     char *name1, *name2;
     788: {
     789:     time_t tvec;
     790:
     791:     time(&tvec);
     792:     if (!SF && !tof)
     793:         (void) write(ofd, FF, strlen(FF));
     794:     if (SB) {   /* short banner only */
     795:         if (class[0]) {
     796:             (void) write(ofd, class, strlen(class));
     797:             (void) write(ofd, ":", 1);
     798:         }
     799:         (void) write(ofd, name1, strlen(name1));
     800:         (void) write(ofd, "  Job: ", 7);
     801:         (void) write(ofd, name2, strlen(name2));
     802:         (void) write(ofd, "  Date: ", 8);
     803:         (void) write(ofd, ctime(&tvec), 24);
     804:         (void) write(ofd, "\n", 1);
     805:     } else {    /* normal banner */
     806:         (void) write(ofd, "\n\n\n", 3);
     807:         scan_out(ofd, name1, '\0');
     808:         (void) write(ofd, "\n\n", 2);
     809:         scan_out(ofd, name2, '\0');
     810:         if (class[0]) {
     811:             (void) write(ofd,"\n\n\n",3);
     812:             scan_out(ofd, class, '\0');
     813:         }
     814:         (void) write(ofd, "\n\n\n\n\t\t\t\t\tJob:  ", 15);
     815:         (void) write(ofd, name2, strlen(name2));
     816:         (void) write(ofd, "\n\t\t\t\t\tDate: ", 12);
     817:         (void) write(ofd, ctime(&tvec), 24);
     818:         (void) write(ofd, "\n", 1);
     819:     }
     820:     if (!SF)
     821:         (void) write(ofd, FF, strlen(FF));
     822:     tof = 1;
     823: }
     824:
     825: char *
     826: scnline(key, p, c)
     827:     register char key, *p;
     828:     char c;
     829: {
     830:     register scnwidth;
     831:
     832:     for (scnwidth = WIDTH; --scnwidth;) {
     833:         key <<= 1;
     834:         *p++ = key & 0200 ? c : BACKGND;
     835:     }
     836:     return (p);
     837: }
     838:
     839: #define TRC(q)  (((q)-' ')&0177)
     840:
     841: scan_out(scfd, scsp, dlm)
     842:     int scfd;
     843:     char *scsp, dlm;
     844: {
     845:     register char *strp;
     846:     register nchrs, j;
     847:     char outbuf[LINELEN+1], *sp, c, cc;
     848:     int d, scnhgt;
     849:     extern char scnkey[][HEIGHT];   /* in lpdchar.c */
     850:
     851:     for (scnhgt = 0; scnhgt++ < HEIGHT+DROP; ) {
     852:         strp = &outbuf[0];
     853:         sp = scsp;
     854:         for (nchrs = 0; ; ) {
     855:             d = dropit(c = TRC(cc = *sp++));
     856:             if ((!d && scnhgt > HEIGHT) || (scnhgt <= DROP && d))
     857:                 for (j = WIDTH; --j;)
     858:                     *strp++ = BACKGND;
     859:             else
     860:                 strp = scnline(scnkey[c][scnhgt-1-d], strp, cc);
     861:             if (*sp == dlm || *sp == '\0' || nchrs++ >= PW/(WIDTH+1)-1)
     862:                 break;
     863:             *strp++ = BACKGND;
     864:             *strp++ = BACKGND;
     865:         }
     866:         while (*--strp == BACKGND && strp >= outbuf)
     867:             ;
     868:         strp++;
     869:         *strp++ = '\n';
     870:         (void) write(scfd, outbuf, strp-outbuf);
     871:     }
     872: }
     873:
     874: dropit(c)
     875:     char c;
     876: {
     877:     switch(c) {
     878:
     879:     case TRC('_'):
     880:     case TRC(';'):
     881:     case TRC(','):
     882:     case TRC('g'):
     883:     case TRC('j'):
     884:     case TRC('p'):
     885:     case TRC('q'):
     886:     case TRC('y'):
     887:         return (DROP);
     888:
     889:     default:
     890:         return (0);
     891:     }
     892: }
     893:
     894: /*
     895:  * sendmail ---
     896:  *   tell people about job completion
     897:  */
     898: sendmail(user, bombed)
     899:     char *user;
     900:     int bombed;
     901: {
     902:     register int i;
     903:     int p[2], s;
     904:     register char *cp;
     905:     char buf[100];
     906:     struct stat stb;
     907:     FILE *fp;
     908:
     909:     pipe(p);
     910:     if ((s = dofork(DORETURN)) == 0) {      /* child */
     911:         dup2(p[0], 0);
     912:         for (i = 3; i < NOFILE; i++)
     913:             (void) close(i);
     914:         if ((cp = rindex(_PATH_SENDMAIL, '/')) != NULL)
     915:             cp++;
     916:         else
     917:             cp = _PATH_SENDMAIL;
     918:         sprintf(buf, "%s@%s", user, fromhost);
     919:         execl(_PATH_SENDMAIL, cp, buf, 0);
     920:         exit(0);
     921:     } else if (s > 0) {             /* parent */
     922:         dup2(p[1], 1);
     923:         printf("To: %s@%s\n", user, fromhost);
     924:         printf("Subject: printer job\n\n");
     925:         printf("Your printer job ");
     926:         if (*jobname)
     927:             printf("(%s) ", jobname);
     928:         switch (bombed) {
     929:         case OK:
     930:             printf("\ncompleted successfully\n");
     931:             break;
     932:         default:
     933:         case FATALERR:
     934:             printf("\ncould not be printed\n");
     935:             break;
     936:         case NOACCT:
     937:             printf("\ncould not be printed without an account on %s\n", host);
     938:             break;
     939:         case FILTERERR:
     940:             if (stat(tmpfile, &stb) < 0 || stb.st_size == 0 ||
     941:                 (fp = fopen(tmpfile, "r")) == NULL) {
     942:                 printf("\nwas printed but had some errors\n");
     943:                 break;
     944:             }
     945:             printf("\nwas printed but had the following errors:\n");
     946:             while ((i = getc(fp)) != EOF)
     947:                 putchar(i);
     948:             (void) fclose(fp);
     949:             break;
     950:         case ACCESS:
     951:             printf("\nwas not printed because it was not linked to the original file\n");
     952:         }
     953:         fflush(stdout);
     954:         (void) close(1);
     955:     }
     956:     (void) close(p[0]);
     957:     (void) close(p[1]);
     958:     wait(&s);
     959: }
     960:
     961: /*
     962:  * dofork - fork with retries on failure
     963:  */
     964: dofork(action)
     965:     int action;
     966: {
     967:     register int i, pid;
     968:
     969:     for (i = 0; i < 20; i++) {
     970:         if ((pid = fork()) < 0) {
     971:             sleep((unsigned)(i*i));
     972:             continue;
     973:         }
     974:         /*
     975: 		 * Child should run as daemon instead of root
     976: 		 */
     977:         if (pid == 0)
     978:             setuid(DU);
     979:         return(pid);
     980:     }
     981:     syslog(LOG_ERR, "can't fork");
     982:
     983:     switch (action) {
     984:     case DORETURN:
     985:         return (-1);
     986:     default:
     987:         syslog(LOG_ERR, "bad action (%d) to dofork", action);
     988:         /*FALL THRU*/
     989:     case DOABORT:
     990:         exit(1);
     991:     }
     992:     /*NOTREACHED*/
     993: }
     994:
     995: /*
     996:  * Kill child processes to abort current job.
     997:  */
     998: abortpr()
     999: {
    1000:     (void) unlink(tmpfile);
    1001:     kill(0, SIGINT);
    1002:     if (ofilter > 0)
    1003:         kill(ofilter, SIGCONT);
    1004:     while (wait(0) > 0)
    1005:         ;
    1006:     exit(0);
    1007: }
    1008:
    1009: init()
    1010: {
    1011:     int status;
    1012:
    1013:     if ((status = pgetent(line, printer)) < 0) {
    1014:         syslog(LOG_ERR, "can't open printer description file");
    1015:         exit(1);
    1016:     } else if (status == 0) {
    1017:         syslog(LOG_ERR, "unknown printer: %s", printer);
    1018:         exit(1);
    1019:     }
    1020:     if ((LP = pgetstr("lp", &bp)) == NULL)
    1021:         LP = DEFDEVLP;
    1022:     if ((RP = pgetstr("rp", &bp)) == NULL)
    1023:         RP = DEFLP;
    1024:     if ((LO = pgetstr("lo", &bp)) == NULL)
    1025:         LO = DEFLOCK;
    1026:     if ((ST = pgetstr("st", &bp)) == NULL)
    1027:         ST = DEFSTAT;
    1028:     if ((LF = pgetstr("lf", &bp)) == NULL)
    1029:         LF = DEFLOGF;
    1030:     if ((SD = pgetstr("sd", &bp)) == NULL)
    1031:         SD = DEFSPOOL;
    1032:     if ((DU = pgetnum("du")) < 0)
    1033:         DU = DEFUID;
    1034:     if ((FF = pgetstr("ff", &bp)) == NULL)
    1035:         FF = DEFFF;
    1036:     if ((PW = pgetnum("pw")) < 0)
    1037:         PW = DEFWIDTH;
    1038:     sprintf(&width[2], "%d", PW);
    1039:     if ((PL = pgetnum("pl")) < 0)
    1040:         PL = DEFLENGTH;
    1041:     sprintf(&length[2], "%d", PL);
    1042:     if ((PX = pgetnum("px")) < 0)
    1043:         PX = 0;
    1044:     sprintf(&pxwidth[2], "%d", PX);
    1045:     if ((PY = pgetnum("py")) < 0)
    1046:         PY = 0;
    1047:     sprintf(&pxlength[2], "%d", PY);
    1048:     RM = pgetstr("rm", &bp);
    1049:     /*
    1050: 	 * Figure out whether the local machine is the same as the remote
    1051: 	 * machine entry (if it exists).  If not, then ignore the local
    1052: 	 * queue information.
    1053: 	 */
    1054:      if (RM != (char *) NULL) {
    1055:         char name[256];
    1056:         struct hostent *hp;
    1057:
    1058:         /* get the standard network name of the local host */
    1059:         gethostname(name, sizeof(name));
    1060:         name[sizeof(name)-1] = '\0';
    1061:         hp = gethostbyname(name);
    1062:         if (hp == (struct hostent *) NULL) {
    1063:             syslog(LOG_ERR,
    1064:             "unable to get network name for local machine %s",
    1065:             name);
    1066:             goto localcheck_done;
    1067:         } else strcpy(name, hp->h_name);
    1068:
    1069:         /* get the standard network name of RM */
    1070:         hp = gethostbyname(RM);
    1071:         if (hp == (struct hostent *) NULL) {
    1072:             syslog(LOG_ERR,
    1073:             "unable to get hostname for remote machine %s", RM);
    1074:             goto localcheck_done;
    1075:         }
    1076:
    1077:         /* if printer is not on local machine, ignore LP */
    1078:         if (strcmp(name, hp->h_name) != 0) *LP = '\0';
    1079:     }
    1080: localcheck_done:
    1081:
    1082:     AF = pgetstr("af", &bp);
    1083:     OF = pgetstr("of", &bp);
    1084:     IF = pgetstr("if", &bp);
    1085:     RF = pgetstr("rf", &bp);
    1086:     TF = pgetstr("tf", &bp);
    1087:     NF = pgetstr("nf", &bp);
    1088:     DF = pgetstr("df", &bp);
    1089:     GF = pgetstr("gf", &bp);
    1090:     VF = pgetstr("vf", &bp);
    1091:     CF = pgetstr("cf", &bp);
    1092:     TR = pgetstr("tr", &bp);
    1093:     RS = pgetflag("rs");
    1094:     SF = pgetflag("sf");
    1095:     SH = pgetflag("sh");
    1096:     SB = pgetflag("sb");
    1097:     HL = pgetflag("hl");
    1098:     RW = pgetflag("rw");
    1099:     BR = pgetnum("br");
    1100:     if ((FC = pgetnum("fc")) < 0)
    1101:         FC = 0;
    1102:     if ((FS = pgetnum("fs")) < 0)
    1103:         FS = 0;
    1104:     if ((XC = pgetnum("xc")) < 0)
    1105:         XC = 0;
    1106:     if ((XS = pgetnum("xs")) < 0)
    1107:         XS = 0;
    1108:     tof = !pgetflag("fo");
    1109: }
    1110:
    1111: /*
    1112:  * Acquire line printer or remote connection.
    1113:  */
    1114: openpr()
    1115: {
    1116:     register int i, n;
    1117:     int resp;
    1118:
    1119:     if (*LP) {
    1120:         for (i = 1; ; i = i < 32 ? i << 1 : i) {
    1121:             pfd = open(LP, RW ? O_RDWR : O_WRONLY);
    1122:             if (pfd >= 0)
    1123:                 break;
    1124:             if (errno == ENOENT) {
    1125:                 syslog(LOG_ERR, "%s: %m", LP);
    1126:                 exit(1);
    1127:             }
    1128:             if (i == 1)
    1129:                 status("waiting for %s to become ready (offline ?)", printer);
    1130:             sleep(i);
    1131:         }
    1132:         if (isatty(pfd))
    1133:             setty();
    1134:         status("%s is ready and printing", printer);
    1135:     } else if (RM != NULL) {
    1136:         for (i = 1; ; i = i < 256 ? i << 1 : i) {
    1137:             resp = -1;
    1138:             pfd = getport(RM);
    1139:             if (pfd >= 0) {
    1140:                 (void) sprintf(line, "\2%s\n", RP);
    1141:                 n = strlen(line);
    1142:                 if (write(pfd, line, n) == n &&
    1143:                     (resp = response()) == '\0')
    1144:                     break;
    1145:                 (void) close(pfd);
    1146:             }
    1147:             if (i == 1) {
    1148:                 if (resp < 0)
    1149:                     status("waiting for %s to come up", RM);
    1150:                 else {
    1151:                     status("waiting for queue to be enabled on %s", RM);
    1152:                     i = 256;
    1153:                 }
    1154:             }
    1155:             sleep(i);
    1156:         }
    1157:         status("sending to %s", RM);
    1158:         remote = 1;
    1159:     } else {
    1160:         syslog(LOG_ERR, "%s: no line printer device or host name",
    1161:             printer);
    1162:         exit(1);
    1163:     }
    1164:     /*
    1165: 	 * Start up an output filter, if needed.
    1166: 	 */
    1167:     if (OF) {
    1168:         int p[2];
    1169:         char *cp;
    1170:
    1171:         pipe(p);
    1172:         if ((ofilter = dofork(DOABORT)) == 0) { /* child */
    1173:             dup2(p[0], 0);      /* pipe is std in */
    1174:             dup2(pfd, 1);       /* printer is std out */
    1175:             for (i = 3; i < NOFILE; i++)
    1176:                 (void) close(i);
    1177:             if ((cp = rindex(OF, '/')) == NULL)
    1178:                 cp = OF;
    1179:             else
    1180:                 cp++;
    1181:             execl(OF, cp, width, length, 0);
    1182:             syslog(LOG_ERR, "%s: %s: %m", printer, OF);
    1183:             exit(1);
    1184:         }
    1185:         (void) close(p[0]);     /* close input side */
    1186:         ofd = p[1];         /* use pipe for output */
    1187:     } else {
    1188:         ofd = pfd;
    1189:         ofilter = 0;
    1190:     }
    1191: }
    1192:
    1193: struct bauds {
    1194:     int baud;
    1195:     int speed;
    1196: } bauds[] = {
    1197:     50, B50,
    1198:     75, B75,
    1199:     110,    B110,
    1200:     134,    B134,
    1201:     150,    B150,
    1202:     200,    B200,
    1203:     300,    B300,
    1204:     600,    B600,
    1205:     1200,   B1200,
    1206:     1800,   B1800,
    1207:     2400,   B2400,
    1208:     4800,   B4800,
    1209:     9600,   B9600,
    1210:     19200,  EXTA,
    1211:     38400,  EXTB,
    1212:     0,  0
    1213: };
    1214:
    1215: /*
    1216:  * setup tty lines.
    1217:  */
    1218: setty()
    1219: {
    1220:     struct sgttyb ttybuf;
    1221:     register struct bauds *bp;
    1222:
    1223:     if (ioctl(pfd, TIOCEXCL, (char *)0) < 0) {
    1224:         syslog(LOG_ERR, "%s: ioctl(TIOCEXCL): %m", printer);
    1225:         exit(1);
    1226:     }
    1227:     if (ioctl(pfd, TIOCGETP, (char *)&ttybuf) < 0) {
    1228:         syslog(LOG_ERR, "%s: ioctl(TIOCGETP): %m", printer);
    1229:         exit(1);
    1230:     }
    1231:     if (BR > 0) {
    1232:         for (bp = bauds; bp->baud; bp++)
    1233:             if (BR == bp->baud)
    1234:                 break;
    1235:         if (!bp->baud) {
    1236:             syslog(LOG_ERR, "%s: illegal baud rate %d", printer, BR);
    1237:             exit(1);
    1238:         }
    1239:         ttybuf.sg_ispeed = ttybuf.sg_ospeed = bp->speed;
    1240:     }
    1241:     ttybuf.sg_flags &= ~FC;
    1242:     ttybuf.sg_flags |= FS;
    1243:     if (ioctl(pfd, TIOCSETP, (char *)&ttybuf) < 0) {
    1244:         syslog(LOG_ERR, "%s: ioctl(TIOCSETP): %m", printer);
    1245:         exit(1);
    1246:     }
    1247:     if (XC || XS) {
    1248:         int ldisc = NTTYDISC;
    1249:
    1250:         if (ioctl(pfd, TIOCSETD, &ldisc) < 0) {
    1251:             syslog(LOG_ERR, "%s: ioctl(TIOCSETD): %m", printer);
    1252:             exit(1);
    1253:         }
    1254:     }
    1255:     if (XC) {
    1256:         if (ioctl(pfd, TIOCLBIC, &XC) < 0) {
    1257:             syslog(LOG_ERR, "%s: ioctl(TIOCLBIC): %m", printer);
    1258:             exit(1);
    1259:         }
    1260:     }
    1261:     if (XS) {
    1262:         if (ioctl(pfd, TIOCLBIS, &XS) < 0) {
    1263:             syslog(LOG_ERR, "%s: ioctl(TIOCLBIS): %m", printer);
    1264:             exit(1);
    1265:         }
    1266:     }
    1267: }
    1268:
    1269: /*VARARGS1*/
    1270: status(msg, a1, a2, a3)
    1271:     char *msg;
    1272: {
    1273:     register int fd;
    1274:     char buf[BUFSIZ];
    1275:
    1276:     umask(0);
    1277:     fd = open(ST, O_WRONLY|O_CREAT, 0664);
    1278:     if (fd < 0 || flock(fd, LOCK_EX) < 0) {
    1279:         syslog(LOG_ERR, "%s: %s: %m", printer, ST);
    1280:         exit(1);
    1281:     }
    1282:     ftruncate(fd, 0L);
    1283:     sprintf(buf, msg, a1, a2, a3);
    1284:     strcat(buf, "\n");
    1285:     (void) write(fd, buf, strlen(buf));
    1286:     (void) close(fd);
    1287: }

#### Defined functions

abortpr defined in line 998; used 5 times

- in line 68, 80-83(4)

banner defined in line 786; used 2 times

- in line 334, 384

dofork defined in line 964; used 4 times

- in line 463, 570, 910, 1172

dropit defined in line 874; used 1 times

- in line 855

init defined in line 1009; used 1 times

- in line 70

openpr defined in line 1114; used 2 times

- in line 130, 183

print defined in line 413; used 1 times

- in line 354

printit defined in line 222; used 1 times

- in line 148

printjob defined in line 60; used 3 times

- in /usr/src/usr.sbin/lpr/lpd.c line 294, 388
- in /usr/src/usr.sbin/lpr/recvjob.c line 75

response defined in line 772; used 3 times

- in line 729, 762, 1143

scan_out defined in line 841; used 3 times

- in line 807-812(3)

scnline defined in line 825; used 1 times

- in line 860

sendfile defined in line 706; used 2 times

- in line 667, 683

sendit defined in line 621; used 1 times

- in line 150

sendmail defined in line 898; used 4 times

- in line 295, 365, 389, 676

setty defined in line 1218; used 1 times

- in line 1133

status defined in line 1270; used 20 times

- in line 422, 559-564(3), 584-586(2), 597-602(3), 610, 735, 742, 1011-1016(3), 1129-1134(2), 1149-1151(2), 1157

#### Defined variables

bauds defined in line 1196; used 1 times

- in line 1232

child defined in line 42; used 4 times

- in line 570, 583-588(3)

class defined in line 52; used 13 times

- in line 286-287(3), 323-325(5), 795-796(3), 810-812(2)

fdev defined in line 46; used 4 times

- in line 306, 433, 654, 723

fino defined in line 47; used 4 times

- in line 311, 433, 659, 723

fonts defined in line 209; used 5 times

- in line 240, 342, 510-512(3)

fromhost defined in line 49; used 4 times

- in line 285, 553, 918-923(2)

ifonts defined in line 211; used 1 times

- in line 240

indent defined in line 57; used 5 times

- in line 242, 350(2), 484, 492

jobname defined in line 51; used 7 times

- in line 316-318(3), 334, 384, 926-927(2)

length defined in line 54; used 7 times

- in line 455, 468, 483, 491, 498, 1041, 1181

lfd defined in line 39; used 11 times

- in line 96-101(3), 107, 113, 127, 142-145(2), 155, 163, 181

logname defined in line 50; used 6 times

- in line 291-293(3), 365, 551, 676

ofd defined in line 38; used 30 times

- in line 175, 199-201(2), 436, 442, 459, 558, 793-821(21), 1186-1188(2)

ofilter defined in line 43; used 11 times

- in line 173-178(4), 557-559(2), 591, 1002-1003(2), 1172, 1189

pfd defined in line 37; used 22 times

- in line 180, 556, 728, 750, 759-762(2), 776, 1121-1122(2), 1132, 1138-1145(4), 1174, 1188, 1223-1227(2), 1243, 1250, 1256, 1262

pid defined in line 40; used 12 times

- in line 78-79(2), 111, 421, 559(2), 586(2), 967-970(2), 977-979(2)

prchild defined in line 41; used 4 times

- in line 463, 474-475(2), 589

pxlength defined in line 56; used 5 times

- in line 519, 525, 531, 537, 1047

pxwidth defined in line 55; used 5 times

- in line 518, 524, 530, 536, 1044

remote defined in line 45; used 2 times

- in line 147, 1158

sccsid defined in line 8; never used
title defined in line 35; used 7 times

- in line 329(2), 367, 457(2), 468(2)

tmpfile defined in line 58; used 6 times

- in line 85, 203, 573, 940-941(2), 1000

tof defined in line 44; used 9 times

- in line 198, 435-440(3), 596, 604, 792, 822, 1108

width defined in line 53; used 10 times

- in line 241, 346(2), 454, 468, 482, 490, 497, 1038, 1181

#### Defined struct's

bauds defined in line 1193; used 2 times

- in line 1221(2)

#### Defined macros

ACCESS defined in line 33; used 3 times

- in line 434, 676, 724

DOABORT defined in line 22; used 1 times

- in line 1172

DORETURN defined in line 21; used 3 times

- in line 463, 570, 910

ERROR defined in line 28; used 9 times

- in line 400, 426, 477, 544, 600, 612, 678, 716, 760

FATALERR defined in line 30; used 1 times

- in line 357

FILTERERR defined in line 32; never used
NOACCT defined in line 31; used 2 times

- in line 294, 388

OK defined in line 29; used 12 times

- in line 169, 227, 234, 356, 400(2), 447, 605, 624, 631, 683, 764

REPRINT defined in line 27; used 10 times

- in line 171, 361, 444, 565, 607, 674, 685, 731, 752, 763

TRC defined in line 839; used 9 times

- in line 855, 879-886(8)

Last modified: 1996-12-23 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 4667 |