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