starting to fix redirects

This commit is contained in:
Jack Halford 2017-02-06 23:49:58 +01:00
parent 5cac33e7cf
commit bb52d35f4d
18 changed files with 820 additions and 56 deletions

16
42sh/11 Normal file
View file

@ -0,0 +1,16 @@
11
42sh
Makefile
Session.vim
a.out
debug
donovan_segaults_06-02
file
includes
libft
objs
out
pdf
script.sh
src
update_makefile.sh

17
42sh/9- Normal file
View file

@ -0,0 +1,17 @@
11
42sh
9-
Makefile
Session.vim
a.out
debug
donovan_segaults_06-02
file
includes
libft
objs
out
pdf
script.sh
src
update_makefile.sh

View file

@ -6,7 +6,7 @@
# By: wescande <wescande@student.42.fr> +#+ +:+ +#+ # # By: wescande <wescande@student.42.fr> +#+ +:+ +#+ #
# +#+#+#+#+#+ +#+ # # +#+#+#+#+#+ +#+ #
# Created: 2016/08/29 21:32:58 by wescande #+# #+# # # Created: 2016/08/29 21:32:58 by wescande #+# #+# #
# Updated: 2017/02/06 15:47:04 by wescande ### ########.fr # # Updated: 2017/02/06 21:49:51 by jhalford ### ########.fr #
# # # #
# **************************************************************************** # # **************************************************************************** #
@ -29,18 +29,6 @@ INC_DIR = includes/
OBJ_DIR = objs/ OBJ_DIR = objs/
SRC_BASE = \ SRC_BASE = \
completion/c_output.c\
completion/c_binary.c\
completion/c_clear.c\
completion/c_files.c\
completion/c_init.c\
completion/c_matching.c\
completion/c_parser.c\
completion/c_pathsolver.c\
completion/c_printer.c\
completion/c_sizing.c\
completion/c_terminal.c\
completion/completion.c\
builtin/bt_read_get.c\ builtin/bt_read_get.c\
builtin/bt_read_parse.c\ builtin/bt_read_parse.c\
builtin/bt_read_term.c\ builtin/bt_read_term.c\
@ -52,7 +40,20 @@ builtin/builtin_read.c\
builtin/builtin_setenv.c\ builtin/builtin_setenv.c\
builtin/builtin_unsetenv.c\ builtin/builtin_unsetenv.c\
builtin/is_builtin.c\ builtin/is_builtin.c\
completion/c_binary.c\
completion/c_clear.c\
completion/c_files.c\
completion/c_init.c\
completion/c_matching.c\
completion/c_output.c\
completion/c_parser.c\
completion/c_pathsolver.c\
completion/c_printer.c\
completion/c_sizing.c\
completion/c_terminal.c\
completion/completion.c\
exec/ast_free.c\ exec/ast_free.c\
exec/bad_fd.c\
exec/exec_ampersand.c\ exec/exec_ampersand.c\
exec/exec_and_if.c\ exec/exec_and_if.c\
exec/exec_command.c\ exec/exec_command.c\
@ -69,6 +70,11 @@ exec/process_reset.c\
exec/process_setexec.c\ exec/process_setexec.c\
exec/process_setgroup.c\ exec/process_setgroup.c\
exec/process_setsig.c\ exec/process_setsig.c\
exec/redirect_dgreat.c\
exec/redirect_great.c\
exec/redirect_greatand.c\
exec/redirect_less.c\
exec/redirect_lessand.c\
exec/set_exitstatus.c\ exec/set_exitstatus.c\
glob/dir_glob.c\ glob/dir_glob.c\
glob/expand_brace.c\ glob/expand_brace.c\

533
42sh/donovan_segaults_06-02 Normal file
View file

