add Mfsiomap
[unix-history] / usr / src / bin / cat / cat.c
... / ...
CommitLineData
1/*
2 * Copyright (c) 1989 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Kevin Fall.
7 *
8 * Redistribution and use in source and binary forms are permitted
9 * provided that the above copyright notice and this paragraph are
10 * duplicated in all such forms and that any documentation,
11 * advertising materials, and other materials related to such
12 * distribution and use acknowledge that the software was developed
13 * by the University of California, Berkeley. The name of the
14 * University may not be used to endorse or promote products derived
15 * from this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
19 */
20
21#ifndef lint
22char copyright[] =
23"@(#) Copyright (c) 1989 The Regents of the University of California.\n\
24 All rights reserved.\n";
25#endif /* not lint */
26
27#ifndef lint
28static char sccsid[] = "@(#)cat.c 5.7 (Berkeley) %G%";
29#endif /* not lint */
30
31#include <sys/param.h>
32#include <sys/stat.h>
33#include <sys/file.h>
34#include <stdio.h>
35#include <ctype.h>
36
37int bflag, eflag, nflag, sflag, tflag, vflag;
38int rval;
39char *filename;
40
41main(argc, argv)
42 int argc;
43 char **argv;
44{
45 extern int errno, optind;
46 int ch;
47 char *strerror();
48
49 while ((ch = getopt(argc, argv, "-benstuv")) != EOF)
50 switch (ch) {
51 case '-':
52 --optind;
53 goto done;
54 case 'b':
55 bflag = nflag = 1; /* -b implies -n */
56 break;
57 case 'e':
58 eflag = vflag = 1; /* -e implies -v */
59 break;
60 case 'n':
61 nflag = 1;
62 break;
63 case 's':
64 sflag = 1;
65 break;
66 case 't':
67 tflag = vflag = 1; /* -t implies -v */
68 break;
69 case 'u':
70 setbuf(stdout, (char *)NULL);
71 break;
72 case 'v':
73 vflag = 1;
74 break;
75 case '?':
76 (void)fprintf(stderr,
77 "usage: cat [-benstuv] [-] [file ...]\n");
78 exit(1);
79 }
80done: argv += optind;
81
82 if (bflag || eflag || nflag || sflag || tflag || vflag)
83 cook_args(argv);
84 else
85 raw_args(argv);
86 exit(rval);
87}
88
89cook_args(argv)
90 char **argv;
91{
92 register FILE *fp;
93
94 fp = stdin;
95 filename = "-";
96 do {
97 if (*argv) {
98 if (!strcmp(*argv, "-"))
99 fp = stdin;
100 else if (!(fp = fopen(*argv, "r"))) {
101 (void)fprintf(stderr,
102 "cat: %s: %s\n", *argv, strerror(errno));
103 rval = 1;
104 ++argv;
105 continue;
106 }
107 filename = *argv++;
108 }
109 cook_buf(fp);
110 if (fp != stdin)
111 (void)fclose(fp);
112 } while (*argv);
113}
114
115cook_buf(fp)
116 register FILE *fp;
117{
118 register int ch, gobble, line, prev;
119
120 line = gobble = 0;
121 for (prev = '\n'; (ch = getc(fp)) != EOF; prev = ch) {
122 if (prev == '\n') {
123 if (ch == '\n') {
124 if (sflag) {
125 if (!gobble && putc(ch, stdout) == EOF)
126 break;
127 gobble = 1;
128 continue;
129 }
130 if (nflag && !bflag) {
131 (void)fprintf(stdout, "%6d\t", ++line);
132 if (ferror(stdout))
133 break;
134 }
135 } else if (nflag) {
136 (void)fprintf(stdout, "%6d\t", ++line);
137 if (ferror(stdout))
138 break;
139 }
140 }
141 gobble = 0;
142 if (ch == '\n') {
143 if (eflag)
144 if (putc('$', stdout) == EOF)
145 break;
146 } else if (ch == '\t') {
147 if (tflag) {
148 if (putc('^', stdout) == EOF ||
149 putc('I', stdout) == EOF)
150 break;
151 continue;
152 }
153 } else if (vflag) {
154 if (ch > 0177) {
155 if (putc('M', stdout) == EOF ||
156 putc('-', stdout) == EOF)
157 break;
158 ch &= 0177;
159 }
160 if (iscntrl(ch)) {
161 if (putc('^', stdout) == EOF ||
162 putc(ch == '\177' ? '?' :
163 ch | 0100, stdout) == EOF)
164 break;
165 continue;
166 }
167 }
168 if (putc(ch, stdout) == EOF)
169 break;
170 }
171 if (ferror(fp)) {
172 (void)fprintf(stderr, "cat: %s: read error\n", filename);
173 rval = 1;
174 }
175 if (ferror(stdout)) {
176 clearerr(stdout);
177 (void)fprintf(stderr, "cat: stdout: write error\n");
178 rval = 1;
179 }
180}
181
182raw_args(argv)
183 char **argv;
184{
185 register int fd;
186
187 fd = fileno(stdin);
188 filename = "-";
189 do {
190 if (*argv) {
191 if (!strcmp(*argv, "-"))
192 fd = fileno(stdin);
193 else if ((fd = open(*argv, O_RDONLY, 0)) < 0) {
194 (void)fprintf(stderr, "cat: %s: %s\n",
195 *argv, strerror(errno));
196 rval = 1;
197 ++argv;
198 continue;
199 }
200 filename = *argv++;
201 }
202 rval |= raw_cat(fd);
203 if (fd != fileno(stdin))
204 (void)close(fd);
205 } while (*argv);
206}
207
208raw_cat(fd)
209 register int fd;
210{
211 extern int errno;
212 register int nr, nw, off;
213 static int bsize;
214 static char *buf;
215 struct stat sbuf;
216 char *malloc(), *strerror();
217
218 if (!buf) {
219 if (fstat(fileno(stdout), &sbuf)) {
220 (void)fprintf(stderr, "cat: %s: %s\n", filename,
221 strerror(errno));
222 return(1);
223 }
224 bsize = MAX(sbuf.st_blksize, 1024);
225 if (!(buf = malloc((u_int)bsize))) {
226 (void)fprintf(stderr, "cat: %s: no memory.\n",
227 filename);
228 return(1);
229 }
230 }
231 while ((nr = read(fd, buf, bsize)) > 0)
232 for (off = 0; off < nr;) {
233 if ((nw = write(fileno(stdout), buf + off, nr)) < 0) {
234 perror("cat: stdout");
235 return(1);
236 }
237 off += nw;
238 }
239 if (nr < 0) {
240 (void)fprintf(stderr, "cat: %s: %s\n", filename,
241 strerror(errno));
242 return(1);
243 }
244 return(0);
245}