Advertisement
Guest User

Untitled

a guest
Mar 25th, 2019
75
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.67 KB | None | 0 0
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include <strings.h>
  5. #include <limits.h>
  6. #include <unistd.h>
  7. #include <stdlib.h>
  8. #include <pwd.h>
  9. #include <dirent.h>
  10. #include <sys/types.h>
  11. #include <sys/wait.h>
  12. #include <signal.h>
  13. #include <errno.h>
  14. #include "sh.h"
  15.  
  16. #define BUFFERSIZE 1024
  17. char buffer[BUFFERSIZE], buffer2[BUFFERSIZE];
  18. int sh( int argc, char **argv, char **envp )
  19. {
  20. char *prompt = calloc(PROMPTMAX, sizeof(char));
  21. char *commandline = calloc(MAX_CANON, sizeof(char));
  22. char *command, *arg, *commandpath, *p, *pwd, *owd;
  23. int uid, i, status, argsct, go = 1;
  24. int len;
  25. struct passwd *password_entry;
  26. char *homedir;
  27. struct pathelement *pathlist;
  28.  
  29. uid = getuid();
  30. password_entry = getpwuid(uid); /* get passwd info */
  31. homedir = password_entry->pw_dir; /* Home directory to start
  32. out with*/
  33.  
  34. if ( (pwd = getcwd(NULL, PATH_MAX+1)) == NULL )
  35. {
  36. perror("getcwd");
  37. exit(2);
  38. }
  39. owd = calloc(strlen(pwd) + 1, sizeof(char));
  40. memcpy(owd, pwd, strlen(pwd));
  41. prompt[0] = ' '; prompt[1] = '\0';
  42. prompt = "term:~";
  43. /* Put PATH into a linked list */
  44. pathlist = get_path();
  45. label:
  46. while ( go )
  47. {
  48. char **args = calloc(MAXARGS, sizeof(char*)); //have to do it here to clear the array each time before a new command.
  49. printf("%s", prompt);
  50. /* print your prompt */
  51. fgets(buffer, BUFFERSIZE, stdin); //buffer stores the terminal input
  52. len = strlen(buffer);
  53. buffer[len - 1] = '\0'; // override \n to become \0 for the last arg.
  54. /* get command line and process */
  55. char* token = strtok(buffer, " "); //space delimits each argument
  56. /* check for each built in command and implement */
  57. //The first word is always the command you want to use in the terminal.
  58. int i = 0;
  59. while(token != NULL){ //I'm assuming we use args[] array to store all the arguments. This is how to do it using strtok.
  60. args[i] = token;
  61. token = strtok(NULL, " ");
  62. i++;
  63. }
  64. if(!strcmp(args[0], "which")){
  65. which(args[1], get_path());
  66. goto label;
  67. }
  68. if(!strcmp(args[0], "where")){
  69. where(args[1], get_path());
  70. goto label;
  71. //implement how to pass to where
  72. }
  73. if(!strcmp(args[0], "list")){
  74. printf("ARGs[1] = %s", args[1]);
  75. list(args[1]);
  76. goto label;
  77. }
  78. if(!strcmp(args[0], "exit")){
  79. free(prompt);
  80. free(commandline);
  81. freepath(pathlist);
  82. exit(0);
  83. }
  84. if(!strcmp(args[0], "cd")){
  85. if(args[1] == NULL){
  86. const char* home = "HOME";
  87. chdir(getenv(home));
  88. }
  89. else{
  90. cd(args[1]);
  91. }
  92. goto label;
  93. }
  94. if(!strcmp(args[0], "pwd")){
  95. char cwd[BUFFERSIZE];
  96. getcwd(cwd, BUFFERSIZE);
  97. printf("%s\n", cwd);
  98. goto label;
  99. }
  100. if(!strcmp(args[0], "printenv")){
  101. printenv(envp);
  102. goto label;
  103. }
  104. if(!strcmp(args[0], "setenv")){
  105. if(args[1] == NULL){
  106. while (*envp){
  107. printf("%s\n", *envp++);
  108. }
  109. }
  110. else{
  111. setenv1(args, envp);
  112. }
  113. freepath(pathlist);
  114. pathlist = get_path();
  115. goto label;
  116. }
  117. if(!strcmp(args[0], "prompt")){
  118. if(args[1] == NULL){
  119. //prompt for a new prefix string
  120. }
  121. else{
  122. prompt = args[1];
  123. }
  124. goto label;
  125. }
  126. /* else program to exec */
  127. else{ //the command is one of your own, either in the directory pointed by args[0] as ./command or as command in PATH.
  128. char *command;
  129. /* find it */
  130. //CASE 1: absolute or relative path - just append the path to it.
  131. if(args[0][0] == '/' || args[0][0] == '.'){ //use strtok() to delimit with /, then use access to see if it's really there. Then run it.
  132. if(!access(args[0], X_OK)){//if the file exists and is executable... (returns 0)
  133. printf("Command found\n");
  134. runcommand(args, envp);
  135. }
  136. else{
  137. printf("Error: %s\n . Consult errno listings for access.", strerror(errno));
  138. }
  139. }
  140. //CASE 2: search for it in the PATHs.
  141. else{ //if the command is given by itself (w/out a path)... loop through the PATHs and find it.
  142. //I'm basically using the which code to find where the executable is.
  143. char cmd[64];
  144. while(pathlist){
  145. sprintf(cmd, "%s/%s", pathlist->element, args[0]);
  146. if(!access(cmd, X_OK)){
  147. args[0] = cmd;
  148. runcommand(args, envp); //command located in all possible paths. Run it.
  149. goto label;
  150. }
  151. pathlist = pathlist->next;
  152. }
  153. if (pathlist == NULL){
  154. fprintf(stderr, "%s: Command not found.\n", args[0]);
  155. goto label;
  156. }
  157. }
  158. }
  159. }
  160. free(prompt);
  161. free(commandline);
  162. freepath(pathlist);
  163. return 0;
  164. } /* sh() */
  165. void runcommand(char **args, char **envp){ //
  166. int i =0;
  167. printf("RUNNING %s \n", args[0]);
  168. //Once you find the command you should execute it, using execve(2)
  169. int PID = fork();
  170. if (PID == 0){
  171. execve(args[0], args, envp); //fork and execute.
  172. }
  173. else{
  174. wait(NULL);
  175. printf("External program completed\n");
  176. }
  177. }
  178. char *which(char *command, struct pathelement *pathlist )
  179. {
  180. int accesss = 0;
  181. /* loop through pathlist until finding command and return it. Return
  182. NULL when not found. */
  183. char cmd[64];
  184. while(pathlist){
  185. sprintf(cmd, "%s/%s", pathlist->element, command);
  186. if(access(cmd, F_OK) == 0){
  187. accesss = 1;
  188. //printf("[%s]\n", cmd);
  189. break;
  190. }
  191. pathlist = pathlist->next;
  192. }
  193. if(access == 0){
  194. printf("Cannot find %s in any paths\n", cmd);
  195. }
  196. } /* which() */
  197.  
  198. char *where(char *command, struct pathelement *pathlist)
  199. {
  200. char cmd[64];
  201. while(pathlist){
  202. sprintf(cmd, "%s/%s", pathlist->element, command);
  203. if(access(cmd, F_OK) == 0){
  204. printf("[%s]\n", cmd);
  205. }
  206. pathlist = pathlist->next;
  207. }
  208. } /* where() */
  209.  
  210. void list ( char *dir ) //works
  211. {
  212. /* see man page for opendir() and readdir() and print out filenames for
  213. the directory passed */
  214. struct dirent *ent;
  215. DIR *d;
  216. if(dir == NULL){
  217. d = opendir("./"); //no 2nd arg = list all files in working directory.
  218. }
  219. else{
  220. d = opendir(dir);
  221. }
  222. if (d) {
  223. /* print all the files and directories within directory */
  224. while ((ent = readdir(d)) != NULL) {
  225. printf ("%s\n", ent->d_name);
  226. }
  227. closedir (d);
  228. }
  229. } /* list() */
  230. void cd(char *dir){ //works
  231. if(chdir(dir) == -1){
  232. printf("Error changing directory!");
  233. }
  234. }
  235. void setenv1(char **args, char **envp){ //MAKE SURE TO CHANGE THE PATH WHEN DONE!!!
  236. if(args[2] == NULL){ //When ran with one argument, sets that as an empty environment variable
  237. const char* arg1 = args[1];
  238. const char* arg2 = args[2];
  239. if(setenv(arg1,NULL,1) == -1){
  240. printf("Error setting environment variable\n");
  241. }
  242. }
  243. else if(args[1]!=NULL && args[2]!=NULL && args[3]==NULL){ //When ran with two arguments, the second one is the value of the first.
  244. const char* arg1 = args[1];
  245. const char* arg2 = args[2];
  246. if(setenv(arg2,arg1,1) == -1){
  247. printf("Error setting environment variable\n");
  248. }
  249. }
  250. else{
  251. printf("Please run with either only 1 argument or only 2 arguments.\n");
  252. }
  253. }
  254. void(printenv(char **envp)){
  255. while (*envp){
  256. printf("%s\n", *envp++);
  257. }
  258. }
  259. void freepath(struct pathelement *path){
  260. struct pathelement *current = path;
  261. struct pathelement *temp;
  262. while(current->next != NULL){
  263. temp = current;
  264. current = current->next;
  265. free(temp);
  266. }
  267. free(current);
  268. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement