xref: /csrg-svn/bin/cat/cat.c (revision 12059)
1962Sbill /*
2962Sbill  * Concatenate files.
3962Sbill  */
4*12059Smckusick static	char *Sccsid = "@(#)cat.c	4.5 (Berkeley) 04/26/83";
5962Sbill 
6962Sbill #include <stdio.h>
7962Sbill #include <sys/types.h>
8962Sbill #include <sys/stat.h>
9962Sbill 
10962Sbill char	stdbuf[BUFSIZ];
111357Sbill int	bflg, eflg, nflg, sflg, tflg, vflg;
121357Sbill int	spaced, col, lno, inline;
13962Sbill 
14962Sbill main(argc, argv)
15962Sbill char **argv;
16962Sbill {
17962Sbill 	int fflg = 0;
18962Sbill 	register FILE *fi;
19962Sbill 	register c;
20962Sbill 	int dev, ino = -1;
21962Sbill 	struct stat statb;
22962Sbill 
231357Sbill 	lno = 1;
24962Sbill 	setbuf(stdout, stdbuf);
25962Sbill 	for( ; argc>1 && argv[1][0]=='-'; argc--,argv++) {
26962Sbill 		switch(argv[1][1]) {
27962Sbill 		case 0:
28962Sbill 			break;
29962Sbill 		case 'u':
30962Sbill 			setbuf(stdout, (char *)NULL);
31962Sbill 			continue;
321357Sbill 		case 'n':
331357Sbill 			nflg++;
341357Sbill 			continue;
351357Sbill 		case 'b':
361357Sbill 			bflg++;
371357Sbill 			nflg++;
381357Sbill 			continue;
391357Sbill 		case 'v':
401357Sbill 			vflg++;
411357Sbill 			continue;
421357Sbill 		case 's':
431357Sbill 			sflg++;
441357Sbill 			continue;
451357Sbill 		case 'e':
461357Sbill 			eflg++;
471357Sbill 			vflg++;
481357Sbill 			continue;
491357Sbill 		case 't':
501357Sbill 			tflg++;
511357Sbill 			vflg++;
521357Sbill 			continue;
53962Sbill 		}
54962Sbill 		break;
55962Sbill 	}
564387Secc 	if (fstat(fileno(stdout), &statb) == 0) {
574387Secc 		statb.st_mode &= S_IFMT;
584387Secc 		if (statb.st_mode!=S_IFCHR && statb.st_mode!=S_IFBLK) {
594387Secc 			dev = statb.st_dev;
604387Secc 			ino = statb.st_ino;
614387Secc 		}
62962Sbill 	}
63962Sbill 	if (argc < 2) {
64962Sbill 		argc = 2;
65962Sbill 		fflg++;
66962Sbill 	}
67962Sbill 	while (--argc > 0) {
68962Sbill 		if (fflg || (*++argv)[0]=='-' && (*argv)[1]=='\0')
69962Sbill 			fi = stdin;
70962Sbill 		else {
71962Sbill 			if ((fi = fopen(*argv, "r")) == NULL) {
72*12059Smckusick 				perror(*argv);
73962Sbill 				continue;
74962Sbill 			}
75962Sbill 		}
764387Secc 		if (fstat(fileno(fi), &statb) == 0) {
775899Sroot 			if ((statb.st_mode & S_IFMT) == S_IFREG &&
785899Sroot 			    statb.st_dev==dev && statb.st_ino==ino) {
794387Secc 				fprintf(stderr, "cat: input %s is output\n",
804387Secc 				   fflg?"-": *argv);
814387Secc 				fclose(fi);
824387Secc 				continue;
834387Secc 			}
84962Sbill 		}
851357Sbill 		if (nflg||sflg||vflg)
861357Sbill 			copyopt(fi);
871357Sbill 		else {
881357Sbill 			while ((c = getc(fi)) != EOF)
891357Sbill 				putchar(c);
901357Sbill 		}
91962Sbill 		if (fi!=stdin)
92962Sbill 			fclose(fi);
93962Sbill 	}
941357Sbill 	if (ferror(stdout))
951357Sbill 		fprintf(stderr, "cat: output write error\n");
96962Sbill 	return(0);
97962Sbill }
981357Sbill 
991357Sbill copyopt(f)
1001357Sbill 	register FILE *f;
1011357Sbill {
1021357Sbill 	register int c;
1031357Sbill 
1041357Sbill top:
1051357Sbill 	c = getc(f);
1061357Sbill 	if (c == EOF)
1071357Sbill 		return;
1081357Sbill 	if (c == '\n') {
1091357Sbill 		if (inline == 0) {
1101357Sbill 			if (sflg && spaced)
1111357Sbill 				goto top;
1121357Sbill 			spaced = 1;
1131357Sbill 		}
1141357Sbill 		if (nflg && bflg==0 && inline == 0)
1151357Sbill 			printf("%6d\t", lno++);
1161357Sbill 		if (eflg)
1171357Sbill 			putchar('$');
1181357Sbill 		putchar('\n');
1191357Sbill 		inline = 0;
1201357Sbill 		goto top;
1211357Sbill 	}
1221357Sbill 	if (nflg && inline == 0)
1231357Sbill 		printf("%6d\t", lno++);
1241357Sbill 	inline = 1;
1251357Sbill 	if (vflg) {
1261357Sbill 		if (tflg==0 && c == '\t')
1271357Sbill 			putchar(c);
1281357Sbill 		else {
1291357Sbill 			if (c > 0177) {
1301357Sbill 				printf("M-");
1311357Sbill 				c &= 0177;
1321357Sbill 			}
1331357Sbill 			if (c < ' ')
1341357Sbill 				printf("^%c", c+'@');
1351357Sbill 			else if (c == 0177)
1361357Sbill 				printf("^?");
1371357Sbill 			else
1381357Sbill 				putchar(c);
1391357Sbill 		}
1401357Sbill 	} else
1411357Sbill 		putchar(c);
1421357Sbill 	spaced = 0;
1431357Sbill 	goto top;
1441357Sbill }
145