+ 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;