#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <err.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/wait.h>

#define MAXLINE     1024
#define MAXARGS     20

char    ps1[10] = "% ";

void    print_ps1(void);
int     tokenize(char *args[], char *command);
char*   ltrim(const char *s);

int
main(void)
{
    char    buf[MAXLINE];
    char    *b;
    char    *args[MAXARGS + 1];
    pid_t   pid;
    int     status;
    int     i;

    print_ps1();
    while (fgets(buf, MAXLINE, stdin) != NULL) {
        b = ltrim(buf);
        if (*b == '\0') {
            print_ps1();
            continue;
        }

        if (b[strlen(b) - 1] == '\n')
            b[strlen(b) - 1] = 0;

        if (strcmp(b, "echo $?") == 0) {
            printf("%d\n", (status & 0xff00) >> 8);
            print_ps1();
            continue;
        } else if (strncmp(b, "cd ", 3) == 0) {
            if (chdir(b+3) < 0) {
                fprintf(stderr, "chdir %s: ", b+3);
                perror(NULL);
            }
            print_ps1();
            continue;
        } else if (strncmp(buf, "PS1=", 4) == 0) {
            if (isspace(b[4]))
                continue;

            char *start, *end;

            start = b + 4;
            if (*start == '"') {
                start++;
                if ((end = strchr(start, '"')) == NULL)
                    continue;
                *end = 0;
            } else {
                for (end = start+1; *end; end++)
                    if (isspace(*end)) {
                        *end = 0;
                        break;
                    }
            }
            strncpy(ps1, start, end-start+1);
            print_ps1();
            continue;
        }


        if ((pid = fork()) < 0)
            err(EXIT_FAILURE, "fork error");
        else if (pid == 0) {
            i = tokenize(args, b);
            execvp(args[0], args);
            err(127, "colud not execute: %s", b);
        }

        /* parent */
        if ((pid = waitpid(pid, &status, 0)) < 0)
            err(EXIT_FAILURE, "waitpid error");
        print_ps1();
    }
    exit(EXIT_SUCCESS);
}

int
tokenize(char *args[], char *command)
{
    char    *s;
    int     i;

    i = 0;
    while ((s = strtok(command, " ")) != NULL) {
        args[i++] = s;
        command = NULL;
    }
    args[i] = NULL;
    return i;
}

void
print_ps1(void)
{
    printf("%s", ps1);
}

char *
ltrim(const char *s)
{
    for ( ; *s && isspace(*s); s++)
        ;
    return (char *) s;
}
