[net.bugs.4bsd] enhancements to script

nz@wucs.UUCP (Neal Ziring) (04/06/85)

Description:

        The script(1) command is a very convenient utility that
        takes a log of the i/o to a terminal.  It is incredibly
        useful in an academic environment.  Unfortunately,
        script was written to be a quick-and-dirty logger, and
        has no nice bells and whistles (like VMS PHOTO or PHOTO
        on TOPS20 or rlogin(1) on BSD Unix).

        The diffs below are enhancements to script, giving it
        a set of tilde escapes, similar to those supported
        by rlogin(1) and Mail(1).

Repeat-by:

        Just go into your favorite editor while in script, and
        then look at the log file.  Also, try suspending the
        shell script runs for you, then look at a `ps -cx'
        and see what processes are running and which are stopped.

Fix:
        Script runs three processed to accomplish its job:
        
                - master, uses one pty
                - slave, uses another pty
                - shell, runs the SHELL for you

        The changes below are primarily changes to the routines
        used by the master, and a few changes to the slave.

        The following is a rcs diff of the original script.c
        versus the results of my hacking.  If you apply patch(n)
        to it, you too will be able to enjoy these enhancements.
        Also, the ~. escape is a sure cure for hung script processes.


15a16,18
> #define BUFFERSIZE 64
> #define ESCCHAR '~'
> 
24c27,39
< int	finish();
---
> int	finish(), toggle();
> char	logging;
> char	cmdchar = ESCCHAR ;
> char	*help[] =  {
> 	"-----------",
> 	"Tilde escapes are:",
> 	"~.	terminate this script session",
> 	"~^Z	suspend this script session",
> 	"~l	turn data logging on/off",
> 	"~?	get this message",
> 	"~~	a single tilde",
> 	"-----------",
> 	NULL };
33a49,50
> int	masterpid, slavepid, shellpid;	/* process ids of parts of script */
> 
68a86,87
>         masterpid = getpid();
> 	logging = 1;
80c99,101
< 		if (f)
---
> 		else shellpid = f;
> 		if (f) {
> 			(void) signal(SIGHUP, toggle);
82c103,104
< 		else
---
> 		}
> 		else 
84a107
>         slavepid = child;
90c113,115
< 	char ibuf[BUFSIZ];
---
> 	int  escstart1, escstart2, esccont, linestart;
> 	char cur;
> 	char readchar();
94,95c119,190
< 	while ((cc = read(0, ibuf, BUFSIZ)) > 0)
< 		(void) write(master, ibuf, cc);
---
> 	for(escstart1=escstart2=esccont=0;
> 	    (cur = readchar()) != EOF; ) {
> 	    if (cur == '\n' || cur == '\015') {
> 		escstart1++;  
> 		if (escstart2) write(master, &cmdchar, 1);
> 		if (esccont) esccont = 0;
> 		escstart2 = 0;
>             }
>             else if (cur == cmdchar && escstart1) {
> 		write(1,&cur,1);
> 		escstart2++; escstart1 = 0;
> 		continue;
> 	    }
> 	    else if (escstart2) {
> 		int i;
> 		esccont++;
> 		escstart2 = 0;
> 		switch (cur & 0177) {
> 		    case '.': 
> 		    case '\04' :
> 			write(1,".\015\n",3);
> 			fflush(fscript);
> 			fclose(fscript);
> 			fail();		
> 		        break;
> 		    case 'a':
> 		    case 'l':
> 			toggle();
> 			kill(slavepid,SIGHUP);
> 			write(1,&cur,1);
> 			break;
> 		    case ESCCHAR:
> 			write(master,&cur,1);
> 			escstart1=escstart2=esccont=0;
> 			break;	
> 		    case '?':
> 			write(1,&cur,1);
> 			for(i=0; help[i] != NULL; i++) {
> 				write(1,"\015\n",2);
> 				write(1,help[i],strlen(help[i]));
> 			}
> 			write(1,"\015\n",2);
> 			write(1,"\nLogging is ",12);
> 			write(1,( (logging)?("on \n"):("off\n") ),4);
> 			write(1,"\015\n",2);
> 			write(master,"\n",1);
> 			escstart1 = 1;
> 			escstart2=esccont=0;
> 		 	break;
> 		    case '\032':
> 			write(1,"^Z\015\n",4);
> 			ioctl(0, TIOCSETP, (char *)&b);
> 			stopall();
> 			fixtty();
> 			escstart1=escstart2=esccont=0;
> 			break;
> 		    default:
> 			write(master,&cmdchar,1);
> 			write(master,&cur,1);
> 			escstart1=escstart2=esccont=0;
> 			break;
> 		}
> 		continue;
> 	    }
> 	    else if (esccont) {
> 		write(1,&cur,1);
> 		continue;
> 	    }
> 	    else escstart1 = 0;
> 
>             (void) write(master, &cur, 1);
>         }
98a194,207
> char readchar()
> {
> 	static char buf[BUFSIZ];
> 	static int nextchar = 0;
> 	static int charcnt  = 0;
> 	if (nextchar >=	charcnt) {
> 		if ( (charcnt = read(0, buf, BUFSIZ)) < 0) return (EOF);
> 		nextchar = 0;
> 	}
> 	return ( buf[nextchar++] );
> }
> 
> 
> 
113c222
< 	char obuf[BUFSIZ];
---
> 	char obuf[BUFFERSIZE];
124c233,234
< 		(void) fwrite(obuf, 1, cc, fscript);
---
> 		if (logging) 
> 		    (void)  fwrite(obuf, 1, cc, fscript);
221a332,343
> 
> toggle()
> {
> 	logging = (logging) ? 0 : 1 ;
> }
> 
> stopall()
> {
> 	kill(0, SIGTSTP);	/* stop pg, I don't know if this will work. */
> 	kill(0, SIGCONT);
> }
> 
-- 
========
...nz (ECL - we're here to provide superior computing)
	Washington University Engineering Computer Laboratory

	old style:	... ihnp4!wucs!nz
	new style:	nz@wucs.UUCP