Skip to content
This repository was archived by the owner on Dec 25, 2018. It is now read-only.

Commit 5cfa628

Browse files
committed
partial hw1
0 parents  commit 5cfa628

File tree

6 files changed

+227
-0
lines changed

6 files changed

+227
-0
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
source

Makefile

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
CC=gcc
2+
CFLAGS=-g
3+
4+
source: source.c builtin.c
5+
cc ${CFLAGS} source.c builtin.c -o source
6+
7+
.PHONY: clean
8+
clean:
9+
rm -f source

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Secure Interactive Shell
2+
##### hw1
3+
4+

builtin.c

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
#include <stdio.h>
2+
#include <stdlib.h>
3+
#include <string.h>
4+
#include <sys/stat.h>
5+
#include <sys/types.h>
6+
#include <unistd.h>
7+
#define N 1024
8+
9+
int builtin_cat(char *cmd) { return 0; }
10+
11+
int builtin_cd(char *line) {
12+
char cmd[N], arg[N], extra[N];
13+
if (sscanf(line, "%s %s %s", cmd, arg, extra) != 2) return -1;
14+
15+
int ret = chdir(arg);
16+
// if (ret == -1)
17+
return 0;
18+
}
19+
20+
int builtin_chmod(char *cmd) { return 0; }
21+
22+
int builtin_echo(char *cmd) { return 0; }
23+
24+
int builtin_exit(char *line) {
25+
char cmd[N], extra[N];
26+
if (sscanf(line, "%s %s", cmd, extra) != 1) return -1;
27+
28+
return 1;
29+
}
30+
31+
int builtin_find(char *cmd) { return 0; }
32+
33+
int builtin_help(char *line) {
34+
char cmd[N], extra[N];
35+
if (sscanf(line, "%s %s", cmd, extra) != 1) return -1;
36+
37+
const char *help_string[] = {
38+
"cat {file}: Display content of {file}.",
39+
"cd {dir}: Switch current working directory to {dir}.",
40+
"chmod {mode} {file/dir}: Change the mode (permission) of a file or "
41+
"directory.",
42+
" {mode} is an octal number.",
43+
" Please do not follow symbolc links.",
44+
"echo {str} [filename]: Display {str}. If [filename] is given,",
45+
" open [filename] and append {str} to the file.",
46+
"exit: Leave the shell.",
47+
"find [dir]: List files/dirs in the current working "
48+
"directory",
49+
" or [dir] if it is given.",
50+
" Minimum outputs contatin file type, size, and "
51+
"name.",
52+
"help: Display help message.",
53+
"id: Show current euid and egid.",
54+
"mkdir {dir}: Create a new directory {dir}.",
55+
"pwd: Print the current working directory.",
56+
"rm {file}: Remove a file.",
57+
"rmdir {dir}: Remove an empty directory.",
58+
"stat {file/dir}: Display detailed information of the given "
59+
"file/dir.",
60+
"touch {file}: Create {file} if it does not exist,",
61+
" or update its access and modification "
62+
"timestamp.",
63+
"umask {mode}: Change the umask of the current session."};
64+
size_t len = sizeof(help_string) / sizeof(char *);
65+
for (size_t i = 0; i < len; ++i) printf("%s\n", help_string[i]);
66+
return 0;
67+
}
68+
69+
int builtin_id(char *line) {
70+
char cmd[N], extra[N];
71+
if (sscanf(line, "%s %s", cmd, extra) != 1) return -1;
72+
73+
printf("uid=%d gid=%d\n", geteuid(), getegid());
74+
return 0;
75+
}
76+
77+
int builtin_mkdir(char *line) {
78+
char cmd[N], arg[N], extra[N];
79+
if (sscanf(line, "%s %s %s", cmd, arg, extra) != 2) return -1;
80+
81+
int ret = mkdir(arg, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
82+
// if (ret == -1)
83+
return 0;
84+
}
85+
86+
int builtin_pwd(char *line) {
87+
char cmd[N], extra[N];
88+
if (sscanf(line, "%s %s", cmd, extra) != 1) return -1;
89+
90+
char name[N];
91+
getcwd(name, N);
92+
// if (name == NULL)
93+
printf("%s\n", name);
94+
return 0;
95+
}
96+
97+
int builtin_rm(char *line) {
98+
char cmd[N], arg[N], extra[N];
99+
if (sscanf(line, "%s %s %s", cmd, arg, extra) != 2) return -1;
100+
101+
int ret = remove(arg);
102+
// if (ret == -1)
103+
return 0;
104+
}
105+
106+
int builtin_rmdir(char *line) {
107+
char cmd[N], arg[N], extra[N];
108+
if (sscanf(line, "%s %s %s", cmd, arg, extra) != 2) return -1;
109+
110+
int ret = rmdir(arg);
111+
// if (ret == -1)
112+
return 0;
113+
}
114+
115+
int builtin_stat(char *cmd) { return 0; }
116+
117+
int builtin_touch(char *line) {
118+
char cmd[N], arg[N], extra[N];
119+
if (sscanf(line, "%s %s %s", cmd, arg, extra) != 2) return -1;
120+
121+
FILE *file;
122+
// if (access(arg, F_OK) != -1)
123+
file = fopen(arg, "a+");
124+
fclose(file);
125+
return 0;
126+
}
127+
128+
int builtin_unmask(char *cmd) { return 0; }

builtin.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
int builtin_cat(char *);
2+
int builtin_cd(char *);
3+
int builtin_chmod(char *);
4+
int builtin_echo(char *);
5+
int builtin_exit(char *);
6+
int builtin_find(char *);
7+
int builtin_help(char *);
8+
int builtin_id(char *);
9+
int builtin_mkdir(char *);
10+
int builtin_pwd(char *);
11+
int builtin_rm(char *);
12+
int builtin_rmdir(char *);
13+
int builtin_stat(char *);
14+
int builtin_touch(char *);
15+
int builtin_unmask(char *);
16+
const char *builtin_name[] = {"cat", "cd", "chmod", "echo", "exit",
17+
"find", "help", "id", "mkdir", "pwd",
18+
"rm", "rmdir", "stat", "touch", "unmask"};
19+
const int (*builtin_func[])(char *) = {
20+
&builtin_cat, &builtin_cd, &builtin_chmod, &builtin_echo,
21+
&builtin_exit, &builtin_find, &builtin_help, &builtin_id,
22+
&builtin_mkdir, &builtin_pwd, &builtin_rm, &builtin_rmdir,
23+
&builtin_stat, &builtin_touch, &builtin_unmask};

source.c

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
#include <stdio.h>
2+
#include <stdlib.h>
3+
#include <string.h>
4+
#include "builtin.h"
5+
6+
int EUID, EGID;
7+
int arg_parse(int, char **);
8+
void shell();
9+
int shell_exec(char *);
10+
11+
int main(int argc, char **argv) {
12+
if (arg_parse(argc, argv) == -1) {
13+
return EXIT_FAILURE;
14+
}
15+
16+
shell();
17+
18+
return EXIT_SUCCESS;
19+
}
20+
21+
int arg_parse(int argc, char **argv) {
22+
if (argc == 3) {
23+
// Q: shoud throw parsing error?
24+
EUID = atoi(argv[1]);
25+
EGID = atoi(argv[2]);
26+
return 0;
27+
}
28+
fprintf(stderr, "Usage: %s {UID} {GID}\n", argv[0]);
29+
return -1;
30+
}
31+
32+
void shell() {
33+
char *cmd = NULL;
34+
size_t len = 0;
35+
int eof = 0;
36+
do {
37+
printf("~> ");
38+
// Q: Can it be killed by C-c?
39+
eof = getline(&cmd, &len, stdin);
40+
if (eof != -1) eof = shell_exec(cmd);
41+
// cleanup
42+
free(cmd);
43+
cmd = NULL;
44+
len = 0;
45+
} while (eof != -1);
46+
}
47+
48+
int shell_exec(char *line) {
49+
char cmd[1024], extra[1024];
50+
if (sscanf(line, "%s %s", cmd, extra) == -1) return 0;
51+
const size_t len = sizeof(builtin_name) / sizeof(char *);
52+
for (size_t i = 0; i < len; ++i) {
53+
if (strcmp(cmd, builtin_name[i]) == 0) {
54+
int ret = (*builtin_func[i])(line);
55+
if (ret == 1) return -1;
56+
if (ret == -1) fprintf(stderr, "Too many arguments\n");
57+
return 0;
58+
}
59+
}
60+
fprintf(stderr, "Unknown command. Type 'help' for help\n");
61+
return 0;
62+
}

0 commit comments

Comments
 (0)