chang@tiguex.cs.unm.edu (S. Charles Chang) (10/17/90)
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@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@hoops.ssc.gov * Misc.: Charles Chang cchang@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@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(); } }