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