/*
 *	THRU
 *	put file through a command.
 *	Usage: thru file command arg1 arg2 ...
 *
 *	Invokes command with args (verbatim) with both stdin and stdout
 *	open to the file, on separate file descriptors so that they have
 *	separate read/write pointers. For this to work properly, the
 *	program should either produce the same amount of output as it
 *	does input, and do read-ahead and write-behind, or should produce
 *	less output than input. Otherwise you risk reading the command's
 *	output as fresh input and garbling the file completely.
 *	Know thine command well!
 *	eg
 *	thru wombats unexpand		might work, but
 *	thru wombats expand		is unlikely to unless the file is
 *					smaller than one I/O buffer.
 *
 *	Problem: If the file should have got smaller, it won't.
 *
 *	If you don't understand the above completely, then DO NOT USE THRU
 *	because it will shit on your files.
 */
#include <stdio.h>

char *progname;		/* argv[0] for error reporting */

main(argc, argv)
char **argv;
{
	register int ifd, ofd;	/* input and output file descriptors */

	progname = argv[0];

	if (argc < 3) {
		fputs("Usage: thru file command [arg] ...\n", stderr);
		fputs("WARNING: thru is dangerous if you do not understand it.\n", stderr);
		exit(1);
	}

	ifd = open(argv[1], 0);	/* open for read */
	if (ifd < 0) {
		fprintf(stderr, "%s: Cannot read ", progname);
		perror(argv[1]);
		exit(1);
	}

	ofd = open(argv[1], 1);	/* open for write */
	if (ofd < 0) {
		fprintf(stderr, "%s: Cannot write to ", progname);
		perror(argv[1]);
		exit(1);
	}

	dup2(ifd, 0);
	close(ifd);
	dup2(ofd, 1);
	close(ofd);

	argv += 2;	/* throw away command name "thru" and filename */
	execvp(argv[0], argv);

	/* what? we're still here? */
	fprintf(stderr, "%s: Cannot execute ", progname);
	perror(argv[0]);
}
