/*
 * PJ Waskiewicz
 * 2/05/2000
 * pnsh.c
 * Systems Programming, CS396
 *
 */

#include "pnsh.h"

int main(int argc, char *argv[]) {
  char **args; /* For execvp() */
  char opts[MY_MAX]; /* Opts for execfile to be parsed */
  int i, j, bool, tokens;
  static int background;
  while(1) {
    /* Signals to be caught */
    signal(SIGCHLD, SIG_IGN);
    signal(SIGINT, SIG_IGN);
    bool = tokens = background = 0;
    /* Event loop */
    if(strcmp(getenv("USER"), "root") == 0)
      printf("%s", SU_PROMPT);
    else
      printf("%s", U_PROMPT);
    if(fgets(opts, MY_MAX, stdin) == NULL) {
      /* And end of file occured; logout time... */
      fprintf(stdout, "logout\n");
      exit(0);
    }
    /* Check for stupidity */
    for(i = 0; i < (strlen(opts) - 1); i++) {
      if(opts[i] == 32) bool = 1;
      else {
        bool = 0;
        break;
      }
    }
    if(bool == 0) {
      if((opts[0] != 0) && (opts[0] != '\n')) {
        /* Clean the arg list of carriage returns */
        for(i = 0; i < strlen(opts); i++)
          if(opts[i] == '\n') opts[i] = 32;
        args = parser(opts, &tokens);
        /* Now parse the args to check for I/O redirection */
        for(i = 0; i < tokens; i++) {
          if((strcmp(args[i], "<") == 0) || (strcmp(args[i], ">") == 0)) {
            /* Sanity check */
            for(j = i; j < tokens; j++) {
              if(strcmp(args[j], "|") == 0) {
                bool = -1;
                break;
              }
              else bool = 1;
            }
            break;
          }
          else if(strcmp(args[i], "|") == 0) {
            bool = 2;
            break;
          }
        }
        if(bool == -1) fprintf(stderr, "Malformed command\n");
        else if(bool == 1)
          redirect(args, i);
        else if(bool == 2)
          pipeme(args, tokens);
        else {
          /* Now the fun begins... */
          if(strcmp(args[0], "cd") == 0) {
            /* We need to change directory */
            if(args[1] == NULL) /* Change to home directory */
              if((args[1] = getenv("HOME")) < 0)
                fprintf(stderr, "cd: %s\n", strerror(errno));
            if(chdir(args[1]) < 0)
              fprintf(stderr, "cd: %s\n", strerror(errno));
          }
          else if(strcmp(args[0], "logout") == 0)
            exit(0);
          else {
            /* Now we exec.  We need to fork then exec so we can reenter */
            if(strcmp(args[tokens - 1], "&") == 0) {
              background = 1;
              args[tokens - 1] = NULL;
            }
            else background = 0;
            if(fork() == 0) {
              /* I'm the child.  I'll exec... */
              if(background == 0) signal(SIGINT, SIG_DFL);
              else signal(SIGINT, SIG_IGN);
              if(execvp(args[0], args) < 0) {
                /* Something bad happened */
                fprintf(stderr, "%s: %s\n", args[0], strerror(errno));
                exit(1);
              }
            }
            else {
              if(background == 0) {
                /* I'm the parent.  I'm going to wait for the child to go away */
                signal(SIGCHLD, SIG_DFL);
                if(wait(NULL) < 0)
                  fprintf(stderr, "%s: wait() in parent\n", strerror(errno));
              }
            }
          }
        }
      }
    }
  }
}