Request help setting up IP printer w/Jetdirect card
Glenn Burkhardt
glenn at aoi.ultranet.com
Thu Jun 1 11:13:51 EDT 2000
> 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
More information about the Discuss
mailing list