|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T a
Length: 8198 (0x2006) Types: TextFile Names: »applef.c«
└─⟦060c9c824⟧ Bits:30007080 DKUUG TeX 2/12/89 └─⟦this⟧ »./DVIware/obsolete/mitdrivers/dvi2ps/applef.c«
/* * applef.c - output filter for postscript to printer * Also figures out if it should be an ascii filter * instead, if a -l or -w swich is given. * * Copyright 1985 Massachusetts Institute of Technology * Author: CJL@OZ * * * TODO: * Page ordering so they will come out right using structuring * conventions defined by adobe. * */ #include <stdio.h> #include <signal.h> #include <sys/ioctl.h> #include <fcntl.h> #include <syslog.h> #include <sys/types.h> #include <sys/stat.h> #define MAXTFP 1000 /* Maximim # of pages in temp file */ #define MAXWAIT 900 /* Maximum time to wait for resync (sec) */ #define TOPY 760 #define BOTTOMY 35 #define LEFTX 60 #define YINCR 11 #define MIN(a,b) (((a) < (b))? (a):(b)) #define ALARM_TIME 5 /* Time between alarm signals (sec) */ #define PAPER_TIME 600 /* Time between paper out complaints (sec) */ #define STATUS_TIME 60 /* Time between printer status checks (sec) */ /* constants */ int infinity = 10000000; char qsend[] = "/usr/local/bin/send"; char msg_tail[] = " ]%%\r\n"; char printer_error[] = "%%[ PrinterError: "; char status_msg[] = "%%[ status: "; /* variables */ int length = 66; int width = 89; long pprtim = 0; long ststim = 0; int ascii = 0; /* Poscript filter by default */ char *user,*host; int curry,charpos,nchars; long tfpos[MAXTFP],tfp; FILE *tf; char tfn[256]; char logbuf[BUFSIZ],*logbp; char last_status[BUFSIZ]; /* First, all the code for just sending chars to the printer */ int synched = 0; timeout() { long t; time(&t); alarm(ALARM_TIME); if (t - ststim > STATUS_TIME) { write(1,"\024",1); /* Control-T */ ststim = t; } getlog(); } getlog() { register int i; int n; char buf[BUFSIZ],ch; while ((ioctl(1,FIONREAD,&n) >= 0) && n) { if (n > sizeof(buf)) n = sizeof(buf); n = read(1,buf,n); if (n > 0) { for (i=0; i<n; i++) { if ((ch = buf[i]) == 4) synched++; else { *logbp++ = ch; if ((ch == '\n') || (logbp >= logbuf+BUFSIZ)) flushlog(); } } } else { perror("read from the printer"); return; } } fflush(stderr); } dopaperout() { char cmdline[256]; FILE *f,*popen(); long t; time(&t); if (t - pprtim > PAPER_TIME) { syslog(LOG_CRIT,"out of paper"); if (user != NULL && host != NULL) { sprintf(cmdline,"exec %s %s@%s",qsend,user,host); if ((f = popen(cmdline,"w")) != NULL) { fprintf(f,"You need to add paper to the printer."); pclose(f); } } pprtim = t; } } dostatusmsg(msg) char *msg; { if (strcmp(msg,last_status)) { syslog(LOG_WARNING,"status: %s",msg); strcpy(last_status,msg); } if (!strcmp(msg,"out of paper")) dopaperout(); } doprintererror(msg) char *msg; { syslog(LOG_WARNING,"printer error: %s",msg); if (!strcmp(msg,"out of paper")) dopaperout(); } flushlog() { register char *p; if ((logbp - logbuf > sizeof(printer_error)-1 + sizeof(msg_tail)-1) && (!strncmp(logbuf,printer_error,sizeof(printer_error)-1))) { *(logbp-sizeof(msg_tail)+1) = 0; doprintererror(logbuf+sizeof(printer_error)-1); } else if ((logbp - logbuf > sizeof(status_msg)-1 + sizeof(msg_tail)-1) && (!strncmp(logbuf,status_msg,sizeof(status_msg)-1))) { *(logbp-sizeof(msg_tail)+1) = 0; dostatusmsg(logbuf+sizeof(status_msg)-1); } else for (p = logbuf; p < logbp; p++) { if (ascii || (tf == NULL)) putc(*p,stderr); else dochar(*p); } logbp = logbuf; } resync() { int seconds = 0; struct stat *buf; fflush(stdout); fstat(stdout,buf); if (buf->st_mode&S_IFCHR){ synched = 0; write(1,"\004",1); while (!synched && ((seconds += ALARM_TIME) < MAXWAIT)) pause(); if (!synched) syslog(LOG_CRIT,"synchronization timeout"); } flushlog(); } init_printer() { strcpy(last_status,"idle"); logbp = logbuf; signal(SIGIO,getlog); signal(SIGALRM,timeout); fcntl(1,F_SETFL,FAPPEND|FASYNC); alarm(ALARM_TIME); resync(); /* Open a temp file for sending the data * for reversing the order of output */ tf = fopen(mktemp(strcpy(tfn,"/usr/tmp/applef.XXXXXX")),"w+"); if (tf == NULL) { perror(tfn); exit(1); } tfp = 0; unlink(tfn); }; term_printer() { resync(); alarm(0); }; copychars(infd,outfd,nchars) { register int i,j; register char *p; char buf[BUFSIZ]; i = 0; while ((nchars > 0) && (i = read(infd,p = buf,MIN(sizeof(buf),nchars))) > 0) { nchars -= i; while (i > 0) { if ((j = write(outfd,p,i)) > 0) { i -= j; p += j; } else { perror("applef"); i = 0; } } } if (i < 0) perror("applef"); } main(argc, argv) int argc; char *argv[]; { register int ch; int i; char *rindex(); char lognam[256]; if (rindex(argv[0],'/')) argv[0] = rindex(argv[0],'/')+1; for (i = 1; i < argc; i++) { if (argv[i][0] == '-') switch (argv[i][1]) { case 'h': host = argv[++i]; break; case 'l': ascii++; /* So I must be an ascii filter */ sscanf(argv[i]+2,"%d",&length); break; case 'n': user = argv[++i]; break; case 'w': ascii++; /* So I must be an ascii filter */ sscanf(argv[i]+2,"%d",&width); break; default: break; } } if (user != NULL) sprintf(lognam,"%s (%s@%s)",argv[0],user,host); else sprintf(lognam,"%s",argv[0]); openlog(lognam,LOG_PID); init_printer(); starttext(); if (ascii) { while (!ferror(stdin) && (ch = getchar()) != EOF) switch (ch) { case '\031': /* * lpd needs to use a different filter to * print data so stop what we are doing and * wait for lpd to restart us. */ if ((ch = getchar()) == '\1') { resync(); kill(getpid(), SIGSTOP); resync(); break; } else { ungetc(ch, stdin); ch = '\031'; } default: dochar(ch); } if (ferror(stdin)) perror("applef stdin"); } else { copychars(0,1,infinity); resync(); } endtext(); term_printer(); exit(0); } \f /* Now code for converting text files to Postscript * and sending it to the printer. We need this stuff * to print printer responses after the print job, * and to print in ascii mode. */ starttext() { newpage(); } endtext() { long end, curr; FILE *tempf; int tempfd; dochar('\f'); tfpos[tfp] = ftell(tf); fflush(tf); tempf = tf; tf = NULL; tempfd = fileno(tempf); /* now send the pages to the printer in reverse order */ while (--tfp >= 0) { curr = tfpos[tfp]; end = tfpos[tfp + 1]; lseek(tempfd,curr,0); copychars(tempfd,1,end-curr); }; fclose(tempf); } newpage() { nchars = 0; charpos = 0; curry = TOPY; } pageinit() { fflush(tf); if (tfp >= MAXTFP) { fprintf(stderr,"too many pages\n"); exit(1); } tfpos[tfp++] = ftell(tf); fprintf(tf,"/Courier findfont 10 scalefont setfont\n"); /* font */ } dostring(p) char *p; { register char ch; while (ch = *p++) dochar(ch); } dochar (ch) int ch; { register int i; if (ch < ' ') switch (ch) { case '\b': if (charpos) { fprintf(tf,") show\n"); fprintf(tf,"(a) stringwidth pop neg 0 rmoveto\n"); if (--charpos) fprintf(tf,"("); } break; case '\t': for (i = 8 - charpos%8; i > 0; i--) dochar(' '); break; case '\n': if (curry - YINCR < BOTTOMY) dochar('\f'); else { if (charpos) fprintf(tf,") show\n"); curry -= YINCR; charpos = 0; } break; case '\r': if (charpos) fprintf(tf,") show\n"); charpos = 0; break; case '\f': if (charpos) fprintf(tf,") show "); if (nchars) fprintf(tf,"showpage\n"); newpage(); break; default: dochar('^'); dochar('\b'); dochar('|'); dochar(ch+'A'-001); break; } else { if (!nchars++) pageinit(); if (!charpos++) fprintf(tf,"%d %d moveto (",LEFTX,curry); if (charpos >= width) { putc('!',tf); dochar('\n'); dochar(ch); } else switch (ch) { case '\\': case '/': case '(': case ')': putc('\\',tf); default: putc(ch,tf); break; } } }