#include #include #include #include #include #include #include #include #include #include #include #include #include #define PS1 "\033[1;31m%s\033[0m@\033[1m%s\033[0m:\033[1;32m%s\033[0m$> " int argparser(char sep, char *str, char **res); /* Get the nice current working directory */ static void shell_getcwd(char *cwd, char *homedir) { getcwd(cwd, PATH_MAX); /* Replace the homedir with "~" */ if (!strncmp(cwd, homedir, strlen(homedir))) { strncpy(cwd + 1, cwd + strlen(homedir), PATH_MAX - strlen(homedir)); cwd[0] = '~'; } } /* Main function */ int main(int argc, char *argv[]) { int fd, sz, i; char *buf; struct dirent *de; /* Get username */ uid_t uid = getuid(); char *hostname, *username, *cwd, *homedir, *line, *ptr; username = malloc(33); homedir = malloc(PATH_MAX); Passwd *pwd = getpwuid(uid); strcpy(username, pwd->pw_name); strcpy(homedir, pwd->pw_dir); /* Get hostname */ hostname = malloc(HOST_NAME_MAX + 1); fd = open("/etc/hostname", O_RDONLY); sz = lseek(fd, 0, SEEK_END); lseek(fd, 0, SEEK_SET); read(fd, hostname, sz - 1); close(fd); /* Get current working directory */ cwd = malloc(PATH_MAX); shell_getcwd(cwd, homedir); line = malloc(1024); pid_t child; int err, count, status; char *v[256], filename[PATH_MAX] = {'/','b','i','n','/'}; while (1) { printf(PS1, username, hostname, cwd); memset(line, 0, 1024); sz = read(STDIN_FILENO, line, 1024); line[--sz] = '\0'; if (sz < 1) continue; count = argparser(' ', line, v); /* Change directory (built-in) */ if (!strcmp(v[0], "cd")) { err = chdir(v[1]); if (err < 0) { printf("%s: cd: ", argv[0]); perror(NULL); } else { shell_getcwd(cwd, homedir); } continue; } /* Exit (built-in) */ if (!strcmp(v[0], "exit")) exit(0); /* Check if program exists */ memcpy(filename+5, v[0], PATH_MAX-5); err = stat(filename, NULL); if (err < 0) { if (errno == ENOENT) { printf("%s: %s: Command not found\n", argv[0], v[0]); } else { printf("%s: %s: ", argv[0], v[0]); perror(NULL); } continue; } /* Execute program */ child = fork(); if (!child) { err = execv(filename, v); if (err < 0) { printf("%s: %s: ", argv[0], v[0]); perror(NULL); } exit(EXIT_FAILURE); } else { if (waitpid(child, &status, 0) < 0) perror("waitpid"); if (WIFEXITED(status) && WEXITSTATUS(status)) printf("Exited with status %d\n", WEXITSTATUS(status)); if (WIFSIGNALED(status) && WTERMSIG(status)) { switch (WTERMSIG(status)) { case SIGSEGV: printf("Segmentation fault\n"); break; } } } child = 0; } }