1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
28 /*	  All Rights Reserved  	*/
29 
30 /*
31  *
32  * Stuff that slows the transmission of jobs to PostScript printers. ONLY use it
33  * if you appear to be having trouble with flow control. The idea is simple - only
34  * send a significant amount of data when we're certain the printer is in the
35  * WAITING state. Depends on receiving status messages and only works when the
36  * program is run as a single process. What's done should stop printer generated
37  * XOFFs - provided our input buffer (ie. blocksize) is sufficiently small. Was
38  * originally included in the postio.tmp directory, but can now be requested with
39  * the -S option. Considered eliminating this code, but some printers still depend
40  * on it. In particular Datakit connections made using Datakit PVCs and DACUs seem
41  * to have the most problems. Much of the new stuff that was added can't work when
42  * you use this code.
43  *
44  */
45 
46 
47 #include <stdio.h>
48 
49 #include "gen.h"
50 #include "postio.h"
51 
52 
53 extern char	*block;
54 extern int	blocksize;
55 extern int	head;
56 extern int	tail;
57 extern char	*line;
58 extern char	mesg[];
59 extern int	ttyo;
60 
61 static int	writeblock(int);
62 
63 /*****************************************************************************/
64 
65 
66 void
slowsend(int fd_in)67 slowsend(int fd_in)
68     /* next input file */
69 {
70 
71 /*
72  *
73  * A slow version of send() that's very careful about when data is sent to the
74  * printer. Should help prevent overflowing the printer's input buffer, provided
75  * blocksize is sufficiently small (1024 should be safe). It's a totally kludged
76  * up routine that should ONLY be used if you have constant transmission problems.
77  * There's really no way it will be able to drive a printer much faster that about
78  * six pages a minute, even for the simplest jobs. Get it by using the -S option.
79  *
80  */
81 
82 
83     while ( readblock(fd_in) )
84 
85 	switch ( getstatus(0) )  {
86 
87 	    case WAITING:
88 		    writeblock(blocksize);
89 		    break;
90 
91 	    case BUSY:
92 	    case IDLE:
93 	    case PRINTING:
94 		    writeblock(30);
95 		    break;
96 
97 	    case NOSTATUS:
98 	    case UNKNOWN:
99 		    break;
100 
101 	    case PRINTERERROR:
102 		    sleep(30);
103 		    break;
104 
105 	    case ERROR:
106 		    fprintf(stderr, "%s", mesg);	/* for csw */
107 		    error(FATAL, "PostScript Error");
108 		    break;
109 
110 	    case FLUSHING:
111 		    error(FATAL, "Flushing Job");
112 		    break;
113 
114 	    case DISCONNECT:
115 		    error(FATAL, "Disconnected - printer may be offline");
116 		    break;
117 
118 	    default:
119 		    sleep(2);
120 		    break;
121 
122 	}   /* End switch */
123 
124 }   /* End of send */
125 
126 
127 /*****************************************************************************/
128 
129 
130 static int
writeblock(int num)131 writeblock(int num)
132     /* most bytes we'll write */
133 {
134     int		count;			/* bytes successfully written */
135 
136 /*
137  *
138  * Called from send() when it's OK to send the next block to the printer. head
139  * is adjusted after the write, and the number of bytes that were successfully
140  * written is returned to the caller.
141  *
142  */
143 
144 
145     if ( num > tail - head )
146 	num = tail - head;
147 
148     if ( (count = write(ttyo, &block[head], num)) == -1 )
149 	error(FATAL, "error writing to %s", line);
150     else if ( count == 0 )
151 	error(FATAL, "printer appears to be offline");
152 
153     head += count;
154     return(count);
155 
156 }   /* End of writeblock */
157 
158 
159 /*****************************************************************************/
160 
161