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