Guest User

Shell_Program_C

a guest
May 21st, 2017
278
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 5.80 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <unistd.h>
  3. #include <stdlib.h>
  4. #include <sys/wait.h>
  5. #include <string.h>
  6. #include <ctype.h>
  7. #include <sys/types.h>
  8.  
  9. #define MAX_LINE 80
  10.  
  11. void checkAmp(int* count, char** tokens, int *amp) {
  12.     size_t strlenth = strlen(tokens[*count - 1]);
  13.     if((strlenth == 1) && tokens[*count - 1][0] == '&')
  14.     {
  15.         *amp = 1;
  16.         tokens[*count - 1] = NULL;
  17.         *count = *count -1;
  18.     } else {
  19.         tokens[*count] = NULL;
  20.     }
  21. }
  22.  
  23. void doExit(int count, char** tokens) {
  24.     if(count == 1 && (strcmp(tokens[count - 1], "exit") == 0)) {
  25.         exit(0);
  26.     }
  27. }
  28.  
  29. int stringTok(char* sentence, char** tokens, int* cAmp) {
  30.     const char* delim = " \r\n";
  31.     int count = 0;
  32.    
  33.     // make copy of sentence for strtok
  34.     size_t len = strlen(sentence);
  35.     char *copy = malloc(len+1);
  36.     if(!copy) return 0; // if copy null, return 0
  37.     strncpy(copy, sentence, len);
  38.    
  39.     copy[len] = '\0';
  40.    
  41.     // Allocate and copy tokens
  42.     for(char* word = strtok(copy, delim);
  43.         word;
  44.         word = strtok(NULL, delim))
  45.     {
  46.         size_t len = strlen(word);
  47.         tokens[count] = malloc(len+1);
  48.         if(!tokens[count]) break;
  49.         strncpy(tokens[count], word, len);
  50.         tokens[count][len] = '\0';
  51.         count++;
  52.     }
  53.     checkAmp(&count, tokens, cAmp);
  54.     doExit(count, tokens);
  55.     return count;
  56. }
  57.  
  58. char** initialize() {
  59.     char** hist = malloc(10 * sizeof(char *));
  60.     for (int i = 0; i < 10; ++i) {
  61.         hist[i] = (char *)malloc((MAX_LINE / 2) + 1);
  62.         for(int j = 0; j < (MAX_LINE / 2); j++) {
  63.             hist[i][j] = '\0';
  64.         }
  65.     }
  66.     return hist;
  67. }
  68.  
  69. void readHist(char**hist, int histC ,char** tokens, int count) {
  70.     int k = (histC - 1) % 10;
  71.     for(int i = 0; i < count; i++) {
  72.         size_t strlenth = strlen(tokens[i]);
  73.         if(count > 1) {
  74.             printf("before:hist[histC]:%stokens[i]:%s\n", hist[k],
  75.                    tokens[i]);
  76.             strcat(hist[k], tokens[i]);
  77.             printf("after strcat:hist[histC]:%stokens[i]:%s\n", hist[k], tokens[i]);
  78.            
  79.             if(i == count - 1) {
  80.                 hist[k][strlenth] = '\0';
  81.             } else {
  82.                 hist[k][strlenth] = ' ';
  83.             }
  84.         } else {
  85.             strcpy(hist[histC], tokens[count - 1]);
  86.             hist[k][strlenth] = '\0';
  87.         }
  88.     }
  89. }
  90. // check if nth History is valid
  91. int checkNthHist(char** tokens, int tcount) {
  92.     if(tcount == 1) {
  93.         if(tokens[tcount - 1][0] == '!') {
  94.             for(int i = 1; i < strlen(tokens[tcount - 1]); i++) {
  95.                 if(!isdigit(tokens[tcount - 1][i])) {
  96.                     return 0;
  97.                 }
  98.             }
  99.             char*str = malloc(strlen(tokens[tcount - 1]));
  100.             for(int i = 1; i < strlen(tokens[tcount -1]); i++) {
  101.                 str[i - 1] = tokens[tcount - 1][i];
  102.             }
  103.             return atoi(str);
  104.         } else {
  105.             return 0;
  106.         }
  107.     } else {
  108.         return 0;
  109.     }
  110. }
  111.  
  112. int findCmd(char** hist, int histC, int searchN) {
  113.     int k = 0;
  114.     if(histC >= 10) {
  115.         if(searchN > histC) {
  116.             return 0;
  117.         }
  118.         if(searchN < (histC - 9)) {
  119.             return 0;
  120.         }
  121.     } else {
  122.         if(searchN == 0) {
  123.             return 0;
  124.         }
  125.         if(searchN > histC) {
  126.             return 0;
  127.         }
  128.     }
  129.    
  130.     for(int i = histC; i > 1; i--) {
  131.         k = (i - 1) % 10;
  132.     }
  133.     return k;
  134. }
  135.  
  136. void histCheck(char**hist, int* histCount, char**tokens, int tcount, int* amp) {
  137.     *histCount = *histCount + 1;
  138.     if(strcmp(tokens[0], "!!") == 0) {
  139.         int k = (*histCount - 1) % 10; // latest
  140.         if(hist[k][0] == '\0') {
  141.             printf("No Command in History\n");
  142.         } else {
  143.             stringTok(hist[k], tokens, amp);
  144.         }
  145.     } else if (checkNthHist(tokens, tcount) > 0) { // !Nth history value
  146.         int searchN = checkNthHist(tokens, tcount);
  147.         if(findCmd(hist,*histCount, searchN) > 0) {
  148.             int k = findCmd(hist, *histCount, searchN);
  149.             stringTok(hist[k], tokens, amp);
  150.         } else {
  151.             printf("No Command in History\n");
  152.         }
  153.     } else {
  154.            readHist(hist, *histCount, tokens, tcount);
  155.     }
  156. }
  157.  
  158. int viewHistory(char** hist, int histCount, char** tokens, int count) {
  159.     int k = 0;
  160.     if(strcmp(tokens[count - 1], "history") == 0) {
  161.         if(count == 1)
  162.         {
  163.             for(int i = histCount; i > 1; i--) {
  164.                 k = (i - 1) % 10;
  165.                 printf("%d %s\n", i, hist[k]);
  166.             }
  167.             return 1;
  168.         } else {
  169.             return 0;
  170.         }
  171.     } else {
  172.         return 0;
  173.     }
  174. }
  175.  
  176. int main(void) {
  177.     char args[MAX_LINE]; // command to be executed
  178.     char *cmdargv[MAX_LINE]; // command tokens
  179.     char **hist;
  180.     int should_run = 1;
  181.     int isAmp = 0;
  182.     int histCount = 0;
  183.     hist = initialize();
  184.     do {
  185.         printf("osh>");
  186.         fflush(stdout);
  187.         fgets(args, MAX_LINE, stdin);
  188.        
  189.         int count = stringTok(args, cmdargv, &isAmp);
  190.        
  191.         histCheck(hist, &histCount, cmdargv, count, &isAmp);
  192.        
  193.         int pid = fork();
  194.        
  195.         if(pid == 0) {
  196.             // view history
  197.             if(viewHistory(hist, histCount, cmdargv, count)) {
  198.                 continue; // display history
  199.             }
  200.             if(execvp(cmdargv[0], cmdargv) < 0) {
  201.                 perror("Error:");
  202.             }
  203.             free(cmdargv);
  204.         } else if (pid > 0) {
  205.             if (isAmp) {
  206.                 printf("is amp is true\n");
  207.                 wait(&pid);
  208.             }
  209.         } else {
  210.             printf("Fork failed\n");
  211.             exit(1);
  212.         }
  213.         printf("\n");
  214.     } while(should_run);
  215.     return 0;
  216. }
Advertisement
Add Comment
Please, Sign In to add comment