/*
 * getredirection() is intended to aid in porting C programs
 * to VMS (Vax-11 C) which does not support '>' and '<'
 * I/O redirection.  With suitable modification, it may
 * useful for other portability problems as well.
 */

#ifdef	vms
#include	<stdio.h>
#include	<errno.h>

int
getredirection(argc, argv)
int		argc;
char		**argv;
/*
 * Process vms redirection arg's.  Exit if any error is seen.
 * If getredirection() processes an argument, it is erased
 * from the vector.  getredirection() returns a new argc value.
 *
 * Warning: do not try to simplify the code for vms.  The code
 * presupposes that getredirection() is called before any data is
 * read from stdin or written to stdout.
 *
 * Normal usage is as follows:
 *
 *	main(argc, argv)
 *	int		argc;
 *	char		*argv[];
 *	{
 *		argc = getredirection(argc, argv);
 *	}
 */
{
	register char		*ap;	/* Argument pointer	*/
	int			i;	/* argv[] index		*/
	int			j;	/* Output index		*/
	int			file;	/* File_descriptor 	*/

	for (j = i = 1; i < argc; i++) {   /* Do all arguments	*/
	    switch (*(ap = argv[i])) {
	    case '<':			/* <file		*/
		if (freopen(++ap, "r", stdin) == NULL) {
		    perror(ap);		/* Can't find file	*/
		    exit(errno);	/* Is a fatal error	*/
		}
		break;

	    case '>':			/* >file or >>file	*/
		if (*++ap == '>') {	/* >>file		*/
		    /*
		     * If the file exists, and is writable by us,
		     * call freopen to append to the file (using the
		     * file's current attributes).  Otherwise, create
		     * a new file with "vanilla" attributes as if
		     * the argument was given as ">filename".
		     * access(name, 2) is TRUE if we can write on
		     * the specified file.
		     */
		    if (access(++ap, 2) == 0) {
			if (freopen(ap, "a", stdout) != NULL)
			    break;	/* Exit case statement	*/
			perror(ap);	/* Error, can't append	*/
			exit(errno);	/* After access test	*/
		    }			/* If file accessable	*/
		}
		/*
		 * On vms, we want to create the file using "standard"
		 * record attributes.  create(...) creates the file
		 * using the caller's default protection mask and
		 * "variable length, implied carriage return"
		 * attributes. dup2() associates the file with stdout.
		 */
	/* GCE - fix up so we get lf_stream attribute default instead */
		if ((file = creat(ap, 0)) == -1
		 || dup2(file, fileno(stdout)) == -1) {
		    perror(ap);		/* Can't create file	*/
		    exit(errno);	/* is a fatal error	*/
		}			/* If '>' creation	*/
		break;			/* Exit case test	*/

	    default:
		argv[j++] = ap;		/* Not a redirector	*/
		break;			/* Exit case test	*/
	    }
	}				/* For all arguments	*/
	argv[j] = NULL;			/* Terminate argv[]	*/
	return (j);			/* Return new argc	*/
}
#else
getredrection(argc, argv)
int		argc;
char		*argv[];
/*
 * Dummy routine.
 */
{
	return (argv[0], argc);
}
#endif
/*
 *	filter [-tc] [-ic] [n]
 *
 * field utility, originally from Bourne pp.228-9.  Distributed on
 * USENET, July 1985.  Rewritten.
 */


/*)BUILD	$(TKBOPTIONS) = {
			TASK	= ...FLT
		}
*/

#ifdef DOCUMENTATION

title	filtr	Remove hi bits and control chars
index		Remove hi bits and control chars

synopsis

	filtr

description

	The filtr command reads stdin, strips off the high bit
	of every character, and emits to stdout. All control
	characters except \n, \r, \t, and \f (cr, lf, ff, and ht)
	are ignored and not sent through. The result is a "cleaned
	up" file that is for the most part guaranteed printable.
authors

	Glenn Everhart from filter by Martin Minow.
#endif

#include <stdio.h>
#ifdef vms
#include		<ssdef.h>
#include		<stsdef.h>
#define	IO_SUCCESS	(SS$_NORMAL | STS$M_INHIB_MSG)
#define	IO_ERROR	SS$_ABORT
#endif
/*
 * Note: IO_SUCCESS and IO_ERROR are defined in the Decus C stdio.h file
 */
#ifndef	IO_SUCCESS
#define	IO_SUCCESS	0
#endif
#ifndef	IO_ERROR
#define	IO_ERROR	1
#endif

main(argc,argv)
int		argc;
char		*argv[];
{
	register int	c;
	register char  ch;
#ifdef vms
	argc = getredirection(argc, argv);
#endif
	while (!feof(stdin)) {
	    while ((c = getchar()) != '\n' && c != EOF) {

/* emit the char after removing hi bit and ctl chars other than */
/* 9 (ht), 10 (lf), 13 (cr), and 12 (ff) */
	ch = c & 127;	/* mask off high bit */
/* emit it if not one of the permitted control chars */
     if ((ch >=' ')&&(ch != '\r' && ch != '\n' && ch != '\t' && ch != '\f')) {
/* Also throw out DEL characters */
		if (ch != '\0177')
		putchar(ch);
               }		
	    }
	    if (c == EOF)
		break;
	    if (c == '\n')
		putchar('\n');
	}
	return (IO_SUCCESS);
}
