Advertisement
CSenshi

shell.c (juicehead_monkeys)

Mar 19th, 2019
216
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 44.23 KB | None | 0 0
  1. #include <ctype.h>
  2. #include <errno.h>
  3. #include <stdbool.h>
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <string.h>
  7. #include <sys/types.h>
  8. #include <signal.h>
  9. #include <sys/wait.h>
  10. #include <termios.h>
  11. #include <unistd.h>
  12. #include <dirent.h>
  13. #include <sys/time.h>
  14. #include <sys/resource.h>
  15. #include <sys/stat.h>
  16. #include <fcntl.h>
  17. #include <stdio.h>
  18. #include "tokenizer.h"
  19.  
  20.  
  21. /* Convenience macro to silence compiler warnings about unused function parameters. */
  22. #define unused __attribute__((unused))
  23.  
  24. /* Whether the shell is connected to an actual terminal or not. */
  25. bool shell_is_interactive;
  26.  
  27. /* File descriptor for the shell input */
  28. int shell_terminal;
  29.  
  30. /* Terminal mode settings for the shell */
  31. struct termios shell_tmodes;
  32.  
  33. /* Process group id for the shell */
  34. pid_t shell_pgid;
  35.  
  36. int cmd_exit(struct tokens *tokens);
  37. int cmd_help(struct tokens *tokens);
  38. int cmd_pwd(struct tokens * tokens);
  39. int cmd_cd(struct tokens *tokens);
  40. int cmd_ulimit(struct tokens * tokens);
  41. int cmd_nice(struct tokens * tokens);
  42. int cmd_type(struct tokens * tokens);
  43. int cmd_kill(struct tokens * tokens);
  44. /* Built-in command functions take token array (see parse.h) and return int */
  45. typedef int cmd_fun_t(struct tokens *tokens);
  46.  
  47. /* Built-in command struct and lookup table */
  48. typedef struct fun_desc {
  49.   cmd_fun_t *fun;
  50.   char *cmd;
  51.   char *doc;
  52. } fun_desc_t;
  53.  
  54. fun_desc_t cmd_table[] = {
  55.   {cmd_help, "?", "show this help menu"},
  56.   {cmd_exit, "exit", "exit the command shell"},
  57.   {cmd_pwd,"pwd","prints working directory"},
  58.   {cmd_cd,"cd","change directory"},
  59.   {cmd_ulimit,"ulimit","prints or changes current limit"},
  60.   {cmd_nice,"nice","prints or changes niceness"},
  61.   {cmd_type,"type","prints whether command is buili-in function or other program"},
  62.   {cmd_kill, "kill", "send a signal to a process"}
  63. };
  64. /* Looks up the built-in command, if it exists. */
  65. int lookup(char cmd[]) {
  66.   for (unsigned int i = 0; i < sizeof(cmd_table) / sizeof(fun_desc_t); i++)
  67.     if (cmd && (strcmp(cmd_table[i].cmd, cmd) == 0))
  68.       return i;
  69.   return -1;
  70. }
  71.  
  72. int getlimit(unused struct tokens * tokens) {
  73.     int status = -1;
  74.     struct rlimit  * t = malloc(sizeof(struct rlimit));
  75.     if(tokens_get_length(tokens)  == 1) {
  76.         status = getrlimit(RLIMIT_FSIZE,t);
  77.         if(t->rlim_cur == RLIM_INFINITY) {
  78.             printf("%s\n","unlimited");
  79.         } else {
  80.             printf("%lu \n",t->rlim_cur);
  81.         }
  82.         return status;
  83.     }
  84.     char * lastpart = tokens_get_token(tokens,(size_t)1);
  85.     if(strcmp(lastpart,"-a")== 0 || strcmp(lastpart,"-Sa")== 0 || strcmp(lastpart,"-Ha")== 0) {
  86.         if(strcmp(lastpart,"-Ha")== 0) {
  87.             status = getrlimit(RLIMIT_CORE,t);
  88.             if(t->rlim_max == RLIM_INFINITY) {
  89.                 printf("core file size      (blocks, -c) %s\n","unlimited");
  90.             } else{
  91.                 printf("core file size      (blocks, -c) %lu\n",t->rlim_max);
  92.             }
  93.             status = getrlimit(RLIMIT_DATA,t);
  94.             if(t->rlim_max == RLIM_INFINITY) {
  95.                 printf("data seg size       (kbytes, -d) %s\n","unlimited");
  96.             } else{
  97.                 printf("data seg size       (kbytes, -d) %lu\n",t->rlim_max/1024);
  98.             }
  99.             status = getrlimit(RLIMIT_FSIZE,t);
  100.             if(t->rlim_max == RLIM_INFINITY) {
  101.                 printf("file size       (blocks, -f) %s\n","unlimited");
  102.             } else{
  103.                 printf("file size       (blocks, -f) %lu\n",t->rlim_max);
  104.             }
  105.             status = getrlimit(RLIMIT_SIGPENDING,t);
  106.             if(t->rlim_max == RLIM_INFINITY) {
  107.                 printf("pending signals         (-i) %s\n","unlimited");
  108.             } else{
  109.                 printf("pending signals         (-i) %lu\n",t->rlim_max);
  110.             }
  111.             status = getrlimit(RLIMIT_MEMLOCK,t);
  112.             if(t->rlim_max == RLIM_INFINITY) {
  113.                 printf("max locked memory   (kbytes, -l) %s\n","unlimited");
  114.             } else{
  115.                 printf("max locked memory   (kbytes, -l) %lu\n",t->rlim_max/1024);
  116.             }
  117.             status = getrlimit(RLIMIT_NOFILE,t);
  118.             if(t->rlim_max == RLIM_INFINITY) {
  119.                 printf("open files          (-n) %s\n","unlimited");
  120.             } else{
  121.                 printf("open files          (-n) %lu\n",t->rlim_max);
  122.             }
  123.             status = getrlimit(RLIMIT_MSGQUEUE,t);
  124.             if(t->rlim_max == RLIM_INFINITY) {
  125.                 printf("POSIX message queues     (bytes, -q) %s\n","unlimited");
  126.             } else{
  127.                 printf("POSIX message queues     (bytes, -q) %lu\n",t->rlim_max);
  128.             }
  129.             status = getrlimit(RLIMIT_RTPRIO,t);
  130.             if(t->rlim_max == RLIM_INFINITY) {
  131.                 printf("real-time priority      (-r) %s\n","unlimited");
  132.             } else{
  133.                 printf("real-time priority      (-r) %lu\n",t->rlim_max);
  134.             }
  135.             status = getrlimit(RLIMIT_STACK,t);
  136.             if(t->rlim_max == RLIM_INFINITY) {
  137.                 printf("stack size       (kbytes,-s) %s\n","unlimited");
  138.             } else{
  139.                 printf("stack size       (kbytes,-s) %lu\n",t->rlim_max/1024);
  140.             }
  141.             status = getrlimit(RLIMIT_CPU,t);
  142.             if(t->rlim_max == RLIM_INFINITY) {
  143.                 printf("spu time        (seconds,-t) %s\n","unlimited");
  144.             } else{
  145.                 printf("cpu time        (seconds,-t) %lu\n",t->rlim_max);
  146.             }
  147.             status = getrlimit(RLIMIT_NPROC,t);
  148.             if(t->rlim_max == RLIM_INFINITY) {
  149.                 printf("max user processes      (-u) %s\n","unlimited");
  150.             } else{
  151.                 printf("max user processes      (-u) %lu\n",t->rlim_max);
  152.             }
  153.             status = getrlimit(RLIMIT_AS,t);
  154.             if(t->rlim_max == RLIM_INFINITY) {
  155.                 printf("virtual memory       (kbytes,-v) %s\n","unlimited");
  156.             } else{
  157.                 printf("virtual memory       (kbytes,-v) %lu\n",t->rlim_max/1024);
  158.             }
  159.             status = getrlimit(RLIMIT_LOCKS,t);
  160.             if(t->rlim_max == RLIM_INFINITY) {
  161.                 printf("file locks          (-x) %s\n","unlimited");
  162.             } else{
  163.                 printf("file locks          (-x) %lu\n",t->rlim_max);
  164.             }
  165.             return status;
  166.  
  167.         }
  168.             status = getrlimit(RLIMIT_CORE,t);
  169.             if(t->rlim_cur == RLIM_INFINITY) {
  170.                 printf("core file size      (blocks, -c) %s\n","unlimited");
  171.             } else{
  172.                 printf("core file size      (blocks, -c) %lu\n",t->rlim_cur);
  173.             }
  174.             status = getrlimit(RLIMIT_DATA,t);
  175.             if(t->rlim_cur == RLIM_INFINITY) {
  176.                 printf("data seg size       (kbytes, -d) %s\n","unlimited");
  177.             } else{
  178.                 printf("data seg size       (kbytes, -d) %lu\n",t->rlim_cur/1024);
  179.             }
  180.             status = getrlimit(RLIMIT_FSIZE,t);
  181.             if(t->rlim_cur == RLIM_INFINITY) {
  182.                 printf("file size       (blocks, -f) %s\n","unlimited");
  183.             } else{
  184.                 printf("file size       (blocks, -f) %lu\n",t->rlim_cur);
  185.             }
  186.             status = getrlimit(RLIMIT_SIGPENDING,t);
  187.             if(t->rlim_cur == RLIM_INFINITY) {
  188.                 printf("pending signals         (-i) %s\n","unlimited");
  189.             } else{
  190.                 printf("pending signals         (-i) %lu\n",t->rlim_cur);
  191.             }
  192.             status = getrlimit(RLIMIT_MEMLOCK,t);
  193.             if(t->rlim_cur == RLIM_INFINITY) {
  194.                 printf("max locked memory   (kbytes, -l) %s\n","unlimited");
  195.             } else{
  196.                 printf("max locked memory   (kbytes, -l) %lu\n",t->rlim_cur/1024);
  197.             }
  198.             status = getrlimit(RLIMIT_NOFILE,t);
  199.             if(t->rlim_cur == RLIM_INFINITY) {
  200.                 printf("open files          (-n) %s\n","unlimited");
  201.             } else{
  202.                 printf("open files          (-n) %lu\n",t->rlim_cur);
  203.             }
  204.             status = getrlimit(RLIMIT_MSGQUEUE,t);
  205.             if(t->rlim_cur == RLIM_INFINITY) {
  206.                 printf("POSIX message queues     (bytes, -q) %s\n","unlimited");
  207.             } else{
  208.                 printf("POSIX message queues     (bytes, -q) %lu\n",t->rlim_cur);
  209.             }
  210.             status = getrlimit(RLIMIT_RTPRIO,t);
  211.             if(t->rlim_cur == RLIM_INFINITY) {
  212.                 printf("real-time priority      (-r) %s\n","unlimited");
  213.             } else{
  214.                 printf("real-time priority      (-r) %lu\n",t->rlim_cur);
  215.             }
  216.             status = getrlimit(RLIMIT_STACK,t);
  217.             if(t->rlim_cur == RLIM_INFINITY) {
  218.                 printf("stack size       (kbytes,-s) %s\n","unlimited");
  219.             } else{
  220.                 printf("stack size       (kbytes,-s) %lu\n",t->rlim_cur/1024);
  221.             }
  222.             status = getrlimit(RLIMIT_CPU,t);
  223.             if(t->rlim_cur == RLIM_INFINITY) {
  224.                 printf("spu time        (seconds,-t) %s\n","unlimited");
  225.             } else{
  226.                 printf("cpu time        (seconds,-t) %lu\n",t->rlim_cur);
  227.             }
  228.             status = getrlimit(RLIMIT_NPROC,t);
  229.             if(t->rlim_cur == RLIM_INFINITY) {
  230.                 printf("max user processes      (-u) %s\n","unlimited");
  231.             } else{
  232.                 printf("max user processes      (-u) %lu\n",t->rlim_cur);
  233.             }
  234.             status = getrlimit(RLIMIT_AS,t);
  235.             if(t->rlim_cur == RLIM_INFINITY) {
  236.                 printf("virtual memory       (kbytes,-v) %s\n","unlimited");
  237.             } else{
  238.                 printf("virtual memory       (kbytes,-v) %lu\n",t->rlim_cur/1024);
  239.             }
  240.             status = getrlimit(RLIMIT_LOCKS,t);
  241.             if(t->rlim_cur == RLIM_INFINITY) {
  242.                 printf("file locks          (-x) %s\n","unlimited");
  243.             } else{
  244.                 printf("file locks          (-x) %lu\n",t->rlim_cur);
  245.             }
  246.             return status;
  247.            
  248.     }
  249.     if(strcmp(lastpart,"-f")== 0 || strcmp(lastpart,"-Sf")== 0 || strcmp(lastpart,"-Hf")== 0){
  250.         status = getrlimit(RLIMIT_FSIZE,t);
  251.         if(strcmp(lastpart,"-Hf")== 0) {
  252.             if(t->rlim_max == RLIM_INFINITY) {
  253.                 printf("%s\n","unlimited");
  254.             } else {
  255.                 printf("%lu\n",t->rlim_max);
  256.             }
  257.             return status;
  258.         }
  259.         if(t->rlim_cur == RLIM_INFINITY) {
  260.             printf("%s\n","unlimited");
  261.         } else {
  262.             printf("%lu\n",t->rlim_cur);
  263.         }
  264.         return status;
  265.     } else if(strcmp(lastpart,"-c")== 0 || strcmp(lastpart,"-Sc")== 0 || strcmp(lastpart,"-Hc")== 0) {
  266.         status = getrlimit(RLIMIT_CORE,t);
  267.         if(strcmp(lastpart,"-Hc")== 0) {
  268.             if(t->rlim_max == RLIM_INFINITY) {
  269.                 printf("%s\n","unlimited");
  270.             } else {
  271.                 printf("%lu\n",t->rlim_max);
  272.             }
  273.             return status;
  274.         }
  275.         if(t->rlim_cur == RLIM_INFINITY) {
  276.             printf("%s\n","unlimited");
  277.         } else {
  278.             printf("%lu\n",t->rlim_cur);
  279.         }
  280.         return status;
  281.     } else if(strcmp(lastpart,"-t")== 0 || strcmp(lastpart,"-St")== 0 || strcmp(lastpart,"-Ht")== 0) {
  282.         status = getrlimit(RLIMIT_CPU,t);
  283.         if(strcmp(lastpart,"-Ht")== 0) {
  284.             if(t->rlim_max == RLIM_INFINITY) {
  285.                 printf("%s\n","unlimited");
  286.             } else {
  287.                 printf("%lu\n",t->rlim_max);
  288.             }
  289.             return status;
  290.         }
  291.         if(t->rlim_cur == RLIM_INFINITY) {
  292.             printf("%s\n","unlimited");
  293.         } else {
  294.             printf("%lu\n",t->rlim_cur);
  295.         }
  296.         return status;
  297.     } else if(strcmp(lastpart,"-v")== 0 || strcmp(lastpart,"-Sv")== 0 || strcmp(lastpart,"-Hv")== 0) {
  298.         status = getrlimit(RLIMIT_AS,t);
  299.         if(strcmp(lastpart,"-Hv")== 0) {
  300.             if(t->rlim_max == RLIM_INFINITY) {
  301.                 printf("%s\n","unlimited");
  302.             } else {
  303.                 printf("%lu\n",t->rlim_max/1024);
  304.             }
  305.             return status;
  306.         }
  307.         if(t->rlim_cur == RLIM_INFINITY) {
  308.             printf("%s\n","unlimited");
  309.         } else {
  310.             printf("%lu\n",t->rlim_cur/1024);
  311.         }
  312.         return status;
  313.     } else if(strcmp(lastpart,"-d")== 0 || strcmp(lastpart,"-Sd")== 0 || strcmp(lastpart,"-Hd")== 0) {
  314.         status = getrlimit(RLIMIT_DATA,t);
  315.         if(strcmp(lastpart,"-Hd")== 0) {
  316.             if(t->rlim_max == RLIM_INFINITY) {
  317.                 printf("%s\n","unlimited");
  318.             } else {
  319.                 printf("%lu\n",t->rlim_max/1024);
  320.             }
  321.             return status;
  322.         }
  323.         if(t->rlim_cur == RLIM_INFINITY) {
  324.             printf("%s\n","unlimited");
  325.         } else {
  326.             printf("%lu\n",t->rlim_cur/1024);
  327.         }
  328.         return status;
  329.     } else if(strcmp(lastpart,"-x")== 0 || strcmp(lastpart,"-Sx")== 0 || strcmp(lastpart,"-Hx")== 0) {
  330.         status = getrlimit(RLIMIT_LOCKS,t);
  331.         if(strcmp(lastpart,"-Hx")== 0) {
  332.             if(t->rlim_max == RLIM_INFINITY) {
  333.                 printf("%s\n","unlimited");
  334.             } else {
  335.                 printf("%lu\n",t->rlim_max);
  336.             }
  337.             return status;
  338.         }
  339.         if(t->rlim_cur == RLIM_INFINITY) {
  340.             printf("%s\n","unlimited");
  341.         } else {
  342.             printf("%lu\n",t->rlim_cur);
  343.         }
  344.         return status;
  345.     } else if(strcmp(lastpart,"-l")== 0 || strcmp(lastpart,"-Sl")== 0 || strcmp(lastpart,"-Hl")== 0) {
  346.         status = getrlimit(RLIMIT_MEMLOCK,t);
  347.         if(strcmp(lastpart,"-Hl")== 0) {
  348.             if(t->rlim_max == RLIM_INFINITY) {
  349.                 printf("%s\n","unlimited");
  350.             } else {
  351.                 printf("%lu\n",t->rlim_max/1024);
  352.             }
  353.             return status;
  354.         }
  355.         if(t->rlim_cur == RLIM_INFINITY) {
  356.             printf("%s\n","unlimited");
  357.         } else {
  358.             printf("%lu\n",t->rlim_cur/1024);
  359.         }
  360.         return status;
  361.     }
  362.     else if(strcmp(lastpart,"-q")== 0 || strcmp(lastpart,"-Sq")== 0 || strcmp(lastpart,"-Hq")== 0) {
  363.         status = getrlimit(RLIMIT_MSGQUEUE,t);
  364.         if(strcmp(lastpart,"-Hq")== 0) {
  365.             if(t->rlim_max == RLIM_INFINITY) {
  366.                 printf("%s\n","unlimited");
  367.             } else {
  368.                 printf("%lu\n",t->rlim_max);
  369.             }
  370.             return status;
  371.         }
  372.         if(t->rlim_cur == RLIM_INFINITY) {
  373.             printf("%s\n","unlimited");
  374.         } else {
  375.             printf("%lu\n",t->rlim_cur);
  376.         }
  377.         return status;
  378.     } else if(strcmp(lastpart,"-n")== 0 || strcmp(lastpart,"-Sn")== 0 || strcmp(lastpart,"-Hn")== 0) {
  379.         status = getrlimit(RLIMIT_NOFILE,t);
  380.         if(strcmp(lastpart,"-Hn")== 0) {
  381.             if(t->rlim_max == RLIM_INFINITY) {
  382.                 printf("%s\n","unlimited");
  383.             } else {
  384.                 printf("%lu\n",t->rlim_max);
  385.             }
  386.             return status;
  387.         }
  388.         if(t->rlim_cur == RLIM_INFINITY) {
  389.             printf("%s\n","unlimited");
  390.         } else {
  391.             printf("%lu\n",t->rlim_cur);
  392.         }
  393.         return status;
  394.     }else if(strcmp(lastpart,"-r")== 0 || strcmp(lastpart,"-Sr")== 0 || strcmp(lastpart,"-Hr")== 0) {
  395.         status = getrlimit(RLIMIT_RTPRIO,t);
  396.         if(strcmp(lastpart,"-Hr")== 0) {
  397.             if(t->rlim_max == RLIM_INFINITY) {
  398.                 printf("%s\n","unlimited");
  399.             } else {
  400.                 printf("%lu\n",t->rlim_max);
  401.             }
  402.             return status;
  403.         }
  404.         if(t->rlim_cur == RLIM_INFINITY) {
  405.             printf("%s\n","unlimited");
  406.         } else {
  407.             printf("%lu\n",t->rlim_cur);
  408.         }
  409.         return status;
  410.     }   else if(strcmp(lastpart,"-i")== 0 || strcmp(lastpart,"-Si")== 0 || strcmp(lastpart,"-Hi")== 0) {
  411.         status = getrlimit(RLIMIT_SIGPENDING,t);
  412.         if(strcmp(lastpart,"-Hi")== 0) {
  413.             if(t->rlim_max == RLIM_INFINITY) {
  414.                 printf("%s\n","unlimited");
  415.             } else {
  416.                 printf("%lu\n",t->rlim_max);
  417.             }
  418.             return status;
  419.         }
  420.         if(t->rlim_cur == RLIM_INFINITY) {
  421.             printf("%s\n","unlimited");
  422.         } else {
  423.             printf("%lu\n",t->rlim_cur);
  424.         }
  425.         return status;
  426.     }   else if(strcmp(lastpart,"-s")== 0 || strcmp(lastpart,"-Ss")== 0 || strcmp(lastpart,"-Hs")== 0) {
  427.             status = getrlimit(RLIMIT_STACK,t);
  428.             if(strcmp(lastpart,"-Hs")== 0) {
  429.                 if(t->rlim_max == RLIM_INFINITY) {
  430.                     printf("%s\n","unlimited");
  431.                 } else {
  432.                     printf("%lu\n",t->rlim_max/1024);
  433.                 }
  434.             return status;
  435.         }
  436.         if(t->rlim_cur == RLIM_INFINITY) {
  437.             printf("%s\n","unlimited");
  438.         } else {
  439.             printf("%lu\n",t->rlim_cur/1024);
  440.         }
  441.         return status;
  442.     }   else if(strcmp(lastpart,"-u")== 0 || strcmp(lastpart,"-Su")== 0 || strcmp(lastpart,"-Hu")== 0) {
  443.         status = getrlimit(RLIMIT_NPROC,t);
  444.         if(strcmp(lastpart,"-Hu")== 0) {
  445.             if(t->rlim_max == RLIM_INFINITY) {
  446.                 printf("%s\n","unlimited");
  447.             } else {
  448.                 printf("%lu\n",t->rlim_max);
  449.             }
  450.             return status;
  451.         }
  452.         if(t->rlim_cur == RLIM_INFINITY) {
  453.             printf("%s\n","unlimited");
  454.         } else {
  455.             printf("%lu\n",t->rlim_cur);
  456.         }
  457.         return status;
  458.     }
  459.     return status;
  460. }
  461. int setlimit(unused struct tokens * tokens) {
  462.     int status = -1;
  463.     int setstatus = -1;
  464.     struct rlimit  * t = malloc(sizeof(struct rlimit));
  465.     struct rlimit *newlimit = malloc(sizeof(struct rlimit));
  466.     char * lastpart = tokens_get_token(tokens,(size_t)1);
  467.     if(strcmp(lastpart,"-f")== 0 || strcmp(lastpart,"-Sf")== 0 || strcmp(lastpart,"-Hf")== 0){
  468.         status = getrlimit(RLIMIT_FSIZE,t);
  469.         if(strcmp(lastpart,"-Hf")== 0) {
  470.             newlimit->rlim_cur = t->rlim_cur;
  471.             if(strcmp(tokens_get_token(tokens,(size_t)2),"unlimited") == 0) {
  472.                 newlimit->rlim_max = RLIM_INFINITY;
  473.             } else {
  474.                 newlimit->rlim_max = atoi(tokens_get_token(tokens,(size_t)2));
  475.             }
  476.             setstatus = setrlimit(RLIMIT_FSIZE,newlimit);
  477.             return setstatus;
  478.         }
  479.             newlimit->rlim_max = t->rlim_max;
  480.             if(strcmp(tokens_get_token(tokens,(size_t)2),"unlimited") == 0) {
  481.                 newlimit->rlim_cur = RLIM_INFINITY;
  482.             } else {
  483.                 newlimit->rlim_cur = atoi(tokens_get_token(tokens,(size_t)2));
  484.             }
  485.             setstatus = setrlimit(RLIMIT_FSIZE,newlimit);
  486.             return setstatus;
  487.        
  488.     } else if(strcmp(lastpart,"-c")== 0 || strcmp(lastpart,"-Sc")== 0 || strcmp(lastpart,"-Hc")== 0) {
  489.         status = getrlimit(RLIMIT_CORE,t);
  490.         if(strcmp(lastpart,"-Hc")== 0) {
  491.             newlimit->rlim_cur = t->rlim_cur;
  492.             if(strcmp(tokens_get_token(tokens,(size_t)2),"unlimited") == 0) {
  493.                 newlimit->rlim_max = RLIM_INFINITY;
  494.             } else {
  495.                 newlimit->rlim_max = atoi(tokens_get_token(tokens,(size_t)2));
  496.             }
  497.             setstatus = setrlimit(RLIMIT_CORE,newlimit);
  498.             return setstatus;
  499.         }
  500.             newlimit->rlim_max = t->rlim_max;
  501.             if(strcmp(tokens_get_token(tokens,(size_t)2),"unlimited") == 0) {
  502.                 newlimit->rlim_cur = RLIM_INFINITY;
  503.             } else {
  504.                 newlimit->rlim_cur = atoi(tokens_get_token(tokens,(size_t)2));
  505.             }
  506.             setstatus = setrlimit(RLIMIT_CORE,newlimit);
  507.             return setstatus;
  508.     } else if(strcmp(lastpart,"-t")== 0 || strcmp(lastpart,"-St")== 0 || strcmp(lastpart,"-Ht")== 0) {
  509.         status = getrlimit(RLIMIT_CPU,t);
  510.         if(strcmp(lastpart,"-Ht")== 0) {
  511.             newlimit->rlim_cur = t->rlim_cur;
  512.             if(strcmp(tokens_get_token(tokens,(size_t)2),"unlimited") == 0) {
  513.                 newlimit->rlim_max = RLIM_INFINITY;
  514.             } else {
  515.                 newlimit->rlim_max = atoi(tokens_get_token(tokens,(size_t)2));
  516.             }
  517.             setstatus = setrlimit(RLIMIT_CPU,newlimit);
  518.             return setstatus;
  519.         }
  520.             newlimit->rlim_max = t->rlim_max;
  521.             if(strcmp(tokens_get_token(tokens,(size_t)2),"unlimited") == 0) {
  522.                 newlimit->rlim_cur = RLIM_INFINITY;
  523.             } else {
  524.                 newlimit->rlim_cur = atoi(tokens_get_token(tokens,(size_t)2));
  525.             }
  526.             setstatus = setrlimit(RLIMIT_CPU,newlimit);
  527.             return setstatus;
  528.     } else if(strcmp(lastpart,"-v")== 0 || strcmp(lastpart,"-Sv")== 0 || strcmp(lastpart,"-Hv")== 0) {
  529.         status = getrlimit(RLIMIT_AS,t);
  530.         if(strcmp(lastpart,"-Hv")== 0) {
  531.             newlimit->rlim_cur = t->rlim_cur;
  532.             if(strcmp(tokens_get_token(tokens,(size_t)2),"unlimited") == 0) {
  533.                 newlimit->rlim_max = RLIM_INFINITY;
  534.             } else {
  535.                 newlimit->rlim_max = atoi(tokens_get_token(tokens,(size_t)2))*1024;
  536.             }
  537.             setstatus = setrlimit(RLIMIT_AS,newlimit);
  538.             return setstatus;
  539.         }
  540.             newlimit->rlim_max = t->rlim_max;
  541.             if(strcmp(tokens_get_token(tokens,(size_t)2),"unlimited") == 0) {
  542.                 newlimit->rlim_cur = RLIM_INFINITY;
  543.             } else {
  544.                 newlimit->rlim_cur = atoi(tokens_get_token(tokens,(size_t)2))*1024;
  545.             }
  546.             setstatus = setrlimit(RLIMIT_AS,newlimit);
  547.             return setstatus;
  548.     } else if(strcmp(lastpart,"-d")== 0 || strcmp(lastpart,"-Sd")== 0 || strcmp(lastpart,"-Hd")== 0) {
  549.         status = getrlimit(RLIMIT_DATA,t);
  550.         if(strcmp(lastpart,"-Hd")== 0) {
  551.             newlimit->rlim_cur = t->rlim_cur;
  552.             if(strcmp(tokens_get_token(tokens,(size_t)2),"unlimited") == 0) {
  553.                 newlimit->rlim_max = RLIM_INFINITY;
  554.             } else {
  555.                 newlimit->rlim_max = atoi(tokens_get_token(tokens,(size_t)2))*1024;
  556.             }
  557.             setstatus = setrlimit(RLIMIT_DATA,newlimit);
  558.             return setstatus;
  559.         }
  560.             newlimit->rlim_max = t->rlim_max;
  561.             if(strcmp(tokens_get_token(tokens,(size_t)2),"unlimited") == 0) {
  562.                 newlimit->rlim_cur = RLIM_INFINITY;
  563.             } else {
  564.                 newlimit->rlim_cur = atoi(tokens_get_token(tokens,(size_t)2))*1024;
  565.             }
  566.             setstatus = setrlimit(RLIMIT_DATA,newlimit);
  567.             return setstatus;
  568.     } else if(strcmp(lastpart,"-x")== 0 || strcmp(lastpart,"-Sx")== 0 || strcmp(lastpart,"-Hx")== 0) {
  569.         status = getrlimit(RLIMIT_LOCKS,t);
  570.         if(strcmp(lastpart,"-Hx")== 0) {
  571.             newlimit->rlim_cur = t->rlim_cur;
  572.             if(strcmp(tokens_get_token(tokens,(size_t)2),"unlimited") == 0) {
  573.                 newlimit->rlim_max = RLIM_INFINITY;
  574.             } else {
  575.                 newlimit->rlim_max = atoi(tokens_get_token(tokens,(size_t)2));
  576.             }
  577.             setstatus = setrlimit(RLIMIT_LOCKS,newlimit);
  578.             return setstatus;
  579.         }
  580.             newlimit->rlim_max = t->rlim_max;
  581.             if(strcmp(tokens_get_token(tokens,(size_t)2),"unlimited") == 0) {
  582.                 newlimit->rlim_cur = RLIM_INFINITY;
  583.             } else {
  584.                 newlimit->rlim_cur = atoi(tokens_get_token(tokens,(size_t)2));
  585.             }
  586.             setstatus = setrlimit(RLIMIT_LOCKS,newlimit);
  587.             return setstatus;
  588.     } else if(strcmp(lastpart,"-l")== 0 || strcmp(lastpart,"-Sl")== 0 || strcmp(lastpart,"-Hl")== 0) {
  589.         status = getrlimit(RLIMIT_MEMLOCK,t);
  590.         if(strcmp(lastpart,"-Hl")== 0) {
  591.             newlimit->rlim_cur = t->rlim_cur;
  592.             if(strcmp(tokens_get_token(tokens,(size_t)2),"unlimited") == 0) {
  593.                 newlimit->rlim_max = RLIM_INFINITY;
  594.             } else {
  595.                 newlimit->rlim_max = atoi(tokens_get_token(tokens,(size_t)2))*1024;
  596.             }
  597.             setstatus = setrlimit(RLIMIT_MEMLOCK,newlimit);
  598.             return setstatus;
  599.         }
  600.             newlimit->rlim_max = t->rlim_max;
  601.             if(strcmp(tokens_get_token(tokens,(size_t)2),"unlimited") == 0) {
  602.                 newlimit->rlim_cur = RLIM_INFINITY;
  603.             } else {
  604.                 newlimit->rlim_cur = atoi(tokens_get_token(tokens,(size_t)2))*1024;
  605.             }
  606.             setstatus = setrlimit(RLIMIT_MEMLOCK,newlimit);
  607.             return setstatus;
  608.  
  609.     }   else if(strcmp(lastpart,"-q")== 0 || strcmp(lastpart,"-Sq")== 0 || strcmp(lastpart,"-Hq")== 0) {
  610.         status = getrlimit(RLIMIT_MSGQUEUE,t);
  611.         if(strcmp(lastpart,"-Hq")== 0) {
  612.             newlimit->rlim_cur = t->rlim_cur;
  613.             if(strcmp(tokens_get_token(tokens,(size_t)2),"unlimited") == 0) {
  614.                 newlimit->rlim_max = RLIM_INFINITY;
  615.             } else {
  616.                 newlimit->rlim_max = atoi(tokens_get_token(tokens,(size_t)2));
  617.             }
  618.             setstatus = setrlimit(RLIMIT_MSGQUEUE,newlimit);
  619.             return setstatus;
  620.         }
  621.             newlimit->rlim_max = t->rlim_max;
  622.             if(strcmp(tokens_get_token(tokens,(size_t)2),"unlimited") == 0) {
  623.                 newlimit->rlim_cur = RLIM_INFINITY;
  624.             } else {
  625.                 newlimit->rlim_cur = atoi(tokens_get_token(tokens,(size_t)2));
  626.             }
  627.             setstatus = setrlimit(RLIMIT_MSGQUEUE,newlimit);
  628.             return setstatus;
  629.     } else if(strcmp(lastpart,"-n")== 0 || strcmp(lastpart,"-Sn")== 0 || strcmp(lastpart,"-Hn")== 0) {
  630.         status = getrlimit(RLIMIT_NOFILE,t);
  631.         if(strcmp(lastpart,"-Hn")== 0) {
  632.             newlimit->rlim_cur = t->rlim_cur;
  633.             if(strcmp(tokens_get_token(tokens,(size_t)2),"unlimited") == 0) {
  634.                 newlimit->rlim_max = RLIM_INFINITY;
  635.             } else {
  636.                 newlimit->rlim_max = atoi(tokens_get_token(tokens,(size_t)2));
  637.                 printf("es unda gaxdes limiti %lu\n",newlimit->rlim_max);
  638.             }
  639.             setstatus = setrlimit(RLIMIT_NOFILE,newlimit);
  640.             printf("%d/n",setstatus);
  641.             return setstatus;
  642.         }
  643.             newlimit->rlim_max = t->rlim_max;
  644.             if(strcmp(tokens_get_token(tokens,(size_t)2),"unlimited") == 0) {
  645.                 newlimit->rlim_cur = RLIM_INFINITY;
  646.             } else {
  647.                 newlimit->rlim_cur = atoi(tokens_get_token(tokens,(size_t)2));
  648.             }
  649.             setstatus = setrlimit(RLIMIT_NOFILE,newlimit);
  650.             return setstatus;
  651.     }else if(strcmp(lastpart,"-r")== 0 || strcmp(lastpart,"-Sr")== 0 || strcmp(lastpart,"-Hr")== 0) {
  652.         status = getrlimit(RLIMIT_RTPRIO,t);
  653.         if(strcmp(lastpart,"-Hr")== 0) {
  654.             newlimit->rlim_cur = t->rlim_cur;
  655.             if(strcmp(tokens_get_token(tokens,(size_t)2),"unlimited") == 0) {
  656.                 newlimit->rlim_max = RLIM_INFINITY;
  657.             } else {
  658.                 newlimit->rlim_max = atoi(tokens_get_token(tokens,(size_t)2));
  659.             }
  660.             setstatus = setrlimit(RLIMIT_RTPRIO,newlimit);
  661.             return setstatus;
  662.         }
  663.             newlimit->rlim_max = t->rlim_max;
  664.             if(strcmp(tokens_get_token(tokens,(size_t)2),"unlimited") == 0) {
  665.                 newlimit->rlim_cur = RLIM_INFINITY;
  666.             } else {
  667.                 newlimit->rlim_cur = atoi(tokens_get_token(tokens,(size_t)2));
  668.             }
  669.             setstatus = setrlimit(RLIMIT_RTPRIO,newlimit);
  670.             return setstatus;
  671.     }   else if(strcmp(lastpart,"-i")== 0 || strcmp(lastpart,"-Si")== 0 || strcmp(lastpart,"-Hi")== 0) {
  672.         status = getrlimit(RLIMIT_SIGPENDING,t);
  673.         if(strcmp(lastpart,"-Hi")== 0) {
  674.             newlimit->rlim_cur = t->rlim_cur;
  675.             if(strcmp(tokens_get_token(tokens,(size_t)2),"unlimited") == 0) {
  676.                 newlimit->rlim_max = RLIM_INFINITY;
  677.             } else {
  678.                 newlimit->rlim_max = atoi(tokens_get_token(tokens,(size_t)2));
  679.             }
  680.             setstatus = setrlimit(RLIMIT_SIGPENDING,newlimit);
  681.             return setstatus;
  682.         }
  683.             newlimit->rlim_max = t->rlim_max;
  684.             if(strcmp(tokens_get_token(tokens,(size_t)2),"unlimited") == 0) {
  685.                 newlimit->rlim_cur = RLIM_INFINITY;
  686.             } else {
  687.                 newlimit->rlim_cur = atoi(tokens_get_token(tokens,(size_t)2));
  688.             }
  689.             setstatus = setrlimit(RLIMIT_SIGPENDING,newlimit);
  690.             return setstatus;
  691.     }   else if(strcmp(lastpart,"-s")== 0 || strcmp(lastpart,"-Ss")== 0 || strcmp(lastpart,"-Hs")== 0) {
  692.         status = getrlimit(RLIMIT_STACK,t);
  693.         if(strcmp(lastpart,"-Hs")== 0) {
  694.             newlimit->rlim_cur = t->rlim_cur;
  695.             if(strcmp(tokens_get_token(tokens,(size_t)2),"unlimited") == 0) {
  696.                 newlimit->rlim_max = RLIM_INFINITY;
  697.             } else {
  698.                 newlimit->rlim_max = atoi(tokens_get_token(tokens,(size_t)2))*1024;
  699.             }
  700.             setstatus = setrlimit(RLIMIT_STACK,newlimit);
  701.             return setstatus;
  702.         }
  703.             newlimit->rlim_max = t->rlim_max;
  704.             if(strcmp(tokens_get_token(tokens,(size_t)2),"unlimited") == 0) {
  705.                 newlimit->rlim_cur = RLIM_INFINITY;
  706.             } else {
  707.                 newlimit->rlim_cur = atoi(tokens_get_token(tokens,(size_t)2))*1024;
  708.             }
  709.             setstatus = setrlimit(RLIMIT_STACK,newlimit);
  710.             return setstatus;
  711.     }   else if(strcmp(lastpart,"-u")== 0 || strcmp(lastpart,"-Su")== 0 || strcmp(lastpart,"-Hu")== 0) {
  712.         status = getrlimit(RLIMIT_NPROC,t);
  713.         if(strcmp(lastpart,"-Hu")== 0) {
  714.             newlimit->rlim_cur = t->rlim_cur;
  715.             if(strcmp(tokens_get_token(tokens,(size_t)2),"unlimited") == 0) {
  716.                 newlimit->rlim_max = RLIM_INFINITY;
  717.             } else {
  718.                 newlimit->rlim_max = atoi(tokens_get_token(tokens,(size_t)2));
  719.             }
  720.             setstatus = setrlimit(RLIMIT_NPROC,newlimit);
  721.             return setstatus;
  722.         }
  723.             newlimit->rlim_max = t->rlim_max;
  724.             if(strcmp(tokens_get_token(tokens,(size_t)2),"unlimited") == 0) {
  725.                 newlimit->rlim_cur = RLIM_INFINITY;
  726.             } else {
  727.                 newlimit->rlim_cur = atoi(tokens_get_token(tokens,(size_t)2));
  728.             }
  729.             setstatus = setrlimit(RLIMIT_NPROC,newlimit);
  730.             return setstatus;
  731.     }
  732.     return (setstatus +status);
  733. }
  734. int cmd_ulimit(unused struct tokens * tokens) {
  735.     int status = -1;
  736.     if(tokens_get_length(tokens)  == 2  || tokens_get_length(tokens)  == 1) {
  737.          status = getlimit(tokens);
  738.          return status;
  739.     }
  740.     if(tokens_get_length(tokens)  == 3) {
  741.         status = setlimit(tokens);
  742.         return status;
  743.     }
  744.     return status;
  745. }
  746. int cmd_nice(unused struct tokens * tokens) {
  747.     if(tokens_get_length(tokens) == 1) {
  748.         errno = 0;
  749.         int prio = getpriority(PRIO_PROCESS,0);
  750.         if(prio == -1 && errno != 0) {
  751.              printf("folowwing error happned : %s\n",strerror(errno));
  752.              return -1;
  753.         }
  754.         printf("%d\n",prio);
  755.         return 0;
  756.     } else if(tokens_get_length(tokens) == 2) {
  757.         int newniceval = atoi(tokens_get_token(tokens,(size_t)1));
  758.         int status = setpriority(PRIO_PROCESS,0,newniceval);
  759.         if(status == -1) {
  760.             printf("folowwing error happned : %s\n",strerror(errno));
  761.             return -1;
  762.         }
  763.     }
  764.     return 0;
  765. }
  766.  
  767.  
  768. int isIOCommand(struct tokens *tokens) {
  769.   char *strings[] = {">", "<", ">>"};
  770.   int size = tokens_get_length(tokens);
  771.   for (int i = 0; i < size; ++i) {
  772.     char *tok = tokens_get_token(tokens, i);
  773.     int arrLen = sizeof(strings)/sizeof(char *);
  774.     for (int j = 0; j < arrLen; j++) {
  775.       if (strcmp(tok, strings[j]) == 0){
  776.         return i;
  777.       }
  778.     }
  779.   }
  780.   return 0;  
  781. }
  782.  
  783. void handleIoCommand(struct tokens *tokens) {
  784.  
  785. }
  786.  
  787.  
  788.  
  789.  
  790. int cmd_cd(unused struct tokens * tokens){
  791.     char *path = tokens_get_token(tokens,(size_t)1);
  792.    
  793.     char buffer [512]; //buffer for current directory
  794.     char * currentDirectory = getcwd(buffer,512);
  795.  
  796.     if(strcmp(path,"..") == 0 && currentDirectory != NULL)
  797.     {
  798.      
  799.         char * last = strrchr(currentDirectory,'/'); //get address of last occurence of '/'
  800.         char previousDirectory [512];
  801.         memset(previousDirectory,0,512);
  802.         strncpy(previousDirectory,buffer,last-currentDirectory); //last-currentDirectory is size of previous Dir
  803.         int status = chdir(previousDirectory);
  804.         if(status == 0){
  805.            return 0;
  806.  
  807.         }else{
  808.              printf("folowwing error happned : %s\n",strerror(errno));
  809.              return -1;
  810.  
  811.         }
  812.     }
  813.  
  814.     int status = chdir(path); //change dir if possible for absolute path
  815.     if(status == 0){
  816.       return 0;
  817.  
  818.  
  819.     }else{
  820.       strcat(buffer,path);
  821.       int statusRelativePath = chdir(buffer); //change dir if possible for relative current dir + relative path
  822.       if(statusRelativePath == 0){
  823.  
  824.  
  825.         return 0;
  826.       }else{
  827.            printf("folowwing error happned : %s\n",strerror(errno));
  828.            return -1;
  829.  
  830.       }
  831.  
  832.  
  833.     }
  834. }
  835.  
  836. /*prints working directory */
  837. int cmd_pwd(unused struct tokens *tokens){
  838.     char * buffer = malloc(512);
  839.     char * result =  getcwd(buffer,512);
  840.    if(result == NULL){
  841.      printf("folowwing error happned : %s\n",strerror(errno));
  842.    
  843.      free(buffer);
  844.      return -1;
  845.  
  846.    } else {
  847.      printf("%s\n",buffer);
  848.      free(buffer);
  849.      return 0;
  850.  
  851.    }
  852. }
  853.  
  854. int isBg(struct tokens *tokens) {
  855.   if (strcmp(tokens_get_token(tokens, tokens_get_length(tokens)-1), "&") == 0) return 1;
  856.   return 0;
  857. }
  858.  
  859.  
  860.  
  861.  
  862. /* executes given program,if absolutePath variable is empty that means we already have absolute paht in tokens[0],
  863. if it's not empty then absolute path will be in absolutePath variable
  864.  
  865.  */
  866. int progrExe(struct tokens *tokens,char * absolutePath) {
  867.  
  868.   int isBgProcess = isBg(tokens);
  869.   int isIO = isIOCommand(tokens);
  870.   int lastFile;
  871.   pid_t pid;
  872.  
  873.   pid = fork();
  874.  
  875.   if (pid < 0) {
  876.     fprintf(stderr, "Fork Failed");
  877.     return 1;
  878.  
  879.   } else if (pid == 0) {
  880.  
  881.     if (setpgid(0, 0) == -1) {
  882.       perror(NULL);
  883.     }
  884.  
  885.     size_t nArgs = tokens_get_length(tokens);
  886.  
  887.     if (isBgProcess) {
  888.       nArgs = nArgs-1; // this means the last token is '&' symbol and is not a program argument
  889.     }
  890.  
  891.     lastFile = nArgs;
  892.     if (isIO) {
  893.       lastFile = nArgs-1;
  894.       nArgs = isIO; // program arguments should be before io sign
  895.     }  
  896.  
  897.     char *arr[nArgs+1];
  898.  
  899.     if(absolutePath == NULL){
  900.       arr[0] = tokens_get_token(tokens,0);
  901.     }else{
  902.  
  903.       arr[0] = absolutePath;
  904.     }
  905.  
  906.  
  907.     // fill arguments for program to be execute
  908.     for (size_t i = 1; i < nArgs; ++i) {
  909.       arr[i] = tokens_get_token(tokens, i);
  910.     }
  911.  
  912.     arr[nArgs] = NULL;
  913.  
  914.     if (isIO) {
  915.       for (int i = isIO; i < lastFile; i += 2){
  916.         char *file = tokens_get_token(tokens, i+1);
  917.    
  918.         int fd;
  919.    
  920.    
  921.         int flags;
  922.         int newfd;
  923.    
  924.        
  925.         char *tok = tokens_get_token(tokens, i);
  926.         // output needs to be redrirected
  927.         if (strcmp(tok, ">") == 0) {
  928.           newfd = 1;
  929.           flags = O_CREAT | O_WRONLY | O_TRUNC;
  930.         // intput needs to be redrirected
  931.         } else if (strcmp(tok, "<") == 0) {
  932.           newfd = 0;
  933.           flags = O_RDONLY;
  934.         // output needs to be redrirected
  935.         } else if (strcmp(tok, ">>") == 0) {
  936.           newfd = 1;
  937.           flags = O_CREAT | O_WRONLY | O_APPEND;
  938.         }
  939.    
  940.        
  941.         fd = open(file, flags, S_IRUSR | S_IWUSR);
  942.         dup2(fd, newfd);
  943.       }
  944.     }
  945.  
  946.     execv(arr[0], arr);
  947.  
  948.     exit(EXIT_FAILURE); //it comes to this line if only execv failed.In this case termiosnate child process with failure
  949.  
  950.    
  951.  
  952.   } else {
  953.       signal(SIGTTOU, SIG_IGN); // ignore
  954.      
  955.     if (setpgid(pid, pid) == -1 && errno != EACCES) {
  956.       perror(NULL);
  957.     }
  958.     if (!isBgProcess) {
  959.       tcsetpgrp(0, pid);
  960.     }
  961.  
  962.     int status = 0;
  963.     waitpid(-1, &status, WSTOPPED);
  964.    
  965.     if (!isBgProcess) {
  966.       tcsetpgrp(0, getpid());
  967.     }
  968.     return WEXITSTATUS(status); //on success returns 0,on error return 1
  969.  
  970.   }
  971.  
  972.   return 0;
  973. }
  974.  
  975.  
  976. // kill builtin
  977. int cmd_kill(struct tokens * tokens) {
  978.  
  979.     int size = tokens_get_length(tokens);
  980.  
  981.     if (size > 2) {
  982.         int sigNUM = -atoi(tokens_get_token(tokens, 1));
  983.         int pid = atoi(tokens_get_token(tokens, 2));
  984.  
  985.         if (sigNUM > 0 && sigNUM < 65) {
  986.             return kill(pid, sigNUM);
  987.         } else {
  988.             printf("invalid signal specification\n");
  989.         }
  990.     }
  991.  
  992.   return -1;
  993. }
  994.  
  995. /* Prints a helpful description for the given command */
  996. int cmd_help(unused struct tokens *tokens) {
  997.   for (unsigned int i = 0; i < sizeof(cmd_table) / sizeof(fun_desc_t); i++)
  998.     printf("%s - %s\n", cmd_table[i].cmd, cmd_table[i].doc);
  999.   return 1;
  1000. }
  1001.  
  1002. /* Exits this shell */
  1003. int cmd_exit(unused struct tokens *tokens) {
  1004.  
  1005.   exit(0);
  1006. }
  1007.  
  1008.  
  1009.  
  1010. /* Intialization procedures for this shell */
  1011. void init_shell() {
  1012.   /* Our shell is connected to standard input. */
  1013.   shell_terminal = STDIN_FILENO;
  1014.  
  1015.   /* Check if we are running interactively */
  1016.   shell_is_interactive = isatty(shell_terminal);
  1017.  
  1018.   if (shell_is_interactive) {
  1019.     /* If the shell is not currently in the foreground, we must pause the shell until it becomes a
  1020.      * foreground process. We use SIGTTIN to pause the shell. When the shell gets moved to the
  1021.      * foreground, we'll receive a SIGCONT. */
  1022.     while (tcgetpgrp(shell_terminal) != (shell_pgid = getpgrp()))
  1023.       kill(-shell_pgid, SIGTTIN);
  1024.  
  1025.     /* Saves the shell's process id */
  1026.     shell_pgid = getpid();
  1027.  
  1028.     /* Take control of the terminal */
  1029.     tcsetpgrp(shell_terminal, shell_pgid);
  1030.  
  1031.     /* Save the current termios to a variable, so it can be restored later. */
  1032.     tcgetattr(shell_terminal, &shell_tmodes);
  1033.   }
  1034. }
  1035.  
  1036. char * searchInPath(char * program){
  1037.   char * pathVariable = getenv("PATH");
  1038.   char * copyPath = malloc(strlen(pathVariable)+1);
  1039.   memset(copyPath,0,strlen(pathVariable)+1);
  1040.   strncpy(copyPath,pathVariable,strlen(pathVariable));
  1041.  
  1042.  
  1043.  
  1044.  
  1045.   for (char *token = strtok(copyPath,":"); token != NULL; token = strtok(NULL, ":"))
  1046.   {
  1047.     DIR *d;
  1048.     struct dirent *dir;
  1049.  
  1050.     d = opendir(token);
  1051.     if (d) {
  1052.      while ((dir = readdir(d)) != NULL) {
  1053.        if(strcmp(dir->d_name,program) == 0){
  1054.          char * copy = malloc(strlen(token) + strlen(program) +2); //keep absolute path to program
  1055.          strcpy(copy,token);
  1056.          strcat(copy,"/");
  1057.          strcat(copy,program);
  1058.          
  1059.  
  1060.          free(copyPath); //free copy of env variable
  1061.          return copy;
  1062.        }
  1063.  
  1064.      }
  1065.     closedir(d);
  1066.   }
  1067.  
  1068.  
  1069.   }
  1070.   free(copyPath); //free copy of env variable
  1071.   return NULL;
  1072. }
  1073. int cmd_type(unused struct tokens * tokens) {
  1074.     if(tokens_get_length(tokens) == 2) {
  1075.         char * cmd = tokens_get_token(tokens,(size_t)1);
  1076.         char * str = malloc(512);
  1077.         strcpy(str,cmd);
  1078.         int res = lookup(cmd);
  1079.         if(res >= 1) {
  1080.             printf("%s is a shell builtin\n",cmd);
  1081.             return 1;
  1082.         }
  1083.         if(searchInPath(str) != NULL) {
  1084.             printf("%s\n",searchInPath(str));
  1085.             return 1;
  1086.         }
  1087.         if(strcmp(cmd,"!") == 0  || strcmp(cmd,"[[") == 0 || strcmp(cmd,"]]") == 0 || strcmp(cmd,"{") == 0 || strcmp(cmd,"}") == 0 || strcmp(cmd,"case") == 0
  1088.             || strcmp(cmd,"do") == 0 || strcmp(cmd,"done") == 0 || strcmp(cmd,"fi") == 0 || strcmp(cmd,"for") == 0 || strcmp(cmd,"function") == 0
  1089.             || strcmp(cmd,"while") == 0 || strcmp(cmd,"until") == 0 || strcmp(cmd,"select") == 0) {
  1090.             printf("%s is a thell keyword \n",cmd);
  1091.             return 1;
  1092.         }
  1093.         printf("-bash: type : %s : not found \n",cmd);
  1094.         return -1;
  1095.     }
  1096.     if(strcmp(tokens_get_token(tokens,(size_t)1),"-a") == 0) {
  1097.         char * cmd = tokens_get_token(tokens,(size_t)2);
  1098.         char * str = malloc(512);
  1099.         strcpy(str,cmd);
  1100.         int res = lookup(cmd);
  1101.         if(res >= 1) {
  1102.             printf("%s is a shell builtin\n",cmd);
  1103.         }
  1104.         if(searchInPath(str) != NULL) {
  1105.             printf("%s\n",searchInPath(str));
  1106.         }
  1107.         return -1;
  1108.     }
  1109.     if(strcmp(tokens_get_token(tokens,(size_t)1),"-p") == 0) {
  1110.         char * cmd = tokens_get_token(tokens,(size_t)2);
  1111.         char * str = malloc(512);
  1112.         strcpy(str,cmd);
  1113.         if(searchInPath(str) != NULL) {
  1114.             printf("%s\n",searchInPath(str));
  1115.         }
  1116.         return -1;
  1117.     }
  1118.  
  1119.     return 0;
  1120. }
  1121.  
  1122. //calls progrExe based on given absolute path / only command
  1123. int runMyProgram(struct  tokens * tokens){
  1124.   int status = progrExe(tokens,NULL); //if user gave us absolute path
  1125.  
  1126.   if(status == 0){
  1127.     return 0;
  1128.   }else{
  1129.  
  1130.     char * commandPath = searchInPath(tokens_get_token(tokens,0)); //user gave us only command.Get the absolutePath
  1131.    
  1132.    
  1133.     int statusForCommand = progrExe(tokens,commandPath);
  1134.     free(commandPath); //deallocation of path
  1135.     if(statusForCommand == 0 ){ //success
  1136.       return 0;
  1137.     }else{
  1138.      
  1139.       return -1;
  1140.     }
  1141.  
  1142.   }
  1143.  
  1144. }
  1145.  
  1146.  
  1147.  
  1148.  
  1149. char ** getExecvArgument(struct  tokens * tokens,int quantityOfPipes , int * pipeTokenLocations ,int childIndex,int numChildren){
  1150.      int start;
  1151.      int end;
  1152.      
  1153.         if(childIndex == 0){
  1154.           start = 0;
  1155.           end = pipeTokenLocations[0];
  1156.         }else {
  1157.           start = pipeTokenLocations[childIndex-1]+1;  
  1158.           if(childIndex == quantityOfPipes ){
  1159.             end = tokens_get_length(tokens);
  1160.           }else {
  1161.             end = pipeTokenLocations[childIndex];
  1162.           }
  1163.         }
  1164.         int argSize = end - start + 1;
  1165.         int argsPos = 1;
  1166.         char ** args = malloc(argSize * sizeof(char*));
  1167.         args[0] = searchInPath(tokens_get_token(tokens,start));
  1168.  
  1169.        
  1170.         for(int index =start+1; index < end;index++ ){
  1171.           args[argsPos] = tokens_get_token(tokens,index);
  1172.  
  1173.           argsPos++;
  1174.          
  1175.         }
  1176.  
  1177.          args[argSize-1] = NULL;
  1178.  
  1179.  
  1180.     return args;    
  1181.  
  1182. }
  1183.  
  1184.  
  1185. int makePipes(struct tokens * tokens,int * pipeTokenLocations,int quantityOfPipes){
  1186.   int pfd[quantityOfPipes][2];
  1187.   int numChildren = quantityOfPipes +1;
  1188.  
  1189.    for (int i=0; i<quantityOfPipes; i++)
  1190.     {
  1191.         if (pipe(pfd[i]) == -1)
  1192.         {
  1193.              printf("folowwing error happned : %s\n",strerror(errno));
  1194.              return -1;
  1195.         }
  1196.     }
  1197.  
  1198.   for(int i=0;i<numChildren;i++){
  1199.     pid_t pid = fork();
  1200.  
  1201.     if(pid < 0 ){
  1202.        printf("folowwing error happned : %s\n",strerror(errno));
  1203.       exit(EXIT_FAILURE);
  1204.     }else if(pid == 0){
  1205.  
  1206.  
  1207.        
  1208.           //bind my stdin to previous pipe
  1209.          if(i>0 && i<numChildren-1 ){
  1210.            if(pfd[i-1][0] !=STDIN_FILENO){
  1211.               if(dup2(pfd[i-1][0],STDIN_FILENO) == -1){
  1212.                 //errExit("dup2 ");
  1213.                     printf("error with dup : %s\n",strerror(errno));
  1214.                     exit(EXIT_FAILURE);
  1215.               }
  1216.               if(close(pfd[i-1][0]) == -1){
  1217.                 //errExit("close desc");
  1218.                   printf("error with close: %s\n",strerror(errno));
  1219.                   exit(EXIT_FAILURE);
  1220.  
  1221.               }
  1222.  
  1223.  
  1224.  
  1225.            }
  1226.            //close my copy of previous pipe's writing
  1227.             close(pfd[i-1][1]);
  1228.  
  1229.             //bind my output to next pipe
  1230.              if(pfd[i][1] !=STDOUT_FILENO){
  1231.                 if(dup2(pfd[i][1],STDOUT_FILENO) == -1){
  1232.                   //errExit("dup2 1");
  1233.                       exit(EXIT_FAILURE);
  1234.                 }
  1235.                 if(close(pfd[i][1]) == -1){
  1236.                   //errExit("close 2");
  1237.                       exit(EXIT_FAILURE);
  1238.  
  1239.                 }
  1240.  
  1241.             }
  1242.             //close my copy of next pipe's reading
  1243.             close(pfd[i][0]);
  1244.                  //close my copy of other descriptors
  1245.           for (int j = 0; j < numChildren-1; j++) {
  1246.             if (j != i && j != i - 1)  {
  1247.               close(pfd[j][0]);
  1248.               close(pfd[j][1]);
  1249.               }
  1250.          }
  1251.           char ** args = getExecvArgument(tokens,quantityOfPipes,pipeTokenLocations,i,numChildren);
  1252.           execv(args[0],args);
  1253.  
  1254.         }else   if(i == 0){
  1255.          
  1256.                //close my copy of reading
  1257.             if(close(pfd[i][0]) == -1){
  1258.               exit(EXIT_FAILURE);
  1259.             }
  1260.              //bind my output to next pipe
  1261.              if(pfd[i][1] !=STDOUT_FILENO){
  1262.                 if(dup2(pfd[i][1],STDOUT_FILENO) == -1){
  1263.                   //errExit("dup2 1");
  1264.                       exit(EXIT_FAILURE);
  1265.                 }
  1266.                 if(close(pfd[i][1]) == -1){
  1267.                   //errExit("close 2");
  1268.                       exit(EXIT_FAILURE);
  1269.  
  1270.                 }
  1271.  
  1272.             }
  1273.            
  1274.              for (int j = 0; j < numChildren-1; j++) {
  1275.               if (j != i)  {
  1276.                 close(pfd[j][0]);
  1277.                 close(pfd[j][1]);
  1278.                 }
  1279.              }
  1280.  
  1281.             char ** args = getExecvArgument(tokens,quantityOfPipes,pipeTokenLocations,i,numChildren);
  1282.             execv(args[0],args);
  1283.  
  1284.         }else {
  1285.  
  1286.             //close my copy of writing
  1287.  
  1288.              if(close(pfd[i-1][1]) == -1){
  1289.                exit(EXIT_FAILURE);
  1290.              }
  1291.              if(pfd[i-1][0] !=STDIN_FILENO){
  1292.               if(dup2(pfd[i-1][0],STDIN_FILENO) == -1){
  1293.                 //errExit("dup2 ");
  1294.                     printf("error with dup : %s\n",strerror(errno));
  1295.                     exit(EXIT_FAILURE);
  1296.               }
  1297.               if(close(pfd[i-1][0]) == -1){
  1298.                 //errExit("close desc");
  1299.                   printf("error with close: %s\n",strerror(errno));
  1300.                   exit(EXIT_FAILURE);
  1301.  
  1302.               }
  1303.            
  1304.             for (int j = 0; j < numChildren-1; j++) {
  1305.               if (j != i-1  )  {
  1306.                 close(pfd[j][0]);
  1307.                 close(pfd[j][1]);
  1308.                 }
  1309.              }
  1310.  
  1311.                char ** args = getExecvArgument(tokens,quantityOfPipes,pipeTokenLocations,i,numChildren);
  1312.                execv(args[0],args);
  1313.         }
  1314.  
  1315.        
  1316.  
  1317.        
  1318.  
  1319.       //errExit("exec problem");
  1320.       printf("folowwing error happned : %s\n",strerror(errno));
  1321.       exit(EXIT_FAILURE);
  1322.  
  1323.  
  1324.       }
  1325.     }
  1326.  
  1327.  
  1328.   }
  1329.  
  1330.  
  1331.  
  1332.   //parent closes it own descriptors
  1333.   for(int i=0;i<numChildren-1;i++){
  1334.     close(pfd[i][0]);
  1335.     close(pfd[i][1]);
  1336.   }
  1337.  
  1338.   for(int i=0;i<numChildren;i++){
  1339.     wait( NULL);
  1340.   }
  1341.  
  1342.   return 0;
  1343.  
  1344.  
  1345. }
  1346.  
  1347. int booleanOperationsHandler(struct tokens * tokens,int booleanOperationQuantity,int * booleanOperationLocations){
  1348.   bool currentBooleanValue = true;
  1349.   char args[1024];
  1350.   memset(args,0,1024);
  1351.   int currentBooleanIndex = 0;
  1352.  
  1353.  
  1354.   for(int i=0;i<tokens_get_length(tokens);i++){
  1355.     if(strcmp(tokens_get_token(tokens,i),"&&") == 0 || strcmp(tokens_get_token(tokens,i),"||") == 0 || i == tokens_get_length(tokens)-1){
  1356.  
  1357.      
  1358.       if(i == tokens_get_length(tokens) -1 ){
  1359.             strcat(args,tokens_get_token(tokens,i));
  1360.       }
  1361.  
  1362.       if(currentBooleanIndex == 0){
  1363.  
  1364.              struct tokens *argsToken = tokenize(args);
  1365.              int status = runMyProgram(argsToken);
  1366.              if(status == 0){
  1367.                currentBooleanValue = true;
  1368.              }else {
  1369.      
  1370.                currentBooleanValue = false;
  1371.              }
  1372.  
  1373.              tokens_destroy(argsToken);
  1374.              
  1375.            
  1376.  
  1377.       }else if((strcmp(tokens_get_token(tokens,booleanOperationLocations[currentBooleanIndex-1]),"&&") == 0 && currentBooleanValue == true) ||
  1378.              (strcmp(tokens_get_token(tokens,booleanOperationLocations[currentBooleanIndex-1]), "||") == 0 && currentBooleanValue == false)    ){
  1379.                struct tokens *argsToken = tokenize(args);
  1380.          
  1381.                int status =  runMyProgram(argsToken);
  1382.                if(status == 0){
  1383.                  currentBooleanValue = true;
  1384.                }else{
  1385.                  currentBooleanValue = false;
  1386.                }
  1387.  
  1388.                tokens_destroy(argsToken);
  1389.              
  1390.              
  1391.  
  1392.              }
  1393.                currentBooleanIndex++;
  1394.                memset(args,0,1024); //clean up args for next one
  1395.     }else{
  1396.       strcat(args,tokens_get_token(tokens,i));
  1397.       strcat(args," ");
  1398.     }
  1399.   }
  1400.  
  1401.  
  1402.   return 0;
  1403.  
  1404. }
  1405.  
  1406. void progrExeWrapper(struct tokens *tokens) {
  1407.       int booleanOperationQuantity = 0;
  1408.       int booleanOperationLocations[tokens_get_length(tokens)];
  1409.  
  1410.       for(int i=0;i<tokens_get_length(tokens);i++){
  1411.         if(strcmp(tokens_get_token(tokens,i),"&&" ) == 0 || strcmp(tokens_get_token(tokens,i),"||" ) == 0){
  1412.           booleanOperationLocations[booleanOperationQuantity] = i;
  1413.        
  1414.           booleanOperationQuantity++;
  1415.         }
  1416.       }
  1417.  
  1418.       if(booleanOperationQuantity > 0){
  1419.         booleanOperationsHandler(tokens,booleanOperationQuantity,booleanOperationLocations);
  1420.    
  1421.     }else{
  1422.  
  1423.  
  1424.  
  1425.       int quantityOfPipes = 0;
  1426.       int pipeTokenLocations[tokens_get_length(tokens)];
  1427.       for(int i=0;i<tokens_get_length(tokens);i++){
  1428.    
  1429.         if(strcmp(tokens_get_token(tokens,i),"|") == 0){
  1430.          
  1431.           pipeTokenLocations[quantityOfPipes] = i;
  1432.           quantityOfPipes++;
  1433.         }
  1434.  
  1435.       }
  1436.    
  1437.    
  1438.       if(quantityOfPipes > 0){
  1439.         makePipes(tokens,pipeTokenLocations,quantityOfPipes);
  1440.  
  1441.      
  1442.  
  1443.      } else{
  1444.  
  1445.  
  1446.  
  1447.       if(tokens_get_length(tokens) != 0){
  1448.  
  1449.          runMyProgram(tokens);
  1450.       }
  1451.  
  1452.       }
  1453.      }
  1454. }
  1455.  
  1456.  
  1457. void shellExe(char *line) {
  1458.     /* Split our line into words. */
  1459.     struct tokens *tokens = tokenize(line);
  1460.  
  1461.     /* Find which built-in function to run. */
  1462.     int fundex = lookup(tokens_get_token(tokens, 0));
  1463.  
  1464.  
  1465.  
  1466.     if (fundex >= 0) {
  1467.       cmd_table[fundex].fun(tokens);
  1468.     } else {
  1469.         progrExeWrapper(tokens);
  1470.     }
  1471.    
  1472.  
  1473.  
  1474.  
  1475.     /* Clean up memory */
  1476.     tokens_destroy(tokens);
  1477. }
  1478.  
  1479. /* Runs shell with passed arguments */
  1480. void runFromBash(int argc, char *commands) {
  1481.   for (char *token = strtok(commands,";"); token != NULL; token = strtok(NULL, ";")) {
  1482.     shellExe(token);
  1483.   }
  1484. }
  1485.  
  1486.  
  1487. int main(unused int argc, unused char *argv[]) {
  1488.   init_shell();
  1489.  
  1490.   static char line[4096];
  1491.   int line_num = 0;
  1492.  
  1493.   if (argc >= 3 && strcmp(argv[1], "-c") == 0) {
  1494.     //printf("%s\n", argv[2]);
  1495.     runFromBash(argc, argv[2]);
  1496.   } else {
  1497.  
  1498.     /* Please only print shell prompts when standard input is not a tty */
  1499.     if (shell_is_interactive)
  1500.       fprintf(stdout, "%d: ", line_num);
  1501.  
  1502.     while (fgets(line, 4096, stdin)) {
  1503.       shellExe(line);
  1504.  
  1505.       if (shell_is_interactive)
  1506.         /* Please only print shell prompts when standard input is not a tty */
  1507.         fprintf(stdout, "%d: ", ++line_num);  
  1508.     }
  1509.   }
  1510.   return 0;
  1511. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement