[alt.sources] [comp.laser-printers] Input Filter to Solve PostScript Protocol Bug

david@WUBIOS.WUSTL.EDU (David J. Camp) (07/19/90)

Archive-name: igixon/04-Jul-90
Original-posting-by: david@WUBIOS.WUSTL.EDU (David J. Camp)
Original-subject: Input Filter to Solve PostScript Protocol Bug
Reposted-by: emv@math.lsa.umich.edu (Edward Vielmetti)

[Reposted from comp.laser-printers.
Comments on this service to emv@math.lsa.umich.edu (Edward Vielmetti).]

/*
After receiving a QMS-810/Turbo, we learned that there is an error in
the xon/xoff protocol that causes data to be lost.  The explanation that
we have heard is that the printer sends xoff, but fails to send xon.
When the wait timeout expires, it dumps the job and sends xon.

The following is a Unix input filter that circumvents this bug.  

Please report problems directly to me, since I am way behing in reading
mailing lists.  -David-

/* igixon.c -- input filter that accomodates erroneous flow control */
/*
Internet: david%wubios@wugate.wustl.edu     ^      Mr. David J. Camp
uucp: ...!uunet!wugate!wubios!david       < * >    Box 8067, Biostatistics
Washington University (314) 36-23635        v      660 South Euclid Avenue
"Depend on God, who has dominion."                 Saint Louis, MO 63110
*/

#define TIMEOUTSEC 280L /* Note printer wait timeout must be 300 */

#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/timeb.h>
#include <sys/time.h>

#ifndef TTYNAME
*** ERROR use -DTTYNAME=\"/dev/tty??\"
#endif

char * ttyname ();

void main (argc, argv)
int argc;
char * argv [];

{
int c;
long readfds;
struct timeval timeout;
time_t the_time;
int x,y;
FILE * outfile;
char * tty_name;
FILE * console;

nice (4);
console = popen ("/usr/ucb/logger -p daemon.notice -f -", "w");
if (console != NULL)
    setbuf (console, NULL);
#ifdef VERBOSE
if (console != NULL)
    fprintf (console, "igixon tty=%s\n", TTYNAME);
#endif
if (NULL == (outfile = freopen (TTYNAME, "r+", stdout)))
    {
    if (console != NULL)
        fprintf (console, "Cannot access port.\n");
    exit (3);
    }
setbuf (outfile, NULL);
system ("/usr/bin/stty 9600 raw -ixon -ixoff -parity ignpar istrip clocal -crtscts tabs -icanon -cstopb -opost -echo -echoe");
c = fgetc (stdin);
while (!feof (stdin))
    {
    timeout.tv_sec = 0L;
    timeout.tv_usec = 0L;
    readfds = (1 << fileno (outfile));
    while (select (fileno(outfile) + 1, &readfds, NULL, NULL, &timeout))
        {
        clearerr (outfile);
        x = fgetc (outfile);
        if (console != NULL && (x >= 040 || x == 012))
            fprintf (console, "%c", x);
        if (x == 023)
            {
            the_time = time (NULL) + TIMEOUTSEC;
            timeout.tv_sec = TIMEOUTSEC;
            timeout.tv_usec = 0L;
            readfds = 1 << fileno (outfile);
            while (select (fileno (outfile) + 1, &readfds, NULL, NULL, &timeout))
                {
                clearerr (outfile);
		y = fgetc (outfile);
                if (console != NULL && (x >= 040 || x == 012))
                    fprintf (console, "%c", y);
                if (y == 021)
                    break;
                else
                    {
                    timeout.tv_sec = the_time - time (NULL);
                    timeout.tv_usec = 0L;
                    if (timeout.tv_sec < 0L)
                        break;
                    }
                }
            }
        timeout.tv_sec = 0L;
        timeout.tv_usec = 0L;
        readfds = 1 << fileno (outfile);
        }
    fputc (c, outfile);
    c = fgetc (stdin);
    }
fprintf (outfile, " \n\004");
outputwait (fileno(outfile));
}

#include <sgtty.h>

outputwait(fd)
int fd;

{
int outchars;
 
while(ioctl(fd, TIOCOUTQ, &outchars) == 0 && outchars > 0)
    {
    sleep(1);
    }
}