From 6c35c9f183329346e8e848553b2cf05e2a4e37ae Mon Sep 17 00:00:00 2001 From: hellisabove Date: Mon, 25 Apr 2022 16:51:36 +0300 Subject: [PATCH] When using cd it will change directory to home if not specifying directory --- LICENSE | 124 +++++++-------- Makefile | 50 +++---- shell.c | 447 ++++++++++++++++++++++++++++--------------------------- 3 files changed, 314 insertions(+), 307 deletions(-) diff --git a/LICENSE b/LICENSE index 74e7e58..a589e75 100644 --- a/LICENSE +++ b/LICENSE @@ -1,62 +1,62 @@ -Author's Integrity License v 0.4 -Copyright 2022 - hellisabove - -1. License - Suckless Atributed Shell (sash) is made available free of charge to any - Individual for personal use provided Limitations (Section 2) are observed. - - The Author hereby grants a license to any Creative to freely use, sample, remix, - or redistribute the Work provided Limitations (Section 2) are observed. - -2. Limitations - 2.1 Redistribution Integrity - 2.1.1 Redistribution of the Work is permitted, except in the following instances: - • Linking to, embedding, re-uploading, or otherwise sharing the Work using thumbnails, headlines, - or body copy which mislead or Misrepresent the Work of the Author OR - • No omission of any part of the original Work has occurred. (See Section 2.2) - 2.2 Derivative Works - 2.2.1 The Creative may sample portions of the Original Content except when Derivative works: - • Intentionally Misrepresent the Original Content OR - • Include Sponsored or Paid Content (in part or in full) - 2.3 Expressly Prohibited Usage - 2.3.1 The use of the Work for the purpose of training neural networks, artificial - intelligence, computer learning algorithms, or voice recognition software (collectively, GANs) is - expressly forbidden. - • Voice recognition software for the purpose of creating text transcripts - of the Work is allowed if: - ◦ The terms of Derivative Works (Section 2.2) are met AND - ◦ Training data are NOT stored AND - ◦ The Author has NOT marked the Work as unavailable for text transcription - either in the Work's metadata or within the Work itself - 2.3.2 The use of the Work in the production of so-called Deepfakes. This includes but is - not limited to: - • Synthesizing the likeness of the Author (or any persons included in this Work) including - visual, audio, or other mediums OR - • Synthesizing the writing style, speech patterns, or other attributes of the Work - 2.3.3 The inclusion of this section is not intended to be an exhaustive list of - prohibited uses. -3. Intent - - The purpose of this license is to preserve the integrity of the Author’s message, their - intent, and the context of the Author’s protected Work. - - This license SHOULD NOT be interpreted as a means of shielding the Author or the Work - from criticism, parody, satire, or other protected speech. - - The abuse thereof would constitute an UNAUTHORIZED REMIX of these terms (this document - is recursively licensed) and would result in a nullification of Author’s right to apply - these terms to their own Work. - - (See Section 2.2 Derivative Works) - -4. Licensing - The terms of this license apply to ALL Derivatives of this Work. Any Creative who makes a - Derivative Work using the Original Content—or who Redistributes the Work—agrees to be - bound by the terms laid out in this license. - - Failure to comply with these terms will result in the non-compliant Creative having their - license to use the Work rescinded, past and future licenses from the same non-compliant - Author nullified (at the original Author’s discretion), and possible legal action taken on - behalf of the original Author. - - Supplemental information can be found at github.com/heavyelement/ail +Author's Integrity License v 0.4 +Copyright 2022 - hellisabove + +1. License + Suckless Atributed Shell (sash) is made available free of charge to any + Individual for personal use provided Limitations (Section 2) are observed. + + The Author hereby grants a license to any Creative to freely use, sample, remix, + or redistribute the Work provided Limitations (Section 2) are observed. + +2. Limitations + 2.1 Redistribution Integrity + 2.1.1 Redistribution of the Work is permitted, except in the following instances: + • Linking to, embedding, re-uploading, or otherwise sharing the Work using thumbnails, headlines, + or body copy which mislead or Misrepresent the Work of the Author OR + • No omission of any part of the original Work has occurred. (See Section 2.2) + 2.2 Derivative Works + 2.2.1 The Creative may sample portions of the Original Content except when Derivative works: + • Intentionally Misrepresent the Original Content OR + • Include Sponsored or Paid Content (in part or in full) + 2.3 Expressly Prohibited Usage + 2.3.1 The use of the Work for the purpose of training neural networks, artificial + intelligence, computer learning algorithms, or voice recognition software (collectively, GANs) is + expressly forbidden. + • Voice recognition software for the purpose of creating text transcripts + of the Work is allowed if: + ◦ The terms of Derivative Works (Section 2.2) are met AND + ◦ Training data are NOT stored AND + ◦ The Author has NOT marked the Work as unavailable for text transcription + either in the Work's metadata or within the Work itself + 2.3.2 The use of the Work in the production of so-called Deepfakes. This includes but is + not limited to: + • Synthesizing the likeness of the Author (or any persons included in this Work) including + visual, audio, or other mediums OR + • Synthesizing the writing style, speech patterns, or other attributes of the Work + 2.3.3 The inclusion of this section is not intended to be an exhaustive list of + prohibited uses. +3. Intent + + The purpose of this license is to preserve the integrity of the Author’s message, their + intent, and the context of the Author’s protected Work. + + This license SHOULD NOT be interpreted as a means of shielding the Author or the Work + from criticism, parody, satire, or other protected speech. + + The abuse thereof would constitute an UNAUTHORIZED REMIX of these terms (this document + is recursively licensed) and would result in a nullification of Author’s right to apply + these terms to their own Work. + + (See Section 2.2 Derivative Works) + +4. Licensing + The terms of this license apply to ALL Derivatives of this Work. Any Creative who makes a + Derivative Work using the Original Content—or who Redistributes the Work—agrees to be + bound by the terms laid out in this license. + + Failure to comply with these terms will result in the non-compliant Creative having their + license to use the Work rescinded, past and future licenses from the same non-compliant + Author nullified (at the original Author’s discretion), and possible legal action taken on + behalf of the original Author. + + Supplemental information can be found at github.com/heavyelement/ail diff --git a/Makefile b/Makefile index 8a504f4..1359e6b 100644 --- a/Makefile +++ b/Makefile @@ -1,25 +1,25 @@ -OBJS = shell.o -SOURCE = shell.c -OUT = sash -CC = cc -FLAGS = -g -c -LFLAGS = -lreadline -PREFIX = local -DESTDIR = /usr/ -all: $(OBJS) - $(CC) -g $(OBJS) -o $(OUT) $(LFLAGS) - -shell.o: shell.c - $(CC) $(FLAGS) shell.c - -install: all - @echo installing executable file to ${DESTDIR}${PREFIX}/bin - @mkdir -p ${DESTDIR}${PREFIX}/bin - @cp -f sash ${DESTDIR}${PREFIX}/bin - @chmod 755 ${DESTDIR}${PREFIX}/bin/sash - @chmod u+s ${DESTDIR}${PREFIX}/bin/sash - @echo "/usr/local/bin/sash" >> /etc/shells - -clean: - @echo cleaning - @rm -f sash $(OBJS) +OBJS = shell.o +SOURCE = shell.c +OUT = sash +CC = cc +FLAGS = -g -c +LFLAGS = -lreadline +PREFIX = local +DESTDIR = /usr/ +all: $(OBJS) + $(CC) -g $(OBJS) -o $(OUT) $(LFLAGS) + +shell.o: shell.c + $(CC) $(FLAGS) shell.c + +install: all + @echo installing executable file to ${DESTDIR}${PREFIX}/bin + @mkdir -p ${DESTDIR}${PREFIX}/bin + @cp -f sash ${DESTDIR}${PREFIX}/bin + @chmod 755 ${DESTDIR}${PREFIX}/bin/sash + @chmod u+s ${DESTDIR}${PREFIX}/bin/sash + @echo "/usr/local/bin/sash" >> /etc/shells + +clean: + @echo cleaning + @rm -f sash $(OBJS) diff --git a/shell.c b/shell.c index e599000..6c31150 100644 --- a/shell.c +++ b/shell.c @@ -1,220 +1,227 @@ -// C Program to design a shell in Linux -#include -#include -#include -#include -#include -#include -#include -#include - -#define MAXCOM 1000 // max number of letters to be supported -#define MAXLIST 100 // max number of commands to be supported - -// Clearing the shell using escape sequences -#define clear() printf("\033[H\033[J") - -// Function to take input -int takeInput(char* str) -{ - char* buf; - - buf = readline("\n$ "); - if (strlen(buf) != 0) { - add_history(buf); - strcpy(str, buf); - return 0; - } else { - return 1; - } -} - -// Function where the system command is executed -void execArgs(char** parsed) -{ - // Forking a child - pid_t pid = fork(); - - if (pid == -1) { - printf("\nFailed forking child.."); - return; - } else if (pid == 0) { - if (execvp(parsed[0], parsed) < 0) { - printf("\nsh: command not found: \%s", parsed[0]); - } - exit(0); - } else { - // waiting for child to terminate - wait(NULL); - return; - } -} - -// Function where the piped system commands is executed -void execArgsPiped(char** parsed, char** parsedpipe) -{ - // 0 is read end, 1 is write end - int pipefd[2]; - pid_t p1, p2; - - if (pipe(pipefd) < 0) { - printf("\nPipe could not be initialized"); - return; - } - p1 = fork(); - if (p1 < 0) { - printf("\nCould not fork"); - return; - } - - if (p1 == 0) { - // Child 1 executing.. - // It only needs to write at the write end - close(pipefd[0]); - dup2(pipefd[1], STDOUT_FILENO); - close(pipefd[1]); - - if (execvp(parsed[0], parsed) < 0) { - printf("\nsh: command not found: \%s", parsed[0], parsedpipe[0]); - exit(0); - } - } else { - // Parent executing - p2 = fork(); - - if (p2 < 0) { - printf("\nCould not fork"); - return; - } - - // Child 2 executing.. - // It only needs to read at the read end - if (p2 == 0) { - close(pipefd[1]); - dup2(pipefd[0], STDIN_FILENO); - close(pipefd[0]); - if (execvp(parsedpipe[0], parsedpipe) < 0) { - printf("\nsh: command not found: \%s", parsedpipe[0]); - exit(0); - } - } else { - // parent executing, waiting for two children - wait(NULL); - wait(NULL); - } - } -} - -// Function to execute builtin commands -int ownCmdHandler(char** parsed) -{ - int NoOfOwnCmds = 2, i, switchOwnArg = 0; - char* ListOfOwnCmds[NoOfOwnCmds]; - char* username; - - ListOfOwnCmds[0] = "exit"; - ListOfOwnCmds[1] = "cd"; - - for (i = 0; i < NoOfOwnCmds; i++) { - if (strcmp(parsed[0], ListOfOwnCmds[i]) == 0) { - switchOwnArg = i + 1; - break; - } - } - - switch (switchOwnArg) { - case 1: - exit(0); - case 2: - chdir(parsed[1]); - return 1; - default: - break; - } - - return 0; -} - -// function for finding pipe -int parsePipe(char* str, char** strpiped) -{ - int i; - for (i = 0; i < 2; i++) { - strpiped[i] = strsep(&str, "|"); - if (strpiped[i] == NULL) - break; - } - - if (strpiped[1] == NULL) - return 0; // returns zero if no pipe is found. - else { - return 1; - } -} - -// function for parsing command words -void parseSpace(char* str, char** parsed) -{ - int i; - - for (i = 0; i < MAXLIST; i++) { - parsed[i] = strsep(&str, " "); - - if (parsed[i] == NULL) - break; - if (strlen(parsed[i]) == 0) - i--; - } -} - -int processString(char* str, char** parsed, char** parsedpipe) -{ - - char* strpiped[2]; - int piped = 0; - - piped = parsePipe(str, strpiped); - - if (piped) { - parseSpace(strpiped[0], parsed); - parseSpace(strpiped[1], parsedpipe); - - } else { - - parseSpace(str, parsed); - } - - if (ownCmdHandler(parsed)) - return 0; - else - return 1 + piped; -} - -int main() -{ - char inputString[MAXCOM], *parsedArgs[MAXLIST]; - char* parsedArgsPiped[MAXLIST]; - int execFlag = 0; - - while (1) { - // take input - if (takeInput(inputString)) - continue; - // process - execFlag = processString(inputString, - parsedArgs, parsedArgsPiped); - // execflag returns zero if there is no command - // or it is a builtin command, - // 1 if it is a simple command - // 2 if it is including a pipe. - - // execute - if (execFlag == 1) - execArgs(parsedArgs); - - if (execFlag == 2) - execArgsPiped(parsedArgs, parsedArgsPiped); - } - return 0; -} - +// C Program to design a shell in Linux +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MAXCOM 1000 // max number of letters to be supported +#define MAXLIST 100 // max number of commands to be supported + +// Clearing the shell using escape sequences +#define clear() printf("\033[H\033[J") + +// Function to take input +int takeInput(char* str) +{ + char* buf; + + buf = readline("\n$ "); + if (strlen(buf) != 0) { + add_history(buf); + strcpy(str, buf); + return 0; + } else { + return 1; + } +} + +// Function where the system command is executed +void execArgs(char** parsed) +{ + // Forking a child + pid_t pid = fork(); + + if (pid == -1) { + printf("\nFailed forking child.."); + return; + } else if (pid == 0) { + if (execvp(parsed[0], parsed) < 0) { + printf("\nsh: command not found: \%s", parsed[0]); + } + exit(0); + } else { + // waiting for child to terminate + wait(NULL); + return; + } +} + +// Function where the piped system commands is executed +void execArgsPiped(char** parsed, char** parsedpipe) +{ + // 0 is read end, 1 is write end + int pipefd[2]; + pid_t p1, p2; + + if (pipe(pipefd) < 0) { + printf("\nPipe could not be initialized"); + return; + } + p1 = fork(); + if (p1 < 0) { + printf("\nCould not fork"); + return; + } + + if (p1 == 0) { + // Child 1 executing.. + // It only needs to write at the write end + close(pipefd[0]); + dup2(pipefd[1], STDOUT_FILENO); + close(pipefd[1]); + + if (execvp(parsed[0], parsed) < 0) { + printf("\nsh: command not found: \%s", parsed[0], parsedpipe[0]); + exit(0); + } + } else { + // Parent executing + p2 = fork(); + + if (p2 < 0) { + printf("\nCould not fork"); + return; + } + + // Child 2 executing.. + // It only needs to read at the read end + if (p2 == 0) { + close(pipefd[1]); + dup2(pipefd[0], STDIN_FILENO); + close(pipefd[0]); + if (execvp(parsedpipe[0], parsedpipe) < 0) { + printf("\nsh: command not found: \%s", parsedpipe[0]); + exit(0); + } + } else { + // parent executing, waiting for two children + wait(NULL); + wait(NULL); + } + } +} + +// Function to execute builtin commands +int ownCmdHandler(char** parsed) +{ + int NoOfOwnCmds = 2, i, switchOwnArg = 0; + char* ListOfOwnCmds[NoOfOwnCmds]; + char* username; + + ListOfOwnCmds[0] = "exit"; + ListOfOwnCmds[1] = "cd"; + + for (i = 0; i < NoOfOwnCmds; i++) { + if (strcmp(parsed[0], ListOfOwnCmds[i]) == 0) { + switchOwnArg = i + 1; + break; + } + } + + switch (switchOwnArg) { + case 1: + exit(0); + case 2: + if(parsed[1]){ + chdir(parsed[1]); + return 1; + } else { + char *home = getenv("HOME"); + chdir(home); + return 1; + } + default: + break; + } + + return 0; +} + +// function for finding pipe +int parsePipe(char* str, char** strpiped) +{ + int i; + for (i = 0; i < 2; i++) { + strpiped[i] = strsep(&str, "|"); + if (strpiped[i] == NULL) + break; + } + + if (strpiped[1] == NULL) + return 0; // returns zero if no pipe is found. + else { + return 1; + } +} + +// function for parsing command words +void parseSpace(char* str, char** parsed) +{ + int i; + + for (i = 0; i < MAXLIST; i++) { + parsed[i] = strsep(&str, " "); + + if (parsed[i] == NULL) + break; + if (strlen(parsed[i]) == 0) + i--; + } +} + +int processString(char* str, char** parsed, char** parsedpipe) +{ + + char* strpiped[2]; + int piped = 0; + + piped = parsePipe(str, strpiped); + + if (piped) { + parseSpace(strpiped[0], parsed); + parseSpace(strpiped[1], parsedpipe); + + } else { + + parseSpace(str, parsed); + } + + if (ownCmdHandler(parsed)) + return 0; + else + return 1 + piped; +} + +int main() +{ + char inputString[MAXCOM], *parsedArgs[MAXLIST]; + char* parsedArgsPiped[MAXLIST]; + int execFlag = 0; + + while (1) { + // take input + if (takeInput(inputString)) + continue; + // process + execFlag = processString(inputString, + parsedArgs, parsedArgsPiped); + // execflag returns zero if there is no command + // or it is a builtin command, + // 1 if it is a simple command + // 2 if it is including a pipe. + + // execute + if (execFlag == 1) + execArgs(parsedArgs); + + if (execFlag == 2) + execArgsPiped(parsedArgs, parsedArgsPiped); + } + return 0; +} +