#include #include #include #include #include #include #include #include #include #define P_ALL 0 #define P_PID 1 #define P_PGID 2 #define P_PIDFD 3 #if !WEXITED #define WEXITED 0x00000004 #endif void parseInput(char *input, char *command, char **argv) { bool reachedArgv = false; char arg[32] = {0}; int idx = 0; int argvIdx = 1; for (int i = 0; i < strlen(input); i++) { char *a = {&(input[i])}; if (reachedArgv) { if (input[i] == ' ') { arg[idx] = '\0'; argv[argvIdx] = strdup(arg); memset(arg, 0, sizeof(arg)); argvIdx++; idx = 0; continue; } arg[idx] = input[i]; idx++; continue; } if (input[i] == ' ') { arg[idx] = '\0'; strcpy(command, arg); reachedArgv = true; memset(arg, 0, sizeof(arg)); idx = 0; continue; } arg[idx] = input[i]; idx++; } argv[0] = command; if (reachedArgv) { arg[idx] = '\0'; argv[argvIdx] = strdup(arg); } else { arg[idx] = '\0'; strcpy(command, arg); } } void joinPath(char *result, const char *base, const char *rel) { strcpy(result, base); strcat(result, "/"); strcat(result, rel); } int main() { char input[255] = {0}; char command[128] = {0}; char *argv[32] = {0}; char path[128] = "/"; char termpcap[512] = "vt102|smolsh|dec vt102:\ :do=^J:co#80:li#24:cl=50\\E[;H\\E[2J:\ :le=^H:bs:cm=5\\E[%i%d;%dH:nd=2\\E[C:up=2\\E[A:\ :ce=3\\E[K:cd=50\\E[J:so=2\\E[7m:se=2\\E[m:us=2\\E[4m:ue=2\\E[m:\ :md=2\\E[1m:mr=2\\E[7m:mb=2\\E[5m:me=2\\E[m:is=\\E[1;24r\\E[24;1H:\ :rs=\\E>\\E[?3l\\E[?4l\\E[?5l\\E[?7h\\E[?8h:ks=\\E[?1h\\E=:ke=\\E[?1l\\E>:\ :ku=\\EOA:kd=\\EOB:kr=\\EOC:kl=\\EOD:kb=^H:\ :ho=\\E[H:k1=\\EOP:k2=\\EOQ:k3=\\EOR:k4=\\EOS:pt:sr=5\\EM:vt#3:\ :sc=\\E7:rc=\\E8:cs=\\E[%i%d;%dr:vs=\\E[?7l:ve=\\E[?7h:\ :mi:al=\\E[L:dc=\\E[P:dl=\\E[M:ei=\\E[4l:im=\\E[4h:"; setenv("TERMCAP", termpcap, 1); setenv("PATH", "/bin", 0); while (!false) { memset(input, 0, sizeof(input)); memset(command, 0, sizeof(command)); memset(argv, 0, sizeof(argv)); write(1, path, strlen(path)); write(1, " $ ", 3); int len = read(1, input, sizeof(input)); input[len - 1] = '\0'; parseInput(input, command, argv); if (!strcmp(command, "cd")) { char newpath[128] = {0}; char newresolvedpath[128] = {0}; if (argv[1][0] == '/') { strcpy(newresolvedpath, argv[1]); } else { joinPath(newpath, path, argv[1]); realpath(newpath, newresolvedpath); } if (!access(newresolvedpath, F_OK)) { struct stat statResult; stat(newresolvedpath, &statResult); if (S_ISDIR(statResult.st_mode)) { strcpy(path, newresolvedpath); } else { write(1, "uuuuh das not a dir\n", 21); } } else { write(1, "uuuuh das not a dir\n", 21); } continue; } chdir(path); __pid_t forkResult = fork(); if (forkResult == 0) { char* pathV = getenv("PATH"); struct stat path_stat; if (stat(command, &path_stat) == 0 && access(command, X_OK)){ execve(command, argv, 0); } else { // algorithm from old shel since i made it on my own bool found = false; char currPath[32] = {0}; int i = 0; int c = 0; char newPath[128] = {0}; while (i < strlen(pathV) && !found) { if (pathV[i] == ':') { currPath[i] = '\0'; memset(newPath, 0, sizeof(newPath)); joinPath(newPath, currPath, command); realpath(newPath, newPath); if(stat(newPath, &path_stat) == 0 && path_stat.st_mode & S_IXUSR) { found = true; continue; } c = 0; } else { currPath[c] = pathV[i]; } i++;c++; } if (!found) { currPath[i] = '\0'; memset(newPath, 0, sizeof(newPath)); joinPath(newPath, currPath, command); realpath(newPath, newPath); if(stat(newPath, &path_stat) == 0 && path_stat.st_mode & S_IXUSR) { found = true; } } if (found) { execve(newPath, argv, 0); } } } else { waitid(P_ALL, 0, 0, WEXITED); } } }