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.
222 lines
4.5 KiB
222 lines
4.5 KiB
/* 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; |
|
}
|
|
|