Xinqi Bao's Git
2dce109d531309c79a0687570f8cf0891db606e1
   1 /* See LICENSE file for license details. */ 
   2 #define _XOPEN_SOURCE 500 
  15 #include <sys/types.h> 
  16 #include <X11/keysym.h> 
  18 #include <X11/Xutil.h> 
  21 #include <login_cap.h> 
  31 extern const char *__progname
; 
  34 die(const char *errstr
, ...) { 
  37         fprintf(stderr
, "%s: ", __progname
); 
  39         vfprintf(stderr
, errstr
, ap
); 
  41         fprintf(stderr
, "\n"); 
  49 getpw(void) { /* only run as root */ 
  54                 die("cannot retrieve password entry (make sure to suid slock)"); 
  55         pw 
= getpwuid(getuid()); 
  62                 sp 
= getspnam(getenv("USER")); 
  69         if(setgid(pw
->pw_gid
) < 0 || setuid(pw
->pw_uid
) < 0) 
  70                 die("cannot drop privileges"); 
  79 readpw(Display 
*dpy
, const char *pws
) 
  82         char buf
[32], passwd
[256]; 
  93         /* As "slock" stands for "Simple X display locker", the DPMS settings 
  94          * had been removed and you can set it with "xset" or some other 
  95          * utility. This way the user can easily set a customized DPMS 
  98         while(running 
&& !XNextEvent(dpy
, &ev
)) { 
  99                 if(ev
.type 
== KeyPress
) { 
 101                         num 
= XLookupString(&ev
.xkey
, buf
, sizeof buf
, &ksym
, 0); 
 102                         if(IsKeypadKey(ksym
)) { 
 103                                 if(ksym 
== XK_KP_Enter
) 
 105                                 else if(ksym 
>= XK_KP_0 
&& ksym 
<= XK_KP_9
) 
 106                                         ksym 
= (ksym 
- XK_KP_0
) + XK_0
; 
 108                         if(IsFunctionKey(ksym
) || IsKeypadKey(ksym
) 
 109                                         || IsMiscFunctionKey(ksym
) || IsPFKey(ksym
) 
 110                                         || IsPrivateKeypadKey(ksym
)) 
 116                                 running 
= !auth_userokay(getlogin(), NULL
, "auth-xlock", passwd
); 
 118                                 running 
= strcmp(crypt(passwd
, pws
), pws
); 
 132                                 if(num 
&& !iscntrl((int) buf
[0]) && (len 
+ num 
< sizeof passwd
)) {  
 133                                         memcpy(passwd 
+ len
, buf
, num
); 
 143 unlockscreen(Display 
*dpy
, struct st_lock 
*lock
) { 
 144         if (dpy 
== NULL 
|| lock 
== NULL
) 
 147         XUngrabPointer(dpy
, CurrentTime
); 
 148         XFreePixmap(dpy
, lock
->pmap
); 
 149         XDestroyWindow(dpy
, lock
->w
); 
 154 static struct st_lock 
* 
 155 lockscreen(Display 
*dpy
, int screen
) { 
 156         char curs
[] = {0, 0, 0, 0, 0, 0, 0, 0}; 
 158         struct st_lock 
*lock
; 
 161         XSetWindowAttributes wa
; 
 164         if (dpy 
== NULL 
|| screen 
< 0) 
 167         lock 
= malloc(sizeof(struct st_lock
)); 
 171         lock
->screen 
= screen
; 
 173         lock
->root 
= RootWindow(dpy
, lock
->screen
); 
 176         wa
.override_redirect 
= 1; 
 177         wa
.background_pixel 
= BlackPixel(dpy
, lock
->screen
); 
 178         lock
->w 
= XCreateWindow(dpy
, lock
->root
, 0, 0, DisplayWidth(dpy
, lock
->screen
), DisplayHeight(dpy
, lock
->screen
), 
 179                         0, DefaultDepth(dpy
, lock
->screen
), CopyFromParent
, 
 180                         DefaultVisual(dpy
, lock
->screen
), CWOverrideRedirect 
| CWBackPixel
, &wa
); 
 181         XAllocNamedColor(dpy
, DefaultColormap(dpy
, lock
->screen
), "black", &black
, &dummy
); 
 182         lock
->pmap 
= XCreateBitmapFromData(dpy
, lock
->w
, curs
, 8, 8); 
 183         invisible 
= XCreatePixmapCursor(dpy
, lock
->pmap
, lock
->pmap
, &black
, &black
, 0, 0); 
 184         XDefineCursor(dpy
, lock
->w
, invisible
); 
 185         XMapRaised(dpy
, lock
->w
); 
 186         for(len 
= 1000; len
; len
--) { 
 187                 if(XGrabPointer(dpy
, lock
->root
, False
, ButtonPressMask 
| ButtonReleaseMask 
| PointerMotionMask
, 
 188                         GrabModeAsync
, GrabModeAsync
, None
, invisible
, CurrentTime
) == GrabSuccess
) 
 192         if((running 
= running 
&& (len 
> 0))) { 
 193                 for(len 
= 1000; len
; len
--) { 
 194                         if(XGrabKeyboard(dpy
, lock
->root
, True
, GrabModeAsync
, GrabModeAsync
, CurrentTime
) 
 203                 unlockscreen(dpy
, lock
); 
 212         fprintf(stderr
, "usage: %s -v", __progname
); 
 217 xerrordummy(Display 
*dpy
, XErrorEvent 
*ee
) { 
 222 main(int argc
, char **argv
) { 
 223 #ifndef HAVE_BSD_AUTH 
 227         int nscreens
, screen
; 
 229         struct st_lock 
**locks
; 
 231         if((argc 
== 2) && !strcmp("-v", argv
[1])) 
 232                 die("slock-%s, © 2006-2012 Anselm R Garbe", VERSION
); 
 236         if(!getpwuid(getuid())) 
 237                 die("no passwd entry for you"); 
 239 #ifndef HAVE_BSD_AUTH 
 243         if(!(dpy 
= XOpenDisplay(0))) 
 244                 die("cannot open display"); 
 245         /* prevent default error handler to take over */ 
 246         XSetErrorHandler(xerrordummy
); 
 247         /* Get the number of screens in display "dpy" and blank them all. */ 
 248         nscreens 
= ScreenCount(dpy
); 
 249         locks 
= malloc(sizeof(struct st_lock 
*) * nscreens
); 
 251                 die("malloc: %s", strerror(errno
)); 
 253         for (screen 
= 0; screen 
< nscreens
; screen
++) 
 254                 locks
[screen
] = lockscreen(dpy
, screen
); 
 258         /* Everything is now blank. Now wait for the correct password. */ 
 265         /* Password ok, unlock everything and quit. */ 
 266         for (screen 
= 0; screen 
< nscreens
; screen
++) 
 267                 unlockscreen(dpy
, locks
[screen
]);