Subject: Re: Need help printing on BJ200 with ghostscript
To: None <ewenger@iastate.edu>
From: Keith Moore <moore@cs.utk.edu>
List: netbsd-help
Date: 02/27/1996 23:08:40
> I am running NetBSD 1.1 on a machine with a Canon BJ200 printer attached.
> I have been able to print text on the printer, but it will not print raw
> output from ghostscript.  This is a major holdup on the usability of my
> machine.  Does anyone have a similar setup that is working?

yeah, here's what I use:

/etc/printcap is:
-------------------------------------------------------------------------------
lp|bj200|slug|Ghostscript device bj200:\
    :lp=/dev/lpa2:\
    :sd=/var/spool/bj200:\
    :lf=/var/spool/bj200/logfile:\
    :af=/var/spool/bj200/acct:\
    :if=/usr/local/lib/bj200/bjif:\
    :mx#0:sb:sh:rs:pl#60:pw#80:
-------------------------------------------------------------------------------
the source for bjif.c is below.  basically it handles the lpr filter 
interface, decides whether the file is text or PostScript (tm), and
handles each accordingly.  If PostScript, it feeds the thing
to GhostScript for processing; if text, it expands tabs and converts
newline to CRLF and sends to the printer.
-------------------------------------------------------------------------------
/*
 * lpr filter for Canon BJ 200 inkjet printer.
 * Keith Moore
 *
 * initial conditions:
 *
 * stdin  [fd 0] file to print (may be a pipe)
 * stdout [fd 1] printer device                 (printcap "lp")
 * stderr [fd 2] printer log file               (printcap "lf")
 * cwd           printer spool directory        (printcap "sd")
 * argv:
 *     bjif [-c] -wwidth -llength -iindent -n {login} -h {host} [ {acctfile} ]
 * environ:
 *     VERBOSELOG
 *              
 *
 * XXX need to handle signals.  on an interrupt, emit a control-D and exit
 *     with an appropriate status code.
 * XXX need to translate 8859/1 input to ibm code page whatever output
 *     (unless -c is given)
 */

#include <stdio.h>
#include <sys/types.h>

/*
 * exit status codes
 */
#define STATUS_OKAY     0       /* printed successfully */
#define STATUS_TEMPFAIL 1       /* failed - requeue */
#define STATUS_PERMFAIL 2       /* failed - don't requeue */

int input_fd = 0;
int printer_fd = 1;

char *filtername;
char *printer = "unknown";
char *user = "anonymous";
char *host = "somewhere";
int width = 0;
int length = 0;
int indent = 0;
int cflag = 0;
char *acctfile;

main (argc, argv)
char **argv;
{
    char *ptr;
    time_t now;

    filtername = argv[0];
    ptr = (argv[0] + strlen(argv[0])) - 2;

    while (argc > 1) {
        if (argv[1][0] == '-') { 
            switch (argv[1][1]) {
            case 'n':           /* -n login */
                user = argv[2];
                argc -= 2;
                argv += 2;
                break;
            case 'h':           /* -h host */
                host = argv[2];
                argc -= 2;
                argv += 2;
                break;
            case 'w':           /* -wwidth (characters) */
            case 'x':           /* -xwidth (pixels) */
                width = atoi(argv[1]+2);
                --argc;
                ++argv;
                break;
            case 'l':           /* -llength (lines) */
            case 'y':           /* -ylength (pixels) */
                length = atoi(argv[1]+2);
                --argc;
                ++argv;
                break;
            case 'i':           /* -iindent (characters) */
                indent = atoi(argv[1]+2);
                --argc;
                ++argv;
                break;
            case 'c':           /* pass control characters */
                cflag = 1;
                --argc;
                ++argv;
                break;
            }
        }
        else {
            acctfile = argv[1];
            --argc;
            ++argv;
        }
    }
    time (&now);
    fprintf (stderr, "%s: %s:%s %s start - %s", filtername, host,
             user, printer, ctime (&now));
    fflush (stderr);

    print_text ();

    time (&now);
    fprintf (stderr, "%s: %s:%s %s end - %s", filtername, host,
             user, printer, ctime (&now));
    fflush (stderr);
    exit (STATUS_OKAY);
}

#define NEXT_TAB(c) (((c) + 8) & ~07)
#define GS \
    "/usr/local/bin/gs -sDEVICE=bj200 -dSAFER -r360x360 -sOutputFile=- -q -"

print_text ()
{
    int c;
    int col = 0;
    int line = 0;
    int i;

    /* skip initial control-d, it probably introduces a Postscript file */

    if ((c = getchar ()) != '\004')
        ungetc (c, stdin);

    /* if file starts with '%!', pipe it to ghostscript... */

    if ((c = getchar ()) == '%') {
        if ((c = getchar ()) == '!') {
            FILE *fp;
            char *gs;
            char *getenv ();

            if ((gs = getenv ("GHOSTSCRIPT")) == NULL)
                gs = GS;
            if ((fp = popen (gs, "w")) == NULL) {
                fprintf (stderr, "%s: can't open pipe to GhostScript\n",
                         filtername);
                exit (1);
            }
            putc ('%', fp);
            putc ('!', fp);
            while ((c = getchar ()) != EOF)
                putc (c, fp);
            pclose (fp);
            exit (0);
        }
        else {
            ungetc (c, stdin);
            c = '%';
        }
    }
    /*
     * NB: 'c' contains first character of file
     *
     * XXX need to do line wrapping
     */
    do {
        switch (c) {
            case '\t':
                for (i = col; i < NEXT_TAB(col); ++i)
                    putchar (' ');
                col = i;
                break;
            case '\n':
                if (col != 0)
                    putchar ('\r');
                putchar ('\n');
                col = 0;
                line++;
                if (line > 62) {
                    putchar ('\f');
                    line = 0;
                }
                break;
            case '\r':
                putchar (c);
                col = 0;
                break;
            case '\b':
                putchar (c);
                if (--col < 0)
                    col = 0;
                break;
            case '\f':
                if (col != 0)
                    putchar ('\r');
                putchar (c);
                line = 0;
                col = 0;
                break;
            default:
                putchar (c);
                col++;
                break;
        }
        if (ferror (stdout))
            exit (STATUS_PERMFAIL);
    } while ((c = getchar ()) != EOF);

    if (line != 0) {
        if (col != 0)
            putchar ('\r');
        putchar ('\f');
    }
}

--------
Take the pledge! "I do not limit my speech to satisfy the whims of Congress."