Boston Linux & Unix (BLU) 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

BLU Discuss list archive


[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Request help setting up IP printer w/Jetdirect card



> 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
BLU is a member of BostonUserGroups
We also thank MIT for the use of their facilities.

Valid HTML 4.01! Valid CSS!



Boston Linux & Unix / webmaster@blu.org