diff options
| author | auric <104602845+ihateamongus@users.noreply.github.com> | 2025-09-08 23:44:06 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-09-08 23:44:06 -0500 |
| commit | 8f03aa9417b06d91182e7adc2e0b8c53e7cf6069 (patch) | |
| tree | bdc85f947d51e5d5243a0544181738fcf7ec3903 /core/slogin/slogin.c | |
| parent | 278f3e9054cf5d7b02e995a69653504242956874 (diff) | |
| parent | 85d91a056004d8dbe5016ba35bc670ad1b75c8b1 (diff) | |
Merge pull request #23 from ihateamongus/codex/create-suckless-style-x11-login-manager
Refactor slogin for framebuffer OpenRC login
Diffstat (limited to 'core/slogin/slogin.c')
| -rw-r--r-- | core/slogin/slogin.c | 186 |
1 files changed, 77 insertions, 109 deletions
diff --git a/core/slogin/slogin.c b/core/slogin/slogin.c index 24a534b..1978d71 100644 --- a/core/slogin/slogin.c +++ b/core/slogin/slogin.c @@ -1,8 +1,5 @@ /* See LICENSE file for license details. */ #define _XOPEN_SOURCE 700 -#include <X11/Xlib.h> -#include <X11/Xft/Xft.h> -#include <X11/keysym.h> #include <unistd.h> #include <pwd.h> #include <grp.h> @@ -12,6 +9,8 @@ #include <stdio.h> #include <string.h> #include <stdarg.h> +#include <termios.h> +#include <sys/wait.h> #include "../accent.h" #include "config.h" @@ -36,6 +35,29 @@ updateaccent(void) memcpy(accentcol, "#005577", 8); } +static void +parseaccent(int *r, int *g, int *b) +{ + unsigned int ri, gi, bi; + if (sscanf(accentcol + 1, "%02x%02x%02x", &ri, &gi, &bi) == 3) { + *r = ri; + *g = gi; + *b = bi; + } else { + *r = 0x00; + *g = 0x55; + *b = 0x77; + } +} + +static void +colored(const char *msg) +{ + int r, g, b; + parseaccent(&r, &g, &b); + printf("\033[38;2;%d;%d;%dm%s\033[0m", r, g, b, msg); +} + static const char * gethash(const char *user) { @@ -68,126 +90,72 @@ auth(const char *user, const char *pass) } static void -runsession(const char *user, const char *pass) +readinput(char *buf, size_t len) { - struct passwd *pw; - if (!auth(user, pass)) - return; - if (!(pw = getpwnam(user))) - return; - if (initgroups(user, pw->pw_gid) < 0) - die("slogin: initgroups failed\n"); - if (setgid(pw->pw_gid) < 0) - die("slogin: setgid failed\n"); - if (setuid(pw->pw_uid) < 0) - die("slogin: setuid failed\n"); - setenv("HOME", pw->pw_dir, 1); - chdir(pw->pw_dir); - setsid(); - execvp(logincmd[0], (char *const *)logincmd); - die("slogin: exec failed\n"); + if (!fgets(buf, len, stdin)) + buf[0] = '\0'; + buf[strcspn(buf, "\n")] = '\0'; } static void -drawscreen(Display *dpy, Window win, XftDraw *draw, XftFont *font, - XftColor *fg, XftColor *accent, - const char *user, const char *pass, int stage) +readpass(char *buf, size_t len) { - char buf[256]; - int width = DisplayWidth(dpy, DefaultScreen(dpy)); - int height = DisplayHeight(dpy, DefaultScreen(dpy)); - int w = 400, h = 100; - int x = (width - w)/2; - int y = (height - h)/2; - GC gc = DefaultGC(dpy, DefaultScreen(dpy)); - - XClearWindow(dpy, win); - XSetForeground(dpy, gc, accent->pixel); - XDrawRectangle(dpy, win, gc, x, y, w, h); + struct termios old, new; + tcgetattr(STDIN_FILENO, &old); + new = old; + new.c_lflag &= ~(ECHO); + tcsetattr(STDIN_FILENO, TCSAFLUSH, &new); + readinput(buf, len); + tcsetattr(STDIN_FILENO, TCSAFLUSH, &old); +} - if (stage == 0) - snprintf(buf, sizeof buf, "login: %s", user); - else { - char stars[sizeof buf]; - size_t i, len = strlen(pass); - for (i = 0; i < len && i < sizeof stars - 1; i++) - stars[i] = '*'; - stars[i] = '\0'; - snprintf(buf, sizeof buf, "password: %s", stars); +static void +runsession(const char *user) +{ + struct passwd *pw; + pid_t pid; + if (!(pw = getpwnam(user))) + return; + if ((pid = fork()) == 0) { + if (initgroups(user, pw->pw_gid) < 0) + die("slogin: initgroups failed\n"); + if (setgid(pw->pw_gid) < 0) + die("slogin: setgid failed\n"); + if (setuid(pw->pw_uid) < 0) + die("slogin: setuid failed\n"); + setenv("HOME", pw->pw_dir, 1); + if (chdir(pw->pw_dir) < 0) + die("slogin: chdir failed\n"); + execvp(logincmd[0], (char *const *)logincmd); + _exit(1); } - XftDrawStringUtf8(draw, fg, font, x + 20, y + h/2 + font->ascent/2, - (XftChar8 *)buf, strlen(buf)); - XFlush(dpy); + waitpid(pid, NULL, 0); } int main(void) { - Display *dpy; - int scr; - Window root, win; - XEvent ev; - XftDraw *xdraw; - XftFont *font; - XftColor xfg, xbg, xaccent; - char user[64] = "", pass[64] = ""; - int stage = 0; - KeySym ksym; - char buf[32]; - int len; - - updateaccent(); - if (!(dpy = XOpenDisplay(NULL))) - die("slogin: cannot open display\n"); - scr = DefaultScreen(dpy); - root = RootWindow(dpy, scr); - win = XCreateSimpleWindow(dpy, root, 0, 0, - DisplayWidth(dpy, scr), DisplayHeight(dpy, scr), - 0, BlackPixel(dpy, scr), BlackPixel(dpy, scr)); - XSelectInput(dpy, win, KeyPressMask | ExposureMask); - XMapRaised(dpy, win); - - font = XftFontOpenName(dpy, scr, fontname); - if (!font) - die("slogin: cannot load font\n"); - xdraw = XftDrawCreate(dpy, win, DefaultVisual(dpy, scr), DefaultColormap(dpy, scr)); - XftColorAllocName(dpy, DefaultVisual(dpy, scr), DefaultColormap(dpy, scr), fgcolor, &xfg); - XftColorAllocName(dpy, DefaultVisual(dpy, scr), DefaultColormap(dpy, scr), bgcolor, &xbg); - XftColorAllocName(dpy, DefaultVisual(dpy, scr), DefaultColormap(dpy, scr), accentcol, &xaccent); - XSetWindowBackground(dpy, win, xbg.pixel); - XClearWindow(dpy, win); + char user[64]; + char pass[64]; for (;;) { - XNextEvent(dpy, &ev); - if (ev.type == Expose) { - drawscreen(dpy, win, xdraw, font, &xfg, &xaccent, - user, pass, stage); - } else if (ev.type == KeyPress) { - len = XLookupString(&ev.xkey, buf, sizeof buf, &ksym, NULL); - if (ksym == XK_Return) { - if (stage == 0) - stage = 1; - else { - runsession(user, pass); - stage = 0; - user[0] = pass[0] = '\0'; - } - } else if (ksym == XK_BackSpace) { - if (stage == 0 && strlen(user) > 0) - user[strlen(user)-1] = '\0'; - else if (stage == 1 && strlen(pass) > 0) - pass[strlen(pass)-1] = '\0'; - } else if (len && buf[0] >= ' ' && buf[0] <= '~') { - if (stage == 0 && strlen(user) + len < sizeof user) { - strncat(user, buf, len); - user[strlen(user)] = '\0'; - } else if (stage == 1 && strlen(pass) + len < sizeof pass) { - strncat(pass, buf, len); - pass[strlen(pass)] = '\0'; - } - } - drawscreen(dpy, win, xdraw, font, &xfg, &xaccent, - user, pass, stage); + updateaccent(); + printf("\033[2J\033[H"); + colored("login: "); + fflush(stdout); + readinput(user, sizeof user); + colored("password: "); + fflush(stdout); + readpass(pass, sizeof pass); + printf("\n"); + if (auth(user, pass)) { + memset(pass, 0, sizeof pass); + runsession(user); + } else { + colored("Login incorrect\n"); + memset(pass, 0, sizeof pass); + sleep(2); } } + return 0; } |
