new copyright notice
[unix-history] / usr / src / bin / cat / cat.c
index 4764abb..2155190 100644 (file)
@@ -5,17 +5,7 @@
  * This code is derived from software contributed to Berkeley by
  * Kevin Fall.
  *
  * This code is derived from software contributed to Berkeley by
  * Kevin Fall.
  *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by the University of California, Berkeley.  The name of the
- * University may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ * %sccs.include.redist.c%
  */
 
 #ifndef lint
  */
 
 #ifndef lint
@@ -25,7 +15,7 @@ char copyright[] =
 #endif /* not lint */
 
 #ifndef lint
 #endif /* not lint */
 
 #ifndef lint
-static char sccsid[] = "@(#)cat.c      5.5 (Berkeley) %G%";
+static char sccsid[] = "@(#)cat.c      5.11 (Berkeley) %G%";
 #endif /* not lint */
 
 #include <sys/param.h>
 #endif /* not lint */
 
 #include <sys/param.h>
@@ -34,33 +24,154 @@ static char sccsid[] = "@(#)cat.c  5.5 (Berkeley) %G%";
 #include <stdio.h>
 #include <ctype.h>
 
 #include <stdio.h>
 #include <ctype.h>
 
+extern int errno;
+int bflag, eflag, nflag, sflag, tflag, vflag;
+int rval;
 char *filename;
 
 main(argc, argv)
        int argc;
        char **argv;
 {
 char *filename;
 
 main(argc, argv)
        int argc;
        char **argv;
 {
-       extern int errno, optind;
-       register int fd, ch, rval;
+       extern int optind;
+       int ch;
        char *strerror();
 
        char *strerror();
 
-       while ((ch = getopt(argc, argv, "-u")) != EOF)
+       while ((ch = getopt(argc, argv, "benstuv")) != EOF)
                switch (ch) {
                switch (ch) {
-               case '-':
-                       --optind;
-                       goto done;
-               case 'u':                       /* always unbuffered */
+               case 'b':
+                       bflag = nflag = 1;      /* -b implies -n */
+                       break;
+               case 'e':
+                       eflag = vflag = 1;      /* -e implies -v */
+                       break;
+               case 'n':
+                       nflag = 1;
+                       break;
+               case 's':
+                       sflag = 1;
+                       break;
+               case 't':
+                       tflag = vflag = 1;      /* -t implies -v */
+                       break;
+               case 'u':
+                       setbuf(stdout, (char *)NULL);
+                       break;
+               case 'v':
+                       vflag = 1;
                        break;
                case '?':
                        (void)fprintf(stderr,
                        break;
                case '?':
                        (void)fprintf(stderr,
-                           "usage: cat [-u] [-] [file ...]\n");
+                           "usage: cat [-benstuv] [-] [file ...]\n");
                        exit(1);
                }
                        exit(1);
                }
-done:  argv += optind;
+       argv += optind;
+
+       if (bflag || eflag || nflag || sflag || tflag || vflag)
+               cook_args(argv);
+       else
+               raw_args(argv);
+       exit(rval);
+}
+
+cook_args(argv)
+       char **argv;
+{
+       register FILE *fp;
+
+       fp = stdin;
+       filename = "-";
+       do {
+               if (*argv) {
+                       if (!strcmp(*argv, "-"))
+                               fp = stdin;
+                       else if (!(fp = fopen(*argv, "r"))) {
+                               (void)fprintf(stderr, 
+                                   "cat: %s: %s\n", *argv, strerror(errno));
+                               rval = 1;
+                               ++argv;
+                               continue;
+                       }
+                       filename = *argv++;
+               }
+               cook_buf(fp);
+               if (fp != stdin)
+                       (void)fclose(fp);
+       } while (*argv);
+}
+
+cook_buf(fp)
+       register FILE *fp;
+{
+       register int ch, gobble, line, prev;
+
+       line = gobble = 0;
+       for (prev = '\n'; (ch = getc(fp)) != EOF; prev = ch) {
+               if (prev == '\n') {
+                       if (ch == '\n') {
+                               if (sflag) {
+                                       if (!gobble && putchar(ch) == EOF)
+                                               break;
+                                       gobble = 1;
+                                       continue;
+                               }
+                               if (nflag && !bflag) {
+                                       (void)fprintf(stdout, "%6d\t", ++line);
+                                       if (ferror(stdout))
+                                               break;
+                               }
+                       } else if (nflag) {
+                               (void)fprintf(stdout, "%6d\t", ++line);
+                               if (ferror(stdout))
+                                       break;
+                       }
+               }
+               gobble = 0;
+               if (ch == '\n') {
+                       if (eflag)
+                               if (putchar('$') == EOF)
+                                       break;
+               } else if (ch == '\t') {
+                       if (tflag) {
+                               if (putchar('^') == EOF || putchar('I') == EOF)
+                                       break;
+                               continue;
+                       }
+               } else if (vflag) {
+                       if (!isascii(ch)) {
+                               if (putchar('M') == EOF || putchar('-') == EOF)
+                                       break;
+                               ch = toascii(ch);
+                       }
+                       if (iscntrl(ch)) {
+                               if (putchar('^') == EOF ||
+                                   putchar(ch == '\177' ? '?' :
+                                   ch | 0100) == EOF)
+                                       break;
+                               continue;
+                       }
+               }
+               if (putchar(ch) == EOF)
+                       break;
+       }
+       if (ferror(fp)) {
+               (void)fprintf(stderr, "cat: %s: read error\n", filename);
+               rval = 1;
+       }
+       if (ferror(stdout)) {
+               clearerr(stdout);
+               (void)fprintf(stderr, "cat: stdout: write error\n");
+               rval = 1;
+       }
+}
+
+raw_args(argv)
+       char **argv;
+{
+       register int fd;
 
        fd = fileno(stdin);
        filename = "-";
 
        fd = fileno(stdin);
        filename = "-";
-       rval = 0;
        do {
                if (*argv) {
                        if (!strcmp(*argv, "-"))
        do {
                if (*argv) {
                        if (!strcmp(*argv, "-"))
@@ -74,17 +185,15 @@ done:      argv += optind;
                        }
                        filename = *argv++;
                }
                        }
                        filename = *argv++;
                }
-               rval |= rawcat(fd);
+               rval |= raw_cat(fd);
                if (fd != fileno(stdin))
                        (void)close(fd);
        } while (*argv);
                if (fd != fileno(stdin))
                        (void)close(fd);
        } while (*argv);
-       exit(rval);
 }
 
 }
 
-rawcat(fd)
+raw_cat(fd)
        register int fd;
 {
        register int fd;
 {
-       extern int errno;
        register int nr, nw, off;
        static int bsize;
        static char *buf;
        register int nr, nw, off;
        static int bsize;
        static char *buf;
@@ -99,7 +208,8 @@ rawcat(fd)
                }
                bsize = MAX(sbuf.st_blksize, 1024);
                if (!(buf = malloc((u_int)bsize))) {
                }
                bsize = MAX(sbuf.st_blksize, 1024);
                if (!(buf = malloc((u_int)bsize))) {
-                       fprintf(stderr, "cat: %s: no memory.\n", filename);
+                       (void)fprintf(stderr, "cat: %s: no memory.\n",
+                           filename);
                        return(1);
                }
        }
                        return(1);
                }
        }