#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <wait.h>
#include <signal.h>

int split(char *string, char c, char **result);
void skip();
int isBackGround(char *command);
void (*oldhandler)();
int bbazig();

int main(int argc,char *argv[],char *envp[]){
char command[PATH_MAX];
char *commands[64];
int pid,c,status,command_num,counter,n;

oldhandler=signal(SIGINT,bbazig);

while(1){
int fd,i;
char *temp[64];
int process_counter;
int flag; /* bg 인지 확인하는 명령임. */

do{
/* 입력을 받기를 기다리다가 명령을 받는다.  */
waitpid(-1,&status,WNOHANG);
printf(“11982241>#”);  /* 프롬프트 */
flag = 0;
gets(command);  /* 명령 입력받기 */

/* 파이프 처리….  */
command_num = split(command,’|’,commands);

n = split(commands[0],’ ‘,temp);
}
while(strcmp(temp[0],””) == 0);

if((c = strcmp(temp[0],”exit”)) == 0){
for(counter = 0 ;counter < n ; counter++)
free(temp[counter]);
break;    /* 군소리 없이 끝내기 */
}
if((c = strcmp(temp[0],”help”)) == 0){
printf (“이 셸을 끝내시려면 exit를 치시는 것이 가장 좋습니다.n”);
printf (“그렇지 않으면 반항을 하는 특징이 있습니다.n”);
printf (“혹시 Ctrl+C로 종료하시려 하신다면 3초간 기다려 주세요.n”);
printf (“파이프나 리디렉션 사용시 상당히 반항하는 특징이 있습니다.n”);
printf (“웬만하면 사용하지 마세요….. 기타 등등. 중얼중얼중얼….n”);
} /*도움말이지만 도움이 될 지는 의문*/

/* cd 명령에서 문제 생겼을 때 */
if((c = strcmp(temp[0],”cd”)) == 0){
if(chdir(temp[1]) == -1)
printf(“%s:%sn”,temp[1],”그런 녀석 없답니다.^^;;;;”);
for(counter = 0;counter < n; counter++)
free(temp[counter]);
continue;
}

for(counter = 0; counter < command_num; counter++){
int n,m;
char *options[64];
char *redirect[4];

if(counter != command_num -1){
printf(“여기서는 파이프 처리가 될 리가 없죠? ^^;;;;n”);
printf(“아직 파이프를 쓰면 죽어 버리는데요……n”);
printf(“그럴 경우에는 주저없이 Ctrl+C 해 주세요.n”);
}

flag = isBackGround(commands[counter]);

pid = fork();
if(pid == 0){
/* 파이프를 쓸 때  */
if(command_num != 1) printf(“”);
/* 리디렉션이 들어왔을 때 */
if(split(commands[counter],’>’,redirect) > 1||split(commands[counter],'<‘,redirect) > 1){
printf(“리디렉션은 먹지않습니다!!!! 꺄하하하하하하~~~~~n”);
printf(“실력이 이것밖에 안 되는데 어떻게 하라고요!!!!!! ^^;;;;n”);
}else{
n = split(commands[counter],’ ‘,options);
execvp(options[0],options);
}
printf(“%sn%sn”,options[0],”command not found”);
_exit(1);
}else{

if(counter != 0 && command_num != 1){
close(fd);
}
if(counter != command_num -1){
printf(“”);

}

for(i = 0;i < n;i++) free(options[i]);
}
}

for(i = 0;i < command_num;i++) free(commands[i]);

if(flag == 0){
for(process_counter=0;process_counter<command_num;process_counter++)
wait(&status);
}
}

exit(0);
}

/* 문자열 자르는 함수. 인터넷 뒤지다가 찾은 함수를 그냥 인용. */
/* 출처는 북마크를 안 해서 잊어버림. –+ */
int split(char *string,char c,char **result){
int counter = 0;
char *workspace;
char *workspace_backup;
char *temp;

workspace = (char *)malloc(strlen(string) +1);
if(workspace == NULL){
printf(“%sn”,”Memory allocation error”);
return 0;
}

workspace_backup = workspace;
strcpy(workspace,string);

while(*workspace == c){
workspace++;
}

while((temp = strchr(workspace,c)) != NULL){
temp[0] = ”;

while(temp[1] == c){
temp++;
}

result[counter] = (char *)malloc(strlen(workspace) + 1);
if(result[counter] == NULL){
printf(“%sn”,”Memory allocation error”);
return 0;
}
strcpy(result[counter],workspace);
workspace = ++temp;
++counter;
}

result[counter] = (char *)malloc(strlen(workspace) + 1);
if(result[counter] == NULL){
printf(“%sn”,”Memory allocation error”);
return 0;
}
strcpy(result[counter],workspace);
++counter;
result[counter] = ”;   /* Null Termination */

free(workspace_backup);
return counter;
}

/* 한줄 내리기…… */
void skip(){
putchar(‘n’);
}

/* &를 구현합니다.  */
int isBackGround(char *command){
char *temp;
temp = strchr(command,’&’);
if(temp == NULL){
return 0;
}else{
*temp = ”;
return 1;
}
}

/* Ctrl+C 눌렀을 때…. */
int bbazig() {
printf(“허억~~~~~ 내가 사용자에게 살해당하다니~~~~!!!!!!!n”);
printf(“죽기 전에 마지막으로 하나 알려드리자면n”);
printf(“이 셸을 만들고 있는 사람은 n”);
printf(“학번은 11982241. 수학과 4학년 전혜진입니다.n”);
alarm(1);
//*(oldhandler)();
}