Removed warning about zrefresh.
git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@281 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
@@ -1,985 +0,0 @@
|
||||
/*
|
||||
* xnlock -- Dan Heller, 1990
|
||||
* "nlock" is a "new lockscreen" type program... something that prevents
|
||||
* screen burnout by making most of it "black" while providing something
|
||||
* of interest to be displayed in case anyone is watching.
|
||||
* "xnlock" is the X11 version of the program.
|
||||
* Original sunview version written by Dan Heller 1985 (not included here).
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#include <protos.h>
|
||||
#define KERBEROS
|
||||
RCSID("$Id$");
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <signal.h>
|
||||
#include <X11/StringDefs.h>
|
||||
#include <X11/Intrinsic.h>
|
||||
#include <X11/keysym.h>
|
||||
#include <X11/Shell.h>
|
||||
#include <X11/Xos.h>
|
||||
#include <ctype.h>
|
||||
#include <pwd.h>
|
||||
#include <xnlock.h>
|
||||
|
||||
#ifdef KERBEROS
|
||||
#include <krb.h>
|
||||
#include <kafs.h>
|
||||
|
||||
char inst[100];
|
||||
char name[100];
|
||||
char realm[REALM_SZ + 1];
|
||||
#endif
|
||||
|
||||
char *SPACE_STRING = " ";
|
||||
char STRING[] = "****************";
|
||||
#define MAX_PASSWD_LENGTH (sizeof(STRING))
|
||||
|
||||
/* The program should be something that outputs a small amount of text */
|
||||
#define DEFAULT_PROGRAM "fortune -s"
|
||||
#define DEFAULT_TEXT "I'm out running around."
|
||||
#define font_height(font) (font->ascent + font->descent)
|
||||
#define FONT_NAME "-*-new century schoolbook-*-*-*-18-*"
|
||||
#define when break;case
|
||||
#define otherwise break;default
|
||||
|
||||
#define PROMPT "Password: "
|
||||
#define FAIL_MSG "Sorry, try again"
|
||||
#define LEFT 001
|
||||
#define RIGHT 002
|
||||
#define DOWN 004
|
||||
#define UP 010
|
||||
#define FRONT 020
|
||||
#define X_INCR 3
|
||||
#define Y_INCR 2
|
||||
#define CTRL 1
|
||||
#define NOCTRL 0
|
||||
|
||||
XtAppContext app;
|
||||
Display *dpy;
|
||||
unsigned short Width, Height;
|
||||
Widget widget;
|
||||
GC gc;
|
||||
XtIntervalId timeout_id;
|
||||
char *ProgName, *words;
|
||||
int x, y;
|
||||
Pixel Black, White;
|
||||
XFontStruct *font;
|
||||
struct passwd *pw;
|
||||
char root_pw[16];
|
||||
char *def_words = DEFAULT_TEXT;
|
||||
int time_left, prompt_x, prompt_y, time_x, time_y;
|
||||
unsigned long interval;
|
||||
Pixmap left0, left1, right0, right1, left_front,
|
||||
right_front, front, down;
|
||||
int test;
|
||||
|
||||
#define MAXLINES 40
|
||||
|
||||
#define FROM_ARGV 1
|
||||
#define FROM_PROGRAM 2
|
||||
#define FROM_FILE 3
|
||||
#define FROM_RESRC 4
|
||||
int getwordsfrom = FROM_RESRC;
|
||||
|
||||
#define IS_MOVING 1
|
||||
#define GET_PASSWD 2
|
||||
int state; /* indicates states: walking or getting passwd */
|
||||
|
||||
int ALLOW_LOGOUT = (60*10); /* Allow logout after nn seconds */
|
||||
char LOGOUT_PASSWD[] = "LOGOUT"; /* when given password "xx" */
|
||||
time_t locked_at;
|
||||
|
||||
struct _resrcs {
|
||||
Pixel fg, bg;
|
||||
XFontStruct *font;
|
||||
Boolean ignore_passwd;
|
||||
Boolean do_reverse;
|
||||
Boolean accept_root;
|
||||
char *text, *text_prog, *file;
|
||||
} Resrcs;
|
||||
|
||||
static XtResource resources[] = {
|
||||
{ XtNfont, XtCFont, XtRFontStruct, sizeof (XFontStruct *),
|
||||
XtOffsetOf(struct _resrcs,font), XtRImmediate, NULL },
|
||||
{ XtNforeground, XtCForeground, XtRPixel, sizeof (Pixel),
|
||||
/* note: the background is really the foreground color */
|
||||
XtOffsetOf(struct _resrcs,fg), XtRString, XtDefaultBackground },
|
||||
{ XtNbackground, XtCBackground, XtRPixel, sizeof (Pixel),
|
||||
/* note: the foreground is really the background color */
|
||||
XtOffsetOf(struct _resrcs,bg), XtRString, XtDefaultForeground },
|
||||
{ XtNreverseVideo, XtCReverseVideo, XtRBoolean, sizeof(Boolean),
|
||||
XtOffsetOf(struct _resrcs,do_reverse), XtRImmediate, (char *)False },
|
||||
{ "ignorePasswd", "IgnorePasswd", XtRBoolean, sizeof(Boolean),
|
||||
XtOffsetOf(struct _resrcs,ignore_passwd), XtRImmediate, (char *)False },
|
||||
{ "acceptRootPasswd", "AcceptRootPasswd", XtRBoolean, sizeof(Boolean),
|
||||
XtOffsetOf(struct _resrcs,accept_root), XtRImmediate, (char *)True },
|
||||
{ "text", "Text", XtRString, sizeof(char *),
|
||||
XtOffsetOf(struct _resrcs,text), XtRImmediate, DEFAULT_TEXT },
|
||||
{ "program", "Program", XtRString, sizeof(char *),
|
||||
XtOffsetOf(struct _resrcs,text_prog), XtRImmediate, DEFAULT_PROGRAM },
|
||||
{ "file", "File", XtRString, sizeof(char *),
|
||||
XtOffsetOf(struct _resrcs,file), XtRImmediate, NULL },
|
||||
};
|
||||
|
||||
static XrmOptionDescRec options[] = {
|
||||
{ "-fn", "font", XrmoptionSepArg, NULL },
|
||||
{ "-fg", "foreground", XrmoptionSepArg, NULL },
|
||||
{ "-bg", "background", XrmoptionSepArg, NULL },
|
||||
{ "-rv", "reverseVideo", XrmoptionNoArg, "True" },
|
||||
{ "-norv", "reverseVideo", XrmoptionNoArg, "False" },
|
||||
{ "-ip", "ignorePasswd", XrmoptionNoArg, "True" },
|
||||
{ "-noip", "ignorePasswd", XrmoptionNoArg, "False" },
|
||||
{ "-ar", "acceptRootPasswd", XrmoptionNoArg, "True" },
|
||||
{ "-noar", "acceptRootPasswd", XrmoptionNoArg, "False" },
|
||||
};
|
||||
|
||||
static char *
|
||||
get_words(char **argv)
|
||||
{
|
||||
FILE *pp = 0;
|
||||
static char buf[BUFSIZ];
|
||||
register char *p = buf;
|
||||
|
||||
if (getwordsfrom == FROM_RESRC)
|
||||
return Resrcs.text;
|
||||
if (getwordsfrom == FROM_PROGRAM) {
|
||||
if (!(pp = popen(Resrcs.text_prog, "r"))) {
|
||||
perror(Resrcs.text_prog);
|
||||
return def_words;
|
||||
}
|
||||
} else if (getwordsfrom == FROM_FILE)
|
||||
if (!(pp = fopen(Resrcs.file, "r"))) {
|
||||
perror(Resrcs.file);
|
||||
return def_words;
|
||||
}
|
||||
else if (getwordsfrom != FROM_PROGRAM && getwordsfrom != FROM_FILE)
|
||||
return def_words;
|
||||
|
||||
buf[0] = 0;
|
||||
if (getwordsfrom == FROM_ARGV) {
|
||||
while (*argv) {
|
||||
p += strlen(strcpy(p, *argv));
|
||||
if (*++argv)
|
||||
strcpy(p++, " ");
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
/* BUG Alert: does not check for overflow */
|
||||
while (fgets(p, sizeof buf, pp))
|
||||
p += strlen(p);
|
||||
if (getwordsfrom == FROM_PROGRAM)
|
||||
(void) pclose(pp);
|
||||
else
|
||||
(void) fclose (pp);
|
||||
if (!buf[0])
|
||||
return def_words;
|
||||
return buf;
|
||||
}
|
||||
|
||||
static void
|
||||
init_words (int argc, char **argv)
|
||||
{
|
||||
char buf[BUFSIZ];
|
||||
|
||||
while (*argv && **argv == '-') {
|
||||
switch(argv[0][1]) {
|
||||
case 'p':
|
||||
getwordsfrom = FROM_PROGRAM;
|
||||
if (!*++argv)
|
||||
puts("specify a program name to get text from!"), exit(1);
|
||||
Resrcs.text_prog = *argv;
|
||||
case 'f':
|
||||
getwordsfrom = FROM_FILE;
|
||||
if (argv[1])
|
||||
Resrcs.file = *++argv;
|
||||
else {
|
||||
sprintf(buf, "%s/.msgfile", pw->pw_dir);
|
||||
Resrcs.file = strcpy(XtMalloc(strlen(buf)+1), buf);
|
||||
}
|
||||
default :
|
||||
printf("usage: %s [options] [message]\n", ProgName);
|
||||
puts("-fg color foreground color");
|
||||
puts("-bg color background color");
|
||||
puts("-rv reverse foreground/background colors");
|
||||
puts("-nrv no reverse video");
|
||||
puts("-ip ignore passwd");
|
||||
puts("-nip don't ignore passwd");
|
||||
puts("-ar accept root's passwd to unlock");
|
||||
puts("-nar don't accept root's passwd");
|
||||
puts("-f [file] message is read from file or ~/.msgfile");
|
||||
puts("-prog program text is gotten from executing `program'");
|
||||
exit(1);
|
||||
}
|
||||
argv++;
|
||||
}
|
||||
if (*argv) {
|
||||
if (getwordsfrom != FROM_RESRC)
|
||||
puts("I don't know what text you want displayed.");
|
||||
getwordsfrom = FROM_ARGV;
|
||||
} else if (!getwordsfrom)
|
||||
if (Resrcs.text)
|
||||
getwordsfrom = FROM_RESRC;
|
||||
else if (Resrcs.file)
|
||||
getwordsfrom = FROM_FILE;
|
||||
else
|
||||
getwordsfrom = FROM_PROGRAM;
|
||||
words = get_words(argv); /* if getwordsfrom != FROM_ARGV, argv is a nop */
|
||||
}
|
||||
|
||||
static void
|
||||
ScreenSaver(int save)
|
||||
{
|
||||
static int timeout, interval, prefer_blank, allow_exp;
|
||||
if (save) {
|
||||
XGetScreenSaver(dpy, &timeout, &interval, &prefer_blank, &allow_exp);
|
||||
XSetScreenSaver(dpy, 0, interval, prefer_blank, allow_exp);
|
||||
} else
|
||||
/* restore state */
|
||||
XSetScreenSaver(dpy, timeout, interval, prefer_blank, allow_exp);
|
||||
}
|
||||
|
||||
/* Forward decls necessary */
|
||||
static void talk(int force_erase);
|
||||
static unsigned long look(void);
|
||||
|
||||
static int
|
||||
zrefresh()
|
||||
{
|
||||
switch (fork()) {
|
||||
case -1:
|
||||
fprintf(stderr, "Warning %s: Failed to fork zrefresh\n", ProgName);
|
||||
return -1;
|
||||
case 0:
|
||||
/* Child */
|
||||
execlp("zrefresh", "zrefresh", 0);
|
||||
execl("/usr/athena/bin/zrefresh", "zrefresh", 0);
|
||||
fprintf(stderr, "Warning %s: Failed to exec zrefresh\n", ProgName);
|
||||
return -1;
|
||||
default:
|
||||
/* Parent */
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
leave(void)
|
||||
{
|
||||
#if 0
|
||||
XUngrabServer(dpy);
|
||||
#else
|
||||
XUngrabPointer(dpy, CurrentTime);
|
||||
XUngrabKeyboard(dpy, CurrentTime);
|
||||
#endif
|
||||
ScreenSaver(0);
|
||||
zrefresh();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
static void
|
||||
walk(int dir)
|
||||
{
|
||||
register int incr = 0;
|
||||
static int lastdir;
|
||||
static int up = 1;
|
||||
static Pixmap frame;
|
||||
|
||||
if (dir & (LEFT|RIGHT)) { /* left/right movement (mabye up/down too) */
|
||||
up = -up; /* bouncing effect (even if hit a wall) */
|
||||
if (dir & LEFT) {
|
||||
incr = X_INCR;
|
||||
frame = (up < 0) ? left0 : left1;
|
||||
} else {
|
||||
incr = -X_INCR;
|
||||
frame = (up < 0) ? right0 : right1;
|
||||
}
|
||||
if ((lastdir == FRONT || lastdir == DOWN) && dir & UP) {
|
||||
/* workaround silly bug that leaves screen dust when
|
||||
* guy is facing forward or down and moves up-left/right.
|
||||
*/
|
||||
XCopyPlane(dpy, frame, XtWindow(widget), gc, 0, 0, 64,64, x, y, 1L);
|
||||
XFlush(dpy);
|
||||
}
|
||||
/* note that maybe neither UP nor DOWN is set! */
|
||||
if (dir & UP && y > Y_INCR)
|
||||
y -= Y_INCR;
|
||||
else if (dir & DOWN && y < (int)Height - 64)
|
||||
y += Y_INCR;
|
||||
}
|
||||
/* Explicit up/down movement only (no left/right) */
|
||||
else if (dir == UP)
|
||||
XCopyPlane(dpy, front, XtWindow(widget), gc,
|
||||
0,0, 64,64, x, y -= Y_INCR, 1L);
|
||||
else if (dir == DOWN)
|
||||
XCopyPlane(dpy, down, XtWindow(widget), gc,
|
||||
0,0, 64,64, x, y += Y_INCR, 1L);
|
||||
else if (dir == FRONT && frame != front) {
|
||||
if (up > 0)
|
||||
up = -up;
|
||||
if (lastdir & LEFT)
|
||||
frame = left_front;
|
||||
else if (lastdir & RIGHT)
|
||||
frame = right_front;
|
||||
else
|
||||
frame = front;
|
||||
XCopyPlane(dpy, frame, XtWindow(widget), gc, 0, 0, 64,64, x, y, 1L);
|
||||
}
|
||||
if (dir & LEFT)
|
||||
while(--incr >= 0) {
|
||||
XCopyPlane(dpy, frame, XtWindow(widget), gc,
|
||||
0,0, 64,64, --x, y+up, 1L);
|
||||
XFlush(dpy);
|
||||
}
|
||||
else if (dir & RIGHT)
|
||||
while(++incr <= 0) {
|
||||
XCopyPlane(dpy, frame, XtWindow(widget), gc,
|
||||
0,0, 64,64, ++x, y+up, 1L);
|
||||
XFlush(dpy);
|
||||
}
|
||||
lastdir = dir;
|
||||
}
|
||||
|
||||
static int
|
||||
think(void)
|
||||
{
|
||||
if (rand() & 1)
|
||||
walk(FRONT);
|
||||
if (rand() & 1) {
|
||||
if (getwordsfrom > 1)
|
||||
words = get_words((char **)NULL);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
move(XtPointer _p, XtIntervalId *_id)
|
||||
{
|
||||
static int length, dir;
|
||||
|
||||
if (!length) {
|
||||
register int tries = 0;
|
||||
dir = 0;
|
||||
if ((rand() & 1) && think()) {
|
||||
talk(0); /* sets timeout to itself */
|
||||
return;
|
||||
}
|
||||
if (!(rand() % 3) && (interval = look())) {
|
||||
timeout_id = XtAppAddTimeOut(app, interval, move, NULL);
|
||||
return;
|
||||
}
|
||||
interval = 20 + rand() % 100;
|
||||
do {
|
||||
if (!tries)
|
||||
length = Width/100 + rand() % 90, tries = 8;
|
||||
else
|
||||
tries--;
|
||||
switch (rand() % 8) {
|
||||
case 0:
|
||||
if (x - X_INCR*length >= 5)
|
||||
dir = LEFT;
|
||||
case 1:
|
||||
if (x + X_INCR*length <= (int)Width - 70)
|
||||
dir = RIGHT;
|
||||
case 2:
|
||||
if (y - (Y_INCR*length) >= 5)
|
||||
dir = UP, interval = 40;
|
||||
case 3:
|
||||
if (y + Y_INCR*length <= (int)Height - 70)
|
||||
dir = DOWN, interval = 20;
|
||||
case 4:
|
||||
if (x - X_INCR*length >= 5 && y - (Y_INCR*length) >= 5)
|
||||
dir = (LEFT|UP);
|
||||
case 5:
|
||||
if (x + X_INCR * length <= (int)Width - 70 &&
|
||||
y-Y_INCR * length >= 5)
|
||||
dir = (RIGHT|UP);
|
||||
case 6:
|
||||
if (x - X_INCR * length >= 5 &&
|
||||
y + Y_INCR * length <= (int)Height - 70)
|
||||
dir = (LEFT|DOWN);
|
||||
case 7:
|
||||
if (x + X_INCR*length <= (int)Width - 70 &&
|
||||
y + Y_INCR*length <= (int)Height - 70)
|
||||
dir = (RIGHT|DOWN);
|
||||
}
|
||||
} while (!dir);
|
||||
}
|
||||
walk(dir);
|
||||
--length;
|
||||
timeout_id = XtAppAddTimeOut(app, interval, move, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
post_prompt_box(Window window)
|
||||
{
|
||||
char s[64];
|
||||
int width = (Width / 3);
|
||||
int height = font_height(font) * 6;
|
||||
int box_x, box_y;
|
||||
|
||||
/* make sure the entire nose icon fits in the box */
|
||||
if (height < 100)
|
||||
height = 100;
|
||||
|
||||
time_x = prompt_x = Width / 3;
|
||||
time_y = prompt_y = Height / 2;
|
||||
box_x = prompt_x - 105;
|
||||
box_y = prompt_y - 3 * font_height(font);
|
||||
|
||||
#ifdef KERBEROS
|
||||
if (inst[0] == 0)
|
||||
sprintf (s, "User: %s@%s", name, realm);
|
||||
else
|
||||
sprintf (s, "User: %s.%s@%s", name, inst, realm);
|
||||
#else
|
||||
sprintf (s, "User: %s", pw->pw_name);
|
||||
#endif
|
||||
/* erase current guy -- text message may still exist */
|
||||
XSetForeground(dpy, gc, Black);
|
||||
XFillRectangle(dpy, window, gc, x, y, 64, 64);
|
||||
talk(1); /* forcefully erase message if one is being displayed */
|
||||
/* Clear area in middle of screen for prompt box */
|
||||
XSetForeground(dpy, gc, White);
|
||||
XFillRectangle(dpy, window, gc, box_x, box_y, width, height);
|
||||
XSetForeground(dpy, gc, Black);
|
||||
|
||||
/* make a box that's 5 pixels thick. Then add a thin box inside it */
|
||||
XSetLineAttributes(dpy, gc, 5, 0, 0, 0);
|
||||
XDrawRectangle(dpy, window, gc, box_x+5, box_y+5, width-10, height-10);
|
||||
XSetLineAttributes(dpy, gc, 0, 0, 0, 0);
|
||||
XDrawRectangle(dpy, window, gc, box_x+12, box_y+12, width-23, height-23);
|
||||
|
||||
XDrawString(dpy, window, gc,
|
||||
prompt_x, prompt_y-font_height(font), s, strlen(s));
|
||||
XDrawString(dpy, window, gc, prompt_x, prompt_y, PROMPT, strlen(PROMPT));
|
||||
/* set background for copyplane and DrawImageString; need reverse video */
|
||||
XSetBackground(dpy, gc, White);
|
||||
XCopyPlane(dpy, right0, window, gc, 0,0, 64,64,
|
||||
box_x + 20, box_y + (height - 64)/2, 1L);
|
||||
prompt_x += XTextWidth(font, PROMPT, strlen(PROMPT));
|
||||
time_y += 2*font_height(font);
|
||||
}
|
||||
|
||||
static void
|
||||
RaiseWindow(Widget w, XEvent *ev, String *s, Cardinal *n)
|
||||
{
|
||||
Widget x;
|
||||
if(!XtIsRealized(w))
|
||||
return;
|
||||
x = XtParent(w);
|
||||
fprintf(stderr, "%s\n", XtName(x));
|
||||
XRaiseWindow(dpy, XtWindow(x));
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ClearWindow(Widget w, XEvent *_event, String *_s, Cardinal *_n)
|
||||
{
|
||||
XExposeEvent *event = (XExposeEvent *)_event;
|
||||
if (!XtIsRealized(w))
|
||||
return;
|
||||
XSetForeground(dpy, gc, Black);
|
||||
XFillRectangle(dpy, XtWindow(w), gc,
|
||||
event->x, event->y, event->width, event->height);
|
||||
XSetForeground(dpy, gc, White);
|
||||
XSetBackground(dpy, gc, Black);
|
||||
if (state == GET_PASSWD)
|
||||
post_prompt_box(XtWindow(w));
|
||||
if (timeout_id == 0 && event->count == 0) {
|
||||
timeout_id = XtAppAddTimeOut(app, 1000L, move, NULL);
|
||||
/* first grab the input focus */
|
||||
XSetInputFocus(dpy, XtWindow(w), RevertToPointerRoot, CurrentTime);
|
||||
/* now grab the pointer and keyboard and contrain to this window */
|
||||
XGrabPointer(dpy, XtWindow(w), TRUE, 0, GrabModeAsync,
|
||||
GrabModeAsync, XtWindow(w), None, CurrentTime);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
countdown(XtPointer _t, XtIntervalId *_d)
|
||||
{
|
||||
int *timeout = (int *)_t;
|
||||
char buf[16];
|
||||
time_t seconds;
|
||||
|
||||
if (--(*timeout) < 0) {
|
||||
XExposeEvent event;
|
||||
XtRemoveTimeOut(timeout_id);
|
||||
state = IS_MOVING;
|
||||
event.x = event.y = 0;
|
||||
event.width = Width, event.height = Height;
|
||||
ClearWindow(widget, (XEvent *)&event, 0, 0);
|
||||
timeout_id = XtAppAddTimeOut(app, 200L, move, NULL);
|
||||
return;
|
||||
}
|
||||
seconds = time(0) - locked_at;
|
||||
if (seconds >= 3600)
|
||||
(void) sprintf(buf, "Locked for %d:%02d:%02d ",
|
||||
(int)seconds/3600, (int)seconds/60%60, (int)seconds%60);
|
||||
else
|
||||
(void) sprintf(buf, "Locked for %2d:%02d ",
|
||||
(int)seconds/60, (int)seconds%60);
|
||||
|
||||
XDrawImageString(dpy, XtWindow(widget), gc,
|
||||
time_x, time_y, buf, strlen(buf));
|
||||
XtAppAddTimeOut(app, 1000L, countdown, timeout);
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
GetPasswd(Widget w, XEvent *_event, String *_s, Cardinal *_n)
|
||||
{
|
||||
XKeyEvent *event = (XKeyEvent *)_event;
|
||||
static char passwd[MAX_PASSWD_LENGTH];
|
||||
static int cnt;
|
||||
static int is_ctrl = NOCTRL;
|
||||
char c;
|
||||
KeySym keysym;
|
||||
|
||||
if (event->type == ButtonPress) {
|
||||
x = event->x, y = event->y, test = 2;
|
||||
return;
|
||||
}
|
||||
if (state == IS_MOVING) {
|
||||
/* guy is running around--change to post prompt box. */
|
||||
XtRemoveTimeOut(timeout_id);
|
||||
state = GET_PASSWD;
|
||||
if (Resrcs.ignore_passwd || !strlen(pw->pw_passwd))
|
||||
leave();
|
||||
post_prompt_box(XtWindow(w));
|
||||
cnt = 0;
|
||||
time_left = 30;
|
||||
countdown((XtPointer)&time_left, 0);
|
||||
return;
|
||||
}
|
||||
if (event->type == KeyRelease) {
|
||||
keysym = XLookupKeysym(event, 0);
|
||||
if (keysym == XK_Control_L || keysym == XK_Control_R) {
|
||||
is_ctrl = NOCTRL;
|
||||
}
|
||||
}
|
||||
if (event->type != KeyPress)
|
||||
return;
|
||||
keysym = XLookupKeysym(event, 0);
|
||||
if (keysym == XK_Control_L || keysym == XK_Control_R) {
|
||||
is_ctrl = CTRL;
|
||||
return;
|
||||
}
|
||||
if (!XLookupString(event, &c, 1, &keysym, 0))
|
||||
return;
|
||||
if (keysym == XK_Return || keysym == XK_Linefeed) {
|
||||
passwd[cnt] = 0;
|
||||
XtRemoveTimeOut(timeout_id);
|
||||
/*
|
||||
* First try with root password, if allowed.
|
||||
*/
|
||||
if (Resrcs.accept_root &&
|
||||
(root_pw[0] == 0 && cnt == 0 ||
|
||||
cnt && root_pw[0] && !strcmp(crypt(passwd, root_pw), root_pw)))
|
||||
leave();
|
||||
/*
|
||||
* Password that log out user
|
||||
*/
|
||||
if ( getuid() != 0
|
||||
&& geteuid() != 0
|
||||
&& (time(0) - locked_at) > ALLOW_LOGOUT
|
||||
&& strncmp(passwd, LOGOUT_PASSWD, sizeof(LOGOUT_PASSWD)) == 0)
|
||||
{
|
||||
signal(SIGHUP, SIG_IGN);
|
||||
kill(-1, SIGHUP);
|
||||
sleep(5);
|
||||
/* If the X-server shut down then so will we, else
|
||||
* continue */
|
||||
signal(SIGHUP, SIG_DFL);
|
||||
}
|
||||
#ifdef KERBEROS
|
||||
/*
|
||||
* Try to verify as user with kerberos.
|
||||
*/
|
||||
if (realm[0] != 0)
|
||||
{
|
||||
if (KSUCCESS == krb_get_pw_in_tkt(name,
|
||||
inst,
|
||||
realm,
|
||||
"krbtgt",
|
||||
realm,
|
||||
DEFAULT_TKT_LIFE,
|
||||
passwd))
|
||||
{
|
||||
int code;
|
||||
if (k_hasafs())
|
||||
{
|
||||
if ((code = k_afsklog(NULL, realm)) != KSUCCESS
|
||||
&& code != KDC_PR_UNKNOWN)
|
||||
fprintf(stderr,
|
||||
"%s: Warning %s\n",
|
||||
ProgName,
|
||||
krb_err_msg(code));
|
||||
}
|
||||
leave();
|
||||
}
|
||||
}
|
||||
#endif /* KERBEROS */
|
||||
/*
|
||||
* Try to verify as user.
|
||||
*/
|
||||
if (!strcmp(crypt(passwd, pw->pw_passwd), pw->pw_passwd))
|
||||
leave();
|
||||
|
||||
XDrawImageString(dpy, XtWindow(widget), gc,
|
||||
time_x, time_y, FAIL_MSG, strlen(FAIL_MSG));
|
||||
time_left = 0;
|
||||
state = IS_MOVING;
|
||||
timeout_id = XtAppAddTimeOut(app, 2000L, countdown, &time_left);
|
||||
return;
|
||||
}
|
||||
if (keysym == XK_BackSpace || keysym == XK_Delete || keysym == XK_Left) {
|
||||
if (cnt)
|
||||
passwd[cnt--] = ' ';
|
||||
} else if (keysym == XK_u && is_ctrl == CTRL) {
|
||||
while (cnt) {
|
||||
passwd[cnt--] = ' ';
|
||||
XDrawImageString(dpy, XtWindow(w), gc,
|
||||
prompt_x, prompt_y, STRING, cnt);
|
||||
XDrawImageString(dpy, XtWindow(w), gc,
|
||||
prompt_x + XTextWidth(font, STRING, cnt),
|
||||
prompt_y, SPACE_STRING, MAX_PASSWD_LENGTH - cnt + 1);
|
||||
}
|
||||
} else if (isprint(c))
|
||||
if ((cnt + 1) >= MAX_PASSWD_LENGTH)
|
||||
XBell(dpy, 50);
|
||||
else
|
||||
passwd[cnt++] = c;
|
||||
else
|
||||
return;
|
||||
XDrawImageString(dpy, XtWindow(w), gc,
|
||||
prompt_x, prompt_y, STRING, cnt);
|
||||
XDrawImageString(dpy, XtWindow(w), gc,
|
||||
prompt_x + XTextWidth(font, STRING, cnt),
|
||||
prompt_y, SPACE_STRING, MAX_PASSWD_LENGTH - cnt + 1);
|
||||
}
|
||||
|
||||
#include "nose.0.left"
|
||||
#include "nose.1.left"
|
||||
#include "nose.0.right"
|
||||
#include "nose.1.right"
|
||||
#include "nose.left.front"
|
||||
#include "nose.right.front"
|
||||
#include "nose.front"
|
||||
#include "nose.down"
|
||||
|
||||
static void
|
||||
init_images(void)
|
||||
{
|
||||
static Pixmap *images[] = {
|
||||
&left0, &left1, &right0, &right1,
|
||||
&left_front, &right_front, &front, &down
|
||||
};
|
||||
static unsigned char *bits[] = {
|
||||
nose_0_left_bits, nose_1_left_bits, nose_0_right_bits,
|
||||
nose_1_right_bits, nose_left_front_bits, nose_right_front_bits,
|
||||
nose_front_bits, nose_down_bits
|
||||
};
|
||||
int i;
|
||||
|
||||
for (i = 0; i < XtNumber(images); i++)
|
||||
if (!(*images[i] =
|
||||
XCreatePixmapFromBitmapData(dpy, DefaultRootWindow(dpy),
|
||||
bits[i], 64, 64, 1, 0, 1)))
|
||||
XtError("Can't load nose images");
|
||||
}
|
||||
|
||||
static void
|
||||
talk(int force_erase)
|
||||
{
|
||||
int width = 0, height, Z, total = 0;
|
||||
static int X, Y, talking;
|
||||
static struct { int x, y, width, height; } s_rect;
|
||||
register char *p, *p2;
|
||||
char buf[BUFSIZ], args[MAXLINES][256];
|
||||
|
||||
/* clear what we've written */
|
||||
if (talking || force_erase) {
|
||||
if (!talking)
|
||||
return;
|
||||
if (talking == 2) {
|
||||
XSetForeground(dpy, gc, Black);
|
||||
XDrawString(dpy, XtWindow(widget), gc, X, Y, words, strlen(words));
|
||||
XSetForeground(dpy, gc, White);
|
||||
} else if (talking == 1) {
|
||||
XSetForeground(dpy, gc, Black);
|
||||
XFillRectangle(dpy, XtWindow(widget), gc, s_rect.x-5, s_rect.y-5,
|
||||
s_rect.width+10, s_rect.height+10);
|
||||
XSetForeground(dpy, gc, White);
|
||||
}
|
||||
talking = 0;
|
||||
if (!force_erase)
|
||||
timeout_id = XtAppAddTimeOut(app, 40L,
|
||||
(XtTimerCallbackProc)move,
|
||||
NULL);
|
||||
return;
|
||||
}
|
||||
talking = 1;
|
||||
walk(FRONT);
|
||||
p = strcpy(buf, words);
|
||||
|
||||
/* possibly avoid a lot of work here
|
||||
* if no CR or only one, then just print the line
|
||||
*/
|
||||
if (!(p2 = index(p, '\n')) || !p2[1]) {
|
||||
register int w;
|
||||
|
||||
if (p2)
|
||||
*p2 = 0;
|
||||
w = XTextWidth(font, words, strlen(words));
|
||||
X = x + 32 - w/2;
|
||||
Y = y - 5 - font_height(font);
|
||||
/* give us a nice 5 pixel margin */
|
||||
if (X < 5)
|
||||
X = 5;
|
||||
else if (X + w + 15 > (int)Width + 5)
|
||||
X = Width - w - 5;
|
||||
if (Y < 5)
|
||||
Y = y + 64 + 5 + font_height(font);
|
||||
XDrawString(dpy, XtWindow(widget), gc, X, Y, words, strlen(words));
|
||||
timeout_id = XtAppAddTimeOut(app, 5000L, (XtTimerCallbackProc)talk,
|
||||
NULL);
|
||||
talking++;
|
||||
return;
|
||||
}
|
||||
|
||||
/* p2 now points to the first '\n' */
|
||||
for (height = 0; p; height++) {
|
||||
int w;
|
||||
*p2 = 0;
|
||||
if ((w = XTextWidth(font, p, p2 - p)) > width)
|
||||
width = w;
|
||||
total += p2 - p; /* total chars; count to determine reading time */
|
||||
strcpy(args[height], p);
|
||||
if (height == MAXLINES - 1) {
|
||||
puts("Message too long!");
|
||||
break;
|
||||
}
|
||||
p = p2+1;
|
||||
if (!(p2 = index(p, '\n')))
|
||||
break;
|
||||
}
|
||||
height++;
|
||||
|
||||
/* Figure out the height and width in pixels (height, width) extend
|
||||
* the new box by 15 pixels on the sides (30 total) top and bottom.
|
||||
*/
|
||||
s_rect.width = width + 30;
|
||||
s_rect.height = height * font_height(font) + 30;
|
||||
if (x - s_rect.width - 10 < 5)
|
||||
s_rect.x = 5;
|
||||
else
|
||||
if ((s_rect.x = x+32-(s_rect.width+15)/2)
|
||||
+ s_rect.width+15 > (int)Width-5)
|
||||
s_rect.x = Width - 15 - s_rect.width;
|
||||
if (y - s_rect.height - 10 < 5)
|
||||
s_rect.y = y + 64 + 5;
|
||||
else
|
||||
s_rect.y = y - 5 - s_rect.height;
|
||||
|
||||
XSetForeground(dpy, gc, White);
|
||||
XFillRectangle(dpy, XtWindow(widget), gc,
|
||||
s_rect.x-5, s_rect.y-5, s_rect.width+10, s_rect.height+10);
|
||||
XSetForeground(dpy, gc, Black);
|
||||
|
||||
/* make a box that's 5 pixels thick. Then add a thin box inside it */
|
||||
XSetLineAttributes(dpy, gc, 5, 0, 0, 0);
|
||||
XDrawRectangle(dpy, XtWindow(widget), gc,
|
||||
s_rect.x, s_rect.y, s_rect.width-1, s_rect.height-1);
|
||||
XSetLineAttributes(dpy, gc, 0, 0, 0, 0);
|
||||
XDrawRectangle(dpy, XtWindow(widget), gc,
|
||||
s_rect.x + 7, s_rect.y + 7, s_rect.width - 15, s_rect.height - 15);
|
||||
|
||||
X = 15;
|
||||
Y = 15 + font_height(font);
|
||||
|
||||
/* now print each string in reverse order (start at bottom of box) */
|
||||
for (Z = 0; Z < height; Z++) {
|
||||
XDrawString(dpy, XtWindow(widget), gc, s_rect.x+X, s_rect.y+Y,
|
||||
args[Z], strlen(args[Z]));
|
||||
Y += font_height(font);
|
||||
}
|
||||
timeout_id = XtAppAddTimeOut(app, (total/15) * 1000,
|
||||
(XtTimerCallbackProc)talk, NULL);
|
||||
}
|
||||
|
||||
static unsigned long
|
||||
look(void)
|
||||
{
|
||||
if (rand() % 3) {
|
||||
XCopyPlane(dpy, (rand() & 1)? down : front, XtWindow(widget), gc,
|
||||
0, 0, 64,64, x, y, 1L);
|
||||
return 1000L;
|
||||
}
|
||||
if (!(rand() % 5))
|
||||
return 0;
|
||||
if (rand() % 3) {
|
||||
XCopyPlane(dpy, (rand() & 1)? left_front : right_front,
|
||||
XtWindow(widget), gc, 0, 0, 64,64, x, y, 1L);
|
||||
return 1000L;
|
||||
}
|
||||
if (!(rand() % 5))
|
||||
return 0;
|
||||
XCopyPlane(dpy, (rand() & 1)? left0 : right0, XtWindow(widget), gc,
|
||||
0, 0, 64,64, x, y, 1L);
|
||||
return 1000L;
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
register int i;
|
||||
int foo;
|
||||
Widget override;
|
||||
XGCValues gcvalues;
|
||||
char **list;
|
||||
|
||||
srand(getpid());
|
||||
for (i = 0; i < (sizeof(STRING)-2); i++)
|
||||
STRING[i] = ((unsigned long)rand() % ('~' - ' ')) + ' ';
|
||||
|
||||
locked_at = time(0);
|
||||
|
||||
if ((ProgName = rindex(*argv, '/')) != 0)
|
||||
ProgName++;
|
||||
else
|
||||
ProgName = *argv;
|
||||
|
||||
/* getpwuid() returns static pointer, so get root's passwd first */
|
||||
if (!(pw = getpwuid(0)))
|
||||
printf("%s: can't get root's passwd!\n", ProgName), exit(1);
|
||||
strcpy(root_pw, pw->pw_passwd);
|
||||
if (!(pw = getpwuid(getuid())))
|
||||
printf("%s: Intruder alert!\n", ProgName), exit(1);
|
||||
|
||||
#ifdef KERBEROS
|
||||
{
|
||||
int code = KSUCCESS;
|
||||
char *file;
|
||||
strcpy(name, pw->pw_name); /* Unix name is default name */
|
||||
if ((file = getenv("KRBTKFILE")) == 0)
|
||||
file = TKT_FILE;
|
||||
code = tf_init(file, R_TKT_FIL);
|
||||
if (code == KSUCCESS)
|
||||
{
|
||||
(void) tf_close();
|
||||
if ((code = krb_get_tf_realm(file, realm)) == KSUCCESS &&
|
||||
(code = tf_init(file, R_TKT_FIL)) == KSUCCESS &&
|
||||
(code = tf_get_pname(name)) == KSUCCESS &&
|
||||
(code = tf_get_pinst(inst)) == KSUCCESS)
|
||||
{
|
||||
(void) tf_close(); /* Alles gut */
|
||||
dest_tkt(); /* Nuke old ticket file */
|
||||
creat(file, 0600); /* but keep a place holder */
|
||||
}
|
||||
}
|
||||
if (code != KSUCCESS)
|
||||
{
|
||||
code = krb_get_lrealm(realm, 1);
|
||||
if (code != KSUCCESS)
|
||||
realm[0] = 0; /* No kerberos today */
|
||||
}
|
||||
}
|
||||
#endif /* KERBEROS */
|
||||
|
||||
XtToolkitInitialize();
|
||||
app = XtCreateApplicationContext();
|
||||
dpy = XtOpenDisplay(app, NULL,
|
||||
"xnlock", "XNlock", options, XtNumber(options), &argc, argv);
|
||||
|
||||
if (dpy == 0)
|
||||
{
|
||||
fprintf(stderr, "Error: Can't open display:\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
Width = DisplayWidth(dpy, DefaultScreen(dpy)) + 2;
|
||||
Height = DisplayHeight(dpy, DefaultScreen(dpy)) + 2;
|
||||
override = XtVaAppCreateShell("xnlock", "XNlock",
|
||||
overrideShellWidgetClass, dpy,
|
||||
XtNx, -1,
|
||||
XtNy, -1,
|
||||
NULL);
|
||||
|
||||
XtGetApplicationResources(override, &Resrcs,
|
||||
resources, XtNumber(resources), NULL, 0);
|
||||
|
||||
widget = XtVaCreateManagedWidget("_foo", widgetClass, override,
|
||||
XtNwidth, Width,
|
||||
XtNheight, Height,
|
||||
NULL);
|
||||
|
||||
init_words(--argc, ++argv);
|
||||
init_images();
|
||||
|
||||
/* the background is black and the little guy is white */
|
||||
Black = Resrcs.do_reverse? Resrcs.fg : Resrcs.bg;
|
||||
White = Resrcs.do_reverse? Resrcs.bg : Resrcs.fg;
|
||||
gcvalues.foreground = Black;
|
||||
gcvalues.background = White;
|
||||
|
||||
if (!(font = Resrcs.font)) {
|
||||
list = XListFonts(dpy, FONT_NAME, 32767, &foo);
|
||||
for (i = 0; i < foo; i++)
|
||||
if ((font = XLoadQueryFont(dpy, list[i])) != 0)
|
||||
break;
|
||||
if (!font)
|
||||
{
|
||||
list = XListFonts(dpy, "fixed", 1, &foo);
|
||||
font = XLoadQueryFont(dpy, list[0]);
|
||||
}
|
||||
if (!font)
|
||||
XtError("Can't find a font (so call me stupid).");
|
||||
XFreeFontNames(list);
|
||||
}
|
||||
gcvalues.font = font->fid;
|
||||
gcvalues.graphics_exposures = False;
|
||||
gc = XCreateGC(dpy, DefaultRootWindow(dpy),
|
||||
GCForeground | GCBackground | GCGraphicsExposures | GCFont,
|
||||
&gcvalues);
|
||||
|
||||
x = Width / 2;
|
||||
y = Height / 2;
|
||||
srand (time(0));
|
||||
state = IS_MOVING;
|
||||
|
||||
{
|
||||
static XtActionsRec actions[] = {
|
||||
{ "ClearWindow", ClearWindow },
|
||||
{ "GetPasswd", GetPasswd },
|
||||
{ "RaiseWindow", RaiseWindow },
|
||||
};
|
||||
XtAppAddActions(app, actions, XtNumber(actions));
|
||||
XtOverrideTranslations(widget,
|
||||
XtParseTranslationTable(
|
||||
"<Expose>: ClearWindow() \n"
|
||||
"<BtnDown>: GetPasswd() \n"
|
||||
"<Visible>: RaiseWindow() \n"
|
||||
"<KeyRelease>: GetPasswd() \n"
|
||||
"<KeyPress>: GetPasswd()"));
|
||||
}
|
||||
|
||||
XtRealizeWidget(override);
|
||||
#if 0
|
||||
XGrabServer(dpy);
|
||||
#else
|
||||
XGrabPointer(dpy, XtWindow(widget), TRUE, 0, GrabModeAsync,
|
||||
GrabModeAsync, XtWindow(widget), None, CurrentTime);
|
||||
XGrabKeyboard(dpy, XtWindow(widget), TRUE, GrabModeAsync,
|
||||
GrabModeAsync, CurrentTime);
|
||||
#endif
|
||||
ScreenSaver(1);
|
||||
XtAppMainLoop(app);
|
||||
exit(0);
|
||||
}
|
||||
|
Reference in New Issue
Block a user