|
|
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;
}
}
}