SUMMARY: HP LaserJet 4MP on SPARCstation 10 parallel port

From: Todd Pfaff (todd@immrc.eng.McMaster.CA)
Date: Wed Feb 01 1995 - 07:06:51 CST


I asked:

----- Begin Included Message -----

Anyone have an HP LaserJet 4MP on an SPARCstation 10 parallel port
(/dev/bpp0) running SunOS 4.1.x?

If so, can you send me:

1) the printcap entry
2) any filters referenced by the printcap
3) any non-default printer menu settings

Thanks.

----- End Included Message -----

It turns out that the problems I was having were communication problems
with the parallel port or the cable. I hooked up another identical system
and it worked fine. I tried swapping printers and cables and suddenly the
first system printed fine. I connected the original cable and it worked,
until I screwed the connector down tight to the SS10 port. Then I was
getting intermittent communication errors again (I was getting text printed
but it was interspersed with garbage.). So something seems to be flaky
with the parallel port or cable on this particular SS10 system.

Thanks to everyone who replied.

I am using lj4m, sent by Yehuda Bamnolker (bamby@Scorpio.Com), modified
slightly, and a shell script wrapper using code sent by Mike Phillips
(ukcphmr@ukpmr.cs.philips.nl).

lj4m takes the user and host name of the print job and displays them on
the LaserJet LCD front panel. Nice touch.

lj4m determines the type of file being printed by examining the first
two characters and processes the file accordingly. I modified this to
skip any leading control characters other than escape because I found
some Postscript files have leading CTRL-Ds which would fool this
program into thinking it was a text file.

Of course, none of this is necessary since the HPLJ4 can autodetect the
type of file anyway, but this filter does a nicer job of handling
different file types and rejecting non-printable files.

:::::::::: BEGIN hplj4mp.if
#!/bin/sh
# hplj4mp.if
# - use as printcap if filter
# - user and host name are passed to lj4m as args 5 and 7
 
while test $# != 0
do case "$1" in
  -c) ;;
  -w*) width=$1 ;;
  -l*) length=$1 ;;
  -i*) indent=$1 ;;
  -x*) width=$1 ;;
  -y*) length=$1 ;;
  -n) user=$2 ; shift ;;
  -n*) user=`expr $1 : '-.\(.*\)'` ;;
  -h) host=$2 ; shift ;;
  -h*) host=`expr $1 : '-.\(.*\)'` ;;
  -*) ;;
  *) afile=$1 ;;
  esac
  shift
done
 
exec /usr/local/etc/lpd/lj4m "" "" "" "" $user "" $host ""
:::::::::: END hplj4mp.if

:::::::::: BEGIN lj4m.c
/*
   lj4m.c -- Michael A. Covington and Mark L. Juric, 1994
   Pre-spooler filter for LaserJet 4M.
   Compile with gcc or ANSI C.
   Install with the "if=" (not "of=") option in /etc/printcap.
   Print jobs are logged as lpr.debug messages.
*/

#include <syslog.h>
#include <stdio.h>
#include <string.h>

#define CTRLD "\004"
#define LINELENGTH 80

/*** HP LaserJet control sequences ***/

#define RESET "\033E"
#define LF_TO_CRLF "\033&k2G"
#define LMARGIN "\033&a11L"
#define FONT "\033(s0p(s12h(s4b(s4099T"
#define START_PJL "\033%-12345X@PJL\n"
#define END_PJL "\033%-12345X"
#define POSTSCRIPT "@PJL ENTER LANGUAGE = POSTSCRIPT\n"
#define PCL "@PJL ENTER LANGUAGE = PCL\n"

/*** Global variables ***/

int c0, c; /* first 2 chars of file */
long int bytes; /* character count */
char userinfo[64] = ""; /* will be "machine:username" */

/*** Printer console display functions ***/

void DisplayOnPrinterConsole(char *s)
{
  fprintf(stdout,"%s%s%s%s%s%s%s",
          RESET,
          START_PJL,
          "@PJL RDYMSG DISPLAY = \"",
          s,
          "\"\n",
          END_PJL,
          RESET);
}

void ResetPrinterConsole() /* to display "00 READY" */
{
  fprintf(stdout,"%s%s%s%s%s",
          RESET,
          START_PJL,
          "@PJL RDYMSG DISPLAY = \"\"\n",
          END_PJL,
          RESET);
}

/*** PostScript and HP file handling ***/

void PrintPostScriptFile()
{
  /* Choose language */
  fprintf(stdout,"%s%s%s",RESET,START_PJL,POSTSCRIPT);

  /* Transmit file transparently */
  putc(c0,stdout);
  for (bytes=1; !feof(stdin); bytes++)
  {
     putc(c,stdout);
     c = getc(stdin);
  }

  /* Add newline, Ctrl-D, and reset at end */
  fprintf(stdout,"\n%s%s%s",CTRLD,END_PJL,RESET);

  /* Log results */
  syslog(LOG_DEBUG,"%s, PostScript file, %d bytes",userinfo,bytes);
}

