a new screen locker and saver

S. Charles Chang chang at tiguex.cs.unm.edu
Wed Oct 17 03:11:27 AEST 1990


This is screen locker and saver which was derived from Andrea Malagoli's
screenlock program.  It is provided as is, no warranty, etc.

Post comments, suggestions, or bugs here; or email them directly to
cchang at quasar.ssc.gov.

------- cut here -------
/*
 *  SPOTLIGHT -- a screen saver and locker for SGI machine.
 *
 *  This program is actually a modification and enhancement of 
 *  Andrea Malagoli's LOCKSCREEN, see credits below.
 *
 *  The enhancements are;
 *
 *  1. The bouncing ball has been replaced with a "spotlight" which
 *     cruises around the screen.  Note that the graphics part was
 *     developed on an 8-bitplane system, imposing the following
 *     restrictions:
 *		- doublebuffer not used
 *		- overlay planes not available (used popup planes instead)
 *
 *  2. A timeout feature was added to the password entry.
 *
 *  3. To unlock, 1st press ANY mouse key, then enter your password.
 *
 *  4. The default screen blank feature is temporarily disabled thus
 *     SPOTLIGHT becomes a screen saver.
 *
 *  A nice touch is to first bring up some nice gif or ipaste images
 *  before invoking the SPOTLIGHT.
 *
 *  To compile:
 *              cc -o spotlight spotlight.c -lgl_s -lc_s -lsun -lm
 *
 *  
 *  Graphics: Pat Estep       estep at hoops.ssc.gov
 *     Misc.: Charles Chang   cchang at quasar.ssc.gov
 *
 *            Physics Research Division
 *            Superconducting Super Collider Laboratory
 *            2550 Beckleymeade Ave., MS-1011
 *            Dallas, Texas  75237
 *
 *  Date: October 12, 1990
 *
 *
 * The following still applies to SPOTLIGHT:
 *
 * ====================================================================
 *
 *  WRITTEN BY:  Andrea Malagoli
 *               Astronomy Department
 *               University of Chicago
 *               malagoli at mhd.uchicago.edu
 *
 *  DATE: 15 June 1990
 * 
 *  LAST MODIFIED: 4 October 1990. 
 *
 *				   - Added an open to /dev/console
 *				    to prevent remote users to run
 *                                  lockscreen and seize the screen.
 * 				   - Added possibility for root to
 * 				    unlock the screen, by simply typing
 *  		                    the super-user password in.
 *				    To prevent this, compile with the
 *				    -DNOROOT flag.
 *                                 ( Modifications suggested by 
 *				     Dan Watts of Ki Research, Inc.).
 *
 *  (KNOWN) BUGS: A remote user can still seize the console terminal
 *                by modifing the source code, or by writing a similar
 *                application that does not open /dev/console. I am not
 *		  sure how to go around this.
 *
 */


#include <sys/types.h>
#include <gl.h>
#include <device.h>
#include <pwd.h>
#include <string.h>
#include <fcntl.h>
#include <math.h>

#define RADIUS 150     /* spotlight radius */
#define MAX_DELTA 10   /* max. spotlight movement per frame */
#define pwdtimeout 500000   /* timeout for password entry
			       this is around 26 sec. on a 4D/25 */

static short parray[2*RADIUS+1+2*MAX_DELTA][2*RADIUS+1+2*MAX_DELTA];

int fcons;     /* Console file descriptor */

/* These lines contain the color and the text of the line
 * printed when the bouncing ball is running. You can change
 * both the color and the text here.
 */

Icoord maxxval;            /* width of prompt window ( in screen coords) */
char filename[20];         /* array to store standard input for the prompt */

struct passwd mypwd;       /* User information from /etc/passwd */

static char fprompt[80] = "Enter Password for ";
char *prompt, *prompt1;

int curpos, prevpos;       /* cursor current and previous positions */
int iter=1;


#define XMIN  0
#define XMAX  XMAXSCREEN
#define YMIN  0
#define YMAX  YMAXSCREEN

            /* setup for the prompt box */
