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  * A few general purpose routines.
33  *
34  */
35 
36 
37 #include <stdio.h>
38 #include <stdarg.h>
39 #include <ctype.h>
40 #include <fcntl.h>
41 
42 #include "gen.h"			/* a few general purpose definitions */
43 #include "ext.h"			/* external variable declarations */
44 
45 
46 int	nolist = 0;			/* number of specified ranges */
47 int	olist[50];			/* processing range pairs */
48 
49 
50 
51 void
error(int kind,char * mesg,...)52 error(int kind, char *mesg, ...)
53 {
54 
55 
56 /*
57  *
58  * Called when we've run into some kind of program error. *mesg is printed using
59  * the control string arguments a?. We'll quit if we're not ignoring errors and
60  * kind is FATAL.
61  *
62  */
63 
64 
65     if ( mesg != NULL && *mesg != '\0' )  {
66 	va_list ap;
67 
68 	fprintf(stderr, "%s: ", prog_name);
69 	va_start(ap, mesg);
70 	vfprintf(stderr, mesg, ap);
71 	va_end(ap);
72 	if ( lineno > 0 )
73 	    fprintf(stderr, " (line %d)", lineno);
74 	if ( position > 0 )
75 	    fprintf(stderr, " (near byte %d)", position);
76 	putc('\n', stderr);
77     }	/* End if */
78 
79     if ( kind == FATAL && ignore == OFF )  {
80 	if ( temp_file != NULL )
81 	    unlink(temp_file);
82 	exit(x_stat | 01);
83     }	/* End if */
84 
85 }   /* End of error */
86 
87 
88 /*****************************************************************************/
89 
90 /*****************************************************************************/
91 
92 
93 void
out_list(str)94 out_list(str)
95 
96 
97     char	*str;			/* process ranges in this string */
98 
99 
100 {
101 
102 
103     int		start, stop;		/* end points */
104 
105 
106 /*
107  *
108  * Called to get the processing ranges that were specified by using the -o option.
109  * The range syntax should be identical to the one used in nroff and troff.
110  *
111  */
112 
113 
114     while ( *str && nolist < sizeof(olist) - 2 )  {
115 	start = stop = str_convert(&str, 0);
116 
117 	if ( *str == '-' && *str++ )
118 	    stop = str_convert(&str, 9999);
119 
120 	if ( start > stop )
121 	    error(FATAL, "illegal range %d-%d", start, stop);
122 
123 	olist[nolist++] = start;
124 	olist[nolist++] = stop;
125 
126 	if ( *str != '\0' ) str++;
127 
128     }	/* End while */
129 
130     olist[nolist] = 0;
131 
132 }   /* End of out_list */
133 
134 
135 /*****************************************************************************/
136 
137 
138 int
in_olist(num)139 in_olist(num)
140 
141 
142     int		num;			/* should we print this page? */
143 
144 
145 {
146 
147 
148     int		i;			/* just a loop index */
149 
150 
151 /*
152  *
153  * Returns ON if num represents a page that we're supposed to print. If no ranges
154  * were selected nolist will be 0 and we'll print everything.
155  *
156  */
157 
158 
159     if ( nolist == 0 )			/* everything's included */
160 	return(ON);
161 
162     for ( i = 0; i < nolist; i += 2 )
163 	if ( num >= olist[i] && num <= olist[i+1] )
164 	    return(ON);
165 
166     return(OFF);
167 
168 }   /* End of in_olist */
169 
170 
171 /*****************************************************************************/
172 
173 
174 int
cat(file)175 cat(file)
176 
177 
178     char	*file;			/* copy this file to stdout */
179 
180 
181 {
182 
183 
184     int		fd_in;			/* for the input */
185     int		fd_out;			/* and output files */
186     char	buf[512];		/* buffer for reads and writes */
187     int		count;			/* number of bytes we just read */
188 
189 
190 /*
191  *
192  * Copies *file to stdout - mostly for the prologue. Returns FALSE if there was a
193  * problem and TRUE otherwise.
194  *
195  */
196 
197 
198     fflush(stdout);
199 
200     if ( (fd_in = open(file, O_RDONLY)) == -1 )
201 	return(FALSE);
202 
203     fd_out = fileno(stdout);
204     while ( (count = read(fd_in, buf, sizeof(buf))) > 0 )
205 	write(fd_out, buf, count);
206 
207     close(fd_in);
208 
209     return(TRUE);
210 
211 }   /* End of cat */
212 
213 
214 /*****************************************************************************/
215 
216 
217 int
str_convert(str,err)218 str_convert(str, err)
219 
220 
221     char	**str;			/* get next number from this string */
222     int		err;			/* value returned on error */
223 
224 
225 {
226 
227 
228     int		i;			/* just a loop index */
229 
230 
231 /*
232  *
233  * Gets the next integer from **str and returns its value to the caller. If **str
234  * isn't an integer err is returned. *str is updated after each digit is processed.
235  *
236  */
237 
238 
239     if ( ! isdigit(**str) )		/* something's wrong */
240 	return(err);
241 
242     for ( i = 0; isdigit(**str); *str += 1 )
243 	i = 10 * i + **str - '0';
244 
245     return(i);
246 
247 }   /* End of str_convert */
248 
249 
250 /*****************************************************************************/
251 
252 
253 
254 
interrupt(sig)255 void interrupt(sig)
256 
257 
258     int		sig;			/* signal that we caught */
259 
260 
261 {
262 
263 
264 /*
265  *
266  * Called when we get a signal that we're supposed to catch.
267  *
268  */
269 
270 
271     if ( temp_file != NULL )
272 	unlink(temp_file);
273 
274     exit(1);
275 
276 }   /* End of interrupt */
277 
278 
279 /*****************************************************************************/
280 
281 
282