xref: /illumos-gate/usr/src/cmd/lp/filter/postscript/postio/slowsend.c (revision 4bc0a2ef2b7ba50a7a717e7ddbf31472ad28e358)
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 #pragma ident	"%Z%%M%	%I%	%E% SMI"
31 /*
32  *
33  * Stuff that slows the transmission of jobs to PostScript printers. ONLY use it
34  * if you appear to be having trouble with flow control. The idea is simple - only
35  * send a significant amount of data when we're certain the printer is in the
36  * WAITING state. Depends on receiving status messages and only works when the
37  * program is run as a single process. What's done should stop printer generated
38  * XOFFs - provided our input buffer (ie. blocksize) is sufficiently small. Was
39  * originally included in the postio.tmp directory, but can now be requested with
40  * the -S option. Considered eliminating this code, but some printers still depend
41  * on it. In particular Datakit connections made using Datakit PVCs and DACUs seem
42  * to have the most problems. Much of the new stuff that was added can't work when
43  * you use this code.
44  *
45  */
46 
47 
48 #include <stdio.h>
49 
50 #include "gen.h"
51 #include "postio.h"
52 
53 
54 extern char	*block;
55 extern int	blocksize;
56 extern int	head;
57 extern int	tail;
58 extern char	*line;
59 extern char	mesg[];
60 extern int	ttyo;
61 
62 static int	writeblock(int);
63 
64 /*****************************************************************************/
65 
66 
67 void
68 slowsend(int fd_in)
69     /* next input file */
70 {
71 
72 /*
73  *
74  * A slow version of send() that's very careful about when data is sent to the
75  * printer. Should help prevent overflowing the printer's input buffer, provided
76  * blocksize is sufficiently small (1024 should be safe). It's a totally kludged
77  * up routine that should ONLY be used if you have constant transmission problems.
78  * There's really no way it will be able to drive a printer much faster that about
79  * six pages a minute, even for the simplest jobs. Get it by using the -S option.
80  *
81  */
82 
83 
84     while ( readblock(fd_in) )
85 
86 	switch ( getstatus(0) )  {
87 
88 	    case WAITING:
89 		    writeblock(blocksize);
90 		    break;
91 
92 	    case BUSY:
93 	    case IDLE:
94 	    case PRINTING:
95 		    writeblock(30);
96 		    break;
97 
98 	    case NOSTATUS:
99 	    case UNKNOWN:
100 		    break;
101 
102 	    case PRINTERERROR:
103 		    sleep(30);
104 		    break;
105 
106 	    case ERROR:
107 		    fprintf(stderr, "%s", mesg);	/* for csw */
108 		    error(FATAL, "PostScript Error");
109 		    break;
110 
111 	    case FLUSHING:
112 		    error(FATAL, "Flushing Job");
113 		    break;
114 
115 	    case DISCONNECT:
116 		    error(FATAL, "Disconnected - printer may be offline");
117 		    break;
118 
119 	    default:
120 		    sleep(2);
121 		    break;
122 
123 	}   /* End switch */
124 
125 }   /* End of send */
126 
127 
128 /*****************************************************************************/
129 
130 
131 static int
132 writeblock(int num)
133     /* most bytes we'll write */
134 {
135     int		count;			/* bytes successfully written */
136 
137 /*
138  *
139  * Called from send() when it's OK to send the next block to the printer. head
140  * is adjusted after the write, and the number of bytes that were successfully
141  * written is returned to the caller.
142  *
143  */
144 
145 
146     if ( num > tail - head )
147 	num = tail - head;
148 
149     if ( (count = write(ttyo, &block[head], num)) == -1 )
150 	error(FATAL, "error writing to %s", line);
151     else if ( count == 0 )
152 	error(FATAL, "printer appears to be offline");
153 
154     head += count;
155     return(count);
156 
157 }   /* End of writeblock */
158 
159 
160 /*****************************************************************************/
161 
162