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