Skip to content
Snippets Groups Projects
Select Git revision
  • 65eec2b982e055a7b0cef577bdada56b8cc402cd
  • master default
2 results

dsh_cli.c

Blame
  • user avatar
    vht24 authored
    b56d02a0
    History
    dsh_cli.c 4.59 KiB
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <zlib.h>  // For decompression
    
    #include "dshlib.h"
    
    /*
     * Implement your main function by building a loop that prompts the
     * user for input.  Use the SH_PROMPT constant from dshlib.h and then
     * use fgets to accept user input.  Since we want fgets to also handle
     * end of file so we can run this headless for testing we need to check
     * the return code of fgets.  I have provided an example below of how
     * to do this assuming you are storing user input inside of the cmd_buff
     * variable.
     *
     *      while(1){
     *        printf("%s", SH_PROMPT);
     *        if (fgets(cmd_buff, ARG_MAX, stdin) == NULL){
     *           printf("\n");
     *           break;
     *        }
     *        //remove the trailing \n from cmd_buff
     *        cmd_buff[strcspn(cmd_buff,"\n")] = '\0';
     *
     *        //IMPLEMENT THE REST OF THE REQUIREMENTS
     *      }
     *
     *   Also, use the constants in the dshlib.h in this code.
     *      SH_CMD_MAX              maximum buffer size for user input
     *      EXIT_CMD                constant that terminates the dsh program
     *      SH_PROMPT               the shell prompt
     *      OK                      the command was parsed properly
     *      WARN_NO_CMDS            the user command was empty
     *      ERR_TOO_MANY_COMMANDS   too many pipes used
     *
     *   Expected output:
     *
     *      CMD_OK_HEADER      if the command parses properly. You will
     *                         follow this by the command details
     *
     *      CMD_WARN_NO_CMD    if the user entered a blank command
     *      CMD_ERR_PIPE_LIMIT if the user entered too many commands using
     *                         the pipe feature, e.g., cmd1 | cmd2 | ... |
     *
     *  See the provided test cases for output expectations.
     */
    
    #define DRAGON_FILE "dragon.bin"
    #define DRAGON_BUFFER_SIZE 100000
    
    void print_dragon_from_file() {
        FILE *file = fopen(DRAGON_FILE, "rb");
        if (!file) {
            fprintf(stderr, "Error: Could not open %s\n", DRAGON_FILE);
            return;
        }
    
        // Determine the size of the compressed file
        fseek(file, 0, SEEK_END);
        long file_size = ftell(file);
        rewind(file);
    
        unsigned char *compressed_data = (unsigned char *)malloc(file_size);
        if (!compressed_data) {
            fprintf(stderr, "Memory allocation failed!\n");
            fclose(file);
            return;
        }
    
        // Read the compressed data from the file
        fread(compressed_data, 1, file_size, file);
        fclose(file);
    
        unsigned char *decompressed_data = (unsigned char *)malloc(DRAGON_BUFFER_SIZE);
        if (!decompressed_data) {
            fprintf(stderr, "Memory allocation failed!\n");
            free(compressed_data);
            return;
        }
    
        // Decompress the data
        uLongf decompressed_size = DRAGON_BUFFER_SIZE;
        if (uncompress(decompressed_data, &decompressed_size, compressed_data, file_size) != Z_OK) {
            fprintf(stderr, "Decompression failed!\n");
            free(compressed_data);
            free(decompressed_data);
            return;
        }
    
        printf("%s", decompressed_data);
    
        free(compressed_data);
        free(decompressed_data);
    }
    
    int main()
    {
        char *cmd_buff = (char *)malloc(SH_CMD_MAX * sizeof(char));
        if (cmd_buff == NULL) {
            fprintf(stderr, "Memory allocation failed!\n");
            return -1;
        }
    
        command_list_t clist;
    
        while (1) {
            printf("%s", SH_PROMPT);
            if (fgets(cmd_buff, SH_CMD_MAX, stdin) == NULL) {
                printf("\n");
                break;
            }
    
            // Remove the trailing newline character
            cmd_buff[strcspn(cmd_buff, "\n")] = '\0';
    
            // Check for empty command
            if (strlen(cmd_buff) == 0) {
                printf(CMD_WARN_NO_CMD);
                continue;
            }
    
            // Exit command
            if (strcmp(cmd_buff, EXIT_CMD) == 0) {
                break;
            }
    
            // Check for dragon command
            if (strcmp(cmd_buff, "dragon") == 0) {
                print_dragon_from_file();
                continue;
            }
    
            // Parse the command line
            int rc = build_cmd_list(cmd_buff, &clist);
    
            if (rc == ERR_TOO_MANY_COMMANDS) {
                printf(CMD_ERR_PIPE_LIMIT, CMD_MAX);
                continue;
            } else if (rc == ERR_CMD_OR_ARGS_TOO_BIG) {
                fprintf(stderr, "Error: Command or arguments too big.\n");
                continue;
            }
    
            // Display parsed commands
            printf(CMD_OK_HEADER, clist.num);
            for (int i = 0; i < clist.num; i++) {
                printf("<%d> %s", i + 1, clist.commands[i].exe);
                if (strlen(clist.commands[i].args) > 0) {
                    printf(" [%s]", clist.commands[i].args);
                }
                printf("\n");
            }
        }
    
        free(cmd_buff);
        return OK;
    }