Advertisement
Guest User

Untitled

a guest
Feb 5th, 2017
136
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 9.80 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <signal.h>
  5. #include <dirent.h>
  6. #include <fcntl.h>
  7. #include <glob.h>
  8. #include <time.h>
  9. #include <unistd.h>
  10. #include <sys/stat.h>
  11. #include <sys/wait.h>
  12. #include <ctype.h>
  13. #include <errno.h>
  14.  
  15. #define LOGOUT 50
  16. #define MAXNUM 40
  17. #define MAXLEN 500
  18. #define MAXSIZE 500
  19. #define BUFSIZE 200
  20. #define TRUE 1
  21. #define FALSE 0
  22.  
  23.  
  24. typedef struct command_history
  25. {
  26.     char *command;
  27.     struct command_history *next;
  28. } history;
  29.  
  30. void sighandler(int sig)
  31. {
  32.     printf("\nauto logout\n");
  33.     exit(0);
  34. }
  35.  
  36. /* left_child --- do the work for the left child */
  37.  
  38. void left_child(char *args[MAXNUM], int pipefd[2])
  39. {
  40.  
  41.     close(pipefd[0]);
  42.     dup2(pipefd[1], STDOUT_FILENO);
  43.     execvp(args[0], args);
  44.     _exit(errno == ENOENT ? 127 : 126);
  45. }
  46.  
  47. /* right_child --- do the work for the right child */
  48.  
  49. void right_child(char *args2[MAXNUM],int pipefd[2])
  50. {
  51.  
  52.     close(pipefd[1]);
  53.     dup2(pipefd[0], STDIN_FILENO);
  54.     execvp(args2[0], args2);
  55.     perror("execv");
  56.     _exit(errno == ENOENT ? 127 : 126);
  57. }
  58.  
  59. int SinglePipe2(char *args[MAXNUM], char *args2[MAXNUM], int redir_in, int redir_out, int fd){
  60.  
  61.     int pipefd[2];
  62.     pid_t left_pid, right_pid;
  63.     pid_t ret;
  64.     pid_t pid;
  65.     int status;
  66.  
  67.     if (pipe(pipefd) < 0) {     /* create pipe, very first thing */
  68.         perror("pipe");
  69.         exit(1);
  70.     }
  71.  
  72.     if ((left_pid = fork()) < 0) {  /* fork left-hand child */
  73.         perror("fork");
  74.         exit(1);
  75.     } else if (left_pid == 0)
  76.         left_child(args, pipefd);
  77.  
  78.     if ((right_pid = fork()) < 0) { /* fork right-hand child */
  79.         perror("fork");
  80.         exit(1);
  81.     } else if (right_pid == 0)
  82.         right_child(args2, pipefd);
  83.  
  84.     close(pipefd[0]);       /* close parent's copy of pipe */
  85.     close(pipefd[1]);
  86.  
  87.     while ((ret = wait(& status)) > 0) {    /* wait for children */
  88.         if (ret == left_pid)
  89.             printf("left child terminated, status: %x\n", status);
  90.         else if (ret == right_pid)
  91.             printf("right child terminated, status: %x\n", status);
  92.         else
  93.             printf("yow! unknown child %d terminated, status %x\n",
  94.                 ret, status);
  95.     }
  96.     switch (pid = fork()) {
  97.             case -1:
  98.  
  99.                 perror("fork");
  100.  
  101.             case 0:/* child process, exec() */
  102.  
  103.                 if(redir_out){ //redirection to output file
  104.                     dup2(fd, STDOUT_FILENO);
  105.                     close(fd);
  106.  
  107.                 }
  108.                 else if(redir_in){ //redirection to input file
  109.                     dup2(fd, STDIN_FILENO);
  110.                     close(fd);
  111.  
  112.                 }
  113.  
  114.  
  115.             if (execvp(args[0], args))
  116.                 perror("execv");
  117.                 exit(1);
  118.  
  119.             }
  120.  
  121.     return 1;
  122. }
  123.  
  124.  
  125. /* Main */
  126. int main(void)
  127. {
  128.  
  129.     char *currentpath, *cmd, line[MAXLEN], *args[MAXNUM], *args2[MAXNUM], *args3[MAXNUM];
  130.     int background, i, j, t, wildcard, opts;
  131.     int redir_in, redir_out;
  132.     int fd;
  133.     long size;
  134.     char *buf;
  135.     /*pid_t pid, pid2; */
  136.     struct sigaction act;
  137.     char *history[MAXSIZE], command[MAXSIZE], command_number[MAXSIZE], *temp;
  138.     int history_count = 0, length, number, offs;
  139.     int pipefd[2], pipefd2[2];
  140.     int numberofpipes, pipesuccess;
  141.     char buffer[BUFSIZE];
  142.     FILE *fp;
  143.  
  144.  
  145.     size = pathconf(".", _PC_PATH_MAX);
  146.     buf = (char*)malloc((size_t)size);
  147.  
  148.     /* set the signal handler for alarm */
  149.     signal(SIGALRM, sighandler);
  150.  
  151.     /*get default working directory as current path*/
  152.     currentpath = getenv("PWD");
  153.  
  154.     while (1)
  155.     {
  156.         /* initialize */
  157.         glob_t globbuf;
  158.         background = FALSE;
  159.         wildcard = FALSE;
  160.         opts = FALSE;
  161.         /*redir_in = FALSE; redir_out = FALSE;*/
  162.         pipesuccess = FALSE;
  163.         numberofpipes = 0, t = 0, offs = 0;
  164.         globbuf.gl_offs = 0;
  165.  
  166.         /* print the prompt */
  167.         fprintf(stdout, "%s > ", currentpath);
  168.  
  169.         /* set the timeout for autologout, function alarm() */
  170.         alarm(LOGOUT);
  171.  
  172.         /* read the users command */
  173.         if (fgets(line,MAXLEN,stdin) == NULL) {
  174.             fprintf(stdout, "\nlogout\n");
  175.             exit(0);
  176.         }
  177.  
  178.         line[strlen(line) - 1] = '\0';
  179.  
  180.         if (strlen(line) == 0)
  181.             continue;
  182.  
  183.  
  184.         /* start to background? (check if the last character is '&') */
  185.         if(line[strlen(line)-1] == '&')
  186.         {
  187.             line[strlen(line)-1] = '\0'; //remove '&'
  188.             background = TRUE;
  189.         }
  190.  
  191.         /* saving the user command into history list */
  192.  
  193.         if(line[0] != '!'){
  194.             if (history_count < MAXSIZE){
  195.                 history[history_count] = strdup(line);
  196.                 history_count++;
  197.             }
  198.         }
  199.  
  200.  
  201.         /* split the command line to args[]*/
  202.         i = 0;  //number of arguments
  203.         cmd = line;
  204.         while((args[i] = strtok(cmd, " ")) != NULL)
  205.         {
  206.             i++; //argument count
  207.             cmd = NULL;
  208.         }
  209.  
  210.         /* history usage */
  211.         if(line[0] == '!')
  212.         {
  213.             // find right command index from history
  214.             j = 0;
  215.             while (isdigit(line[j+1])){
  216.                 command_number[j] = line[j+1];
  217.                 j++;
  218.             }
  219.             number = atoi(command_number);
  220.             if (number <= history_count)
  221.             {
  222.                 // parsing the history commands back into args
  223.                 t = 0;
  224.                 temp = history[number-1];
  225.                 while((args[t] = strtok(temp, " ")) != NULL)
  226.                 {
  227.                     t++;
  228.                     temp = NULL;
  229.                 }
  230.             }
  231.             else
  232.             {
  233.                 printf("Out of range of array.\n");
  234.             }
  235.         }
  236.  
  237.         /* find and open redirected files*/
  238.         for(j = 0; j < i; j++)
  239.         {
  240.             if(strcmp(args[j], ">") == 0){
  241.                 args[j] = NULL;
  242.                 fd = open(args[j+1], O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR);
  243.                 redir_out = TRUE;
  244.                 if (fd < 0) {
  245.                     perror("open");
  246.                     exit(0);
  247.                 }
  248.             }
  249.             else if(strcmp(args[j], "<") == 0){
  250.                 args[j] = NULL;
  251.                 fd = open(args[j+1], O_RDONLY, S_IRUSR | S_IWUSR);
  252.                 redir_in = TRUE;
  253.                 if (fd < 0) {
  254.                     perror("open");
  255.                     exit(0);
  256.                 }
  257.             }
  258.         }
  259.  
  260.         /* exit? */
  261.         if (strcmp(args[0], "exit") == 0) {
  262.             exit(0);
  263.         }
  264.  
  265.         /* wildcards */
  266.         for(j = 0; j < i; j++) {
  267.             // see if there're options
  268.             if(!strncmp(args[j], "-", 1)) { opts = TRUE; }
  269.             // enable and count the wildcards
  270.             if(!strncmp(args[j], "*", 1) || !strncmp(args[j], "?", 1) || !strncmp(args[j], "[", 1))             {
  271.                 wildcard = TRUE;
  272.                 offs++;
  273.             }
  274.         }
  275.  
  276.         if(wildcard) {
  277.             if(opts) // cmd with options
  278.             {
  279.                 globbuf.gl_offs = 2;
  280.                 glob(args[2], GLOB_DOOFFS, NULL, &globbuf);
  281.                 for(j = 3; j < (offs+offs); j++)
  282.                 {
  283.                     glob(args[j], GLOB_DOOFFS|GLOB_APPEND, NULL, &globbuf);
  284.                 }
  285.  
  286.                 globbuf.gl_pathv[0] = args[0];
  287.                 globbuf.gl_pathv[1] = args[1];
  288.             }
  289.             else // cmd without options
  290.             {
  291.                 globbuf.gl_offs = 1;
  292.                 glob(args[1], GLOB_DOOFFS, NULL, &globbuf);
  293.                 for(j = 2; j < (offs+1); j++)
  294.                 {
  295.                     glob(args[j], GLOB_DOOFFS|GLOB_APPEND, NULL, &globbuf);
  296.                 }
  297.                 globbuf.gl_pathv[0] = args[0];
  298.             }
  299.         }
  300.  
  301.  
  302.         /*  cd  */
  303.         if (strcmp(args[0], "cd") == 0)
  304.         {
  305.             if(i > 1)
  306.             {
  307.                 if(chdir(args[1]) != 0) //change to inputted directory
  308.                 {
  309.                     perror("chdir");
  310.                 }
  311.                 currentpath = getcwd(buf, (size_t)size); //set currentpath to cwd
  312.             }
  313.             else
  314.             {
  315.                 currentpath = getenv("HOME"); // change to homedir
  316.             }
  317.  
  318.             continue;
  319.         }
  320.  
  321.         /* history */
  322.         if(strcmp(args[0], "history") == 0)
  323.         {
  324.             printf("Command history: \n");
  325.             for (j = 0; j < history_count; j++) {
  326.                 printf("[%d]  %s \n", j+1, history[j]);
  327.             }
  328.             continue;
  329.         }
  330.  
  331.         /* find pipe marks for single and double pipe*/
  332.         int k=0, z=0, y=0;
  333.         if(!redir_out && !redir_in){
  334.             for (j = 0; j < i; j++) //i == argument count
  335.             {
  336.                 if(strncmp(args[j], "|", 1) == 0){
  337.                     args[j] = NULL; // make it null, so exec will stop there
  338.                     numberofpipes++;
  339.                     continue;
  340.                 }
  341.                 if(numberofpipes == 1){
  342.                     args2[z] = args[j]; //copy other part of args to args2
  343.                     args2[z+1] = NULL; //make sure last args2 is (null)
  344.                     z++;
  345.                     continue;
  346.                 }
  347.                 if(numberofpipes == 2){
  348.                     args3[y] = args[j]; //copy other part of args to args3
  349.                     args3[y+1] = NULL; //make sure last args3 is (null)
  350.                     y++;
  351.                 }
  352.             }
  353.         }
  354.  
  355.         /* single pipe */
  356.         if(numberofpipes == 1){
  357.  
  358.         SinglePipe2(args, args2, redir_in, redir_out, fd);
  359.  
  360.         }
  361.  
  362.         /*  pipe(pipefd);
  363.             if((pid = fork()) == -1){
  364.                 perror("fork");
  365.                 exit(1);
  366.             }
  367.             if(pid == 0) { /* child, args2
  368.                 close(pipefd[0]);
  369.                 dup2(pipefd[1], STDOUT_FILENO);
  370.                 close(pipefd[1]);
  371.                 execvp(args[0], args);
  372.  
  373.             }
  374.             else {   parent, args  /*
  375.                 close(pipefd[1]);
  376.                 dup2(pipefd[0], STDIN_FILENO);
  377.                 close(pipefd[0]);
  378.                 execvp(args2[0], args2);
  379.                 perror("execv");
  380.  
  381.             }
  382.         } */
  383.         /* double pipe
  384.         if(numberofpipes == 2){
  385.             pipe(pipefd);
  386.             pipe(pipefd2);
  387.  
  388.             if((pid = fork()) == -1){
  389.                 perror("fork");
  390.                 exit(1);
  391.             }
  392.                 if(pid == 0) {
  393.                     if((pid2 = fork()) == -1){
  394.                         perror("fork 2");
  395.                         exit(1);
  396.                     }
  397.                     if(pid2 == 0){ /* grandchild, args3
  398.                         close(pipefd[0]);
  399.                         close(pipefd[1]);
  400.                         close(pipefd2[1]);
  401.                         dup2(pipefd2[0], STDIN_FILENO);
  402.                         close(pipefd2[0]);
  403.                         execvp(args3[0], args3);
  404.                         perror("execv");
  405.                     }
  406.                     else { /* child, args2
  407.                         close(pipefd[1]);
  408.                         dup2(pipefd[0], STDIN_FILENO);
  409.                         close(pipefd[0]);
  410.                         close(pipefd2[0]);
  411.                         dup2(pipefd2[1], STDOUT_FILENO);
  412.                         close(pipefd2[0]);
  413.                         execvp(args2[0], args2);
  414.                         perror("execv");
  415.                     }
  416.                 }
  417.             else{ /* parent, args
  418.                 close(pipefd[0]);
  419.                 dup2(pipefd[1], STDOUT_FILENO);
  420.                 close(pipefd[1]);
  421.                 execvp(args[0], args);
  422.             }
  423.         } */
  424.  
  425.         /* fork to run the command
  426.         switch (pid = fork()) {
  427.             case -1:
  428.                 /* error
  429.                 perror("fork");
  430.                 continue;
  431.             case 0:/* child process, exec()
  432.  
  433.                 if(redir_out){ //redirection to output file
  434.                     dup2(fd, STDOUT_FILENO);
  435.                     close(fd);
  436.  
  437.                 }
  438.                 else if(redir_in){ //redirection to input file
  439.                     dup2(fd, STDIN_FILENO);
  440.                     close(fd);
  441.  
  442.                 }
  443.  
  444.                 else if (wildcard) {
  445.                     execvp(globbuf.gl_pathv[0], globbuf.gl_pathv);
  446.                     perror("execv");
  447.                     globfree(&globbuf);
  448.                     exit(1);
  449.                 }
  450.  
  451.                 else if (execvp(args[0], args)) {
  452.                 perror("execv");
  453.                 exit(1);
  454.             }
  455.             default:
  456.                 /* parent (shell), wait() if not background process
  457.                 if(!background){
  458.                     alarm(0);
  459.                     while(wait(NULL) != pid)
  460.                     {
  461.                         printf("please.");
  462.                     }
  463.                 }
  464.                 continue;
  465.         } */
  466.  
  467.     }
  468.     //globfree(&globbuf);
  469.     free(buf);
  470.     return 0;
  471. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement