Skip to content

Commit

Permalink
shell, the gate of hell
Browse files Browse the repository at this point in the history
  • Loading branch information
Musoye committed Nov 7, 2022
1 parent 7983fc3 commit 4d4b322
Show file tree
Hide file tree
Showing 23 changed files with 2,689 additions and 4 deletions.
152 changes: 152 additions & 0 deletions alias_builtins.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
#include "shell.h"

int shellby_alias(char **args, char __attribute__((__unused__)) **front);
void set_alias(char *var_name, char *value);
void print_alias(alias_t *alias);

/**
* shellby_alias - Builtin command that either prints all aliases, specific
* aliases, or sets an alias.
* @args: An array of arguments.
* @front: A double pointer to the beginning of args.
*
* Return: If an error occurs - -1.
* Otherwise - 0.
*/
int shellby_alias(char **args, char __attribute__((__unused__)) **front)
{
alias_t *temp = aliases;
int i, ret = 0;
char *value;

if (!args[0])
{
while (temp)
{
print_alias(temp);
temp = temp->next;
}
return (ret);
}
for (i = 0; args[i]; i++)
{
temp = aliases;
value = _strchr(args[i], '=');
if (!value)
{
while (temp)
{
if (_strcmp(args[i], temp->name) == 0)
{
print_alias(temp);
break;
}
temp = temp->next;
}
if (!temp)
ret = create_error(args + i, 1);
}
else
set_alias(args[i], value);
}
return (ret);
}

/**
* set_alias - Will either set an existing alias 'name' with a new value,
* 'value' or creates a new alias with 'name' and 'value'.
* @var_name: Name of the alias.
* @value: Value of the alias. First character is a '='.
*/
void set_alias(char *var_name, char *value)
{
alias_t *temp = aliases;
int len, j, k;
char *new_value;

*value = '\0';
value++;
len = _strlen(value) - _strspn(value, "'\"");
new_value = malloc(sizeof(char) * (len + 1));
if (!new_value)
return;
for (j = 0, k = 0; value[j]; j++)
{
if (value[j] != '\'' && value[j] != '"')
new_value[k++] = value[j];
}
new_value[k] = '\0';
while (temp)
{
if (_strcmp(var_name, temp->name) == 0)
{
free(temp->value);
temp->value = new_value;
break;
}
temp = temp->next;
}
if (!temp)
add_alias_end(&aliases, var_name, new_value);
}

/**
* print_alias - Prints the alias in the format name='value'.
* @alias: Pointer to an alias.
*/
void print_alias(alias_t *alias)
{
char *alias_string;
int len = _strlen(alias->name) + _strlen(alias->value) + 4;

alias_string = malloc(sizeof(char) * (len + 1));
if (!alias_string)
return;
_strcpy(alias_string, alias->name);
_strcat(alias_string, "='");
_strcat(alias_string, alias->value);
_strcat(alias_string, "'\n");

write(STDOUT_FILENO, alias_string, len);
free(alias_string);
}
/**
* replace_aliases - Goes through the arguments and replace any matching alias
* with their value.
* @args: 2D pointer to the arguments.
*
* Return: 2D pointer to the arguments.
*/
char **replace_aliases(char **args)
{
alias_t *temp;
int i;
char *new_value;

if (_strcmp(args[0], "alias") == 0)
return (args);
for (i = 0; args[i]; i++)
{
temp = aliases;
while (temp)
{
if (_strcmp(args[i], temp->name) == 0)
{
new_value = malloc(sizeof(char) * (_strlen(temp->value) + 1));
if (!new_value)
{
free_args(args, args);
return (NULL);
}
_strcpy(new_value, temp->value);
free(args[i]);
args[i] = new_value;
i--;
break;
}
temp = temp->next;
}
}

return (args);
}
192 changes: 192 additions & 0 deletions builtin.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
#include "shell.h"
int (*get_builtin(char *command))(char **args, char **front);
int shellby_exit(char **args, char **front);
int shellby_cd(char **args, char __attribute__((__unused__)) **front);
int shellby_help(char **args, char __attribute__((__unused__)) **front);

/**
* get_builtin - Matches a command with a corresponding
* shellby builtin function.
* @command: The command to match.
*
* Return: A function pointer to the corresponding builtin.
*/
int (*get_builtin(char *command))(char **args, char **front)
{
builtin_t funcs[] = {
{ "exit", shellby_exit },
{ "env", shellby_env },
{ "setenv", shellby_setenv },
{ "unsetenv", shellby_unsetenv },
{ "cd", shellby_cd },
{ "alias", shellby_alias },
{ "help", shellby_help },
{ NULL, NULL }
};
int i;

for (i = 0; funcs[i].name; i++)
{
if (_strcmp(funcs[i].name, command) == 0)
break;
}
return (funcs[i].f);
}

