17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
57c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
67c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
77c478bd9Sstevel@tonic-gate  * with the License.
87c478bd9Sstevel@tonic-gate  *
97c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
107c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
117c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
127c478bd9Sstevel@tonic-gate  * and limitations under the License.
137c478bd9Sstevel@tonic-gate  *
147c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
157c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
167c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
177c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
187c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
197c478bd9Sstevel@tonic-gate  *
207c478bd9Sstevel@tonic-gate  * CDDL HEADER END
217c478bd9Sstevel@tonic-gate  */
22*f928ce67Sceastha /*
23*f928ce67Sceastha  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
24*f928ce67Sceastha  * Use is subject to license terms.
25*f928ce67Sceastha  */
26*f928ce67Sceastha 
277c478bd9Sstevel@tonic-gate /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
287c478bd9Sstevel@tonic-gate /*	  All Rights Reserved  	*/
297c478bd9Sstevel@tonic-gate 
307c478bd9Sstevel@tonic-gate /*
317c478bd9Sstevel@tonic-gate  *
327c478bd9Sstevel@tonic-gate  * Stuff that slows the transmission of jobs to PostScript printers. ONLY use it
337c478bd9Sstevel@tonic-gate  * if you appear to be having trouble with flow control. The idea is simple - only
347c478bd9Sstevel@tonic-gate  * send a significant amount of data when we're certain the printer is in the
357c478bd9Sstevel@tonic-gate  * WAITING state. Depends on receiving status messages and only works when the
367c478bd9Sstevel@tonic-gate  * program is run as a single process. What's done should stop printer generated
377c478bd9Sstevel@tonic-gate  * XOFFs - provided our input buffer (ie. blocksize) is sufficiently small. Was
387c478bd9Sstevel@tonic-gate  * originally included in the postio.tmp directory, but can now be requested with
397c478bd9Sstevel@tonic-gate  * the -S option. Considered eliminating this code, but some printers still depend
407c478bd9Sstevel@tonic-gate  * on it. In particular Datakit connections made using Datakit PVCs and DACUs seem
417c478bd9Sstevel@tonic-gate  * to have the most problems. Much of the new stuff that was added can't work when
427c478bd9Sstevel@tonic-gate  * you use this code.
437c478bd9Sstevel@tonic-gate  *
447c478bd9Sstevel@tonic-gate  */
457c478bd9Sstevel@tonic-gate 
467c478bd9Sstevel@tonic-gate 
477c478bd9Sstevel@tonic-gate #include <stdio.h>
487c478bd9Sstevel@tonic-gate 
497c478bd9Sstevel@tonic-gate #include "gen.h"
507c478bd9Sstevel@tonic-gate #include "postio.h"
517c478bd9Sstevel@tonic-gate 
527c478bd9Sstevel@tonic-gate 
537c478bd9Sstevel@tonic-gate extern char	*block;
547c478bd9Sstevel@tonic-gate extern int	blocksize;
557c478bd9Sstevel@tonic-gate extern int	head;
567c478bd9Sstevel@tonic-gate extern int	tail;
577c478bd9Sstevel@tonic-gate extern char	*line;
587c478bd9Sstevel@tonic-gate extern char	mesg[];
597c478bd9Sstevel@tonic-gate extern int	ttyo;
607c478bd9Sstevel@tonic-gate 
61*f928ce67Sceastha static int	writeblock(int);
627c478bd9Sstevel@tonic-gate 
637c478bd9Sstevel@tonic-gate /*****************************************************************************/
647c478bd9Sstevel@tonic-gate 
657c478bd9Sstevel@tonic-gate 
66*f928ce67Sceastha void
slowsend(int fd_in)67*f928ce67Sceastha slowsend(int fd_in)
68*f928ce67Sceastha     /* next input file */
697c478bd9Sstevel@tonic-gate {
707c478bd9Sstevel@tonic-gate 
717c478bd9Sstevel@tonic-gate /*
727c478bd9Sstevel@tonic-gate  *
737c478bd9Sstevel@tonic-gate  * A slow version of send() that's very careful about when data is sent to the
747c478bd9Sstevel@tonic-gate  * printer. Should help prevent overflowing the printer's input buffer, provided
757c478bd9Sstevel@tonic-gate  * blocksize is sufficiently small (1024 should be safe). It's a totally kludged
767c478bd9Sstevel@tonic-gate  * up routine that should ONLY be used if you have constant transmission problems.
777c478bd9Sstevel@tonic-gate  * There's really no way it will be able to drive a printer much faster that about
787c478bd9Sstevel@tonic-gate  * six pages a minute, even for the simplest jobs. Get it by using the -S option.
797c478bd9Sstevel@tonic-gate  *
807c478bd9Sstevel@tonic-gate  */
817c478bd9Sstevel@tonic-gate 
827c478bd9Sstevel@tonic-gate 
837c478bd9Sstevel@tonic-gate     while ( readblock(fd_in) )
847c478bd9Sstevel@tonic-gate 
857c478bd9Sstevel@tonic-gate 	switch ( getstatus(0) )  {
867c478bd9Sstevel@tonic-gate 
877c478bd9Sstevel@tonic-gate 	    case WAITING:
887c478bd9Sstevel@tonic-gate 		    writeblock(blocksize);
897c478bd9Sstevel@tonic-gate 		    break;
907c478bd9Sstevel@tonic-gate 
917c478bd9Sstevel@tonic-gate 	    case BUSY:
927c478bd9Sstevel@tonic-gate 	    case IDLE:
937c478bd9Sstevel@tonic-gate 	    case PRINTING:
947c478bd9Sstevel@tonic-gate 		    writeblock(30);
957c478bd9Sstevel@tonic-gate 		    break;
967c478bd9Sstevel@tonic-gate 
977c478bd9Sstevel@tonic-gate 	    case NOSTATUS:
987c478bd9Sstevel@tonic-gate 	    case UNKNOWN:
997c478bd9Sstevel@tonic-gate 		    break;
1007c478bd9Sstevel@tonic-gate 
1017c478bd9Sstevel@tonic-gate 	    case PRINTERERROR:
1027c478bd9Sstevel@tonic-gate 		    sleep(30);
1037c478bd9Sstevel@tonic-gate 		    break;
1047c478bd9Sstevel@tonic-gate 
1057c478bd9Sstevel@tonic-gate 	    case ERROR:
1067c478bd9Sstevel@tonic-gate 		    fprintf(stderr, "%s", mesg);	/* for csw */
1077c478bd9Sstevel@tonic-gate 		    error(FATAL, "PostScript Error");
1087c478bd9Sstevel@tonic-gate 		    break;
1097c478bd9Sstevel@tonic-gate 
1107c478bd9Sstevel@tonic-gate 	    case FLUSHING:
1117c478bd9Sstevel@tonic-gate 		    error(FATAL, "Flushing Job");
1127c478bd9Sstevel@tonic-gate 		    break;
1137c478bd9Sstevel@tonic-gate 
1147c478bd9Sstevel@tonic-gate 	    case DISCONNECT:
1157c478bd9Sstevel@tonic-gate 		    error(FATAL, "Disconnected - printer may be offline");
1167c478bd9Sstevel@tonic-gate 		    break;
1177c478bd9Sstevel@tonic-gate 
1187c478bd9Sstevel@tonic-gate 	    default:
1197c478bd9Sstevel@tonic-gate 		    sleep(2);
1207c478bd9Sstevel@tonic-gate 		    break;
1217c478bd9Sstevel@tonic-gate 
1227c478bd9Sstevel@tonic-gate 	}   /* End switch */
1237c478bd9Sstevel@tonic-gate 
1247c478bd9Sstevel@tonic-gate }   /* End of send */
1257c478bd9Sstevel@tonic-gate 
1267c478bd9Sstevel@tonic-gate 
1277c478bd9Sstevel@tonic-gate /*****************************************************************************/
1287c478bd9Sstevel@tonic-gate 
1297c478bd9Sstevel@tonic-gate 
130*f928ce67Sceastha static int
writeblock(int num)131*f928ce67Sceastha writeblock(int num)
132*f928ce67Sceastha     /* most bytes we'll write */
1337c478bd9Sstevel@tonic-gate {
1347c478bd9Sstevel@tonic-gate     int		count;			/* bytes successfully written */
1357c478bd9Sstevel@tonic-gate 
1367c478bd9Sstevel@tonic-gate /*
1377c478bd9Sstevel@tonic-gate  *
1387c478bd9Sstevel@tonic-gate  * Called from send() when it's OK to send the next block to the printer. head
1397c478bd9Sstevel@tonic-gate  * is adjusted after the write, and the number of bytes that were successfully
1407c478bd9Sstevel@tonic-gate  * written is returned to the caller.
1417c478bd9Sstevel@tonic-gate  *
1427c478bd9Sstevel@tonic-gate  */
1437c478bd9Sstevel@tonic-gate 
1447c478bd9Sstevel@tonic-gate 
1457c478bd9Sstevel@tonic-gate     if ( num > tail - head )
1467c478bd9Sstevel@tonic-gate 	num = tail - head;
1477c478bd9Sstevel@tonic-gate 
1487c478bd9Sstevel@tonic-gate     if ( (count = write(ttyo, &block[head], num)) == -1 )
1497c478bd9Sstevel@tonic-gate 	error(FATAL, "error writing to %s", line);
1507c478bd9Sstevel@tonic-gate     else if ( count == 0 )
1517c478bd9Sstevel@tonic-gate 	error(FATAL, "printer appears to be offline");
1527c478bd9Sstevel@tonic-gate 
1537c478bd9Sstevel@tonic-gate     head += count;
1547c478bd9Sstevel@tonic-gate     return(count);
1557c478bd9Sstevel@tonic-gate 
1567c478bd9Sstevel@tonic-gate }   /* End of writeblock */
1577c478bd9Sstevel@tonic-gate 
1587c478bd9Sstevel@tonic-gate 
1597c478bd9Sstevel@tonic-gate /*****************************************************************************/
1607c478bd9Sstevel@tonic-gate 
161