From: biff@biff.uucp (Dwight Everhart)
Newsgroups: comp.sys.next.misc
Subject: Re: ScreenBlanker during "login" console
Date: Sun, 30 Aug 1992 02:09:04 GMT

In article <BtntLL.LB1@mentor.cc.purdue.edu> jbradsha@mentor.cc.purdue.edu  
(Jonathan Bradshaw) writes:
> Is there a way to put a screen blanker on the console login window?

I believe there are screen blankers that will do that.  If you just want  
something to blank the screen rather than flying toasters across it, then  
perhaps the one I wrote will do.  It sets the brightness level of the screen  
to 0 after a certain amount of inactivity (specified on the command line) has  
occurred.  It will work whether someone is logged in or not.  It should be  
run from /etc/rc.local.  Example:

    /usr/local/etc/blankit 5

This will cause the screen to be blanked after five minutes of inactivity,  
whether or not someone is logged in.  Note the absence of an ampersand.   
Blankit puts itself in the background.

I've used blankit for a year and only encountered a couple of bugs in the  
beginning (which I corrected).  It's worked fine since then.  Enjoy.

--------------------------------Hack Here-----------------------------------

#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
#	blankit
# This archive created: Sat Aug 29 20:51:34 1992
export PATH; PATH=/bin:$PATH
if test ! -d 'blankit'
then
	mkdir 'blankit'
fi
cd 'blankit'
if test -f 'blankit.c'
then
	echo shar: will not over-write existing file "'blankit.c'"
else
cat << \SHAR_EOF > 'blankit.c'
/*
  blankit.c:  A daemon for NeXT computers that automatically blanks
  the screen after argv[1] minutes

  Author:  Dwight Everhart (biff@biff.uucp), although originally based
  on dim.c by John W. Garnett (garnett@cs.utexas.edu).

  Version:  1.0 (8/29/92)

  Usage:  blankit <dim time in minutes> (No ampersand (&) is needed.
  Blankit will put itself in the background.)

  Bugs:  Blankit will blank the screen according the the parameter
  given when it was started and not according to the preferences of
  any user that may be logged in.  If this user has his blanking
  interval set longer than blankit's, the screen will blank earlier
  than he specified.  If his interval is shorter than blankit's, then
  the screen will dim normally at the time he specified and later will
  blank when blankit's interval is reached.
  
  Distribution:  Blankit is in the public domain and is provided AS
  IS.  No warranties are expressed or implied.  Do with it what you
  will.  Copy it freely.

*/

#include <stdio.h>
#include <stdlib.h>
#include <sys/fcntl.h>
#include <sys/ioctl.h>
#include <nextdev/evsio.h>
#include "daemon.h"

#define EVS_DEVICE "/dev/evs0"

/* When the screen is blanked, this is how often we will check for */
/* activity, in seconds.                                           */
#define ACTIVITY_CHECK  2



/* open the event status device (see man page for evs) */

int open_evs()
{
   int evs;

   evs = open (EVS_DEVICE, O_RDWR, 0660);
   if (evs < 0) {
      fprintf (stderr, "error: couldn't open %s\n", EVS_DEVICE);
      exit (EXIT_FAILURE);
   };
   return (evs);
};



main (int argc, char *argv[]) {
   int blank_time, evs, cadt, ladt, idle_count = 0;
   int old_brightness, zero_brightness = 0;

   if (argc != 2) {
      fputs ("Usage:  blankit <dim time in minutes>\n", stderr);
      exit (EXIT_FAILURE);
   };

   blank_time = strtol (argv[1], 0, 10);
   if ((blank_time < 1) || (blank_time > 60)) {
      fputs ("The blank time should be between 1 and 60 minutes\n", stderr);
      exit (EXIT_FAILURE);
   };

   daemon_start (1);

   evs = open_evs();
   ioctl (evs, EVSIOGADT, &cadt);

   while (1) {
      ladt = cadt;
      sleep (60);
      ioctl (evs, EVSIOGADT, &cadt);
      if (cadt == ladt) {
	 ++idle_count;
	 if (idle_count == blank_time) {
	    ioctl (evs, EVSIOCB, &old_brightness);
	    ioctl (evs, EVSIOSB, &zero_brightness);
	    while (cadt == ladt) {
	       sleep (ACTIVITY_CHECK);
	       ioctl (evs, EVSIOGADT, &cadt);
	    };
	    ioctl (evs, EVSIOSB, &old_brightness);
	    idle_count = 0;
	 };
      }
      else /* There was activity -- reset the idle count */
	 idle_count = 0;
   };

   close (evs);
};

SHAR_EOF
fi # end of overwriting check
if test -f 'daemon.c'
then
	echo shar: will not over-write existing file "'daemon.c'"