@ -0,0 +1,533 @@
ls
cat
`ls`
`
`ls`
`ls`
`ls`
cat *
ls *
echo "*"
echo *
echo */*
ls
make
make
ls
ls | cat
ls | cat -e
`ls`
`ls`
`ls`
`ls`
`ls`
`ls`
`ls`
`ls`
ls
`ls`
echo `ls -l`
(ls)
`ls`
`
`ls`
`
`
`
`
`
`
(ls))
(ls))
(ls))
`
(
`ls`
`ls`
`ls`
ls
`
ls
`ls`
`
)
(vim))
ls
`ls`
`l`
ls
ls
ls
`ls`
ls
`ls`
ls m
ls m 2>/dev/null
ls
ls >/dev/null
ls m
ls m 2>&1
ls m
ls m >/dev/null
ls m 2>/dev/null
ls m 2>&-
ls m
ls m 2>&-
ls
ls 1>/dev/null
ls merde
ls merde 2>/dev/null
ls merde 1>/dev/null
ls merde 3>/dev/null
ls merde 2>/dev/null
ls 2>/dev/null
ls
ls >/dev/null
ls >/dev/null
ls >/dev/null
ls >/dev/null
ls >/dev/null
ls >/dev/null
ls 1>/dev/null
ls 1>/dev/null
ls merde
ls merde >/dev/null
ls merde 2>/dev/null
ls merde 2>&-
ls merde 2<&-
ls merde 2<&-
ls merde 2<&-
ls
ls >&-
ls >&-
ls 2>&-
ls m 2>&-
ls
ls 1>&2 2>&-
ls 2>&- 1>&2
ls 2>&- 1>&2
ls 1>&2 2>&-
ls 1>&2 2>&-
ls 2>&- 1>&2
ls 1>&2
ls 1>&2 1>&-
ls 1>&- 1>&2
ls 2>&- 1>&2
ls 1>&- 2>&-
ls 1>&2- 2>&-
ls 1>&2 2>&-
ls 2>&- 1>&2
ls 1>&2-
ls 1>&2
ls 1>&2 1>&-
ls 1>&- 1>&2
ls 1>&- 1>&2
ls 2>&-
ls 2>&- 1>&-
ls 2>&- 1>&2
ls 2>&- 1>&2
ls 2>&- 1>&2
ls 2>&- 1>&2
ls 2>&- 1>&-
ls 2>&- 1>&-
ls 2>&- 1>&2
ls 1>&2 2>&-
ls
ls 2>&-
ls 2>&- 1>&2
ls
ls
ls
ls
ls
ls
ls
ls
ls
ls
ls
ls
`ls`
` `
`` ``
echo `ls``ls`
echo `ls` `ls`
`ls``ls`
a`ls`
`ls``
`ls``ls`
``
```
````
`` ```
`` ``
````
``
``
`
``
ls
``
`
make
``
````
`` ``
````
`` ``
`
``
````
`` ``
````
``
``
````
````
````
````
a`ls` echo `ls`
echo `ls`
echo `ls`
a`ls`
a`ls`
a`ls`
a`ls`
a`ls`
a`ls | wc`
ls
ls
ls
ls | cat
ls
``
` `
````
`` ``
cd
ls
alalalalal`ls`
1
`
``
` `
(vim)& `ls`
jobs
fg
fg
jobs -l
kill -9 80401
jobs
jobs
fg
vim&
jobs
ls
vim&
ls&
jobs
fg
jobs
ls&
jobs
jobs -l
ls
ls&
jobs
vim
jobs
jobs
ls
ls&
jobs
ls&
jobs
vim&
fg
ls
a`la`
ls
ls
ls
```` ```` ``
ls
ls
ls >&-
ls >&waf-
ls >&24-
ls
{}
{()}
({})
{(ls)}
()
ls
read -n 4
read -n 5
echo $REPLY
read -n 4
l
read -n 4
read - n5
read -n 5
echo $REPLY | cat -e
echo $REPLY
read -n 5
echo $REPLY
read -n 3
echo $REPLY
read -n 3
echo $REPLY
read -n -s
read -n 2 -s
read -s
ls
read -n 3
echo $REPLY
echo $REPLY | cat -e
echo $PATH
read -n 10
echo $REPLY
read -n 10
echo $REPLY
(ls)
(ls)l
(ls)
(ls)l
(ls)
(ls)l
{()}
{}
42sh_cpy > wc -l < Makefile
42sh_cpy > wc -l > Makefile
wc -l < Makefile
cat <Makefile
wc -l < Makefile
wc -l
make
ls
wc -l < Makefile
wc <
ls >out1
ls <out1
ls > out
ls < out
ls > out
ls < out
ls>out
ls<out
ls>out
ls<out
ls>out
ls<out
ls
cat out
ls<Makefile
cat<Makefile
make
ls>out
ls<out
cat<Makefile
ls>out
ls<out
wc<Makefile
cat Makefile
cat<Makefile
cat Makefile
cat<out
make
cat<out
ls
cat<out
ls>out
cat out
ls<out
ls>out
ls<out
ls>out
ls<out
ls>out
cat out
ls>out
ls<out
ls>out
rm out
ls >out
ls -l
ls out
ls
ls<out
ls>out
ls<out
echo $?
ls>out
cat out
ls>out
make
ls>out
ls<out
ls
ls -l
ls<file1
cat file1
cat script.sh
ls<script.sh
cat script.sh
ls >&-
ls
ls >&2 2>&-
ls > out
rm out
ls > out
ls -l
ls >out
;
l
ls
ls>out
cat out
wc -l <out
ls>out
ls -l >out
catout
cat out
cat <out
ls<out
make
ls>out
ls<out
ls>out
ls<out
ls>out
wc -l <out
wc -l <Makefile
cat <out
cat<out
ls -l >file1
cat file1
cat <file1
ls >file1
cat file1
cat <file1
ls
echo $PATH
$PATH
env
exit
vim &
jobs
fg
jobs -l
ls | wc -l | ls &
jobs -l
ls | wc -l | ls | sleep 444444 &
jobs -l
kill -9 22969
vim &
ls
jobs- l
jobs -l
vim &
ls
jobs
ls>out
wc -l <out
wc <out
ls 2>&- 1>&2
cat
cat /dev/random|base64|head -c 8 &
cat /dev/random|base64|head -c 8
ls
stty
stty -a
ls
cat
ls 'abc
def'
ls 'abc
'
ls >&-
ls 2>&-
ls mm 2>&-
ls mm 2>&-
cd >&-
./a.out
ls
./a.out
./42sh
pwd
/Users/jhalford/minishell/a.out
ls | /Users/jhalford/minishell/a.out
/a | cat /dev/random | base64 > /dev/null
./42sh
sleep 66666 &
jobs
echo '\
'
ls \
ls '\'
ls "\"
\
\
\
\
\
\\
\\
abc\
def
l\
s
ls 3>&-
ls >&3
ls -- -1>file3
ls -- 9>file3
ls -- 10>file3
ls -- 9999999999999999999999999999999999999999999999999999999>file3
ls -- 2147483648>file3
ls -- 2147483647>file3
ls -- >&2147483648
ls -- >&2147483649
ulimit -a
&
\\ \ \\\
${$(})} ${$((}))} ${`}`} ${${a}}
( ls # )
ls&&ls;ls||ls;
ls&&ls;ls||ls
echo a && echo b;
echo a || echo b;
echo a ||; echo b;
echo a; || echo b;
(ls;) ;
ls ;; ls
` ( echo "(ls" )`
` ( echo "(ls(" )`
` ( echo "(ls((" )`
`echo "ls -l"`
` echo "ls `echo .`"`

17
42sh/file Normal file
View file

@ -0,0 +1,17 @@
11
42sh
9-
Makefile
Session.vim
a.out
debug
donovan_segaults_06-02
file
includes
libft
objs
out
pdf
script.sh
src
update_makefile.sh

View file

@ -6,7 +6,7 @@
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */ /* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2016/11/27 20:29:56 by jhalford #+# #+# */ /* Created: 2016/11/27 20:29:56 by jhalford #+# #+# */
/* Updated: 2017/02/06 15:54:00 by jhalford ### ########.fr */ /* Updated: 2017/02/06 22:34:37 by jhalford ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
@ -84,14 +84,19 @@ int exec_command(t_btree **ast);
int launch_process(t_process *p); int launch_process(t_process *p);
int process_setexec(t_type type, t_process *p); int process_setexec(t_type type, t_process *p);
int process_setgroup(t_process *p, pid_t pid); int process_setgroup(t_process *p, pid_t pid);
int process_redirect(t_process *p);
int process_do_redirection(t_redir *redir);
void process_setsig(void); void process_setsig(void);
void process_free(void *content, size_t content_size); void process_free(void *content, size_t content_size);
void process_reset(void); void process_reset(void);
void fd_redirect(void); int process_redirect(t_process *p);
void fd_reset(void); int process_do_redirection(t_redir *redir);
void bad_fd(int fd);
int redirect_great(t_redir *redir, int *fdold, int *fdnew);
int redirect_less(t_redir *redir, int *fdold, int *fdnew);
int redirect_dgreat(t_redir *redir, int *fdold, int *fdnew);
int redirect_dless(t_redir *redir, int *fdold, int *fdnew);
int redirect_greatand(t_redir *redir, int *fdold, int *fdnew);
int redirect_lessand(t_redir *redir, int *fdold, int *fdnew);
char *ft_findexec(char *path, char *file); char *ft_findexec(char *path, char *file);

20
42sh/src/exec/bad_fd.c Normal file
View file

@ -0,0 +1,20 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* bad_fd.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2017/02/06 22:32:43 by jhalford #+# #+# */
/* Updated: 2017/02/06 22:34:21 by jhalford ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
void bad_fd(int fd)
{
ft_dprintf(2, "{red}%s: %i: Bad file descriptor{eoc}\n",
SHELL_NAME, fd);
exit(1);
}

View file

@ -6,7 +6,7 @@
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */ /* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2017/02/03 13:46:40 by jhalford #+# #+# */ /* Created: 2017/02/03 13:46:40 by jhalford #+# #+# */
/* Updated: 2017/02/06 16:51:17 by jhalford ### ########.fr */ /* Updated: 2017/02/06 22:54:19 by jhalford ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
@ -22,46 +22,44 @@ int process_do_redirection(t_redir *redir)
int fdold; int fdold;
int fdnew; int fdnew;
if (redir->type & (TK_GREAT | TK_DGREAT)) if (redir->n > 9)
{ bad_fd(redir->n);
fdold = redir->n; if (redir->type & TK_GREAT)
if ((fdnew = open(redir->word.word, O_WRONLY | O_CREAT redirect_great(redir, &fdold, &fdnew);
| ((redir->type & TK_GREAT) ? O_TRUNC : O_APPEND), else if (redir->type & TK_GREAT)
0644)) < 0) redirect_dgreat(redir, &fdold, &fdnew);
{
DG("open errno=%i", errno);
exit(1);
}
}
else if (redir->type & TK_LESS) else if (redir->type & TK_LESS)
redirect_less(redir, &fdold, &fdnew);
else if (redir->type & TK_GREATAND)
{ {
fdold = redir->n; if (redirect_greatand(redir, &fdold, &fdnew))
if ((fdnew = open(redir->word.word, O_RDONLY)) < 0)
{
ft_dprintf(2, "{red}%s: no such file or directory: %s{eoc}\n",
SHELL_NAME, redir->word.word);
exit (1);
}
}
else if (redir->type & (TK_LESSAND | TK_GREATAND))
{
if (redir->close)
{
close(redir->n);
return (0); return (0);
}
else if (redir->type & TK_LESSAND)
{
if (redirect_lessand(redir, &fdold, &fdnew))
return (0);
}
else
exit(42);
DG("gonna redirect dup2(%i,%i)", fdold, fdnew);
if (fd_is_valid(fdnew))
{
if (fd_is_valid(fdold))
{
dup2(fdold, fdnew);
close(fdold);
} }
else else
{ bad_fd(fdold);
fdold = redir->type & TK_LESSAND ? redir->word.fd : redir->n;
fdnew = redir->type & TK_LESSAND ? redir->n : redir->word.fd;
}
} }
else else
{ {
ft_dprintf(2, "{red}%s: redirection error.{eoc}\n", SHELL_NAME); DG("[%i] is not a valid fd", fdnew);
return (-1); if (fdnew <= 2)
close(fdnew);
else
bad_fd(fdnew);
} }
fd_is_valid(fdold) ? dup2(fdnew, fdold) : close(fdnew);
close(fdnew);
return (0); return (0);
} }

View file

@ -6,7 +6,7 @@
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */ /* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2016/11/29 16:04:18 by jhalford #+# #+# */ /* Created: 2016/11/29 16:04:18 by jhalford #+# #+# */
/* Updated: 2017/02/06 16:46:06 by jhalford ### ########.fr */ /* Updated: 2017/02/06 22:23:33 by jhalford ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */

View file

@ -0,0 +1,25 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* redirect_dgreat.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2017/02/06 22:07:37 by jhalford #+# #+# */
/* Updated: 2017/02/06 22:27:10 by jhalford ### ########.fr */
/* */
/* ************************************************************************** */
#include "exec.h"
int redirect_dgreat(t_redir *redir, int *fdold, int *fdnew)
{
*fdold = redir->n;
if ((*fdnew = open(redir->word.word,
O_WRONLY | O_CREAT | O_APPEND, 0644)) < 0)
{
DG("open errno=%i", errno);
exit(1);
}
return (0);
}

View file

@ -0,0 +1,26 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* redirect_great.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2017/02/06 22:03:53 by jhalford #+# #+# */
/* Updated: 2017/02/06 22:42:05 by jhalford ### ########.fr */
/* */
/* ************************************************************************** */
#include "exec.h"
int redirect_great(t_redir* redir, int *fdold, int *fdnew)
{
*fdnew = redir->n;
if ((*fdold = open(redir->word.word,
O_WRONLY | O_CREAT | O_TRUNC, 0644)) < 0)
{
DG("open errno=%i", errno);
exit(1);
}
return (0);
dup2(fdold, fdnew);
}

View file

@ -0,0 +1,38 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* redirect_greatand.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2017/02/06 22:12:31 by jhalford #+# #+# */
/* Updated: 2017/02/06 22:54:20 by jhalford ### ########.fr */
/* */
/* ************************************************************************** */
#include "exec.h"
int redirect_greatand(t_redir *redir, int *fdold, int *fdnew)
{
if (redir->word.fd > 9)
bad_fd(redir->word.fd);
if (redir->close)
{
close(redir->n);
return (1);
}
else
{
*fdnew = redir->n;
*fdold = redir->word.fd;
}
if (fd_is_valid(fdold))
{
dup2(fdold, fdnew);
close(fdold);
}
else
bad_fd(fdold);
return (0);
}

View file

@ -0,0 +1,26 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* redirect_less.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2017/02/06 22:09:53 by jhalford #+# #+# */
/* Updated: 2017/02/06 22:38:46 by jhalford ### ########.fr */
/* */
/* ************************************************************************** */
#include "exec.h"
int redirect_less(t_redir *redir, int *fdold, int *fdnew)
{
*fdnew = redir->n;
if ((*fdold = open(redir->word.word, O_RDONLY)) < 0)
{
ft_dprintf(2, "{red}%s: no such file or directory: %s{eoc}\n",
SHELL_NAME, redir->word.word);
exit (1);
}
return (0);
dup2(fdold, fdnew);
}

View file

@ -0,0 +1,37 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* redirect_lessand.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2017/02/06 22:11:18 by jhalford #+# #+# */
/* Updated: 2017/02/06 22:55:03 by jhalford ### ########.fr */
/* */
/* ************************************************************************** */
#include "exec.h"
int redirect_lessand(t_redir *redir, int *fdold, int *fdnew)
{
if (redir->word.fd > 9)
bad_fd(redir->word.fd);
if (redir->close)
{
close(redir->n);
return (1);
}
else
{
*fdnew = redir->word.fd;
*fdold = redir->n;
}
if (fd_is_valid(fdnew))
{
dup2(fdold, fdnew);
close(fdold);
}
else
bad_fd(fdold);
return (0);
}

View file

@ -6,7 +6,7 @@
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */ /* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2017/02/02 15:30:59 by jhalford #+# #+# */ /* Created: 2017/02/02 15:30:59 by jhalford #+# #+# */
/* Updated: 2017/02/03 15:40:34 by jhalford ### ########.fr */ /* Updated: 2017/02/06 21:49:55 by jhalford ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */

View file

@ -6,7 +6,7 @@
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */ /* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2016/12/03 12:06:35 by jhalford #+# #+# */ /* Created: 2016/12/03 12:06:35 by jhalford #+# #+# */
/* Updated: 2017/01/27 15:54:53 by wescande ### ########.fr */ /* Updated: 2017/02/06 22:29:32 by jhalford ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */

View file

@ -6,7 +6,7 @@
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */ /* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2016/12/03 12:06:53 by jhalford #+# #+# */ /* Created: 2016/12/03 12:06:53 by jhalford #+# #+# */
/* Updated: 2017/01/27 15:55:16 by wescande ### ########.fr */ /* Updated: 2017/02/06 22:30:07 by jhalford ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */

View file

@ -6,7 +6,7 @@
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */ /* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2016/12/03 11:58:51 by jhalford #+# #+# */ /* Created: 2016/12/03 11:58:51 by jhalford #+# #+# */
/* Updated: 2017/01/27 15:55:27 by wescande ### ########.fr */ /* Updated: 2017/02/06 21:58:23 by jhalford ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */