custom-unix-shell / wish-v3.c
wish-v3.c
Raw
//Add your code here
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<ctype.h>

#define MAXCOM 1000 // max number of letters to be supported
#define MAX_ARGS 100 // max number of commands to be supported

char allDirectories[30][30]; // contains all paths specified by user

// function for finding ampersand (parallel commands)
int findParallelCmds(char* str, char** parallelStr)
{
    int i; // to be used as parallel cmds counter
    for (i = 0; i < MAX_ARGS; i++) {
        parallelStr[i] = strsep(&str, "&");
        printf("i value here: %d, cmd: %s\n", i, parallelStr[i]);
        if (parallelStr[i] == NULL) {
            break;
        }
    }
    if (i > 1)
        return i; 
    else {
        return 0; // returns zero if no pipe is found.
    }
}

// function to handle built-in commands
// if 0 is returned, it means that none of 
// the built-in commands was executed
int useBuiltInCmds(int argc, char **args) {

    int noOfSysCmds = 3, chosenCmd = 0;
    char* listOfSysCmds[noOfSysCmds];
    listOfSysCmds[0] = "exit";
    listOfSysCmds[1] = "cd";
    listOfSysCmds[2] = "path";
    
    for (int i = 0; i < noOfSysCmds; i++) {
        if (strcmp(args[0], listOfSysCmds[i]) == 0) {
            chosenCmd = i + 1;
            break;
        }
    }
    switch (chosenCmd) {
    case 1:
        if (argc > 1) {
            printf("Error occurs\n");
            char error_message[30] = "An error has occurred\n";
            write(STDERR_FILENO, error_message, strlen(error_message));
            return 1;
        }
        exit(0);
    case 2:
        if (argc == 1 || argc > 2) {
            char error_message[30] = "An error has occurred\n";
            write(STDERR_FILENO, error_message, strlen(error_message));
            return 1;
        }
        chdir(args[1]);
        return 1;
    case 3:
        if (argc == 1) {
            int numPaths = sizeof(allDirectories) / sizeof(allDirectories[0]);
            for (int i=0; i<numPaths; i++) {
                sprintf(allDirectories[i], "%d", '\0');
            }
        } else {
            for (int i=0; i<argc-1; i++) {
                sprintf(allDirectories[i], "%s", args[i+1]);
            }
        }
        return 1;
    default:
        break;
    }
    return 0;
}

// function for parsing parallel command words
int parseSpaceParallel(char **parallelStr, int **parallelArgsCounter, char ***parallelArgs) 
{


    return 1;
}

// function for parsing single command words
int parseSpace(char *str, int argsCounter, char **args)
{
    int i;
    for (i = 0; i < MAX_ARGS; i++) {
        args[i] = strsep(&str, " ");
        if (args[i] == NULL)
            break;
        if (strlen(args[i]) == 0 || strcmp(args[i], "\t") == 0)
            i--;
    }
    argsCounter = i;

    printf("Current counter: %d\n", argsCounter);

    if (useBuiltInCmds(argsCounter, args)) {
        // executed with built-in cmds
        return 1;
    } else {
        return 0;
        // to be executed with execv
    }
}


// this function executes when the user does not put
// any argument after ./wish, meaning they use stdin
void takeStdInput(char* str, int argsCounter, char **args, 
                    int **parallelArgsCounter, char ***parallelArgs)
{
    while(1) {

        // print shell prompt to terminal
        printf("wish> ");

        char *line = NULL; // buffer to store each line read
        size_t len = 0; // length of the line read
        ssize_t read; // number of characters read by getline

        // take input line by line
        while ((read = getline(&line, &len, stdin)) != -1) {
            // remove newline character from command string
            if (line[strlen(line) - 1] == '\n') {
                line[strlen(line) - 1] = '\0';
            }
            // copy to pointer str
            strcpy(str, line);

            // Free the line buffer
            free(line);
            // Reset the line pointer and size for the next line
            line = NULL;
            len = 0;
            break;
        }

        // check for parallel cmds
        char *parallelStr[MAX_ARGS];
        int parallelCmdsNum = findParallelCmds(str, parallelStr);
        
        if (parallelCmdsNum) {
            printf("%d\n", parallelCmdsNum);
            // return a number greater than 0
            //parseSpaceParallel(parallelStr, parallelArgsCounter, parallelArgs);
            printf("Parse parallel completed: %d\n", parseSpaceParallel(parallelStr, parallelArgsCounter, parallelArgs));
            
            // for (int j=0;j<parallelCmds;j++) {
            //     printf("%s\n", parallelStr[j]);      
            // }
            //exit(0);

        } else {
            // no parallel cmds found
            printf("No parallel cmds found\n");   
            parseSpace(str, argsCounter, args);
            exit(0);
        
        }

        // if (parseSpace(str, argsCounter, args)) {
        //     // 

        // } else {
        //     //
        // }
    }
}

// function to execute given batch file
void takeBatchInput(char *inputFile) 
{
    FILE * fp = fopen(inputFile, "r");
    if (fp == NULL) {
        char error_message[30] = "An error has occurred\n";
        write(STDERR_FILENO, error_message, strlen(error_message));
    }
}

int main(int argc, char *argv[]) 
{    
    char str[MAXCOM]; // ptr to store command line

    char *args[MAX_ARGS]; // ptr to a list of arguments
    int argsCounter = 0; // number of arguments, including the cmd arg

    char **parallelArgs[MAX_ARGS];
    int *parallelArgsCounter[MAX_ARGS];
    
    //sprintf(allDirectories[0], "%s", "/bin");

    // If given more than one command-line argument -> error
    if (argc > 2) {
        char error_message[30] = "An error has occurred\n";
        write(STDERR_FILENO, error_message, strlen(error_message));
    }
    // If given one argument -> prompt input
    else if (argc == 1) {
        takeStdInput(str, argsCounter, args, parallelArgsCounter, parallelArgs);
    }
    // If given a batch file -> execute commands in file
    else {
        takeBatchInput(argv[1]);
    }

    return 0;
  
}