]> git.armaanb.net Git - slock.git/blob - slock.c
initial commit
[slock.git] / slock.c
1 /* (C)opyright MMIV-MMV Anselm R. Garbe <garbeam at gmail dot com>
2  * See LICENSE file for license details.
3  */
4 #define _XOPEN_SOURCE
5 #include <shadow.h>
6 #include <stdlib.h>
7 #include <stdio.h>
8 #include <string.h>
9 #include <unistd.h>
10 #include <sys/types.h>
11 #include <X11/keysym.h>
12 #include <X11/Xlib.h>
13 #include <X11/Xutil.h>
14
15 int
16 main(int argc, char **argv) {
17         char buf[32], passwd[256];
18         int num, prev_nitem;
19         struct spwd *sp;
20         unsigned int i, len;
21         Bool running = True;
22         KeySym ksym;
23         Display *dpy;
24         XEvent ev;
25
26         if((argc > 1) && !strncmp(argv[1], "-v", 3)) {
27                 fputs("slock-"VERSION", (C)opyright MMVI Anselm R. Garbe\n", stdout);
28                 exit(EXIT_SUCCESS);
29         }
30         if(!(sp = getspnam(getenv("USER")))) {
31                 fputs("slock: cannot retrieve password entry (make sure to suid slock)\n", stderr);
32                 exit(EXIT_FAILURE);
33         }
34         endspent();
35         if(!(dpy = XOpenDisplay(0))) {
36                 fputs("slock: cannot open display\n", stderr);
37                 exit(EXIT_FAILURE);
38         }
39
40         /* init */
41         passwd[0] = 0;
42         while(XGrabKeyboard(dpy, DefaultRootWindow(dpy), True, GrabModeAsync,
43                          GrabModeAsync, CurrentTime) != GrabSuccess)
44                 usleep(1000);
45
46         /* main event loop */
47         while(running && !XNextEvent(dpy, &ev))
48                 if(ev.type == KeyPress) {
49                         len = strlen(passwd);
50                         buf[0] = 0;
51                         num = XLookupString(&ev.xkey, buf, sizeof(buf), &ksym, 0);
52                         if(IsFunctionKey(ksym) || IsKeypadKey(ksym)
53                                         || IsMiscFunctionKey(ksym) || IsPFKey(ksym)
54                                         || IsPrivateKeypadKey(ksym))
55                                 continue;
56                         /* first check if a control mask is omitted */
57                         if(ev.xkey.state & ControlMask) {
58                                 switch (ksym) {
59                                 case XK_h:
60                                 case XK_H: ksym = XK_BackSpace;
61                                         break;
62                                 case XK_u:
63                                 case XK_U: passwd[0] = 0;
64                                         continue;
65                                 }
66                         }
67                         switch(ksym) {
68                         case XK_Return:
69                                 running = strncmp(crypt(passwd, sp->sp_pwdp), sp->sp_pwdp, sizeof(passwd));
70                                 passwd[0] = 0;
71                                 break;
72                         case XK_Escape:
73                                 passwd[0] = 0;
74                                 break;
75                         case XK_BackSpace:
76                                 if(len)
77                                         passwd[--len] = 0;
78                                 break;
79                         default:
80                                 if(num && !iscntrl((int) buf[0])) {
81                                         buf[num] = 0;
82                                         if(len)
83                                                 strncat(passwd, buf, sizeof(passwd));
84                                         else
85                                                 strncpy(passwd, buf, sizeof(passwd));
86                                 }
87                                 break;
88                         }
89                 }
90         XCloseDisplay(dpy);
91         return 0;
92 }