1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
|
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <stdbool.h>
#include <string.h>
#include <stdlib.h>
#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 *env[32] = {"PATH=/bin"};
char path[128] = "/";
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;
}
__pid_t forkResult = fork();
if (forkResult == 0) {
execve(command, argv, 0);
} else {
waitid(P_ALL, 0, 0, WEXITED);
}
}
}
|