aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arg.h65
-rw-r--r--slock.c85
2 files changed, 119 insertions, 31 deletions
diff --git a/arg.h b/arg.h
new file mode 100644
index 0000000..0b23c53
--- /dev/null
+++ b/arg.h
@@ -0,0 +1,65 @@
1/*
2 * Copy me if you can.
3 * by 20h
4 */
5
6#ifndef ARG_H__
7#define ARG_H__
8
9extern char *argv0;
10
11/* use main(int argc, char *argv[]) */
12#define ARGBEGIN for (argv0 = *argv, argv++, argc--;\
13 argv[0] && argv[0][0] == '-'\
14 && argv[0][1];\
15 argc--, argv++) {\
16 char argc_;\
17 char **argv_;\
18 int brk_;\
19 if (argv[0][1] == '-' && argv[0][2] == '\0') {\
20 argv++;\
21 argc--;\
22 break;\
23 }\
24 for (brk_ = 0, argv[0]++, argv_ = argv;\
25 argv[0][0] && !brk_;\
26 argv[0]++) {\
27 if (argv_ != argv)\
28 break;\
29 argc_ = argv[0][0];\
30 switch (argc_)
31
32/* Handles obsolete -NUM syntax */
33#define ARGNUM case '0':\
34 case '1':\
35 case '2':\
36 case '3':\
37 case '4':\
38 case '5':\
39 case '6':\
40 case '7':\
41 case '8':\
42 case '9'
43
44#define ARGEND }\
45 }
46
47#define ARGC() argc_
48
49#define ARGNUMF() (brk_ = 1, estrtonum(argv[0], 0, INT_MAX))
50
51#define EARGF(x) ((argv[0][1] == '\0' && argv[1] == NULL)?\
52 ((x), abort(), (char *)0) :\
53 (brk_ = 1, (argv[0][1] != '\0')?\
54 (&argv[0][1]) :\
55 (argc--, argv++, argv[0])))
56
57#define ARGF() ((argv[0][1] == '\0' && argv[1] == NULL)?\
58 (char *)0 :\
59 (brk_ = 1, (argv[0][1] != '\0')?\
60 (&argv[0][1]) :\
61 (argc--, argv++, argv[0])))
62
63#define LNGARG() &argv[0][0]
64
65#endif
diff --git a/slock.c b/slock.c
index a00fbb9..210d5c8 100644
--- a/slock.c
+++ b/slock.c
@@ -23,8 +23,11 @@
23#include <bsd_auth.h> 23#include <bsd_auth.h>
24#endif 24#endif
25 25
26#include "arg.h"
26#include "util.h" 27#include "util.h"
27 28
29char *argv0;
30
28enum { 31enum {
29 INIT, 32 INIT,
30 INPUT, 33 INPUT,
@@ -54,7 +57,6 @@ die(const char *errstr, ...)
54{ 57{
55 va_list ap; 58 va_list ap;
56 59
57 fputs("slock: ", stderr);
58 va_start(ap, errstr); 60 va_start(ap, errstr);
59 vfprintf(stderr, errstr, ap); 61 vfprintf(stderr, errstr, ap);
60 va_end(ap); 62 va_end(ap);
@@ -280,8 +282,7 @@ lockscreen(Display *dpy, int screen)
280static void 282static void
281usage(void) 283usage(void)
282{ 284{
283 fprintf(stderr, "usage: slock [-v|POST_LOCK_CMD]\n"); 285 die("usage: slock [-v | cmd [arg ...]]\n");
284 exit(1);
285} 286}
286 287
287int 288int
@@ -290,64 +291,86 @@ main(int argc, char **argv) {
290 const char *pws; 291 const char *pws;
291#endif 292#endif
292 Display *dpy; 293 Display *dpy;
293 int screen; 294 int s, nlocks;
294 295
295 if ((argc >= 2) && !strcmp("-v", argv[1])) 296 ARGBEGIN {
296 die("version %s, © 2006-2016 slock engineers\n", VERSION); 297 case 'v':
297 298 fprintf(stderr, "slock-"VERSION"\n");
298 /* treat first argument starting with a '-' as option */ 299 return 0;
299 if ((argc >= 2) && argv[1][0] == '-') 300 default:
300 usage(); 301 usage();
302 } ARGEND
301 303
302#ifdef __linux__ 304#ifdef __linux__
303 dontkillme(); 305 dontkillme();
304#endif 306#endif
305 307
306 if (!getpwuid(getuid())) 308 /* Check if the current user has a password entry */
307 die("no passwd entry for you\n"); 309 errno = 0;
310 if (!getpwuid(getuid())) {
311 if (errno == 0)
312 die("slock: no password entry for current user\n");
313 else
314 die("slock: getpwuid: %s\n", strerror(errno));
315 }
308 316
309#ifndef HAVE_BSD_AUTH 317#ifndef HAVE_BSD_AUTH
310 pws = getpw(); 318 pws = getpw();
311#endif 319#endif
312 320
313 if (!(dpy = XOpenDisplay(0))) 321 if (!(dpy = XOpenDisplay(NULL)))
314 die("cannot open display\n"); 322 die("slock: cannot open display\n");
323
324 /* check for Xrandr support */
315 rr = XRRQueryExtension(dpy, &rrevbase, &rrerrbase); 325 rr = XRRQueryExtension(dpy, &rrevbase, &rrerrbase);
316 /* Get the number of screens in display "dpy" and blank them all. */ 326
327 /* get number of screens in display "dpy" and blank them */
317 nscreens = ScreenCount(dpy); 328 nscreens = ScreenCount(dpy);
318 if (!(locks = malloc(sizeof(Lock*) * nscreens))) 329 if (!(locks = malloc(sizeof(Lock *) * nscreens))) {
319 die("Out of memory.\n"); 330 XCloseDisplay(dpy);
320 int nlocks = 0; 331 die("slock: out of memory\n");
321 for (screen = 0; screen < nscreens; screen++) { 332 }
322 if ((locks[screen] = lockscreen(dpy, screen)) != NULL) 333 for (nlocks = 0, s = 0; s < nscreens; s++) {
334 if ((locks[s] = lockscreen(dpy, s)) != NULL)
323 nlocks++; 335 nlocks++;
324 } 336 }
325 XSync(dpy, False); 337 XSync(dpy, 0);
326 338
327 /* Did we actually manage to lock something? */ 339 /* did we actually manage to lock anything? */
328 if (nlocks == 0) { /* nothing to protect */ 340 if (nlocks == 0) {
341 /* nothing to protect */
329 free(locks); 342 free(locks);
330 XCloseDisplay(dpy); 343 XCloseDisplay(dpy);
331 return 1; 344 return 1;
332 } 345 }
333 346
334 if (argc >= 2 && fork() == 0) { 347 /* run post-lock command */
335 if (dpy) 348 if (argc > 0) {
336 close(ConnectionNumber(dpy)); 349 switch (fork()) {
337 execvp(argv[1], argv+1); 350 case -1:
338 die("execvp %s failed: %s\n", argv[1], strerror(errno)); 351 free(locks);
352 XCloseDisplay(dpy);
353 die("slock: fork failed: %s\n", strerror(errno));
354 case 0:
355 if (close(ConnectionNumber(dpy)) < 0)
356 die("slock: close: %s\n", strerror(errno));
357 execvp(argv[0], argv);
358 fprintf(stderr, "slock: execvp %s: %s\n", argv[0],
359 strerror(errno));
360 _exit(1);
361 }
339 } 362 }
340 363
341 /* Everything is now blank. Now wait for the correct password. */ 364 /* everything is now blank. Wait for the correct password */
342#ifdef HAVE_BSD_AUTH 365#ifdef HAVE_BSD_AUTH
343 readpw(dpy); 366 readpw(dpy);
344#else 367#else
345 readpw(dpy, pws); 368 readpw(dpy, pws);
346#endif 369#endif
347 370
348 /* Password ok, unlock everything and quit. */ 371 /* password ok, unlock everything and quit */
349 for (screen = 0; screen < nscreens; screen++) 372 for (s = 0; s < nscreens; s++)
350 unlockscreen(dpy, locks[screen]); 373 unlockscreen(dpy, locks[s]);
351 374
352 free(locks); 375 free(locks);
353 XCloseDisplay(dpy); 376 XCloseDisplay(dpy);