/**
* shellby_exit - Causes normal process termination
* for the shellby shell.
* @args: An array of arguments containing the exit value.
* @front: A double pointer to the beginning of args.
*
* Return: If there are no arguments - -3.
* If the given exit value is invalid - 2.
* O/w - exits with the given status value.
*
* Description: Upon returning -3, the program exits back in the main function.
*/
int shellby_exit(char **args, char **front)
{
int i, len_of_int = 10;
unsigned int num = 0, max = 1 << (sizeof(int) * 8 - 1);

if (args[0])
{
if (args[0][0] == '+')
{
i = 1;
len_of_int++;
}
for (; args[0][i]; i++)
{
if (i <= len_of_int && args[0][i] >= '0' && args[0][i] <= '9')
num = (num * 10) + (args[0][i] - '0');
else
return (create_error(--args, 2));
}
}
else
{
return (-3);
}
if (num > max - 1)
return (create_error(--args, 2));
args -= 1;
free_args(args, front);
free_env();
free_alias_list(aliases);
exit(num);
}

/**
* shellby_cd - Changes the current directory of the shellby process.
* @args: An array of arguments.
* @front: A double pointer to the beginning of args.
*
* Return: If the given string is not a directory - 2.
* If an error occurs - -1.
* Otherwise - 0.
*/
int shellby_cd(char **args, char __attribute__((__unused__)) **front)
{
char **dir_info, *new_line = "\n";
char *oldpwd = NULL, *pwd = NULL;
struct stat dir;

oldpwd = getcwd(oldpwd, 0);
if (!oldpwd)
return (-1);

if (args[0])
{
if (*(args[0]) == '-' || _strcmp(args[0], "--") == 0)
{
if ((args[0][1] == '-' && args[0][2] == '\0') ||
args[0][1] == '\0')
{
if (_getenv("OLDPWD") != NULL)
(chdir(*_getenv("OLDPWD") + 7));
}
else
{
free(oldpwd);
return (create_error(args, 2));
}
}
else
{
if (stat(args[0], &dir) == 0 && S_ISDIR(dir.st_mode)
&& ((dir.st_mode & S_IXUSR) != 0))
chdir(args[0]);
else
{
free(oldpwd);
return (create_error(args, 2));
}
}
}
else
{
if (_getenv("HOME") != NULL)
chdir(*(_getenv("HOME")) + 5);
}

pwd = getcwd(pwd, 0);
if (!pwd)
return (-1);

dir_info = malloc(sizeof(char *) * 2);
if (!dir_info)
return (-1);

dir_info[0] = "OLDPWD";
dir_info[1] = oldpwd;
if (shellby_setenv(dir_info, dir_info) == -1)
return (-1);

dir_info[0] = "PWD";
dir_info[1] = pwd;
if (shellby_setenv(dir_info, dir_info) == -1)
return (-1);
if (args[0] && args[0][0] == '-' && args[0][1] != '-')
{
write(STDOUT_FILENO, pwd, _strlen(pwd));
write(STDOUT_FILENO, new_line, 1);
}
free(oldpwd);
free(pwd);
free(dir_info);
return (0);
}

/**
* shellby_help - Displays information about shellby builtin commands.
* @args: An array of arguments.
* @front: A pointer to the beginning of args.
*
* Return: If an error occurs - -1.
* Otherwise - 0.
*/
int shellby_help(char **args, char __attribute__((__unused__)) **front)
{
if (!args[0])
help_all();
else if (_strcmp(args[0], "alias") == 0)
help_alias();
else if (_strcmp(args[0], "cd") == 0)
help_cd();
else if (_strcmp(args[0], "exit") == 0)
help_exit();
else if (_strcmp(args[0], "env") == 0)
help_env();
else if (_strcmp(args[0], "setenv") == 0)
help_setenv();
else if (_strcmp(args[0], "unsetenv") == 0)
help_unsetenv();
else if (_strcmp(args[0], "help") == 0)
help_help();
else
write(STDERR_FILENO, name, _strlen(name));

return (0);
}
Loading

0 comments on commit 4d4b322

Please sign in to comment.