[net.sources] SUN screensaver source

clyde@ut-ngp.UTEXAS (Clyde W. Hoover) (10/15/85)

Here is a package to make a screensaver version 
of /etc/getty that I made to keep our SUN workstation screens from
burning out. 

Share and Enjoy
-Clyde Hoover

#	This is a shell archive.
#	Remove everything above and including the cut line.
#	Then run the rest of the file through sh.
-----cut here-----cut here-----cut here-----cut here-----
#!/bin/sh
# shar:	Shell Archiver
#	Run the following text with /bin/sh to create:
#	README		The explination
#	getty.diffs	Diffs for /usr/src/etc/getty/...
#	gettytab	Example /etc/gettytab entries
#	holdscreen.1	Man page for screen holder program
#	holdscreen.c	Source for screen holder program
# This archive created: Mon Oct 14 21:34:45 1985
cat << \SHAR_EOF > README

This is the kit to create a screensaver version of /etc/getty so your
SUN workstation screen don't fry.  The screensaver is composed
of two parts:

	Mods to /etc/getty to specify a 'greeting program' to be executed
	before any prompts are issued.  An example /etc/gettytab entry
	is included.

	A screenholder program that runs the acutal screensaver program
	until interrupted by keyboard input.  A simple manual page
	is included.

While this was done for a SUN workstation, it is trivially portable to
any 4.2BSD-based U-Know-What* and should be easily portable (at least
holdscreen) to most U-Know-What systems.

* Not a trademark of anybody I know of (yet). 
SHAR_EOF
cat << \SHAR_EOF > getty.diffs

Apply these diffs to your VAX source for /etc/getty to get the
screensaver version for the SUN

*** gettytab.h	Mon Oct 14 21:11:52 1985
--- ../gettytab.h	Wed Jul 24 11:28:49 1985
***************
*** 
  #define DS	gettystrs[19].value
  #define RP	gettystrs[20].value
  #define FL	gettystrs[21].value
  #define WE	gettystrs[22].value
  #define LN	gettystrs[23].value
  
--- 
  #define DS	gettystrs[19].value
  #define RP	gettystrs[20].value
  #define FL	gettystrs[21].value
  #define WE	gettystrs[22].value
  #define LN	gettystrs[23].value
+ #define GP	gettystrs[24].value

*** init.c	Mon Oct 14 21:11:53 1985
--- ../init.c	Wed Jul 24 11:28:49 1985
***************
*** 38
  	{ "ds", &ltc.t_dsuspc },	/* delayed suspend */
  	{ "rp", &ltc.t_rprntc },	/* reprint char */
  	{ "fl", &ltc.t_flushc },	/* flush output */
  	{ "we", &ltc.t_werasc },	/* word erase */
  	{ "ln", &ltc.t_lnextc },	/* literal next */
  	{ 0 }
  };
  
--- 38
  	{ "ds", &ltc.t_dsuspc },	/* delayed suspend */
  	{ "rp", &ltc.t_rprntc },	/* reprint char */
  	{ "fl", &ltc.t_flushc },	/* flush output */
  	{ "we", &ltc.t_werasc },	/* word erase */
  	{ "ln", &ltc.t_lnextc },	/* literal next */
+ 	{ "gp" },			/* greeting program */
  	{ 0 }
  };
  

*** main.c	Mon Oct 14 21:11:55 1985
--- ../main.c	Mon Oct 14 21:07:13 1985
***************
*** 90,99
  main(argc, argv)
  	char *argv[];
  {
  	char *tname;
  	long allflags;
  
  	signal(SIGINT, SIG_IGN);
  /*
  	signal(SIGQUIT, SIG_DFL);
  */

--- 90,100 -----
  main(argc, argv)
  	char *argv[];
  {
  	char *tname;
  	long allflags;
+ 	int	gprun = 0;
  
  	signal(SIGINT, SIG_IGN);
  /*
  	signal(SIGQUIT, SIG_DFL);
  */
***************
*** 133
  			continue;
  		}
  		if (CL && *CL)
  			putpad(CL);
  		edithost(HE);
  		if (IM && *IM)
  			putf(IM);

--- 134
  			continue;
  		}
  		if (CL && *CL)
  			putpad(CL);
  		edithost(HE);
