userspace/sh/sh.c
2020-01-19 17:54:47 +02:00

123 lines
2.3 KiB
C

#include <string.h>
#include <stdio.h>
#include <pwd.h>
#include "readline.h"
#include "config.h"
#include "cmd.h"
// Data needed for prompt
static char p_hostname[64];
static char p_username[64];
static char p_cwd[256];
static uid_t p_uid;
//static gid_t p_gid;
static void update_prompt(void) {
struct utsname _u;
struct passwd _p;
struct passwd *p;
char pwbuf[512];
p_uid = getuid();
if (getcwd(p_cwd, sizeof(p_cwd)) == NULL) {
perror("getcwd()");
p_cwd[0] = 0;
}
if (uname(&_u) != 0) {
perror("uname()");
p_hostname[0] = 0;
} else {
strcpy(p_hostname, _u.nodename);
}
if (getpwuid_r(p_uid, &_p, pwbuf, sizeof(pwbuf), &p) != 0) {
perror("getpwuid_r()");
p_username[0] = 0;
} else {
strcpy(p_username, p->pw_name);
}
}
static void display_prompt(void) {
const char *p = PS1;
while (*p) {
if (*p == '%') {
switch (*++p) {
case '#':
putchar(p_uid == 0 ? '#' : '$');
break;
case 'h':
puts2(p_hostname);
break;
case 'u':
puts2(p_username);
break;
case 'd':
puts2(p_cwd);
break;
default:
putchar('%');
putchar(*p);
break;
}
} else {
putchar(*p);
}
++p;
}
}
int main(int argc, char **argv) {
int fd = STDIN_FILENO;
char linebuf[256];
int res;
if (argc == 2) {
fd = open(argv[1], O_RDONLY, 0);
if (fd < 0) {
perror(argv[1]);
return -1;
}
} else if (argc != 1) {
printf("usage: sh [filename]\n");
return -1;
}
if (!isatty(fd)) {
while (1) {
if (gets_safe(fd, linebuf, sizeof(linebuf)) < 0) {
break;
}
eval(linebuf);
}
if (fd != STDIN_FILENO) {
close(fd);
}
return 0;
}
while (1) {
update_prompt();
display_prompt();
if (readline(linebuf, sizeof(linebuf)) < 0) {
break;
}
if ((res = eval(linebuf)) != 0) {
printf(COLOR_RED "Status: %d" COLOR_RESET "\n", res);
}
}
return 0;
}