From: doleh@mcs.kent.edu (Yaser K. Doleh)
Newsgroups: comp.sys.sun.admin
Subject: Re: Looking to replace NeWSprint.
Date: 2 Jan 93 15:44:40 GMT
Reply-To: doleh@mcs.kent.edu
Distribution: comp
Organization: Dept. of Math and Computer Science, Kent State U.

Here is a program that will read a raw pbm file and print it to sparcprinter
We use Ghostscript to print PS files, use dvips to print dvi files.
If you are interested in the script, I will post it too.

Enjoy.
------------------
Yaser Doleh

to try it 
sparcprint <file.pbm >/dev/lpvi0

--------------------------------------------------------------------------
/* Copright 1992  Yaser K. Doleh & Jeff Bailey */

#include <stdio.h>
#include <sys/types.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <sys/asynch.h>
#include <signal.h>
#include "lpviio.h"

#define BUFSIZE 256
#define FAIL -1
#define SUCCESS 0
#define RAW_PBM "P4"
#ifndef STATUS_FILE
#define STATUS_FILE  "filter.status"
#endif
#define TRUE 1
#define FALSE 0

#define STR_OK   "Hey it worked"
#define WORKING  "I am working on it"
#define BAD_FILE "What the heck was that file !!!"
#define NO_MEMORY "I can't remeber what I was suppose to print"
#define INCOMPLETE "The file was not all there"

typedef struct msg_tbl {
    u_char	code;
    char	*msg;
} msg_tbl;
	
struct msg_tbl  err_code_str[] = {
    EMOTOR, "motor malfunction",
    EROS, "optical subsystem malfunction",
    EFUSER, "fuser assembly malfunction",
    XEROFAIL, "imaging subsystem malfunction",
    ILCKOPEN, "printer cover not locked",
    NOTRAY, "tray not (properly) installed",
    NOPAPR, "out of media (paper)",
    XITJAM, "media (paper) jam in exit path",
    MISFEED, "media (paper) jam in feed path",
    WDRUMX, "drum assembly almost expended",
    WDEVEX, "toner cartridge almost expended",
    NODRUM, "drum assembly not (properly) installed",
    NODEVE, "toner cartridge not (properly) installed",
    EDRUMX, "drum assembly requires replacement",
    EDEVEX, "toner cartridge requires replacement",
    ENGCOLD, "fuser warming up",
    TIMEOUT, "printer not responding"
};

struct msg_tbl  err_class_str[] = {
    ENGWARN, "non-fatal printer error: ",
    ENGFATL, "fatal printer error: ",
    EDRVR, "fatal communication error: "
};

struct queue_el {
    char *buf;
    int  bufs;
    aio_result_t  resultp;
};

int exit_err=0;
int write_pending=0;
struct queue_el queue_el;
extern char *sys_errlist[];

output_status(dst_str)
char *dst_str;
{
  FILE *fd;

  if ((fd = fopen(STATUS_FILE, "w")) == NULL ) {
     perror(STATUS_FILE);
     exit(exit_err);
  }

  fprintf(fd,"%s\n",dst_str);
  fclose(fd);
}

queue_page(buffer, size)
char *buffer;
int  size;
{
    queue_el.buf = buffer;
    queue_el.bufs = size;
    aiowrite(fileno(stdout), buffer, size, 0, 0, &(queue_el.resultp));
    write_pending = TRUE;
    return;
}

int check_page(dst_str)
char *dst_str;
{
    struct lpvi_err err_struct;
    int i;
    char temp[BUFSIZE];
    aio_result_t *wait_return;

    strcpy(temp, dst_str);
try_again:
    wait_return = (aio_result_t *)aiowait(NULL);

    if (queue_el.resultp.aio_return != queue_el.bufs ) {
        dst_str[0] = (char)NULL;
	ioctl(fileno(stdout), LPVIIOC_TESTIO, &err_struct);

	if (ioctl(fileno(stdout), LPVIIOC_GETERR, &err_struct) < 0) {
	    perror("ioctl LPVIIOC_GETERR ");
	    sprintf(dst_str, "ioctl: LPVIIOC_GETERR, %s",  sys_errlist[errno]);
	} else {
	    for(i = 0; i < (sizeof(err_class_str) / sizeof(msg_tbl)); i++ ){
		if (err_class_str[i].code == err_struct.err_type) {
		     strcpy(dst_str, err_class_str[i].msg);
		     break;
		}
	    }
	    
	    for(i = 0; i < (sizeof(err_code_str) / sizeof(msg_tbl)); i++ ){
		if (err_code_str[i].code == err_struct.err_code) {
		     strcat(dst_str, err_code_str[i].msg);
		     break;
		}
	    }

	    output_status(dst_str);
	}

	if (err_struct.err_type == ENGWARN) {
	    sleep(5);
	    queue_page(queue_el.buf,queue_el.bufs);
	    goto try_again;
	}
        if (err_struct.err_type != 0) {
	    free(queue_el.buf);
	    write_pending = FALSE;
	    return(FAIL);
	} 
    } 
    
    strcpy(dst_str, temp);
    output_status(dst_str);
    free(queue_el.buf);
    write_pending = FALSE;
    return(SUCCESS);
}

