main.c (2547B)
1 /* 2 * Simple, transparent screen locker in X11 3 */ 4 #include <X11/Xlib.h> 5 #include <X11/Xutil.h> 6 #include <X11/keysym.h> 7 #include <stdio.h> 8 #include <stdlib.h> 9 #include <unistd.h> 10 #include <crypt.h> 11 #include <string.h> 12 #include <pwd.h> 13 14 #ifdef NEED_SHADOW 15 #include <shadow.h> 16 #endif 17 18 int 19 main(int argc, char *argv[]) 20 { 21 Display *display; 22 Window root; 23 int len = 0, i; 24 XEvent ev; 25 char keybuffer[256], *passwd; 26 27 if (argc > 1) { 28 setenv("XLPASSWD", argv[1], 1); 29 execl("/proc/self/exe", argv[0], NULL); 30 fprintf(stderr, "failed to execute self, use XLPASSWD environment\n"); 31 exit(1); 32 } 33 else if ((passwd = getenv("XLPASSWD"))) 34 passwd = strdup(crypt(passwd, "ax")); 35 else { 36 #ifndef NEED_SHADOW 37 passwd = getpwuid(getuid())->pw_passwd; 38 #else 39 { 40 struct spwd *sp = getspnam(getpwuid(getuid())->pw_name); 41 if (sp) 42 passwd = sp->sp_pwdp; 43 else { 44 fprintf(stderr, "could not get shadow entry\n"); 45 exit(1); 46 } 47 } 48 #endif 49 if (!passwd) { 50 fprintf(stderr, "could not get passwd\n"); 51 exit(1); 52 } 53 } 54 55 if (strlen(passwd) < 2) { 56 fprintf(stderr, "passwd too short\n"); 57 exit(1); 58 } 59 60 if ((display = XOpenDisplay(NULL)) == NULL) { 61 fprintf(stderr, "could not connect to $DISPLAY\n"); 62 exit(1); 63 } 64 65 root = DefaultRootWindow(display); 66 67 for (i = 0; i < 1000; i++) { 68 if (XGrabPointer(display, root, 1, ButtonPress, GrabModeAsync, 69 GrabModeAsync, None, None, CurrentTime) == GrabSuccess) 70 break; 71 usleep(1000); 72 } 73 74 75 if (i == 1000) { 76 fprintf(stderr, "could not grab pointer\n"); 77 exit(1); 78 } 79 80 for (i = 0; i < 1000; i++) { 81 if (XGrabKeyboard(display, root, 0, GrabModeAsync, 82 GrabModeAsync, CurrentTime) == GrabSuccess) 83 break; 84 usleep(1000); 85 } 86 if (i == 1000) { 87 XUngrabPointer(display, CurrentTime); 88 fprintf(stderr, "could not grab keyboard\n"); 89 exit(1); 90 } 91 XSelectInput(display, root, KeyPressMask); 92 93 while (XNextEvent(display, &ev), 1) { 94 if (ev.type == KeyPress) { 95 KeySym keysym; 96 XComposeStatus compose; 97 if (len > sizeof(keybuffer)-10) 98 len = 0; 99 i = XLookupString(&ev.xkey, keybuffer+len, 10, &keysym, &compose); 100 101 if (keysym == XK_Return) { 102 keybuffer[len] = 0; 103 if (len && !strcmp(crypt(keybuffer, passwd), passwd)) { 104 XUngrabKeyboard(display, CurrentTime); 105 XUngrabPointer(display, CurrentTime); 106 exit(0); 107 } else 108 len = 0; 109 } else 110 len += i; 111 } 112 } 113 }