119840Sdist /* 237128Sbostic * Copyright (c) 1989 The Regents of the University of California. 337128Sbostic * All rights reserved. 437128Sbostic * 537128Sbostic * This code is derived from software contributed to Berkeley by 637128Sbostic * Kevin Fall. 737128Sbostic * 837128Sbostic * Redistribution and use in source and binary forms are permitted 937128Sbostic * provided that the above copyright notice and this paragraph are 1037128Sbostic * duplicated in all such forms and that any documentation, 1137128Sbostic * advertising materials, and other materials related to such 1237128Sbostic * distribution and use acknowledge that the software was developed 1337128Sbostic * by the University of California, Berkeley. The name of the 1437128Sbostic * University may not be used to endorse or promote products derived 1537128Sbostic * from this software without specific prior written permission. 1637128Sbostic * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 1737128Sbostic * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 1837128Sbostic * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 1919840Sdist */ 2019840Sdist 2114463Ssam #ifndef lint 2234079Sbostic char copyright[] = 2337128Sbostic "@(#) Copyright (c) 1989 The Regents of the University of California.\n\ 2434079Sbostic All rights reserved.\n"; 2534079Sbostic #endif /* not lint */ 2614463Ssam 2734079Sbostic #ifndef lint 28*38900Sbostic static char sccsid[] = "@(#)cat.c 5.8 (Berkeley) 09/01/89"; 2934079Sbostic #endif /* not lint */ 3034079Sbostic 3137178Sbostic #include <sys/param.h> 3237178Sbostic #include <sys/stat.h> 3337178Sbostic #include <sys/file.h> 34962Sbill #include <stdio.h> 3537128Sbostic #include <ctype.h> 36962Sbill 3737179Sbostic int bflag, eflag, nflag, sflag, tflag, vflag; 3837179Sbostic int rval; 3937128Sbostic char *filename; 40962Sbill 41962Sbill main(argc, argv) 4237128Sbostic int argc; 4337128Sbostic char **argv; 44962Sbill { 4537128Sbostic extern int errno, optind; 4637179Sbostic int ch; 4737128Sbostic char *strerror(); 48962Sbill 4937179Sbostic while ((ch = getopt(argc, argv, "-benstuv")) != EOF) 5037128Sbostic switch (ch) { 5137128Sbostic case '-': 5237128Sbostic --optind; 5337128Sbostic goto done; 5437179Sbostic case 'b': 5537179Sbostic bflag = nflag = 1; /* -b implies -n */ 56962Sbill break; 5737179Sbostic case 'e': 5837179Sbostic eflag = vflag = 1; /* -e implies -v */ 5937179Sbostic break; 6037179Sbostic case 'n': 6137179Sbostic nflag = 1; 6237179Sbostic break; 6337179Sbostic case 's': 6437179Sbostic sflag = 1; 6537179Sbostic break; 6637179Sbostic case 't': 6737179Sbostic tflag = vflag = 1; /* -t implies -v */ 6837179Sbostic break; 6937179Sbostic case 'u': 7037179Sbostic setbuf(stdout, (char *)NULL); 7137179Sbostic break; 7237179Sbostic case 'v': 7337179Sbostic vflag = 1; 7437179Sbostic break; 7537128Sbostic case '?': 7637128Sbostic (void)fprintf(stderr, 7737179Sbostic "usage: cat [-benstuv] [-] [file ...]\n"); 7837128Sbostic exit(1); 79962Sbill } 8037128Sbostic done: argv += optind; 8137128Sbostic 8237179Sbostic if (bflag || eflag || nflag || sflag || tflag || vflag) 8337179Sbostic cook_args(argv); 8437179Sbostic else 8537179Sbostic raw_args(argv); 8637179Sbostic exit(rval); 8737179Sbostic } 8837179Sbostic 8937179Sbostic cook_args(argv) 9037179Sbostic char **argv; 9137179Sbostic { 9237179Sbostic register FILE *fp; 9337179Sbostic 9437179Sbostic fp = stdin; 9537179Sbostic filename = "-"; 9637179Sbostic do { 9737179Sbostic if (*argv) { 9837179Sbostic if (!strcmp(*argv, "-")) 9937179Sbostic fp = stdin; 10037179Sbostic else if (!(fp = fopen(*argv, "r"))) { 10137179Sbostic (void)fprintf(stderr, 10237179Sbostic "cat: %s: %s\n", *argv, strerror(errno)); 10337179Sbostic rval = 1; 10437179Sbostic ++argv; 10537179Sbostic continue; 10637179Sbostic } 10737179Sbostic filename = *argv++; 10837179Sbostic } 10937179Sbostic cook_buf(fp); 11037179Sbostic if (fp != stdin) 11137179Sbostic (void)fclose(fp); 11237179Sbostic } while (*argv); 11337179Sbostic } 11437179Sbostic 11537179Sbostic cook_buf(fp) 11637179Sbostic register FILE *fp; 11737179Sbostic { 11837179Sbostic register int ch, gobble, line, prev; 11937179Sbostic 12037179Sbostic line = gobble = 0; 12137179Sbostic for (prev = '\n'; (ch = getc(fp)) != EOF; prev = ch) { 12237179Sbostic if (prev == '\n') { 12337179Sbostic if (ch == '\n') { 12437179Sbostic if (sflag) { 125*38900Sbostic if (!gobble && putchar(ch) == EOF) 12638471Sbostic break; 12737179Sbostic gobble = 1; 12838471Sbostic continue; 12937179Sbostic } 13037179Sbostic if (nflag && !bflag) { 13137179Sbostic (void)fprintf(stdout, "%6d\t", ++line); 13237179Sbostic if (ferror(stdout)) 13337179Sbostic break; 13437179Sbostic } 13538471Sbostic } else if (nflag) { 13637179Sbostic (void)fprintf(stdout, "%6d\t", ++line); 13737179Sbostic if (ferror(stdout)) 13837179Sbostic break; 13937179Sbostic } 14037179Sbostic } 14138471Sbostic gobble = 0; 14237179Sbostic if (ch == '\n') { 14337179Sbostic if (eflag) 144*38900Sbostic if (putchar('$') == EOF) 14537179Sbostic break; 14637179Sbostic } else if (ch == '\t') { 14737179Sbostic if (tflag) { 148*38900Sbostic if (putchar('^') == EOF || putchar('I') == EOF) 14937179Sbostic break; 15037179Sbostic continue; 15137179Sbostic } 15237179Sbostic } else if (vflag) { 153*38900Sbostic if (!isascii(ch)) { 154*38900Sbostic if (putchar('M') == EOF || putchar('-') == EOF) 15537179Sbostic break; 156*38900Sbostic ch = toascii(ch); 15737179Sbostic } 15837179Sbostic if (iscntrl(ch)) { 159*38900Sbostic if (putchar('^') == EOF || 160*38900Sbostic putchar(ch == '\177' ? '?' : 161*38900Sbostic ch | 0100) == EOF) 16237179Sbostic break; 16337179Sbostic continue; 16437179Sbostic } 16537179Sbostic } 166*38900Sbostic if (putchar(ch) == EOF) 16737179Sbostic break; 16837179Sbostic } 16937179Sbostic if (ferror(fp)) { 17037179Sbostic (void)fprintf(stderr, "cat: %s: read error\n", filename); 17137179Sbostic rval = 1; 17237179Sbostic } 17337179Sbostic if (ferror(stdout)) { 17437179Sbostic clearerr(stdout); 17537179Sbostic (void)fprintf(stderr, "cat: stdout: write error\n"); 17637179Sbostic rval = 1; 17737179Sbostic } 17837179Sbostic } 17937179Sbostic 18037179Sbostic raw_args(argv) 18137179Sbostic char **argv; 18237179Sbostic { 18337179Sbostic register int fd; 18437179Sbostic 18537178Sbostic fd = fileno(stdin); 18637128Sbostic filename = "-"; 18737128Sbostic do { 18837128Sbostic if (*argv) { 18937178Sbostic if (!strcmp(*argv, "-")) 19037178Sbostic fd = fileno(stdin); 19137178Sbostic else if ((fd = open(*argv, O_RDONLY, 0)) < 0) { 19237178Sbostic (void)fprintf(stderr, "cat: %s: %s\n", 19337178Sbostic *argv, strerror(errno)); 19437178Sbostic rval = 1; 19537128Sbostic ++argv; 1964387Secc continue; 1974387Secc } 19837178Sbostic filename = *argv++; 199962Sbill } 20037179Sbostic rval |= raw_cat(fd); 20137178Sbostic if (fd != fileno(stdin)) 20237178Sbostic (void)close(fd); 20337128Sbostic } while (*argv); 204962Sbill } 2051357Sbill 20637179Sbostic raw_cat(fd) 20737128Sbostic register int fd; 20817947Sralph { 20937128Sbostic extern int errno; 21037128Sbostic register int nr, nw, off; 21137178Sbostic static int bsize; 21237178Sbostic static char *buf; 21337178Sbostic struct stat sbuf; 21437178Sbostic char *malloc(), *strerror(); 21517947Sralph 21637178Sbostic if (!buf) { 21737178Sbostic if (fstat(fileno(stdout), &sbuf)) { 21837178Sbostic (void)fprintf(stderr, "cat: %s: %s\n", filename, 21937178Sbostic strerror(errno)); 22037178Sbostic return(1); 22137178Sbostic } 22237178Sbostic bsize = MAX(sbuf.st_blksize, 1024); 22337178Sbostic if (!(buf = malloc((u_int)bsize))) { 22437179Sbostic (void)fprintf(stderr, "cat: %s: no memory.\n", 22537179Sbostic filename); 22637178Sbostic return(1); 22737178Sbostic } 22837178Sbostic } 22937178Sbostic while ((nr = read(fd, buf, bsize)) > 0) 23037128Sbostic for (off = 0; off < nr;) { 23137128Sbostic if ((nw = write(fileno(stdout), buf + off, nr)) < 0) { 23237128Sbostic perror("cat: stdout"); 23337178Sbostic return(1); 23417965Skarels } 23537128Sbostic off += nw; 23637128Sbostic } 23737128Sbostic if (nr < 0) { 23837128Sbostic (void)fprintf(stderr, "cat: %s: %s\n", filename, 23937128Sbostic strerror(errno)); 24037178Sbostic return(1); 24117947Sralph } 24237178Sbostic return(0); 24317947Sralph } 244