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 2004 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #include <ctype.h> 28 #include <limits.h> 29 #include <locale.h> 30 #include <nl_types.h> 31 #include <stdlib.h> 32 #include <stdio.h> 33 #include <string.h> 34 #include <unistd.h> 35 #include <errno.h> 36 37 #define FF '\f' 38 #define NL '\n' 39 #define NUL '\0' 40 41 static void usage(void); 42 static void disp_file(FILE *f, char *filename); 43 static FILE *get_next_file(int, char *, char *[], int); 44 static void finish(int need_a_newline); 45 46 int estatus = 0; /* exit status */ 47 int i; /* argv index */ 48 49 int 50 main(int argc, char *argv[]) 51 { 52 int c; 53 int form_feeds = 0; 54 int need_a_newline = 0; 55 char *filename = NULL; 56 FILE *f; 57 58 (void) setlocale(LC_ALL, ""); 59 #if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */ 60 #define TEXT_DOMAIN "SYS_TEST" /* Use this only if it were not */ 61 #endif 62 63 (void) textdomain(TEXT_DOMAIN); 64 65 while ((c = getopt(argc, argv, "f")) != EOF) { 66 switch (c) { 67 case 'f': 68 form_feeds = 1; 69 break; 70 71 case '?': 72 usage(); 73 } 74 } 75 76 i = optind; 77 if (argc <= i) { 78 filename = NULL; 79 f = stdin; 80 } else { 81 f = get_next_file(need_a_newline, filename, argv, argc); 82 } 83 84 need_a_newline = 0; 85 for (;;) { 86 /* interpret the first character in the line */ 87 88 c = getc(f); 89 switch (c) { 90 case EOF: 91 disp_file(f, filename); 92 93 if (i >= argc) 94 finish(need_a_newline); 95 96 f = get_next_file(need_a_newline, filename, argv, argc); 97 98 if (need_a_newline) { 99 (void) putchar(NL); 100 need_a_newline = 0; 101 } 102 103 if (form_feeds) 104 (void) putchar(FF); 105 106 continue; 107 108 case NL: 109 if (need_a_newline) 110 (void) putchar(NL); 111 need_a_newline = 1; 112 continue; 113 114 case '+': 115 if (need_a_newline) 116 (void) putchar('\r'); 117 break; 118 119 case '0': 120 if (need_a_newline) 121 (void) putchar(NL); 122 (void) putchar(NL); 123 break; 124 125 case '1': 126 if (need_a_newline) 127 (void) putchar(NL); 128 (void) putchar(FF); 129 break; 130 131 case ' ': 132 default: 133 if (need_a_newline) 134 (void) putchar(NL); 135 break; 136 } 137 138 need_a_newline = 0; 139 140 for (;;) { 141 c = getc(f); 142 if (c == NL) { 143 need_a_newline = 1; 144 break; 145 } else if (c == EOF) { 146 disp_file(f, filename); 147 148 if (i >= argc) 149 finish(need_a_newline); 150 151 f = get_next_file(need_a_newline, filename, 152 argv, argc); 153 154 if (form_feeds) { 155 (void) putchar(NL); 156 (void) putchar(FF); 157 need_a_newline = 0; 158 break; 159 } 160 } else { 161 (void) putchar(c); 162 } 163 } 164 } 165 /* NOTREACHED */ 166 return (0); 167 } 168 169 static void 170 usage(void) 171 { 172 (void) fprintf(stderr, gettext("usage: asa [-f] [-|file...]\n")); 173 exit(1); 174 } 175 176 177 static void 178 disp_file(FILE *f, char *filename) 179 { 180 181 if (ferror(f)) { 182 int serror = errno; 183 if (filename) { 184 (void) fprintf(stderr, gettext( 185 "asa: read error on file %s\n"), filename); 186 } else { 187 (void) fprintf(stderr, gettext( 188 "asa: read error on standard input\n")); 189 } 190 errno = serror; 191 perror(""); 192 estatus = 1; 193 } 194 195 (void) fclose(f); 196 197 } 198 199 static FILE * 200 get_next_file(int need_a_newline, char *filename, char *argv[], int argc) 201 { 202 FILE *f; 203 if (strcmp(argv[i], "-") == 0) { 204 filename = NULL; 205 f = stdin; 206 } else { 207 /* 208 * Process each file operand. If unsuccessful, affect the 209 * exit status and continue processing the next operand. 210 */ 211 filename = argv[i]; 212 while ((f = fopen(filename, "r")) == NULL) { 213 int serror = errno; 214 (void) fprintf(stderr, 215 gettext("asa: cannot open %s:"), filename); 216 errno = serror; 217 perror(""); 218 estatus = 1; 219 if (++i < argc) { 220 if (strcmp(argv[i], "-") == 0) { 221 filename = NULL; 222 f = stdin; 223 break; 224 } else { 225 filename = argv[i]; 226 } 227 } else { 228 finish(need_a_newline); 229 } 230 } 231 } 232 ++i; 233 return (f); 234 } 235 236 static void 237 finish(int need_a_newline) 238 { 239 if (need_a_newline) 240 (void) putchar(NL); 241 exit(estatus); 242 } 243