This repository has been archived on 2021-09-16. You can view files and clone it, but cannot push or open issues or pull requests.
msh/msh.c

112 lines
1.9 KiB
C
Raw Normal View History

2021-09-14 19:00:19 +02:00
#define _POSIX_C_SOURCE 200809l
#include <sys/types.h>
2021-09-13 23:46:17 +02:00
#include <stdlib.h>
2021-09-15 14:39:02 +02:00
#include <stdio.h>
2021-09-14 19:00:19 +02:00
#include <unistd.h>
#include <pwd.h>
2021-09-15 14:39:02 +02:00
#include <termios.h>
2021-09-13 23:46:17 +02:00
2021-09-14 19:00:19 +02:00
#include "config.h"
#include "fstr.h"
2021-09-15 14:39:02 +02:00
#include "err.h"
2021-09-14 19:00:19 +02:00
fstr_t PS1 = {0};
2021-09-13 23:46:17 +02:00
unsigned int histsize = DEF_HISTSIZE;
// Buffered user data
struct {
char *name;
char *home;
uid_t uid;
gid_t gid;
2021-09-14 19:00:19 +02:00
} uinfo = {0};
struct {
// $ or #
char tag;
} shinfo;
2021-09-13 23:46:17 +02:00
2021-09-15 14:39:02 +02:00
struct {
struct termios tio;
struct termios tio_before;
} terminfo;
void sh_setup_terminal(void);
2021-09-14 19:00:19 +02:00
void sh_update_uinfo(void);
void sh_update_shinfo(void);
2021-09-13 23:46:17 +02:00
void sh_update_ps1(void);
inline void sh_print_ps1(void);
int main(int argc, char **argv)
{
2021-09-14 19:00:19 +02:00
(void)argc;
(void)argv;
2021-09-15 14:39:02 +02:00
char i;
2021-09-13 23:46:17 +02:00
2021-09-15 14:39:02 +02:00
sh_setup_terminal();
2021-09-13 23:46:17 +02:00
for (;;) {
2021-09-14 19:00:19 +02:00
sh_update_uinfo();
sh_update_shinfo();
2021-09-13 23:46:17 +02:00
sh_update_ps1();
sh_print_ps1();
2021-09-15 14:39:02 +02:00
fflush(stdout);
while (1) {
read(STDIN_FILENO, &i, 1); // This blocks
fputc(i, stdout);
fflush(stdout);
if (i == '\n')
break;
}
2021-09-13 23:46:17 +02:00
}
return EXIT_SUCCESS;
}
2021-09-15 14:39:02 +02:00
void sh_setup_terminal(void)
{
if (tcgetattr(STDOUT_FILENO, &terminfo.tio_before) == -1)
die("tcgetattr:");
terminfo.tio = terminfo.tio_before;
/* Do not echo and input is available immediately */
terminfo.tio.c_lflag &= ~ECHO;
terminfo.tio.c_lflag &= ~ICANON;
if (tcsetattr(STDOUT_FILENO, TCSANOW, &terminfo.tio) == -1)
die("tcsetattr:");
}
void sh_update_uinfo(void)
2021-09-13 23:46:17 +02:00
{
2021-09-14 19:00:19 +02:00
struct passwd *pw;
uid_t nuid;
nuid = getuid();
if (nuid == uinfo.uid && uinfo.name)
return;
uinfo.uid = nuid;
pw = getpwuid(uinfo.uid);
// User not found
if (!pw)
2021-09-15 14:39:02 +02:00
die("getpwuid:");
2021-09-14 19:00:19 +02:00
uinfo.gid = pw->pw_gid;
uinfo.name = estrdup(pw->pw_name);
uinfo.home = estrdup(pw->pw_dir);
}
2021-09-13 23:46:17 +02:00
2021-09-14 19:00:19 +02:00
void sh_update_shinfo(void)
{
shinfo.tag = uinfo.uid ? '$' : '#';
2021-09-13 23:46:17 +02:00
}
2021-09-15 14:39:02 +02:00
void sh_print_ps1(void)
2021-09-13 23:46:17 +02:00
{
2021-09-15 14:39:02 +02:00
fputs(PS1.s, stdout);
2021-09-13 23:46:17 +02:00
}
void sh_update_ps1(void)
{
2021-09-15 14:39:02 +02:00
fstr_clear(&PS1);
2021-09-14 19:00:19 +02:00
fstr_append_char(&PS1, shinfo.tag);
fstr_append_char(&PS1, ' ');
}