usage error message; BUFSIZ -> MAXPATHLEN
[unix-history] / usr / src / bin / cat / cat.c
CommitLineData
205a2d85 1#ifndef lint
ef57e02f 2static char *sccsid = "@(#)cat.c 4.8 (Berkeley) %G%";
205a2d85
SL
3#endif
4
efa30d97
BJ
5/*
6 * Concatenate files.
7 */
8
9#include <stdio.h>
10#include <sys/types.h>
11#include <sys/stat.h>
12
ef57e02f
RC
13/* #define OPTSIZE BUFSIZ /* define this only if not 4.2 BSD */
14
15int bflg, eflg, nflg, sflg, tflg, uflg, vflg;
16int spaced, col, lno, inline, ibsize, obsize;
efa30d97
BJ
17
18main(argc, argv)
19char **argv;
20{
21 int fflg = 0;
22 register FILE *fi;
23 register c;
24 int dev, ino = -1;
25 struct stat statb;
ef57e02f 26 int retval = 0;
efa30d97 27
3c67f80d 28 lno = 1;
efa30d97
BJ
29 for( ; argc>1 && argv[1][0]=='-'; argc--,argv++) {
30 switch(argv[1][1]) {
31 case 0:
32 break;
33 case 'u':
34 setbuf(stdout, (char *)NULL);
ef57e02f 35 uflg++;
efa30d97 36 continue;
3c67f80d
BJ
37 case 'n':
38 nflg++;
39 continue;
40 case 'b':
41 bflg++;
42 nflg++;
43 continue;
44 case 'v':
45 vflg++;
46 continue;
47 case 's':
48 sflg++;
49 continue;
50 case 'e':
51 eflg++;
52 vflg++;
53 continue;
54 case 't':
55 tflg++;
56 vflg++;
57 continue;
efa30d97
BJ
58 }
59 break;
60 }
72c98f6b
EC
61 if (fstat(fileno(stdout), &statb) == 0) {
62 statb.st_mode &= S_IFMT;
63 if (statb.st_mode!=S_IFCHR && statb.st_mode!=S_IFBLK) {
64 dev = statb.st_dev;
65 ino = statb.st_ino;
66 }
ef57e02f 67 obsize = statb.st_blksize;
efa30d97 68 }
ef57e02f
RC
69 else
70 obsize = 0;
efa30d97
BJ
71 if (argc < 2) {
72 argc = 2;
73 fflg++;
74 }
75 while (--argc > 0) {
76 if (fflg || (*++argv)[0]=='-' && (*argv)[1]=='\0')
77 fi = stdin;
78 else {
79 if ((fi = fopen(*argv, "r")) == NULL) {
45fb66b3 80 perror(*argv);
ef57e02f 81 retval = 1;
efa30d97
BJ
82 continue;
83 }
84 }
72c98f6b 85 if (fstat(fileno(fi), &statb) == 0) {
ec0bdac7
BJ
86 if ((statb.st_mode & S_IFMT) == S_IFREG &&
87 statb.st_dev==dev && statb.st_ino==ino) {
72c98f6b
EC
88 fprintf(stderr, "cat: input %s is output\n",
89 fflg?"-": *argv);
90 fclose(fi);
ef57e02f 91 retval = 1;
72c98f6b
EC
92 continue;
93 }
ef57e02f 94 ibsize = statb.st_blksize;
efa30d97 95 }
ef57e02f
RC
96 else
97 ibsize = 0;
3c67f80d
BJ
98 if (nflg||sflg||vflg)
99 copyopt(fi);
ef57e02f 100 else if (uflg) {
3c67f80d
BJ
101 while ((c = getc(fi)) != EOF)
102 putchar(c);
ef57e02f
RC
103 } else
104 fastcat(fileno(fi)); /* no flags specified */
efa30d97
BJ
105 if (fi!=stdin)
106 fclose(fi);
ef57e02f
RC
107 if (ferror(stdout)) {
108 fprintf(stderr, "cat: output write error\n");
109 retval = 1;
110 break;
111 }
efa30d97 112 }
ef57e02f 113 exit(retval);
efa30d97 114}
3c67f80d
BJ
115
116copyopt(f)
117 register FILE *f;
118{
119 register int c;
120
121top:
122 c = getc(f);
123 if (c == EOF)
124 return;
125 if (c == '\n') {
126 if (inline == 0) {
127 if (sflg && spaced)
128 goto top;
129 spaced = 1;
130 }
131 if (nflg && bflg==0 && inline == 0)
132 printf("%6d\t", lno++);
133 if (eflg)
134 putchar('$');
135 putchar('\n');
136 inline = 0;
137 goto top;
138 }
139 if (nflg && inline == 0)
140 printf("%6d\t", lno++);
141 inline = 1;
142 if (vflg) {
143 if (tflg==0 && c == '\t')
144 putchar(c);
145 else {
146 if (c > 0177) {
147 printf("M-");
148 c &= 0177;
149 }
150 if (c < ' ')
151 printf("^%c", c+'@');
152 else if (c == 0177)
153 printf("^?");
154 else
155 putchar(c);
156 }
157 } else
158 putchar(c);
159 spaced = 0;
160 goto top;
161}
ef57e02f
RC
162
163fastcat(fd)
164register int fd;
165{
166 register int buffsize, n, nwritten, offset;
167 register char *buff;
168 struct stat statbuff;
169 char *malloc();
170
171#ifndef OPTSIZE
172 if (ibsize == 0)
173 buffsize = BUFSIZ; /* handle reads from a pipe */
174 else if (obsize == 0)
175 buffsize = ibsize;
176 else
177 buffsize = obsize; /* common case, use output blksize */
178#else
179 buffsize = OPTSIZE;
180#endif
181
182 if ((buff = malloc(buffsize)) == NULL)
183 perror("cat: no memory");
184
185 /*
186 * Note that on some systems (V7), very large writes to a pipe
187 * return less than the requested size of the write.
188 * In this case, multiple writes are required.
189 */
190 while ((n = read(fd, buff, buffsize)) > 0) {
191 offset = 0;
192 do {
193 nwritten = write(fileno(stdout), &buff[offset], n);
194 if (nwritten <= 0)
195 perror("cat: write error");
196 offset += nwritten;
197 } while ((n -= nwritten) > 0);
198 }
199 if (n < 0)
200 perror("cat: read error");
201
202 free(buff);
203}