136 lines
3 KiB
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);
|
|
}
|