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 commands.
myshell$ search a filename pattern : To search all the occurrence of pattern in the file.
myshell$ search c filename pattern : To count the number of occurrence of pattern in the file.

 #include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <unistd.h>

#include <sys/types.h>

#include <sys/wait.h>

#include <fcntl.h>


#define MAX_INPUT_SIZE 1024

#define MAX_TOKENS 100


void execute_command(char **tokens) {

    pid_t pid = fork();

    if (pid < 0) {

        perror("fork failed");

        exit(EXIT_FAILURE);

    } else if (pid == 0) {

        // Child process

        execvp(tokens[0], tokens);

        perror("execvp failed");

        exit(EXIT_FAILURE);

    } else {

        // Parent process

        int status;

        waitpid(pid, &status, 0);

    }

}


void search_occurrences(const char *filename, const char *pattern) {

    FILE *file = fopen(filename, "r");

    if (file == NULL) {

        perror("fopen failed");

        return;

    }


    char line[MAX_INPUT_SIZE];

    int found = 0;

    while (fgets(line, sizeof(line), file)) {

        if (strstr(line, pattern) != NULL) {

            printf("%s", line);

            found = 1;

        }

    }


    if (!found) {

        printf("No occurrences of pattern \"%s\" found in file \"%s\".\n", pattern, filename);

    }


    fclose(file);

}


void count_occurrences(const char *filename, const char *pattern) {

    FILE *file = fopen(filename, "r");

    if (file == NULL) {

        perror("fopen failed");

        return;

    }


    char line[MAX_INPUT_SIZE];

    int count = 0;

    while (fgets(line, sizeof(line), file)) {

        char *pos = line;

        while ((pos = strstr(pos, pattern)) != NULL) {

            count++;

            pos += strlen(pattern);

        }

    }


    printf("Number of occurrences of pattern \"%s\" in file \"%s\": %d\n", pattern, filename, count);


    fclose(file);

}


int main() {

    char input[MAX_INPUT_SIZE];


    while (1) {

        printf("myshell$ ");

        if (fgets(input, sizeof(input), stdin) == NULL) {

            perror("fgets failed");

            exit(EXIT_FAILURE);

        }


        // Remove trailing newline

        input[strcspn(input, "\n")] = '\0';


        char *tokens[MAX_TOKENS];

        int token_count = 0;


        // Tokenize the input

        char *token = strtok(input, " ");

        while (token != NULL && token_count < MAX_TOKENS - 1) {

            tokens[token_count++] = token;

            token = strtok(NULL, " ");

        }

        tokens[token_count] = NULL;


        // Check if it's a special search command

        if (token_count >= 3 && strcmp(tokens[0], "search") == 0) {

            if (strcmp(tokens[1], "a") == 0 && token_count == 4) {

                // search a filename pattern

                search_occurrences(tokens[2], tokens[3]);

            } else if (strcmp(tokens[1], "c") == 0 && token_count == 4) {

                // search c filename pattern

                count_occurrences(tokens[2], tokens[3]);

            } else {

                printf("Usage: search [a|c] filename pattern\n");

            }

        } else {

            // Execute other commands

            execute_command(tokens);

        }

    }


    return 0;

}