From 67161e1b7dda8f9ffe4a94e89b606dff31263768 Mon Sep 17 00:00:00 2001 From: luishernandez <lahr730@gmail.com> Date: Tue, 11 Feb 2025 17:39:25 -0500 Subject: [PATCH] 3-shellp1 --- dshlib.c | 93 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 dshlib.c diff --git a/dshlib.c b/dshlib.c new file mode 100644 index 0000000..3ee5c6c --- /dev/null +++ b/dshlib.c @@ -0,0 +1,93 @@ +#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; +} \ No newline at end of file -- GitLab