17bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes/* $NetBSD: cat.c,v 1.54 2013/12/08 08:32:13 spz Exp $	*/
2dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
3dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*
4dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Copyright (c) 1989, 1993
5dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *	The Regents of the University of California.  All rights reserved.
6dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *
7dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * This code is derived from software contributed to Berkeley by
8dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Kevin Fall.
9dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *
10dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Redistribution and use in source and binary forms, with or without
11dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * modification, are permitted provided that the following conditions
12dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * are met:
13dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 1. Redistributions of source code must retain the above copyright
14dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *    notice, this list of conditions and the following disclaimer.
15dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright
16dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *    notice, this list of conditions and the following disclaimer in the
17dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *    documentation and/or other materials provided with the distribution.
18dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 3. Neither the name of the University nor the names of its contributors
19dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *    may be used to endorse or promote products derived from this software
20dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *    without specific prior written permission.
21dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *
22dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * SUCH DAMAGE.
33dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */
34dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
357bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes#if HAVE_NBTOOL_CONFIG_H
367bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes#include "nbtool_config.h"
377bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes#endif
387bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes
397bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes#include <sys/cdefs.h>
407bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes#if !defined(lint)
417bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes__COPYRIGHT(
427bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes"@(#) Copyright (c) 1989, 1993\
437bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes The Regents of the University of California.  All rights reserved.");
447bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes#if 0
457bb5660647d0106f96b000c25f5690a45734c38cElliott Hughesstatic char sccsid[] = "@(#)cat.c	8.2 (Berkeley) 4/27/95";
467bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes#else
477bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes__RCSID("$NetBSD: cat.c,v 1.54 2013/12/08 08:32:13 spz Exp $");
487bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes#endif
497bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes#endif /* not lint */
507bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes
51dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/param.h>
52dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/stat.h>
53dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
54dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <ctype.h>
557bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes#include <err.h>
56dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <errno.h>
57dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <fcntl.h>
587bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes#include <locale.h>
59dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdio.h>
60dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdlib.h>
61dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <string.h>
62dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <unistd.h>
63dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
64dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int bflag, eflag, fflag, lflag, nflag, sflag, tflag, vflag;
657bb5660647d0106f96b000c25f5690a45734c38cElliott Hughesstatic size_t bsize;
66dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int rval;
67dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic const char *filename;
68dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
697bb5660647d0106f96b000c25f5690a45734c38cElliott Hughesvoid cook_args(char *argv[]);
707bb5660647d0106f96b000c25f5690a45734c38cElliott Hughesvoid cook_buf(FILE *);
717bb5660647d0106f96b000c25f5690a45734c38cElliott Hughesvoid raw_args(char *argv[]);
727bb5660647d0106f96b000c25f5690a45734c38cElliott Hughesvoid raw_cat(int);
737bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes
747bb5660647d0106f96b000c25f5690a45734c38cElliott Hughesint
757bb5660647d0106f96b000c25f5690a45734c38cElliott Hughesmain(int argc, char *argv[])
767bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes{
777bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes	int ch;
787bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes	struct flock stdout_lock;
797bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes
807bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes	setprogname(argv[0]);
817bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes	(void)setlocale(LC_ALL, "");
827bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes
837bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes	while ((ch = getopt(argc, argv, "B:beflnstuv")) != -1)
847bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes		switch (ch) {
857bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes		case 'B':
867bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes			bsize = (size_t)strtol(optarg, NULL, 0);
877bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes			break;
887bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes		case 'b':
897bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes			bflag = nflag = 1;	/* -b implies -n */
907bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes			break;
917bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes		case 'e':
927bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes			eflag = vflag = 1;	/* -e implies -v */
937bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes			break;
947bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes		case 'f':
957bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes			fflag = 1;
967bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes			break;
977bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes		case 'l':
987bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes			lflag = 1;
997bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes			break;
1007bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes		case 'n':
1017bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes			nflag = 1;
1027bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes			break;
1037bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes		case 's':
1047bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes			sflag = 1;
1057bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes			break;
1067bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes		case 't':
1077bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes			tflag = vflag = 1;	/* -t implies -v */
1087bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes			break;
1097bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes		case 'u':
1107bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes			setbuf(stdout, NULL);
1117bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes			break;
1127bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes		case 'v':
1137bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes			vflag = 1;
1147bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes			break;
1157bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes		default:
1167bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes		case '?':
1177bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes			(void)fprintf(stderr,
1187bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes			    "Usage: %s [-beflnstuv] [-B bsize] [-] "
1197bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes			    "[file ...]\n", getprogname());
1207bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes			return EXIT_FAILURE;
1217bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes		}
1227bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes	argv += optind;
1237bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes
1247bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes	if (lflag) {
1257bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes		stdout_lock.l_len = 0;
1267bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes		stdout_lock.l_start = 0;
1277bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes		stdout_lock.l_type = F_WRLCK;
1287bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes		stdout_lock.l_whence = SEEK_SET;
1297bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes		if (fcntl(STDOUT_FILENO, F_SETLKW, &stdout_lock) == -1)
1307bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes			err(EXIT_FAILURE, "stdout");
1317bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes	}
1327bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes
1337bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes	if (bflag || eflag || nflag || sflag || tflag || vflag)
1347bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes		cook_args(argv);
1357bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes	else
1367bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes		raw_args(argv);
1377bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes	if (fclose(stdout))
1387bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes		err(EXIT_FAILURE, "stdout");
1397bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes	return rval;
1407bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes}
1417bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes
1427bb5660647d0106f96b000c25f5690a45734c38cElliott Hughesvoid
1437bb5660647d0106f96b000c25f5690a45734c38cElliott Hughescook_args(char **argv)
1447bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes{
1457bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes	FILE *fp;
1467bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes
1477bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes	fp = stdin;
1487bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes	filename = "stdin";
1497bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes	do {
1507bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes		if (*argv) {
1517bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes			if (!strcmp(*argv, "-"))
1527bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes				fp = stdin;
1537bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes			else if ((fp = fopen(*argv,
1547bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes			    fflag ? "rf" : "r")) == NULL) {
1557bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes				warn("%s", *argv);
1567bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes				rval = EXIT_FAILURE;
1577bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes				++argv;
1587bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes				continue;
1597bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes			}
1607bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes			filename = *argv++;
1617bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes		}
1627bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes		cook_buf(fp);
1637bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes		if (fp != stdin)
1647bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes			(void)fclose(fp);
1657bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes		else
1667bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes			clearerr(fp);
1677bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes	} while (*argv);
1687bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes}
1697bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes
1707bb5660647d0106f96b000c25f5690a45734c38cElliott Hughesvoid
171dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectcook_buf(FILE *fp)
172dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
173dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	int ch, gobble, line, prev;
174dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
175dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	line = gobble = 0;
176dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	for (prev = '\n'; (ch = getc(fp)) != EOF; prev = ch) {
177dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (prev == '\n') {
178dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			if (ch == '\n') {
179dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				if (sflag) {
1807bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes					if (!gobble && nflag && !bflag)
1817bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes						(void)fprintf(stdout,
1827bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes							"%6d\t\n", ++line);
1837bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes					else if (!gobble && putchar(ch) == EOF)
184dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project						break;
185dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					gobble = 1;
186dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					continue;
187dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				}
188dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				if (nflag) {
189dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					if (!bflag) {
1907bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes						(void)fprintf(stdout,
1917bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes						    "%6d\t", ++line);
1927bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes						if (ferror(stdout))
193dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project							break;
194dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					} else if (eflag) {
1957bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes						(void)fprintf(stdout,
1967bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes						    "%6s\t", "");
1977bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes						if (ferror(stdout))
198dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project							break;
199dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					}
200dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				}
201dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			} else if (nflag) {
2027bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes				(void)fprintf(stdout, "%6d\t", ++line);
2037bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes				if (ferror(stdout))
204dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					break;
205dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			}
206dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		}
207dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		gobble = 0;
208dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (ch == '\n') {
209dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			if (eflag)
210dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				if (putchar('$') == EOF)
211dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					break;
212dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		} else if (ch == '\t') {
213dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			if (tflag) {
214dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				if (putchar('^') == EOF || putchar('I') == EOF)
215dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					break;
216dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				continue;
217dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			}
218dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		} else if (vflag) {
219dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			if (!isascii(ch)) {
220dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				if (putchar('M') == EOF || putchar('-') == EOF)
221dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					break;
2227bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes				ch = toascii(ch);
223dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			}
224dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			if (iscntrl(ch)) {
225dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				if (putchar('^') == EOF ||
226dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				    putchar(ch == '\177' ? '?' :
227dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				    ch | 0100) == EOF)
228dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					break;
229dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				continue;
230dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			}
231dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		}
232dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (putchar(ch) == EOF)
233dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			break;
234dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
2357bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes	if (ferror(fp)) {
2367bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes		warn("%s", filename);
2377bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes		rval = EXIT_FAILURE;
2387bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes		clearerr(fp);
239dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
2407bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes	if (ferror(stdout))
2417bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes		err(EXIT_FAILURE, "stdout");
242dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
243dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
2447bb5660647d0106f96b000c25f5690a45734c38cElliott Hughesvoid
245dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectraw_args(char **argv)
246dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
247dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	int fd;
248dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
249dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	fd = fileno(stdin);
250dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	filename = "stdin";
251dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	do {
252dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (*argv) {
2537bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes			if (!strcmp(*argv, "-")) {
254dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				fd = fileno(stdin);
2557bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes				if (fd < 0)
2567bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes					goto skip;
2577bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes			} else if (fflag) {
258dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				struct stat st;
259dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				fd = open(*argv, O_RDONLY|O_NONBLOCK, 0);
260dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				if (fd < 0)
261dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					goto skip;
262dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
263dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				if (fstat(fd, &st) == -1) {
264dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					close(fd);
265dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					goto skip;
266dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				}
267dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				if (!S_ISREG(st.st_mode)) {
268dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					close(fd);
2697bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes					warnx("%s: not a regular file", *argv);
270dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					goto skipnomsg;
271dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				}
272dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			}
273dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			else if ((fd = open(*argv, O_RDONLY, 0)) < 0) {
274dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectskip:
2757bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes				warn("%s", *argv);
276dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectskipnomsg:
2777bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes				rval = EXIT_FAILURE;
278dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				++argv;
279dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				continue;
280dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			}
281dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			filename = *argv++;
2827bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes		} else if (fd < 0) {
2837bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes			err(EXIT_FAILURE, "stdin");
284dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		}
285dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		raw_cat(fd);
286dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (fd != fileno(stdin))
2877bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes			(void)close(fd);
288dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	} while (*argv);
289dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
290dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
2917bb5660647d0106f96b000c25f5690a45734c38cElliott Hughesvoid
2927bb5660647d0106f96b000c25f5690a45734c38cElliott Hughesraw_cat(int rfd)
293dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
2947bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes	static char *buf;
2957bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes	static char fb_buf[BUFSIZ];
296dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
2977bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes	ssize_t nr, nw, off;
2987bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes	int wfd;
299dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
3007bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes	wfd = fileno(stdout);
3017bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes	if (wfd < 0)
3027bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes		err(EXIT_FAILURE, "stdout");
3037bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes	if (buf == NULL) {
3047bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes		struct stat sbuf;
3057bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes
3067bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes		if (bsize == 0) {
3077bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes			if (fstat(wfd, &sbuf) == 0 && sbuf.st_blksize > 0 &&
3087bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes			    (size_t)sbuf.st_blksize > sizeof(fb_buf))
3097bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes				bsize = sbuf.st_blksize;
3107bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes		}
3117bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes		if (bsize > sizeof(fb_buf)) {
3127bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes			buf = malloc(bsize);
3137bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes			if (buf == NULL)
3147bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes				warnx("malloc, using %zu buffer", bsize);
3157bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes		}
3167bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes		if (buf == NULL) {
3177bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes			bsize = sizeof(fb_buf);
3187bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes			buf = fb_buf;
319dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		}
320dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
3217bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes	while ((nr = read(rfd, buf, bsize)) > 0)
3227bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes		for (off = 0; nr; nr -= nw, off += nw)
3237bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes			if ((nw = write(wfd, buf + off, (size_t)nr)) < 0)
3247bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes				err(EXIT_FAILURE, "stdout");
3257bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes	if (nr < 0) {
3267bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes		warn("%s", filename);
3277bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes		rval = EXIT_FAILURE;
328dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
329dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
330