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