mv tar to /usr/src/old
[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 *
27c71911 8 * %sccs.include.redist.c%
bcf1365c
DF
9 */
10
205a2d85 11#ifndef lint
d6d4c082 12char copyright[] =
0986a758 13"@(#) Copyright (c) 1989 The Regents of the University of California.\n\
d6d4c082
KB
14 All rights reserved.\n";
15#endif /* not lint */
16
17#ifndef lint
9da2e0c8 18static char sccsid[] = "@(#)cat.c 5.17 (Berkeley) %G%";
d6d4c082 19#endif /* not lint */
205a2d85 20
0ae48d09
KB
21#include <sys/param.h>
22#include <sys/stat.h>
9da2e0c8
KB
23
24#include <ctype.h>
25#include <err.h>
87851fcf 26#include <errno.h>
9da2e0c8 27#include <fcntl.h>
efa30d97 28#include <stdio.h>
87851fcf
KB
29#include <stdlib.h>
30#include <string.h>
9da2e0c8 31#include <unistd.h>
efa30d97 32
f56eef62
KB
33int bflag, eflag, nflag, sflag, tflag, vflag;
34int rval;
0986a758 35char *filename;
efa30d97 36
9da2e0c8
KB
37void cook_args __P((char *argv[]));
38void cook_buf __P((FILE *));
39void raw_args __P((char *argv[]));
40void raw_cat __P((int));
87851fcf 41
9da2e0c8 42int
efa30d97 43main(argc, argv)
0986a758 44 int argc;
9da2e0c8 45 char *argv[];
efa30d97 46{
2b7b0bbf 47 extern int optind;
f56eef62 48 int ch;
efa30d97 49
fc16a647 50 while ((ch = getopt(argc, argv, "benstuv")) != EOF)
0986a758 51 switch (ch) {
f56eef62
KB
52 case 'b':
53 bflag = nflag = 1; /* -b implies -n */
54 break;
55 case 'e':
56 eflag = vflag = 1; /* -e implies -v */
57 break;
58 case 'n':
59 nflag = 1;
60 break;
61 case 's':
62 sflag = 1;
63 break;
64 case 't':
65 tflag = vflag = 1; /* -t implies -v */
66 break;
67 case 'u':
68 setbuf(stdout, (char *)NULL);
69 break;
70 case 'v':
71 vflag = 1;
0986a758
KB
72 break;
73 case '?':
74 (void)fprintf(stderr,
f56eef62 75 "usage: cat [-benstuv] [-] [file ...]\n");
0986a758 76 exit(1);
72c98f6b 77 }
fc16a647 78 argv += optind;
0986a758 79
f56eef62
KB
80 if (bflag || eflag || nflag || sflag || tflag || vflag)
81 cook_args(argv);
82 else
83 raw_args(argv);
96c88030 84 if (fclose(stdout))
9da2e0c8 85 err(1, "stdout");
f56eef62
KB
86 exit(rval);
87}
88
87851fcf 89void
f56eef62
KB
90cook_args(argv)
91 char **argv;
92{
93 register FILE *fp;
94
95 fp = stdin;
a320e76f 96 filename = "stdin";
f56eef62
KB
97 do {
98 if (*argv) {
99 if (!strcmp(*argv, "-"))
100 fp = stdin;
9da2e0c8
KB
101 else if ((fp = fopen(*argv, "r")) == NULL) {
102 warn("%s", *argv);
f56eef62
KB
103 ++argv;
104 continue;
105 }
106 filename = *argv++;
107 }
108 cook_buf(fp);
109 if (fp != stdin)
110 (void)fclose(fp);
111 } while (*argv);
112}
113
87851fcf 114void
f56eef62
KB
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) {
73e4609d 125 if (!gobble && putchar(ch) == EOF)
7d9ace85 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)
73e4609d 144 if (putchar('$') == EOF)
f56eef62
KB
145 break;
146 } else if (ch == '\t') {
147 if (tflag) {
73e4609d 148 if (putchar('^') == EOF || putchar('I') == EOF)
f56eef62
KB
149 break;
150 continue;
151 }
152 } else if (vflag) {
73e4609d
KB
153 if (!isascii(ch)) {
154 if (putchar('M') == EOF || putchar('-') == EOF)
f56eef62 155 break;
73e4609d 156 ch = toascii(ch);
f56eef62
KB
157 }
158 if (iscntrl(ch)) {
73e4609d
KB
159 if (putchar('^') == EOF ||
160 putchar(ch == '\177' ? '?' :
161 ch | 0100) == EOF)
f56eef62
KB
162 break;
163 continue;
164 }
165 }
73e4609d 166 if (putchar(ch) == EOF)
f56eef62
KB
167 break;
168 }
169 if (ferror(fp)) {
9da2e0c8 170 warn("%s", filename);
87851fcf 171 clearerr(fp);
f56eef62 172 }
87851fcf 173 if (ferror(stdout))
9da2e0c8 174 err(1, "stdout");
f56eef62
KB
175}
176
87851fcf 177void
f56eef62
KB
178raw_args(argv)
179 char **argv;
180{
181 register int fd;
182
0ae48d09 183 fd = fileno(stdin);
a320e76f 184 filename = "stdin";
0986a758
KB
185 do {
186 if (*argv) {
0ae48d09
KB
187 if (!strcmp(*argv, "-"))
188 fd = fileno(stdin);
189 else if ((fd = open(*argv, O_RDONLY, 0)) < 0) {
9da2e0c8 190 warn("%s", *argv);
0986a758 191 ++argv;
72c98f6b
EC
192 continue;
193 }
0ae48d09 194 filename = *argv++;
efa30d97 195 }
87851fcf 196 raw_cat(fd);
0ae48d09
KB
197 if (fd != fileno(stdin))
198 (void)close(fd);
0986a758 199 } while (*argv);
efa30d97 200}
3c67f80d 201
87851fcf
KB
202void
203raw_cat(rfd)
204 register int rfd;
ef57e02f 205{
87851fcf 206 register int nr, nw, off, wfd;
0ae48d09
KB
207 static int bsize;
208 static char *buf;
209 struct stat sbuf;
ef57e02f 210
87851fcf 211 wfd = fileno(stdout);
9da2e0c8 212 if (buf == NULL) {
87851fcf 213 if (fstat(wfd, &sbuf))
9da2e0c8 214 err(1, "%s", filename);
0ae48d09 215 bsize = MAX(sbuf.st_blksize, 1024);
9da2e0c8
KB
216 if ((buf = malloc((u_int)bsize)) == NULL)
217 err(1, "");
0ae48d09 218 }
87851fcf 219 while ((nr = read(rfd, buf, bsize)) > 0)
53ec5995 220 for (off = 0; off < nr; nr -= nw, off += nw)
87851fcf 221 if ((nw = write(wfd, buf + off, nr)) < 0)
9da2e0c8 222 err(1, "stdout");
87851fcf 223 if (nr < 0)
9da2e0c8 224 warn("%s", filename);
ef57e02f 225}