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