diff --git a/.codespellrc b/.codespellrc index a8f0594..9122e4a 100644 --- a/.codespellrc +++ b/.codespellrc @@ -1,2 +1,2 @@ [codespell] -skip = ./assets/pkg/aur/*/src +skip = ./assets/pkg/aur/*/src,./assets/pkg/aur/*/*/objects diff --git a/README.md b/README.md index 07e2a93..5042d5b 100644 --- a/README.md +++ b/README.md @@ -123,3 +123,9 @@ The name is just ly but changing "y" with "i", that had a reason but forgot it, * cerealexperiments\_, found a missing newline (had the guts to read the source code, crazy ik) * ChatGPT, in times of slow laptops where pages take ages to load, a single tab connected to a bunch of burning cloud GPUs feeding corporate hype is all you need to get quick answers for your questions, as long as you know how to filter AI crap ofc. * [My lack of gf](https://www.instagram.com/reel/C8sa3Gltmtq), can't imagine this project being possible if somebody actually cared about me daily. + +--- + +🌟 Finally, consider starring this repo or... 🔪 + +![star-history](https://api.star-history.com/svg?repos=javalsai/lidm&type=Date) diff --git a/assets/man/lidm-config.5 b/assets/man/lidm-config.5 index 9fbb66a..6641924 100644 --- a/assets/man/lidm-config.5 +++ b/assets/man/lidm-config.5 @@ -73,6 +73,12 @@ Text to display as the header for such sessions. .TP \fBbehavior.include_defshell\fP "true"/"false" (invalid input defaults to false), if true, includes the user default shell as a session to launch +.TP +\fBbehavior.source\fP +Specify paths to source on login, simple KEY=VALUE format with comments (#) or empty'ish lines, quoting or escape sequences not supported yet. It is NOT an array, but you rather assign to it multiple times. +.TP +\fBbehavior.user_source\fP +Same as \fIbehavior.source\fP but relative to user home (if present). .SH "SEE ALSO" diff --git a/include/auth.h b/include/auth.h index d0d075a..b456227 100644 --- a/include/auth.h +++ b/include/auth.h @@ -3,8 +3,9 @@ #include -#include +#include "config.h" +#include "sessions.h" -bool launch(char *user, char *passwd, struct session session, void (*cb)(void)); +bool launch(char *user, char *passwd, struct session session, void (*cb)(void), struct behavior* behavior); #endif diff --git a/include/config.h b/include/config.h index 833fb46..a9fa05d 100644 --- a/include/config.h +++ b/include/config.h @@ -4,9 +4,8 @@ #include #include -#include -#include -#include +#include "keys.h" +#include "util.h" // should be ansi escape codes under \x1b[...m // if not prepared accordingly, it might break @@ -63,6 +62,8 @@ struct strings { struct behavior { bool include_defshell; + struct Vector source; + struct Vector user_source; }; struct config { diff --git a/include/sessions.h b/include/sessions.h index 1019410..c632a88 100644 --- a/include/sessions.h +++ b/include/sessions.h @@ -3,7 +3,7 @@ #include -#include +#include "util.h" enum session_type { XORG, diff --git a/include/ui.h b/include/ui.h index c6bb884..023a947 100644 --- a/include/ui.h +++ b/include/ui.h @@ -1,8 +1,8 @@ #ifndef _UIH_ #define _UIH_ -#include -#include +#include "config.h" +#include "util.h" void setup(struct config); int load(struct Vector * users, struct Vector * sessions); diff --git a/include/users.h b/include/users.h index 60fac69..8344833 100644 --- a/include/users.h +++ b/include/users.h @@ -3,7 +3,7 @@ #include -#include +#include "util.h" struct user { char *shell; diff --git a/include/util.h b/include/util.h index be9bdce..96b1a5a 100644 --- a/include/util.h +++ b/include/util.h @@ -1,11 +1,13 @@ #ifndef _UTILH_ #define _UTILH_ -#include #include #include +#include #include +#include "keys.h" + enum keys find_keyname(char *); enum keys find_ansi(char *); void read_press(u_char *, char *); @@ -24,6 +26,6 @@ void vec_free(struct Vector*); void vec_clear(struct Vector*); void vec_reset(struct Vector*); void* vec_pop(struct Vector*); // won't free it, nor shrink vec list space -void* vec_get(struct Vector*, uint32_t index); +void* vec_get(struct Vector*, size_t index); #endif diff --git a/src/auth.c b/src/auth.c index 4038c72..e041a89 100644 --- a/src/auth.c +++ b/src/auth.c @@ -1,22 +1,25 @@ #include #include #include +#include #include #include +#include #include #include -#include -#include -#include -#include -#include +#include "auth.h" +#include "config.h" +#include "sessions.h" +#include "ui.h" +#include "unistd.h" +#include "util.h" int pam_conversation(int num_msg, const struct pam_message **msg, struct pam_response **resp, void *appdata_ptr) { struct pam_response *reply = (struct pam_response *)malloc(sizeof(struct pam_response) * num_msg); - for (int i = 0; i < num_msg; i++) { + for (size_t i = 0; i < num_msg; i++) { reply[i].resp = NULL; reply[i].resp_retcode = 0; if (msg[i]->msg_style == PAM_PROMPT_ECHO_OFF || @@ -59,7 +62,40 @@ void *shmalloc(size_t size) { -1, 0); } -void moarEnv(char *user, struct session session, struct passwd *pw) { +void sourceFileTry(char *file) { + FILE *file2source = fopen(file, "r"); + if (file2source == NULL) + return; + + char *line = NULL; + size_t len = 0; + ssize_t read; + + while ((read = getline(&line, &len, file2source)) != -1) { + if (read == 0 || (read > 0 && *line == '#')) + continue; + if (line[read - 1] == '\n') + line[read - 1] = '\0'; + + /* printf("Retrieved line of length %zu:\n", read); */ + /* printf("%s\n", line); */ + for (size_t i = 1; i < read; i++) { + if (line[i] == '=') { + /* printf("FOUND '='!\n"); */ + line[i] = '\0'; + setenv(line, &line[i + 1], 1); + break; + } + } + } + + if (line) + free(line); + fclose(file2source); +} + +void moarEnv(char *user, struct session session, struct passwd *pw, + struct behavior *behavior) { if (chdir(pw->pw_dir) == -1) print_errno("can't chdir to user home"); @@ -81,6 +117,31 @@ void moarEnv(char *user, struct session session, struct passwd *pw) { xdg_session_type = "wayland"; setenv("XDG_SESSION_TYPE", xdg_session_type, true); + printf("\n\n\n\n\x1b[1m"); + for (size_t i = 0; i < behavior->source.length; i++) { + /* printf("DEBUG(source)!!!! %d %s\n", i, (char*)vec_get(&behavior->source, + * i)); */ + sourceFileTry((char *)vec_get(&behavior->source, i)); + } + /* printf("\n"); */ + if (pw->pw_dir) { + uint home_len = strlen(pw->pw_dir); + for (size_t i = 0; i < behavior->user_source.length; i++) { + char *file2sourcepath = (char *)vec_get(&behavior->user_source, i); + char *newbuf = + malloc(home_len + strlen(file2sourcepath) + 2); // nullbyte and slash + if (newbuf == NULL) + continue; // can't bother + strcpy(newbuf, pw->pw_dir); + newbuf[home_len] = '/'; // assume pw_dir doesn't start with '/' :P + strcpy(&newbuf[home_len + 1], file2sourcepath); + + /* printf("DEBUG(user_source)!!!! %d %s\n", i, newbuf); */ + sourceFileTry(newbuf); + free(newbuf); + } + } + /*char *buf;*/ /*size_t bsize = snprintf(NULL, 0, "/run/user/%d", pw->pw_uid) + 1;*/ /*buf = malloc(bsize);*/ @@ -92,8 +153,8 @@ void moarEnv(char *user, struct session session, struct passwd *pw) { /*setenv("XDG_SEAT", "seat0", true);*/ } -bool launch(char *user, char *passwd, struct session session, - void (*cb)(void)) { +bool launch(char *user, char *passwd, struct session session, void (*cb)(void), + struct behavior *behavior) { struct passwd *pw = getpwnam(user); if (pw == NULL) { print_err("could not get user info"); @@ -129,7 +190,7 @@ bool launch(char *user, char *passwd, struct session session, print_errno("pam_getenvlist"); _exit(EXIT_FAILURE); } - for (uint i = 0; envlist[i] != NULL; i++) { + for (size_t i = 0; envlist[i] != NULL; i++) { putenv(envlist[i]); } // FIXME: path hotfix @@ -140,7 +201,7 @@ bool launch(char *user, char *passwd, struct session session, } free(envlist); - moarEnv(user, session, pw); + moarEnv(user, session, pw, behavior); // TODO: chown stdin to user // does it inherit stdin from parent and @@ -168,11 +229,14 @@ bool launch(char *user, char *passwd, struct session session, // TODO: these will be different due to TryExec // and, Exec/TryExec might contain spaces as args + printf("\x1b[0m"); if (session.type == SHELL) { clear_screen(); + fflush(stdout); execlp(session.exec, session.exec, NULL); } else if (session.type == XORG || session.type == WAYLAND) { clear_screen(); + fflush(stdout); execlp(session.exec, session.exec, NULL); } perror("execl error"); diff --git a/src/chvt.c b/src/chvt.c index 8445ca7..34b9346 100644 --- a/src/chvt.c +++ b/src/chvt.c @@ -3,7 +3,7 @@ #include #include -#include +#include "chvt.h" static char *vterms[] = {"/dev/tty", "/dev/tty0", "/dev/vc/0", "/dev/systty", "/dev/console"}; @@ -26,7 +26,7 @@ int chvt_str(char *str) { int chvt(int n) { fprintf(stderr, "activating vt %d\n", n); char c = 0; - for (int i = 0; i < sizeof(vterms) / sizeof(vterms[0]); i++) { + for (size_t i = 0; i < sizeof(vterms) / sizeof(vterms[0]); i++) { int fd = open(vterms[i], O_RDWR); if (fd >= 0 && isatty(fd) && ioctl(fd, KDGKBTYPE, &c) == 0 && c < 3) { if (ioctl(fd, VT_ACTIVATE, n) < 0 || ioctl(fd, VT_WAITACTIVE, n) < 0) { diff --git a/src/config.c b/src/config.c index c0788df..fed2461 100644 --- a/src/config.c +++ b/src/config.c @@ -1,8 +1,8 @@ -#include "util.h" #include #include -#include +#include "config.h" +#include "util.h" bool line_parser(FILE *fd, ssize_t *blksize, u_char (*cb)(char *key, char *value)) { @@ -109,6 +109,10 @@ u_char config_line_handler(char *k, char *v) { __config->strings.s_shell = v; else if (strcmp(k, "behavior.include_defshell") == 0) __config->behavior.include_defshell = strcmp(v, "true") == 0; + else if (strcmp(k, "behavior.source") == 0) + vec_push(&__config->behavior.source, v); + else if (strcmp(k, "behavior.user_source") == 0) + vec_push(&__config->behavior.user_source, v); else return 0b1111; @@ -124,6 +128,9 @@ struct config *parse_config(char *path) { } __config = malloc(sizeof(struct config)); + __config->behavior.source = vec_new(); + __config->behavior.user_source = vec_new(); + if (__config == NULL) return NULL; bool ret = line_parser(fd, (ssize_t *)&sb.st_blksize, config_line_handler); diff --git a/src/efield.c b/src/efield.c index daa798c..c76b2e7 100644 --- a/src/efield.c +++ b/src/efield.c @@ -1,7 +1,7 @@ #include -#include -#include +#include "efield.h" +#include "ui.h" struct editable_field field_new(char *content) { struct editable_field __efield; diff --git a/src/main.c b/src/main.c index a5f0425..dec1037 100644 --- a/src/main.c +++ b/src/main.c @@ -4,12 +4,12 @@ #include #include -#include -#include -#include -#include -#include -#include +#include "chvt.h" +#include "config.h" +#include "sessions.h" +#include "ui.h" +#include "users.h" +#include "util.h" int main(int argc, char *argv[]) { if (argc == 2) diff --git a/src/sessions.c b/src/sessions.c index 8ea36b9..c0ebbea 100644 --- a/src/sessions.c +++ b/src/sessions.c @@ -7,8 +7,8 @@ #include #include -#include -#include +#include "sessions.h" +#include "util.h" struct source_dir { enum session_type type; @@ -110,7 +110,7 @@ struct Vector get_avaliable_sessions() { struct Vector sessions = vec_new(); cb_sessions = &sessions; - for (uint i = 0; i < (sizeof(sources) / sizeof(sources[0])); i++) { + for (size_t i = 0; i < (sizeof(sources) / sizeof(sources[0])); i++) { /*printf("recurring into %s\n", sources[i].dir);*/ session_type = sources[i].type; ftw(sources[i].dir, &fn, 1); diff --git a/src/ui.c b/src/ui.c index f6bcdff..f711554 100644 --- a/src/ui.c +++ b/src/ui.c @@ -10,17 +10,19 @@ #include #include #include +#include #include #include #include #include -#include -#include -#include -#include -#include -#include +#include "auth.h" +#include "efield.h" +#include "keys.h" +#include "sessions.h" +#include "ui.h" +#include "users.h" +#include "util.h" static void print_box(); static void print_footer(); @@ -394,7 +396,7 @@ int load(struct Vector *users, struct Vector *sessions) { } else { if (len == 1 && *seq == '\n') { if (!launch(get_current_user().username, of_passwd.efield.content, - get_current_session(), &restore_all)) { + get_current_session(), &restore_all, &behavior)) { print_passwd(box_start(), of_passwd.efield.length, true); ffield_cursor_focus(); } @@ -498,15 +500,15 @@ static void print_passwd(struct uint_point origin, uint length, bool err) { } static void print_empty_row(uint w, uint n, char *edge1, char *edge2) { - for (uint i = 0; i < n; i++) { + for (size_t i = 0; i < n; i++) { printf("%s\x1b[%dC%s\x1b[%dD\x1b[1B", edge1, w, edge2, w + 2); } } static void print_row(uint w, uint n, char *edge1, char *edge2, char *filler) { - for (uint i = 0; i < n; i++) { + for (size_t i = 0; i < n; i++) { printf("%s", edge1); - for (uint i = 0; i < w; i++) { + for (size_t i = 0; i < w; i++) { printf("%s", filler); } printf("%s\x1b[%dD\x1b[1B", edge2, w + 2); diff --git a/src/users.c b/src/users.c index e86bff5..67049a8 100644 --- a/src/users.c +++ b/src/users.c @@ -5,8 +5,8 @@ #include #include -#include -#include +#include "users.h" +#include "util.h" static struct user __new_user(struct passwd *p) { struct user __user; diff --git a/src/util.c b/src/util.c index 877ddd7..50a88a0 100644 --- a/src/util.c +++ b/src/util.c @@ -5,9 +5,9 @@ #include #include -#include -#include -#include +#include "keys.h" +#include "ui.h" +#include "util.h" static int selret_magic(); @@ -119,7 +119,7 @@ void* vec_pop(struct Vector* vec) { return vec->pages[--vec->length]; } -void* vec_get(struct Vector* vec, uint32_t index) { +void* vec_get(struct Vector* vec, size_t index) { if (index >= vec->length) return NULL; diff --git a/themes/cherry.ini b/themes/cherry.ini index b2b1bc0..4d014c3 100644 --- a/themes/cherry.ini +++ b/themes/cherry.ini @@ -30,3 +30,6 @@ strings.s_wayland = wayland strings.s_xorg = xorg strings.s_shell = shell behavior.include_defshell = true +behavior.source = /etc/lidm.env +behavior.source = /etc/locale.conf +behavior.user_source = .lidm.env diff --git a/themes/default.ini b/themes/default.ini index f9b59d2..ff4727d 100644 --- a/themes/default.ini +++ b/themes/default.ini @@ -30,3 +30,6 @@ strings.s_wayland = wayland strings.s_xorg = xorg strings.s_shell = shell behavior.include_defshell = true +behavior.source = /etc/lidm.env +behavior.source = /etc/locale.conf +behavior.user_source = .lidm.env diff --git a/themes/kanagawa-dragon.ini b/themes/kanagawa-dragon.ini index 30ca105..8dfb715 100644 --- a/themes/kanagawa-dragon.ini +++ b/themes/kanagawa-dragon.ini @@ -30,3 +30,6 @@ strings.s_wayland = wayland strings.s_xorg = xorg strings.s_shell = shell behavior.include_defshell = true +behavior.source = /etc/lidm.env +behavior.source = /etc/locale.conf +behavior.user_source = .lidm.env diff --git a/themes/kanagawa-wave.ini b/themes/kanagawa-wave.ini index 5b01c11..93368e1 100644 --- a/themes/kanagawa-wave.ini +++ b/themes/kanagawa-wave.ini @@ -30,3 +30,6 @@ strings.s_wayland = wayland strings.s_xorg = xorg strings.s_shell = shell behavior.include_defshell = true +behavior.source = /etc/lidm.env +behavior.source = /etc/locale.conf +behavior.user_source = .lidm.env diff --git a/themes/nature.ini b/themes/nature.ini index 199dd6c..7e6ee04 100644 --- a/themes/nature.ini +++ b/themes/nature.ini @@ -30,3 +30,6 @@ strings.s_wayland = wayland strings.s_xorg = xorg strings.s_shell = shell behavior.include_defshell = true +behavior.source = /etc/lidm.env +behavior.source = /etc/locale.conf +behavior.user_source = .lidm.env diff --git a/themes/nord.ini b/themes/nord.ini index 16c7073..07d832e 100644 --- a/themes/nord.ini +++ b/themes/nord.ini @@ -30,3 +30,6 @@ strings.s_wayland = wayland strings.s_xorg = xorg strings.s_shell = shell behavior.include_defshell = true +behavior.source = /etc/lidm.env +behavior.source = /etc/locale.conf +behavior.user_source = .lidm.env diff --git a/themes/nothing.ini b/themes/nothing.ini index eac12ee..ade26d6 100644 --- a/themes/nothing.ini +++ b/themes/nothing.ini @@ -30,3 +30,6 @@ strings.s_wayland = wayland strings.s_xorg = xorg strings.s_shell = shell behavior.include_defshell = true +behavior.source = /etc/lidm.env +behavior.source = /etc/locale.conf +behavior.user_source = .lidm.env diff --git a/themes/old-blue.ini b/themes/old-blue.ini index 96fabe3..9ac2e88 100644 --- a/themes/old-blue.ini +++ b/themes/old-blue.ini @@ -30,3 +30,6 @@ strings.s_wayland = waywand strings.s_xorg = xworg strings.s_shell = swell behavior.include_defshell = true +behavior.source = /etc/lidm.env +behavior.source = /etc/locale.conf +behavior.user_source = .lidm.env diff --git a/themes/tasteless.ini b/themes/tasteless.ini index ea50656..f56617a 100644 --- a/themes/tasteless.ini +++ b/themes/tasteless.ini @@ -30,3 +30,6 @@ strings.s_wayland = wayland strings.s_xorg = xorg strings.s_shell = shell behavior.include_defshell = true +behavior.source = /etc/lidm.env +behavior.source = /etc/locale.conf +behavior.user_source = .lidm.env