| @ -0,0 +1,22 @@ | |||
| MIT/X Consortium License | |||
| © 2006-2008 Anselm R Garbe <garbeam at gmail dot com> | |||
| © 2009 Michael Stapelberg <michael+i3lock at stapelberg dot de> | |||
| Permission is hereby granted, free of charge, to any person obtaining a | |||
| copy of this software and associated documentation files (the "Software"), | |||
| to deal in the Software without restriction, including without limitation | |||
| the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||
| and/or sell copies of the Software, and to permit persons to whom the | |||
| Software is furnished to do so, subject to the following conditions: | |||
| The above copyright notice and this permission notice shall be included in | |||
| all copies or substantial portions of the Software. | |||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |||
| THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||
| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |||
| FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |||
| DEALINGS IN THE SOFTWARE. | |||
| @ -0,0 +1,49 @@ | |||
| # slock - simple screen locker | |||
| # © 2006-2007 Anselm R. Garbe, Sander van Dijk | |||
| # © 2009 Michael Stapelberg | |||
| include config.mk | |||
| SRC = i3lock.c | |||
| OBJ = ${SRC:.c=.o} | |||
| all: options i3lock | |||
| options: | |||
| @echo i3lock build options: | |||
| @echo "CFLAGS = ${CFLAGS}" | |||
| @echo "LDFLAGS = ${LDFLAGS}" | |||
| @echo "CC = ${CC}" | |||
| .c.o: | |||
| @echo CC $< | |||
| @${CC} -c ${CFLAGS} $< | |||
| ${OBJ}: config.mk | |||
| i3lock: ${OBJ} | |||
| @echo CC -o $@ | |||
| @${CC} -o $@ ${OBJ} ${LDFLAGS} | |||
| clean: | |||
| @echo cleaning | |||
| @rm -f i3lock ${OBJ} i3lock-${VERSION}.tar.gz | |||
| dist: clean | |||
| @echo creating dist tarball | |||
| @mkdir -p i3lock-${VERSION} | |||
| @cp -R LICENSE Makefile README config.mk ${SRC} slock-${VERSION} | |||
| @tar -cf i3lock-${VERSION}.tar i3lock-${VERSION} | |||
| @gzip i3lock-${VERSION}.tar | |||
| @rm -rf i3lock-${VERSION} | |||
| install: all | |||
| @echo installing executable file to $(DESTDIR)$(PREFIX)/bin | |||
| $(INSTALL) -d $(DESTDIR)$(PREFIX)/bin | |||
| $(INSTALL) -m 4755 i3lock $(DESTDIR)$(PREFIX)/bin/i3lock | |||
| uninstall: | |||
| @echo removing executable file from $(DESTDIR)$(PREFIX)/bin | |||
| @rm -f $(DESTDIR)$(PREFIX)/bin/i3lock | |||
| .PHONY: all options clean dist install uninstall | |||
| @ -0,0 +1,31 @@ | |||
| i3lock - slightly improved screen locker based on slock | |||
| ============================ | |||
| i3lock improves slock by making it fork() and therefore combinable with | |||
| commands to suspend your computer. Additionally, instead of turning of | |||
| your screen via DPMS and/or displaying a black screen, i3lock displays a | |||
| white screen so you can see if your computer failed to resume from suspend | |||
| or if your screen is just locked. Also, when entering a wrong password, | |||
| i3lock does not call XBell(). This is important because i3lock/slock think | |||
| you’ve entered a password when resuming from suspend, at least sometimes. | |||
| i3lock was forked from slock-0.9 | |||
| Requirements | |||
| ------------ | |||
| In order to build i3lock you need the Xlib header files. | |||
| Installation | |||
| ------------ | |||
| Edit config.mk to match your local setup (slock is installed into | |||
| the /usr/local namespace by default). | |||
| Afterwards enter the following command to build and install slock | |||
| (if necessary as root): | |||
| make clean install | |||
| Running i3lock | |||
| ------------- | |||
| Simply invoke the 'i3lock' command. To get out of it, enter your password. | |||
| @ -0,0 +1,26 @@ | |||
| # slock version | |||
| VERSION = 0.9 | |||
| # Customize below to fit your system | |||
| # paths | |||
| PREFIX = /usr | |||
| X11INC = /usr/X11R6/include | |||
| X11LIB = /usr/X11R6/lib | |||
| # includes and libs | |||
| INCS = -I. -I/usr/include -I${X11INC} | |||
| LIBS = -L/usr/lib -lc -lcrypt -L${X11LIB} -lX11 -lXext | |||
| # flags | |||
| CPPFLAGS = -DVERSION=\"${VERSION}\" -DHAVE_SHADOW_H | |||
| CFLAGS = -std=c99 -pedantic -Wall -Os ${INCS} ${CPPFLAGS} | |||
| LDFLAGS = -s ${LIBS} | |||
| # On *BSD remove -DHAVE_SHADOW_H from CPPFLAGS and add -DHAVE_BSD_AUTH | |||
| # On OpenBSD and Darwin remove -lcrypt from LIBS | |||
| # compiler and linker | |||
| CC = cc | |||
| INSTALL=install | |||
| @ -0,0 +1,174 @@ | |||
| /* See LICENSE file for license details. */ | |||
| #define _XOPEN_SOURCE 500 | |||
| #if HAVE_SHADOW_H | |||
| #include <shadow.h> | |||
| #endif | |||
| #include <ctype.h> | |||
| #include <pwd.h> | |||
| #include <stdarg.h> | |||
| #include <stdlib.h> | |||
| #include <stdio.h> | |||
| #include <string.h> | |||
| #include <unistd.h> | |||
| #include <sys/types.h> | |||
| #include <X11/keysym.h> | |||
| #include <X11/Xlib.h> | |||
| #include <X11/Xutil.h> | |||
| #if HAVE_BSD_AUTH | |||
| #include <login_cap.h> | |||
| #include <bsd_auth.h> | |||
| #endif | |||
| static void | |||
| die(const char *errstr, ...) { | |||
| va_list ap; | |||
| va_start(ap, errstr); | |||
| vfprintf(stderr, errstr, ap); | |||
| va_end(ap); | |||
| exit(EXIT_FAILURE); | |||
| } | |||
| #ifndef HAVE_BSD_AUTH | |||
| static const char * | |||
| get_password() { /* only run as root */ | |||
| const char *rval; | |||
| struct passwd *pw; | |||
| if(geteuid() != 0) | |||
| die("slock: cannot retrieve password entry (make sure to suid slock)\n"); | |||
| pw = getpwuid(getuid()); | |||
| endpwent(); | |||
| rval = pw->pw_passwd; | |||
| #if HAVE_SHADOW_H | |||
| { | |||
| struct spwd *sp; | |||
| sp = getspnam(getenv("USER")); | |||
| endspent(); | |||
| rval = sp->sp_pwdp; | |||
| } | |||
| #endif | |||
| /* drop privileges */ | |||
| if(setgid(pw->pw_gid) < 0 || setuid(pw->pw_uid) < 0) | |||
| die("slock: cannot drop privileges\n"); | |||
| return rval; | |||
| } | |||
| #endif | |||
| int | |||
| main(int argc, char **argv) { | |||
| char curs[] = {0, 0, 0, 0, 0, 0, 0, 0}; | |||
| char buf[32], passwd[256]; | |||
| int num, screen; | |||
| #ifndef HAVE_BSD_AUTH | |||
| const char *pws; | |||
| #endif | |||
| unsigned int len; | |||
| Bool running = True; | |||
| Cursor invisible; | |||
| Display *dpy; | |||
| KeySym ksym; | |||
| Pixmap pmap; | |||
| Window root, w; | |||
| XColor black, dummy; | |||
| XEvent ev; | |||
| XSetWindowAttributes wa; | |||
| if((argc == 2) && !strcmp("-v", argv[1])) | |||
| die("slock-"VERSION", © 2006-2008 Anselm R Garbe\n"); | |||
| else if(argc != 1) | |||
| die("usage: slock [-v]\n"); | |||
| #ifndef HAVE_BSD_AUTH | |||
| pws = get_password(); | |||
| #endif | |||
| if(!(dpy = XOpenDisplay(0))) | |||
| die("slock: cannot open display\n"); | |||
| screen = DefaultScreen(dpy); | |||
| root = RootWindow(dpy, screen); | |||
| if (fork() != 0) | |||
| return 0; | |||
| /* init */ | |||
| wa.override_redirect = 1; | |||
| wa.background_pixel = WhitePixel(dpy, screen); | |||
| w = XCreateWindow(dpy, root, 0, 0, DisplayWidth(dpy, screen), DisplayHeight(dpy, screen), | |||
| 0, DefaultDepth(dpy, screen), CopyFromParent, | |||
| DefaultVisual(dpy, screen), CWOverrideRedirect | CWBackPixel, &wa); | |||
| XAllocNamedColor(dpy, DefaultColormap(dpy, screen), "black", &black, &dummy); | |||
| pmap = XCreateBitmapFromData(dpy, w, curs, 8, 8); | |||
| invisible = XCreatePixmapCursor(dpy, pmap, pmap, &black, &black, 0, 0); | |||
| XDefineCursor(dpy, w, invisible); | |||
| XMapRaised(dpy, w); | |||
| for(len = 1000; len; len--) { | |||
| if(XGrabPointer(dpy, root, False, ButtonPressMask | ButtonReleaseMask | PointerMotionMask, | |||
| GrabModeAsync, GrabModeAsync, None, invisible, CurrentTime) == GrabSuccess) | |||
| break; | |||
| usleep(1000); | |||
| } | |||
| if((running = running && (len > 0))) { | |||
| for(len = 1000; len; len--) { | |||
| if(XGrabKeyboard(dpy, root, True, GrabModeAsync, GrabModeAsync, CurrentTime) | |||
| == GrabSuccess) | |||
| break; | |||
| usleep(1000); | |||
| } | |||
| running = (len > 0); | |||
| } | |||
| len = 0; | |||
| XSync(dpy, False); | |||
| /* main event loop */ | |||
| while(running && !XNextEvent(dpy, &ev)) { | |||
| if(ev.type == KeyPress) { | |||
| buf[0] = 0; | |||
| num = XLookupString(&ev.xkey, buf, sizeof buf, &ksym, 0); | |||
| if(IsKeypadKey(ksym)) { | |||
| if(ksym == XK_KP_Enter) | |||
| ksym = XK_Return; | |||
| else if(ksym >= XK_KP_0 && ksym <= XK_KP_9) | |||
| ksym = (ksym - XK_KP_0) + XK_0; | |||
| } | |||
| if(IsFunctionKey(ksym) || IsKeypadKey(ksym) | |||
| || IsMiscFunctionKey(ksym) || IsPFKey(ksym) | |||
| || IsPrivateKeypadKey(ksym)) | |||
| continue; | |||
| switch(ksym) { | |||
| case XK_Return: | |||
| passwd[len] = 0; | |||
| #ifdef HAVE_BSD_AUTH | |||
| running = !auth_userokay(getlogin(), NULL, "auth-xlock", passwd); | |||
| #else | |||
| running = strcmp(crypt(passwd, pws), pws); | |||
| #endif | |||
| len = 0; | |||
| break; | |||
| case XK_Escape: | |||
| len = 0; | |||
| break; | |||
| case XK_BackSpace: | |||
| if(len) | |||
| --len; | |||
| break; | |||
| default: | |||
| if(num && !iscntrl((int) buf[0]) && (len + num < sizeof passwd)) { | |||
| memcpy(passwd + len, buf, num); | |||
| len += num; | |||
| } | |||
| break; | |||
| } | |||
| } | |||
| } | |||
| XUngrabPointer(dpy, CurrentTime); | |||
| XFreePixmap(dpy, pmap); | |||
| XDestroyWindow(dpy, w); | |||
| XCloseDisplay(dpy); | |||
| return 0; | |||
| } | |||