Beispiel #1
0
/*
 * Are these two really the same inode?
 */
int
samei(struct stat64 *sp, unsigned char *cp)
{
	struct stat64 stb;

	if (stat64((char *)cp, &stb) < 0)
		return (0);
	return (IDENTICAL((*sp), stb));
}
Beispiel #2
0
int
main(int argc, char **argv)
{
	FILE *fi;
	int c;
	extern	int optind;
	int	errflg = 0;
	int	stdinflg = 0;
	int	status = 0;
	int	estatus = 0;
	struct stat source, target;

	(void) setlocale(LC_ALL, "");
#if !defined(TEXT_DOMAIN)	/* Should be defined by cc -D */
#define	TEXT_DOMAIN "SYS_TEST"	/* Use this only if it weren't */
#endif
	(void) textdomain(TEXT_DOMAIN);

#ifdef STANDALONE
	/*
	 * If the first argument is NULL,
	 * discard arguments until we find cat.
	 */
	if (argv[0][0] == '\0')
		argc = getargv("cat", &argv, 0);
#endif

	/*
	 * Process the options for cat.
	 */

	while ((c = getopt(argc, argv, "usvtebn")) != EOF) {
		switch (c) {

		case 'u':

			/*
			 * If not standalone, set stdout to
			 * completely unbuffered I/O when
			 * the 'u' option is used.
			 */

#ifndef	STANDALONE
			setbuf(stdout, (char *)NULL);
#endif
			continue;

		case 's':

			/*
			 * The 's' option requests silent mode
			 * where no messages are written.
			 */

			silent++;
			continue;

		case 'v':

			/*
			 * The 'v' option requests that non-printing
			 * characters (with the exception of newlines,
			 * form-feeds, and tabs) be displayed visibly.
			 *
			 * Control characters are printed as "^x".
			 * DEL characters are printed as "^?".
			 * Non-printable  and non-contrlol characters with the
			 * 8th bit set are printed as "M-x".
			 */

			visi_mode++;
			continue;

		case 't':

			/*
			 * When in visi_mode, this option causes tabs
			 * to be displayed as "^I".
			 */

			visi_tab++;
			continue;

		case 'e':

			/*
			 * When in visi_mode, this option causes newlines
			 * and form-feeds to be displayed as "$" at the end
			 * of the line prior to the newline.
			 */

			visi_newline++;
			continue;

		case 'b':

			/*
			 * Precede each line output with its line number,
			 * but omit the line numbers from blank lines.
			 */

			bflg++;
			nflg++;
			continue;

		case 'n':

			/*
			 * Precede each line output with its line number.
			 */

			nflg++;
			continue;

		case '?':
			errflg++;
			break;
		}
		break;
	}

	if (errflg) {
		if (!silent)
			(void) fprintf(stderr,
			    gettext("usage: cat [ -usvtebn ] [-|file] ...\n"));
		exit(2);
	}

	/*
	 * Stat stdout to be sure it is defined.
	 */

	if (fstat(fileno(stdout), &target) < 0) {
		if (!silent)
			(void) fprintf(stderr,
			    gettext("cat: Cannot stat stdout\n"));
		exit(2);
	}
	obsize = target.st_blksize;

	/*
	 * If no arguments given, then use stdin for input.
	 */

	if (optind == argc) {
		argc++;
		stdinflg++;
	}

	/*
	 * Process each remaining argument,
	 * unless there is an error with stdout.
	 */


	for (argv = &argv[optind];
	    optind < argc && !ferror(stdout); optind++, argv++) {

		/*
		 * If the argument was '-' or there were no files
		 * specified, take the input from stdin.
		 */

		if (stdinflg ||
		    ((*argv)[0] == '-' && (*argv)[1] == '\0'))
			fi = stdin;
		else {
			/*
			 * Attempt to open each specified file.
			 */

			if ((fi = fopen(*argv, "r")) == NULL) {
				if (!silent)
				    (void) fprintf(stderr,
				    gettext("cat: cannot open %s: %s\n"),
					    *argv, strerror(errno));
				status = 2;
				continue;
			}
		}

		/*
		 * Stat source to make sure it is defined.
		 */

		if (fstat(fileno(fi), &source) < 0) {
			if (!silent)
				(void) fprintf(stderr,
				    gettext("cat: cannot stat %s: %s\n"),
				    (stdinflg) ? "-" : *argv, strerror(errno));
			status = 2;
			continue;
		}


		/*
		 * If the source is not a character special file, socket or a
		 * block special file, make sure it is not identical
		 * to the target.
		 */

		if (!S_ISCHR(target.st_mode) &&
		    !S_ISBLK(target.st_mode) &&
		    !S_ISSOCK(target.st_mode) &&
		    IDENTICAL(target, source)) {
			if (!silent)
			    (void) fprintf(stderr,
			    gettext("cat: input/output files '%s' identical\n"),
				stdinflg?"-": *argv);
			if (fclose(fi) != 0)
				(void) fprintf(stderr,
				    gettext("cat: close error: %s\n"),
				    strerror(errno));
			status = 2;
			continue;
		}
		ibsize = source.st_blksize;

		/*
		 * If in visible mode and/or nflg, use vncat;
		 * otherwise, use cat.
		 */

		if (visi_mode || nflg)
			estatus = vncat(fi);
		else
			estatus = cat(fi, &source, &target,
			    fi != stdin ? *argv : "standard input");

		if (estatus)
			status = estatus;

		/*
		 * If the input is not stdin, close the source file.
		 */

		if (fi != stdin) {
			if (fclose(fi) != 0)
				if (!silent)
					(void) fprintf(stderr,
					    gettext("cat: close error: %s\n"),
					    strerror(errno));
		}
	}

	/*
	 * Display any error with stdout operations.
	 */

	if (fclose(stdout) != 0) {
		if (!silent)
			perror(gettext("cat: close error"));
		status = 2;
	}
	return (status);
}