Skip to content
Snippets Groups Projects
Select Git revision
  • master
1 result

dshlib.h

Blame
  • dshlib.c 3.79 KiB
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    #include <ctype.h>
    
    #include "dshlib.h"
    
    /*
     *  build_cmd_list
     *    cmd_line:     the command line from the user
     *    clist *:      pointer to clist structure to be populated
     *
     *  This function builds the command_list_t structure passed by the caller
     *  It does this by first splitting the cmd_line into commands by spltting
     *  the string based on any pipe characters '|'.  It then traverses each
     *  command.  For each command (a substring of cmd_line), it then parses
     *  that command by taking the first token as the executable name, and
     *  then the remaining tokens as the arguments.
     *
     *  NOTE your implementation should be able to handle properly removing
     *  leading and trailing spaces!
     *
     *  errors returned:
     *
     *    OK:                      No Error
     *    ERR_TOO_MANY_COMMANDS:   There is a limit of CMD_MAX (see dshlib.h)
     *                             commands.
     *    ERR_CMD_OR_ARGS_TOO_BIG: One of the commands provided by the user
     *                             was larger than allowed, either the
     *                             executable name, or the arg string.
     *
     *  Standard Library Functions You Might Want To Consider Using
     *      memset(), strcmp(), strcpy(), strtok(), strlen(), strchr()
     */
    
    
    int build_cmd_list(char *cmd_line, command_list_t *clist) {
        if (cmd_line == NULL) {
            return ERR_CMD_OR_ARGS_TOO_BIG; //I lowkey don't know what other error to put 
        }
    
        char *original_line = strdup(cmd_line); //So we duplicate so I can then trimm it down
        if (original_line == NULL) {
            return ERR_CMD_OR_ARGS_TOO_BIG;
        }
    
        char *trimmed_line = original_line; // Use another pointer for trimming
    
        // Trim leading spaces
        while (*trimmed_line == ' ') {
            trimmed_line++;
        }
    
        // Trim trailing spaces
        size_t len = strlen(trimmed_line);
        while (len > 0 && trimmed_line[len - 1] == ' ') {
            trimmed_line[--len] = '\0';
        }
    
        int command_count = 0;
        char *saveptr1, *saveptr2; 
        char *command = strtok_r(trimmed_line, PIPE_STRING, &saveptr1); 
    	 //This is so I can reenter the string to reuse it again so strtok_r  would be easier
    
        while (command != NULL && command_count < CMD_MAX) { 
    	 //checks if over max and still variables
            memset(&clist->commands[command_count], 0, sizeof(command_t));
    
            // Parse the command and its arguments
            char *command_and_arguments = strtok_r(command, " ", &saveptr2);
            if (command_and_arguments != NULL) {
                if (strlen(command_and_arguments) >= EXE_MAX) {
                    free(original_line);
                    return ERR_CMD_OR_ARGS_TOO_BIG;
                }
                strcpy(clist->commands[command_count].exe, command_and_arguments);
    
                char *arg = strtok_r(NULL, " ", &saveptr2); //Checks argument by space 
    				//Space string thingy did not work 
                while (arg != NULL) {
                    if (strlen(clist->commands[command_count].args) + strlen(arg) + 1 >= ARG_MAX) {
                        free(original_line);
                        return ERR_CMD_OR_ARGS_TOO_BIG;
                    }
    
                    if (strlen(clist->commands[command_count].args) > 0) {
                        strcat(clist->commands[command_count].args, " ");
                    }
                    strcat(clist->commands[command_count].args, arg);
                    arg = strtok_r(NULL, " ", &saveptr2); //increment 
                }
            }
    
            command_count++; 
            command = strtok_r(NULL, PIPE_STRING, &saveptr1); // Get the next command
        }
    
        if (command != NULL) {// If it's empty it breaks, if it somehow breaks and not empty
    	 //It does not work 
            free(original_line);
            return ERR_TOO_MANY_COMMANDS;
        }
    
        clist->num = command_count;
        free(original_line); // Free the original pointer, not the modified one
        return OK;
    }