42-archive/42sh/src/builtin/builtin_env.c

136 lines
3 KiB
C

/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* builtin_env.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: jhalford <jhalford@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2016/11/28 14:14:20 by jhalford #+# #+# */
/* Updated: 2017/03/03 16:07:30 by jhalford ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
/*
** a ajouter dans la lib ?
*/
int ft_sstr_found(char **sstr, char *name)
{
int size;
size = 0;
if (sstr)
while (sstr[size] && ft_strncmp(name, sstr[size], ft_strlen(name)))
++size;
return (size);
}
void ft_sstr_freeone(char **sstr, int index)
{
char *tmp;
if (!sstr || !sstr[index])
return ;
tmp = sstr[index];
while (sstr[index])
{
sstr[index] = sstr[index + 1];
index++;
}
free(tmp);
}
/*
**
*/
static void ft_env_execute(char *const argv[], char **env)
{
pid_t soon;
char *path;
char *path_exe;
path = ft_getenv(env, "PATH");
path_exe = ft_findexec(path, *argv);
if (!path || !path_exe)
{
ft_dprintf(2, "{red}%s: no such file or directory: %s{eoc}\n",
SHELL_NAME, *argv);
return ;
}
if ((soon = fork()))
wait(&soon);
else
set_exitstatus(execve(path_exe, argv, env), 1);
free(path_exe);
}
static void ft_illegal_opt_env(char c)
{
ft_dprintf(2, "{red}env: option requires an argument -- %c\n", c);
ft_dprintf(2, "usage: env\t[-iv] [-P utilpath] [-S string]");
ft_dprintf(2, " [-u name]\n\t\t[name=value ...] ");
ft_dprintf(2, "[utility [argument ...]]{eoc}\n");
}
static int ft_check_env_opt(char ***argv, char ***env)
{
if (!ft_strcmp(**argv, "-i"))
{
ft_sstrfree(*env);
*env = NULL;
++(*argv);
}
else if (!ft_strcmp(**argv, "-u"))
{
++(*argv);
if (!**argv)
{
ft_illegal_opt_env('u');
return (1);
}
ft_sstr_freeone(*env, ft_sstr_found(*env, **argv));
++(*argv);
}
else if (***argv == '-')
{
ft_illegal_opt_env(*(**argv + 1));
return (1);
}
return (0);
}
int builtin_env(const char *path, char *const argv[], char *const envp[])
{
char **env;
(void)path;
env = ft_sstrdup((char **)envp);
while (*argv)
{
if (ft_check_env_opt((char ***)&argv, (char ***)&env))
break ;
while (*argv && ft_strrchr(*argv, '='))
{
env = ft_sstradd(env, *argv);
++argv;
}
if (env && (!*argv || (!ft_strcmp(*argv, "env") && !*(argv + 1))))
{
ft_sstrprint(env, '\n');
ft_putchar('\n');
break ;
}
if (*argv && ft_strcmp(*argv, "env"))
{
ft_env_execute(argv, env);
break ;
}
if (*argv)
++argv;
}
ft_sstrfree(env);
return (0);
}