cck@cunixc.columbia.EDU (Charlie C. Kim) (01/26/88)
The input filter is supposed to process a file called ".banner" created by the output filter. papif doesn't process the .banner file. lnof doesn't create one. To do things correctly, papif needs to be modified. (The banner should go down in the same job stream to prevent interleaving of pages from other jobs). Transcript's psbanner program can be used, but some care needs to be taken (with all the transcript programs). This is a very very low priority here since we have policy of no text printing unless absolutely necessary on our LaserWriter. Charlie C. Kim User Services Columbia University
ddl@husc6.harvard.edu (Dan Lanciani) (02/01/88)
In article <8801261521.AA02893@columbia.edu>, cck@cunixc.columbia.EDU (Charlie C. Kim) writes: | The input filter is supposed to process a file called ".banner" | created by the output filter. papif doesn't process the .banner file. | lnof doesn't create one. Strangely, the version of lnof we got does create one. | To do things correctly, papif needs to be modified. (The banner | should go down in the same job stream to prevent interleaving of pages | from other jobs). Transcript's psbanner program can be used, but some | care needs to be taken (with all the transcript programs). I modified papif to grind lpd's standard banner through pstext because I didn't like the idea of parsing the "short-form" lpr banner to recover the information to print a fancy burst page. (Though I never understood why Transcript does this rather than using the appropriate arguments.) I also added to papif the ability to return output from a job to its originator, although this uses a feature of lpd that seems to have changed in real 4.3. Sigh. Anyway, here are some context diffs; use part or all at your own risk... By the way, has anyone noticed that leaving the STATUS feature enabled reduces reliability? Dan Lanciani ddl@harvard.* *** /usr/src/local/at/cap/samples/papif.c Sat Jan 16 22:07:00 1988 --- /users/isr/isr-staff/staffs/ddl/src/cap/papif.c Sat Jan 30 20:11:03 1988 *************** *** 1,6 **** ! static char rcsid[] = "$Author: cck $ $Date: 87/08/06 17:48:02 $"; ! static char rcsident[] = "$Header: papif.c,v 1.24 87/08/06 17:48:02 cck Rel $"; ! static char revision[] = "$Revision: 1.24 $"; /* * papif - UNIX AppleTalk test program: simple line printer input filter --- 1,5 ---- ! #define PSTEXT "/usr/vendor/lib/ps/pstext" ! #define NOSTATUS /* * papif - UNIX AppleTalk test program: simple line printer input filter *************** *** 45,51 **** int cno; int ppid; int pid; ! char host[30],printer[30],user[30]; #define RFLOWQ 8 #ifndef SFLOWQ # define SFLOWQ 8 --- 44,50 ---- int cno; int ppid; int pid; ! char host[30],printer[30],user[30],group[30]; #define RFLOWQ 8 #ifndef SFLOWQ # define SFLOWQ 8 *************** *** 56,61 **** --- 55,62 ---- char rbuf[BUFMAX+10]; int xdebug = TRUE; char *ptime(); + FILE *pout; + int didout; /* quit gets called when we've been killed by lprm via SIGINT */ quit() *************** *** 91,96 **** --- 92,100 ---- case 'p': /* printer name */ strcpy(printer,argv[++i]); break; + case 'g': /* group name */ + strcpy(group,argv[++i]); + break; case 'n': /* user name */ strcpy(user,argv[++i]); break; *************** *** 122,128 **** --- 126,134 ---- strcpy(printer, pgmname); } + char tname[] = "/tmp/papifXXXXXX"; + /* * our "input" filter - send input to laserwriter * *************** *** 166,171 **** --- 172,181 ---- nbpInit(); PAPInit(); /* init PAP printer routines */ + mktemp(tname); + if(!(pout = fopen(tname, "w"))) + pout = stderr; + /* log message */ fprintf(stderr,"PAPIF: Starting job for %s@%s at %s on printer %s\n", user,host,ptime(),lwname); *************** *** 175,187 **** #endif signal(SIGINT,quit); /* this is what lprm sends us */ - #ifdef notdef - if ((bannerfd = open(".banner", 0)) >= 0) { - sendbanner(ptr, bannerfd); /* don't care if we can't send it */ - close(bannerfd); - } - #endif - cno = openlw(lwname); #ifndef NOSTATUS --- 185,190 ---- *************** *** 202,212 **** --- 205,235 ---- sendfile(cno); /* send file to laserwriter */ + #ifdef PSTEXT + close(0); + wait(0); + if (!index(host, '@') && !open(".banner", 0)) { + pstext(); + sendfile(cno); + } + #endif + epc = getpagecount(cno); /* get the page count */ PAPClose(cno); if (acctfile != NULL) doacct(spc, epc, acctfile, user, host); + if(pout != stderr) { + fclose(pout); + if(didout || index(host, '@')) { + if(!fork()) { + execl("/usr/local/bin/returnfile", "returnfile", host, user, tname, 0); + exit(1); + } + } + else + unlink(tname); + } exit(lpd_OK); /* exit okay */ } *************** *** 320,327 **** fprintf(stderr,"PAPRead error %d\n",rcomp); break; } else if (rlen > 0) { ! rbuf[rlen] = '\0'; ! fprintf(stderr,"%s",rbuf); } paperr = PAPRead(cno, rbuf, &rlen, &eof, &rcomp); if (paperr < 0) { --- 343,350 ---- fprintf(stderr,"PAPRead error %d\n",rcomp); break; } else if (rlen > 0) { ! write(fileno(pout), rbuf, rlen); ! didout = 1; } paperr = PAPRead(cno, rbuf, &rlen, &eof, &rcomp); if (paperr < 0) { *************** *** 353,360 **** fprintf(stderr,"PAPRead error %d\n",rcomp); break; } else if (rlen > 0) { ! rbuf[rlen] = '\0'; ! fprintf(stderr,"%s",rbuf); } if (eof) break; PAPRead(cno, rbuf, &rlen, &eof, &rcomp); --- 376,383 ---- fprintf(stderr,"PAPRead error %d\n",rcomp); break; } else if (rlen > 0) { ! write(fileno(pout), rbuf, rlen); ! didout = 1; } if (eof) break; PAPRead(cno, rbuf, &rlen, &eof, &rcomp); *************** *** 423,429 **** if (epc >= spc && epc > 0 && spc > 0) { if (user[0] != '\0' && acctfile && access(acctfile, 02) >= 0 && (afd = fopen(acctfile, "a")) != NULL) ! fprintf(afd,"%7.2f\t%s:%s\n", (float)(epc-spc), host, user); } else fprintf(stderr, "Problems getting pagecount: start %d, end %d\n",spc,epc); } --- 446,452 ---- if (epc >= spc && epc > 0 && spc > 0) { if (user[0] != '\0' && acctfile && access(acctfile, 02) >= 0 && (afd = fopen(acctfile, "a")) != NULL) ! fprintf(afd,"%7.2f %-16s %-20s %-8s\n", (float)(epc-spc), host, group, user); } else fprintf(stderr, "Problems getting pagecount: start %d, end %d\n",spc,epc); } *************** *** 553,559 **** for (i = 0 ; i < NSIG ; i++) signal(i, SIG_IGN); sprintf(retry, ! "(sleep 2;/etc/lpc abort %s;sleep 2;/etc/lpc start %s)&", printer, printer); system(retry); exit(lpd_REPRINT); --- 576,582 ---- for (i = 0 ; i < NSIG ; i++) signal(i, SIG_IGN); sprintf(retry, ! "(sleep 3;/etc/lpc abort %s;sleep 3;/etc/lpc start %s)&", printer, printer); system(retry); exit(lpd_REPRINT); *************** *** 564,569 **** } #endif IDLESTUFF pstatus(status.StatusStr); ! sleep(10); /* update every 10 seconds */ } while (1); } --- 587,592 ---- } #endif IDLESTUFF pstatus(status.StatusStr); ! sleep(30); /* update every 10 seconds */ } while (1); }
mkupfer@acornrc.UUCP (Mike Kupfer) (02/03/88)
Brad Smith from UC Santa Cruz sent me a hacked version of papif that produces banner pages in conjunction with psbanner. I hacked on that version some more, and the resulting diffs are appended to this message. This version, unlike Dan Lanciani's recent posting, uses psbanner to produce the banner. Another difference is that it lets you control whether the banner is produced before or after the actual job (depending on how your printer stacks its output). There are also some changes that I put in to better handle the "idle printer" problem and to make lint happier. Once again, thanks to all who replied to my original query. Mike Kupfer Olivetti Research Center 415-496-6238 orc!kupfer@unix.sri.com ...!oliveb!orc!kupfer ...!{decwrl, ames}!acornrc!mkupfer ...!ucbvax!kupfer ========== sample printcap entry ========== lp|ps|PostScript|OliWriter (LaserWriter):\ :lp=/dev/null:if=/usr/local/lib/lp:\ :sd=/usr/spool/lpd:sb:\ :of=/usr/local/lib/ps/psof:\ :lf=/usr/adm/lp-errs:\ :af=/usr/adm/lp.acct: ========== samples/INSTALLATION diffs ========== *** INSTALLATION.orig Tue Feb 2 14:02:18 1988 --- INSTALLATION Tue Feb 2 14:01:36 1988 *************** *** 1,3 **** --- 1,6 ---- + + @(#)INSTALLATION 2.1 (ORC) 1/28/88 + General notes: tlw, papif, lwpr, iwpr now have a settable "Send Flow Quantum *************** *** 46,53 **** /etc/printcap. (b) make a copy or a hard or symbolic link to papif. papif will take the program name (if not papif) as the unix printer ! name. point to the copy instead of papif in /etc/printcap ! (b) is the recommended method. LWSRV ----- --- 49,70 ---- /etc/printcap. (b) make a copy or a hard or symbolic link to papif. papif will take the program name (if not papif) as the unix printer ! name. point to the copy instead of papif in /etc/printcap. ! (b) is the recommended method, unless you want a banner page to be produced ! with each print job (see next paragraph). ! ! If you are using Transcript and you want a banner page to be produced ! with each job, you must use method (a) (see previous paragraph). This script ! should set either $BANNERFIRST or $BANNERLAST to 1, depending on which way ! your printer stacks the output. For example, the script: ! ! #! /bin/sh ! BANNERFIRST=1 ! BANNERLAST=0 ! export BANNERFIRST BANNERLAST ! /usr/local/cap/papif ${*} -p lp ! ! will generate a banner page before each job is printed. LWSRV ----- ========== papif.c diffs ========== *** papif.c.old Tue Feb 2 14:47:36 1988 --- papif.c Tue Feb 2 14:54:22 1988 *************** *** 1,6 **** --- 1,9 ---- + #ifndef lint static char rcsid[] = "$Author: cck $ $Date: 87/08/06 17:48:02 $"; static char rcsident[] = "$Header: papif.c,v 1.24 87/08/06 17:48:02 cck Rel $"; static char revision[] = "$Revision: 1.24 $"; + static char orcid[] = "@(#)papif.c 2.2 (ORC) 2/2/88"; + #endif /* * papif - UNIX AppleTalk test program: simple line printer input filter *************** *** 20,26 **** --- 23,31 ---- * */ + #ifndef lint char copyright[] = "Copyright (c) 1986, 1987 by The Trustees of Columbia University in the City of New York"; + #endif #include <stdio.h> #include <sys/types.h> *************** *** 41,47 **** #define lpd_REPRINT 1 /* forces a reprint */ #define lpd_ERRORS 2 /* printed with errors */ - char *fname ; int cno; int ppid; int pid; --- 46,51 ---- *************** *** 124,129 **** --- 128,171 ---- /* + * If "envname" is defined in the environment, then send a banner + * to the printer. + */ + void + maybesendbanner(cno, envname) + int cno; /* connection to printer */ + char *envname; + { + int bannerfd; + void sendbanner(); + extern char *getenv(); + char *s; /* value of envname, usually "0" or "1" */ + + s = getenv(envname); + if (s == (char *)NULL || atoi(s) == 0) + return; + + if ((bannerfd = open(".banner", 0)) >= 0) { + sendbanner(cno, bannerfd); /* don't care if we can't send it */ + close(bannerfd); + } + } + + void + sendbanner(cno, bfd) + int bfd; /* Banner file descriptor */ + int cno; + { + int tfd; + + tfd = dup(fileno(stdin)); + dup2(bfd, fileno(stdin)); + sendfile(cno); + dup2(tfd, fileno(stdin)); + } + + + /* * our "input" filter - send input to laserwriter * * stdin - input *************** *** 130,135 **** --- 172,178 ---- * stdout - points to devices, empty here * stderr - points to log file on BSD4.2, Ultrix 1.0 through Ultrix 1.2 * - points to "err" tmp file on BSD 4.3 + * environment - BANNERFIRST, BANNERLAST * * Exit codes are listed above * *************** *** 175,187 **** #endif signal(SIGINT,quit); /* this is what lprm sends us */ - #ifdef notdef - if ((bannerfd = open(".banner", 0)) >= 0) { - sendbanner(ptr, bannerfd); /* don't care if we can't send it */ - close(bannerfd); - } - #endif - cno = openlw(lwname); #ifndef NOSTATUS --- 218,223 ---- *************** *** 192,198 **** } if (pid) /* status process */ statuswatch(lwname, cno); - #endif spc = getpagecount(cno); /* get the page count */ --- 228,233 ---- *************** *** 200,207 **** pstext(); /* convert text to postscript */ #endif sendfile(cno); /* send file to laserwriter */ ! epc = getpagecount(cno); /* get the page count */ PAPClose(cno); --- 235,243 ---- pstext(); /* convert text to postscript */ #endif + maybesendbanner(cno, "BANNERFIRST"); sendfile(cno); /* send file to laserwriter */ ! maybesendbanner(cno, "BANNERLAST"); epc = getpagecount(cno); /* get the page count */ PAPClose(cno); *************** *** 299,305 **** #endif PSTEXT /* ! * Send a file to the specified connection */ sendfile(cno) int cno; --- 335,341 ---- #endif PSTEXT /* ! * Send a file from stdin to the specified connection (cno). */ sendfile(cno) int cno; *************** *** 346,352 **** if (err < 0) /* this is a little overloaded */ perror("read"); ! paperr = PAPWrite(cno, NULL, 0, TRUE, &wcomp); /* send eof */ while (!eof) { /* wait for completion */ if (rcomp <= 0) { if (rcomp != noErr) { --- 382,388 ---- if (err < 0) /* this is a little overloaded */ perror("read"); ! paperr = PAPWrite(cno, (char *)NULL, 0, TRUE, &wcomp); /* send eof */ while (!eof) { /* wait for completion */ if (rcomp <= 0) { if (rcomp != noErr) { *************** *** 376,382 **** int cno; { static char gpcstr[] = "statusdict begin pagecount (*) print == "; ! char buf[100]; /* enough for page count! */ char *p; int err, wcomp, rlen, eof, rcomp, started; --- 412,418 ---- int cno; { static char gpcstr[] = "statusdict begin pagecount (*) print == "; ! char countbuf[100]; /* enough for page count! */ char *p; int err, wcomp, rlen, eof, rcomp, started; *************** *** 395,403 **** started = 1; p = index(rbuf, '*'); /* look for marker */ if (p != NULL) ! strcpy(buf, p+1); } else ! strcat(buf, p); } if (eof) break; --- 431,439 ---- started = 1; p = index(rbuf, '*'); /* look for marker */ if (p != NULL) ! strcpy(countbuf, p+1); } else ! strcat(countbuf, p); } if (eof) break; *************** *** 407,413 **** } abSleep(4, TRUE); } while (!eof); ! return(atoi(buf)); } /* --- 443,449 ---- } abSleep(4, TRUE); } while (!eof); ! return(atoi(countbuf)); } /* *************** *** 454,460 **** hangup() { union wait status; ! while (wait3(&status, WNOHANG, 0) > 0) ; fprintf(stderr,"Finished job at %s\n",ptime()); fflush(stderr); exit(lpd_OK); /* exit */ --- 490,496 ---- hangup() { union wait status; ! while (wait3(&status, WNOHANG, (struct rusage *)0) > 0) ; fprintf(stderr,"Finished job at %s\n",ptime()); fflush(stderr); exit(lpd_OK); /* exit */ *************** *** 466,475 **** char * ptime() { ! long clock; char *timestr; ! clock = time(0); timestr = (char *)asctime(localtime(&clock)); timestr[24] = '\0'; /* pretty hooky - but it works */ return(timestr); --- 502,512 ---- char * ptime() { ! time_t clock; char *timestr; + extern time_t time(); ! clock = time((time_t *)0); timestr = (char *)asctime(localtime(&clock)); timestr[24] = '\0'; /* pretty hooky - but it works */ return(timestr); *************** *** 486,492 **** char *printer; { FILE *fd; ! static char buf[256]; char *ep; if (printer[0] == '\0') --- 523,529 ---- char *printer; { FILE *fd; ! static char namebuf[256]; char *ep; if (printer[0] == '\0') *************** *** 497,511 **** return(NULL); } do { ! if (fgets(buf, 256, fd) == NULL) break; ! buf[strlen(buf)-1] = '\0'; /* get rid of the lf */ ! if (buf[0] == '#' || buf[0] == '\0') continue; ! if ((ep=index(buf,'=')) == NULL) /* find first = */ continue; /* no = in string */ *ep = '\0'; /* set = to null now */ ! if (strcmp(buf,printer) == 0) { if (strlen(ep+1) == 0) /* no name */ continue; fclose(fd); --- 534,548 ---- return(NULL); } do { ! if (fgets(namebuf, 256, fd) == NULL) break; ! namebuf[strlen(namebuf)-1] = '\0'; /* get rid of the lf */ ! if (namebuf[0] == '#' || namebuf[0] == '\0') continue; ! if ((ep=index(namebuf,'=')) == NULL) /* find first = */ continue; /* no = in string */ *ep = '\0'; /* set = to null now */ ! if (strcmp(namebuf,printer) == 0) { if (strlen(ep+1) == 0) /* no name */ continue; fclose(fd); *************** *** 517,525 **** } /* ! * Listens for status messages from lw * */ statuswatch(lwname, cno) char *lwname; int cno; --- 554,563 ---- } /* ! * Listens for status messages from lw every SLEEPTIME seconds. * */ + #define SLEEPTIME 10 statuswatch(lwname, cno) char *lwname; int cno; *************** *** 527,532 **** --- 565,573 ---- AddrBlock addr; int hangup(); PAPStatusRec status; + #ifdef IDLESTUFF + int idleSeconds = 0; /* num of seconds printer is idle so far */ + #endif PAPHalfClose(cno); signal(SIGCHLD, hangup); *************** *** 534,539 **** --- 575,585 ---- do { PAPStatus(lwname, &status, &addr); #ifdef IDLESTUFF + /* + * If the printer has been idle for more than MAXIDLE seconds, then assume + * that something is hung. Kill the current daemon and restart it. + */ + #define MAXIDLE 60 { int i; char retry[128]; *************** *** 540,547 **** char tmpbuf[255]; cpyp2cstr(tmpbuf, status.StatusStr); ! if (strncmp("status: idle", tmpbuf, 12) == 0 ! || access("/tmp/papifidletest", F_OK) == 0) { fprintf(stderr,"PAPIF: status: idle bug; restarting\n"); fflush(stderr); unlink("/tmp/papifidletest"); --- 586,596 ---- char tmpbuf[255]; cpyp2cstr(tmpbuf, status.StatusStr); ! if (strncmp("status: idle", tmpbuf, 12) == 0) ! idleSeconds += SLEEPTIME; ! else ! idleSeconds = 0; ! if (idleSeconds > MAXIDLE || access("/tmp/papifidletest", F_OK) == 0) { fprintf(stderr,"PAPIF: status: idle bug; restarting\n"); fflush(stderr); unlink("/tmp/papifidletest"); *************** *** 556,561 **** } #endif IDLESTUFF pstatus(status.StatusStr); ! sleep(10); /* update every 10 seconds */ ! } while (1); } --- 605,610 ---- } #endif IDLESTUFF pstatus(status.StatusStr); ! sleep(SLEEPTIME); ! } while (1); /* breaks out of loop via SIGCHLD */ }