You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
223 lines
4.5 KiB
223 lines
4.5 KiB
11 years ago
|
/* Copyright (C) 2012 Fabien Givors <fabien.givors@chezlefab.net>
|
||
|
* Copyright (C) 2012 Debian Facile
|
||
|
*
|
||
|
* Ce programme est un logiciel libre ; vous pouvez le redistribuer ou le
|
||
|
* modifier suivant les termes de la GNU General Public License telle que
|
||
|
* publiée par la Free Software Foundation ; soit la version 3 de la licence,
|
||
|
* soit (à votre gré) toute version ultérieure.
|
||
|
*
|
||
|
* Ce programme est distribué dans l'espoir qu'il sera utile, mais SANS AUCUNE
|
||
|
* GARANTIE ; pas même la garantie implicite de COMMERCIABILISABILITÉ ni
|
||
|
* d'ADÉQUATION à UN OBJECTIF PARTICULIER. Consultez la GNU General Public
|
||
|
* License pour plus de détails.
|
||
|
*
|
||
|
* Vous devriez avoir reçu une copie de la GNU General Public License en même
|
||
|
* temps que ce programme ; si ce n'est pas le cas, consultez
|
||
|
* <http://www.gnu.org/licenses>.
|
||
|
*
|
||
|
*/
|
||
|
|
||
|
#define _BSD_SOURCE
|
||
|
#define _GNU_SOURCE
|
||
|
#include <unistd.h>
|
||
|
#include <sys/types.h>
|
||
|
#include <sys/wait.h>
|
||
|
#include <stdlib.h>
|
||
|
#include <stdio.h>
|
||
|
#include <string.h>
|
||
|
#include <errno.h>
|
||
|
|
||
|
enum cmd_types {
|
||
|
CMD_NULL,
|
||
|
CMD_EXIT,
|
||
|
CMD_CD,
|
||
|
CMD_EXEC,
|
||
|
CMD_FORKANDWAIT,
|
||
|
CMD_FORKANDCONTINUE
|
||
|
};
|
||
|
|
||
|
enum cmd_types get_cmd_type(char* cmd[])
|
||
|
{
|
||
|
if(!cmd[0])
|
||
|
return CMD_NULL;
|
||
|
|
||
|
if(strcmp(cmd[0],"cd")==0)
|
||
|
return CMD_CD;
|
||
|
|
||
|
if(strcmp(cmd[0],"exit")==0)
|
||
|
return CMD_EXIT;
|
||
|
|
||
|
if(strcmp(cmd[0],"exec")==0)
|
||
|
return CMD_EXEC;
|
||
|
|
||
|
{
|
||
|
int i=0;
|
||
|
while(cmd[++i]);
|
||
|
i--;
|
||
|
if(strlen(cmd[i])==1 && cmd[i][0] == '&')
|
||
|
{
|
||
|
free(cmd[i]);
|
||
|
cmd[i]=NULL;
|
||
|
return CMD_FORKANDCONTINUE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return CMD_FORKANDWAIT;
|
||
|
}
|
||
|
|
||
|
char** parse_cmd(char* cmd)
|
||
|
{
|
||
|
char** argv = (char**)malloc(128*sizeof(char*));
|
||
|
int np = 0;
|
||
|
|
||
|
for(char* arg = NULL; (arg = strtok_r(cmd, " ",&cmd)); np++)
|
||
|
{
|
||
|
argv[np] = (char*)malloc(sizeof(arg));
|
||
|
strcpy(argv[np], arg);
|
||
|
}
|
||
|
argv[np]=NULL;
|
||
|
|
||
|
return argv;
|
||
|
}
|
||
|
|
||
|
void free_cmd(char** argv)
|
||
|
{
|
||
|
for(int np = 0; argv[np]; np++)
|
||
|
free(argv[np]);
|
||
|
free(argv);
|
||
|
}
|
||
|
|
||
|
void print_prompt(void)
|
||
|
{
|
||
|
char* user = getenv("USER");
|
||
|
|
||
|
char hostname[64];
|
||
|
gethostname(hostname,sizeof(hostname));
|
||
|
|
||
|
char* cwd = get_current_dir_name();
|
||
|
char* home = getenv("HOME");
|
||
|
char* cwd2 = cwd;
|
||
|
if(strstr(cwd,home) == cwd)
|
||
|
{
|
||
|
cwd2+=strlen(home)-1;
|
||
|
cwd2[0]='~';
|
||
|
}
|
||
|
|
||
|
printf("%s@%s:%s$ ", user, hostname, cwd2);
|
||
|
free(cwd);
|
||
|
}
|
||
|
|
||
|
int main(void)
|
||
|
{
|
||
|
char buf[256];
|
||
|
|
||
|
print_prompt();
|
||
|
|
||
|
while(gets(buf))
|
||
|
{
|
||
|
char* buf_temp = buf;
|
||
|
char* cmd = NULL;
|
||
|
while((cmd = strtok_r(buf_temp, ";", &buf_temp)))
|
||
|
{
|
||
|
char** cmd_argv = parse_cmd(cmd);
|
||
|
|
||
|
int cmd_type = get_cmd_type(cmd_argv);
|
||
|
|
||
|
switch(cmd_type)
|
||
|
{
|
||
|
case CMD_NULL:
|
||
|
break;
|
||
|
|
||
|
case CMD_EXIT:
|
||
|
return 0;
|
||
|
|
||
|
case CMD_CD:
|
||
|
{
|
||
|
int r;
|
||
|
if(cmd_argv[1])
|
||
|
r = chdir(cmd_argv[1]);
|
||
|
else
|
||
|
r = chdir(getenv("HOME"));
|
||
|
|
||
|
if(r)
|
||
|
{
|
||
|
printf("cd: ");
|
||
|
switch(errno)
|
||
|
{
|
||
|
case EACCES:
|
||
|
printf("Pas le droit d'aller ici !\n");
|
||
|
break;
|
||
|
|
||
|
case ENOENT:
|
||
|
printf("La destination n'existe pas !\n");
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
printf("Erreur n°%d.\n", errno);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case CMD_FORKANDWAIT:
|
||
|
{
|
||
|
int f = 0;
|
||
|
int status;
|
||
|
switch(f = fork())
|
||
|
{
|
||
|
case 0:
|
||
|
execvp(cmd_argv[0],cmd_argv);
|
||
|
printf("Échec de l'exécution de la commande %s\n", cmd);
|
||
|
break;
|
||
|
|
||
|
case -1:
|
||
|
printf("Échec du fork.\n");
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
wait(&status);
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case CMD_FORKANDCONTINUE:
|
||
|
{
|
||
|
int f = 0;
|
||
|
switch(f = fork())
|
||
|
{
|
||
|
case 0:
|
||
|
execvp(cmd_argv[0],cmd_argv);
|
||
|
printf("Échec de l'exécution de la commande %s\n", cmd);
|
||
|
break;
|
||
|
|
||
|
case -1:
|
||
|
printf("Échec du fork.\n");
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case CMD_EXEC:
|
||
|
{
|
||
|
execvp(cmd_argv[0],cmd_argv);
|
||
|
printf("Échec de l'exécution de la commande %s\n", cmd);
|
||
|
}
|
||
|
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
free_cmd(cmd_argv);
|
||
|
|
||
|
}
|
||
|
print_prompt();
|
||
|
}
|
||
|
|
||
|
|
||
|
return 0;
|
||
|
}
|