enhancements to the MENU program

Orest Jarosiewicz orest at pyuxd.UUCP
Wed Oct 5 01:00:18 AEST 1983


# This is an enhaced version of Richard Conn's MENU program.
# Rather than using system(3) to execute the command lines this version
# opens a pipe to shell at the start of the session, and sends the command
# lines over the pipe to the shell.
# This allows things like the ability to set shell variables and having the
# the shell remember the current working directory.
# 
# This changes were made on a 3B20S running BTL UNIX 5.0.
# To install the MENU program and its new documentation, just execute this file.
# Two files will be created, "menu.1" and "menu.c".
# On BTL UNIX 5.0 compile the program with:
# 	cc menu.c -DSYS3 -o menu
# 
# 					Orest Jarosiewicz
awk 'BEGIN	{file=""}
/^#### /	{file=$2; print "Building " $2
		print "" > file
		next
		}
		{if( file == "" ) next
		print substr( $0, 2 ) >> file
		}' $0
#### menu.1
#.TH MENU 1
#.SH NAME
#MENU -- A Menu Preprocessor for UNIX
#.sp 2
#MENU Version 2.0 by Richard Conn
#.SH SYNOPSIS
#
#	MENU is invoked by a command line of the following form:
#
#.ce
#menu [-n] menufile
#
#where the "-n" is optional and is the number of a menu to be invoked in
#a menu file which contains more than one menu.
#
#	Hence, MENU command lines may take the following forms:
#
#.nf
#		menu mymenu	<-- invoke on file 'mymenu'
#		menu -2 mymenu	<-- invoke menu 2 of file 'mymenu'
#
#.fi
#.SH DESCRIPTION
#	MENU (written in C) is a very simple menu preprocessor for use
#under the UNIX operating system.  A user can compose files containing
#screen displays and command lines which are invoked in response to
#single-character
#commands, and MENU will present those screen displays to the user and
#accept both single-character and text string (terminated by a RETURN)
#input from the user.
#
#.SH WRITING MENU FILES
#
#	A file which can be processed by MENU can take on the following
#general format:
#
#.nf
#-o		<-- set global options (optional line)
##o		<-- define screen display and set local options
#<text>		<-- text of screen display
##		<-- end of screen display
#<c><text>	<-- command letter followed by text of command line
#   ...		<-- additional menus, all of the format
#			#o
#			<text>
#			#
#			<c><text>
##o		<-- define screen display and set local options for
#			next menu
#<text>
##
#<c><text>	<-- command letter followed by text of command line
##		<-- marks end of last menu
#
#.fi
#	There are three options recognized by the MENU processor.  These
#options are:
#
#.nf
#		d - Display text of menu (screen display)
#		p - If 'd' is on, page (fill screen with blank lines)
#			when end of menu text (screen display)
#			is reached
#		x - Allow the user to exit to UNIX
#
#.fi
#	When MENU is first invoked, all three options are OFF.  The text
#of the screen displays will not be shown and the user will not be allowed
#to exit to UNIX.
#
#	The first line (which is optional) of the menu file
#toggles the global options to ON from their initial state of OFF.  The
#dash (-) can be followed by any combination of the menu options in any
#order (-dpx = -xpd = -pxd).  This global option line sets the options
#for all of the menus in the file except for those menus whose option
#line toggles selected options.
#
#	Each menu begins with its own option line.  This is the hash (#)
#followed by zero or more of the option characters.  For each option character
#specified, the state of the global options FOR THIS MENU ONLY is reversed.
#Note the following example:
#
#.ne 20
#.nf
#		-dpx		<-- turn on all options
#		#x		<-- do not allow the user to exit
#					to UNIX for this menu
#		<text>
#		#
#		<c><text>
#		#px		<-- do not allow the user to exit
#					to UNIX and do not page the
#					screen display for this menu
#		<text>
#		#
#		<c><text>
#		#		<-- all options are on for this menu
#		<text>
#		#
#		<c><text>
#		#
#
#.fi
#	The text of the screen display (that text which follows the
#local options line for each menu) can be any text desired with the
#one exception that the first character of any line of this text may
#not be a hash (#).  The hash, of course, signals the end of the
#screen display text and the beginning of the command text.
#Example:
#
#.nf
#		#dpx		<-- this menu has no globals set
#			Any	<-- text of menu
#			Text
#			I Want
#		#
#		<c><text>
#		#		<-- only one menu in this file
#
#.fi
#	Finally, the last part of a menu entry is the command
#definition itself.  The definition of a menu command is of the
#following general form:
#
#.ce
#<char><text>
#
#where <char> is one character which will invoke the text of a
#command line.
#When you first invoke the MENU program it creates a pipe to the shell.
#The shell is selected by looking at the SHELL environment variable.
#If this variable is not set then
#.I "sh(1)"
#is used.
#For example, valid menu command lines include:
#
#.nf
#		dls		<-- run ls if char 'd' is typed
#		Dls | pr -4t	<-- run 'ls | pr -4t' if char
#					'D' is typed
#
#.fi
#	There are three special characters which may be embedded
#into the text of the command line to cause MENU to perform some
#additional processing.  These characters are:
#
#.nf
#		:	<-- goto a menu
#		!	<-- cause MENU to wait when
#				command line completes
#		~	<-- submit the command line by spawning off a
#				subshell, this is useful for invoking commands
#				which must be attached to a physical
#				device, such as vi.
#		=	<-- change the current working directory
#		'	<-- prompt user for string input
#
#.fi
#	The first special character is used to transfer control
#from one menu in a menu file to another.  If the colon (:) is the
#first character of text (right after the single-character command),
#then the rest of the line is assumed to be the text of a number,
#and control is transferred to that menu (first menu is 1, second is 2, etc)
#in the file.  ":2" will transfer to menu 2, ":20" will transfer
#to menu 20, etc.  Examples:
#
#.nf
#		2:2	<-- goto menu 2 if char '2' is typed
#		h:1	<-- goto menu 1 if char 'h' is typed
#		?:100	<-- goto menu 100 if char '?' is typed
#
#.fi
#	The second character is used to cause MENU to wait for user
#input after the text of the command line is executed (before displaying
#the screen of the menu the user is returning to).  If the exclamation
#mark (!) is the first character of text (right after the single-character
#command), then MENU will wait after the text of the command line
#is executed.  Examples:
#
#.nf
#		d!ls		<-- run 'ls' and then wait
#		D!ls | pr -4t	<-- run 'ls | pr -4t' and then wait
#
#.fi
#	The third character is used to invoke a command line by using a
#subshell.  This option is useful when submitting commands which
#put the terminal into raw mode, such as screen editors.
#
#	The fourth character is used to change MENU's current working directory.
#Upon seeing this option MENU will send a change directory command to the
#shell so that it too will change to the new working directory.  Examples:
#
#.nf
#		U=..		<-- go up to the parent directory
#		c=bin		<-- go into the bin directory
#.fi
#
#	Finally, the fifth character is followed by text to prompt the
#user for input, and the user is allowed to enter any text he desires.
#This text will be inserted at the point of the prompt.  Unlike the
#other two commands, the text input command (') may appear anywhere
#in the text of the command line.  This text may be bracketed by the
#quote character (like 'Enter Source File'), in which case the user's
#input is inserted into the command line at this point and command line
#processing from the menu file resumes after the second quote.  Alternatively,
#this text may be preceeded by the quote character (like 'Enter File? ),
#in which case the end of the line indicates the end of the prompt.  In
#both cases, the last character of the prompt is followed by a trailing
#blank to improve readability.
#Examples:
#
#.ne 22
#.nf
#		u'Enter Command? 	<-- user is prompted with
#						'Enter Command? '
#						and his text becomes
#						the command line
#		u!'Command? 		<-- like above, but MENU
#						waits when the command
#						is completed
#		d!ls 'File Spec?' | wc 	<-- the command line
#						'ls <user input> | wc' is
#						built
#		ccp 'Source?' 'Destination?'
#					<-- the user is prompted once
#						with 'Source? ', allowed
#						to enter his input, is
#						prompted on the next line
#						with 'Destintion? ',
#						allowed to enter his input,
#						and the command line
#						'cp <user 1> <user 2>'
#						is built
#.fi
#.SH EXAMPLE
#
#	The following is a sample menu file.
#Note that it contains commands which are available
#on my UNIX SYSTEM III but may not be available on yours.
#
#.nf
#
#-dpx
##p
#MENU 1 - Basic Operations
#
#        ---- Directory ----     ---- File Transfer ----
#        d display directory     1 compress file
#        D disp dir with arg     2 uncompress file
#        / change directory      u uc - transfer file
#
#        ------ Filer ------     -------- Other --------
#            c  copy file         C  C Programming Menu
#            e  edit file         w  who is on?
#            f  format file       z  enter any command
#            r  remove file
#            t  type file
#
##
#C:2
#ccp 'Source File?' 'Destination File or Dir?
#d!ls | pr -4t
#D!ls 'Enter File Spec?
#/='Enter Directory Name?
#1xsq 'Enter File Name?
#2xusq 'Enter File Name?
#uuc z
#e~vi 'Enter File Name?
#fnroff >out.roff 'Output is on out.roff -- Enter File Name?
#rrm 'Enter File Name?
#t!type 'Enter File Name?
#w!who
#z!'Enter Command Line?
##
#MENU 2 -- C Programming
#
#        -------- Filer --------         ---- Compiler ----
#          d  display directory            c  compile prog
#          e  edit file
#          r  remove file                ----- Other ------
#          t  type file                    z  run prog
#                                          M  Main menu
##
#M:1
#d!ls | pr -4t
#evi 'Enter File Name?
#rrm 'Enter File Name?
#t!type 'Enter File Name?
#c!cc  'Enter File Name?
#z!'Enter Command Line?
##
#.fi
#.SH FILES
#.nf
#menu.c   -- source code
#mcheck.c -- menu file syntax checker
#.fi
#.SH DIAGNOSTICS
#	MENU issues very simple error messages when syntax errors are
#encountered in the menu file.  I did this to keep MENU as simple as possible,
#and it is a good idea to run any new menu file through MCHECK before running
#it under MENU.  MCHECK gives complete, self-explanatory error messages on
#syntax errors contained in a menu file.
#
#.SH BUGS
#
#	No known problems exist at this time.  This design is vastly improved
#over the original MENU 1.0, and nesting of shell procedures as well as
#multiple prompted entries on the same line are now supported.
#### menu.c
#/*
# *  MENU -- a menu preprocessor for UNIX
# *		by Richard Conn
# *
# *  MENU allows the user to create menu files, containing screen displays
# *  and command lines which are to be issued in response to single-character
# *  commands presented by the user.  Once a user issues a single-character
# *  command, MENU executes his command line (as a shell procedure) and
# *  then resumes control (in most cases).
# *
# ** enhacements involving piping to a shell, and changing the current
# ** working directory where done by Orest Jarosiewicz
# *
# ** compile with
# ** cc -DSYS3 menu.c -o menu
# **
# ** [odj]
# */
#
##define versmaj	2	/* major version */
##define versmin 0	/* minor version */
#
#/*  Version History
# *	Version 1.0 - Richard Conn
# *	2.0 - Richard Conn
# *		Rather than creating a shell procedure file and then
# *			executing it via an execl, the program was
# *			redesigned to use the system() library function,
# *			which I feel is a much better, cleaner design.
# *			No intermediate command files are created now.
# *			NOTE:  This redesign caused many problems because
# *			of what I believe to be an undocumented bug with
# *			system() -- if an global variables of type int
# *			are declared, calling system() results in an
# *			error message about an invalid instruction exec
# *			and then a core dump.  The program redesign removed
# *			all global variables.
# */
#
##define FALSE	0
##define TRUE	~FALSE
##define HASH	'#'	/* menu separator */
##define GOTO	':'	/* goto command in menu text */
##define WAIT	'!'	/* Wait command in menu text */
##define QUOTE	'\''	/* quote for user input */
##define SUBSHELL '~'	/** invoke command in subshell **/
##define CHGDIR	'='	/** change working directory **/
##define	llimit	23	/* number of lines in screen display */
##define EOB	0x7f	/* end of buffer marker */
##define ESC	0x1b	/* user abort (if allowed) */
##define BEL	'\7'
##define LF	'\n'
##define SCRSIZ	4000	/* size of buffer for screen display */
##define CMDSIZ	8000	/* size of buffer for command lines */
#
##include <stdio.h>
##include <ctype.h>
#
##ifdef SYS3
##include <sgtty.h>
##endif
#
##ifdef JHU
##include </usr/includeJHU/stty.h>  /* at BRL */
##endif
#
#/*  options structure  */
##include <sys/signal.h>
#
#struct opt {
#	int disp;  /* display on/off */
#	int page;  /* page on/off */
#	int exit;  /* exit on/off */
#};
#
#catchit()
#{
#	return;
#	}
#
#main(argc,argv)
#int argc;
#char *argv[];
#{
#	char file[50];				/* menu file name */
#	char inline[400];			/* menu command line */
#	int cmd, ccode;				/* user command, ret code */
#	int Wait, menunum;			/* Wait flag, menu number */
#	struct opt globopts, locopts;		/* global and local options */
#	char screen[SCRSIZ], text[CMDSIZ];	/* screen and text buffers */
#	extern char *getenv();
#	int pid;				/** process id **/
#	FILE *Shell;
#	char *Shelle;
#	char Cmd[ 420 ];			/** Shell points to a pipe
#						 ** to the shell, cmd holds
#						 ** the commands sent to it
#						 ** Shelle points to the
#						 ** environment var SHELL.
#						 ** [odj]
#						 **/
#
#	if (argc==1) { 	/* give user help info if no args */
#		help();
#		exit(-1);
#	}
#
#	/* process options if any */
#	menunum = 1;   /* set to first menu */
#	if (*argv[1]=='-') menunum = atoi(argv[1]+1);  /* extract options */
#	if (!menunum) menunum = 1;  /* set to 1 if error in arg */
#
#	/* extract menu file name */
#	file[0] = '\0';  /* set no file name */
#	if (argc==2 && *argv[1]!='-') strcat(file, argv[1]);
#	else if (argc>2) strcat(file, argv[2]);
#	else {
#		help();
#		exit(-1);
#	}
#
#	/** open pipe to shell [odj] **/
#	Shelle = getenv( "SHELL" );
#	if( Shelle != NULL && Shelle[ 0 ] != '\0' ) strcpy( Cmd, Shelle );
#	else strcpy( Cmd, "sh" );
#	Shell = popen( Cmd, "w" );
#	if( Shell == NULL ){
#		fprintf( stderr,"%s: can't open pipe to %s\n", argv[ 0 ], Cmd);
#		exit( 5 );
#		}
#	pid = getpid();
#
#	/* get menu from file */
#	getmenu(file,menunum,&globopts,&locopts,screen,text);
#
#	/* process menu */
#	while (TRUE) {		/* exit only on ESC from user (if allowed) */
#		if (locopts.disp) prdisp(screen,&locopts);  /* print display */
#		Wait = FALSE;  /* set no Wait */
#		printf("MENU %d.%d Command%s", versmaj, versmin,
#		locopts.exit ? " (ESC to exit)? " : "? ");	/* prompt */
#		cmd = getcmd();		/* get command from user */
#		if (locopts.exit && cmd==ESC) exit(0);		/* exit */
#		ccode = prcmd(cmd,text,inline,&Wait);		/* get cmnd */
#		switch (ccode) {
#		case 0 :	/* command line */
#			/** execute command, the signal will notify
#			 ** the process when the shell is done processing
#			 ** this line
#			 **/
#			sprintf( Cmd, "%s;kill -16 %d", inline, pid );
#			signal( SIGUSR1, catchit );
#			fprintf( Shell, "%s\n", Cmd );
#			fflush( Shell );
#			wait((int *) 0); /** wait for shell to process the line
#					  **/
#			if (Wait) {
#				printf("Strike any key -- ");
#				setraw();
#				getchar();
#				clrraw();
#				printf("\n");
#			}
#			break;
#		case 2 : /** do a plain "system", for things like calling vi **/
#			system( inline );
#			if (Wait) {
#				printf("Strike any key -- ");
#				setraw();
#				getchar();
#				clrraw();
#				printf("\n");
#			}
#			break;
#		case 1 :	/* goto new menu */
#			menunum = atoi (inline);  /* get menu number */
#			if (!menunum) menunum = 1;
#			getmenu(file,menunum,&globopts,&locopts,
#			screen,text);  /* get menu */
#			break;
#		case 3 :	/** change current directory, this has to
#				 ** be done within menu, and within the shell
#				 ** [odj]
#				 **/
#			if( chdir( inline ) != 0 ){
#				fprintf(stderr,"Can't change to directory %s\n",
#					inline);
#				break;
#				}
#			fprintf( Shell, "cd %s\n", inline ); fflush( Shell );
#			break;
#		default :	/* invalid command */
#			putchar(BEL);
#			break;
#		}
#	}
#}
#
#/*  print display if desired and page if desired  */
#prdisp(screen,locops)
#char *screen;
#struct opt *locops;
#{
#	int linecnt;
#
#	linecnt = 0;  /* init line counter */
#	while (*screen != EOB) {
#		putchar(*screen);  /* send char */
#		if (*screen++ == LF) linecnt++;  /* increment line count */
#	}
#	if (locops->page) /* page display */
#		while (linecnt++ < llimit) printf("\n");
#}
#
#/*  get raw command from user  */
#getcmd()
#{
#	int c;
#
#	setraw();			/* set no echo and immed input */
#	c = getchar() & 0x7f;		/* get command and mask out MSB */
#	clrraw();			/* restore normal I/O */
#	if (c > ' ') putchar(c);	/* echo if printing char */
#	printf("\n");			/* new line */
#	return(c);
#}
#
#/*  get and process command from user  */
#prcmd(c,text,line,Wait)
#int c, *Wait;
#char *text, *line;
#{
#	char *scmd(), *cline;
#	register Subshell = 0;
#
#	cline = scmd(c,text);		/* cline pts to command from text */
#	*line = '\0';			/* init command line */
#	if (!(*cline)) return(99);	/* command not found */
#	if (*cline==GOTO) {		/* GOTO command */
#		++cline;		/* pt to first digit */
#		while (isdigit(*cline)) *line++ = *cline++;	/* copy */
#		*line = '\0';		/* set end of string */
#		return(1);		/* goto return code */
#	}
#	if( *cline == CHGDIR ){		/** check if this a directory change**/
#		++cline;
#		docmnd( cline, line );	 /** directive **/
#		return( 3 );
#		}
#	if( *cline == SUBSHELL ){	/** is this a subshell invokation?**/
#		Subshell = 1;	 /** (useful for invoking things like vi)**/
#		++cline;
#		}
#	if (*cline==WAIT) {		/* Wait in command line */
#		*Wait=TRUE;		/* set flag */
#		++cline;		/* pt to first valid cmd line char */
#	}
#	docmnd(cline,line);		/* extract and process command line */
#	return(Subshell ? 2 : 0);	/* command line return code */
#}
#
#/*  scan commands in command buffer for command passed  */
#char *scmd(cmd,text)
#int cmd;
#char *text;
#{
#	while (*text != EOB) {			/* scan thru buffer */
#		if (*text==cmd) return(++text);	/* found command */
#		while (*text++ != LF);		/* skip current line */
#	}
#	return("");				/* null command if not found */
#}
#
#/*  build command line  */
#docmnd(cline,line)
#char *cline, *line;
#{
#	char userin[200];		/* buffer for build and user input */
#
#	while (*cline != LF) {		/* advance over line */
#		switch (*cline) {
#		case QUOTE :
#			++cline;	/* pt to after quote */
#			while (*cline != LF && *cline != QUOTE)
#				putchar(*cline++);	/* print prompt */
#			putchar(' ');	/* print extra space */
#			gets(userin);	/* get input from user */
#			if (*cline == QUOTE) cline++;	/* skip ending quote */
#			break;
#		default :
#			userin[0] = *cline++;	/* set up string */
#			userin[1] = '\0';
#			break;
#		}
#		strcat (line, userin);		/* append user input or char */
#	}
#}
#
#/* extract menu from menu file */
#getmenu(file,menunum,globopts,locopts,screen,text)
#int menunum;
#struct opt *globopts, *locopts;
#char *file, *screen, *text;
#{
#	FILE *fopen(), *fd;
#	int c;
#
#	/* open menu file */
#	fd=fopen(file,"r");
#	if (fd==NULL) {
#		printf("Menu %s NOT Found\n", file);
#		exit(0);
#	}
#
#	/* set global options */
#	globopts->disp = FALSE;
#	globopts->page = FALSE;
#	globopts->exit = FALSE;
#	if ((c=getc(fd)) == '-') setopts(fd,globopts);
#	else ungetc(fd,c);
#
#	/* skip to desired menu */
#	skip(fd,menunum);
#
#	/* set local options */
#	locopts->disp = globopts->disp;
#	locopts->page = globopts->page;
#	locopts->exit = globopts->exit;
#	setopts(fd,locopts);
#
#	/* build buffers */
#	build(fd,screen,SCRSIZ);  /* build screen display */
#	build(fd,text,CMDSIZ);    /* build command buffer */
#
#	/* close menu file */
#	fclose(fd);
#}
#
#/*  set options  */
#setopts(fd,opts)
#FILE *fd;
#struct opt *opts;
#{
#	int c;
#
#	while ((c=getc(fd)) != LF)
#		switch (c) {
#		case 'D' :
#		case 'd' :
#			opts->disp = ~opts->disp;
#			break;
#		case 'P' :
#		case 'p' :
#			opts->page = ~opts->page;
#			break;
#		case 'X' :
#		case 'x' :
#			opts->exit = ~opts->exit;
#			break;
#		case EOF :
#			premature();
#			break;
#		default :
#			break;  /* skip invalid option */
#		}
#}
#
#/*  Skip to desired menu and load buffers  */
#skip(fd,menunum)
#FILE *fd;
#int menunum;
#{
#	int mctr, c;
#
#	/*  skip required number of menus  */
#	if (getc(fd) != HASH) strerror();	/* first char must be a hash */
#	for (mctr=menunum-1; mctr; mctr--) skipmenu(fd);	/* skip menus */
#}
#
#/*  Skip over menu  */
#skipmenu(fd)
#FILE *fd;
#{
#	int c;
#
#	/*  advance over screen display  */
#	while ((c=getc(fd)) != HASH)
#		while (c != LF) {
#			if (c == EOF) strerror();
#			c=getc(fd);
#		}
#
#	/*  advance over commands  */
#	while ((c=getc(fd)) != HASH)
#		while (c != LF) {
#			if (c == EOF) strerror();
#			c=getc(fd);
#		}
#}
#
#/*  Build buffers  */
#build(fd,buff,size)
#FILE *fd;
#char *buff;
#int size;
#{
#	int c;
#
#	while ((c=getc(fd)) != HASH) {		/* loop to end of section */
#		while (c != LF) {		/* loop to end of line */
#			if (c == EOF) premature();
#			*buff++ = c & 0x7f;	/* store char */
#			if (!(--size)) overflow();
#			c = getc(fd);		/* get next char */
#		}
#		*buff++ = c;			/* store LF */
#		if (!(--size)) overflow();
#	}
#	*buff = EOB;				/* set end of buffer marker */
#}
#
#/*  premature EOF exit  */
#premature()
#{
#	printf("Premature End of File Encountered\n");
#	exit(-1);
#}
#
#/*  menu structure error  */
#strerror()
#{
#	printf("Menu Structure Error\n");
#	exit(-1);
#}
#
#/*  Buffer overflow  */
#overflow()
#{
#	printf("Buffer Overflow\n");
#	exit(-1);
#}
#
#/*  Print Help Message  */
#help()
#{
#	printf("Usage:  menu [-n] menufile");
#	printf("\n\twhere 'n' is the menu number to start at\n");
#}
#
#/*  set byte-oriented I/O  */
#setraw()
#{
##ifdef SYS3
#	struct sgttyb ttys;
#
#	if (gtty(0,&ttys) < 0) {		/* get term characteristics */
#		printf("Can't set Byte-Oriented I/O\n");
#		exit(-1);
#	}
#	ttys.sg_flags |= RAW;	/* set RAW */
#	ttys.sg_flags &= ~ECHO;	/* set no echo */
#	if (stty(0,&ttys) < 0) {		/* set term characteristics */
#		printf("Can't set Byte-Oriented I/O\n");
#		exit(-1);
#	}
##endif
##ifdef JHU
#	struct sttybuf ttys;
#
#	if (gtty(0,&ttys) < 0) {		/* get term characteristics */
#		printf("Can't set Byte-Oriented I/O\n");
#		exit(-1);
#	}
#	ttys.sg_mode |= RAW;	/* set RAW */
#	ttys.sg_mode &= ~ECHO;	/* set no echo */
#	if (stty(0,&ttys) < 0) {		/* set term characteristics */
#		printf("Can't set Byte-Oriented I/O\n");
#		exit(-1);
#	}
##endif
#}
#
#/*  restore normal operation for I/O  */
#clrraw()
#{
##ifdef SYS3
#	struct sgttyb ttys;
#
#	if (gtty(0,&ttys) <0) {			/* get term characteristics */
#		printf("Can't restore normal I/O\n");
#		exit(-1);
#	}
#	ttys.sg_flags &= ~RAW;	/* clear RAW */
#	ttys.sg_flags |= ECHO;	/* enable ECHO */
#	if (stty(0,&ttys) < 0) {		/* set term characteristics */
#		printf("Can't restore normal I/O\n");
#		exit(-1);
#	}
##endif
##ifdef JHU
#	struct sttybuf ttys;
#
#	if (gtty(0,&ttys) <0) {			/* get term characteristics */
#		printf("Can't restore normal I/O\n");
#		exit(-1);
#	}
#	ttys.sg_mode &= ~RAW;	/* clear RAW */
#	ttys.sg_mode |= ECHO;	/* enable ECHO */
#	if (stty(0,&ttys) < 0) {		/* set term characteristics */
#		printf("Can't restore normal I/O\n");
#		exit(-1);
#	}
##endif
#}



More information about the Comp.sources.unix mailing list