functional

This commit is contained in:
Nishi 2025-11-17 18:17:33 +09:00
commit 54efe25a24
Signed by: nishi
GPG key ID: 27EF69B208EB9343
4 changed files with 121 additions and 18 deletions

View file

@ -1,14 +1,52 @@
#include "mdm.h"
#include <ini.h>
#include <security/pam_appl.h>
#include <stb_ds.h>
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;

View file

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

View file

@ -22,6 +22,11 @@
#include <setjmp.h>
#include <pthread.h>
/* 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;

View file

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