Screencoord mask1, mask2, mask3, mask4;  /* full window */

main()
{
        Device dev;
        short val;
        int check_pwd();

	if( (fcons = open("/dev/console", O_RDWR)) == -1 ) 
	{
			printf("Cannot start lockscreen\n");
			exit(1);
	}

        init();

        mypwd = *getpwuid( getuid() ); /* Get User ID and 
					* encrypted password */

        prompt1 = strcat(fprompt,mypwd.pw_name);  /* Set the prompt */
        prompt  = strcat(prompt1,": ");

        /* process events forever */
        while(TRUE) 
	{

            draw_spotlight();

            while( qtest() )
	    {
                dev=qread(&val);
                if(val) 
		{
		    color(3);
		    clear();
		    mktxtport();
		    if(check_pwd(filename) == 1)
		       endit(); 
                }
	    }
        } 
}


endit() 
{
    close( fcons );
    blanktime(60300);
    gexit();
    system("gclear");
    exit(0);
}


init() 
{                               /* do all the basic graphics setup */
    ginit();
    drawmode(PUPDRAW);
    mapcolor(1,0,0,0);
    mapcolor(2,255,255,255);
    mapcolor(3,0,0,255);
    maxxval = 590;                   /* prompt window's width in pixels */
    qdevice(RIGHTMOUSE);
    qdevice(LEFTMOUSE);
    qdevice(MIDDLEMOUSE);
    blanktime(0);
}


/* screen positionings of prompt box */
#define FILEX 340
#define FILEY 500
#define FILEYHI (30+FILEY)        /* 30 pixels hi */
#define TEXTX (FILEX+5)
#define TEXTY (FILEY+10)

/* Clear prompt, move to start of prompt box, and output requested prompt */
clearprompt(prmpt)
char *prmpt;
{ 
    color(2); 
    rectfi(FILEX, FILEY, (Screencoord)(FILEX+maxxval-6), FILEYHI);
    color(1);
    linewidth(2);
    recti(FILEX+2, FILEY+2, FILEX+maxxval-6, FILEYHI-3);
    linewidth(1);
    cmov2i(TEXTX, TEXTY);
    charstr(prmpt); 
}


mktxtport()                             /* get name of file */
{
    int curstrlen;
    short c; 
    int ic;
    char *cc = "a";
    char *str;
    Device dev;
    long maxwidth;
    size_t maxlen = sizeof(filename);
    char *prmpt;

    prmpt = prompt;
    maxwidth = (XMAXSCREEN-11) - (FILEX + strwidth(prmpt));
        
    /* display prompt */
    curstrlen = 0;
    clearprompt(prmpt);

    curpos = TEXTX + strwidth(prmpt) + 2;
    prevpos = curpos;
    draw_bar();

    qdevice(KEYBD);
    ic = 0;
    while ( ic < pwdtimeout )
    {
	if ( !qtest () ) 
	{
	   ic++;
	   continue;
        }
    /* read until carriage return or linefeed */
	ic = 0;
        dev = qread(&c);
        if(dev == KEYBD)
	{
          switch(c) 
	  {
            case '\027':         /* Ctrl-W,U,X and ESC set back */
	    case '\025':         /* to start of password prompt */
	    case '\030':
	    case '\033':
                curstrlen = 0;
                clearprompt(prmpt);
                prevpos = curpos;
                curpos = TEXTX + strwidth(prmpt) + 2;
                draw_bar();
                break;
            case '\n':
            case '\r':
		goto done;
            case '\b':
                if(curstrlen) 
		{
		    *cc = filename[--curstrlen];
                    filename[curstrlen] = '\0';
                    clearprompt(prmpt);
                    /* display rightmost portion */
                    for(str=filename; *str && strwidth(str) > maxwidth; str++);
                    prevpos = curpos;
		    curpos = curpos - strwidth(cc);
		    draw_bar();
                }
                break;
            default:
                if( curstrlen > 20 ) break;
                str = &filename[curstrlen];
                filename[curstrlen++] = c;
                filename[curstrlen] = '\0';
                *cc = c;
                prevpos = curpos;
		curpos = curpos + strwidth(cc);
		draw_bar();
            break;
	  }
	}
    }
done:
    unqdevice(KEYBD);
    color(1);
    clear();
}


