functional
This commit is contained in:
parent
dee8cc858b
commit
54efe25a24
4 changed files with 121 additions and 18 deletions
64
mdm/login.c
64
mdm/login.c
|
|
@ -1,14 +1,52 @@
|
||||||
#include "mdm.h"
|
#include "mdm.h"
|
||||||
|
|
||||||
|
#include <ini.h>
|
||||||
#include <security/pam_appl.h>
|
#include <security/pam_appl.h>
|
||||||
|
#include <stb_ds.h>
|
||||||
|
|
||||||
MwWidget root;
|
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){
|
static void add_user(const char* name, void* user){
|
||||||
MwComboBoxAdd(user, -1, name);
|
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){
|
static int conversation(int num_msg, const struct pam_message** msg, struct pam_response** resp, void* appdata){
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
|
@ -47,6 +85,13 @@ static void try_login(MwWidget handle, void* user, void* client){
|
||||||
if(err){
|
if(err){
|
||||||
MwSetText(passentry, MwNtext, "");
|
MwSetText(passentry, MwNtext, "");
|
||||||
}else{
|
}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);
|
MwDestroyWidget(root);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -73,9 +118,12 @@ static void try_login(MwWidget handle, void* user, void* client){
|
||||||
}
|
}
|
||||||
|
|
||||||
void login_window(void){
|
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;
|
MwLLPixmap p;
|
||||||
void* out;
|
void* out;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
pthread_mutex_lock(&xmutex);
|
||||||
|
|
||||||
MwLibraryInit();
|
MwLibraryInit();
|
||||||
|
|
||||||
|
|
@ -123,7 +171,17 @@ void login_window(void){
|
||||||
MwAddUserHandler(ok, MwNactivateHandler, try_login, NULL);
|
MwAddUserHandler(ok, MwNactivateHandler, try_login, NULL);
|
||||||
MwAddUserHandler(passentry, 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){
|
while(1){
|
||||||
int s = 0;
|
int s = 0;
|
||||||
|
|
|
||||||
39
mdm/main.c
39
mdm/main.c
|
|
@ -2,8 +2,13 @@
|
||||||
|
|
||||||
int is_launch_x = 1;
|
int is_launch_x = 1;
|
||||||
|
|
||||||
|
gid_t gid;
|
||||||
|
uid_t uid;
|
||||||
|
char* run;
|
||||||
|
|
||||||
int main(int argc, char** argv){
|
int main(int argc, char** argv){
|
||||||
int i, st;
|
int i, st;
|
||||||
|
char* backup = NULL;
|
||||||
|
|
||||||
for(i = 1; i < argc; i++){
|
for(i = 1; i < argc; i++){
|
||||||
if(argv[i][0] == '-'){
|
if(argv[i][0] == '-'){
|
||||||
|
|
@ -26,15 +31,37 @@ int main(int argc, char** argv){
|
||||||
|
|
||||||
parse_config();
|
parse_config();
|
||||||
|
|
||||||
if(is_launch_x){
|
if(getenv("DISPLAY") != NULL) backup = MDEStringDuplicate(getenv("DISPLAY"));
|
||||||
if((st = launch_x()) != 0) return st;
|
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;
|
if((st = init_x()) != 0) return st;
|
||||||
|
|
||||||
login_window();
|
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);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,11 @@
|
||||||
#include <setjmp.h>
|
#include <setjmp.h>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
|
||||||
|
/* main.c */
|
||||||
|
extern gid_t gid;
|
||||||
|
extern uid_t uid;
|
||||||
|
extern char* run;
|
||||||
|
|
||||||
/* xserver.c */
|
/* xserver.c */
|
||||||
extern pthread_t xthread;
|
extern pthread_t xthread;
|
||||||
extern pthread_mutex_t xmutex;
|
extern pthread_mutex_t xmutex;
|
||||||
|
|
@ -31,7 +36,8 @@ int launch_x(void);
|
||||||
int x_width(void);
|
int x_width(void);
|
||||||
int x_height(void);
|
int x_height(void);
|
||||||
int init_x(void);
|
int init_x(void);
|
||||||
void x_loop(void);
|
void loop_x(void);
|
||||||
|
void kill_x(void);
|
||||||
|
|
||||||
/* login.c */
|
/* login.c */
|
||||||
extern MwWidget root;
|
extern MwWidget root;
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
#include "stb_ds.h"
|
#include "stb_ds.h"
|
||||||
|
|
||||||
static pid_t x_server;
|
static pid_t xserver;
|
||||||
static int got_usr1;
|
static int got_usr1;
|
||||||
|
|
||||||
Display* xdisplay;
|
Display* xdisplay;
|
||||||
|
|
@ -22,13 +22,15 @@ int launch_x(void){
|
||||||
|
|
||||||
signal(SIGUSR1, catch_usr1);
|
signal(SIGUSR1, catch_usr1);
|
||||||
|
|
||||||
if((x_server = fork()) == 0){
|
/* TODO: Remove hardcoded DISPLAY */
|
||||||
|
|
||||||
|
if((xserver = fork()) == 0){
|
||||||
signal(SIGUSR1, SIG_IGN);
|
signal(SIGUSR1, SIG_IGN);
|
||||||
execlp("X", "X", ":0", NULL);
|
execlp("X", "X", ":0", NULL);
|
||||||
_exit(-1);
|
_exit(-1);
|
||||||
}else{
|
}else{
|
||||||
while(!got_usr1){
|
while(!got_usr1){
|
||||||
if(waitpid(x_server, NULL, WNOHANG) != 0){
|
if(waitpid(xserver, NULL, WNOHANG) != 0){
|
||||||
fprintf(stderr, "server died. what happened?\n");
|
fprintf(stderr, "server died. what happened?\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
@ -50,7 +52,7 @@ static int wm_detect(Display* disp, XErrorEvent* ev){
|
||||||
}
|
}
|
||||||
|
|
||||||
static void* x11_thread_routine(void* arg){
|
static void* x11_thread_routine(void* arg){
|
||||||
x_loop();
|
loop_x();
|
||||||
XCloseDisplay(xdisplay);
|
XCloseDisplay(xdisplay);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -74,7 +76,10 @@ int init_x(void){
|
||||||
XSync(xdisplay, False);
|
XSync(xdisplay, False);
|
||||||
XSetErrorHandler(old);
|
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);
|
pthread_mutex_init(&xmutex, NULL);
|
||||||
|
|
||||||
|
|
@ -96,7 +101,7 @@ typedef struct window {
|
||||||
Window client;
|
Window client;
|
||||||
} window_t;
|
} window_t;
|
||||||
|
|
||||||
void x_loop(void){
|
void loop_x(void){
|
||||||
XEvent ev;
|
XEvent ev;
|
||||||
window_t* frames = NULL;
|
window_t* frames = NULL;
|
||||||
|
|
||||||
|
|
@ -110,7 +115,7 @@ void x_loop(void){
|
||||||
pthread_mutex_lock(&xmutex);
|
pthread_mutex_lock(&xmutex);
|
||||||
for(i = 0; i < arrlen(frames); i++){
|
for(i = 0; i < arrlen(frames); i++){
|
||||||
if(frames[i].frame->lowlevel->x11.window == ev.xmaprequest.window){
|
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, ev.xmaprequest.window);
|
||||||
XMapWindow(xdisplay, frames[i].client);
|
XMapWindow(xdisplay, frames[i].client);
|
||||||
break;
|
break;
|
||||||
|
|
@ -135,18 +140,25 @@ void x_loop(void){
|
||||||
pthread_mutex_unlock(&xmutex);
|
pthread_mutex_unlock(&xmutex);
|
||||||
}else if(ev.type == UnmapNotify){
|
}else if(ev.type == UnmapNotify){
|
||||||
int i;
|
int i;
|
||||||
|
int c = 0;
|
||||||
|
|
||||||
pthread_mutex_lock(&xmutex);
|
pthread_mutex_lock(&xmutex);
|
||||||
for(i = 0; i < arrlen(frames); i++){
|
for(i = 0; i < arrlen(frames); i++){
|
||||||
if(frames[i].client == ev.xunmap.window){
|
if(frames[i].client == ev.xunmap.window){
|
||||||
MwDestroyWidget(frames[i].frame);
|
MwDestroyWidget(frames[i].frame);
|
||||||
arrdel(frames, i);
|
arrdel(frames, i);
|
||||||
|
c = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock(&xmutex);
|
pthread_mutex_unlock(&xmutex);
|
||||||
|
|
||||||
break;
|
if(c) break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void kill_x(void){
|
||||||
|
kill(xserver, SIGINT);
|
||||||
|
waitpid(xserver, NULL, 0);
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue