#ifndef shell_main_func #define shell_main_func #include #include #include #include #include #include #include "helper_functions.c" #define LSH_RL_BUFSIZE 1024 char *lsh_read_line(void) { int bufsize = LSH_RL_BUFSIZE; int position = 0; char *buffer = malloce(sizeof(char) * bufsize); int c; while (1) { // Read a character c = getchar(); // If we hit EOF, replace it with a null character and return. if (c == EOF || c == '\n') { buffer[position] = '\0'; return buffer; } else { buffer[position] = c; } position++; // If we have exceeded the buffer, reallocate. if (position >= bufsize) { bufsize += LSH_RL_BUFSIZE; buffer = realloc(buffer, bufsize); if (!buffer) { fprintf(stderr, "lsh: allocation error\n"); exit(EXIT_FAILURE); } } } } char *handle_vars(char *token){ char *ret_token=(char*)malloce(sizeof(char)*strlen(token)+1); strcpy(ret_token,token); if (token[0]=='~'){ token++; if(!getenv("HOME")){ fprintf(stderr,"lsh: you aint got no home. da hell\n"); free(ret_token); ret_token=(char*)malloce(sizeof(char)*strlen(token)+1); strcpy(ret_token,token); return ret_token; } free(ret_token); ret_token=(char*)malloce(sizeof(char)*strlen(token)+strlen(getenv("HOME"))+1); strcpy(ret_token,getenv("HOME")); strcat(ret_token,token); } char *tmp_token=(char*)malloce(sizeof(char)*strlen(ret_token)+1); strcpy(tmp_token,ret_token); int i=0; while (tmp_token[i]!='\0'){ if(tmp_token[i]=='$'){ int j=0; while(tmp_token[i+j]!=' ' && tmp_token[i+j]) j++; char *varname=(char*)malloce(sizeof(char)*j+1); varname[j]='\0'; strncpy(varname,&tmp_token[i+1],j); varname[j-1]='\0'; char *env = getenv(varname); if(!env){ env=""; } free(ret_token); int tmp_len=strlen(tmp_token); ret_token=(char*)malloce(sizeof(char)*(strlen(tmp_token)-strlen(varname))+strlen(env)+1); tmp_token[i]='\0'; tmp_token[i+j]='\0'; strcpy(ret_token,tmp_token); strcat(ret_token,env); strcat(ret_token," "); if(i+j+1 < tmp_len){ strcat(ret_token,&tmp_token[i+j+1]); } free(tmp_token); tmp_token=(char*)malloce(sizeof(char)*strlen(ret_token)+1); strcpy(tmp_token,ret_token); free(varname); } i++; } free(tmp_token); return ret_token; } char * strtok_quotes(char *token){ static char* parse_args_last_p; if(token != NULL){ parse_args_last_p=token; } if(parse_args_last_p==NULL){ return NULL; } char *return_char=parse_args_last_p; char in_quote=' '; if(parse_args_last_p != NULL){ int ch_i=0; while(1){ if (parse_args_last_p[ch_i] == '\0') break; if (in_quote==' ' && (parse_args_last_p[ch_i]=='"' || parse_args_last_p[ch_i]=='\'')){ bool pass_check=true; if(ch_i>0 && parse_args_last_p[ch_i-1]=='\\') pass_check=false; if(pass_check==true){ in_quote=parse_args_last_p[ch_i]; if (parse_args_last_p[ch_i+1] == '\0') break; if(ch_i==0){ parse_args_last_p[0]='\0'; parse_args_last_p=&parse_args_last_p[1]; return_char=&return_char[1]; } else { pop(return_char,ch_i); } ch_i++; } } if(in_quote!=' '){ if (parse_args_last_p[ch_i]==in_quote){ bool pass_check=true; if(ch_i>0 && parse_args_last_p[ch_i-1]=='\\') pass_check=false; if(pass_check==true){ in_quote=' '; if(parse_args_last_p[ch_i+1]=='\0'){ parse_args_last_p[ch_i]='\0'; } else if(parse_args_last_p[ch_i+1]==' '){ parse_args_last_p[ch_i]='\0'; parse_args_last_p = &parse_args_last_p[ch_i+2]; pop(return_char,ch_i); return return_char; } pop(return_char,ch_i); } } } else { if (parse_args_last_p[ch_i] == ' '){ parse_args_last_p[ch_i] = '\0'; parse_args_last_p = &parse_args_last_p[ch_i+1]; return return_char; } } ch_i++; } parse_args_last_p=NULL; } return return_char; } #define LSH_TOK_BUFSIZE 64 char **lsh_split_line(char *line) { int bufsize = LSH_TOK_BUFSIZE, position = 0; char **tokens = malloce(bufsize * sizeof(char*)); char *token; token = strtok_quotes(line); while (token != NULL) { token = handle_vars(token); tokens[position] = token; position++; if (position >= bufsize) { bufsize += LSH_TOK_BUFSIZE; tokens = realloc(tokens, bufsize * sizeof(char*)); if (!tokens) { fprintf(stderr, "lsh: allocation error\n"); exit(EXIT_FAILURE); } } token = strtok_quotes(NULL); } tokens[position] = NULL; return tokens; } int lsh_launch(char **args) { pid_t pid, wpid; int status; pid = fork(); if (pid == 0) { // Child process if (execvp(args[0], args) == -1) { perror("lsh"); } exit(EXIT_FAILURE); } else if (pid < 0) { // Error forking perror("lsh"); } else { // Parent process do { wpid = waitpid(pid, &status, WUNTRACED); } while (!WIFEXITED(status) && !WIFSIGNALED(status)); } return 1; } #endif