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 | } | 
