|
|
1.1 root 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: (1) source distributions retain this entire copyright
10: * notice and comment, and (2) distributions including binaries display
11: * the following acknowledgement: ``This product includes software
12: * developed by the University of California, Berkeley and its contributors''
13: * in the documentation or other materials provided with the distribution
14: * and in all advertising materials mentioning features or use of this
15: * software. Neither the name of the University nor the names of its
16: * contributors may be used to endorse or promote products derived
17: * from this software without specific prior written permission.
18: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
19: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
20: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
21: */
22:
23: #ifndef lint
24: char copyright[] =
25: "@(#) Copyright (c) 1989 The Regents of the University of California.\n\
26: All rights reserved.\n";
27: #endif /* not lint */
28:
29: #ifndef lint
30: static char sccsid[] = "@(#)cat.c 5.11 (Berkeley) 5/31/90";
31: #endif /* not lint */
32:
33: #include <sys/param.h>
34: #include <sys/stat.h>
35: #include <sys/file.h>
36: #include <stdio.h>
37: #include <ctype.h>
38:
39: extern int errno;
40: int bflag, eflag, nflag, sflag, tflag, vflag;
41: int rval;
42: char *filename;
43:
44: main(argc, argv)
45: int argc;
46: char **argv;
47: {
48: extern int optind;
49: int ch;
50: char *strerror();
51:
52: while ((ch = getopt(argc, argv, "benstuv")) != EOF)
53: switch (ch) {
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: }
80: 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:
89: cook_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:
115: cook_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 && putchar(ch) == 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 (putchar('$') == EOF)
145: break;
146: } else if (ch == '\t') {
147: if (tflag) {
148: if (putchar('^') == EOF || putchar('I') == EOF)
149: break;
150: continue;
151: }
152: } else if (vflag) {
153: if (!isascii(ch)) {
154: if (putchar('M') == EOF || putchar('-') == EOF)
155: break;
156: ch = toascii(ch);
157: }
158: if (iscntrl(ch)) {
159: if (putchar('^') == EOF ||
160: putchar(ch == '\177' ? '?' :
161: ch | 0100) == EOF)
162: break;
163: continue;
164: }
165: }
166: if (putchar(ch) == EOF)
167: break;
168: }
169: if (ferror(fp)) {
170: (void)fprintf(stderr, "cat: %s: read error\n", filename);
171: rval = 1;
172: }
173: if (ferror(stdout)) {
174: clearerr(stdout);
175: (void)fprintf(stderr, "cat: stdout: write error\n");
176: rval = 1;
177: }
178: }
179:
180: raw_args(argv)
181: char **argv;
182: {
183: register int fd;
184:
185: fd = fileno(stdin);
186: filename = "-";
187: do {
188: if (*argv) {
189: if (!strcmp(*argv, "-"))
190: fd = fileno(stdin);
191: else if ((fd = open(*argv, O_RDONLY, 0)) < 0) {
192: (void)fprintf(stderr, "cat: %s: %s\n",
193: *argv, strerror(errno));
194: rval = 1;
195: ++argv;
196: continue;
197: }
198: filename = *argv++;
199: }
200: rval |= raw_cat(fd);
201: if (fd != fileno(stdin))
202: (void)close(fd);
203: } while (*argv);
204: }
205:
206: raw_cat(fd)
207: register int fd;
208: {
209: register int nr, nw, off;
210: static int bsize;
211: static char *buf;
212: struct stat sbuf;
213: char *malloc(), *strerror();
214:
215: if (!buf) {
216: if (fstat(fileno(stdout), &sbuf)) {
217: (void)fprintf(stderr, "cat: %s: %s\n", filename,
218: strerror(errno));
219: return(1);
220: }
221: bsize = MAX(sbuf.st_blksize, 1024);
222: if (!(buf = malloc((u_int)bsize))) {
223: (void)fprintf(stderr, "cat: %s: no memory.\n",
224: filename);
225: return(1);
226: }
227: }
228: while ((nr = read(fd, buf, bsize)) > 0)
229: for (off = 0; off < nr;) {
230: if ((nw = write(fileno(stdout), buf + off, nr)) < 0) {
231: perror("cat: stdout");
232: return(1);
233: }
234: off += nw;
235: }
236: if (nr < 0) {
237: (void)fprintf(stderr, "cat: %s: %s\n", filename,
238: strerror(errno));
239: return(1);
240: }
241: return(0);
242: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.