120 lines
2.7 KiB
C
120 lines
2.7 KiB
C
#include "mdm.h"
|
|
|
|
int is_launch_x = 1;
|
|
int is_daemon = 1;
|
|
|
|
gid_t gid;
|
|
uid_t uid;
|
|
session_environment_t* env;
|
|
|
|
static void set_env_standard(struct passwd* pwd);
|
|
static void set_env_xdg(struct passwd* pwd);
|
|
|
|
int main(int argc, char** argv) {
|
|
int i, st, exit;
|
|
char* backup = NULL;
|
|
pid_t pid;
|
|
|
|
for(i = 1; i < argc; i++) {
|
|
if(argv[i][0] == '-') {
|
|
if(strcmp(argv[i], "-X") == 0 || strcmp(argv[i], "--no-launch-x") == 0) {
|
|
is_launch_x = 0;
|
|
} else if(strcmp(argv[i], "-d") == 0 || strcmp(argv[i], "--no-daemon") == 0) {
|
|
is_daemon = 0;
|
|
} else {
|
|
fprintf(stderr, "%s: bad option: %s\n", argv[0], argv[i]);
|
|
return 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
if(getuid() != 0) {
|
|
fprintf(stderr, "MDM has to be ran as root\n");
|
|
return 1;
|
|
}
|
|
|
|
if(is_daemon && (pid = fork()) != 0) {
|
|
FILE* f = fopen("/var/run/mdm.pid", "w");
|
|
fprintf(f, "%d\n", pid);
|
|
fclose(f);
|
|
return 0;
|
|
}
|
|
|
|
parse_config();
|
|
|
|
if(getenv("DISPLAY") != NULL) backup = MDEStringDuplicate(getenv("DISPLAY"));
|
|
do {
|
|
setenv("DISPLAY", backup == NULL ? "" : backup, 1);
|
|
if(is_launch_x && (st = launch_x()) != 0) return st;
|
|
|
|
if((st = init_x()) != 0) return st;
|
|
|
|
login_window();
|
|
|
|
if(env->run == NULL && env->try_run == NULL) continue;
|
|
|
|
if((pid = fork()) == 0) {
|
|
struct passwd* pwd = getpwuid(uid);
|
|
|
|
setgid(gid);
|
|
setuid(uid);
|
|
chdir(pwd->pw_dir);
|
|
|
|
set_env_standard(pwd);
|
|
set_env_xdg(pwd);
|
|
|
|
if((exit = system(env->try_run)) != 0) {
|
|
exit = system(env->run);
|
|
} else {
|
|
_exit(exit);
|
|
}
|
|
} else {
|
|
waitpid(pid, NULL, 0);
|
|
}
|
|
|
|
if(is_launch_x) {
|
|
unsetenv("DISPLAY");
|
|
kill_x();
|
|
}
|
|
} while(is_launch_x);
|
|
|
|
if(backup != NULL) free(backup);
|
|
}
|
|
|
|
void set_env_standard(struct passwd* pwd) {
|
|
setenv("HOME", pwd->pw_dir, 1);
|
|
setenv("PWD", pwd->pw_dir, 1);
|
|
setenv("USER", pwd->pw_name, 1);
|
|
setenv("SHELL", pwd->pw_shell, 1);
|
|
setenv("LOGNAME", pwd->pw_shell, 1);
|
|
}
|
|
void set_env_xdg(struct passwd* pwd) {
|
|
// this directory isn't avaliable on bsd, but we can't check for all of them.
|
|
// so just assume it's only on linux, idek if that's true but who care
|
|
#if defined(__linux__)
|
|
char runtime_dir[255];
|
|
snprintf(runtime_dir, 255, "/run/user/%d", pwd->pw_uid);
|
|
setenv("XDG_RUNTIME_DIR", runtime_dir, 1);
|
|
#endif
|
|
|
|
switch(env->session_type) {
|
|
case MDM_SESSION_TYPE_X:
|
|
setenv("XDG_SESSION_TYPE", "x11", 1);
|
|
break;
|
|
case MDM_SESSION_TYPE_WAYLAND:
|
|
setenv("XDG_SESSION_TYPE", "wayland", 1);
|
|
break;
|
|
}
|
|
|
|
if(env->desktop_names) {
|
|
if(strlen(env->desktop_names) > 1) {
|
|
setenv("XDG_SESSION_DESKTOP", strtok(env->desktop_names, ";"), 1);
|
|
}
|
|
setenv("XDG_CURRENT_DESKTOP", env->desktop_names, 1);
|
|
}
|
|
|
|
setenv("XDG_SESSION_CLASS", "user", 1);
|
|
setenv("XDG_SESSION_ID", "1", 1);
|
|
setenv("XDG_SEAT", "seat0", 1);
|
|
// setenv("XDG_VTNR", "/dev/pts/7", 1);
|
|
}
|