int print_a_page(buffer, size, dst_str)
char *buffer, *dst_str;
int  size;
{
    if (write_pending)
    {
	if (check_page(dst_str) == FAIL) return(FAIL);
    }

    queue_page(buffer, size);
    return(SUCCESS);
}

char *fetch_line(buf)
char *buf;
{
    char *ret;

    while (((ret = gets(buf)) != (char *)NULL) && buf[0] == '#');
    return(ret);
}

main(argc, argv)
int argc;
char *argv[];
{
  char line[BUFSIZE], dst_str[BUFSIZE], *buffer;
  int  pixel_width, byte_width, height, i, c;
  struct lpvi_page page;
  int top=0, left=0, res=300;
  int center=FALSE;

  signal(SIGPIPE, SIG_IGN);

  for (i = 1; i < argc; i++)
  {
    if (!strcmp(argv[i], "-r"))
    {
	res = atoi(argv[++i]);

	if ((res != 300) && (res != 400))
	{
	    fprintf(stderr,"Invalid printer resolution: %d\n", res);
	    exit(-1);
	}
	continue;
    }

    if (!strcmp(argv[i], "-c"))
    {
	center = TRUE;
	continue;
    }
  }

  strcpy(dst_str, WORKING);
  output_status(dst_str); 

  while(fetch_line(line) != (char *)NULL ) {
    if (strcmp(line, RAW_PBM)) {
	fprintf(stderr, BAD_FILE);
	strcpy(dst_str, BAD_FILE);
	exit_err = -1;
	break;
    }

    if ((fetch_line(line) == (char *)NULL) ||
	(sscanf(line, "%d %d\n", &pixel_width, &height) != 2))
    {
	fprintf(stderr, BAD_FILE);
	strcpy(dst_str, BAD_FILE);
	exit_err = -1;
	break;
    }

    byte_width = (pixel_width + 7) / 8 ;

    if ((buffer = (char *)malloc(byte_width*height)) == NULL ) {
	fprintf(stderr, NO_MEMORY);
	strcpy(dst_str, NO_MEMORY);
	exit_err = 1;
	break;
    }

    for (i = 0; i <  (byte_width * height); i++ ) {
	if ((c = getchar()) == EOF) {
	    fprintf(stderr, INCOMPLETE);
	    strcpy(dst_str, INCOMPLETE);
	    exit_err = -1;
	    height = i / byte_width;
	    break;
	}
	buffer[i] = c;
    }

    if (center)
    {
	top = ((10.5 * res) - height) / 2;
	left = ((8 * res) - pixel_width) / 2;
	if (top < 0) top = 0;
	if (left < 0) left = 0;
    }

    page.bitmap_width = byte_width;
    page.page_width = pixel_width;
    page.page_length = height;
    page.top_margin = top;
    page.left_margin = left;
    page.resolution = res;

    if (ioctl(fileno(stdout), LPVIIOC_SETPAGE, &page) != 0) {
	perror("ioctl LPVIIOC_SETPAGE ");
	exit(-1);
    }
    if (print_a_page(buffer, byte_width * height, dst_str) == FAIL) {
	exit_err = -1;
	break;
    }
  }

  if (write_pending) {
    if (check_page(dst_str) == FAIL) {
	exit_err = -1;
    }
  }

  if (exit_err)
      output_status(dst_str);
  else
      output_status(STR_OK);
  exit(exit_err);
}
Newsgroups: comp.sys.sun.admin