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