Skip to content
Snippets Groups Projects
Select Git revision
  • 98d41d74f3e56be2fb4b1fb68c32e5051c1b55db
  • main default
2 results

sdbsc

Blame
  • dshlib.c 2.77 KiB
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    #include <ctype.h>
    
    #include "dshlib.h"
    
    /*
     * trim: Removes leading and trailing whitespace from a string in-place.
     * Returns a pointer to the first non-space character.
     */
    static char *trim(char *str)
    {
        /* Trim leading spaces */
        while (isspace((unsigned char)*str))
            str++;
    
        if (*str == '\0')  /* All spaces? */
            return str;
    
        /* Trim trailing spaces */
        char *end = str + strlen(str) - 1;
        while (end > str && isspace((unsigned char)*end)) {
            *end = '\0';
            end--;
        }
        return str;
    }
    
    /*
     * build_cmd_list:
     *   - Splits the provided cmd_line into commands separated by '|'
     *   - For each command it trims leading/trailing spaces and then splits the
     *     command into tokens (using whitespace as the delimiter).
     *   - The first token is stored in the exe field (if it is not too long).
     *   - Any subsequent tokens are concatenated (with no intervening spaces)
     *     and stored in the args field.
     *
     * Returns:
     *   OK if the command was parsed successfully.
     *   ERR_TOO_MANY_COMMANDS if more than CMD_MAX commands are specified.
     *   ERR_CMD_OR_ARGS_TOO_BIG if the executable or argument string exceeds its size.
     */
    int build_cmd_list(char *cmd_line, command_list_t *clist)
    {
        clist->num = 0;
        char *saveptr1;
        /* Use strtok_r to split the command line by the pipe '|' character */
        char *token = strtok_r(cmd_line, PIPE_STRING, &saveptr1);
        while (token != NULL) {
            char *trimmed = trim(token);
            if (strlen(trimmed) == 0) {
                token = strtok_r(NULL, PIPE_STRING, &saveptr1);
                continue;
            }
    
            if (clist->num >= CMD_MAX) {
                return ERR_TOO_MANY_COMMANDS;
            }
    
            char command_buffer[SH_CMD_MAX];
            strncpy(command_buffer, trimmed, sizeof(command_buffer) - 1);
            command_buffer[sizeof(command_buffer) - 1] = '\0';
    
            char *saveptr2;
            /* Use strtok_r to split the command_buffer by spaces */
            char *arg = strtok_r(command_buffer, " ", &saveptr2);
            if (arg == NULL) {
                token = strtok_r(NULL, PIPE_STRING, &saveptr1);
                continue;
            }
    
            if (strlen(arg) >= EXE_MAX) {
                return ERR_CMD_OR_ARGS_TOO_BIG;
            }
            strcpy(clist->commands[clist->num].exe, arg);
    
            /* Initialize the args string as empty */
            clist->commands[clist->num].args[0] = '\0';
    
            while ((arg = strtok_r(NULL, " ", &saveptr2)) != NULL) {
                if (strlen(clist->commands[clist->num].args) + strlen(arg) >= ARG_MAX) {
                    return ERR_CMD_OR_ARGS_TOO_BIG;
                }
                strcat(clist->commands[clist->num].args, arg);
            }
    
            clist->num++;
            token = strtok_r(NULL, PIPE_STRING, &saveptr1);
        }
    
        return OK;
    }