Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <unistd.h>
- #include <stdlib.h>
- #include <sys/wait.h>
- #include <string.h>
- #include <ctype.h>
- #include <sys/types.h>
- #define MAX_LINE 80
- void checkAmp(int* count, char** tokens, int *amp) {
- size_t strlenth = strlen(tokens[*count - 1]);
- if((strlenth == 1) && tokens[*count - 1][0] == '&')
- {
- *amp = 1;
- tokens[*count - 1] = NULL;
- *count = *count -1;
- } else {
- tokens[*count] = NULL;
- }
- }
- void doExit(int count, char** tokens) {
- if(count == 1 && (strcmp(tokens[count - 1], "exit") == 0)) {
- exit(0);
- }
- }
- int stringTok(char* sentence, char** tokens, int* cAmp) {
- const char* delim = " \r\n";
- int count = 0;
- // make copy of sentence for strtok
- size_t len = strlen(sentence);
- char *copy = malloc(len+1);
- if(!copy) return 0; // if copy null, return 0
- strncpy(copy, sentence, len);
- copy[len] = '\0';
- // Allocate and copy tokens
- for(char* word = strtok(copy, delim);
- word;
- word = strtok(NULL, delim))
- {
- size_t len = strlen(word);
- tokens[count] = malloc(len+1);
- if(!tokens[count]) break;
- strncpy(tokens[count], word, len);
- tokens[count][len] = '\0';
- count++;
- }
- checkAmp(&count, tokens, cAmp);
- doExit(count, tokens);
- return count;
- }
- char** initialize() {
- char** hist = malloc(10 * sizeof(char *));
- for (int i = 0; i < 10; ++i) {
- hist[i] = (char *)malloc((MAX_LINE / 2) + 1);
- for(int j = 0; j < (MAX_LINE / 2); j++) {
- hist[i][j] = '\0';
- }
- }
- return hist;
- }
- void readHist(char**hist, int histC ,char** tokens, int count) {
- int k = (histC - 1) % 10;
- for(int i = 0; i < count; i++) {
- size_t strlenth = strlen(tokens[i]);
- if(count > 1) {
- printf("before:hist[histC]:%stokens[i]:%s\n", hist[k],
- tokens[i]);
- strcat(hist[k], tokens[i]);
- printf("after strcat:hist[histC]:%stokens[i]:%s\n", hist[k], tokens[i]);
- if(i == count - 1) {
- hist[k][strlenth] = '\0';
- } else {
- hist[k][strlenth] = ' ';
- }
- } else {
- strcpy(hist[histC], tokens[count - 1]);
- hist[k][strlenth] = '\0';
- }
- }
- }
- // check if nth History is valid
- int checkNthHist(char** tokens, int tcount) {
- if(tcount == 1) {
- if(tokens[tcount - 1][0] == '!') {
- for(int i = 1; i < strlen(tokens[tcount - 1]); i++) {
- if(!isdigit(tokens[tcount - 1][i])) {
- return 0;
- }
- }
- char*str = malloc(strlen(tokens[tcount - 1]));
- for(int i = 1; i < strlen(tokens[tcount -1]); i++) {
- str[i - 1] = tokens[tcount - 1][i];
- }
- return atoi(str);
- } else {
- return 0;
- }
- } else {
- return 0;
- }
- }
- int findCmd(char** hist, int histC, int searchN) {
- int k = 0;
- if(histC >= 10) {
- if(searchN > histC) {
- return 0;
- }
- if(searchN < (histC - 9)) {
- return 0;
- }
- } else {
- if(searchN == 0) {
- return 0;
- }
- if(searchN > histC) {
- return 0;
- }
- }
- for(int i = histC; i > 1; i--) {
- k = (i - 1) % 10;
- }
- return k;
- }
- void histCheck(char**hist, int* histCount, char**tokens, int tcount, int* amp) {
- *histCount = *histCount + 1;
- if(strcmp(tokens[0], "!!") == 0) {
- int k = (*histCount - 1) % 10; // latest
- if(hist[k][0] == '\0') {
- printf("No Command in History\n");
- } else {
- stringTok(hist[k], tokens, amp);
- }
- } else if (checkNthHist(tokens, tcount) > 0) { // !Nth history value
- int searchN = checkNthHist(tokens, tcount);
- if(findCmd(hist,*histCount, searchN) > 0) {
- int k = findCmd(hist, *histCount, searchN);
- stringTok(hist[k], tokens, amp);
- } else {
- printf("No Command in History\n");
- }
- } else {
- readHist(hist, *histCount, tokens, tcount);
- }
- }
- int viewHistory(char** hist, int histCount, char** tokens, int count) {
- int k = 0;
- if(strcmp(tokens[count - 1], "history") == 0) {
- if(count == 1)
- {
- for(int i = histCount; i > 1; i--) {
- k = (i - 1) % 10;
- printf("%d %s\n", i, hist[k]);
- }
- return 1;
- } else {
- return 0;
- }
- } else {
- return 0;
- }
- }
- int main(void) {
- char args[MAX_LINE]; // command to be executed
- char *cmdargv[MAX_LINE]; // command tokens
- char **hist;
- int should_run = 1;
- int isAmp = 0;
- int histCount = 0;
- hist = initialize();
- do {
- printf("osh>");
- fflush(stdout);
- fgets(args, MAX_LINE, stdin);
- int count = stringTok(args, cmdargv, &isAmp);
- histCheck(hist, &histCount, cmdargv, count, &isAmp);
- int pid = fork();
- if(pid == 0) {
- // view history
- if(viewHistory(hist, histCount, cmdargv, count)) {
- continue; // display history
- }
- if(execvp(cmdargv[0], cmdargv) < 0) {
- perror("Error:");
- }
- free(cmdargv);
- } else if (pid > 0) {
- if (isAmp) {
- printf("is amp is true\n");
- wait(&pid);
- }
- } else {
- printf("Fork failed\n");
- exit(1);
- }
- printf("\n");
- } while(should_run);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment