Write a program to implement the shell. It should display the command prompt “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 i dirname To print names and inodes of the files in the current directory.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <dirent.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>

// Function to list files in the directory
void list_files(const char *dirname) {
    struct dirent *entry;
    DIR *dp = opendir(dirname);

    if (dp == NULL) {
        perror("opendir");
        return;
    }

    printf("Files in directory '%s':\n", dirname);
    while ((entry = readdir(dp))) {
        if (entry->d_type == DT_REG) { // Regular file
            printf("%s\n", entry->d_name);
        }
    }

    closedir(dp);
}

// Function to list files and their inodes in the directory
void list_files_with_inodes(const char *dirname) {
    struct dirent *entry;
    DIR *dp = opendir(dirname);

    if (dp == NULL) {
        perror("opendir");
        return;
    }

    printf("Files and inodes in directory '%s':\n", dirname);
    while ((entry = readdir(dp))) {
        if (entry->d_type == DT_REG) { // Regular file
            struct stat file_stat;
            char path[1024];
            snprintf(path, sizeof(path), "%s/%s", dirname, entry->d_name);
            if (stat(path, &file_stat) == 0) {
                printf("%s: %lu\n", entry->d_name, file_stat.st_ino);
            } else {
                perror("stat");
            }
        }
    }

    closedir(dp);
}

int main() {
    char input[1024];

    while (1) {
        // Display the command prompt
        printf("myshell$ ");
        fflush(stdout);

        // Read the input command
        if (!fgets(input, sizeof(input), stdin)) {
            perror("fgets");
            exit(EXIT_FAILURE);
        }

        // Remove newline character from input
        input[strcspn(input, "\n")] = '\0';

        // Tokenize the command line
        char *token = strtok(input, " ");
        if (!token) continue; // No command entered

        // Check for 'list' command
        if (strcmp(token, "list") == 0) {
            token = strtok(NULL, " ");
            if (!token) continue; // Missing option

            char *option = token;
            token = strtok(NULL, " ");
            if (!token) continue; // Missing directory name

            char *dirname = token;

            if (strcmp(option, "f") == 0) {
                // Fork and exec to run the list files command
                pid_t pid = fork();
                if (pid == 0) {
                    // Child process
                    list_files(dirname);
                    exit(EXIT_SUCCESS);
                } else if (pid > 0) {
                    // Parent process
                    wait(NULL); // Wait for child process to finish
                } else {
                    perror("fork");
                }
            } else if (strcmp(option, "i") == 0) {
                // Fork and exec to run the list files with inodes command
                pid_t pid = fork();
                if (pid == 0) {
                    // Child process
                    list_files_with_inodes(dirname);
                    exit(EXIT_SUCCESS);
                } else if (pid > 0) {
                    // Parent process
                    wait(NULL); // Wait for child process to finish
                } else {
                    perror("fork");
                }
            } else {
                printf("Invalid option. Use 'f' for files or 'i' for files with inodes.\n");
            }
        } else {
            printf("Invalid command. Use 'list' followed by option and directory name.\n");
        }
    }

    return 0;
}