+ 		if (GP && *GP && gprun == 0) {
+ 			rung(GP);
+ 			gprun++;
+ 		}
  		if (IM && *IM)
  			putf(IM);

*** subr.c	Mon Oct 14 21:11:57 1985
--- ../subr.c	Wed Jul 24 11:28:50 1985
***************
*** 355,364
  			*ep++ = p;
  	}
  	*ep = (char *)0;
  }
  
  # ifdef	DEVELCON
  /*
   * This speed select mechanism is written for the Develcon DATASWITCH.
   * The Develcon sends a string of the form "B{speed}\n" at a predefined
   * baud rate. This string indicates the user's actual speed.

--- 355,381 -----
  			*ep++ = p;
  	}
  	*ep = (char *)0;
  }
  
+ rung(prog)
+ char	*prog;
+ {
+ 	register int	child,
+ 			waitpid;
+ 
+ 	if ((child = vfork()) == 0) {
+ 		setuid(1);	/* Don't run greeter as SU */
+ 		execl("/bin/sh","sh","-c", prog, (char *)0);
+ /*		execl(prog, prog, (char *)0); */ /* Is an alternative */
+ 		_exit(0);
+ 	}
+ 	if (child < 0)
+ 		return;
+ 	while ((waitpid = wait(0)) != child && waitpid != -1);
+ }
+ 
  # ifdef	DEVELCON
  /*
   * This speed select mechanism is written for the Develcon DATASWITCH.
   * The Develcon sends a string of the form "B{speed}\n" at a predefined
   * baud rate. This string indicates the user's actual speed.

SHAR_EOF
#
# An example from a workstation /etc/gettytab showing how the
# screensaver feature is specified
#
cat << \SHAR_EOF > gettytab
2|std.9600|9600-baud:\
	:sp#9600:
C|SUN console:\
	:gp=/usr/local/holdscreen /usr/demo/stringart:to#60:tc=std.9600:
#
# I use 'stringart' for my screensaver.  Any program you wish can
# be substituted here.  FULL PATH NAMES MUST BE USED for the 'gp'
# entry.
#
SHAR_EOF
cat << \SHAR_EOF > holdscreen.1
.TH HOLDSCREEN 1 LOCAL
.SH NAME
holdscreen \- screen locker
.SH SYNOPSIS
.B holdscreen command
.SH DESCRIPTION
.I Holdscreen
executes its arguments as a child process
and waits until standard input is ready
to read.
.I Holdscreen
then kills the screen holder process, clears the screen and exits.
This is usually done by pressing a key on the terminal keyboard.
Since
.I holdscreen
runs in RAW mode, any key may be pressed.
.SH BUGS
.I Holdscreen
was developed for use on SUN workstation displays, so the screen clear
sequence is coded in.  For more general usage,
.IR termcap (5)
should be used.
.SH AUTHOR
Clyde Hoover @ Computation Center, The University of Texas at Austin
.br
clyde@ngp.UTEXAS.EDU, !seismo!ut-ngp!clyde
SHAR_EOF
cat << \SHAR_EOF > holdscreen.c
/*
 *	holdscreen - run arbitrary screen saver.
 *
 *	Holdscreen runs the rest of its arguments as a subprocess, and
 *	waits for keyboard activity.  On the SUN console, mouse activity
 *	is also waited for.  When a key is pressed, the subprocesses
 *	are killed and the screen cleared.
 *
 *	Written by Clyde Hoover, UTexas Computation Center, July 1985
 *
 *	Usage: holdscreen program program-args
 *
 *	Compliation:	cc -o holdscreen -O holdscreen.c
 *	Libraries:	std
 *	Binary:		/usr/local/holdscreen
 *	Mode:		0555
 *	Ownership:	?/?
 */

#include <stdio.h>
#include <signal.h>
#include <setjmp.h>
#include <sgtty.h>