void PrintHPFile()
{
  /* Choose language */
  fprintf(stdout,"%s%s%s",RESET,START_PJL,PCL);

  /* Transmit file transparently */
  putc(c0,stdout);
  for (bytes=1; !feof(stdin); bytes++)
  {
     putc(c,stdout);
     c = getc(stdin);
  }

  /* Reset printer at end */
  fprintf(stdout,"%s%s",END_PJL,RESET);

  /* Log results */
  syslog(LOG_DEBUG,"%s, HP file, %d bytes",userinfo,bytes);
}

/*** ASCII and unprintable file handling ***/

#define PRINTABLE(c) (printable[(unsigned char) c])

char printable[256] =
   /* Table of which ASCII codes are printable characters */
       { 0,0,0,0,1,0,0,1,1,1,1,0,1,1,0,0, /* NUL to ^O */
         0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0, /* ^P to 31 */
         1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 32 to 47 */
         1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 48 to 63 */
         1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 64 to 79 */
         1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 80 to 95 */
         1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 96 to 112 */
         1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0, /* 113 to 127 */
         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 128 to 143 */
         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 144 to 159 */
         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 160 to 175 */
         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 176 to 191 */
         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 192 to 207 */
         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 208 to 223 */
         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 224 to 239 */
         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 }; /* 240 to 255 */
                                /* -1 (eof) maps onto 255 */

void RejectFileAsUnprintable()
{
  /* Set up printer again because it may have been disrupted */
  fprintf(stdout,"\n%s%s%s%s%s%s",
          RESET,
          START_PJL,
          PCL,
          LF_TO_CRLF,
          FONT,
          LMARGIN);

  /* Dump 30 lines, printing '.' for unprintable characters */
  fprintf(stdout,
          "%s\nUnprintable data! Partial dump follows...\n",
          userinfo);

  for (bytes=1; bytes<LINELENGTH*30+1; bytes++)
  {
    if (feof(stdin)) break;
    if (c<32 || c>126) c = '.';
    fputc(c,stdout);
    if (bytes % LINELENGTH == 0) fputc('\n',stdout);
    c = getc(stdin);
  }

  /* Log the error */
  syslog(LOG_ERR,
         "LJ4M: %s: tried to print unprintable data\n",userinfo);

}

void PrintASCIIFile()
{
  int position = 1; /* where the next char on the line will be */
  int ok_to_print; /* true if no bad chars found */

  /* Set up printer */
  fprintf(stdout,"%s%s%s%s%s%s",
          RESET,
          START_PJL,
          PCL,
          LF_TO_CRLF,
          FONT,
          LMARGIN);

  /* Deal with the first character already read */
  ok_to_print = PRINTABLE(c0) && PRINTABLE(c);
  if (ok_to_print && (c0 != EOF)) putc(c0,stdout);

  /* Process rest of file, breaking at column 80 and
     underlining last character if line continues beyond */

  for(bytes=1; ok_to_print && !feof(stdin); bytes++)
  {
    if (c==4 || c==26) break; /* Skip UNIX or DOS EOF mark */

    /* Compute where c will print */
    if (c==10 || c==12 || c==13) position=0; /* CR, FF, or LF */
    else if (c==8 && position>0) position--; /* Backspace */
    else position++;

    /* If in a printable column, print it */
    if (position <= LINELENGTH) fputc(c,stdout);

    /* If we have just run past margin, underline last character */
    if (position == LINELENGTH+1) fputs("\b_",stdout);

    /* Obtain and check next character */
    c = getc(stdin);
    ok_to_print = PRINTABLE(c);
  }

  /* If a bad byte was found, print messages and dump */
  if(!ok_to_print) RejectFileAsUnprintable();

  /* Reset printer at end */
  fprintf(stdout,"%s%s",END_PJL,RESET);

  /* If normal termination, report results */
  if (ok_to_print)
     syslog(LOG_DEBUG,"%s, ASCII file, %d bytes",userinfo,bytes);
}

/*** Main program ***/

main(int argc, char* argv[])
{
  /* Obtain machine name and user name from cmd line args */

  if (argc>=8)
    sprintf(userinfo,"%s@%s",argv[5],argv[7]);
  else
    sprintf(userinfo,"%d Unknown username", argc);
/* strcpy(userinfo,"Unknown username");*/

  

  

  DisplayOnPrinterConsole(userinfo);

  openlog("LaserJet 4M",0,LOG_LPR);

  /* Examine first 2 bytes, decide how to handle file */
  /* skip any leading CTRL-Ds or other non-escape control characters */
  do
    c0 = getc(stdin);
  while(c0 != 27 && !isprint(c0) && !feof(stdin));
  c = getc(stdin);

  if (c0=='%' && c=='!')
    PrintPostScriptFile();
  else if (c0==27 && (c=='E' || c=='%'))
    PrintHPFile();
  else
    PrintASCIIFile();

  /* Clean up */
  ResetPrinterConsole();
  closelog();
  return(0); /* UNIX insists on return code 0. */
}
:::::::::: END lj4m.c

--
Todd Pfaff                       \  Internet: todd@water.eng.mcmaster.ca
Dept. of Mechanical Engineering   \    Voice: (905) 525-9140 x27351
McMaster University                \     FAX: (905) 572-7944
Hamilton, Ontario, CANADA  L8S 4L7  \



This archive was generated by hypermail 2.1.2 : Fri Sep 28 2001 - 23:10:15 CDT