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