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 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 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 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 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 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 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