Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include <strings.h>
- #include <limits.h>
- #include <unistd.h>
- #include <stdlib.h>
- #include <pwd.h>
- #include <dirent.h>
- #include <sys/types.h>
- #include <sys/wait.h>
- #include <signal.h>
- #include <errno.h>
- #include "sh.h"
- #define BUFFERSIZE 1024
- char buffer[BUFFERSIZE], buffer2[BUFFERSIZE];
- int sh( int argc, char **argv, char **envp )
- {
- char *prompt = calloc(PROMPTMAX, sizeof(char));
- char *commandline = calloc(MAX_CANON, sizeof(char));
- char *command, *arg, *commandpath, *p, *pwd, *owd;
- int uid, i, status, argsct, go = 1;
- int len;
- struct passwd *password_entry;
- char *homedir;
- struct pathelement *pathlist;
- uid = getuid();
- password_entry = getpwuid(uid); /* get passwd info */
- homedir = password_entry->pw_dir; /* Home directory to start
- out with*/
- if ( (pwd = getcwd(NULL, PATH_MAX+1)) == NULL )
- {
- perror("getcwd");
- exit(2);
- }
- owd = calloc(strlen(pwd) + 1, sizeof(char));
- memcpy(owd, pwd, strlen(pwd));
- prompt[0] = ' '; prompt[1] = '\0';
- prompt = "term:~";
- /* Put PATH into a linked list */
- pathlist = get_path();
- label:
- while ( go )
- {
- char **args = calloc(MAXARGS, sizeof(char*)); //have to do it here to clear the array each time before a new command.
- printf("%s", prompt);
- /* print your prompt */
- fgets(buffer, BUFFERSIZE, stdin); //buffer stores the terminal input
- len = strlen(buffer);
- buffer[len - 1] = '\0'; // override \n to become \0 for the last arg.
- /* get command line and process */
- char* token = strtok(buffer, " "); //space delimits each argument
- /* check for each built in command and implement */
- //The first word is always the command you want to use in the terminal.
- int i = 0;
- while(token != NULL){ //I'm assuming we use args[] array to store all the arguments. This is how to do it using strtok.
- args[i] = token;
- token = strtok(NULL, " ");
- i++;
- }
- if(!strcmp(args[0], "which")){
- which(args[1], get_path());
- goto label;
- }
- if(!strcmp(args[0], "where")){
- where(args[1], get_path());
- goto label;
- //implement how to pass to where
- }
- if(!strcmp(args[0], "list")){
- printf("ARGs[1] = %s", args[1]);
- list(args[1]);
- goto label;
- }
- if(!strcmp(args[0], "exit")){
- free(prompt);
- free(commandline);
- freepath(pathlist);
- exit(0);
- }
- if(!strcmp(args[0], "cd")){
- if(args[1] == NULL){
- const char* home = "HOME";
- chdir(getenv(home));
- }
- else{
- cd(args[1]);
- }
- goto label;
- }
- if(!strcmp(args[0], "pwd")){
- char cwd[BUFFERSIZE];
- getcwd(cwd, BUFFERSIZE);
- printf("%s\n", cwd);
- goto label;
- }
- if(!strcmp(args[0], "printenv")){
- printenv(envp);
- goto label;
- }
- if(!strcmp(args[0], "setenv")){
- if(args[1] == NULL){
- while (*envp){
- printf("%s\n", *envp++);
- }
- }
- else{
- setenv1(args, envp);
- }
- freepath(pathlist);
- pathlist = get_path();
- goto label;
- }
- if(!strcmp(args[0], "prompt")){
- if(args[1] == NULL){
- //prompt for a new prefix string
- }
- else{
- prompt = args[1];
- }
- goto label;
- }
- /* else program to exec */
- else{ //the command is one of your own, either in the directory pointed by args[0] as ./command or as command in PATH.
- char *command;
- /* find it */
- //CASE 1: absolute or relative path - just append the path to it.
- 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.
- if(!access(args[0], X_OK)){//if the file exists and is executable... (returns 0)
- printf("Command found\n");
- runcommand(args, envp);
- }
- else{
- printf("Error: %s\n . Consult errno listings for access.", strerror(errno));
- }
- }
- //CASE 2: search for it in the PATHs.
- else{ //if the command is given by itself (w/out a path)... loop through the PATHs and find it.
- //I'm basically using the which code to find where the executable is.
- char cmd[64];
- while(pathlist){
- sprintf(cmd, "%s/%s", pathlist->element, args[0]);
- if(!access(cmd, X_OK)){
- args[0] = cmd;
- runcommand(args, envp); //command located in all possible paths. Run it.
- goto label;
- }
- pathlist = pathlist->next;
- }
- if (pathlist == NULL){
- fprintf(stderr, "%s: Command not found.\n", args[0]);
- goto label;
- }
- }
- }
- }
- free(prompt);
- free(commandline);
- freepath(pathlist);
- return 0;
- } /* sh() */
- void runcommand(char **args, char **envp){ //
- int i =0;
- printf("RUNNING %s \n", args[0]);
- //Once you find the command you should execute it, using execve(2)
- int PID = fork();
- if (PID == 0){
- execve(args[0], args, envp); //fork and execute.
- }
- else{
- wait(NULL);
- printf("External program completed\n");
- }
- }
- char *which(char *command, struct pathelement *pathlist )
- {
- int accesss = 0;
- /* loop through pathlist until finding command and return it. Return
- NULL when not found. */
- char cmd[64];
- while(pathlist){
- sprintf(cmd, "%s/%s", pathlist->element, command);
- if(access(cmd, F_OK) == 0){
- accesss = 1;
- //printf("[%s]\n", cmd);
- break;
- }
- pathlist = pathlist->next;
- }
- if(access == 0){
- printf("Cannot find %s in any paths\n", cmd);
- }
- } /* which() */
- char *where(char *command, struct pathelement *pathlist)
- {
- char cmd[64];
- while(pathlist){
- sprintf(cmd, "%s/%s", pathlist->element, command);
- if(access(cmd, F_OK) == 0){
- printf("[%s]\n", cmd);
- }
- pathlist = pathlist->next;
- }
- } /* where() */
- void list ( char *dir ) //works
- {
- /* see man page for opendir() and readdir() and print out filenames for
- the directory passed */
- struct dirent *ent;
- DIR *d;
- if(dir == NULL){
- d = opendir("./"); //no 2nd arg = list all files in working directory.
- }
- else{
- d = opendir(dir);
- }
- if (d) {
- /* print all the files and directories within directory */
- while ((ent = readdir(d)) != NULL) {
- printf ("%s\n", ent->d_name);
- }
- closedir (d);
- }
- } /* list() */
- void cd(char *dir){ //works
- if(chdir(dir) == -1){
- printf("Error changing directory!");
- }
- }
- void setenv1(char **args, char **envp){ //MAKE SURE TO CHANGE THE PATH WHEN DONE!!!
- if(args[2] == NULL){ //When ran with one argument, sets that as an empty environment variable
- const char* arg1 = args[1];
- const char* arg2 = args[2];
- if(setenv(arg1,NULL,1) == -1){
- printf("Error setting environment variable\n");
- }
- }
- 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.
- const char* arg1 = args[1];
- const char* arg2 = args[2];
- if(setenv(arg2,arg1,1) == -1){
- printf("Error setting environment variable\n");
- }
- }
- else{
- printf("Please run with either only 1 argument or only 2 arguments.\n");
- }
- }
- void(printenv(char **envp)){
- while (*envp){
- printf("%s\n", *envp++);
- }
- }
- void freepath(struct pathelement *path){
- struct pathelement *current = path;
- struct pathelement *temp;
- while(current->next != NULL){
- temp = current;
- current = current->next;
- free(temp);
- }
- free(current);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement