1*7dd7cddfSDavid du Colombier /*
2*7dd7cddfSDavid du Colombier *
3*7dd7cddfSDavid du Colombier * Stuff that slows the transmission of jobs to PostScript printers. ONLY use it
4*7dd7cddfSDavid du Colombier * if you appear to be having trouble with flow control. The idea is simple - only
5*7dd7cddfSDavid du Colombier * send a significant amount of data when we're certain the printer is in the
6*7dd7cddfSDavid du Colombier * WAITING state. Depends on receiving status messages and only works when the
7*7dd7cddfSDavid du Colombier * program is run as a single process. What's done should stop printer generated
8*7dd7cddfSDavid du Colombier * XOFFs - provided our input buffer (ie. blocksize) is sufficiently small. Was
9*7dd7cddfSDavid du Colombier * originally included in the postio.tmp directory, but can now be requested with
10*7dd7cddfSDavid du Colombier * the -S option. Considered eliminating this code, but some printers still depend
11*7dd7cddfSDavid du Colombier * on it. In particular Datakit connections made using Datakit PVCs and DACUs seem
12*7dd7cddfSDavid du Colombier * to have the most problems. Much of the new stuff that was added can't work when
13*7dd7cddfSDavid du Colombier * you use this code and will be automatically disabled.
14*7dd7cddfSDavid du Colombier *
15*7dd7cddfSDavid du Colombier */
16*7dd7cddfSDavid du Colombier
17*7dd7cddfSDavid du Colombier #include <stdio.h>
18*7dd7cddfSDavid du Colombier
19*7dd7cddfSDavid du Colombier #include "gen.h"
20*7dd7cddfSDavid du Colombier #include "postio.h"
21*7dd7cddfSDavid du Colombier
22*7dd7cddfSDavid du Colombier extern char *block;
23*7dd7cddfSDavid du Colombier extern int blocksize;
24*7dd7cddfSDavid du Colombier extern int head;
25*7dd7cddfSDavid du Colombier extern int tail;
26*7dd7cddfSDavid du Colombier extern char *line;
27*7dd7cddfSDavid du Colombier extern char mesg[];
28*7dd7cddfSDavid du Colombier extern int ttyo;
29*7dd7cddfSDavid du Colombier
30*7dd7cddfSDavid du Colombier /*****************************************************************************/
31*7dd7cddfSDavid du Colombier
slowsend(fd_in)32*7dd7cddfSDavid du Colombier slowsend(fd_in)
33*7dd7cddfSDavid du Colombier
34*7dd7cddfSDavid du Colombier int fd_in; /* next input file */
35*7dd7cddfSDavid du Colombier
36*7dd7cddfSDavid du Colombier {
37*7dd7cddfSDavid du Colombier
38*7dd7cddfSDavid du Colombier /*
39*7dd7cddfSDavid du Colombier *
40*7dd7cddfSDavid du Colombier * A slow version of send() that's very careful about when data is sent to the
41*7dd7cddfSDavid du Colombier * printer. Should help prevent overflowing the printer's input buffer, provided
42*7dd7cddfSDavid du Colombier * blocksize is sufficiently small (1024 should be safe). It's a totally kludged
43*7dd7cddfSDavid du Colombier * up routine that should ONLY be used if you have constant transmission problems.
44*7dd7cddfSDavid du Colombier * There's really no way it will be able to drive a printer much faster that about
45*7dd7cddfSDavid du Colombier * six pages a minute, even for the simplest jobs. Get it by using the -S option.
46*7dd7cddfSDavid du Colombier *
47*7dd7cddfSDavid du Colombier */
48*7dd7cddfSDavid du Colombier
49*7dd7cddfSDavid du Colombier while ( readblock(fd_in) )
50*7dd7cddfSDavid du Colombier switch ( getstatus(0) ) {
51*7dd7cddfSDavid du Colombier case WAITING:
52*7dd7cddfSDavid du Colombier writeblock(blocksize);
53*7dd7cddfSDavid du Colombier break;
54*7dd7cddfSDavid du Colombier
55*7dd7cddfSDavid du Colombier case BUSY:
56*7dd7cddfSDavid du Colombier case IDLE:
57*7dd7cddfSDavid du Colombier case PRINTING:
58*7dd7cddfSDavid du Colombier writeblock(30);
59*7dd7cddfSDavid du Colombier break;
60*7dd7cddfSDavid du Colombier
61*7dd7cddfSDavid du Colombier case NOSTATUS:
62*7dd7cddfSDavid du Colombier case UNKNOWN:
63*7dd7cddfSDavid du Colombier break;
64*7dd7cddfSDavid du Colombier
65*7dd7cddfSDavid du Colombier case PRINTERERROR:
66*7dd7cddfSDavid du Colombier sleep(30);
67*7dd7cddfSDavid du Colombier break;
68*7dd7cddfSDavid du Colombier
69*7dd7cddfSDavid du Colombier case ERROR:
70*7dd7cddfSDavid du Colombier fprintf(stderr, "%s", mesg); /* for csw */
71*7dd7cddfSDavid du Colombier error(FATAL, "PostScript Error");
72*7dd7cddfSDavid du Colombier break;
73*7dd7cddfSDavid du Colombier
74*7dd7cddfSDavid du Colombier case FLUSHING:
75*7dd7cddfSDavid du Colombier error(FATAL, "Flushing Job");
76*7dd7cddfSDavid du Colombier break;
77*7dd7cddfSDavid du Colombier
78*7dd7cddfSDavid du Colombier case DISCONNECT:
79*7dd7cddfSDavid du Colombier error(FATAL, "Disconnected - printer may be offline");
80*7dd7cddfSDavid du Colombier break;
81*7dd7cddfSDavid du Colombier
82*7dd7cddfSDavid du Colombier default:
83*7dd7cddfSDavid du Colombier sleep(2);
84*7dd7cddfSDavid du Colombier break;
85*7dd7cddfSDavid du Colombier } /* End switch */
86*7dd7cddfSDavid du Colombier
87*7dd7cddfSDavid du Colombier } /* End of send */
88*7dd7cddfSDavid du Colombier
89*7dd7cddfSDavid du Colombier /*****************************************************************************/
90*7dd7cddfSDavid du Colombier
writeblock(num)91*7dd7cddfSDavid du Colombier static writeblock(num)
92*7dd7cddfSDavid du Colombier
93*7dd7cddfSDavid du Colombier int num; /* most bytes we'll write */
94*7dd7cddfSDavid du Colombier
95*7dd7cddfSDavid du Colombier {
96*7dd7cddfSDavid du Colombier
97*7dd7cddfSDavid du Colombier int count; /* bytes successfully written */
98*7dd7cddfSDavid du Colombier
99*7dd7cddfSDavid du Colombier /*
100*7dd7cddfSDavid du Colombier *
101*7dd7cddfSDavid du Colombier * Called from send() when it's OK to send the next block to the printer. head
102*7dd7cddfSDavid du Colombier * is adjusted after the write, and the number of bytes that were successfully
103*7dd7cddfSDavid du Colombier * written is returned to the caller.
104*7dd7cddfSDavid du Colombier *
105*7dd7cddfSDavid du Colombier */
106*7dd7cddfSDavid du Colombier
107*7dd7cddfSDavid du Colombier if ( num > tail - head )
108*7dd7cddfSDavid du Colombier num = tail - head;
109*7dd7cddfSDavid du Colombier
110*7dd7cddfSDavid du Colombier if ( (count = write(ttyo, &block[head], num)) == -1 )
111*7dd7cddfSDavid du Colombier error(FATAL, "error writing to %s", line);
112*7dd7cddfSDavid du Colombier else if ( count == 0 )
113*7dd7cddfSDavid du Colombier error(FATAL, "printer appears to be offline");
114*7dd7cddfSDavid du Colombier
115*7dd7cddfSDavid du Colombier head += count;
116*7dd7cddfSDavid du Colombier return(count);
117*7dd7cddfSDavid du Colombier
118*7dd7cddfSDavid du Colombier } /* End of writeblock */
119*7dd7cddfSDavid du Colombier
120*7dd7cddfSDavid du Colombier /*****************************************************************************/
121*7dd7cddfSDavid du Colombier
122