Home
| Calendar
| Mail Lists
| List Archives
| Desktop SIG
| Hardware Hacking SIG
Wiki | Flickr | PicasaWeb | Video | Maps & Directions | Installfests | Keysignings Linux Cafe | Meeting Notes | Linux Links | Bling | About BLU |
> My next task will be to devise a filter to ideally have all jobs (text and > binary) converted to postscript, the universal language, and then printed. The HP4000/JetDirect does this automatically if you specify the 'auto' queue. However, if you like, you can play with this filter, which senses the file type, and does the "right thing". It also has hooks for turning on the duplexer (I strongly recommend fitting the HP4000 with a duplexer!)... -------------- next part -------------- /* @(#)hplaser.c 1.9 4/14/99 Taste the file to determine file type: PCL, text, Postscript. For text files, expand tabs and put a CR before each LF. For reasons unknown, executing 'write' with 0 bytes will hang the Aurora parallel port - avoid it... */ #include <stdio.h> #include <signal.h> #include <errno.h> enum FILETYPE { text, PCL, Postscript }; static enum FILETYPE mode; static int psDup_off; static int gs_pid; void duplex_off(void) { #ifdef DUPLEX char cmd[80]; if (mode == Postscript) { if (!psDup_off) { strcpy(cmd, "<< /Duplex false >> setpagedevice\n"); write(1, cmd, strlen(cmd)); psDup_off = 1; } } else write(1, "\033&l0S", 5); /* duplex off */ #endif } /* when 'lprm' is executed, clean up the job before terminating. */ void sigint(int s) { #ifdef GHOSTSCRIPT /* If postscript, we've started a subprocess to run gs which may have gone away when a job is removed - just exit in this case, so we don't hang on the write. */ if (mode == Postscript) { if (gs_pid) kill(gs_pid, SIGINT); exit(0); } #else duplex_off(); write(1, "\033E", 2); /* reset */ #endif exit(0); } void gs_sig(int s) { int n; wait(&n); /* pick up gs subprocess exit status */ if ((n & 0xff) != 0) exit(-1); else exit((n >> 8) & 0xff); } int main(int ac, char **av) { int nbytes, col, i, nb, n, sd[2]; char buff[307], *p, *s, *eob; char cmd[80]; signal(SIGINT, sigint); /* Get some characters, and determine its type */ nbytes = read(0, buff, sizeof(buff)); p = s = buff; if ((nbytes > 0) && (buff[0] == '\033')) { mode = PCL; write(1, "\033E", 2); /* Scan for initial \033E reset sequence at beginning of buffer. This can turn off other modes (e.g., duplex) if sent later.. */ if (buff[1] == 'E') s = &buff[2]; } else if ((nbytes >= 10) && !strncmp(buff, "%!PS-Adobe", 10)) { mode = Postscript; } else { mode = text; /* Check for first character ^L; omit since we're already at top of form. */ if (*p == '\f') { p++; s = p; } write(1, "\033E", 2); #ifdef LAND132 strcpy(cmd, "\033&l2A\033(s13H\033&l1O"); write(1, cmd, strlen(cmd)); #endif } #ifdef GHOSTSCRIPT if (mode == Postscript) { /* fork subprocess, make pipe, run 'hpps' script */ pipe(sd); if (!(gs_pid = fork())) { /* subprocess */ close(sd[1]); dup2(sd[0], 0); /* pick up stdin */ if (execl("/usr/local/bin/hpps", "hpps", 0) < 0) perror("can't exec /usr/local/bin/hpps"); exit(0); } else { dup2(sd[1], 1); /* pick up stdout */ /* we want to be notified of abnormal terminations, so we can quit.... */ signal(SIGCHLD, gs_sig); } } #endif #ifdef DUPLEX if (mode == Postscript) { /* Scan to end of first line; insert duplex command */ eob = &buff[nbytes]; while (p < eob) { if (*p == '\n') { p++; write(1, buff, p - buff); s = p; strcpy(cmd, "<< /Duplex true >> setpagedevice\n"); write(1, cmd, strlen(cmd)); break; } else p++; } } else { write(1, "\033&l1S", 5); /* duplex, long edge binding */ } #endif col = 0; do { if (mode == text) { /* expand tabs and add CR to LF */ for (eob = &buff[nbytes]; p < eob; i++, p++) { switch (*p) { /* Line feeds expand to CR LF */ case '\n': n = p - s; if (n > 0) write(1, s, n); write(1, "\r\n", 2); s = p + 1; col = 0; continue; case '\r': col = 0; break; /* Tabs expand by 8 012345678901234567890 x x */ case '\t': n = p - s; if (n > 0) write(1, s, n); nb = 8 - (col % 8); write(1, " ", nb); col += nb; s = p + 1; continue; default: col++; break; } } #ifdef DUPLEX } else if (mode == Postscript) { /* Scan for %%EOF; put in end of duplex if found. Note that if not found, p will equal &buff[nbytes], and entire buffer will be written out, below. */ eob = &buff[nbytes]; for (p=buff; p<eob; p++) { if (*p == '%') { /* Check for enough chars to compare; get more if need more */ if (eob - p < 5) { n = p - s; if (n > 0) write(1, s, n); nbytes = eob - p; memcpy(s, p, nbytes); n = read(0, &buff[nbytes], sizeof(buff)-nbytes); if (n < 0) break; nbytes += n; eob = &buff[nbytes]; p = buff; } if (eob - p >= 5 && !strncmp(p, "%%EOF", 5)) { n = p - s; if (n) write(1, s, n); duplex_off(); s = p; p = eob; break; } } } #endif } else { /* PCL and non-Duplex Postscript modes are just pass thru */ p = &buff[nbytes]; } /* Flush buffer */ n = p - s; if (n > 0) write(1, s, n); nbytes = read(0, buff, sizeof(buff)); p = s = buff; } while (nbytes > 0); duplex_off(); if (mode != Postscript) write(1, "\033E", 2); #ifdef GHOSTSCRIPT close(sd[1]); close(1); if (mode == Postscript) { /* wait for Ghostscript subprocess to terminate */ signal(SIGCHLD, SIG_DFL); wait(&n); if ((n & 0xff) != 0) return -1; else return (n >> 8) & 0xff; } else { return 0; } #else close(1); return 0; #endif } -------------- next part -------------- #!/bin/sh LD_LIBRARY_PATH=/usr/local/X11/lib export LD_LIBRARY_PATH cat > $$.ps if cat $$.ps | /usr/local/bin/gs -q -dNOPAUSE -sDEVICE=laserjet -sOutputFile=- - then rm $$.ps else exit -1 fi
BLU is a member of BostonUserGroups | |
We also thank MIT for the use of their facilities. |