Advertisement
Guest User

Untitled

a guest
Nov 28th, 2015
83
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 10.36 KB | None | 0 0
  1. /* Authors:
  2. Laura Manninen and Joni Suomalainen
  3.  
  4. 27.11.2015 */
  5.  
  6.  
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <string.h>
  10. #include <signal.h>
  11. #include <unistd.h>
  12. #include <limits.h>
  13. #include <sys/wait.h>
  14. #include <sys/types.h>
  15. #include <fcntl.h>
  16. #include <sys/stat.h>
  17. #include <glob.h>
  18. #include <unistd.h>
  19. #include <ctype.h>
  20.  
  21. #define LOGOUT 100
  22. #define MAXNUM 40
  23. #define MAXLEN 160
  24. #define die(msg) do {perror(msg); exit(EXIT_FAILURE);} while (0);
  25.  
  26. void sighandler(int sig)
  27. {
  28.         switch (sig) {
  29.                 case SIGALRM:
  30.                         printf("\nautologout\n");
  31.                         exit(0);
  32.                 default:
  33.                         break;
  34.         }
  35.         return;
  36. }
  37. /*reding history file*/
  38. void histRead(char* currentdir){
  39.         char* line;
  40.         size_t len = 0;
  41.         ssize_t read;
  42.         int id = 1;
  43.         FILE *filee;
  44.  
  45.         filee = fopen(currentdir, "r");
  46.         while((read = getline(&line, &len, filee)) != -1) {
  47.                 printf("%d %s", id,  line);
  48.                 id ++;
  49.         }
  50.         fclose(filee);
  51. }
  52. /*Reads specified command from history*/
  53. char* historynum(int i, char* currentdir) {
  54.  
  55.         char* line;
  56.         size_t len = 0;
  57.         ssize_t read;
  58.         int j = 1;
  59.         char * cmd;
  60.         int pid;
  61.  
  62.         FILE *file2;
  63.         file2 = fopen(currentdir, "r");
  64.         while((read = getline(&line, &len, file2)) != -1) {
  65.                 if (i==j) {            
  66.                         printf("%s", line);
  67.                         cmd = line;
  68.                 break;
  69.                 }
  70.             else {
  71.                         j++;
  72.                 }
  73.          
  74.     }
  75.     fclose(file2);
  76.     return cmd;
  77. }
  78.  
  79. int main(void)
  80. {
  81.         char * cmd, line[MAXLEN], * args[MAXNUM];
  82.         int background;
  83.     int i = 0;
  84.         int pid;
  85.         char buff[PATH_MAX + 1];
  86.         char* cwd;
  87.         char buf[512];
  88.         char* histline;
  89.         int cmd_in = 0;
  90.         FILE *f;
  91.        
  92.         signal(SIGALRM, sighandler);
  93.         signal(SIGINT, sighandler);
  94.  
  95.         char currentdir[1234];
  96.  
  97.         if ((getcwd(currentdir, sizeof(currentdir)) != NULL))
  98.                 strcat(currentdir, "/history.txt");
  99.  
  100.         while (1) {
  101.                 int argc = i;
  102.                 int k = 0;
  103.                 int output_mode = 0;
  104.                 int input_mode = 0;
  105.                 char input[MAXNUM];
  106.                 char output[MAXNUM];
  107.                 char pipeput[MAXNUM];
  108.                 background = 0;
  109.                
  110.                 cwd = getcwd(buff, PATH_MAX + 1);
  111.                
  112.                 /* print the prompt */
  113.                
  114.                 if (cwd != NULL) {
  115.                         printf("%s ", cwd);
  116.                 };
  117.                 /* set the timeout for alarm signal (autologout) */
  118.                 alarm(LOGOUT);
  119.                
  120.                 /* read the users command */
  121.                 if (fgets(line,MAXLEN,stdin) == NULL) {
  122.                         printf("\nlogout\n");
  123.                         exit(0);
  124.                 }
  125.  
  126.                 line[strlen(line) - 1] = '\0';
  127.                
  128.                 if (strlen(line) == 0)
  129.                         continue;
  130.                
  131.                 /* start to background? */
  132.                 if (line[strlen(line)-1] == '&') {
  133.                         line[strlen(line)-1] = 0;
  134.                         background = 1;
  135.                 }
  136.  
  137.                 /* write history log */
  138.                
  139.                 if (strlen(line) != 0) {
  140.                         FILE* file3 = fopen(currentdir, "a");
  141.                         fprintf(file3, "%s\n", line);
  142.                         fclose(file3);
  143.                 }
  144.  
  145.                 /*check if there is pipe and splits the command line */
  146.                 i = 0;
  147.                 cmd = line;
  148.  
  149.                 if((strchr(line, '|'))!=NULL){
  150.                         while ( (args[i] = strtok(cmd, "|")) != NULL) {
  151.                                 i++;
  152.                                 cmd = NULL;
  153.                                 //break;      
  154.                         }
  155.                         args[0][strlen(args[0]) - 1] = '\0';
  156.                         args[1] = args[1] + 1;
  157.                         printf("arg 0: %s\n", args[0]);
  158.                         printf("arg 1: %s\n", args[1]);
  159.                         FILE *pipein, *pipeout;
  160.                         char readbuf[80];
  161.                         /* PIPE with popen */                      
  162.                         pipein = popen(args[0], "r");
  163.                         pipeout = popen(args[1], "w");
  164.                        
  165.                         while(fgets(readbuf, 80, pipein)){
  166.                                 fputs(readbuf, pipeout);
  167.             }
  168.                         pclose(pipein);
  169.                         pclose(pipeout);
  170.                         continue;
  171.                 }
  172.                 else{
  173.                         while ( (args[i] = strtok(cmd, " ")) != NULL) {
  174.                                 printf("arg %d: %s\n", i, args[i]);
  175.                                 i++;
  176.                                 cmd = NULL;              
  177.                         }      
  178.                 }              
  179.  
  180.                 int cmd_in = 0;
  181.                 /*executes the specified command from history again*/
  182.                 if (strlen(args[0]) >= 2 && args[0][0] == '!' && atoi(args[0]+1)) {
  183.                         int i = atoi(args[0]+1);
  184.                         histline = historynum(i, currentdir);
  185.                         histline[strlen(histline) - 1] = '\0';
  186.                         if((strchr(histline, '|'))!=NULL) {                        
  187.                                 while ( (args[i] = strtok(cmd, "|")) != NULL) {
  188.                                         i++;
  189.                                         cmd = NULL;
  190.                                 }
  191.                                 args[0][strlen(args[0]) - 1] = '\0';
  192.                                 args[1] = args[1] + 1;
  193.                         }
  194.                         else {
  195.              
  196.                                 while ( (args[cmd_in] = strtok(histline, " ")) != NULL) {
  197.                                         printf("arg %d: %s\n", cmd_in, args[cmd_in]);
  198.                                         cmd_in++;
  199.                                         histline = NULL;
  200.                                 }
  201.                         }
  202.              
  203.                 }
  204.  
  205.         /*checks if there is redirect and also if there is wildcard*/
  206.                 int bonari = 0;
  207.                 while(args[k] != NULL){
  208.                         if(strcmp(args[k], "<") == 0){
  209.                                 input_mode = 1;
  210.                                 args[k] = NULL;
  211.                                 strcpy(input, args[k+1]);
  212.  
  213.                         }else if(strcmp(args[k], ">") == 0){
  214.                                 output_mode = 1;
  215.                                 args[k] = NULL;
  216.                                 strcpy(output, args[k+1]);
  217.                         }else if (strstr(args[k], "*") != NULL) {                            
  218.                                 bonari = 1;
  219.                         }
  220.                         k++;
  221.                 }
  222.                
  223.                 if (strcmp(args[0],"exit")==0) {
  224.                         exit(0);
  225.                 }
  226.                
  227.  
  228.                 if (strcmp(args[0], "cd")==0) {
  229.                         if (args[1] == NULL) {
  230.                                 const char* home = getenv("HOME");
  231.                                 chdir(home);
  232.                         }
  233.                         char *token = args[1];
  234.                         chdir(token);
  235.                         continue;
  236.                 }
  237.  
  238.                 /* print history log */
  239.                 if (strcmp(args[0],"history")==0) {
  240.                         histRead(currentdir);
  241.                         continue;
  242.                 }
  243.  
  244.         /* wildcard bonus feature*/
  245.                 int jj;
  246.                 glob_t globbuf;
  247.                 if (bonari == 1){
  248.                         for (jj = 0; jj < argc; jj++) {
  249.                                 if (jj == 0)
  250.                                         glob(args[0],GLOB_NOCHECK, NULL, &globbuf);
  251.                                 else
  252.                                         glob(args[jj], GLOB_NOCHECK | GLOB_APPEND, NULL, &globbuf);
  253.                         }
  254.  
  255.                 }
  256.                
  257.                 char reout;
  258.                 char rein;
  259.              
  260.                 switch (pid = fork()) {
  261.            
  262.                         case -1:
  263.                                 /* error */
  264.                                 perror("fork");
  265.                                 continue;
  266.                         case 0:
  267.                                 /* child process */
  268.                 /*Redirect*/
  269.                                 if (output_mode == 1) {
  270.                                         reout = creat(output, 0644);
  271.                                         dup2(reout, STDOUT_FILENO);
  272.                                         close(reout);
  273.  
  274.                                 }
  275.                                 if (input_mode == 1) {
  276.                                         rein = open(input, O_RDONLY, 0);
  277.                                         dup2(rein, STDIN_FILENO);
  278.                                         close(rein);
  279.                                 }
  280.                                 if (bonari == 1){
  281.                                         execvp(&globbuf.gl_pathv[0][0], &globbuf.gl_pathv[0]);
  282.                                         perror("execvp");
  283.                                         exit(1);
  284.                                 }
  285.                                 else{
  286.                                         execvp(args[0], args);
  287.                                         perror("execvp");
  288.                                         exit(1);
  289.                                 }
  290.                         default:
  291.                                 /* parent (shell) */
  292.                                 if (!background) {
  293.                                         alarm(0);
  294.                                         while (wait(NULL)!=pid)
  295.                                                 printf("some other child process exited\n");
  296.                                 }
  297.                                 break;
  298.                 }
  299.                
  300.         }
  301.         return 0;
  302. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement