banan-os/userspace/programs/init/main.cpp

145 lines
2.4 KiB
C++
Raw Normal View History

#include <BAN/String.h>
#include <BAN/Optional.h>
#include <BAN/Vector.h>
#include <ctype.h>
#include <fcntl.h>
#include <pwd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/banan-os.h>
#include <termios.h>
void initialize_stdio()
{
const char* tty = "/dev/tty";
if (open(tty, O_RDONLY | O_TTY_INIT) != 0) _exit(1);
if (open(tty, O_WRONLY) != 1) _exit(1);
if (open(tty, O_WRONLY) != 2) _exit(1);
if (open("/dev/debug", O_WRONLY) != 3) _exit(1);
}
int main()
{
initialize_stdio();
if (signal(SIGINT, [](int) {}) == SIG_ERR)
perror("signal");
if (load_keymap("/usr/share/keymaps/us.keymap") == -1)
perror("load_keymap");
if (fork() == 0)
{
execl("/bin/dhcp-client", "dhcp-client", NULL);
exit(1);
}
if (fork() == 0)
{
execl("/bin/resolver", "resolver", NULL);
exit(1);
}
bool first = true;
termios termios;
tcgetattr(STDIN_FILENO, &termios);
while (true)
{
tcsetattr(STDIN_FILENO, TCSANOW, &termios);
char name_buffer[128];
while (!first)
{
printf("username: ");
fflush(stdout);
ssize_t nread = read(STDIN_FILENO, name_buffer, sizeof(name_buffer) - 1);
if (nread == -1)
{
perror("read");
return 1;
}
if (nread <= 1 || name_buffer[nread - 1] != '\n')
continue;
name_buffer[nread - 1] = '\0';
break;
}
if (first)
{
strcpy(name_buffer, "user");
first = false;
}
auto* pwd = getpwnam(name_buffer);
if (pwd == nullptr)
continue;
if (chown("/dev/tty", pwd->pw_uid, pwd->pw_gid) == -1)
{
perror("chown");
continue;
}
if (chmod("/dev/tty", 0600) == -1)
{
perror("chmod");
continue;
}
pid_t pid = fork();
if (pid == 0)
{
pid_t pgrp = setpgrp();
if (tcsetpgrp(0, pgrp) == -1)
{
perror("tcsetpgrp");
exit(1);
}
printf("Welcome back %s!\n", pwd->pw_name);
if (setgid(pwd->pw_gid) == -1)
perror("setgid");
if (setuid(pwd->pw_uid) == -1)
perror("setuid");
setenv("PATH", "/bin:/usr/bin", 0);
setenv("HOME", pwd->pw_dir, 1);
chdir(pwd->pw_dir);
setenv("SHELL", pwd->pw_shell, 1);
char shell_path[PATH_MAX];
strcpy(shell_path, pwd->pw_shell);
endpwent();
execl(shell_path, shell_path, nullptr);
perror("execl");
exit(1);
}
endpwent();
if (pid == -1)
{
perror("fork");
break;
}
int status;
waitpid(pid, &status, 0);
if (tcsetpgrp(0, getpgrp()) == -1)
perror("tcsetpgrp");
}
}