shell and ls command
This commit is contained in:
parent
ba12753402
commit
a43436b20b
2
Makefile
2
Makefile
@ -1,7 +1,7 @@
|
||||
NAME := seyshell
|
||||
DRIVE := disk
|
||||
CC := gcc
|
||||
CFLAGS :=
|
||||
CFLAGS := -Wall -Wextra -Werror -g
|
||||
OBJ_DIR := obj
|
||||
SRC_DIR := src
|
||||
|
||||
|
||||
@ -7,6 +7,5 @@
|
||||
|
||||
#define TYPE_NULL 0
|
||||
#define TYPE_FILE 1
|
||||
#define TYPE_BINARY 2
|
||||
#define TYPE_DIRECTORY 3
|
||||
#define TYPE_SYMBOLIC_LINK 4
|
||||
133
src/disk.c
133
src/disk.c
@ -1,5 +1,6 @@
|
||||
/** @file */
|
||||
#include "disk.h"
|
||||
#include "env.h"
|
||||
#include "struct.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@ -48,15 +49,12 @@ int find_offset_in_parent_bloc(bloc *parent_bloc) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int create_directory(disk *disk, inode *parent, char *dirname) {}
|
||||
|
||||
int create_file(disk *disk, inode *parent, char *filename) {
|
||||
int allocate_node(disk *disk, inode *parent, char *name, char type) {
|
||||
int inode_index = 0;
|
||||
while (inode_index < MAX_INODE &&
|
||||
disk->inodes[inode_index].filetype != TYPE_NULL) {
|
||||
inode_index++;
|
||||
}
|
||||
|
||||
if (inode_index >= MAX_INODE) {
|
||||
dprintf(STDERR_FILENO, "No free inodes\n");
|
||||
return -1;
|
||||
@ -70,46 +68,42 @@ int create_file(disk *disk, inode *parent, char *filename) {
|
||||
|
||||
int p_bloc_idx = parent->blocs[0];
|
||||
int offset = find_offset_in_parent_bloc(&disk->blocs[p_bloc_idx]);
|
||||
|
||||
if (offset == -1) {
|
||||
dprintf(STDERR_FILENO, "Parent directory full\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
strncpy(&disk->blocs[p_bloc_idx].datas[offset], filename, MAX_INODE_NAME);
|
||||
strncpy(&disk->blocs[p_bloc_idx].datas[offset], name, MAX_INODE_NAME);
|
||||
memcpy(&disk->blocs[p_bloc_idx].datas[offset + MAX_INODE_NAME], &inode_index,
|
||||
sizeof(int));
|
||||
|
||||
init_inode_in_disk(disk, inode_index, TYPE_FILE, 0b111111111, new_bloc_idx);
|
||||
init_inode_in_disk(disk, inode_index, type, 0b111111111, new_bloc_idx);
|
||||
|
||||
return inode_index;
|
||||
}
|
||||
|
||||
int create_inode(disk *disk, inode *parent, char inode_type, char *name) {
|
||||
if (strlen(name) > MAX_INODE_NAME) {
|
||||
dprintf(STDERR_FILENO, "A inode name must be < %d\n", MAX_INODE_NAME);
|
||||
return -1;
|
||||
}
|
||||
if (parent->filetype != TYPE_DIRECTORY) {
|
||||
dprintf(STDERR_FILENO, "A parent's inode must be a directory!\n");
|
||||
return -1;
|
||||
}
|
||||
int create_file(disk *disk, inode *parent, char *filename) {
|
||||
return allocate_node(disk, parent, filename, TYPE_FILE);
|
||||
}
|
||||
|
||||
switch (inode_type) {
|
||||
case TYPE_DIRECTORY:
|
||||
return create_directory(disk, parent, name);
|
||||
break;
|
||||
case TYPE_FILE:
|
||||
return create_file(disk, parent, name);
|
||||
case TYPE_BINARY:
|
||||
// TODO plus tard
|
||||
break;
|
||||
case TYPE_SYMBOLIC_LINK:
|
||||
// TODO plus tard
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return -1;
|
||||
int create_directory(disk *disk, inode *parent, char *dirname) {
|
||||
int new_idx = allocate_node(disk, parent, dirname, TYPE_DIRECTORY);
|
||||
|
||||
if (new_idx == -1)
|
||||
return -1;
|
||||
|
||||
int bloc_idx = disk->inodes[new_idx].blocs[0];
|
||||
int entry_size = MAX_INODE_NAME + sizeof(int);
|
||||
int p_idx = (int)(parent - disk->inodes);
|
||||
|
||||
strncpy(&disk->blocs[bloc_idx].datas[0], ".", MAX_INODE_NAME);
|
||||
memcpy(&disk->blocs[bloc_idx].datas[MAX_INODE_NAME], &new_idx, sizeof(int));
|
||||
|
||||
strncpy(&disk->blocs[bloc_idx].datas[entry_size], "..", MAX_INODE_NAME);
|
||||
memcpy(&disk->blocs[bloc_idx].datas[entry_size + MAX_INODE_NAME], &p_idx,
|
||||
sizeof(int));
|
||||
|
||||
return new_idx;
|
||||
}
|
||||
|
||||
void write_in_file(disk *d, int file_index, char *data /*, char mode*/) {
|
||||
@ -133,15 +127,60 @@ void write_in_file(disk *d, int file_index, char *data /*, char mode*/) {
|
||||
strncpy(&d->blocs[bloc_index_to_overwrite].datas[0], data, strlen(data));
|
||||
}
|
||||
|
||||
void do_ls(disk *d, int dir_index) {
|
||||
inode dir = d->inodes[dir_index];
|
||||
if (dir.filetype != TYPE_DIRECTORY) {
|
||||
dprintf(STDERR_FILENO, "ls: Can only list in directories\n");
|
||||
return;
|
||||
int find_dir_inode_by_name(char *name, int dir_index, disk *d) {
|
||||
|
||||
int bloc = d->inodes[dir_index].blocs[0];
|
||||
|
||||
for (int i = 0; i < MAX_BYTES_PER_BLOC; i += MAX_INODE_NAME + sizeof(int)) {
|
||||
char inode_name[MAX_INODE_NAME];
|
||||
strncpy(inode_name, &d->blocs[bloc].datas[i], MAX_INODE_NAME);
|
||||
if (strcmp(name, inode_name) == 0) {
|
||||
int inode_id;
|
||||
memcpy(&inode_id, &d->blocs[bloc].datas[i + MAX_INODE_NAME], sizeof(int));
|
||||
return inode_id;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: chercher sur tous les blocs possédés
|
||||
int bloc = dir.blocs[0];
|
||||
return -1;
|
||||
}
|
||||
|
||||
int do_ls(disk *d, char *path) {
|
||||
char *path_to_process;
|
||||
|
||||
if (path == NULL) {
|
||||
path_to_process = strdup(get_env_value("PWD"));
|
||||
} else {
|
||||
path_to_process = strdup(path);
|
||||
}
|
||||
|
||||
int dir_index = 0;
|
||||
char *token = strtok(path_to_process, "/");
|
||||
|
||||
while (token != NULL) {
|
||||
dir_index = find_dir_inode_by_name(token, dir_index, d);
|
||||
|
||||
if (dir_index == -1) {
|
||||
dprintf(STDERR_FILENO, "ls: This directory does not exist\n");
|
||||
free(path_to_process);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (d->inodes[dir_index].filetype != TYPE_DIRECTORY) {
|
||||
dprintf(STDERR_FILENO, "ls: '%s' is not a directory\n", token);
|
||||
free(path_to_process);
|
||||
return -1;
|
||||
}
|
||||
|
||||
token = strtok(NULL, "/");
|
||||
}
|
||||
|
||||
inode dir_to_list = d->inodes[dir_index];
|
||||
int bloc = dir_to_list.blocs[0];
|
||||
|
||||
if (bloc == -1) {
|
||||
free(path_to_process);
|
||||
return 1;
|
||||
}
|
||||
|
||||
for (int i = 0; i < MAX_BYTES_PER_BLOC; i += MAX_INODE_NAME + sizeof(int)) {
|
||||
if (d->blocs[bloc].datas[i] != '\0') {
|
||||
@ -150,6 +189,9 @@ void do_ls(disk *d, int dir_index) {
|
||||
dprintf(STDOUT_FILENO, "%-16s %d\n", &d->blocs[bloc].datas[i], inode_id);
|
||||
}
|
||||
}
|
||||
|
||||
free(path_to_process);
|
||||
return 1;
|
||||
}
|
||||
|
||||
char *read_in_file(disk *d, int file_index) {
|
||||
@ -163,7 +205,8 @@ char *read_in_file(disk *d, int file_index) {
|
||||
int bloc = file.blocs[0];
|
||||
char *out;
|
||||
int c_index = 0;
|
||||
while (d->blocs[bloc].datas[c_index] != '\0' || c_index < MAX_BYTES_PER_BLOC) {
|
||||
while (d->blocs[bloc].datas[c_index] != '\0' ||
|
||||
c_index < MAX_BYTES_PER_BLOC) {
|
||||
c_index++;
|
||||
}
|
||||
|
||||
@ -178,9 +221,11 @@ char *read_in_file(disk *d, int file_index) {
|
||||
return out;
|
||||
}
|
||||
|
||||
void init_env_var_file(disk *d) {
|
||||
int inode_idx = create_inode(d, &d->inodes[0], TYPE_FILE, "env");
|
||||
write_in_file(d, inode_idx, "PWD=/\nUSER=user");
|
||||
void init_test_files(disk *d) {
|
||||
int inode_idx = create_file(d, &d->inodes[0], "test");
|
||||
write_in_file(d, inode_idx, "Contenu du fichier :)\n");
|
||||
int dir_idx = create_directory(d, &d->inodes[0], "dir");
|
||||
create_file(d, &d->inodes[dir_idx], "test1");
|
||||
}
|
||||
|
||||
/**
|
||||
@ -211,7 +256,7 @@ disk create_disk() {
|
||||
d.inodes[0].blocs[0] = 0; // utilise le bloc 0
|
||||
d.owned_blocs[0] = 1; // le bloc 1 est maintenant occupé
|
||||
|
||||
init_env_var_file(&d);
|
||||
init_test_files(&d);
|
||||
|
||||
int n = fwrite(&d, sizeof(disk), 1, fptr);
|
||||
if (n == 1) {
|
||||
|
||||
@ -5,7 +5,8 @@
|
||||
#include "const.h"
|
||||
#include "struct.h"
|
||||
#include <string.h>
|
||||
#include "env.h"
|
||||
|
||||
disk create_disk();
|
||||
disk open_disk(char* filename);
|
||||
void do_ls(disk *d, int dir_index);
|
||||
int do_ls(disk *d, char* path);
|
||||
47
src/env.c
Normal file
47
src/env.c
Normal file
@ -0,0 +1,47 @@
|
||||
#include "env.h"
|
||||
|
||||
env *init_envs() {
|
||||
env *envs = malloc(sizeof(env) * 3);
|
||||
|
||||
if (envs == NULL)
|
||||
return NULL;
|
||||
|
||||
envs[0].key = "PWD";
|
||||
envs[0].value = "/";
|
||||
|
||||
envs[1].key = "USER";
|
||||
envs[1].value = "guams";
|
||||
|
||||
envs[2].key = "HOST";
|
||||
envs[2].value = "tartempion";
|
||||
|
||||
return envs;
|
||||
}
|
||||
|
||||
env *get_instance() {
|
||||
static env *instance = NULL;
|
||||
|
||||
if (instance == NULL) {
|
||||
instance = init_envs();
|
||||
}
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
int get_env_len(env *envs) {
|
||||
int i = 0;
|
||||
while (envs[i].key != NULL) {
|
||||
i++;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
char *get_env_value(char *key) {
|
||||
env *envs = get_instance();
|
||||
for (int i = 0; i < get_env_len(envs); i++) {
|
||||
if (strcmp(envs[i].key, key) == 0) {
|
||||
return envs[i].value;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
8
src/env.h
Normal file
8
src/env.h
Normal file
@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
#include "struct.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
char* get_env_value(char* key);
|
||||
int get_env_len(env *envs);
|
||||
env* init_envs();
|
||||
35
src/exec.c
35
src/exec.c
@ -1,18 +1,13 @@
|
||||
/** @file */
|
||||
#include "exec.h"
|
||||
#include "disk.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
// TODO : Tout ce fichier est à changer je pense
|
||||
|
||||
int is_builtin_cmd(char *executable) {
|
||||
(void)executable;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// à changer parce que je veux pas chercher dans le PATH, je veux juste executer
|
||||
// les futures primitives qui seront implémentées
|
||||
int execute_cmd(char **args) {
|
||||
/*int execute_cmd(char **args) {
|
||||
if (!is_builtin_cmd(args[0])) {
|
||||
int pid = fork();
|
||||
if (pid == -1)
|
||||
@ -30,4 +25,28 @@ int execute_cmd(char **args) {
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
*/
|
||||
|
||||
int child_process_job(disk *d, char **args) {
|
||||
if (strcmp("ls", args[0]) == 0) {
|
||||
do_ls(d, args[1]);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int execute_cmd(disk *d, char **args) {
|
||||
int pid = fork();
|
||||
|
||||
if (pid == 1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (pid == 0) {
|
||||
child_process_job(d, args);
|
||||
} else {
|
||||
int status;
|
||||
waitpid(pid, &status, WUNTRACED);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@ -1,7 +1,8 @@
|
||||
/** @file */
|
||||
#pragma once
|
||||
#include "disk.h"
|
||||
#include <stdio.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
int is_builtin_cmd(char *executable);
|
||||
int execute_cmd(char **args);
|
||||
int execute_cmd(disk *d, char **args);
|
||||
11
src/main.c
11
src/main.c
@ -1,24 +1,17 @@
|
||||
/** @file */
|
||||
#include "disk.h"
|
||||
#include "parsing.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
int main(int argc, char *argv[], char *envp[]) {
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
(void)envp;
|
||||
|
||||
// shell_loop();
|
||||
int main() {
|
||||
|
||||
disk drive;
|
||||
if (access("disk", F_OK) == 0) {
|
||||
drive = open_disk("disk");
|
||||
do_ls(&drive, 0);
|
||||
} else
|
||||
drive = create_disk();
|
||||
|
||||
(void)drive;
|
||||
open_seyshell(&drive);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
@ -1,6 +1,7 @@
|
||||
/** @file */
|
||||
#include "parsing.h"
|
||||
#include "const.h"
|
||||
#include "env.h"
|
||||
#include "exec.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@ -15,6 +16,8 @@
|
||||
char *read_line() {
|
||||
char c;
|
||||
int i = 0;
|
||||
|
||||
// buffer overflow attention
|
||||
char *buffer = malloc(BUFSIZE * sizeof(char));
|
||||
if (buffer == NULL) {
|
||||
dprintf(STDERR_FILENO, "Line read buffer allocation error !");
|
||||
@ -70,15 +73,14 @@ char **split_line(char *line) {
|
||||
* @see char** split_line(char *line)
|
||||
* @see int execute_cmd(char **args)
|
||||
*/
|
||||
void shell_loop(void) {
|
||||
char *user = getenv("USER");
|
||||
void shell_loop(disk *disk) {
|
||||
char *user = get_env_value("USER");
|
||||
|
||||
char *hostname = malloc(BUFSIZE * sizeof(char));
|
||||
if (hostname == NULL) {
|
||||
dprintf(STDERR_FILENO, "Allocation error");
|
||||
if (user == NULL) {
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
// sur le sgf le hostname se récupèrera pas comme ça donc à changer :)
|
||||
gethostname(hostname, sizeof(hostname));
|
||||
|
||||
char *hostname = get_env_value("HOST");
|
||||
|
||||
char *line;
|
||||
char **args;
|
||||
@ -86,13 +88,19 @@ void shell_loop(void) {
|
||||
|
||||
do {
|
||||
// ça aussi c'est pas bien, ça sera à changer une fois le sgf fonctionnel
|
||||
dprintf(STDOUT_FILENO, "%s@%s %s> ", user, hostname, getenv("PWD"));
|
||||
dprintf(STDOUT_FILENO, "%s@%s %s> ", user, hostname, get_env_value("PWD"));
|
||||
line = read_line();
|
||||
args = split_line(line);
|
||||
status = execute_cmd(args);
|
||||
status = execute_cmd(disk, args);
|
||||
|
||||
free(line);
|
||||
free(args);
|
||||
} while (status);
|
||||
}
|
||||
|
||||
void open_seyshell(disk* disk) {
|
||||
env* envs = init_envs();
|
||||
shell_loop(disk);
|
||||
free(envs);
|
||||
}
|
||||
|
||||
|
||||
@ -1,7 +1,9 @@
|
||||
/** @file */
|
||||
#pragma once
|
||||
#include "env.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include "struct.h"
|
||||
|
||||
void shell_loop(void);
|
||||
void open_seyshell(disk* disk);
|
||||
@ -2,6 +2,11 @@
|
||||
#pragma once
|
||||
#include "const.h"
|
||||
|
||||
typedef struct env {
|
||||
char* key;
|
||||
char* value;
|
||||
} env;
|
||||
|
||||
/**
|
||||
* @struct inode
|
||||
* @brief Un inode est un fichier, il possède des permissions, un type
|
||||
|
||||
Loading…
Reference in New Issue
Block a user