xref: /csrg-svn/bin/cat/cat.c (revision 17965)
114463Ssam #ifndef lint
2*17965Skarels static	char *sccsid = "@(#)cat.c	4.9 (Berkeley) 02/14/85";
314463Ssam #endif
414463Ssam 
5962Sbill /*
6962Sbill  * Concatenate files.
7962Sbill  */
8962Sbill 
9962Sbill #include <stdio.h>
10962Sbill #include <sys/types.h>
11962Sbill #include <sys/stat.h>
12962Sbill 
13*17965Skarels /* #define OPTSIZE BUFSIZ	/* define this only if not 4.2 BSD or beyond */
14962Sbill 
1517947Sralph int	bflg, eflg, nflg, sflg, tflg, uflg, vflg;
1617947Sralph int	spaced, col, lno, inline, ibsize, obsize;
1717947Sralph 
18962Sbill main(argc, argv)
19962Sbill char **argv;
20962Sbill {
21962Sbill 	int fflg = 0;
22962Sbill 	register FILE *fi;
23962Sbill 	register c;
24962Sbill 	int dev, ino = -1;
25962Sbill 	struct stat statb;
2617947Sralph 	int retval = 0;
27962Sbill 
281357Sbill 	lno = 1;
29962Sbill 	for( ; argc>1 && argv[1][0]=='-'; argc--,argv++) {
30962Sbill 		switch(argv[1][1]) {
31962Sbill 		case 0:
32962Sbill 			break;
33962Sbill 		case 'u':
34962Sbill 			setbuf(stdout, (char *)NULL);
3517947Sralph 			uflg++;
36962Sbill 			continue;
371357Sbill 		case 'n':
381357Sbill 			nflg++;
391357Sbill 			continue;
401357Sbill 		case 'b':
411357Sbill 			bflg++;
421357Sbill 			nflg++;
431357Sbill 			continue;
441357Sbill 		case 'v':
451357Sbill 			vflg++;
461357Sbill 			continue;
471357Sbill 		case 's':
481357Sbill 			sflg++;
491357Sbill 			continue;
501357Sbill 		case 'e':
511357Sbill 			eflg++;
521357Sbill 			vflg++;
531357Sbill 			continue;
541357Sbill 		case 't':
551357Sbill 			tflg++;
561357Sbill 			vflg++;
571357Sbill 			continue;
58962Sbill 		}
59962Sbill 		break;
60962Sbill 	}
614387Secc 	if (fstat(fileno(stdout), &statb) == 0) {
624387Secc 		statb.st_mode &= S_IFMT;
634387Secc 		if (statb.st_mode!=S_IFCHR && statb.st_mode!=S_IFBLK) {
644387Secc 			dev = statb.st_dev;
654387Secc 			ino = statb.st_ino;
664387Secc 		}
67*17965Skarels #ifndef	OPTSIZE
6817947Sralph 		obsize = statb.st_blksize;
69*17965Skarels #endif
70962Sbill 	}
7117947Sralph 	else
7217947Sralph 		obsize = 0;
73962Sbill 	if (argc < 2) {
74962Sbill 		argc = 2;
75962Sbill 		fflg++;
76962Sbill 	}
77962Sbill 	while (--argc > 0) {
78962Sbill 		if (fflg || (*++argv)[0]=='-' && (*argv)[1]=='\0')
79962Sbill 			fi = stdin;
80962Sbill 		else {
81962Sbill 			if ((fi = fopen(*argv, "r")) == NULL) {
8212059Smckusick 				perror(*argv);
8317947Sralph 				retval = 1;
84962Sbill 				continue;
85962Sbill 			}
86962Sbill 		}
874387Secc 		if (fstat(fileno(fi), &statb) == 0) {
885899Sroot 			if ((statb.st_mode & S_IFMT) == S_IFREG &&
895899Sroot 			    statb.st_dev==dev && statb.st_ino==ino) {
904387Secc 				fprintf(stderr, "cat: input %s is output\n",
914387Secc 				   fflg?"-": *argv);
924387Secc 				fclose(fi);
9317947Sralph 				retval = 1;
944387Secc 				continue;
954387Secc 			}
96*17965Skarels #ifndef	OPTSIZE
9717947Sralph 			ibsize = statb.st_blksize;
98*17965Skarels #endif
99962Sbill 		}
10017947Sralph 		else
10117947Sralph 			ibsize = 0;
1021357Sbill 		if (nflg||sflg||vflg)
1031357Sbill 			copyopt(fi);
10417947Sralph 		else if (uflg) {
1051357Sbill 			while ((c = getc(fi)) != EOF)
1061357Sbill 				putchar(c);
10717947Sralph 		} else
108*17965Skarels 			retval |= fastcat(fileno(fi));	/* no flags specified */
109962Sbill 		if (fi!=stdin)
110962Sbill 			fclose(fi);
11117947Sralph 		if (ferror(stdout)) {
11217947Sralph 			fprintf(stderr, "cat: output write error\n");
11317947Sralph 			retval = 1;
11417947Sralph 			break;
11517947Sralph 		}
116962Sbill 	}
11717947Sralph 	exit(retval);
118962Sbill }
1191357Sbill 
1201357Sbill copyopt(f)
1211357Sbill 	register FILE *f;
1221357Sbill {
1231357Sbill 	register int c;
1241357Sbill 
1251357Sbill top:
1261357Sbill 	c = getc(f);
1271357Sbill 	if (c == EOF)
1281357Sbill 		return;
1291357Sbill 	if (c == '\n') {
1301357Sbill 		if (inline == 0) {
1311357Sbill 			if (sflg && spaced)
1321357Sbill 				goto top;
1331357Sbill 			spaced = 1;
1341357Sbill 		}
1351357Sbill 		if (nflg && bflg==0 && inline == 0)
1361357Sbill 			printf("%6d\t", lno++);
1371357Sbill 		if (eflg)
1381357Sbill 			putchar('$');
1391357Sbill 		putchar('\n');
1401357Sbill 		inline = 0;
1411357Sbill 		goto top;
1421357Sbill 	}
1431357Sbill 	if (nflg && inline == 0)
1441357Sbill 		printf("%6d\t", lno++);
1451357Sbill 	inline = 1;
1461357Sbill 	if (vflg) {
1471357Sbill 		if (tflg==0 && c == '\t')
1481357Sbill 			putchar(c);
1491357Sbill 		else {
1501357Sbill 			if (c > 0177) {
1511357Sbill 				printf("M-");
1521357Sbill 				c &= 0177;
1531357Sbill 			}
1541357Sbill 			if (c < ' ')
1551357Sbill 				printf("^%c", c+'@');
1561357Sbill 			else if (c == 0177)
1571357Sbill 				printf("^?");
1581357Sbill 			else
1591357Sbill 				putchar(c);
1601357Sbill 		}
1611357Sbill 	} else
1621357Sbill 		putchar(c);
1631357Sbill 	spaced = 0;
1641357Sbill 	goto top;
1651357Sbill }
16617947Sralph 
16717947Sralph fastcat(fd)
16817947Sralph register int fd;
16917947Sralph {
17017947Sralph 	register int	buffsize, n, nwritten, offset;
17117947Sralph 	register char	*buff;
17217947Sralph 	struct stat	statbuff;
17317947Sralph 	char		*malloc();
17417947Sralph 
17517947Sralph #ifndef	OPTSIZE
176*17965Skarels 	if (obsize)
177*17965Skarels 		buffsize = obsize;	/* common case, use output blksize */
178*17965Skarels 	else if (ibsize)
17917947Sralph 		buffsize = ibsize;
18017947Sralph 	else
181*17965Skarels 		buffsize = BUFSIZ;
18217947Sralph #else
18317947Sralph 	buffsize = OPTSIZE;
18417947Sralph #endif
18517947Sralph 
186*17965Skarels 	if ((buff = malloc(buffsize)) == NULL) {
18717947Sralph 		perror("cat: no memory");
188*17965Skarels 		return (1);
189*17965Skarels 	}
19017947Sralph 
19117947Sralph 	/*
19217947Sralph 	 * Note that on some systems (V7), very large writes to a pipe
19317947Sralph 	 * return less than the requested size of the write.
19417947Sralph 	 * In this case, multiple writes are required.
19517947Sralph 	 */
19617947Sralph 	while ((n = read(fd, buff, buffsize)) > 0) {
19717947Sralph 		offset = 0;
19817947Sralph 		do {
19917947Sralph 			nwritten = write(fileno(stdout), &buff[offset], n);
200*17965Skarels 			if (nwritten <= 0) {
20117947Sralph 				perror("cat: write error");
202*17965Skarels 				exit(2);
203*17965Skarels 			}
20417947Sralph 			offset += nwritten;
20517947Sralph 		} while ((n -= nwritten) > 0);
20617947Sralph 	}
20717947Sralph 
20817947Sralph 	free(buff);
209*17965Skarels 	if (n < 0) {
210*17965Skarels 		perror("cat: read error");
211*17965Skarels 		return (1);
212*17965Skarels 	}
213*17965Skarels 	return (0);
21417947Sralph }
215