From 35df93be953e559b0fbdf76e9d7396332a1fd7c3 Mon Sep 17 00:00:00 2001 From: Itai-Nelken Date: Fri, 31 Dec 2021 14:19:21 +0200 Subject: [PATCH 1/4] Handle shell built-in commands Signed-off-by: Itai-Nelken --- dollarskip.c | 86 ++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 84 insertions(+), 2 deletions(-) diff --git a/dollarskip.c b/dollarskip.c index 7ea416e..934ef5a 100644 --- a/dollarskip.c +++ b/dollarskip.c @@ -2,11 +2,80 @@ #include #include #include +#include #ifndef COMMAND_MAX_SIZE #define COMMAND_MAX_SIZE 8096 #endif +/*** wrapped shell builtins ***/ +int easter_egg() { + printf("You found the DollarSkip easter egg!\n"); + return 0; +} + +/*** handled and unhandled shell builtins checks ***/ +const char *unhandled_shell_builtins[] = { + "cd" +}; +#define UNHANDLED_SHELL_BUILTINS_SIZE (sizeof(unhandled_shell_builtins) / sizeof(unhandled_shell_builtins[0])) + +typedef int (*wrapperFn)(); + +typedef struct wrapper { + wrapperFn func; + const char *name; // name HAS to be a string literal +} Wrapper; + +Wrapper handled_shell_builtins[] = { + {easter_egg, "e_egg"} // DollarSkip easter eff +}; +#define HANDLED_SHELL_BUILTINS_SIZE (sizeof(handled_shell_builtins) / sizeof(handled_shell_builtins[0])) + +bool handled_shell_builtin(const char *cmd, int *return_value) { + for(int i = 0; i < (int)HANDLED_SHELL_BUILTINS_SIZE; ++i) { + if(!strcmp(cmd, handled_shell_builtins[i].name)) { + if(return_value != NULL) { + *return_value = handled_shell_builtins[i].func(); + } else { + handled_shell_builtins[i].func(); + } + return true; + } + } + return false; +} + +bool is_unhandled_shell_builtin(const char *cmd) { + for(int i = 0; i < (int)UNHANDLED_SHELL_BUILTINS_SIZE; ++i) { + if(!strcmp(cmd, unhandled_shell_builtins[i])) { + return true; + } + } + return false; +} + +/*** Argument collecting and proccessing ***/ +void check_args(char *args) { + char *argsCopy = strdup(args); + char *p = strtok(argsCopy, " "); + int retval = 0; + while(p != NULL) { + if(handled_shell_builtin(p, &retval)) { + free(args); + free(argsCopy); + exit(retval); + } else if(is_unhandled_shell_builtin(p)) { + fprintf(stderr, "\x1b[31;1m[ERROR: DollarSkip]: built-in shell commands aren't supported!\x1b[0m\n"); + free(args); + free(argsCopy); + exit(1); + } + p = strtok(NULL, " "); + } + free(argsCopy); +} + /****** * Collect all the arguments (argv) excluding the first one (argv[0]) into a single string. * returned string is heap allocated so you have to free() it. @@ -26,11 +95,13 @@ char *collect_args(int argc, char **argv, size_t *argv_size) { argv_len += strlen(argv[i]) + 1; // 1 for the space and null terminator at the end } // if argv_size isn't NULL, dereference it and put argv_len in it. - if(argv_size != NULL) *argv_size = argv_len; + if(argv_size != NULL) + *argv_size = argv_len; // allocate memory for the argument string args = malloc(argv_len); - if(args == NULL) exit(1); + if(args == NULL) + exit(1); // copy all of argv (exluding argv[0]) to args and add a space after each argument for(int i = 1; i < argc; ++i) { @@ -42,6 +113,7 @@ char *collect_args(int argc, char **argv, size_t *argv_size) { return args; } +/*** main ***/ int main(int argc, char **argv) { // if arguments are provided if(argc > 1) { @@ -53,6 +125,13 @@ int main(int argc, char **argv) { size_t argv_len = 0; // collect arguments char *args = collect_args(argc, argv, &argv_len); + // we check if the arguments are something we can execute + // for example, we don't want to run built-in shell commands + // (for example: cd) because running them won't change anything for the user + // as they run in a separate shell. + // but we want to handle shell built-ins we wrapped (for example: pwd)/ + // check_args() does that for us. + check_args(args); // check that there is enough space in 'command' assert(argv_len + strlen(shell_env) + 6 < COMMAND_MAX_SIZE); // 6 = strlen(" -c ''") // and format them @@ -62,6 +141,9 @@ int main(int argc, char **argv) { size_t argv_len = 0; // collect the arguments char *args = collect_args(argc, argv, &argv_len); + if(args == NULL) { + return 1; + } // check that there is enough space in 'command' assert(argv_len < COMMAND_MAX_SIZE); // and copy them to the command variable unformatted From 785580389c7ee0f88ab7853b43c65883bcf0ded3 Mon Sep 17 00:00:00 2001 From: Itai-Nelken Date: Fri, 31 Dec 2021 14:45:28 +0200 Subject: [PATCH 2/4] Add more unhandled commands and update error message. Signed-off-by: Itai-Nelken --- dollarskip.c | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/dollarskip.c b/dollarskip.c index 934ef5a..8379265 100644 --- a/dollarskip.c +++ b/dollarskip.c @@ -16,7 +16,30 @@ int easter_egg() { /*** handled and unhandled shell builtins checks ***/ const char *unhandled_shell_builtins[] = { - "cd" + "cd", + "alias", + "unalias", + "pushd", + "popd", + "dirs", + "read", + "set", + "readonly", + "unset", + "typeset", + "declare", + "disown", + "enable", + "export", + "exit", // doesn't do anything when run through DollarSkip + "fc", + "history", + "fg", + "getopts", + "hash", // we don't want it to report fake data dor the current shell (true for the shell in which it is run) + "jobs", // same reason as the one for 'hash' + "times", // same as above + "local" }; #define UNHANDLED_SHELL_BUILTINS_SIZE (sizeof(unhandled_shell_builtins) / sizeof(unhandled_shell_builtins[0])) @@ -66,7 +89,7 @@ void check_args(char *args) { free(argsCopy); exit(retval); } else if(is_unhandled_shell_builtin(p)) { - fprintf(stderr, "\x1b[31;1m[ERROR: DollarSkip]: built-in shell commands aren't supported!\x1b[0m\n"); + fprintf(stderr, "\x1b[31;1m[ERROR: DollarSkip]: '\x1b[97m%s\x1b[0;1;31m': built-in shell commands aren't supported!\x1b[0m\n", p); free(args); free(argsCopy); exit(1); From 4165c18bab82954e48fe16323e3601138fd36077 Mon Sep 17 00:00:00 2001 From: Itai Nelken <70802936+Itai-Nelken@users.noreply.github.com> Date: Fri, 31 Dec 2021 15:30:37 +0200 Subject: [PATCH 3/4] Update dollarskip.c Co-authored-by: CleanMachine1 <78213164+CleanMachine1@users.noreply.github.com> --- dollarskip.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dollarskip.c b/dollarskip.c index 8379265..3346d28 100644 --- a/dollarskip.c +++ b/dollarskip.c @@ -51,7 +51,7 @@ typedef struct wrapper { } Wrapper; Wrapper handled_shell_builtins[] = { - {easter_egg, "e_egg"} // DollarSkip easter eff + {easter_egg, "e_egg"} // DollarSkip easter egg }; #define HANDLED_SHELL_BUILTINS_SIZE (sizeof(handled_shell_builtins) / sizeof(handled_shell_builtins[0])) From 0f25633632aa019abec1a89674f1a173b0fb74c1 Mon Sep 17 00:00:00 2001 From: Itai Nelken <70802936+Itai-Nelken@users.noreply.github.com> Date: Fri, 31 Dec 2021 15:53:02 +0200 Subject: [PATCH 4/4] Update dollarskip.c --- dollarskip.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dollarskip.c b/dollarskip.c index 3346d28..5d68065 100644 --- a/dollarskip.c +++ b/dollarskip.c @@ -36,7 +36,7 @@ const char *unhandled_shell_builtins[] = { "history", "fg", "getopts", - "hash", // we don't want it to report fake data dor the current shell (true for the shell in which it is run) + "hash", // we don't want it to report fake data for the current shell (true for the shell in which it is run) "jobs", // same reason as the one for 'hash' "times", // same as above "local"