119840Sdist /* 2*63892Sbostic * Copyright (c) 1989, 1993 3*63892Sbostic * The Regents of the University of California. All rights reserved. 437128Sbostic * 537128Sbostic * This code is derived from software contributed to Berkeley by 637128Sbostic * Kevin Fall. 737128Sbostic * 842524Sbostic * %sccs.include.redist.c% 919840Sdist */ 1019840Sdist 1114463Ssam #ifndef lint 12*63892Sbostic static char copyright[] = 13*63892Sbostic "@(#) Copyright (c) 1989, 1993\n\ 14*63892Sbostic The Regents of the University of California. All rights reserved.\n"; 1534079Sbostic #endif /* not lint */ 1614463Ssam 1734079Sbostic #ifndef lint 18*63892Sbostic static char sccsid[] = "@(#)cat.c 8.1 (Berkeley) 07/19/93"; 1934079Sbostic #endif /* not lint */ 2034079Sbostic 2137178Sbostic #include <sys/param.h> 2237178Sbostic #include <sys/stat.h> 2358141Sbostic 2458141Sbostic #include <ctype.h> 2558141Sbostic #include <err.h> 2658141Sbostic #include <errno.h> 2748953Sbostic #include <fcntl.h> 28962Sbill #include <stdio.h> 2948953Sbostic #include <stdlib.h> 3048953Sbostic #include <string.h> 3158141Sbostic #include <unistd.h> 32962Sbill 3337179Sbostic int bflag, eflag, nflag, sflag, tflag, vflag; 3437179Sbostic int rval; 3537128Sbostic char *filename; 36962Sbill 3758141Sbostic void cook_args __P((char *argv[])); 3858141Sbostic void cook_buf __P((FILE *)); 3958141Sbostic void raw_args __P((char *argv[])); 4058141Sbostic void raw_cat __P((int)); 4148953Sbostic 4258141Sbostic int 43962Sbill main(argc, argv) 4437128Sbostic int argc; 4558141Sbostic char *argv[]; 46962Sbill { 4740268Sbostic extern int optind; 4837179Sbostic int ch; 49962Sbill 5039713Sbostic while ((ch = getopt(argc, argv, "benstuv")) != EOF) 5137128Sbostic switch (ch) { 5237179Sbostic case 'b': 5337179Sbostic bflag = nflag = 1; /* -b implies -n */ 54962Sbill break; 5537179Sbostic case 'e': 5637179Sbostic eflag = vflag = 1; /* -e implies -v */ 5737179Sbostic break; 5837179Sbostic case 'n': 5937179Sbostic nflag = 1; 6037179Sbostic break; 6137179Sbostic case 's': 6237179Sbostic sflag = 1; 6337179Sbostic break; 6437179Sbostic case 't': 6537179Sbostic tflag = vflag = 1; /* -t implies -v */ 6637179Sbostic break; 6737179Sbostic case 'u': 6837179Sbostic setbuf(stdout, (char *)NULL); 6937179Sbostic break; 7037179Sbostic case 'v': 7137179Sbostic vflag = 1; 7237179Sbostic break; 7337128Sbostic case '?': 7437128Sbostic (void)fprintf(stderr, 7537179Sbostic "usage: cat [-benstuv] [-] [file ...]\n"); 7637128Sbostic exit(1); 77962Sbill } 7839713Sbostic argv += optind; 7937128Sbostic 8037179Sbostic if (bflag || eflag || nflag || sflag || tflag || vflag) 8137179Sbostic cook_args(argv); 8237179Sbostic else 8337179Sbostic raw_args(argv); 8449212Sbostic if (fclose(stdout)) 8558141Sbostic err(1, "stdout"); 8637179Sbostic exit(rval); 8737179Sbostic } 8837179Sbostic 8948953Sbostic void 9037179Sbostic cook_args(argv) 9137179Sbostic char **argv; 9237179Sbostic { 9337179Sbostic register FILE *fp; 9437179Sbostic 9537179Sbostic fp = stdin; 9649860Sbostic filename = "stdin"; 9737179Sbostic do { 9837179Sbostic if (*argv) { 9937179Sbostic if (!strcmp(*argv, "-")) 10037179Sbostic fp = stdin; 10158141Sbostic else if ((fp = fopen(*argv, "r")) == NULL) { 10258141Sbostic warn("%s", *argv); 10337179Sbostic ++argv; 10437179Sbostic continue; 10537179Sbostic } 10637179Sbostic filename = *argv++; 10737179Sbostic } 10837179Sbostic cook_buf(fp); 10937179Sbostic if (fp != stdin) 11037179Sbostic (void)fclose(fp); 11137179Sbostic } while (*argv); 11237179Sbostic } 11337179Sbostic 11448953Sbostic void 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) { 12538900Sbostic 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) 14438900Sbostic if (putchar('$') == EOF) 14537179Sbostic break; 14637179Sbostic } else if (ch == '\t') { 14737179Sbostic if (tflag) { 14838900Sbostic if (putchar('^') == EOF || putchar('I') == EOF) 14937179Sbostic break; 15037179Sbostic continue; 15137179Sbostic } 15237179Sbostic } else if (vflag) { 15338900Sbostic if (!isascii(ch)) { 15438900Sbostic if (putchar('M') == EOF || putchar('-') == EOF) 15537179Sbostic break; 15638900Sbostic ch = toascii(ch); 15737179Sbostic } 15837179Sbostic if (iscntrl(ch)) { 15938900Sbostic if (putchar('^') == EOF || 16038900Sbostic putchar(ch == '\177' ? '?' : 16138900Sbostic ch | 0100) == EOF) 16237179Sbostic break; 16337179Sbostic continue; 16437179Sbostic } 16537179Sbostic } 16638900Sbostic if (putchar(ch) == EOF) 16737179Sbostic break; 16837179Sbostic } 16937179Sbostic if (ferror(fp)) { 17058141Sbostic warn("%s", filename); 17148953Sbostic clearerr(fp); 17237179Sbostic } 17348953Sbostic if (ferror(stdout)) 17458141Sbostic err(1, "stdout"); 17537179Sbostic } 17637179Sbostic 17748953Sbostic void 17837179Sbostic raw_args(argv) 17937179Sbostic char **argv; 18037179Sbostic { 18137179Sbostic register int fd; 18237179Sbostic 18337178Sbostic fd = fileno(stdin); 18449860Sbostic filename = "stdin"; 18537128Sbostic do { 18637128Sbostic if (*argv) { 18737178Sbostic if (!strcmp(*argv, "-")) 18837178Sbostic fd = fileno(stdin); 18937178Sbostic else if ((fd = open(*argv, O_RDONLY, 0)) < 0) { 19058141Sbostic warn("%s", *argv); 19137128Sbostic ++argv; 1924387Secc continue; 1934387Secc } 19437178Sbostic filename = *argv++; 195962Sbill } 19648953Sbostic raw_cat(fd); 19737178Sbostic if (fd != fileno(stdin)) 19837178Sbostic (void)close(fd); 19937128Sbostic } while (*argv); 200962Sbill } 2011357Sbill 20248953Sbostic void 20348953Sbostic raw_cat(rfd) 20448953Sbostic register int rfd; 20517947Sralph { 20648953Sbostic register int nr, nw, off, wfd; 20737178Sbostic static int bsize; 20837178Sbostic static char *buf; 20937178Sbostic struct stat sbuf; 21017947Sralph 21148953Sbostic wfd = fileno(stdout); 21258141Sbostic if (buf == NULL) { 21348953Sbostic if (fstat(wfd, &sbuf)) 21458141Sbostic err(1, "%s", filename); 21537178Sbostic bsize = MAX(sbuf.st_blksize, 1024); 21658141Sbostic if ((buf = malloc((u_int)bsize)) == NULL) 21758141Sbostic err(1, ""); 21837178Sbostic } 21948953Sbostic while ((nr = read(rfd, buf, bsize)) > 0) 22063891Sbostic for (off = 0; nr; nr -= nw, off += nw) 22148953Sbostic if ((nw = write(wfd, buf + off, nr)) < 0) 22258141Sbostic err(1, "stdout"); 22348953Sbostic if (nr < 0) 22458141Sbostic warn("%s", filename); 22517947Sralph } 226