int check_pwd(pww)
char *pww;
{
        struct passwd rootpwd;    /* Root information from /etc/passwd */
	char salt[3];

        mypwd = *getpwuid( getuid() ); /* Get User ID and 
					* encrypted password */
	strncpy(salt, mypwd.pw_passwd, 2);
	if( strcmp(mypwd.pw_passwd,crypt(pww,salt)) == 0 )
	{
 			return 1;
#ifdef NOROOT
	} else return 0;
#else NOROOT
        } else  { rootpwd = *getpwnam("root"); /* Get root encrypted
password */
                  strncpy(salt, rootpwd.pw_passwd, 2);
	          if( strcmp(rootpwd.pw_passwd,crypt(pww,salt)) == 0 ) 
		         return 1;  /* We can also enter root password */
		  else return 0;
        }
#endif NOROOT
}



draw_spotlight()
{
  register int i;
  static int x, y;
  static int dx, dy;
  static int num_loops = 0;
  static int max_delta;

  if (num_loops == 0)
  {
    cursoff();
    build_mask();
    color(1);
    clear();
    x = XMAXSCREEN/2;
    y = YMAXSCREEN/2;
  }

  if (!(num_loops%1000))
  {
    dx = rand()/32766.*MAX_DELTA/2 + 1;
    dy = rand()/32766.*MAX_DELTA + 1;
    max_delta = (dx > dy ? dx : dy);
  }

  /*---------------------------*/
  /* Update spotlight position */
  /*---------------------------*/
  x += dx; y += dy;
  if (x + RADIUS >= XMAXSCREEN)
  {
    x = XMAXSCREEN - RADIUS;
    dx = -dx;
  }
  else if (x - RADIUS <= 0)
  {
    x = RADIUS;
    dx = -dx;
  }
  if (y + RADIUS >= YMAXSCREEN)
  {
    y = YMAXSCREEN - RADIUS;
    dy = -dy;
  }
  else if (y - RADIUS <= 0)
  {
    y = RADIUS;
    dy = -dy;
  }

  /*----------------*/
  /* Draw spotlight */
  /*----------------*/
  rectwrite(x-RADIUS-MAX_DELTA, y-RADIUS-MAX_DELTA,
    x+RADIUS+MAX_DELTA, y+RADIUS+MAX_DELTA, parray);
  num_loops++;
}

build_mask()
{
  int x, y;

  color(1);
  clear();
  x = XMAXSCREEN/2; y = YMAXSCREEN/2;
  color(0);
  circfi(x, y, RADIUS);
  rectread(x-RADIUS-MAX_DELTA, y-RADIUS-MAX_DELTA,
    x+RADIUS+MAX_DELTA, y+RADIUS+MAX_DELTA, parray);
}


draw_bar()
{
	static int ydown = (FILEY + 5);
	static int yup   = (FILEYHI - 7);
	int vert[2];

        linewidth(1);
	if( prevpos != curpos )
	{
		color(2);
		
		bgnline();
		vert[0] = prevpos; vert[1] = ydown;
		v2i(vert);
		vert[0] = prevpos; vert[1] = yup;
		v2i(vert);
		endline();

		color(1);
		
		bgnline();
		vert[0] = curpos; vert[1] = ydown;
		v2i(vert);
		vert[0] = curpos; vert[1] = yup;
		v2i(vert);
		endline();
	} 
	else 
	{
		color(1);
		
		bgnline();
		vert[0] = curpos; vert[1] = ydown;
		v2i(vert);
		vert[0] = curpos; vert[1] = yup;
		v2i(vert);
		endline();
	}
}



More information about the Comp.sys.sgi mailing list