diff options
-rw-r--r-- | slock.c | 70 |
1 files changed, 42 insertions, 28 deletions
@@ -76,10 +76,9 @@ dontkillme(void) | |||
76 | if (fclose(f)) { | 76 | if (fclose(f)) { |
77 | if (errno == EACCES) | 77 | if (errno == EACCES) |
78 | die("slock: unable to disable OOM killer. " | 78 | die("slock: unable to disable OOM killer. " |
79 | "suid or sgid set?\n"); | 79 | "Make sure to suid or sgid slock.\n"); |
80 | else | 80 | else |
81 | die("slock: fclose %s: %s\n", oomfile, | 81 | die("slock: fclose %s: %s\n", oomfile, strerror(errno)); |
82 | strerror(errno)); | ||
83 | } | 82 | } |
84 | } | 83 | } |
85 | #endif | 84 | #endif |
@@ -104,17 +103,20 @@ gethash(void) | |||
104 | if (hash[0] == 'x' && hash[1] == '\0') { | 103 | if (hash[0] == 'x' && hash[1] == '\0') { |
105 | struct spwd *sp; | 104 | struct spwd *sp; |
106 | if (!(sp = getspnam(pw->pw_name))) | 105 | if (!(sp = getspnam(pw->pw_name))) |
107 | die("slock: getspnam: cannot retrieve shadow entry (make sure to suid or sgid slock)\n"); | 106 | die("slock: getspnam: cannot retrieve shadow entry. " |
107 | "Make sure to suid or sgid slock.\n"); | ||
108 | hash = sp->sp_pwdp; | 108 | hash = sp->sp_pwdp; |
109 | } | 109 | } |
110 | #else | 110 | #else |
111 | if (hash[0] == '*' && hash[1] == '\0') { | 111 | if (hash[0] == '*' && hash[1] == '\0') { |
112 | #ifdef __OpenBSD__ | 112 | #ifdef __OpenBSD__ |
113 | if (!(pw = getpwuid_shadow(getuid()))) | 113 | if (!(pw = getpwuid_shadow(getuid()))) |
114 | die("slock: getpwnam_shadow: cannot retrieve shadow entry (make sure to suid or sgid slock)\n"); | 114 | die("slock: getpwnam_shadow: cannot retrieve shadow entry. " |
115 | "Make sure to suid or sgid slock.\n"); | ||
115 | hash = pw->pw_passwd; | 116 | hash = pw->pw_passwd; |
116 | #else | 117 | #else |
117 | die("slock: getpwuid: cannot retrieve shadow entry (make sure to suid or sgid slock)\n"); | 118 | die("slock: getpwuid: cannot retrieve shadow entry. " |
119 | "Make sure to suid or sgid slock.\n"); | ||
118 | #endif /* __OpenBSD__ */ | 120 | #endif /* __OpenBSD__ */ |
119 | } | 121 | } |
120 | #endif /* HAVE_SHADOW_H */ | 122 | #endif /* HAVE_SHADOW_H */ |
@@ -126,6 +128,7 @@ static void | |||
126 | readpw(Display *dpy, struct xrandr *rr, struct lock **locks, int nscreens, | 128 | readpw(Display *dpy, struct xrandr *rr, struct lock **locks, int nscreens, |
127 | const char *hash) | 129 | const char *hash) |
128 | { | 130 | { |
131 | XRRScreenChangeNotifyEvent *rre; | ||
129 | char buf[32], passwd[256], *inputhash; | 132 | char buf[32], passwd[256], *inputhash; |
130 | int num, screen, running, failure; | 133 | int num, screen, running, failure; |
131 | unsigned int len, color; | 134 | unsigned int len, color; |
@@ -177,25 +180,29 @@ readpw(Display *dpy, struct xrandr *rr, struct lock **locks, int nscreens, | |||
177 | passwd[len--] = 0; | 180 | passwd[len--] = 0; |
178 | break; | 181 | break; |
179 | default: | 182 | default: |
180 | if (num && !iscntrl((int)buf[0]) && (len + num < sizeof(passwd))) { | 183 | if (num && !iscntrl((int)buf[0]) && |
184 | (len + num < sizeof(passwd))) { | ||
181 | memcpy(passwd + len, buf, num); | 185 | memcpy(passwd + len, buf, num); |
182 | len += num; | 186 | len += num; |
183 | } | 187 | } |
184 | break; | 188 | break; |
185 | } | 189 | } |
186 | color = len ? INPUT : (failure || failonclear ? FAILED : INIT); | 190 | color = len ? INPUT : ((failure || failonclear) ? FAILED : INIT); |
187 | if (running && oldc != color) { | 191 | if (running && oldc != color) { |
188 | for (screen = 0; screen < nscreens; screen++) { | 192 | for (screen = 0; screen < nscreens; screen++) { |
189 | XSetWindowBackground(dpy, locks[screen]->win, locks[screen]->colors[color]); | 193 | XSetWindowBackground(dpy, |
194 | locks[screen]->win, | ||
195 | locks[screen]->colors[color]); | ||
190 | XClearWindow(dpy, locks[screen]->win); | 196 | XClearWindow(dpy, locks[screen]->win); |
191 | } | 197 | } |
192 | oldc = color; | 198 | oldc = color; |
193 | } | 199 | } |
194 | } else if (rr->active && ev.type == rr->evbase + RRScreenChangeNotify) { | 200 | } else if (rr->active && ev.type == rr->evbase + RRScreenChangeNotify) { |
195 | XRRScreenChangeNotifyEvent *rre = (XRRScreenChangeNotifyEvent*)&ev; | 201 | rre = (XRRScreenChangeNotifyEvent*)&ev; |
196 | for (screen = 0; screen < nscreens; screen++) { | 202 | for (screen = 0; screen < nscreens; screen++) { |
197 | if (locks[screen]->win == rre->window) { | 203 | if (locks[screen]->win == rre->window) { |
198 | XResizeWindow(dpy, locks[screen]->win, rre->width, rre->height); | 204 | XResizeWindow(dpy, locks[screen]->win, |
205 | rre->width, rre->height); | ||
199 | XClearWindow(dpy, locks[screen]->win); | 206 | XClearWindow(dpy, locks[screen]->win); |
200 | } | 207 | } |
201 | } | 208 | } |
@@ -221,31 +228,37 @@ lockscreen(Display *dpy, struct xrandr *rr, int screen) | |||
221 | lock->root = RootWindow(dpy, lock->screen); | 228 | lock->root = RootWindow(dpy, lock->screen); |
222 | 229 | ||
223 | for (i = 0; i < NUMCOLS; i++) { | 230 | for (i = 0; i < NUMCOLS; i++) { |
224 | XAllocNamedColor(dpy, DefaultColormap(dpy, lock->screen), colorname[i], &color, &dummy); | 231 | XAllocNamedColor(dpy, DefaultColormap(dpy, lock->screen), |
232 | colorname[i], &color, &dummy); | ||
225 | lock->colors[i] = color.pixel; | 233 | lock->colors[i] = color.pixel; |
226 | } | 234 | } |
227 | 235 | ||
228 | /* init */ | 236 | /* init */ |
229 | wa.override_redirect = 1; | 237 | wa.override_redirect = 1; |
230 | wa.background_pixel = lock->colors[INIT]; | 238 | wa.background_pixel = lock->colors[INIT]; |
231 | lock->win = XCreateWindow(dpy, lock->root, 0, 0, DisplayWidth(dpy, lock->screen), DisplayHeight(dpy, lock->screen), | 239 | lock->win = XCreateWindow(dpy, lock->root, 0, 0, |
232 | 0, DefaultDepth(dpy, lock->screen), CopyFromParent, | 240 | DisplayWidth(dpy, lock->screen), |
233 | DefaultVisual(dpy, lock->screen), CWOverrideRedirect | CWBackPixel, &wa); | 241 | DisplayHeight(dpy, lock->screen), |
242 | 0, DefaultDepth(dpy, lock->screen), | ||
243 | CopyFromParent, | ||
244 | DefaultVisual(dpy, lock->screen), | ||
245 | CWOverrideRedirect | CWBackPixel, &wa); | ||
234 | lock->pmap = XCreateBitmapFromData(dpy, lock->win, curs, 8, 8); | 246 | lock->pmap = XCreateBitmapFromData(dpy, lock->win, curs, 8, 8); |
235 | invisible = XCreatePixmapCursor(dpy, lock->pmap, lock->pmap, &color, &color, 0, 0); | 247 | invisible = XCreatePixmapCursor(dpy, lock->pmap, lock->pmap, |
248 | &color, &color, 0, 0); | ||
236 | XDefineCursor(dpy, lock->win, invisible); | 249 | XDefineCursor(dpy, lock->win, invisible); |
237 | 250 | ||
238 | /* Try to grab mouse pointer *and* keyboard for 600ms, else fail the lock */ | 251 | /* Try to grab mouse pointer *and* keyboard for 600ms, else fail the lock */ |
239 | for (i = 0, ptgrab = kbgrab = -1; i < 6; i++) { | 252 | for (i = 0, ptgrab = kbgrab = -1; i < 6; i++) { |
240 | if (ptgrab != GrabSuccess) { | 253 | if (ptgrab != GrabSuccess) { |
241 | ptgrab = XGrabPointer(dpy, lock->root, False, | 254 | ptgrab = XGrabPointer(dpy, lock->root, False, |
242 | ButtonPressMask | ButtonReleaseMask | | 255 | ButtonPressMask | ButtonReleaseMask | |
243 | PointerMotionMask, GrabModeAsync, | 256 | PointerMotionMask, GrabModeAsync, |
244 | GrabModeAsync, None, invisible, CurrentTime); | 257 | GrabModeAsync, None, invisible, CurrentTime); |
245 | } | 258 | } |
246 | if (kbgrab != GrabSuccess) { | 259 | if (kbgrab != GrabSuccess) { |
247 | kbgrab = XGrabKeyboard(dpy, lock->root, True, | 260 | kbgrab = XGrabKeyboard(dpy, lock->root, True, |
248 | GrabModeAsync, GrabModeAsync, CurrentTime); | 261 | GrabModeAsync, GrabModeAsync, CurrentTime); |
249 | } | 262 | } |
250 | 263 | ||
251 | /* input is grabbed: we can lock the screen */ | 264 | /* input is grabbed: we can lock the screen */ |
@@ -268,9 +281,11 @@ lockscreen(Display *dpy, struct xrandr *rr, int screen) | |||
268 | 281 | ||
269 | /* we couldn't grab all input: fail out */ | 282 | /* we couldn't grab all input: fail out */ |
270 | if (ptgrab != GrabSuccess) | 283 | if (ptgrab != GrabSuccess) |
271 | fprintf(stderr, "slock: unable to grab mouse pointer for screen %d\n", screen); | 284 | fprintf(stderr, "slock: unable to grab mouse pointer for screen %d\n", |
285 | screen); | ||
272 | if (kbgrab != GrabSuccess) | 286 | if (kbgrab != GrabSuccess) |
273 | fprintf(stderr, "slock: unable to grab keyboard for screen %d\n", screen); | 287 | fprintf(stderr, "slock: unable to grab keyboard for screen %d\n", |
288 | screen); | ||
274 | return NULL; | 289 | return NULL; |
275 | } | 290 | } |
276 | 291 | ||
@@ -303,13 +318,13 @@ main(int argc, char **argv) { | |||
303 | /* validate drop-user and -group */ | 318 | /* validate drop-user and -group */ |
304 | errno = 0; | 319 | errno = 0; |
305 | if (!(pwd = getpwnam(user))) | 320 | if (!(pwd = getpwnam(user))) |
306 | die("slock: getpwnam %s: %s\n", user, errno ? | 321 | die("slock: getpwnam %s: %s\n", user, |
307 | strerror(errno) : "user entry not found"); | 322 | errno ? strerror(errno) : "user entry not found"); |
308 | duid = pwd->pw_uid; | 323 | duid = pwd->pw_uid; |
309 | errno = 0; | 324 | errno = 0; |
310 | if (!(grp = getgrnam(group))) | 325 | if (!(grp = getgrnam(group))) |
311 | die("slock: getgrnam %s: %s\n", group, errno ? | 326 | die("slock: getgrnam %s: %s\n", group, |
312 | strerror(errno) : "group entry not found"); | 327 | errno ? strerror(errno) : "group entry not found"); |
313 | dgid = grp->gr_gid; | 328 | dgid = grp->gr_gid; |
314 | 329 | ||
315 | #ifdef __linux__ | 330 | #ifdef __linux__ |
@@ -360,8 +375,7 @@ main(int argc, char **argv) { | |||
360 | if (close(ConnectionNumber(dpy)) < 0) | 375 | if (close(ConnectionNumber(dpy)) < 0) |
361 | die("slock: close: %s\n", strerror(errno)); | 376 | die("slock: close: %s\n", strerror(errno)); |
362 | execvp(argv[0], argv); | 377 | execvp(argv[0], argv); |
363 | fprintf(stderr, "slock: execvp %s: %s\n", argv[0], | 378 | fprintf(stderr, "slock: execvp %s: %s\n", argv[0], strerror(errno)); |
364 | strerror(errno)); | ||
365 | _exit(1); | 379 | _exit(1); |
366 | } | 380 | } |
367 | } | 381 | } |