char	*clear = "\014";	/* SUN console screen clear */
jmp_buf	ping;			/* Longjmp buffer */
struct sgttyb	oldmodes;	/* TTY mode buf */

/*
 *	holdscreen - screen saver exec
 */
main(argc,argv)
int	argc;
char	**argv;
{
	int	pgrp;		/* Subprocess process group */

	setbuf(stderr, (char *)NULL);	/* No error message buffering */
	pgrp = execargs (argc,argv);	/* Exec screen saver */
	waitforevent ();		/* Wait for human interaction */
	killoff (pgrp);			/* Kill off children */
					/* init (pid 1) will inherit them */
	cleanup ();			/* Reset TTY modes */
	(void) write (1, clear, 1);	/* Clear screen */
	exit (0);
}

/*
 *	catchsig - catch signals
 */
catchsig(sig)
int	sig;		/* Signal that got us here */
{
	(void) signal(sig, SIG_IGN);
	longjmp(ping,1);
}

/*
 *	cleanup - tidy up
 */
cleanup()
{
	(void) ioctl (0, TIOCSETP, &oldmodes);
}

/*
 *	execargs - fork off command line
 *
 *	Returns: process group number of the subprocess tree
 */
execargs(c,v)
int	c;
char	**v;
{
	int	pid;		/* process id */

	c--;
	v++;
	if (c <= 0)		/* No args */
		exit (0);
	pid = fork ();
	if (pid < 0)
		exit (1);
	if (pid == 0) {
		(void) setpgrp (0, getpid());
		(void) close (0);		/* Redirect stdin */
		(void) open ("/dev/null",0);
		(void) execv (v[0], v, 0);
		_exit (0);
	}
	return (pid);
}


/*
 *	killoff - kill subprocess tree.
 */
killoff (pg)
int	pg;		/* Subprocess process group */
{
	if (vfork () == 0) {
		if (setpgrp(0, pg) < 0)		/* Put self in childs pgrp */
			perror("\r\nsetpgrp");
		if (kill (0, SIGKILL) < 0)	/* Shoot us all in head */
			perror ("\r\nkillpg");
		_exit (0);
	}
	(void) wait(0);
}

/*
 *	waitforevent - wait for human-genereated event (hitting a key or
 *		or mouse button)
 */
waitforevent()
{
	int	(*catchsig)();	/* SIGCHLD catcher */
	int	imask;		/* Select mask */
	struct sgttyb	sx;	/* TTY RAW mode */
	int x;

	/*
	 * Set RAW if needed. Do this because I want select
	 * to return if any key on the keyboard is pressed, and
	 * I don't want to catch tty signals.
	 */
	(void) ioctl(0, TIOCGETP, &sx);
	oldmodes = sx;
	if ((sx.sg_flags & RAW) == 0) {
		sx.sg_flags |= RAW;		/* RAW on */
		sx.sg_flags &= ~ECHO;		/* ECHO off */
		(void) ioctl(0, TIOCSETP, &sx);
	}

	/*
	 * Arrange for SIGCHLD to be caught
	 */
	(void) signal(SIGCHLD, catchsig);
	if (x = setjmp(ping))
		goto restore;

	/*
	 * If on SUN console, turn mouse on (N/A)
	 *
	 *if (strcmp(ttyname(0),"/dev/console") == 0)
	 *	enable_mouse();
	 */

	/*
	 * Wait for stdin to become readable (tty input).
	 * This won't work quite the same with the mouse enabled.
	 */
	(void) ioctl (0, TIOCFLUSH, 0);
	imask = 1;
	(void) select(20,&imask,(int *)0,(int *)0,(struct timeval *)0);

restore:
	(void) signal(SIGCHLD, SIG_DFL);
}
SHAR_EOF
#	End of shell archive
exit 0
-- 
Shouter-To-Dead-Parrots @ Univ. of Texas Computation Center; Austin, Texas  

"All life is a blur of Republicans and meat." -Zippy the Pinhead

	clyde@ngp.UTEXAS.EDU, clyde@sally.UTEXAS.EDU
	...!ihnp4!ut-ngp!clyde, ...!allegra!ut-ngp!clyde