else
cat << \SHAR_EOF > 'daemon.c'
/*
 * daemon.c:  Typed in fairly faithfully from _UNIX Network Programming_,
 * by W. Richard Stevens (Prentice Hall), p. 82-85.
 */


/* Initialize a daemon process. */

#include "daemon.h"
#include <stdio.h>
#include <signal.h>
#include <sys/param.h>
#include <errno.h>

extern int errno;

#ifdef SIGTSTP          /* True if BSD system */
#include <sys/file.h>
#include <sys/ioctl.h>
#include <sys/wait.h>
#endif



#ifdef SIGTSTP

/*
 * This is a 4.3BSD SIGCLD signal handler that can be used by a
 * server that's not interested in its child's exit status, but needs to
 * wait for them, to avoid cloging up the system with zombies.
 *
 * Beware that the calling process may get an interrupted system call
 * when we return, so they had better handle that.
 */

void sig_child()
{
   int pid;
   union wait status;

   /* Use the wait3() system call with the WNOHANG option. */
   while ((pid = wait3 (&status, WNOHANG, (struct rusage *)0)) > 0);
};

#endif



/* Detach a daemon process from login session context. */

void daemon_start (int ignsigcld)
                /* nonzero -> handle SIGCLDs so zombies don't clog */
{
   register int childpid, fd;

   /*
    * If we were started by init (process 1) from the /etc/inittab file
    * there's no need to detach.
    * This test is unreliable due to an unavoidable ambiguity
    * if the process is started by some other process and orphaned
    * (i.e., if the parent process terminates before we are started).
    */

   if (getppid() == 1) goto out;

   /* Ignore the terminal stop signals (BSD). */

#ifdef SIGTTOU
   signal (SIGTTOU, SIG_IGN);
#endif
#ifdef SIGTTIN
   signal (SIGTTIN, SIG_IGN);
#endif
#ifdef SIGTSTP
   signal (SIGTSTP, SIG_IGN);
#endif

   /*
    * If we were not started in the background, fork and
    * let the parent exit.  This also guarentees the first child
    * is not a process group leader.
    */

   if ((childpid = fork()) < 0)
      perror ("can't fork first child");
   else if (childpid > 0)
      exit (0);     /* parent */

   /*
    * First child process.
    *
    * Disassociate from controlling terminal and proces group.
    * Ensure the process can't reacquire a new controlling terminal.
    */

#ifdef SIGTSTP     /* BSD */

   if (setpgrp (0, getpid()) == -1)
      perror ("can't change process group");

   if ((fd = open ("/dev/tty", O_RDWR)) >= 0) {
      ioctl (fd, TIOCNOTTY, (char *)NULL);   /* lose controlling tty */
      close (fd);
   };

#else     /* System V */

   if (setpgrp() == -1)
      perror ("can't change process group");

   signal (SIGHUP, SIG_IGN);   /* immune from pgrp leader death */

   if ((childpid = fork()) < 0)
      perror ("can't fork second child");
   else if (childpid > 0)
      exit (0);   /* first child */

   /* second child */

#endif

out:

   /* Close any open file descriptors. */

   for (fd = 0; fd < NOFILE; fd++) close (fd);

   errno = 0;   /* probably got set to EBADF from a close */

   /*
    * Move the current directory to root, to make sure we
    * aren't on a mounted filesystem.
    */

   chdir ("/");

   /* Clear any inherited file mode creation mask. */

   umask (0);

   /*
    * See if the caller isn't interested in the exit status of its
    * children, and doesn't want to have them become zombies and
    * clog up the system.
    *
    * With System V all we need do is ignore the signal.
    * With BSD, however, we have to catch each signal
    * and execute the wait3() system call.
    */

   if (ignsigcld) {
#ifdef SIGTSTP
      signal (SIGCLD, sig_child);   /* BSD */
#else
      signal (SIGCLD, SIG_IGN);     /* System V */
#endif
   };
};

SHAR_EOF
fi # end of overwriting check
if test -f 'daemon.h'
then
	echo shar: will not over-write existing file "'daemon.h'"
else
cat << \SHAR_EOF > 'daemon.h'
/* daemon.h */

void daemon_start (int ignsigcld);
/*
  Detach a daemon process from login session context.
  ignsigcld:  nonzero -> handle SIGCLDs so zombies don't clog.
*/

SHAR_EOF
fi # end of overwriting check
if test -f 'Makefile'
then
	echo shar: will not over-write existing file "'Makefile'"
else
cat << \SHAR_EOF > 'Makefile'
# Makefile for blankit

CFLAGS = -O
LDFLAGS = -object -s

blankit: blankit.o daemon.o
	cc $(LDFLAGS) -o blankit blankit.o daemon.o

blankit.c: daemon.h

SHAR_EOF
fi # end of overwriting check
cd ..
#	End of shell archive
exit 0

--
Dwight Everhart
biff@biff.uucp
Newsgroups: comp.sys.next.misc