When using cd it will change directory to home if not specifying directory

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