Write a C program to implement the shell. It should display the command promt "myshell$". Tokenize the command line and execute the given command by creating the child process. Additionally it should interpret the following ‘list’ commands as
myshell$ list f dirname: To print names of all the files in current directory. 
myshell$ list n dirname: To print the number of all entries in the current directory.


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

#define MAX_INPUT_SIZE 1024
#define MAX_ARG_SIZE 100

// Function to list files in a directory
void listFiles(const char *dirname) {
    DIR *dir = opendir(dirname);
    if (dir == NULL) {
        perror("Error opening directory");
        return;
    }
    
    struct dirent *entry;
    while ((entry = readdir(dir)) != NULL) {
        // Skip the '.' and '..' entries
        if (entry->d_name[0] != '.') {
            printf("%s\n", entry->d_name);
        }
    }
    closedir(dir);
}

// Function to count entries in a directory
void countEntries(const char *dirname) {
    DIR *dir = opendir(dirname);
    if (dir == NULL) {
        perror("Error opening directory");
        return;
    }
    
    struct dirent *entry;
    int count = 0;
    while ((entry = readdir(dir)) != NULL) {
        count++;
    }
    closedir(dir);
    
    printf("Total entries: %d\n", count);
}

// Function to execute commands
void executeCommand(char *cmd) {
    char *args[MAX_ARG_SIZE];
    char *token = strtok(cmd, " \t\n");
    int i = 0;

    // Tokenize the command line
    while (token != NULL) {
        args[i++] = token;
        token = strtok(NULL, " \t\n");
    }
    args[i] = NULL; // Null-terminate the argument list

    if (strcmp(args[0], "list") == 0) {
        if (i < 3) {
            printf("Usage: list f dirname | list n dirname\n");
            return;
        }
        if (strcmp(args[1], "f") == 0) {
            // List files in the directory
            listFiles(args[2]);
        } else if (strcmp(args[1], "n") == 0) {
            // Count entries in the directory
            countEntries(args[2]);
        } else {
            printf("Usage: list f dirname | list n dirname\n");
        }
    } else {
        pid_t pid = fork();
        if (pid == 0) {
            // Child process
            execvp(args[0], args);
            perror("execvp failed");
            exit(1);
        } else if (pid > 0) {
            // Parent process
            wait(NULL);
        } else {
            perror("fork failed");
        }
    }
}

int main() {
    char input[MAX_INPUT_SIZE];

    while (1) {
        printf("myshell$ ");
        if (fgets(input, sizeof(input), stdin) == NULL) {
            break; // Exit on EOF
        }
        // Remove the trailing newline character from the input
        input[strcspn(input, "\n")] = 0;

        if (strcmp(input, "exit") == 0) {
            break; // Exit the shell
        }

        executeCommand(input);
    }

    return 0;
}