add Mfsiomap
[unix-history] / usr / src / bin / cat / cat.c
CommitLineData
bcf1365c 1/*
0986a758
KB
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.
bcf1365c
DF
19 */
20
205a2d85 21#ifndef lint
d6d4c082 22char copyright[] =
0986a758 23"@(#) Copyright (c) 1989 The Regents of the University of California.\n\
d6d4c082
KB
24 All rights reserved.\n";
25#endif /* not lint */
26
27#ifndef lint
7d9ace85 28static char sccsid[] = "@(#)cat.c 5.7 (Berkeley) %G%";
d6d4c082 29#endif /* not lint */
205a2d85 30
0ae48d09
KB
31#include <sys/param.h>
32#include <sys/stat.h>
33#include <sys/file.h>
efa30d97 34#include <stdio.h>
0986a758 35#include <ctype.h>
efa30d97 36
f56eef62
KB
37int bflag, eflag, nflag, sflag, tflag, vflag;
38int rval;
0986a758 39char *filename;
efa30d97
BJ
40
41main(argc, argv)
0986a758
KB
42 int argc;
43 char **argv;
efa30d97 44{
0986a758 45 extern int errno, optind;
f56eef62 46 int ch;
0986a758 47 char *strerror();
efa30d97 48
f56eef62 49 while ((ch = getopt(argc, argv, "-benstuv")) != EOF)
0986a758
KB
50 switch (ch) {
51 case '-':
52 --optind;
53 goto done;
f56eef62
KB
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;
0986a758
KB
74 break;
75 case '?':
76 (void)fprintf(stderr,
f56eef62 77 "usage: cat [-benstuv] [-] [file ...]\n");
0986a758 78 exit(1);
72c98f6b 79 }
0986a758
KB
80done: argv += optind;
81
f56eef62
KB
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) {
7d9ace85
KB
125 if (!gobble && putc(ch, stdout) == EOF)
126 break;
f56eef62 127 gobble = 1;
7d9ace85 128 continue;
f56eef62
KB
129 }
130 if (nflag && !bflag) {
131 (void)fprintf(stdout, "%6d\t", ++line);
132 if (ferror(stdout))
133 break;
134 }
7d9ace85 135 } else if (nflag) {
f56eef62
KB
136 (void)fprintf(stdout, "%6d\t", ++line);
137 if (ferror(stdout))
138 break;
139 }
140 }
7d9ace85 141 gobble = 0;
f56eef62
KB
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
0ae48d09 187 fd = fileno(stdin);
0986a758
KB
188 filename = "-";
189 do {
190 if (*argv) {
0ae48d09
KB
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;
0986a758 197 ++argv;
72c98f6b
EC
198 continue;
199 }
0ae48d09 200 filename = *argv++;
efa30d97 201 }
f56eef62 202 rval |= raw_cat(fd);
0ae48d09
KB
203 if (fd != fileno(stdin))
204 (void)close(fd);
0986a758 205 } while (*argv);
efa30d97 206}
3c67f80d 207
f56eef62 208raw_cat(fd)
0986a758 209 register int fd;
ef57e02f 210{
0986a758 211 extern int errno;
0986a758 212 register int nr, nw, off;
0ae48d09
KB
213 static int bsize;
214 static char *buf;
215 struct stat sbuf;
216 char *malloc(), *strerror();
ef57e02f 217
0ae48d09
KB
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))) {
f56eef62
KB
226 (void)fprintf(stderr, "cat: %s: no memory.\n",
227 filename);
0ae48d09
KB
228 return(1);
229 }
230 }
231 while ((nr = read(fd, buf, bsize)) > 0)
0986a758
KB
232 for (off = 0; off < nr;) {
233 if ((nw = write(fileno(stdout), buf + off, nr)) < 0) {
234 perror("cat: stdout");
0ae48d09 235 return(1);
a58e01f9 236 }
0986a758
KB
237 off += nw;
238 }
239 if (nr < 0) {
240 (void)fprintf(stderr, "cat: %s: %s\n", filename,
241 strerror(errno));
0ae48d09 242 return(1);
a58e01f9 243 }
0ae48d09 244 return(0);
ef57e02f 245}