xref: /original-bsd/bin/cat/cat.c (revision 92d3de31)
1 /*
2  * Concatenate files.
3  */
4 static	char *Sccsid = "@(#)cat.c	4.5 (Berkeley) 04/26/83";
5 
6 #include <stdio.h>
7 #include <sys/types.h>
8 #include <sys/stat.h>
9 
10 char	stdbuf[BUFSIZ];
11 int	bflg, eflg, nflg, sflg, tflg, vflg;
12 int	spaced, col, lno, inline;
13 
14 main(argc, argv)
15 char **argv;
16 {
17 	int fflg = 0;
18 	register FILE *fi;
19 	register c;
20 	int dev, ino = -1;
21 	struct stat statb;
22 
23 	lno = 1;
24 	setbuf(stdout, stdbuf);
25 	for( ; argc>1 && argv[1][0]=='-'; argc--,argv++) {
26 		switch(argv[1][1]) {
27 		case 0:
28 			break;
29 		case 'u':
30 			setbuf(stdout, (char *)NULL);
31 			continue;
32 		case 'n':
33 			nflg++;
34 			continue;
35 		case 'b':
36 			bflg++;
37 			nflg++;
38 			continue;
39 		case 'v':
40 			vflg++;
41 			continue;
42 		case 's':
43 			sflg++;
44 			continue;
45 		case 'e':
46 			eflg++;
47 			vflg++;
48 			continue;
49 		case 't':
50 			tflg++;
51 			vflg++;
52 			continue;
53 		}
54 		break;
55 	}
56 	if (fstat(fileno(stdout), &statb) == 0) {
57 		statb.st_mode &= S_IFMT;
58 		if (statb.st_mode!=S_IFCHR && statb.st_mode!=S_IFBLK) {
59 			dev = statb.st_dev;
60 			ino = statb.st_ino;
61 		}
62 	}
63 	if (argc < 2) {
64 		argc = 2;
65 		fflg++;
66 	}
67 	while (--argc > 0) {
68 		if (fflg || (*++argv)[0]=='-' && (*argv)[1]=='\0')
69 			fi = stdin;
70 		else {
71 			if ((fi = fopen(*argv, "r")) == NULL) {
72 				perror(*argv);
73 				continue;
74 			}
75 		}
76 		if (fstat(fileno(fi), &statb) == 0) {
77 			if ((statb.st_mode & S_IFMT) == S_IFREG &&
78 			    statb.st_dev==dev && statb.st_ino==ino) {
79 				fprintf(stderr, "cat: input %s is output\n",
80 				   fflg?"-": *argv);
81 				fclose(fi);
82 				continue;
83 			}
84 		}
85 		if (nflg||sflg||vflg)
86 			copyopt(fi);
87 		else {
88 			while ((c = getc(fi)) != EOF)
89 				putchar(c);
90 		}
91 		if (fi!=stdin)
92 			fclose(fi);
93 	}
94 	if (ferror(stdout))
95 		fprintf(stderr, "cat: output write error\n");
96 	return(0);
97 }
98 
99 copyopt(f)
100 	register FILE *f;
101 {
102 	register int c;
103 
104 top:
105 	c = getc(f);
106 	if (c == EOF)
107 		return;
108 	if (c == '\n') {
109 		if (inline == 0) {
110 			if (sflg && spaced)
111 				goto top;
112 			spaced = 1;
113 		}
114 		if (nflg && bflg==0 && inline == 0)
115 			printf("%6d\t", lno++);
116 		if (eflg)
117 			putchar('$');
118 		putchar('\n');
119 		inline = 0;
120 		goto top;
121 	}
122 	if (nflg && inline == 0)
123 		printf("%6d\t", lno++);
124 	inline = 1;
125 	if (vflg) {
126 		if (tflg==0 && c == '\t')
127 			putchar(c);
128 		else {
129 			if (c > 0177) {
130 				printf("M-");
131 				c &= 0177;
132 			}
133 			if (c < ' ')
134 				printf("^%c", c+'@');
135 			else if (c == 0177)
136 				printf("^?");
137 			else
138 				putchar(c);
139 		}
140 	} else
141 		putchar(c);
142 	spaced = 0;
143 	goto top;
144 }
145