aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--LICENSE2
-rw-r--r--slock.c86
2 files changed, 36 insertions, 52 deletions
diff --git a/LICENSE b/LICENSE
index faf1c09..5626eab 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,6 @@
1MIT/X Consortium License 1MIT/X Consortium License
2 2
3© 2006-2008 Anselm R Garbe <garbeam at gmail dot com> 3© 2006-2012 Anselm R Garbe <anselm@garbe.us>
4 4
5Permission is hereby granted, free of charge, to any person obtaining a 5Permission is hereby granted, free of charge, to any person obtaining a
6copy of this software and associated documentation files (the "Software"), 6copy of this software and associated documentation files (the "Software"),
diff --git a/slock.c b/slock.c
index d150009..28cb4f9 100644
--- a/slock.c
+++ b/slock.c
@@ -22,25 +22,23 @@
22#include <bsd_auth.h> 22#include <bsd_auth.h>
23#endif 23#endif
24 24
25struct st_lock { 25typedef struct {
26 int screen; 26 int screen;
27 Window root, w; 27 Window root, win;
28 Pixmap pmap; 28 Pixmap pmap;
29}; 29} Lock;
30 30
31extern const char *__progname; 31static Lock **locks;
32static int nscreens;
33static Bool running = True;
32 34
33static void 35static void
34die(const char *errstr, ...) { 36die(const char *errstr, ...) {
35 va_list ap; 37 va_list ap;
36 38
37 fprintf(stderr, "%s: ", __progname);
38 va_start(ap, errstr); 39 va_start(ap, errstr);
39 vfprintf(stderr, errstr, ap); 40 vfprintf(stderr, errstr, ap);
40 va_end(ap); 41 va_end(ap);
41 fprintf(stderr, "\n");
42 fflush(stderr);
43
44 exit(EXIT_FAILURE); 42 exit(EXIT_FAILURE);
45} 43}
46 44
@@ -52,7 +50,7 @@ getpw(void) { /* only run as root */
52 50
53 pw = getpwuid(getuid()); 51 pw = getpwuid(getuid());
54 if(!pw) 52 if(!pw)
55 die("cannot retrieve password entry (make sure to suid or sgid slock)"); 53 die("slock: cannot retrieve password entry (make sure to suid or sgid slock)");
56 endpwent(); 54 endpwent();
57 rval = pw->pw_passwd; 55 rval = pw->pw_passwd;
58 56
@@ -69,7 +67,7 @@ getpw(void) { /* only run as root */
69 67
70 /* drop privileges */ 68 /* drop privileges */
71 if(setgid(pw->pw_gid) < 0 || setuid(pw->pw_uid) < 0) 69 if(setgid(pw->pw_gid) < 0 || setuid(pw->pw_uid) < 0)
72 die("cannot drop privileges"); 70 die("slock: cannot drop privileges");
73 return rval; 71 return rval;
74} 72}
75#endif 73#endif
@@ -82,10 +80,8 @@ readpw(Display *dpy, const char *pws)
82#endif 80#endif
83{ 81{
84 char buf[32], passwd[256]; 82 char buf[32], passwd[256];
85 int num; 83 int num, screen;
86
87 unsigned int len; 84 unsigned int len;
88 Bool running = True;
89 KeySym ksym; 85 KeySym ksym;
90 XEvent ev; 86 XEvent ev;
91 87
@@ -96,7 +92,6 @@ readpw(Display *dpy, const char *pws)
96 * had been removed and you can set it with "xset" or some other 92 * had been removed and you can set it with "xset" or some other
97 * utility. This way the user can easily set a customized DPMS 93 * utility. This way the user can easily set a customized DPMS
98 * timeout. */ 94 * timeout. */
99
100 while(running && !XNextEvent(dpy, &ev)) { 95 while(running && !XNextEvent(dpy, &ev)) {
101 if(ev.type == KeyPress) { 96 if(ev.type == KeyPress) {
102 buf[0] = 0; 97 buf[0] = 0;
@@ -119,7 +114,7 @@ readpw(Display *dpy, const char *pws)
119#else 114#else
120 running = strcmp(crypt(passwd, pws), pws); 115 running = strcmp(crypt(passwd, pws), pws);
121#endif 116#endif
122 if (running != 0) 117 if(running != False)
123 XBell(dpy, 100); 118 XBell(dpy, 100);
124 len = 0; 119 len = 0;
125 break; 120 break;
@@ -138,36 +133,37 @@ readpw(Display *dpy, const char *pws)
138 break; 133 break;
139 } 134 }
140 } 135 }
136 else for(screen = 0; screen < nscreens; screen++)
137 XMapRaised(dpy, locks[screen]->win);
141 } 138 }
142} 139}
143 140
144static void 141static void
145unlockscreen(Display *dpy, struct st_lock *lock) { 142unlockscreen(Display *dpy, Lock *lock) {
146 if (dpy == NULL || lock == NULL) 143 if(dpy == NULL || lock == NULL)
147 return; 144 return;
148 145
149 XUngrabPointer(dpy, CurrentTime); 146 XUngrabPointer(dpy, CurrentTime);
150 XFreePixmap(dpy, lock->pmap); 147 XFreePixmap(dpy, lock->pmap);
151 XDestroyWindow(dpy, lock->w); 148 XDestroyWindow(dpy, lock->win);
152 149
153 free(lock); 150 free(lock);
154} 151}
155 152
156static struct st_lock * 153static Lock *
157lockscreen(Display *dpy, int screen) { 154lockscreen(Display *dpy, int screen) {
158 char curs[] = {0, 0, 0, 0, 0, 0, 0, 0}; 155 char curs[] = {0, 0, 0, 0, 0, 0, 0, 0};
159 unsigned int len; 156 unsigned int len;
160 struct st_lock *lock; 157 Lock *lock;
161 Bool running = True;
162 XColor black, dummy; 158 XColor black, dummy;
163 XSetWindowAttributes wa; 159 XSetWindowAttributes wa;
164 Cursor invisible; 160 Cursor invisible;
165 161
166 if (dpy == NULL || screen < 0) 162 if(dpy == NULL || screen < 0)
167 return NULL; 163 return NULL;
168 164
169 lock = malloc(sizeof(struct st_lock)); 165 lock = malloc(sizeof(Lock));
170 if (lock == NULL) 166 if(lock == NULL)
171 return NULL; 167 return NULL;
172 168
173 lock->screen = screen; 169 lock->screen = screen;
@@ -177,21 +173,21 @@ lockscreen(Display *dpy, int screen) {
177 /* init */ 173 /* init */
178 wa.override_redirect = 1; 174 wa.override_redirect = 1;
179 wa.background_pixel = BlackPixel(dpy, lock->screen); 175 wa.background_pixel = BlackPixel(dpy, lock->screen);
180 lock->w = XCreateWindow(dpy, lock->root, 0, 0, DisplayWidth(dpy, lock->screen), DisplayHeight(dpy, lock->screen), 176 lock->win = XCreateWindow(dpy, lock->root, 0, 0, DisplayWidth(dpy, lock->screen), DisplayHeight(dpy, lock->screen),
181 0, DefaultDepth(dpy, lock->screen), CopyFromParent, 177 0, DefaultDepth(dpy, lock->screen), CopyFromParent,
182 DefaultVisual(dpy, lock->screen), CWOverrideRedirect | CWBackPixel, &wa); 178 DefaultVisual(dpy, lock->screen), CWOverrideRedirect | CWBackPixel, &wa);
183 XAllocNamedColor(dpy, DefaultColormap(dpy, lock->screen), "black", &black, &dummy); 179 XAllocNamedColor(dpy, DefaultColormap(dpy, lock->screen), "black", &black, &dummy);
184 lock->pmap = XCreateBitmapFromData(dpy, lock->w, curs, 8, 8); 180 lock->pmap = XCreateBitmapFromData(dpy, lock->win, curs, 8, 8);
185 invisible = XCreatePixmapCursor(dpy, lock->pmap, lock->pmap, &black, &black, 0, 0); 181 invisible = XCreatePixmapCursor(dpy, lock->pmap, lock->pmap, &black, &black, 0, 0);
186 XDefineCursor(dpy, lock->w, invisible); 182 XDefineCursor(dpy, lock->win, invisible);
187 XMapRaised(dpy, lock->w); 183 XMapRaised(dpy, lock->win);
188 for(len = 1000; len; len--) { 184 for(len = 1000; len; len--) {
189 if(XGrabPointer(dpy, lock->root, False, ButtonPressMask | ButtonReleaseMask | PointerMotionMask, 185 if(XGrabPointer(dpy, lock->root, False, ButtonPressMask | ButtonReleaseMask | PointerMotionMask,
190 GrabModeAsync, GrabModeAsync, None, invisible, CurrentTime) == GrabSuccess) 186 GrabModeAsync, GrabModeAsync, None, invisible, CurrentTime) == GrabSuccess)
191 break; 187 break;
192 usleep(1000); 188 usleep(1000);
193 } 189 }
194 if((running = running && (len > 0))) { 190 if(running && (len > 0)) {
195 for(len = 1000; len; len--) { 191 for(len = 1000; len; len--) {
196 if(XGrabKeyboard(dpy, lock->root, True, GrabModeAsync, GrabModeAsync, CurrentTime) 192 if(XGrabKeyboard(dpy, lock->root, True, GrabModeAsync, GrabModeAsync, CurrentTime)
197 == GrabSuccess) 193 == GrabSuccess)
@@ -201,7 +197,7 @@ lockscreen(Display *dpy, int screen) {
201 running = (len > 0); 197 running = (len > 0);
202 } 198 }
203 199
204 if (!running) { 200 if(!running) {
205 unlockscreen(dpy, lock); 201 unlockscreen(dpy, lock);
206 lock = NULL; 202 lock = NULL;
207 } 203 }
@@ -211,24 +207,17 @@ lockscreen(Display *dpy, int screen) {
211 207
212static void 208static void
213usage(void) { 209usage(void) {
214 fprintf(stderr, "usage: %s -v", __progname); 210 fprintf(stderr, "usage: slock [-v]");
215 exit(EXIT_FAILURE); 211 exit(EXIT_FAILURE);
216} 212}
217 213
218static int
219xerrordummy(Display *dpy, XErrorEvent *ee) {
220 return 0;
221}
222
223int 214int
224main(int argc, char **argv) { 215main(int argc, char **argv) {
225#ifndef HAVE_BSD_AUTH 216#ifndef HAVE_BSD_AUTH
226 const char *pws; 217 const char *pws;
227#endif 218#endif
228 Display *dpy; 219 Display *dpy;
229 int nscreens, screen; 220 int screen;
230
231 struct st_lock **locks;
232 221
233 if((argc == 2) && !strcmp("-v", argv[1])) 222 if((argc == 2) && !strcmp("-v", argv[1]))
234 die("slock-%s, © 2006-2012 Anselm R Garbe", VERSION); 223 die("slock-%s, © 2006-2012 Anselm R Garbe", VERSION);
@@ -236,25 +225,21 @@ main(int argc, char **argv) {
236 usage(); 225 usage();
237 226
238 if(!getpwuid(getuid())) 227 if(!getpwuid(getuid()))
239 die("no passwd entry for you"); 228 die("slock: no passwd entry for you");
240 229
241#ifndef HAVE_BSD_AUTH 230#ifndef HAVE_BSD_AUTH
242 pws = getpw(); 231 pws = getpw();
243#endif 232#endif
244 233
245 if(!(dpy = XOpenDisplay(0))) 234 if(!(dpy = XOpenDisplay(0)))
246 die("cannot open display"); 235 die("slock: cannot open display");
247 /* prevent default error handler to take over */
248 XSetErrorHandler(xerrordummy);
249 /* Get the number of screens in display "dpy" and blank them all. */ 236 /* Get the number of screens in display "dpy" and blank them all. */
250 nscreens = ScreenCount(dpy); 237 nscreens = ScreenCount(dpy);
251 locks = malloc(sizeof(struct st_lock *) * nscreens); 238 locks = malloc(sizeof(Lock *) * nscreens);
252 if (locks == NULL) 239 if(locks == NULL)
253 die("malloc: %s", strerror(errno)); 240 die("slock: malloc: %s", strerror(errno));
254 241 for(screen = 0; screen < nscreens; screen++)
255 for (screen = 0; screen < nscreens; screen++)
256 locks[screen] = lockscreen(dpy, screen); 242 locks[screen] = lockscreen(dpy, screen);
257
258 XSync(dpy, False); 243 XSync(dpy, False);
259 244
260 /* Everything is now blank. Now wait for the correct password. */ 245 /* Everything is now blank. Now wait for the correct password. */
@@ -265,11 +250,10 @@ main(int argc, char **argv) {
265#endif 250#endif
266 251
267 /* Password ok, unlock everything and quit. */ 252 /* Password ok, unlock everything and quit. */
268 for (screen = 0; screen < nscreens; screen++) 253 for(screen = 0; screen < nscreens; screen++)
269 unlockscreen(dpy, locks[screen]); 254 unlockscreen(dpy, locks[screen]);
270 255
271 free(locks); 256 free(locks);
272
273 XCloseDisplay(dpy); 257 XCloseDisplay(dpy);
274 258
275 return 0; 259 return 0;