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
main(int argc,char * argv[])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
usage(void)170 usage(void)
171 {
172 (void) fprintf(stderr, gettext("usage: asa [-f] [-|file...]\n"));
173 exit(1);
174 }
175
176
177 static void
disp_file(FILE * f,char * filename)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 *
get_next_file(int need_a_newline,char * filename,char * argv[],int argc)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
finish(int need_a_newline)237 finish(int need_a_newline)
238 {
239 if (need_a_newline)
240 (void) putchar(NL);
241 exit(estatus);
242 }
243