change_directory
#include "main.h"
/**
* cd_dot - changes to the parent directory
* @my_data_sh: data relevant (environ)
* Return: no return
*/
void cd_dot(data_shell *my_data_sh)
char pwd[PATH_MAX];
char *my_directory, *cp_pwd, *cp_strtok_pwd;
getcwd(pwd, sizeof(pwd));
cp_pwd = _strdup(pwd);
set_env("OLDPWD", cp_pwd, my_data_sh);
my_directory = my_data_sh->args[1];
if (_strcmp(".", my_directory) == 0)
set_env("PWD", cp_pwd, my_data_sh);
free(cp_pwd);
return;
if (_strcmp("/", cp_pwd) == 0)
free(cp_pwd);
return;
cp_strtok_pwd = cp_pwd;
rev_string(cp_strtok_pwd);
cp_strtok_pwd = _strtok(cp_strtok_pwd, "/");
if (cp_strtok_pwd != NULL)
cp_strtok_pwd = _strtok(NULL, "\0");
if (cp_strtok_pwd != NULL)
rev_string(cp_strtok_pwd);
if (cp_strtok_pwd != NULL)
chdir(cp_strtok_pwd);
set_env("PWD", cp_strtok_pwd, my_data_sh);
else
chdir("/");
set_env("PWD", "/", my_data_sh);
my_data_sh->status = 0;
free(cp_pwd);
/**
* cd_to - changes to a directory given
* by the user
* @my_data_sh: data relevant (directories)
* Return: no return
*/
void cd_to(data_shell *my_data_sh)
{
char pwd[PATH_MAX];
char *my_directory, *cp_pwd, *cp_dir;
getcwd(pwd, sizeof(pwd));
my_directory = my_data_sh->args[1];
if (chdir(my_directory) == -1)
get_error(my_data_sh, 2);
return;
cp_pwd = _strdup(pwd);
set_env("OLDPWD", cp_pwd, my_data_sh);
cp_dir = _strdup(my_directory);
set_env("PWD", cp_dir, my_data_sh);
free(cp_pwd);
free(cp_dir);
my_data_sh->status = 0;
chdir(my_directory);
/**
* cd_previous - changes to the previous directory
* @my_data_sh: data relevant (environ)
* Return: no return
*/
void cd_previous(data_shell *my_data_sh)
char pwd[PATH_MAX];
char *p_pwd, *p_oldpwd, *cp_pwd, *cp_oldpwd;
getcwd(pwd, sizeof(pwd));
cp_pwd = _strdup(pwd);
p_oldpwd = _getenv("OLDPWD", my_data_sh->_environ);
if (p_oldpwd == NULL)
cp_oldpwd = cp_pwd;
else
cp_oldpwd = _strdup(p_oldpwd);
set_env("OLDPWD", cp_pwd, my_data_sh);
if (chdir(cp_oldpwd) == -1)
set_env("PWD", cp_pwd, my_data_sh);
else
set_env("PWD", cp_oldpwd, my_data_sh);
p_pwd = _getenv("PWD", my_data_sh->_environ);
write(STDOUT_FILENO, p_pwd, _strlen(p_pwd));
write(STDOUT_FILENO, "\n", 1);
free(cp_pwd);
if (p_oldpwd)
free(cp_oldpwd);
my_data_sh->status = 0;
chdir(p_pwd);
/**
* cd_to_home - changes to home directory
* @my_data_sh: data relevant (environ)
* Return: no return
*/
void cd_to_home(data_shell *my_data_sh)
char *p_pwd, *home;
char pwd[PATH_MAX];
getcwd(pwd, sizeof(pwd));
p_pwd = _strdup(pwd);
home = _getenv("HOME", my_data_sh->_environ);
if (home == NULL)
set_env("OLDPWD", p_pwd, my_data_sh);
free(p_pwd);
return;
if (chdir(home) == -1)
{
get_error(my_data_sh, 2);
free(p_pwd);
return;
set_env("OLDPWD", p_pwd, my_data_sh);
set_env("PWD", home, my_data_sh);
free(p_pwd);
my_data_sh->status = 0;
cmd_exec
#include "main.h"
/**
* is_cdir - checks ":" if is in the current directory.
* @path: type char pointer char.
* @i: type int pointer of index.
* Return: 1 if the path is searchable in the cd, 0 otherwise.
*/
int is_cdir(char *path, int *i)
if (path[*i] == ':')
return (1);
while (path[*i] != ':' && path[*i])
*i += 1;
if (path[*i])
*i += 1;
return (0);
/**
* _which - locates a command
* @cmd: command name
* @_environ: environment variable
* Return: location of the command.
*/
char *_which(char *cmd, char **_environ)
char *path, *ptr_path, *token_path, *dir;
int len_dir, len_cmd, i;
struct stat st;
path = _getenv("PATH", _environ);
if (path)
ptr_path = _strdup(path);
len_cmd = _strlen(cmd);
token_path = _strtok(ptr_path, ":");
i = 0;
while (token_path != NULL)
if (is_cdir(path, &i))
if (stat(cmd, &st) == 0)
return (cmd);
len_dir = _strlen(token_path);
dir = malloc(len_dir + len_cmd + 2);
_strcpy(dir, token_path);
_strcat(dir, "/");
_strcat(dir, cmd);
_strcat(dir, "\0");
if (stat(dir, &st) == 0)
free(ptr_path);
return (dir);
free(dir);
token_path = _strtok(NULL, ":");
free(ptr_path);
if (stat(cmd, &st) == 0)
return (cmd);
return (NULL);
if (cmd[0] == '/')
if (stat(cmd, &st) == 0)
return (cmd);
return (NULL);
/**
* is_executable - determines if is an executable
* @datash: data structure
* Return: 0 if is not an executable, other number if it does
*/
int is_executable(data_shell *datash)
{
struct stat st;
int i;
char *input;
input = datash->args[0];
for (i = 0; input[i]; i++)
if (input[i] == '.')
if (input[i + 1] == '.')
return (0);
if (input[i + 1] == '/')
continue;
else
break;
else if (input[i] == '/' && i != 0)
if (input[i + 1] == '.')
continue;
i++;
break;
else
break;
if (i == 0)
return (0);
if (stat(input + i, &st) == 0)
{
return (i);
get_error(datash, 127);
return (-1);
/**
* check_error_cmd - verifies if user has permissions to access
* @dir: destination directory
* @datash: data structure
* Return: 1 if there is an error, 0 if not
*/
int check_error_cmd(char *dir, data_shell *datash)
if (dir == NULL)
get_error(datash, 127);
return (1);
if (_strcmp(datash->args[0], dir) != 0)
if (access(dir, X_OK) == -1)
get_error(datash, 126);
free(dir);
return (1);
free(dir);
}
else
if (access(datash->args[0], X_OK) == -1)
get_error(datash, 126);
return (1);
return (0);
/**
* cmd_exec - executes command lines
* @datash: data relevant (args and input)
* Return: 1 on success.
*/
int cmd_exec(data_shell *datash)
pid_t pd;
pid_t wpd;
int state;
int exec;
char *dir;
(void) wpd;
exec = is_executable(datash);
if (exec == -1)
return (1);
if (exec == 0)
dir = _which(datash->args[0], datash->_environ);
if (check_error_cmd(dir, datash) == 1)
return (1);
pd = fork();
if (pd == 0)
if (exec == 0)
dir = _which(datash->args[0], datash->_environ);
else
dir = datash->args[0];
execve(dir + exec, datash->args, datash->_environ);
else if (pd < 0)
perror(datash->av[0]);
return (1);
else
do {
wpd = waitpid(pd, &state, WUNTRACED);
} while (!WIFEXITED(state) && !WIFSIGNALED(state));
datash->status = state / 256;
return (1);
}
env1
#include "main.h"
/**
* cmp_env_name - compares env variables names
* with the name passed.
* @nenv: name of the environment variable
* @name: name passed
* Return: 0 if are not equal. Another value if they are.
*/
int cmp_env_name(const char *nenv, const char *name)
int i;
for (i = 0; nenv[i] != '='; i++)
if (nenv[i] != name[i])
return (0);
return (i + 1);
/**
* _getenv - get an environment variable
* @name: name of the environment variable
* @_environ: environment variable
*
* Return: value of the environment variable if is found.
* In other case, returns NULL.
*/
char *_getenv(const char *name, char **_environ)
char *ptr_env;
int i, mov;
/* Initialize ptr_env value */
ptr_env = NULL;
mov = 0;
/* Compare all environment variables */
/* environ is declared in the header file */
for (i = 0; _environ[i]; i++)
/* If name and env are equal */
mov = cmp_env_name(_environ[i], name);
if (mov)
ptr_env = _environ[i];
break;
return (ptr_env + mov);
/**
* _env - prints the evironment variables
*
* @datash: data relevant.
* Return: 1 on success.
*/
int _env(data_shell *datash)
int i, j;
for (i = 0; datash->_environ[i]; i++)
for (j = 0; datash->_environ[i][j]; j++)
write(STDOUT_FILENO, datash->_environ[i], j);
write(STDOUT_FILENO, "\n", 1);
datash->status = 0;
return (1);
Env2
#include "main.h"
/**
* copy_info - copies info to create
* a new env or alias
* @name: name (env or alias)
* @value: value (env or alias)
*
* Return: new env or alias.
*/
char *copy_info(char *name, char *value)
{
char *new;
int len_name, len_value, len;
len_name = _strlen(name);
len_value = _strlen(value);
len = len_name + len_value + 2;
new = malloc(sizeof(char) * (len));
_strcpy(new, name);
_strcat(new, "=");
_strcat(new, value);
_strcat(new, "\0");
return (new);
}
/**
* set_env - sets an environment variable
*
* @name: name of the environment variable
* @value: value of the environment variable
* @datash: data structure (environ)
* Return: no return
*/
void set_env(char *name, char *value, data_shell *datash)
{
int i;
char *var_env, *name_env;
for (i = 0; datash->_environ[i]; i++)
{
var_env = _strdup(datash->_environ[i]);
name_env = _strtok(var_env, "=");
if (_strcmp(name_env, name) == 0)
{
free(datash->_environ[i]);
datash->_environ[i] = copy_info(name_env, value);
free(var_env);
return;
}
free(var_env);
}
datash->_environ = _reallocdp(datash->_environ, i, sizeof(char *) * (i + 2));
datash->_environ[i] = copy_info(name, value);
datash->_environ[i + 1] = NULL;
}
/**
* _setenv - compares env variables names
* with the name passed.
* @datash: data relevant (env name and env value)
*
* Return: 1 on success.
*/
int _setenv(data_shell *datash)
{
if (datash->args[1] == NULL || datash->args[2] == NULL)
{
get_error(datash, -1);
return (1);
}
set_env(datash->args[1], datash->args[2], datash);
return (1);
}
execute_some_line
/**
* _unsetenv - deletes a environment variable
*
* @datash: data relevant (env name)
*
* Return: 1 on success.
*/
int _unsetenv(data_shell *datash)
{
char **realloc_environ;
char *var_env, *name_env;
int i, j, k;
if (datash->args[1] == NULL)
{
get_error(datash, -1);
return (1);
}
k = -1;
for (i = 0; datash->_environ[i]; i++)
{
var_env = _strdup(datash->_environ[i]);
name_env = _strtok(var_env, "=");
if (_strcmp(name_env, datash->args[1]) == 0)
{
k = i;
}
free(var_env);
}
if (k == -1)
{
get_error(datash, -1);
return (1);
}
realloc_environ = malloc(sizeof(char *) * (i));
for (i = j = 0; datash->_environ[i]; i++)
{
if (i != k)
{
realloc_environ[j] = datash->_environ[i];
j++;
}
}
realloc_environ[j] = NULL;
free(datash->_environ[k]);
free(datash->_environ);
datash->_environ = realloc_environ;
return (1);
}
#include "main.h"
/**
* exec_line - finds builtins and commands
*
* @my_data_sh: data relevant (args)
* Return: 1 on success.
*/
int exec_line(data_shell *my_data_sh)
{
int (*builtin)(data_shell *my_data_sh);
if (my_data_sh->args[0] == NULL)
return (1);
builtin = get_builtin(my_data_sh->args[0]);
if (builtin != NULL)
return (builtin(my_data_sh));
return (cmd_exec(my_data_sh));
}
get_error
#include "main.h"
/**
* get_error - calls the error according the builtin, syntax or permission
* @datash: data structure that contains arguments
* @eval: error value
* Return: error
*/
int get_error(data_shell *datash, int eval)
{
char *error;
switch (eval)
{
case -1:
error = error_env(datash);
break;
case 126:
error = error_path_126(datash);
break;
case 127:
error = error_not_found(datash);
break;
case 2:
if (_strcmp("exit", datash->args[0]) == 0)
error = error_exit_shell(datash);
else if (_strcmp("cd", datash->args[0]) == 0)
error = error_get_cd(datash);
break;
}
if (error)
{
write(STDERR_FILENO, error, _strlen(error));
free(error);
}
datash->status = eval;
return (eval);
}
get_line
#include "main.h"
/**
* bring_line - assigns the line var for get_line
* @lineptr: Buffer that store the input str
* @buffer: str that is been called to line
* @n: size of line
* @j: size of buffer
*/
void bring_line(char **lineptr, size_t *n, char *buffer, size_t j)
{
if (*lineptr == NULL)
{
if (j > BUFSIZE)
*n = j;
else
*n = BUFSIZE;
*lineptr = buffer;
}
else if (*n < j)
{
if (j > BUFSIZE)
*n = j;
else
*n = BUFSIZE;
*lineptr = buffer;
}
else
{
_strcpy(*lineptr, buffer);
free(buffer);
}
}
/**
* get_line - Read inpt from stream
* @lineptr: buffer that stores the input
* @n: size of lineptr
* @stream: stream to read from
* Return: The number of bytes
*/
ssize_t get_line(char **lineptr, size_t *n, FILE *stream)
{
int i;
static ssize_t input;
ssize_t retval;
char *buffer;
char t = 'z';
if (input == 0)
fflush(stream);
else
return (-1);
input = 0;
buffer = malloc(sizeof(char) * BUFSIZE);
if (buffer == 0)
return (-1);
while (t != '\n')
{
i = read(STDIN_FILENO, &t, 1);
if (i == -1 || (i == 0 && input == 0))
{
free(buffer);
return (-1);
}
if (i == 0 && input != 0)
{
input++;
break;
}
if (input >= BUFSIZE)
buffer = _realloc(buffer, input, input + 1);
buffer[input] = t;
input++;
}
buffer[input] = '\0';
bring_line(lineptr, n, buffer, input);
retval = input;
if (i != 0)
input = 0;
return (retval);
}
get_sigint
#include "main.h"
/**
* get_sigint - Handle the crtl + c call in prompt
* @sig: Signal handler
*/
void get_sigint(int sig)
(void)sig;
write(STDOUT_FILENO, "\n^-^ ", 5);
get_some_help
#include "main.h"
/**
* get_help - function that retrieves help messages according builtin
* @my_data_sh: data structure (args and input)
* Return: Return 0
*/
int get_help(data_shell *my_data_sh)
{
if (my_data_sh->args[1] == 0)
aux_help_general();
else if (_strcmp(my_data_sh->args[1], "setenv") == 0)
aux_help_setenv();
else if (_strcmp(my_data_sh->args[1], "env") == 0)
aux_help_env();
else if (_strcmp(my_data_sh->args[1], "unsetenv") == 0)
aux_help_unsetenv();
else if (_strcmp(my_data_sh->args[1], "help") == 0)
aux_help();
else if (_strcmp(my_data_sh->args[1], "exit") == 0)
aux_help_exit();
else if (_strcmp(my_data_sh->args[1], "cd") == 0)
aux_help_cd();
else if (_strcmp(my_data_sh->args[1], "alias") == 0)
aux_help_alias();
else
write(STDERR_FILENO, my_data_sh->args[0],
_strlen(my_data_sh->args[0]));
my_data_sh->status = 0;
return (1);
getting_some_builtin
#include "main.h"
/**
* get_builtin - builtin that pais the command in the arg
* @cmd: command
* Return: function pointer of the builtin command
*/
int (*get_builtin(char *cmd))(data_shell *)
builtin_t blt_in[] = {
{ "env", _env },
{ "exit", exit_shell },
{ "setenv", _setenv },
{ "unsetenv", _unsetenv },
{ "cd", cd_shell },
{ "help", get_help },
{ NULL, NULL }
};
int m;
for (m = 0; blt_in[m].name; m++)
if (_strcmp(blt_in[m].name, cmd) == 0)
break;
return (blt_in[m].f);
help_auxios
#include "main.h"
/**
* aux_help_env - Help information for the builtin env
* Return: no return
*/
void aux_help_env(void)
char *may_be_some_help = "env: env [option] [name=value] [command [args]]\n\t";
write(STDOUT_FILENO, may_be_some_help, _strlen(may_be_some_help));
may_be_some_help = "Print the enviroment of the shell.\n";
write(STDOUT_FILENO, may_be_some_help, _strlen(may_be_some_help));
/**
* aux_help_setenv - Help information for the builtin setenv
* Return: no return
*/
void aux_help_setenv(void)
char *may_be_some_help = "setenv: setenv (const char *name, const char *value,";
write(STDOUT_FILENO, may_be_some_help, _strlen(may_be_some_help));
may_be_some_help = "int replace)\n\t";
write(STDOUT_FILENO, may_be_some_help, _strlen(may_be_some_help));
may_be_some_help = "Add a new definition to the environment\n";
write(STDOUT_FILENO, may_be_some_help, _strlen(may_be_some_help));
/**
* aux_help_unsetenv - Help information for the builtin unsetenv
* Return: no return
*/
void aux_help_unsetenv(void)
char *may_be_some_help = "unsetenv: unsetenv (const char *name)\n\t";
write(STDOUT_FILENO, may_be_some_help, _strlen(may_be_some_help));
may_be_some_help = "Remove an entry completely from the environment\n";
write(STDOUT_FILENO, may_be_some_help, _strlen(may_be_some_help));
/**
* aux_help_general - Entry point for help information for the help builtin
* Return: no return
*/
void aux_help_general(void)
char *may_be_some_help = "^-^ bash, version 1.0(1)-release\n";
write(STDOUT_FILENO, may_be_some_help, _strlen(may_be_some_help));
may_be_some_help = "These commands are defined internally.Type 'help' to see the list";
write(STDOUT_FILENO, may_be_some_help, _strlen(may_be_some_help));
may_be_some_help = "Type 'help name' to find out more about the function 'name'.\n\n ";
write(STDOUT_FILENO, may_be_some_help, _strlen(may_be_some_help));
may_be_some_help = " alias: alias [name=['string']]\n cd: cd [-L|[-P [-e]] [-@]] ";
write(STDOUT_FILENO, may_be_some_help, _strlen(may_be_some_help));
may_be_some_help = "[dir]\nexit: exit [n]\n env: env [option] [name=value] [command ";
write(STDOUT_FILENO, may_be_some_help, _strlen(may_be_some_help));
may_be_some_help = "[args]]\n setenv: setenv [variable] [value]\n unsetenv: ";
write(STDOUT_FILENO, may_be_some_help, _strlen(may_be_some_help));
may_be_some_help = "unsetenv [variable]\n";
write(STDOUT_FILENO, may_be_some_help, _strlen(may_be_some_help));
/**
* aux_help_exit - Help information fot the builint exit
* Return: no return
*/
void aux_help_exit(void)
{
char *help = "exit: exit [n]\n Exit shell.\n";
write(STDOUT_FILENO, help, _strlen(help));
help = "Exits the shell with a status of N. If N is ommited, the exit";
write(STDOUT_FILENO, help, _strlen(help));
help = "statusis that of the last command executed\n";
write(STDOUT_FILENO, help, _strlen(help));
help_auxios2
#include "main.h"
/**
* aux_help - Help information for the builtin help.
* Return: no return
*/
void aux_help(void)
char *may_be_some_help = "help: help [-dms] [pattern ...]\n";
write(STDOUT_FILENO, may_be_some_help, _strlen(may_be_some_help));
may_be_some_help = "\tDisplay information about builtin commands.\n ";
write(STDOUT_FILENO, may_be_some_help, _strlen(may_be_some_help));
may_be_some_help = "Displays brief summaries of builtin commands.\n";
write(STDOUT_FILENO, may_be_some_help, _strlen(may_be_some_help));
/**
* aux_help_alias - Help information for the builtin alias.
* Return: no return
*/
void aux_help_alias(void)
{
char *may_be_some_help = "alias: alias [-p] [name[=value]...]\n";
write(STDOUT_FILENO, may_be_some_help, _strlen(may_be_some_help));
may_be_some_help = "\tDefine or display aliases.\n ";
write(STDOUT_FILENO, may_be_some_help, _strlen(may_be_some_help));
/**
* aux_help_cd - Help information for the builtin alias.
* Return: no return
*/
void aux_help_cd(void)
char *may_be_some_help = "cd: cd [-L|[-P [-e]] [-@]] [dir]\n";
write(STDOUT_FILENO, may_be_some_help, _strlen(may_be_some_help));
may_be_some_help = "\tChange the shell working directory.\n ";
write(STDOUT_FILENO, may_be_some_help, _strlen(may_be_some_help));
lists_auxios
#include "main.h"
/**
* add_sep_node_end - adds a separator found at the end
* of a sep_list.
* @hd: head of the linked list.
* @my_sepr: separator found (; | &).
* Return: address of the head.
*/
sep_list *add_sep_node_end(sep_list **hd, char my_sepr)
{
sep_list *new, *temp;
new = malloc(sizeof(sep_list));
if (new == NULL)
return (NULL);
new->separator = my_sepr;
new->next = NULL;
temp = *hd;
if (temp == NULL)
*hd = new;
else
while (temp->next != NULL)
temp = temp->next;
temp->next = new;
return (*hd);
/**
* free_sep_list - frees a sep_list
* @hd: head of the linked list.
* Return: no return.
*/
void free_sep_list(sep_list **hd)
{
sep_list *temp;
sep_list *curr;
if (hd != NULL)
curr = *hd;
while ((temp = curr) != NULL)
curr = curr->next;
free(temp);
*hd = NULL;
/**
* add_line_node_end - adds a command line at the end
* of a line_list.
* @hd: head of the linked list.
* @line: command line.
* Return: address of the head.
*/
line_list *add_line_node_end(line_list **hd, char *line)
line_list *new, *temp;
new = malloc(sizeof(line_list));
if (new == NULL)
return (NULL);
new->line = line;
new->next = NULL;
temp = *hd;
if (temp == NULL)
*hd = new;
else
while (temp->next != NULL)
temp = temp->next;
temp->next = new;
return (*hd);
/**
* free_line_list - frees a line_list
* @hd: head of the linked list.
* Return: no return.
*/
void free_line_list(line_list **hd)
line_list *temp;
line_list *curr;
if (hd != NULL)
curr = *hd;
while ((temp = curr) != NULL)
{
curr = curr->next;
free(temp);
*hd = NULL;
lists_auxios2
#include "main.h"
/**
* add_rvar_node - adds a variable at the end
* of a r_var list.
* @hd: head of the linked list.
* @lvar: length of the variable.
* @val: value of the variable.
* @lval: length of the value.
* Return: address of the head.
*/
r_var *add_rvar_node(r_var **hd, int lvar, char *val, int lval)
r_var *my_new, *my_temp;
my_new = malloc(sizeof(r_var));
if (my_new == NULL)
return (NULL);
my_new->len_var = lvar;
my_new->val = val;
my_new->len_val = lval;
my_new->next = NULL;
my_temp = *hd;
if (my_temp == NULL)
*hd = my_new;
else
while (my_temp->next != NULL)
my_temp = my_temp->next;
my_temp->next = my_new;
return (*hd);
/**
* free_rvar_list - frees a r_var list
* @hd: head of the linked list.
* Return: no return.
*/
void free_rvar_list(r_var **hd)
r_var *my_temp;
r_var *my_currently;
if (hd != NULL)
my_currently = *hd;
while ((my_temp = my_currently) != NULL)
{
my_currently = my_currently->next;
free(my_temp);
*hd = NULL;
Main
#include "main.h"
/**
* free_data - frees data structure
* @datash: data structure
* Return: no return
*/
void free_data(data_shell *datash)
unsigned int i;
for (i = 0; datash->_environ[i]; i++)
free(datash->_environ[i]);
free(datash->_environ);
free(datash->pid);
/**
* set_data - Initialize data structure
*
* @datash: data structure
* @av: argument vector
* Return: no return
*/
void set_data(data_shell *datash, char **av)
unsigned int i;
datash->av = av;
datash->input = NULL;
datash->args = NULL;
datash->status = 0;
datash->counter = 1;
for (i = 0; environ[i]; i++)
datash->_environ = malloc(sizeof(char *) * (i + 1));
for (i = 0; environ[i]; i++)
datash->_environ[i] = _strdup(environ[i]);
datash->_environ[i] = NULL;
datash->pid = aux_itoa(getpid());
/**
* main - Entry point
*
* @ac: argument count
* @av: argument vector
* Return: 0 on success.
*/
int main(int ac, char **av)
data_shell datash;
(void) ac;
signal(SIGINT, get_sigint);
set_data(&datash, av);
shell_loop(&datash);
free_data(&datash);
if (datash.status < 0)
return (255);
return (datash.status);
Main.h
#ifndef MAIN
#define MAIN
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
#include <signal.h>
#include <limits.h>
#define BUFSIZE 1024
#define TOK_BUFSIZE 128
#define TOK_DELIM " \t\r\n\a"
/* Points to an array of pointers to strings called the "environment" */
extern char **environ;
/**
* struct data - struct that contains all relevant data on runtime
* @av: argument vector
* @input: command line written by the user
* @args: tokens of the command line
* @status: last status of the shell
* @counter: lines counter
* @_environ: environment variable
* @pid: process ID of the shell
*/
typedef struct data
char **av;
char *input;
char **args;
int status;
int counter;
char **_environ;
char *pid;
} data_shell;
/**
* struct sep_list_s - single linked list
* @separator: ; | &
* @next: next node
* Description: single linked list to store separators
*/
typedef struct sep_list_s
char separator;
struct sep_list_s *next;
} sep_list;
/**
* struct line_list_s - single linked list
* @line: command line
* @next: next node
* Description: single linked list to store command lines
*/
typedef struct line_list_s
char *line;
struct line_list_s *next;
} line_list;
/**
* struct r_var_list - single linked list
* @len_var: length of the variable
* @val: value of the variable
* @len_val: length of the value
* @next: next node
* Description: single linked list to store variables
*/
typedef struct r_var_list
int len_var;
char *val;
int len_val;
struct r_var_list *next;
} r_var;
/**
* struct builtin_s - Builtin struct for command args.
* @name: The name of the command builtin i.e cd, exit, env
* @f: data type pointer function.
*/
typedef struct builtin_s
char *name;
int (*f)(data_shell *datash);
} builtin_t;
/* aux_lists.c */
sep_list *add_sep_node_end(sep_list **head, char sep);
void free_sep_list(sep_list **head);
line_list *add_line_node_end(line_list **head, char *line);
void free_line_list(line_list **head);
/* aux_lists2.c */
r_var *add_rvar_node(r_var **head, int lvar, char *var, int lval);
void free_rvar_list(r_var **head);
/* aux_str functions */
char *_strcat(char *dest, const char *src);
char *_strcpy(char *dest, char *src);
int _strcmp(char *s1, char *s2);
char *_strchr(char *s, char c);
int _strspn(char *s, char *accept);
/* aux_mem.c */
void _memcpy(void *newptr, const void *ptr, unsigned int size);
void *_realloc(void *ptr, unsigned int old_size, unsigned int new_size);
char **_reallocdp(char **ptr, unsigned int old_size, unsigned int new_size);
/* aux_str2.c */
char *_strdup(const char *s);
int _strlen(const char *s);
int cmp_chars(char str[], const char *delim);
char *_strtok(char str[], const char *delim);
int _isdigit(const char *s);
/* aux_str3.c */
void rev_string(char *s);
/* check_syntax_error.c */
int repeated_char(char *input, int i);
int error_sep_op(char *input, int i, char last);
int first_char(char *input, int *i);
void print_syntax_error(data_shell *datash, char *input, int i, int bool);
int check_syntax_error(data_shell *datash, char *input);
/* shell_loop.c */
char *without_comment(char *in);
void shell_loop(data_shell *datash);
/* read_line.c */
char *read_line(int *i_eof);
/* split.c */
char *swap_char(char *input, int bool);
void add_nodes(sep_list **head_s, line_list **head_l, char *input);
void go_next(sep_list **list_s, line_list **list_l, data_shell *datash);
int split_commands(data_shell *datash, char *input);
char **split_line(char *input);
/* rep_var.c */
void check_env(r_var **h, char *in, data_shell *data);
int check_vars(r_var **h, char *in, char *st, data_shell *data);
char *replaced_input(r_var **head, char *input, char *new_input, int nlen);
char *rep_var(char *input, data_shell *datash);
/* get_line.c */
void bring_line(char **lineptr, size_t *n, char *buffer, size_t j);
ssize_t get_line(char **lineptr, size_t *n, FILE *stream);
/* exec_line */
int exec_line(data_shell *datash);
/* cmd_exec.c */
int is_cdir(char *path, int *i);
char *_which(char *cmd, char **_environ);
int is_executable(data_shell *datash);
int check_error_cmd(char *dir, data_shell *datash);
int cmd_exec(data_shell *datash);
/* env1.c */
char *_getenv(const char *name, char **_environ);
int _env(data_shell *datash);
/* env2.c */
char *copy_info(char *name, char *value);
void set_env(char *name, char *value, data_shell *datash);
int _setenv(data_shell *datash);
int _unsetenv(data_shell *datash);
/* cd.c */
void cd_dot(data_shell *datash);
void cd_to(data_shell *datash);
void cd_previous(data_shell *datash);
void cd_to_home(data_shell *datash);
/* cd_shell.c */
int cd_shell(data_shell *datash);
/* get_builtin */
int (*get_builtin(char *cmd))(data_shell *datash);
/* _exit.c */
int exit_shell(data_shell *datash);
/* aux_stdlib.c */
int get_len(int n);
char *aux_itoa(int n);
int _atoi(char *s);
/* aux_error1.c */
char *strcat_cd(data_shell *, char *, char *, char *);
char *error_get_cd(data_shell *datash);
char *error_not_found(data_shell *datash);
char *error_exit_shell(data_shell *datash);
/* aux_error2.c */
char *error_get_alias(char **args);
char *error_env(data_shell *datash);
char *error_syntax(char **args);
char *error_permission(char **args);
char *error_path_126(data_shell *datash);
/* get_error.c */
int get_error(data_shell *datash, int eval);
/* get_sigint.c */
void get_sigint(int sig);
/* aux_help.c */
void aux_help_env(void);
void aux_help_setenv(void);
void aux_help_unsetenv(void);
void aux_help_general(void);
void aux_help_exit(void);
/* aux_help2.c */
void aux_help(void);
void aux_help_alias(void);
void aux_help_cd(void);
/* get_help.c */
int get_help(data_shell *datash);
#endif
memo_auxios
#include "main.h"
/**
* _memcpy - copies information between void pointers.
* @my_newptr: destination pointer.
* @my_ptr: source pointer.
* @size: size of the new pointer.
* Return: no return.
*/
void _memcpy(void *my_newptr, const void *my_ptr, unsigned int size)
char *char_ptr = (char *)my_ptr;
char *char_newptr = (char *)my_newptr;
unsigned int i;
for (i = 0; i < size; i++)
char_newptr[i] = char_ptr[i];
/**
* _realloc - reallocates a memory block.
* @my_ptr: pointer to the memory previously allocated.
* @old_size: size, in bytes, of the allocated space of ptr.
* @new_size: new size, in bytes, of the new memory block.
*
* Return: my_ptr.
* if new_size == old_size, returns ptr without changes.
* if malloc fails, returns NULL.
*/
void *_realloc(void *my_ptr, unsigned int old_size, unsigned int new_size)
void *my_newptr;
if (my_ptr == NULL)
return (malloc(new_size));
if (new_size == 0)
free(my_ptr);
return (NULL);
if (new_size == old_size)
return (my_ptr);
my_newptr = malloc(new_size);
if (my_newptr == NULL)
return (NULL);
if (new_size < old_size)
_memcpy(my_newptr, my_ptr, new_size);
else
_memcpy(my_newptr, my_ptr, old_size);
free(my_ptr);
return (my_newptr);
/**
* _reallocdp - reallocates a memory block of a double pointer.
* @my_ptr: double pointer to the memory previously allocated.
* @old_size: size, in bytes, of the allocated space of ptr.
* @new_size: new size, in bytes, of the new memory block.
* Return: ptr.
* if new_size == old_size, returns ptr without changes.
* if malloc fails, returns NULL.
*/
char **_reallocdp(char **my_ptr, unsigned int old_size, unsigned int new_size)
char **my_newptr;
unsigned int i;
if (my_ptr == NULL)
return (malloc(sizeof(char *) * new_size));
if (new_size == old_size)
return (my_ptr);
my_newptr = malloc(sizeof(char *) * new_size);
if (my_newptr == NULL)
return (NULL);
for (i = 0; i < old_size; i++)
my_newptr[i] = my_ptr[i];
free(my_ptr);
return (my_newptr);
reading_some_line
#include "main.h"
/**
* read_line - reads the input string.
* @i_end_of_file: return value of getline function
* Return: input string
*/
char *read_line(int *i_end_of_file)
char *my_inpt = NULL;
size_t my_bfr_sz = 0;
*i_end_of_file = getline(&my_inpt, &my_bfr_sz, stdin);
return (my_inpt);
rep_var
#include "main.h"
/**
* check_env - checks if the typed variable is an env variable
* @h: head of linked list
* @in: input string
* @data: data structure
* Return: no return
*/
void check_env(r_var **h, char *in, data_shell *data)
int row, chr, j, lval;
char **_envr;
_envr = data->_environ;
for (row = 0; _envr[row]; row++)
for (j = 1, chr = 0; _envr[row][chr]; chr++)
if (_envr[row][chr] == '=')
lval = _strlen(_envr[row] + chr + 1);
add_rvar_node(h, j, _envr[row] + chr + 1, lval);
return;
if (in[j] == _envr[row][chr])
j++;
else
break;
for (j = 0; in[j]; j++)
if (in[j] == ' ' || in[j] == '\t' || in[j] == ';' || in[j] == '\n')
break;
}
add_rvar_node(h, j, NULL, 0);
/**
* check_vars - check if the typed variable is $$ or $?
* @h: head of the linked list
* @in: input string
* @st: last status of the Shell
* @data: data structure
* Return: no return
*/
int check_vars(r_var **h, char *in, char *st, data_shell *data)
int i, lst, lpd;
lst = _strlen(st);
lpd = _strlen(data->pid);
for (i = 0; in[i]; i++)
if (in[i] == '$')
if (in[i + 1] == '?')
add_rvar_node(h, 2, st, lst), i++;
else if (in[i + 1] == '$')
add_rvar_node(h, 2, data->pid, lpd), i++;
else if (in[i + 1] == '\n')
add_rvar_node(h, 0, NULL, 0);
else if (in[i + 1] == '\0')
add_rvar_node(h, 0, NULL, 0);
else if (in[i + 1] == ' ')
add_rvar_node(h, 0, NULL, 0);
else if (in[i + 1] == '\t')
add_rvar_node(h, 0, NULL, 0);
else if (in[i + 1] == ';')
add_rvar_node(h, 0, NULL, 0);
else
check_env(h, in + i, data);
return (i);
/**
* replaced_input - replaces string into variables
* @head: head of the linked list
* @input: input string
* @new_input: new input string (replaced)
* @nlen: new length
* Return: replaced string
*/
char *replaced_input(r_var **head, char *input, char *new_input, int nlen)
r_var *indx;
int i, j, k;
indx = *head;
for (j = i = 0; i < nlen; i++)
if (input[j] == '$')
if (!(indx->len_var) && !(indx->len_val))
new_input[i] = input[j];
j++;
else if (indx->len_var && !(indx->len_val))
for (k = 0; k < indx->len_var; k++)
j++;
i--;
else
for (k = 0; k < indx->len_val; k++)
new_input[i] = indx->val[k];
i++;
j += (indx->len_var);
i--;
indx = indx->next;
else
new_input[i] = input[j];
j++;
}
return (new_input);
/**
* rep_var - calls functions to replace string into vars
* @input: input string
* @datash: data structure
* Return: replaced string
*/
char *rep_var(char *input, data_shell *datash)
r_var *head, *indx;
char *status, *new_input;
int olen, nlen;
status = aux_itoa(datash->status);
head = NULL;
olen = check_vars(&head, input, status, datash);
if (head == NULL)
free(status);
return (input);
indx = head;
nlen = 0;
while (indx != NULL)
nlen += (indx->len_val - indx->len_var);
indx = indx->next;
nlen += olen;
new_input = malloc(sizeof(char) * (nlen + 1));
new_input[nlen] = '\0';
new_input = replaced_input(&head, input, new_input, nlen);
free(input);
free(status);
free_rvar_list(&head);
return (new_input);
shell_change_directory
#include "main.h"
/**
* cd_shell - changes current directory
* @my_data_sh: data relevant
* Return: 1 on success
*/
int cd_shell(data_shell *my_data_sh)
{
char *my_directory;
int is_hm, is_hm2, is_d_sh;
my_directory = my_data_sh->args[1];
if (my_directory != NULL)
is_hm = _strcmp("$HOME", my_directory);
is_hm2 = _strcmp("~", my_directory);
is_d_sh = _strcmp("--", my_directory);
if (my_directory == NULL || !is_hm || !is_hm2 || !is_d_sh)
cd_to_home(my_data_sh);
return (1);
if (_strcmp("-", my_directory) == 0)
cd_previous(my_data_sh);
return (1);
if (_strcmp(".", my_directory) == 0 || _strcmp("..", my_directory) == 0)
cd_dot(my_data_sh);
return (1);
cd_to(my_data_sh);
return (1);
}
shell_exit
#include "main.h"
/**
* exit_shell - exits the shell
* @my_data_sh: data relevant (status and args)
* Return: 0 on success.
*/
int exit_shell(data_shell *my_data_sh)
unsigned int my_status;
int is_it_digit;
int my_string_l;
int my_bg_num;
if (my_data_sh->args[1] != NULL)
my_status = _atoi(my_data_sh->args[1]);
is_it_digit = _isdigit(my_data_sh->args[1]);
my_string_l = _strlen(my_data_sh->args[1]);
my_bg_num = my_status > (unsigned int)INT_MAX;
if (!is_it_digit || my_string_l > 10 || my_bg_num)
get_error(my_data_sh, 2);
my_data_sh->status = 2;
return (1);
my_data_sh->status = (my_status % 256);
}
return (0);
shell_loop
#include "main.h"
/**
* without_comment - deletes comments from the input
* @in: input string
* Return: input without comments
*/
char *without_comment(char *in)
int i, up_to;
up_to = 0;
for (i = 0; in[i]; i++)
if (in[i] == '#')
if (i == 0)
free(in);
return (NULL);
if (in[i - 1] == ' ' || in[i - 1] == '\t' || in[i - 1] == ';')
up_to = i;
}
}
if (up_to != 0)
in = _realloc(in, i, up_to + 1);
in[up_to] = '\0';
return (in);
/**
* shell_loop - Loop of shell
* @datash: data relevant (av, input, args)
* Return: no return.
*/
void shell_loop(data_shell *datash)
int loop, i_eof;
char *input;
loop = 1;
while (loop == 1)
write(STDIN_FILENO, "^-^ ", 4);
input = read_line(&i_eof);
if (i_eof != -1)
input = without_comment(input);
if (input == NULL)
continue;
if (check_syntax_error(datash, input) == 1)
datash->status = 2;
free(input);
continue;
input = rep_var(input, datash);
loop = split_commands(datash, input);
datash->counter += 1;
free(input);
else
loop = 0;
free(input);
split
#include "main.h"
/**
* swap_char - swaps | and & for non-printed chars
* @input: input string
* @bool: type of swap
* Return: swapped string
*/
char *swap_char(char *input, int bool)
int i;
if (bool == 0)
for (i = 0; input[i]; i++)
if (input[i] == '|')
if (input[i + 1] != '|')
input[i] = 16;
else
i++;
if (input[i] == '&')
if (input[i + 1] != '&')
input[i] = 12;
else
i++;
else
for (i = 0; input[i]; i++)
input[i] = (input[i] == 16 ? '|' : input[i]);
input[i] = (input[i] == 12 ? '&' : input[i]);
}
return (input);
/**
* add_nodes - add separators and command lines in the lists
* @head_s: head of separator list
* @head_l: head of command lines list
* @input: input string
* Return: no return
*/
void add_nodes(sep_list **head_s, line_list **head_l, char *input)
int i;
char *line;
input = swap_char(input, 0);
for (i = 0; input[i]; i++)
if (input[i] == ';')
add_sep_node_end(head_s, input[i]);
if (input[i] == '|' || input[i] == '&')
add_sep_node_end(head_s, input[i]);
i++;
}
line = _strtok(input, ";|&");
do {
line = swap_char(line, 1);
add_line_node_end(head_l, line);
line = _strtok(NULL, ";|&");
} while (line != NULL);
/**
* go_next - go to the next command line stored
* @list_s: separator list
* @list_l: command line list
* @datash: data structure
* Return: no return
*/
void go_next(sep_list **list_s, line_list **list_l, data_shell *datash)
int loop_sep;
sep_list *ls_s;
line_list *ls_l;
loop_sep = 1;
ls_s = *list_s;
ls_l = *list_l;
while (ls_s != NULL && loop_sep)
if (datash->status == 0)
{
if (ls_s->separator == '&' || ls_s->separator == ';')
loop_sep = 0;
if (ls_s->separator == '|')
ls_l = ls_l->next, ls_s = ls_s->next;
else
if (ls_s->separator == '|' || ls_s->separator == ';')
loop_sep = 0;
if (ls_s->separator == '&')
ls_l = ls_l->next, ls_s = ls_s->next;
if (ls_s != NULL && !loop_sep)
ls_s = ls_s->next;
*list_s = ls_s;
*list_l = ls_l;
/**
* split_commands - splits command lines according to
* the separators ;, | and &, and executes them
* @datash: data structure
* @input: input string
* Return: 0 to exit, 1 to continue
*/
int split_commands(data_shell *datash, char *input)
{
sep_list *head_s, *list_s;
line_list *head_l, *list_l;
int loop;
head_s = NULL;
head_l = NULL;
add_nodes(&head_s, &head_l, input);
list_s = head_s;
list_l = head_l;
while (list_l != NULL)
datash->input = list_l->line;
datash->args = split_line(datash->input);
loop = exec_line(datash);
free(datash->args);
if (loop == 0)
break;
go_next(&list_s, &list_l, datash);
if (list_l != NULL)
list_l = list_l->next;
free_sep_list(&head_s);
free_line_list(&head_l);
if (loop == 0)
return (0);
return (1);
/**
* split_line - tokenizes the input string
* @input: input string.
* Return: string splitted.
*/
char **split_line(char *input)
size_t bsize;
size_t i;
char **tokens;
char *token;
bsize = TOK_BUFSIZE;
tokens = malloc(sizeof(char *) * (bsize));
if (tokens == NULL)
write(STDERR_FILENO, ": allocation error\n", 18);
exit(EXIT_FAILURE);
token = _strtok(input, TOK_DELIM);
tokens[0] = token;
for (i = 1; token != NULL; i++)
{
if (i == bsize)
bsize += TOK_BUFSIZE;
tokens = _reallocdp(tokens, i, sizeof(char *) * bsize);
if (tokens == NULL)
write(STDERR_FILENO, ": allocation error\n", 18);
exit(EXIT_FAILURE);
token = _strtok(NULL, TOK_DELIM);
tokens[i] = token;
return (tokens);
standar_lib_auxios
#include "main.h"
/**
* get_len - Get the lenght of a number.
* @n: type int number.
* Return: Lenght of a number.
*/
int get_len(int n)
unsigned int n1;
int my_l = 1;
if (n < 0)
{
my_l++;
n1 = n * -1;
else
n1 = n;
while (n1 > 9)
my_l++;
n1 = n1 / 10;
return (my_l);
/**
* aux_itoa - function converts int to string.
* @n: type int number
* Return: String.
*/
char *aux_itoa(int n)
unsigned int n1;
int lenght = get_len(n);
char *my_bfr;
my_bfr = malloc(sizeof(char) * (lenght + 1));
if (my_bfr == 0)
return (NULL);
*(my_bfr + lenght) = '\0';
if (n < 0)
n1 = n * -1;
my_bfr[0] = '-';
else
n1 = n;
lenght--;
do
*(my_bfr + lenght) = (n1 % 10) + '0';
n1 = n1 / 10;
lenght--;
} while (n1 > 0);
return (my_bfr);
/**
* _atoi - converts a string to an integer.
* @s: input string.
* Return: integer.
*/
int _atoi(char *s)
unsigned int my_counter = 0, sz = 0, oi = 0, pn = 1, m = 1, i;
while (*(s + my_counter) != '\0')
if (sz > 0 && (*(s + my_counter) < '0' || *(s + my_counter) > '9'))
break;
if (*(s + my_counter) == '-')
pn *= -1;
if ((*(s + my_counter) >= '0') && (*(s + my_counter) <= '9'))
{
if (sz > 0)
m *= 10;
sz++;
my_counter++;
for (i = my_counter - sz; i < my_counter; i++)
oi = oi + ((*(s + i) - 48) * m);
m /= 10;
return (oi * pn);
string_auxios
#include "main.h"
/**
* _strcat - concatenate two strings
* @destination: char pointer the dest of the copied str
* @src: const char pointer the source of str
* Return: the dest
*/
char *_strcat(char *destination, const char *src)
int m;
int n;
for (m = 0; destination[m] != '\0'; m++)
for (n = 0; src[n] != '\0'; n++)
{
destination[m] = src[n];
m++;
destination[m] = '\0';
return (destination);
/**
* *_strcpy - Copies the string pointed to by src.
* @destination: Type char pointer the dest of the copied str
* @src: Type char pointer the source of str
* Return: the dest.
*/
char *_strcpy(char *destination, char *src)
size_t a;
for (a = 0; src[a] != '\0'; a++)
destination[a] = src[a];
destination[a] = '\0';
return (destination);
/**
* _strcmp - Function that compares two strings.
* @string1: type str compared
* @string2: type str compared
* Return: Always 0.
*/
int _strcmp(char *string1, char *string2)
{
int m;
for (m = 0; string1[m] == string2[m] && string1[m]; m++)
if (string1[m] > string2[m])
return (1);
if (string1[m] < string2[m])
return (-1);
return (0);
/**
* _strchr - locates a character in a string,
* @s: string.
* @c: character.
* Return: the pointer to the first occurrence of the character c.
*/
char *_strchr(char *s, char c)
unsigned int i = 0;
for (; *(s + i) != '\0'; i++)
if (*(s + i) == c)
return (s + i);
if (*(s + i) == c)
return (s + i);
return ('\0');
/**
* _strspn - gets the length of a prefix substring.
* @s: initial segment.
* @accept: accepted bytes.
* Return: the number of accepted bytes.
*/
int _strspn(char *s, char *accept)
int m, n, bool;
for (m = 0; *(s + m) != '\0'; m++)
bool = 1;
for (n = 0; *(accept + n) != '\0'; n++)
if (*(s + m) == *(accept + n))
bool = 0;
break;
if (bool == 1)
break;
return (m);
string_auxios2
#include "main.h"
/**
* _strdup - duplicates a str in the heap memory.
* @my_str: Type char pointer str
* Return: duplicated str
*/
char *_strdup(const char *my_str)
char *my_new;
size_t my_l;
my_l = _strlen(my_str);
my_new = malloc(sizeof(char) * (my_l + 1));
if (my_new == NULL)
return (NULL);
_memcpy(my_new, my_str, my_l + 1);
return (my_new);
/**
* _strlen - Returns the lenght of a string.
* @s: Type char pointer
* Return: Always 0.
*/
int _strlen(const char *s)
int len;
for (len = 0; s[len] != 0; len++)
return (len);
/**
* cmp_chars - compare chars of strings
* @str: input string.
* @delim: delimiter.
* Return: 1 if are equals, 0 if not.
*/
int cmp_chars(char str[], const char *delim)
unsigned int m, n, o;
for (m = 0, o = 0; str[m]; m++)
for (n = 0; delim[n]; n++)
if (str[m] == delim[n])
o++;
break;
if (m == o)
return (1);
return (0);
/**
* _strtok - splits a string by some delimiter.
* @str: input string.
* @delim: delimiter.
* Return: string splited.
*/
char *_strtok(char str[], const char *delim)
static char *my_spliter, *end_string;
char *strat_string;
unsigned int i, bool;
if (str != NULL)
if (cmp_chars(str, delim))
return (NULL);
my_spliter = str; /*Store first address*/
i = _strlen(str);
end_string = &str[i]; /*Store last address*/
strat_string = my_spliter;
if (strat_string == end_string) /*Reaching the end*/
return (NULL);
for (bool = 0; *my_spliter; my_spliter++)
/*Breaking loop finding the next token*/
if (my_spliter != strat_string)
if (*my_spliter && *(my_spliter - 1) == '\0')
break;
/*Replacing delimiter for null char*/
for (i = 0; delim[i]; i++)
if (*my_spliter == delim[i])
*my_spliter = '\0';
if (my_spliter == strat_string)
strat_string++;
break;
if (bool == 0 && *my_spliter) /*Str != Delim*/
bool = 1;
if (bool == 0) /*Str == Delim*/
return (NULL);
return (strat_string);
/**
* _isdigit - defines if string passed is a number
* @s: input string
* Return: 1 if string is a number. 0 in other case.
*/
int _isdigit(const char *s)
unsigned int i;
for (i = 0; s[i]; i++)
if (s[i] < 48 || s[i] > 57)
return (0);
return (1);
}
string_auxios3
#include "main.h"
/**
* rev_string - reverses a string.
* @s: input string.
* Return: no return.
*/
void rev_string(char *s)
int full_counter = 0, m, n;
char *my_str, my_temp;
while (full_counter >= 0)
if (s[full_counter] == '\0')
break;
full_counter++;
my_str = s;
for (m = 0; m < (full_counter - 1); m++)
for (n = m + 1; n > 0; n--)
my_temp = *(my_str + n);
*(my_str + n) = *(my_str + (n - 1));
*(my_str + (n - 1)) = my_temp;
}
}
syntax_err_checking
#include "main.h"
/**
* repeated_char - counts the repetitions of a char
* @my_inpt: input string
* @i: index
* Return: repetitions
*/
int repeated_char(char *my_inpt, int i)
if (*(my_inpt - 1) == *my_inpt)
return (repeated_char(my_inpt - 1, i + 1));
return (i);
/**
* error_sep_op - finds syntax errors
* @my_inpt: input string
* @m: index
* @my_lst: last char read
* Return: index of error. 0 when there are no
* errors
*/
int error_sep_op(char *my_inpt, int m, char my_lst)
int full_counter;
full_counter = 0;
if (*my_inpt == '\0')
return (0);
if (*my_inpt == ' ' || *my_inpt == '\t')
return (error_sep_op(my_inpt + 1, m + 1, my_lst));
if (*my_inpt == ';')
if (my_lst == '|' || my_lst == '&' || my_lst == ';')
return (m);
if (*my_inpt == '|')
if (my_lst == ';' || my_lst == '&')
return (m);
if (my_lst == '|')
full_counter = repeated_char(my_inpt, 0);
if (full_counter == 0 || full_counter > 1)
return (m);
if (*my_inpt == '&')
if (my_lst == ';' || my_lst == '|')
return (m);
if (my_lst == '&')
{
full_counter = repeated_char(my_inpt, 0);
if (full_counter == 0 || full_counter > 1)
return (m);
return (error_sep_op(my_inpt + 1, m + 1, *my_inpt));
/**
* first_char - finds index of the first char
* @input: input string
* @i: index
* Return: 1 if there is an error. 0 in other case.
*/
int first_char(char *input, int *i)
for (*i = 0; input[*i]; *i += 1)
if (input[*i] == ' ' || input[*i] == '\t')
continue;
if (input[*i] == ';' || input[*i] == '|' || input[*i] == '&')
return (-1);
break;
}
return (0);
/**
* print_syntax_error - prints when a syntax error is found
* @my_data_sh: data structure
* @input: input string
* @m: index of the error
* @bool: to control msg error
* Return: no return
*/
void print_syntax_error(data_shell *my_data_sh, char *input, int m, int bool)
char *my_message, *my_message2, *my_message3, *some_err, *full_counter;
int my_l;
if (input[m] == ';')
if (bool == 0)
my_message = (input[m + 1] == ';' ? ";;" : ";");
else
my_message = (input[m - 1] == ';' ? ";;" : ";");
if (input[m] == '|')
my_message = (input[m + 1] == '|' ? "||" : "|");
if (input[m] == '&')
my_message = (input[m + 1] == '&' ? "&&" : "&");
my_message2 = ": Syntax error: \"";
my_message3 = "\" unexpected\n";
full_counter = aux_itoa(my_data_sh->counter);
my_l = _strlen(my_data_sh->av[0]) + _strlen(full_counter);
my_l += _strlen(my_message) + _strlen(my_message2) + _strlen(my_message3) + 2;
some_err = malloc(sizeof(char) * (my_l + 1));
if (some_err == 0)
free(full_counter);
return;
_strcpy(some_err, my_data_sh->av[0]);
_strcat(some_err, ": ");
_strcat(some_err, full_counter);
_strcat(some_err, my_message2);
_strcat(some_err, my_message);
_strcat(some_err, my_message3);
_strcat(some_err, "\0");
write(STDERR_FILENO, some_err, my_l);
free(some_err);
free(full_counter);
/**
* check_syntax_error - intermediate function to
* find and print a syntax error
* @my_data_sh: data structure
* @input: input string
* Return: 1 if there is an error. 0 in other case
*/
int check_syntax_error(data_shell *my_data_sh, char *input)
{
int begin = 0;
int f_char = 0;
int i = 0;
f_char = first_char(input, &begin);
if (f_char == -1)
print_syntax_error(my_data_sh, input, begin, 0);
return (1);
i = error_sep_op(input + begin, 0, *(input + begin));
if (i != 0)
print_syntax_error(my_data_sh, input, begin + i, 1);
return (1);
return (0);
we_get_err2
#include "main.h"
/**
* error_env - my_err message for env in get_env.
* @my_data_sh: data relevant (counter, arguments)
* Return: my_err message.
*/
char *error_env(data_shell *my_data_sh)
{
int my_l;
char *my_err;
char *ver_str;
char *my_message;
ver_str = aux_itoa(my_data_sh->counter);
my_message = ": Unable to add/remove from environment\n";
my_l = _strlen(my_data_sh->av[0]) + _strlen(ver_str);
my_l += _strlen(my_data_sh->args[0]) + _strlen(my_message) + 4;
my_err = malloc(sizeof(char) * (my_l + 1));
if (my_err == 0)
free(my_err);
free(ver_str);
return (NULL);
_strcpy(my_err, my_data_sh->av[0]);
_strcat(my_err, ": ");
_strcat(my_err, ver_str);
_strcat(my_err, ": ");
_strcat(my_err, my_data_sh->args[0]);
_strcat(my_err, my_message);
_strcat(my_err, "\0");
free(ver_str);
return (my_err);
/**
* error_path_126 - my_err message for path and failure denied permission.
* @my_data_sh: data relevant (counter, arguments).
* Return: The my_err string.
*/
char *error_path_126(data_shell *my_data_sh)
int my_l;
char *ver_str;
char *my_err;
ver_str = aux_itoa(my_data_sh->counter);
my_l = _strlen(my_data_sh->av[0]) + _strlen(ver_str);
my_l += _strlen(my_data_sh->args[0]) + 24;
my_err = malloc(sizeof(char) * (my_l + 1));
if (my_err == 0)
free(my_err);
free(ver_str);
return (NULL);
_strcpy(my_err, my_data_sh->av[0]);
_strcat(my_err, ": ");
_strcat(my_err, ver_str);
_strcat(my_err, ": ");
_strcat(my_err, my_data_sh->args[0]);
_strcat(my_err, ": Permission denied\n");
_strcat(my_err, "\0");
free(ver_str);
return (my_err);
}
we_got_err1
#include "main.h"
/**
* strcat_cd - function that concatenates the message for cd error
* @my_data_sh: data relevant (directory)
* @my_message: message to print
* @my_err: output message
* @my_ver_string: counter lines
* Return: error message
*/
char *strcat_cd(data_shell *my_data_sh, char *my_message, char *my_err, char *my_ver_string)
char *illegal_flag;
_strcpy(my_err, my_data_sh->av[0]);
_strcat(my_err, ": ");
_strcat(my_err, my_ver_string);
_strcat(my_err, ": ");
_strcat(my_err, my_data_sh->args[0]);
_strcat(my_err, my_message);
if (my_data_sh->args[1][0] == '-')
illegal_flag = malloc(3);
illegal_flag[0] = '-';
illegal_flag[1] = my_data_sh->args[1][1];
illegal_flag[2] = '\0';
_strcat(my_err, illegal_flag);
free(illegal_flag);
}
else
_strcat(my_err, my_data_sh->args[1]);
_strcat(my_err, "\n");
_strcat(my_err, "\0");
return (my_err);
/**
* error_get_cd - error message for cd command in get_cd
* @my_data_sh: data relevant (directory)
* Return: Error message
*/
char *error_get_cd(data_shell *my_data_sh)
int my_l, my_l_id;
char *my_err, *ver_str, *my_message;
ver_str = aux_itoa(my_data_sh->counter);
if (my_data_sh->args[1][0] == '-')
my_message = ": Illegal option ";
my_l_id = 2;
else
my_message = ": can't cd to ";
my_l_id = _strlen(my_data_sh->args[1]);
}
my_l = _strlen(my_data_sh->av[0]) + _strlen(my_data_sh->args[0]);
my_l += _strlen(ver_str) + _strlen(my_message) + my_l_id + 5;
my_err = malloc(sizeof(char) * (my_l + 1));
if (my_err == 0)
free(ver_str);
return (NULL);
my_err = strcat_cd(my_data_sh, my_message, my_err, ver_str);
free(ver_str);
return (my_err);
/**
* error_not_found - generic error message for command not found
* @my_data_sh: data relevant (counter, arguments)
* Return: Error message
*/
char *error_not_found(data_shell *my_data_sh)
int my_l;
char *my_err;
char *my_ver_string;
my_ver_string = aux_itoa(my_data_sh->counter);
my_l = _strlen(my_data_sh->av[0]) + _strlen(my_ver_string);
my_l += _strlen(my_data_sh->args[0]) + 16;
my_err = malloc(sizeof(char) * (my_l + 1));
if (my_err == 0)
free(my_err);
free(my_ver_string);
return (NULL);
_strcpy(my_err, my_data_sh->av[0]);
_strcat(my_err, ": ");
_strcat(my_err, my_ver_string);
_strcat(my_err, ": ");
_strcat(my_err, my_data_sh->args[0]);
_strcat(my_err, ": not found\n");
_strcat(my_err, "\0");
free(my_ver_string);
return (my_err);
/**
* error_exit_shell - generic error message for exit in get_exit
* @my_data_sh: data relevant (counter, arguments)
* Return: Error message
*/
char *error_exit_shell(data_shell *my_data_sh)
int my_l;
char *my_err;
char *my_ver_string;
my_ver_string = aux_itoa(my_data_sh->counter);
my_l = _strlen(my_data_sh->av[0]) + _strlen(my_ver_string);
my_l += _strlen(my_data_sh->args[0]) + _strlen(my_data_sh->args[1]) + 23;
my_err = malloc(sizeof(char) * (my_l + 1));
if (my_err == 0)
{
free(my_ver_string);
return (NULL);
_strcpy(my_err, my_data_sh->av[0]);
_strcat(my_err, ": ");
_strcat(my_err, my_ver_string);
_strcat(my_err, ": ");
_strcat(my_err, my_data_sh->args[0]);
_strcat(my_err, ": Illegal number: ");
_strcat(my_err, my_data_sh->args[1]);
_strcat(my_err, "\n\0");
free(my_ver_string);
return (my_err);