Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stdlib.h>
- #include <signal.h>
- #include <unistd.h>
- #include <sys/wait.h>
- #include <sys/types.h>
- #include <string.h>
- #include <readline/history.h>
- #include <readline/readline.h>
- enum PIPES
- {
- READ, WRITE
- };
- typedef void sigfunc(int);
- sigfunc *signal(int, sigfunc*);
- #define MAX 100
- #define MAXCOM 1000 // max number of letters to be supported
- #define MAXLIST 100 // max number of commands to be supported
- char *filename;
- void getArgs(char* line,char** argsList)
- {
- int i;
- for (i = 0; i < MAXLIST; i++)
- {
- argsList[i] = strsep(&line, " ");
- if (argsList[i] == NULL)
- break;
- if (strlen(argsList[i]) == 0)
- i--;
- }
- }
- int inputLine(char* line)
- {
- char* help;
- help = readline("\n$ ");
- if (strlen(help) != 0)
- {
- add_history(help);
- strcpy(line, help);
- return 0;
- }
- else
- {
- return 1;
- }
- }
- int checkForPipes(char* str, char** argsLines)
- {
- int i;
- int count=0;
- for (i = 0; i < MAXLIST; i++)
- {
- argsLines[i] = strsep(&str, "|");
- if (argsLines[i] == NULL)
- break;
- }
- while (argsLines[count + 1] != NULL)
- count++;
- return count;
- }
- void printDir()
- {
- char cwd[1024];
- getcwd(cwd, sizeof(cwd));
- printf("\nDir: %s", cwd);
- }
- void editPath(char* str)
- {
- int i;
- char help[MAXCOM];
- char help2[MAXCOM]="./";
- if(str!=NULL)
- {
- if(str[0]=='/')
- {
- for(i=0; i<strlen(str); i++)
- {
- if(str[strlen(str)-1-i]=='/')
- {
- strncpy(help,str,strlen(str)-i);
- strcat(help,"./");
- strcat(help,str+(strlen(str)-i));
- str=help;
- }
- }
- }
- else
- {
- strcat(help2,str);
- strcpy(str,help2);
- }
- }
- }
- void loadHistory(const char *filename)
- {
- using_history();
- read_history(filename);
- }
- void printHistory(void)
- {
- HISTORY_STATE *commandHistory = history_get_history_state();
- HIST_ENTRY **commandList = history_list();
- printf("\n**********Shell History**********\n\n");
- for(int i = 0; i < commandHistory->length; i++)
- {
- printf("Command: %d ",i+1);
- printf("%8s %s\n ", commandList[i]->line, commandList[i]->timestamp);
- }
- }
- void writeHistory(const char *filename)
- {
- write_history(filename);
- }
- void deleteHistory(const char *filename)
- {
- FILE *file = fopen(filename, "r+");
- int temp = remove(filename);
- clear_history();
- }
- void sigHandler(int signo)
- {
- if(signo == SIGQUIT) printHistory();
- }
- int lineInMenu(char* line, char** argsList)
- {
- if(strcmp(line, "exit")==0)
- {
- writeHistory(filename);
- exit(0);
- }
- else if(strcmp(line, "history") ==0)
- {
- printHistory();
- return 1;
- }
- else if(strcmp(line, "delete") ==0)
- {
- deleteHistory(filename);
- return 1;
- }
- else if(strcmp(argsList[0],"cd")==0)
- {
- chdir(argsList[1]);
- return 1;
- }
- else return 0;
- }
- char* getUsername(void)
- {
- char *username;
- username = malloc(MAX*sizeof(char));
- username = getlogin();
- return username;
- }
- void setFilepath()
- {
- char *temp;
- temp = malloc(MAX*sizeof(char));
- char *username;
- username = malloc(MAX*sizeof(char));
- username = getUsername();
- char first[] = "/home/";
- char second[] = "/historyfile.txt";
- strcat(temp, first);
- strcat(temp, username);
- strcat(temp, second);
- filename = malloc(strlen(temp));
- filename = temp;
- printf("FILENAME: %s\n", filename);
- }
- void interpretExecution(char** argsList)
- {
- pid_t pid = fork();
- int i = 0;
- while (argsList[i + 1] != NULL)
- i++;
- if (strcmp(argsList[i], "&") == 0)
- {
- if (pid == 0)
- {
- argsList[i] = NULL;
- if ((execvp(argsList[0], argsList)) < 0)
- {
- editPath(argsList[0]);
- execvp(argsList[0], argsList);
- }
- exit(0);
- }
- }
- else
- {
- if (strcmp(argsList[i], "&") != 0 && pid == 0) //Child
- {
- if ((execvp(argsList[0], argsList)) < 0)
- {
- editPath(argsList[0]);
- execvp(argsList[0], argsList);
- }
- exit(0);
- }
- else //Parent
- {
- wait(NULL);
- }
- }
- }
- void interpretExecutionWithPipes(char*** extendedArgsList,int execCounter)
- {
- int i;
- int filedes[execCounter-1][2];
- for(i=0; i<execCounter-1; i++)
- {
- pipe(filedes[i]);
- }
- pid_t pid = fork();
- puts(extendedArgsList[0][0]);
- puts(extendedArgsList[0][1]);
- puts(extendedArgsList[1][0]);
- if (pid == 0)
- {
- dup2(filedes[0][WRITE], 1);
- execvp(extendedArgsList[i][0], extendedArgsList[i]);
- exit(0);
- }
- else
- {
- close(filedes[0][1]);
- }
- for(i=0; i<execCounter-2; i++)
- {
- pid = fork();
- if (pid == 0)
- {
- dup2(filedes[i][READ], 0);
- dup2(filedes[i+1][WRITE], 1);
- execvp(extendedArgsList[i][0], extendedArgsList[i]);
- }
- else
- {
- close(filedes[i][1]);
- }
- }
- pid = fork();
- if (pid == 0)
- {
- dup2(filedes[execCounter-2][READ], 0);
- execvp(extendedArgsList[i][0], extendedArgsList[i]);
- }
- wait(NULL);
- }
- int main(void)
- {
- setFilepath();
- if (signal(SIGQUIT, sigHandler) == SIG_ERR)
- printf("SIGQUIT ERROR");
- loadHistory(filename);
- char line[MAXCOM];
- char *argsList[MAXLIST];
- char*** extendedArgsList;
- puts("nowy program");
- int execCounter;
- int i,j;
- while(1)
- {
- printDir();
- if (inputLine(line))
- continue;
- execCounter=checkForPipes(line,argsList);
- if(execCounter)
- {
- extendedArgsList= (char ***)malloc(execCounter*sizeof(char**));
- for (i = 0; i< MAXLIST; i++)
- {
- extendedArgsList[i] = (char **) malloc(MAXLIST*sizeof(char *));
- for (j = 0; j < MAXCOM; j++)
- {
- extendedArgsList[i][j] = (char *)malloc(MAXCOM*sizeof(char));
- }
- }
- for(i=0; i<execCounter; i++)
- {
- getArgs(argsList[i],extendedArgsList[i]);
- }
- interpretExecutionWithPipes(extendedArgsList,execCounter);
- }
- else
- {
- getArgs(line,argsList);
- if (lineInMenu(line,argsList))
- continue;
- interpretExecution(argsList);
- }
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement