xref: /plan9/sys/src/cmd/postscript/postio/slowsend.c (revision 7dd7cddf99dd7472612f1413b4da293630e6b1bc)
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