From 54efe25a241ed4e9196d637fbd63c95a09708c4d Mon Sep 17 00:00:00 2001 From: NishiOwO Date: Mon, 17 Nov 2025 18:17:33 +0900 Subject: [PATCH] functional --- mdm/login.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++--- mdm/main.c | 39 ++++++++++++++++++++++++++----- mdm/mdm.h | 8 ++++++- mdm/xserver.c | 28 +++++++++++++++------- 4 files changed, 121 insertions(+), 18 deletions(-) diff --git a/mdm/login.c b/mdm/login.c index ae82750..0663f38 100644 --- a/mdm/login.c +++ b/mdm/login.c @@ -1,14 +1,52 @@ #include "mdm.h" +#include #include +#include MwWidget root; -MwWidget window, usercombo, passentry; +MwWidget window, sesscombo, usercombo, passentry; + +typedef struct session { + char* key; + char* value; +} session_t; + +session_t* sessions = NULL; +char* name_line; +char* exec_line; static void add_user(const char* name, void* user){ MwComboBoxAdd(user, -1, name); } +static int dumper(void* user, const char* section, const char* name, const char* value){ + if(strcmp(section, "Desktop Entry") != 0) return 1; + + if(strcmp(name, "Name") == 0){ + MwComboBoxAdd(user, -1, value); + + name_line = MDEStringDuplicate(value); + }else if(strcmp(name, "Exec") == 0){ + exec_line = MDEStringDuplicate(value); + } + + return 1; +} + +static void add_session(const char* path, int dir, void* user){ + name_line = NULL; + exec_line = NULL; + + ini_parse(path, dumper, user); + + if(name_line != NULL && exec_line != NULL){ + shput(sessions, name_line, exec_line); + } + + if(name_line != NULL) free(name_line); +} + static int conversation(int num_msg, const struct pam_message** msg, struct pam_response** resp, void* appdata){ int i; @@ -47,6 +85,13 @@ static void try_login(MwWidget handle, void* user, void* client){ if(err){ MwSetText(passentry, MwNtext, ""); }else{ + struct passwd* pwd = getpwnam(username); + const char* session = MwComboBoxGet(sesscombo, MwGetInteger(sesscombo, MwNvalue)); + + uid = pwd->pw_uid; + gid = pwd->pw_gid; + run = shget(sessions, session); + MwDestroyWidget(root); } @@ -73,9 +118,12 @@ static void try_login(MwWidget handle, void* user, void* client){ } void login_window(void){ - MwWidget pic, userlabel, passlabel, mainsep, sesslabel, sesscombo, fieldsep, shutdown, reboot, ok; + MwWidget pic, userlabel, passlabel, mainsep, sesslabel, fieldsep, shutdown, reboot, ok; MwLLPixmap p; void* out; + int i; + + pthread_mutex_lock(&xmutex); MwLibraryInit(); @@ -123,7 +171,17 @@ void login_window(void){ MwAddUserHandler(ok, MwNactivateHandler, try_login, NULL); MwAddUserHandler(passentry, MwNactivateHandler, try_login, NULL); - MDEListUsers(add_user, usercombo); + MDEUsersList(add_user, usercombo); + + for(i = 0; i < shlen(sessions); i++){ + free(sessions[i].value); + } + shfree(sessions); + sh_new_strdup(sessions); + shdefault(sessions, NULL); + MDEDirectoryScan(DATADIR "/xsessions", add_session, sesscombo); + + pthread_mutex_unlock(&xmutex); while(1){ int s = 0; diff --git a/mdm/main.c b/mdm/main.c index f91ed1d..2395551 100644 --- a/mdm/main.c +++ b/mdm/main.c @@ -2,8 +2,13 @@ int is_launch_x = 1; +gid_t gid; +uid_t uid; +char* run; + int main(int argc, char** argv){ int i, st; + char* backup = NULL; for(i = 1; i < argc; i++){ if(argv[i][0] == '-'){ @@ -26,15 +31,37 @@ int main(int argc, char** argv){ parse_config(); - if(is_launch_x){ - if((st = launch_x()) != 0) return st; - } + if(getenv("DISPLAY") != NULL) backup = MDEStringDuplicate(getenv("DISPLAY")); + do{ + pid_t pid; + + setenv("DISPLAY", backup == NULL ? "" : backup, 1); + if(is_launch_x && (st = launch_x()) != 0) return st; - while(1){ if((st = init_x()) != 0) return st; login_window(); - /* TODO: run session */ - } + if(run == NULL) continue; + + if((pid = fork()) == 0){ + struct passwd* pwd = getpwuid(uid); + + setgid(gid); + setuid(uid); + chdir(pwd->pw_dir); + setenv("USER", pwd->pw_name, 1); + setenv("SHELL", pwd->pw_shell, 1); + setenv("HOME", pwd->pw_dir, 1); + _exit(system(run)); + }else{ + waitpid(pid, NULL, 0); + } + + if(is_launch_x){ + kill_x(); + } + }while(is_launch_x); + + if(backup != NULL) free(backup); } diff --git a/mdm/mdm.h b/mdm/mdm.h index 60869bd..9e8be8d 100644 --- a/mdm/mdm.h +++ b/mdm/mdm.h @@ -22,6 +22,11 @@ #include #include +/* main.c */ +extern gid_t gid; +extern uid_t uid; +extern char* run; + /* xserver.c */ extern pthread_t xthread; extern pthread_mutex_t xmutex; @@ -31,7 +36,8 @@ int launch_x(void); int x_width(void); int x_height(void); int init_x(void); -void x_loop(void); +void loop_x(void); +void kill_x(void); /* login.c */ extern MwWidget root; diff --git a/mdm/xserver.c b/mdm/xserver.c index 21b6eed..9414346 100644 --- a/mdm/xserver.c +++ b/mdm/xserver.c @@ -4,7 +4,7 @@ #include "stb_ds.h" -static pid_t x_server; +static pid_t xserver; static int got_usr1; Display* xdisplay; @@ -22,13 +22,15 @@ int launch_x(void){ signal(SIGUSR1, catch_usr1); - if((x_server = fork()) == 0){ + /* TODO: Remove hardcoded DISPLAY */ + + if((xserver = fork()) == 0){ signal(SIGUSR1, SIG_IGN); execlp("X", "X", ":0", NULL); _exit(-1); }else{ while(!got_usr1){ - if(waitpid(x_server, NULL, WNOHANG) != 0){ + if(waitpid(xserver, NULL, WNOHANG) != 0){ fprintf(stderr, "server died. what happened?\n"); return 1; } @@ -50,7 +52,7 @@ static int wm_detect(Display* disp, XErrorEvent* ev){ } static void* x11_thread_routine(void* arg){ - x_loop(); + loop_x(); XCloseDisplay(xdisplay); } @@ -74,7 +76,10 @@ int init_x(void){ XSync(xdisplay, False); XSetErrorHandler(old); - if(wm_detected) return 1; + if(wm_detected){ + fprintf(stderr, "WM or something seem to be running\n"); + return 1; + } pthread_mutex_init(&xmutex, NULL); @@ -96,7 +101,7 @@ typedef struct window { Window client; } window_t; -void x_loop(void){ +void loop_x(void){ XEvent ev; window_t* frames = NULL; @@ -110,7 +115,7 @@ void x_loop(void){ pthread_mutex_lock(&xmutex); for(i = 0; i < arrlen(frames); i++){ if(frames[i].frame->lowlevel->x11.window == ev.xmaprequest.window){ - XReparentWindow(xdisplay, frames[i].client, ev.xmaprequest.window, MwDefaultBorderWidth(root), MwDefaultBorderWidth(root)); + XReparentWindow(xdisplay, frames[i].client, frames[i].frame->lowlevel->x11.window, MwDefaultBorderWidth(root), MwDefaultBorderWidth(root)); XMapWindow(xdisplay, ev.xmaprequest.window); XMapWindow(xdisplay, frames[i].client); break; @@ -135,18 +140,25 @@ void x_loop(void){ pthread_mutex_unlock(&xmutex); }else if(ev.type == UnmapNotify){ int i; + int c = 0; pthread_mutex_lock(&xmutex); for(i = 0; i < arrlen(frames); i++){ if(frames[i].client == ev.xunmap.window){ MwDestroyWidget(frames[i].frame); arrdel(frames, i); + c = 1; break; } } pthread_mutex_unlock(&xmutex); - break; + if(c) break; } } } + +void kill_x(void){ + kill(xserver, SIGINT); + waitpid(xserver, NULL, 0); +}