From e4864c25c0a839f9c83d9f55a1c416e8f0874c72 Mon Sep 17 00:00:00 2001 From: Asdam9 <49947700+Asdam9@users.noreply.github.com> Date: Sat, 6 Feb 2021 16:42:14 +0000 Subject: [PATCH] Add files via upload --- LICENSE | 24 ++ Makefile | 61 +++++ README | 24 ++ arg.h | 65 +++++ config.def.h | 38 +++ config.mk | 32 +++ explicit_bzero.c | 19 ++ explicit_bzero.o | Bin 0 -> 1536 bytes slock.1 | 46 ++++ slock.c | 616 +++++++++++++++++++++++++++++++++++++++++++++++ slock.o | Bin 0 -> 19664 bytes util.h | 2 + 12 files changed, 927 insertions(+) create mode 100644 LICENSE create mode 100644 Makefile create mode 100644 README create mode 100644 arg.h create mode 100644 config.def.h create mode 100644 config.mk create mode 100644 explicit_bzero.c create mode 100644 explicit_bzero.o create mode 100644 slock.1 create mode 100644 slock.c create mode 100644 slock.o create mode 100644 util.h diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..2e4419b --- /dev/null +++ b/LICENSE @@ -0,0 +1,24 @@ +MIT/X Consortium License + +© 2015-2016 Markus Teich +© 2014 Dimitris Papastamos +© 2006-2014 Anselm R Garbe +© 2014-2016 Laslo Hunhold + +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. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..f4ffbb7 --- /dev/null +++ b/Makefile @@ -0,0 +1,61 @@ +# slock - simple screen locker +# See LICENSE file for copyright and license details. + +include config.mk + +SRC = slock.c ${COMPATSRC} +OBJ = ${SRC:.c=.o} + +all: options slock + +options: + @echo slock build options: + @echo "CFLAGS = ${CFLAGS}" + @echo "LDFLAGS = ${LDFLAGS}" + @echo "CC = ${CC}" + +.c.o: + @echo CC $< + @${CC} -c ${CFLAGS} $< + +${OBJ}: config.h config.mk arg.h util.h + +config.h: + @echo creating $@ from config.def.h + @cp config.def.h $@ + +slock: ${OBJ} + @echo CC -o $@ + @${CC} -o $@ ${OBJ} ${LDFLAGS} + +clean: + @echo cleaning + @rm -f slock ${OBJ} slock-${VERSION}.tar.gz + +dist: clean + @echo creating dist tarball + @mkdir -p slock-${VERSION} + @cp -R LICENSE Makefile README slock.1 config.mk \ + ${SRC} explicit_bzero.c config.def.h arg.h util.h slock-${VERSION} + @tar -cf slock-${VERSION}.tar slock-${VERSION} + @gzip slock-${VERSION}.tar + @rm -rf slock-${VERSION} + +install: all + @echo installing executable file to ${DESTDIR}${PREFIX}/bin + @mkdir -p ${DESTDIR}${PREFIX}/bin + @cp -f slock ${DESTDIR}${PREFIX}/bin + @chmod 755 ${DESTDIR}${PREFIX}/bin/slock + @chmod u+s ${DESTDIR}${PREFIX}/bin/slock + @echo installing manual page to ${DESTDIR}${MANPREFIX}/man1 + @mkdir -p ${DESTDIR}${MANPREFIX}/man1 + @sed "s/VERSION/${VERSION}/g" ${DESTDIR}${MANPREFIX}/man1/slock.1 + @chmod 644 ${DESTDIR}${MANPREFIX}/man1/slock.1 + +uninstall: + @echo removing executable file from ${DESTDIR}${PREFIX}/bin + @rm -f ${DESTDIR}${PREFIX}/bin/slock + @echo removing manual page from ${DESTDIR}${MANPREFIX}/man1 + @rm -f ${DESTDIR}${MANPREFIX}/man1/slock.1 + +.PHONY: all options clean dist install uninstall diff --git a/README b/README new file mode 100644 index 0000000..dcacd01 --- /dev/null +++ b/README @@ -0,0 +1,24 @@ +slock - simple screen locker +============================ +simple screen locker utility for X. + + +Requirements +------------ +In order to build slock 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 slock +------------- +Simply invoke the 'slock' command. To get out of it, enter your password. diff --git a/arg.h b/arg.h new file mode 100644 index 0000000..0b23c53 --- /dev/null +++ b/arg.h @@ -0,0 +1,65 @@ +/* + * Copy me if you can. + * by 20h + */ + +#ifndef ARG_H__ +#define ARG_H__ + +extern char *argv0; + +/* use main(int argc, char *argv[]) */ +#define ARGBEGIN for (argv0 = *argv, argv++, argc--;\ + argv[0] && argv[0][0] == '-'\ + && argv[0][1];\ + argc--, argv++) {\ + char argc_;\ + char **argv_;\ + int brk_;\ + if (argv[0][1] == '-' && argv[0][2] == '\0') {\ + argv++;\ + argc--;\ + break;\ + }\ + for (brk_ = 0, argv[0]++, argv_ = argv;\ + argv[0][0] && !brk_;\ + argv[0]++) {\ + if (argv_ != argv)\ + break;\ + argc_ = argv[0][0];\ + switch (argc_) + +/* Handles obsolete -NUM syntax */ +#define ARGNUM case '0':\ + case '1':\ + case '2':\ + case '3':\ + case '4':\ + case '5':\ + case '6':\ + case '7':\ + case '8':\ + case '9' + +#define ARGEND }\ + } + +#define ARGC() argc_ + +#define ARGNUMF() (brk_ = 1, estrtonum(argv[0], 0, INT_MAX)) + +#define EARGF(x) ((argv[0][1] == '\0' && argv[1] == NULL)?\ + ((x), abort(), (char *)0) :\ + (brk_ = 1, (argv[0][1] != '\0')?\ + (&argv[0][1]) :\ + (argc--, argv++, argv[0]))) + +#define ARGF() ((argv[0][1] == '\0' && argv[1] == NULL)?\ + (char *)0 :\ + (brk_ = 1, (argv[0][1] != '\0')?\ + (&argv[0][1]) :\ + (argc--, argv++, argv[0]))) + +#define LNGARG() &argv[0][0] + +#endif diff --git a/config.def.h b/config.def.h new file mode 100644 index 0000000..3345f1a --- /dev/null +++ b/config.def.h @@ -0,0 +1,38 @@ +/* user and group to drop privileges to */ +static const char *user = "adam"; +static const char *group = "adam"; + +static const char *colorname[NUMCOLS] = { + [INIT] = "black", /* after initialization */ + [INPUT] = "#005577", /* during input */ + [FAILED] = "#CC3333", /* wrong password */ +}; + +/* treat a cleared input like a wrong password (color) */ +static const int failonclear = 1; + +/* time in seconds to cancel lock with mouse movement */ +static const int timetocancel = 4; + +/* default message */ +static const char * message = "Input Password:"; + +/* text color */ +static const char * text_color = "#ffffff"; + +/* text size (must be a valid size) */ +static const char * font_name = "-b&h-lucidabright-medium-r-normal--20-200-75-75-p-200-iso8859-1" ; + //-Misc-Fixed-Medium-R-Normal--20-200-75-75-C-100-ISO10646-1 + //-misc-fixed-medium-r-semicondensed--13-120-75-75-c-60-iso8859-1 + //-bitstream-charter-medium-i-normal--0-0-75-75-p-0-iso8859-1 + +#define SCREENSLEEP + +/*Enable blur*/ +#define BLUR +/*Set blur radius*/ +static const int blurRadius=10; +/*Enable Pixelation*/ +#define PIXELATION +/*Set pixelation radius*/ +static const int pixelSize=30; diff --git a/config.mk b/config.mk new file mode 100644 index 0000000..13b0b67 --- /dev/null +++ b/config.mk @@ -0,0 +1,32 @@ +# slock version +VERSION = 1.4 + +# Customize below to fit your system + +# paths +PREFIX = /usr/local +MANPREFIX = ${PREFIX}/share/man + +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 -lXrandr -lImlib2 -lXinerama + +# flags +CPPFLAGS = -DVERSION=\"${VERSION}\" -D_DEFAULT_SOURCE -DHAVE_SHADOW_H +CFLAGS = -std=c99 -pedantic -Wall -Ofast ${INCS} ${CPPFLAGS} +LDFLAGS = -s ${LIBS} +COMPATSRC = explicit_bzero.c + +# On OpenBSD and Darwin remove -lcrypt from LIBS +#LIBS = -L/usr/lib -lc -L${X11LIB} -lX11 -lXext -lXrandr +# On *BSD remove -DHAVE_SHADOW_H from CPPFLAGS +# On NetBSD add -D_NETBSD_SOURCE to CPPFLAGS +#CPPFLAGS = -DVERSION=\"${VERSION}\" -D_BSD_SOURCE -D_NETBSD_SOURCE +# On OpenBSD set COMPATSRC to empty +#COMPATSRC = + +# compiler and linker +CC = cc diff --git a/explicit_bzero.c b/explicit_bzero.c new file mode 100644 index 0000000..3e33ca8 --- /dev/null +++ b/explicit_bzero.c @@ -0,0 +1,19 @@ +/* $OpenBSD: explicit_bzero.c,v 1.3 2014/06/21 02:34:26 matthew Exp $ */ +/* + * Public domain. + * Written by Matthew Dempsky. + */ + +#include + +__attribute__((weak)) void +__explicit_bzero_hook(void *buf, size_t len) +{ +} + +void +explicit_bzero(void *buf, size_t len) +{ + memset(buf, 0, len); + __explicit_bzero_hook(buf, len); +} diff --git a/explicit_bzero.o b/explicit_bzero.o new file mode 100644 index 0000000000000000000000000000000000000000..4799a708e75f1d46ddfb481a4a5755f2a8ab695c GIT binary patch literal 1536 zcmbtT&ubGw6n>kit+uqW_8?a1;z6p|A(29%hq7r&vPd+j>A{06n>Zo;vE7p0LoA3M zM99rQ!T-gB{weh$DCkM3?@i{V<2b$O2Rq-J@6DTe@6GJ%TC-m8JYaaR31>4_k&9<` zpv(YfVFo_-dSZV0ty1Qf1K0^i-^0<5%Fh#$!qL~~;po#B}`?N?F_& zWl|TF3&1;m0^YFXEzM3%zsCehsNZCt=Ih8R2>AwS)w$BU!sEGVvd;n4asj@by4*!~ zrC6#_tPxnmom?owC6|o5Or4`&{7YXz<(82T-@yv%3#d~+2&!)6b^KT(o$(M2mkx4x zbg%P_t$n-JRw88qM29do?^0)&c%Lilbvo(+hvB>2x2k|1#V-TGz z1JO;BL>{7cnC4R8b6d^wxVsNREtmbMH;5C-=l(DIxB=aj{Q?5i2zSRc87FmVWeJ&j z6zDlqpqo?H!ewMShu=E=3k2#j>Gq4=Bc}uWuGn=C4chZx<0}|Tdvcy=D)9N&SkTPp zGjE{Iwz>3`IWcT|ZA-_SZ;6(_p#c$&X)<#ESa^VjtN%xi{?p&g@!WsP$3C0({!9bH o*9l)in_}&Fx>vjRD8Y%2YtzJlUH?_|x#B +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "arg.h" +#include "util.h" + +char *argv0; + +/* global count to prevent repeated error messages */ +int count_error = 0; +float priorBackLight = 100; + +enum { + INIT, + INPUT, + FAILED, + NUMCOLS +}; + +struct lock { + int screen; + Window root, win; + Pixmap pmap; + Pixmap bgmap; + unsigned long colors[NUMCOLS]; +}; + +struct xrandr { + int active; + int evbase; + int errbase; +}; + +#include "config.h" + +Imlib_Image image; + +static void +die(const char *errstr, ...) +{ + va_list ap; + + va_start(ap, errstr); + vfprintf(stderr, errstr, ap); + va_end(ap); + exit(1); +} + +#ifdef __linux__ +#include +#include + +static void +dontkillme(void) +{ + FILE *f; + const char oomfile[] = "/proc/self/oom_score_adj"; + + if (!(f = fopen(oomfile, "w"))) { + if (errno == ENOENT) + return; + die("slock: fopen %s: %s\n", oomfile, strerror(errno)); + } + fprintf(f, "%d", OOM_SCORE_ADJ_MIN); + if (fclose(f)) { + if (errno == EACCES) + die("slock: unable to disable OOM killer. " + "Make sure to suid or sgid slock.\n"); + else + die("slock: fclose %s: %s\n", oomfile, strerror(errno)); + } +} +#endif + +static void +writemessage(Display *dpy, Window win, int screen) +{ + int len, line_len, width, height, s_width, s_height, i, j, k, tab_replace, tab_size; + XGCValues gr_values; + XFontStruct *fontinfo; + XColor color, dummy; + XineramaScreenInfo *xsi; + GC gc; + fontinfo = XLoadQueryFont(dpy, font_name); + + if (fontinfo == NULL) { + if (count_error == 0) { + fprintf(stderr, "slock: Unable to load font \"%s\"\n", font_name); + fprintf(stderr, "slock: Try listing fonts with 'slock -f'\n"); + count_error++; + } + return; + } + + tab_size = 8 * XTextWidth(fontinfo, " ", 1); + + XAllocNamedColor(dpy, DefaultColormap(dpy, screen), + text_color, &color, &dummy); + + gr_values.font = fontinfo->fid; + gr_values.foreground = color.pixel; + gc=XCreateGC(dpy,win,GCFont+GCForeground, &gr_values); + + /* To prevent "Uninitialized" warnings. */ + xsi = NULL; + + /* + * Start formatting and drawing text + */ + + len = strlen(message); + + /* Max max line length (cut at '\n') */ + line_len = 0; + k = 0; + for (i = j = 0; i < len; i++) { + if (message[i] == '\n') { + if (i - j > line_len) + line_len = i - j; + k++; + i++; + j = i; + } + } + /* If there is only one line */ + if (line_len == 0) + line_len = len; + + if (XineramaIsActive(dpy)) { + xsi = XineramaQueryScreens(dpy, &i); + s_width = xsi[0].width; + s_height = xsi[0].height; + } else { + s_width = DisplayWidth(dpy, screen); + s_height = DisplayHeight(dpy, screen); + } + + height = s_height*3/7 - (k*20)/3; + width = (s_width - XTextWidth(fontinfo, message, line_len))/2; + + /* Look for '\n' and print the text between them. */ + for (i = j = k = 0; i <= len; i++) { + /* i == len is the special case for the last line */ + if (i == len || message[i] == '\n') { + tab_replace = 0; + while (message[j] == '\t' && j < i) { + tab_replace++; + j++; + } + + XDrawString(dpy, win, gc, width + tab_size*tab_replace, height + 20*k, message + j, i - j); + while (i < len && message[i] == '\n') { + i++; + j = i; + k++; + } + } + } + + /* xsi should not be NULL anyway if Xinerama is active, but to be safe */ + if (XineramaIsActive(dpy) && xsi != NULL) + XFree(xsi); +} + +float +getPriorBackLight(void) +{ + FILE *fp; + char path[1035]; + float bl = 100; + + fp = popen("/bin/xbacklight", "r"); + if (fp == NULL) + { + printf("Failed to run command\n"); + } + + while(fgets(path, sizeof(path), fp) != NULL) + { + bl = strtof(path, NULL); + } + + return bl; +} + +static const char * +gethash(void) +{ + const char *hash; + struct passwd *pw; + + /* Check if the current user has a password entry */ + errno = 0; + if (!(pw = getpwuid(getuid()))) { + if (errno) + die("slock: getpwuid: %s\n", strerror(errno)); + else + die("slock: cannot retrieve password entry\n"); + } + hash = pw->pw_passwd; + +#if HAVE_SHADOW_H + if (!strcmp(hash, "x")) { + struct spwd *sp; + if (!(sp = getspnam(pw->pw_name))) + die("slock: getspnam: cannot retrieve shadow entry. " + "Make sure to suid or sgid slock.\n"); + hash = sp->sp_pwdp; + } +#else + if (!strcmp(hash, "*")) { +#ifdef __OpenBSD__ + if (!(pw = getpwuid_shadow(getuid()))) + die("slock: getpwnam_shadow: cannot retrieve shadow entry. " + "Make sure to suid or sgid slock.\n"); + hash = pw->pw_passwd; +#else + die("slock: getpwuid: cannot retrieve shadow entry. " + "Make sure to suid or sgid slock.\n"); +#endif /* __OpenBSD__ */ + } +#endif /* HAVE_SHADOW_H */ + + return hash; +} + +static void +readpw(Display *dpy, struct xrandr *rr, struct lock **locks, int nscreens, + const char *hash) +{ + XRRScreenChangeNotifyEvent *rre; + char buf[32], passwd[256], *inputhash; + int num, screen, running, failure, oldc; + unsigned int len, color; + KeySym ksym; + XEvent ev; + + len = 0; + running = 1; + failure = 0; + oldc = INIT; + + while (running && !XNextEvent(dpy, &ev)) { + if (ev.type == KeyPress) { +#ifdef SCREENSLEEP + char* tmpSTR; + if(0 > asprintf(&tmpSTR, "xbacklight -set %f", priorBackLight)) tmpSTR = "xbacklight -set 100"; + system(tmpSTR); + free(tmpSTR); +#endif + explicit_bzero(&buf, sizeof(buf)); + 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'; + errno = 0; + if (!(inputhash = crypt(passwd, hash))) + fprintf(stderr, "slock: crypt: %s\n", strerror(errno)); + else + running = !!strcmp(inputhash, hash); + if (running) { + XBell(dpy, 100); + failure = 1; + } + explicit_bzero(&passwd, sizeof(passwd)); + len = 0; + break; + case XK_Escape: + explicit_bzero(&passwd, sizeof(passwd)); + len = 0; + break; + case XK_BackSpace: + if (len) + passwd[--len] = '\0'; + break; + default: + if (num && !iscntrl((int)buf[0]) && + (len + num < sizeof(passwd))) { + memcpy(passwd + len, buf, num); + len += num; + } + break; + } + color = len ? INPUT : ((failure || failonclear) ? FAILED : INIT); + if (running && oldc != color) { + for (screen = 0; screen < nscreens; screen++) { + if(locks[screen]->bgmap) + XSetWindowBackgroundPixmap(dpy, locks[screen]->win, locks[screen]->bgmap); + else + XSetWindowBackground(dpy, locks[screen]->win, locks[screen]->colors[0]); + XClearWindow(dpy, locks[screen]->win); + writemessage(dpy, locks[screen]->win, screen); + } + oldc = color; + } + } else if (rr->active && ev.type == rr->evbase + RRScreenChangeNotify) { + rre = (XRRScreenChangeNotifyEvent*)&ev; + for (screen = 0; screen < nscreens; screen++) { + if (locks[screen]->win == rre->window) { + if (rre->rotation == RR_Rotate_90 || + rre->rotation == RR_Rotate_270) + XResizeWindow(dpy, locks[screen]->win, + rre->height, rre->width); + else + XResizeWindow(dpy, locks[screen]->win, + rre->width, rre->height); + XClearWindow(dpy, locks[screen]->win); + break; + } + } + } else { + for (screen = 0; screen < nscreens; screen++) + XRaiseWindow(dpy, locks[screen]->win); + } + } +} + +static struct lock * +lockscreen(Display *dpy, struct xrandr *rr, int screen) +{ + char curs[] = {0, 0, 0, 0, 0, 0, 0, 0}; + int i, ptgrab, kbgrab; + struct lock *lock; + XColor color, dummy; + XSetWindowAttributes wa; + Cursor invisible; + + if (dpy == NULL || screen < 0 || !(lock = malloc(sizeof(struct lock)))) + return NULL; + + lock->screen = screen; + lock->root = RootWindow(dpy, lock->screen); + + if(image) + { + lock->bgmap = XCreatePixmap(dpy, lock->root, DisplayWidth(dpy, lock->screen), DisplayHeight(dpy, lock->screen), DefaultDepth(dpy, lock->screen)); + imlib_context_set_image(image); + imlib_context_set_display(dpy); + imlib_context_set_visual(DefaultVisual(dpy, lock->screen)); + imlib_context_set_colormap(DefaultColormap(dpy, lock->screen)); + imlib_context_set_drawable(lock->bgmap); + imlib_render_image_on_drawable(0, 0); + imlib_free_image(); + } + for (i = 0; i < NUMCOLS; i++) { + XAllocNamedColor(dpy, DefaultColormap(dpy, lock->screen), + colorname[i], &color, &dummy); + lock->colors[i] = color.pixel; + } + + /* init */ + wa.override_redirect = 1; + wa.background_pixel = lock->colors[INIT]; + lock->win = XCreateWindow(dpy, lock->root, 0, 0, + DisplayWidth(dpy, lock->screen), + DisplayHeight(dpy, lock->screen), + 0, DefaultDepth(dpy, lock->screen), + CopyFromParent, + DefaultVisual(dpy, lock->screen), + CWOverrideRedirect | CWBackPixel, &wa); + if(lock->bgmap) + XSetWindowBackgroundPixmap(dpy, lock->win, lock->bgmap); + lock->pmap = XCreateBitmapFromData(dpy, lock->win, curs, 8, 8); + invisible = XCreatePixmapCursor(dpy, lock->pmap, lock->pmap, + &color, &color, 0, 0); + XDefineCursor(dpy, lock->win, invisible); + + /* Try to grab mouse pointer *and* keyboard for 600ms, else fail the lock */ + for (i = 0, ptgrab = kbgrab = -1; i < 6; i++) { + if (ptgrab != GrabSuccess) { + ptgrab = XGrabPointer(dpy, lock->root, False, + ButtonPressMask | ButtonReleaseMask | + PointerMotionMask, GrabModeAsync, + GrabModeAsync, None, invisible, CurrentTime); + } + if (kbgrab != GrabSuccess) { + kbgrab = XGrabKeyboard(dpy, lock->root, True, + GrabModeAsync, GrabModeAsync, CurrentTime); + } + + /* input is grabbed: we can lock the screen */ + if (ptgrab == GrabSuccess && kbgrab == GrabSuccess) { + XMapRaised(dpy, lock->win); + if (rr->active) + XRRSelectInput(dpy, lock->win, RRScreenChangeNotifyMask); + + XSelectInput(dpy, lock->root, SubstructureNotifyMask); + return lock; + } + + /* retry on AlreadyGrabbed but fail on other errors */ + if ((ptgrab != AlreadyGrabbed && ptgrab != GrabSuccess) || + (kbgrab != AlreadyGrabbed && kbgrab != GrabSuccess)) + break; + + usleep(100000); + } + + /* we couldn't grab all input: fail out */ + if (ptgrab != GrabSuccess) + fprintf(stderr, "slock: unable to grab mouse pointer for screen %d\n", + screen); + if (kbgrab != GrabSuccess) + fprintf(stderr, "slock: unable to grab keyboard for screen %d\n", + screen); + return NULL; +} + +static void +usage(void) +{ + die("usage: slock [-v] [-f] [-m message] [cmd [arg ...]]\n"); +} + +int +main(int argc, char **argv) { + struct xrandr rr; + struct lock **locks; + struct passwd *pwd; + struct group *grp; + uid_t duid; + gid_t dgid; + const char *hash; + Display *dpy; + int i, s, nlocks, nscreens; + int count_fonts; + char **font_names; + + ARGBEGIN { + case 'v': + fprintf(stderr, "slock-"VERSION"\n"); + return 0; + case 'm': + message = EARGF(usage()); + break; + case 'f': + if (!(dpy = XOpenDisplay(NULL))) + die("slock: cannot open display\n"); + font_names = XListFonts(dpy, "*", 10000 /* list 10000 fonts*/, &count_fonts); + for (i=0; ipw_uid; + errno = 0; + if (!(grp = getgrnam(group))) + die("slock: getgrnam %s: %s\n", group, + errno ? strerror(errno) : "group entry not found"); + dgid = grp->gr_gid; + +#ifdef __linux__ + dontkillme(); +#endif + + hash = gethash(); + errno = 0; + if (!crypt("", hash)) + die("slock: crypt: %s\n", strerror(errno)); + + if (!(dpy = XOpenDisplay(NULL))) + die("slock: cannot open display\n"); + + /* drop privileges */ + if (setgroups(0, NULL) < 0) + die("slock: setgroups: %s\n", strerror(errno)); + if (setgid(dgid) < 0) + die("slock: setgid: %s\n", strerror(errno)); + if (setuid(duid) < 0) + die("slock: setuid: %s\n", strerror(errno)); + + /*Create screenshot Image*/ + Screen *scr = ScreenOfDisplay(dpy, DefaultScreen(dpy)); + image = imlib_create_image(scr->width,scr->height); + imlib_context_set_image(image); + imlib_context_set_display(dpy); + imlib_context_set_visual(DefaultVisual(dpy,0)); + imlib_context_set_drawable(RootWindow(dpy,XScreenNumberOfScreen(scr))); + imlib_copy_drawable_to_image(0,0,0,scr->width,scr->height,0,0,1); + +#ifdef BLUR + + /*Blur function*/ + imlib_image_blur(blurRadius); +#endif // BLUR + +#ifdef PIXELATION + /*Pixelation*/ + int width = scr->width; + int height = scr->height; + + for(int y = 0; y < height; y += pixelSize) + { + for(int x = 0; x < width; x += pixelSize) + { + int red = 0; + int green = 0; + int blue = 0; + + Imlib_Color pixel; + Imlib_Color* pp; + pp = &pixel; + for(int j = 0; j < pixelSize && j < height; j++) + { + for(int i = 0; i < pixelSize && i < width; i++) + { + imlib_image_query_pixel(x+i,y+j,pp); + red += pixel.red; + green += pixel.green; + blue += pixel.blue; + } + } + red /= (pixelSize*pixelSize); + green /= (pixelSize*pixelSize); + blue /= (pixelSize*pixelSize); + imlib_context_set_color(red,green,blue,pixel.alpha); + imlib_image_fill_rectangle(x,y,pixelSize,pixelSize); + red = 0; + green = 0; + blue = 0; + } + } + + +#endif + +#ifdef SCREENSLEEP + priorBackLight = getPriorBackLight(); + system("xbacklight -set 0"); +#endif + + /* check for Xrandr support */ + rr.active = XRRQueryExtension(dpy, &rr.evbase, &rr.errbase); + + /* get number of screens in display "dpy" and blank them */ + nscreens = ScreenCount(dpy); + if (!(locks = calloc(nscreens, sizeof(struct lock *)))) + die("slock: out of memory\n"); + for (nlocks = 0, s = 0; s < nscreens; s++) { + if ((locks[s] = lockscreen(dpy, &rr, s)) != NULL) { + writemessage(dpy, locks[s]->win, s); + nlocks++; + } else { + break; + } + } + XSync(dpy, 0); + + /* did we manage to lock everything? */ + if (nlocks != nscreens) + return 1; + + /* run post-lock command */ + if (argc > 0) { + switch (fork()) { + case -1: + die("slock: fork failed: %s\n", strerror(errno)); + case 0: + if (close(ConnectionNumber(dpy)) < 0) + die("slock: close: %s\n", strerror(errno)); + execvp(argv[0], argv); + fprintf(stderr, "slock: execvp %s: %s\n", argv[0], strerror(errno)); + _exit(1); + } + } + + /* everything is now blank. Wait for the correct password */ + readpw(dpy, &rr, locks, nscreens, hash); + + return 0; +} +/* See LICENSE file for license details. */ +#define _XOPEN_SOURCE 500 +#if HAVE_SHADOW_H +#include +#endif diff --git a/slock.o b/slock.o new file mode 100644 index 0000000000000000000000000000000000000000..b81848a3d2a71081c7a4161b42c3933602bf1768 GIT binary patch literal 19664 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 literal 0 HcmV?d00001 diff --git a/util.h b/util.h new file mode 100644 index 0000000..6f748b8 --- /dev/null +++ b/util.h @@ -0,0 +1,2 @@ +#undef explicit_bzero +void explicit_bzero(void *, size_t);