diff options
-rw-r--r-- | LICENSE | 21 | ||||
-rw-r--r-- | Makefile | 52 | ||||
-rw-r--r-- | README | 24 | ||||
-rw-r--r-- | config.mk | 25 | ||||
-rw-r--r-- | slock.c | 92 |
5 files changed, 214 insertions, 0 deletions
@@ -0,0 +1,21 @@ | |||
1 | MIT/X Consortium License | ||
2 | |||
3 | (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com> | ||
4 | |||
5 | Permission is hereby granted, free of charge, to any person obtaining a | ||
6 | copy of this software and associated documentation files (the "Software"), | ||
7 | to deal in the Software without restriction, including without limitation | ||
8 | the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
9 | and/or sell copies of the Software, and to permit persons to whom the | ||
10 | Software is furnished to do so, subject to the following conditions: | ||
11 | |||
12 | The above copyright notice and this permission notice shall be included in | ||
13 | all copies or substantial portions of the Software. | ||
14 | |||
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
18 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
20 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | ||
21 | DEALINGS IN THE SOFTWARE. | ||
diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..a84e889 --- /dev/null +++ b/Makefile | |||
@@ -0,0 +1,52 @@ | |||
1 | # slock - simple screen locker | ||
2 | # (C)opyright MMVI Anselm R. Garbe | ||
3 | |||
4 | include config.mk | ||
5 | |||
6 | SRC = slock.c | ||
7 | OBJ = ${SRC:.c=.o} | ||
8 | |||
9 | all: options slock | ||
10 | |||
11 | options: | ||
12 | @echo slock build options: | ||
13 | @echo "CFLAGS = ${CFLAGS}" | ||
14 | @echo "LDFLAGS = ${LDFLAGS}" | ||
15 | @echo "CC = ${CC}" | ||
16 | @echo "LD = ${LD}" | ||
17 | |||
18 | .c.o: | ||
19 | @echo CC $< | ||
20 | @${CC} -c ${CFLAGS} $< | ||
21 | |||
22 | ${OBJ}: config.mk | ||
23 | |||
24 | slock: ${OBJ} | ||
25 | @echo LD $@ | ||
26 | @${LD} -o $@ ${OBJ} ${LDFLAGS} | ||
27 | @strip $@ | ||
28 | |||
29 | clean: | ||
30 | @echo cleaning | ||
31 | @rm -f slock ${OBJ} slock-${VERSION}.tar.gz | ||
32 | |||
33 | dist: clean | ||
34 | @echo creating dist tarball | ||
35 | @mkdir -p slock-${VERSION} | ||
36 | @cp -R LICENSE Makefile README config.mk ${SRC} slock-${VERSION} | ||
37 | @tar -cf slock-${VERSION}.tar slock-${VERSION} | ||
38 | @gzip slock-${VERSION}.tar | ||
39 | @rm -rf slock-${VERSION} | ||
40 | |||
41 | install: all | ||
42 | @echo installing executable file to ${DESTDIR}${PREFIX}/bin | ||
43 | @mkdir -p ${DESTDIR}${PREFIX}/bin | ||
44 | @cp -f slock ${DESTDIR}${PREFIX}/bin | ||
45 | @chmod 755 ${DESTDIR}${PREFIX}/bin/slock | ||
46 | @chmod u+s ${DESTDIR}${PREFIX}/bin/slock | ||
47 | |||
48 | uninstall: | ||
49 | @echo removing executable file from ${DESTDIR}${PREFIX}/bin | ||
50 | @rm -f ${DESTDIR}${PREFIX}/bin/slock | ||
51 | |||
52 | .PHONY: all options clean dist install uninstall | ||
@@ -0,0 +1,24 @@ | |||
1 | slock - simple screen locker | ||
2 | ============================ | ||
3 | simple screen locker utility for X. | ||
4 | |||
5 | |||
6 | Requirements | ||
7 | ------------ | ||
8 | In order to build slock you need the Xlib header files. | ||
9 | |||
10 | |||
11 | Installation | ||
12 | ------------ | ||
13 | Edit config.mk to match your local setup (slock is installed into | ||
14 | the /usr/local namespace by default). | ||
15 | |||
16 | Afterwards enter the following command to build and install slock (if | ||
17 | necessary as root): | ||
18 | |||
19 | make clean install | ||
20 | |||
21 | |||
22 | Running slock | ||
23 | ------------- | ||
24 | Simply invoke the 'slock' command. | ||
diff --git a/config.mk b/config.mk new file mode 100644 index 0000000..48eef1f --- /dev/null +++ b/config.mk | |||
@@ -0,0 +1,25 @@ | |||
1 | # slock version | ||
2 | VERSION = 0.1 | ||
3 | |||
4 | # Customize below to fit your system | ||
5 | |||
6 | # paths | ||
7 | PREFIX = /usr/local | ||
8 | MANPREFIX = ${PREFIX}/share/man | ||
9 | |||
10 | X11INC = /usr/X11R6/include | ||
11 | X11LIB = /usr/X11R6/lib | ||
12 | |||
13 | # includes and libs | ||
14 | INCS = -I. -I/usr/include -I${X11INC} | ||
15 | LIBS = -L/usr/lib -lc -lcrypt -L${X11LIB} -lX11 | ||
16 | |||
17 | # flags | ||
18 | CFLAGS = -Os ${INCS} -DVERSION=\"${VERSION}\" | ||
19 | LDFLAGS = ${LIBS} | ||
20 | #CFLAGS = -g -Wall -O2 ${INCS} -DVERSION=\"${VERSION}\" | ||
21 | #LDFLAGS = -g ${LIBS} | ||
22 | |||
23 | # compiler and linker | ||
24 | CC = cc | ||
25 | LD = ${CC} | ||
@@ -0,0 +1,92 @@ | |||
1 | /* (C)opyright MMIV-MMV Anselm R. Garbe <garbeam at gmail dot com> | ||
2 | * See LICENSE file for license details. | ||
3 | */ | ||
4 | #define _XOPEN_SOURCE | ||
5 | #include <shadow.h> | ||
6 | #include <stdlib.h> | ||
7 | #include <stdio.h> | ||
8 | #include <string.h> | ||
9 | #include <unistd.h> | ||
10 | #include <sys/types.h> | ||
11 | #include <X11/keysym.h> | ||
12 | #include <X11/Xlib.h> | ||
13 | #include <X11/Xutil.h> | ||
14 | |||
15 | int | ||
16 | main(int argc, char **argv) { | ||
17 | char buf[32], passwd[256]; | ||
18 | int num, prev_nitem; | ||
19 | struct spwd *sp; | ||
20 | unsigned int i, len; | ||
21 | Bool running = True; | ||
22 | KeySym ksym; | ||
23 | Display *dpy; | ||
24 | XEvent ev; | ||
25 | |||
26 | if((argc > 1) && !strncmp(argv[1], "-v", 3)) { | ||
27 | fputs("slock-"VERSION", (C)opyright MMVI Anselm R. Garbe\n", stdout); | ||
28 | exit(EXIT_SUCCESS); | ||
29 | } | ||
30 | if(!(sp = getspnam(getenv("USER")))) { | ||
31 | fputs("slock: cannot retrieve password entry (make sure to suid slock)\n", stderr); | ||
32 | exit(EXIT_FAILURE); | ||
33 | } | ||
34 | endspent(); | ||
35 | if(!(dpy = XOpenDisplay(0))) { | ||
36 | fputs("slock: cannot open display\n", stderr); | ||
37 | exit(EXIT_FAILURE); | ||
38 | } | ||
39 | |||
40 | /* init */ | ||
41 | passwd[0] = 0; | ||
42 | while(XGrabKeyboard(dpy, DefaultRootWindow(dpy), True, GrabModeAsync, | ||
43 | GrabModeAsync, CurrentTime) != GrabSuccess) | ||
44 | usleep(1000); | ||
45 | |||
46 | /* main event loop */ | ||
47 | while(running && !XNextEvent(dpy, &ev)) | ||
48 | if(ev.type == KeyPress) { | ||
49 | len = strlen(passwd); | ||
50 | buf[0] = 0; | ||
51 | num = XLookupString(&ev.xkey, buf, sizeof(buf), &ksym, 0); | ||
52 | if(IsFunctionKey(ksym) || IsKeypadKey(ksym) | ||
53 | || IsMiscFunctionKey(ksym) || IsPFKey(ksym) | ||
54 | || IsPrivateKeypadKey(ksym)) | ||
55 | continue; | ||
56 | /* first check if a control mask is omitted */ | ||
57 | if(ev.xkey.state & ControlMask) { | ||
58 | switch (ksym) { | ||
59 | case XK_h: | ||
60 | case XK_H: ksym = XK_BackSpace; | ||
61 | break; | ||
62 | case XK_u: | ||
63 | case XK_U: passwd[0] = 0; | ||
64 | continue; | ||
65 | } | ||
66 | } | ||
67 | switch(ksym) { | ||
68 | case XK_Return: | ||
69 | running = strncmp(crypt(passwd, sp->sp_pwdp), sp->sp_pwdp, sizeof(passwd)); | ||
70 | passwd[0] = 0; | ||
71 | break; | ||
72 | case XK_Escape: | ||
73 | passwd[0] = 0; | ||
74 | break; | ||
75 | case XK_BackSpace: | ||
76 | if(len) | ||
77 | passwd[--len] = 0; | ||
78 | break; | ||
79 | default: | ||
80 | if(num && !iscntrl((int) buf[0])) { | ||
81 | buf[num] = 0; | ||
82 | if(len) | ||
83 | strncat(passwd, buf, sizeof(passwd)); | ||
84 | else | ||
85 | strncpy(passwd, buf, sizeof(passwd)); | ||
86 | } | ||
87 | break; | ||
88 | } | ||
89 | } | ||
90 | XCloseDisplay(dpy); | ||
91 | return 0; | ||
92 | } | ||