Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "../lib/operations.h"
- #include <stddef.h>
- #include <stdint.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- int get_index_parent_from_path(file_system *fs, char *path){
- //printf("ANFANG GET INDEX PARENT\n");
- //printf("PATH = %s\n", path);
- int index_current = fs->root_node; //fangen beim wurzel an
- //printf("INDEX CURRENT = %d\n", index_current);
- char* path_temp = strdup(path);
- char* token = NULL;
- char* last_token = (char *)strrchr(path_temp, '/')+1;
- //printf("last_token = %s\n", last_token);
- token = strtok(path_temp, "/");
- //printf("token = %s\n", token);
- if(last_token == token) {
- //printf("gleich, return 0\n");
- return 0;
- }
- //bei pfad /root/home/folder/...
- while (token!=last_token){ //durchlaufen path
- //printf("TOCKEN = %s\n", token);
- int flag = 0; //zeigt, ob wir das kind von current_node gefunden haben
- for (int i=0; i<DIRECT_BLOCKS_COUNT; i++){
- //printf("i = %d\n", i);
- int block_num = fs->inodes[index_current].direct_blocks[i]; //schauen in direct_blocks von root
- //printf("BLOCK_NUM = %d\n", block_num);
- //printf("index_current = %d\n", index_current);
- if (block_num != -1){ //if block exist
- if(fs->inodes[block_num].n_type == directory){ //schauen nur auf verzeichnisse
- if (strcmp(fs->inodes[block_num].name, token) == 0){ // wenn inodes name = home
- //printf("CHILD GEFUNDEN\n");
- index_current = block_num;
- flag = 1;
- token = strtok(NULL, "/");
- break; //for schleife beenden
- }
- }
- }
- else if(i>=DIRECT_BLOCKS_COUNT-1) flag = 0;
- }
- //printf("WEITER GEHTS\n");
- if(flag != 1){ //es wurde in current directory kein kind gefunden
- index_current = -1;
- break; // etwas schief, raus aus while schleife
- }
- }
- //printf("index_current = %d\n", index_current);
- free(path_temp);
- return index_current;
- }
- int get_index_from_path(file_system *fs, char *filename){
- char* filename_temp = strdup(filename);
- char* file_name = (char *)strrchr(filename_temp, '/')+1;
- int index_parent = get_index_parent_from_path(fs, filename);
- if (index_parent == -1) return -1;
- int index_file = -1;
- int exist = 0; //zeigt, ob die datei existiert
- for (int i = 0; i < fs->s_block->num_blocks; i++){
- int current_block_index = fs->inodes[index_parent].direct_blocks[i];
- //printf("current_block_index = %d\n", current_block_index);
- if (current_block_index !=-1){ //es gibt einen block, schauen rein
- //printf("current_block_name = %s\n", fs->inodes[current_block_index].name);
- if(strcmp(fs->inodes[current_block_index].name, file_name)==0){ //datei existiert
- index_file = current_block_index;
- break;
- }
- }
- }
- free(filename_temp);
- return index_file;
- }
- int set_kid(file_system* fs, int index_parent, int index_kind){
- //size of array direct_blocks
- for (int j = 0; j<DIRECT_BLOCKS_COUNT; j++){
- if (fs->inodes[index_parent].direct_blocks[j] == -1){ //no block
- fs->inodes[index_parent].direct_blocks[j] = index_kind;
- //printf("......\n");
- return 0;
- }
- }
- return -1;
- }
- void delete_kid(file_system* fs, int index_parent, int index_kind){
- //size of array direct_blocks
- for (int j = 0; j<DIRECT_BLOCKS_COUNT; j++){
- if (fs->inodes[index_parent].direct_blocks[j] == index_kind){ //child gefunden
- fs->inodes[index_parent].direct_blocks[j] = -1;
- }
- }
- }
- int find_free_datablock(file_system *fs){
- int block_num = -1;
- //data blocks in free list durchgehen
- for (int i = 0; i<fs->s_block->num_blocks; i++){
- if (fs->free_list[i] == 1){ //block free
- block_num = i;
- break; //free block mit geringstem index gefunden
- }
- }
- return block_num;
- }
- int write_in_datablock(file_system *fs, int file_index, int block_num, char* text, int flag, int size_text){ //flag zeigt, ob der block schon etwas enthaelt
- if (size_text < 0) size_text = strlen(text); //wenn die write funktion fuer binaries benutzt wird - keine strlen operation moeglich
- //entweder definieren wir size direkt, oder durch srlen wenn nicht fuer binaries
- int size_written = 0;
- int first_occupied_bytes = fs->data_blocks[block_num].size;
- //printf("size of first block = %d\n",first_occupied_bytes);
- int first_free_bytes = BLOCK_SIZE-first_occupied_bytes;
- int max_size_array = fs->s_block->free_blocks*BLOCK_SIZE+first_free_bytes; // anzahl freie bloecke * size eines blocks + freie bytes im ersten block
- int max_file_size_available = DIRECT_BLOCKS_COUNT * BLOCK_SIZE - fs->inodes[file_index].size;
- //maximale anzahl bits die belegt werden koennen
- //wenn size_text > max_size_array return NULL
- if ((size_text > max_size_array) || (size_text > max_file_size_available)) return -2;
- char* part_text = text;
- if(flag){ //block nicht leer
- int temp_size = size_text > first_free_bytes ? first_free_bytes : size_text; // wie viel wir schreiben
- memcpy(fs->data_blocks[block_num].block+first_occupied_bytes, part_text, temp_size);
- size_written += temp_size;
- fs->data_blocks[block_num].size = first_occupied_bytes+temp_size; //maximaler size fuer den block gesetzt
- part_text+=temp_size;
- size_text-=temp_size;
- if(size_text > 0){ //wenn etwas noch zu schreiben ist
- block_num = find_free_datablock(fs);
- if(block_num == -1) return -1; // und kein freier block gefunden
- }
- }
- int a = size_text/BLOCK_SIZE; //wie viele male passt text in block = vie viele bloecke man verwenden soll
- while(a > 0){ //gehen die blocks durch
- memcpy(fs->data_blocks[block_num].block, part_text, BLOCK_SIZE);
- size_written += BLOCK_SIZE;
- fs->data_blocks[block_num].size = BLOCK_SIZE; //maximaler size fuer den block gesetzt
- fs->free_list[block_num] = 0; //block is jz besetzt
- --fs->s_block->free_blocks;
- set_kid(fs,file_index,block_num);
- part_text+=BLOCK_SIZE;
- size_text-=BLOCK_SIZE;
- --a;
- if(size_text > 0){ //wenn etwas noch zu schreiben ist
- block_num = find_free_datablock(fs);
- if(block_num == -1) return -1; // und kein freier block gefunden
- }
- }
- if(size_text>0){ // wenn etwas uebrig geblieben ist
- memcpy(fs->data_blocks[block_num].block, part_text, size_text); //text in data kopieren
- size_written += size_text;
- fs->data_blocks[block_num].size = size_text;
- fs->free_list[block_num] = 0; //block is jz besetzt
- set_kid(fs,file_index,block_num);
- --fs->s_block->free_blocks;
- }
- return size_written; //wenn alles gut ist
- }
- int duplicate_directory(file_system *fs, int parent_index, char* path, enum node_type n_type){ //return 1 wenn directory schon existiert
- char* path_temp = strdup(path);
- char* child_name = (char *)strrchr(path_temp, '/')+1;
- for (int i=0; i<DIRECT_BLOCKS_COUNT; i++){
- int index_current = fs->inodes[parent_index].direct_blocks[i];
- if (index_current != -1){
- if((strcmp(fs->inodes[index_current].name, child_name) == 0) && (fs->inodes[index_current].n_type == n_type)){
- free(path_temp);
- return 1; //existiert bereits, also duplicate
- }
- }
- }
- free(path_temp);
- return 0;
- }
- int fs_mkdir(file_system *fs, char *path)
- {
- if (fs == NULL || path == NULL) return -1;
- if (path[0] != '/') return -1; //wenn path kein absoluter pfad ist
- int index_parent = get_index_parent_from_path(fs,path);
- if (index_parent == -1) return -1; //kein parent gefunden
- //pruefen ob es nicht schonmal ein ordner mit solchem namen gibt
- if(duplicate_directory(fs,index_parent,path,directory)) return -1;
- int index = find_free_inode(fs);
- if(index==-1) return -1; //es gibt keinen freien inode
- if(set_kid(fs, index_parent, index)) return -1;
- fs->inodes[index].n_type = directory; //type = directory
- fs->inodes[index].size = 0;
- strncpy(fs->inodes[index].name, strrchr(path, '/')+1, NAME_MAX_LENGTH);
- //printf("root index = %d\n", fs->root_node);
- //printf("index parent = %d\n", fs->root_node);
- fs->inodes[index].parent = index_parent;
- return 0; //wenn diese stelle erreicht alles gut
- }
- int
- fs_mkfile(file_system *fs, char *path_and_name)
- {
- if (fs == NULL || path_and_name == NULL){
- return -1;
- }
- if (path_and_name[0] != '/') return -1; //wenn path kein absoluter pfad ist
- int index_parent = get_index_parent_from_path(fs,path_and_name);
- if (index_parent == -1) return -1; //kein parent gefunden
- if(duplicate_directory(fs,index_parent,path_and_name,reg_file)) return -2;
- int index = find_free_inode(fs);
- if(index==-1) return -1; //es gibt keinen freien inode
- if(set_kid(fs, index_parent, index)) return -1;
- fs->inodes[index].n_type = reg_file; //type = directory
- fs->inodes[index].size = 0;
- strncpy(fs->inodes[index].name, strrchr(path_and_name, '/')+1, NAME_MAX_LENGTH);
- //printf("root index = %d\n", fs->root_node);
- //printf("index parent = %d\n", fs->root_node);
- fs->inodes[index].parent = index_parent;
- return 0; //wenn diese stelle erreicht alles gut
- }
- char *
- fs_list(file_system *fs, char *path)
- {
- if(fs == NULL || path == NULL) return NULL;
- int index_current = fs->root_node; //fangen beim wurzel an
- //printf("INDEX CURRENT = %d\n", index_current);
- char* path_temp = strdup(path);
- char* token = strtok(path_temp, "/");
- //bei pfad /root/home/folder/...
- while (token!=NULL){ //durchlaufen path
- //printf("TOCKEN = %s\n", token);
- int flag = 0; //zeigt, ob wir das kind von current_node gefunden haben
- for (int i=0; i<DIRECT_BLOCKS_COUNT; i++){
- //printf("i = %d\n", i);
- int block_num = fs->inodes[index_current].direct_blocks[i]; //schauen in direct_blocks von root
- //printf("BLOCK_NUM = %d\n", block_num);
- //printf("index_current = %d\n", index_current);
- if (block_num != -1){ //if block exist
- if(fs->inodes[block_num].n_type == directory){ //schauen nur auf verzeichnisse
- if (strcmp(fs->inodes[block_num].name, token) == 0){ // wenn inodes name = home
- //printf("CHILD GEFUNDEN\n");
- index_current = block_num;
- flag = 1;
- token = strtok(NULL, "/");
- break; //for schleife beenden
- }
- }
- }
- else if(i>=DIRECT_BLOCKS_COUNT-1) flag = 0;
- }
- //printf("WEITER GEHTS\n");
- if(flag != 1){ //es wurde in current directory kein kind gefunden
- index_current = -1;
- return NULL; // etwas schief, raus aus while schleife
- }
- }
- char* str = (char*)calloc(1,sizeof(char));
- for (int j = 0; j<fs->s_block->num_blocks; j++){
- if(fs->inodes[j].parent == index_current){
- if(fs->inodes[j].n_type == directory){
- str = (char*)realloc(str,5+strlen(str)+strnlen(fs->inodes[j].name, NAME_MAX_LENGTH));
- strcat(str, "DIR ");
- strcat(str, fs->inodes[j].name);
- strcat(str, "\n");
- }
- else if(fs->inodes[j].n_type == reg_file){
- str = (char*)realloc(str,5+strlen(str)+strnlen(fs->inodes[j].name, NAME_MAX_LENGTH));
- strcat(str, "FIL ");
- strcat(str, fs->inodes[j].name);
- strcat(str, "\n");
- }
- }
- }
- free(path_temp);
- return str;
- }
- int
- fs_nwritef(file_system* fs, char* filename, char* text, int size_text) //write funktion, die noch size_text benoetigt
- {
- int res = 0;
- if (fs == NULL || filename == NULL) return -1;
- int index_file = get_index_from_path(fs, filename);
- if (index_file == -1) return -1; //file nicht gefunden oder sein parent nicht gefunden
- int flag = 0; //zeigt, ob in datei schon etwas liegt
- int block_num; //nummer blocks in den geschrieben wird
- for (int j = 0; j < DIRECT_BLOCKS_COUNT; j++) {
- if (fs->inodes[index_file].direct_blocks[j] != -1) { //es gibt einen block schon - datei nicht leer
- flag = 1;
- block_num = fs->inodes[index_file].direct_blocks[j];
- res = write_in_datablock(fs, index_file, block_num, text, flag, size_text); //schreiben in/ab diesen datablock je nachdem ob size uebershritten. falls NULL returned - fehler, return -1
- break;
- }
- }
- if (!flag) { //wenn datei leer
- block_num = find_free_datablock(fs); //finden den kleinstmöglichen block
- //printf("block in den wir schreiben = %d\n", block_num);
- if (block_num == -1) return -1; //wenn freier block nicht gefunden
- res = write_in_datablock(fs, index_file, block_num, text, flag, size_text); //schreiben in/ab diesen datablock je nachdem ob size uebershritten. falls NULL returned - fehler, return -1
- }
- //size von file setzen
- int file_actual_size = 0;
- for(int i = 0; i < DIRECT_BLOCKS_COUNT; ++i) {
- if (fs->inodes[index_file].direct_blocks[i] != -1) {
- file_actual_size += fs->data_blocks[fs->inodes[index_file].direct_blocks[i]].size;
- }
- }
- fs->inodes[index_file].size = file_actual_size;
- return res; //wenn alles gut
- }
- int
- fs_writef(file_system *fs, char *filename, char *text)
- {
- return fs_nwritef(fs, filename, text, -1); //-1 weil wir nicht mit binaries arbeiten und size_text mit strlen spaeter bestimmen wollen
- }
- uint8_t *
- fs_readf(file_system *fs, char *filename, int *file_size)
- {
- //printf("ANFANG TEST\n");
- if(filename == NULL || fs == NULL) return NULL;
- int index_file = get_index_from_path(fs, filename);
- if (index_file == -1) return NULL; //file nicht gefunden oder parent nicht gefunden
- int total_size = 0;
- int leer = 1; //zeigt ob file leer ist
- //printf("start for schleife\n");
- for (int j = 0; j < DIRECT_BLOCKS_COUNT; j++){ //schauen in die daten, bestimmen size
- int current_data_block_index = fs->inodes[index_file].direct_blocks[j];
- //printf("current index of datablock = %d\n",current_data_block_index);
- if (current_data_block_index != -1){ //es liegt etwas im block
- data_block current_block = fs->data_blocks[current_data_block_index];
- leer = 0;
- //printf("size of this datablock = %d\n", current_block.size);
- total_size+=current_block.size;
- }
- }
- uint8_t* buffer = (uint8_t*)calloc(total_size,sizeof(uint8_t)); //memory allocate!!!!!!!
- int offs = 0;
- for (int j = 0; j < DIRECT_BLOCKS_COUNT; j++){ //schauen in die daten
- int current_data_block_index = fs->inodes[index_file].direct_blocks[j];
- //printf("current index of datablock = %d\n",current_data_block_index);
- if (current_data_block_index != -1){ //es liegt etwas im block
- data_block current_block = fs->data_blocks[current_data_block_index];
- memcpy(buffer+offs, current_block.block, current_block.size);
- offs+=current_block.size;
- //printf("buffer = %s\n",buffer);
- }
- //printf("---------------------------\n");
- }
- //printf("end for schleife\n");
- //printf("total size = %d\n", total_size);
- if (leer) return NULL;
- *file_size = total_size;
- //printf("%u", file_size);
- return buffer;
- }
- void fs_rm_aux(file_system *fs, int index){ //hilfefunktion fuer fs_rm
- if(fs->inodes[index].n_type == reg_file){ //wenn datei zu loeschen ist
- for (int j = 0; j < DIRECT_BLOCKS_COUNT; j++){ //schauen in die daten
- int current_data_block_index = fs->inodes[index].direct_blocks[j];
- if (current_data_block_index != -1){ //es liegt etwas im block
- data_block current_block = fs->data_blocks[current_data_block_index];
- current_block.size = 0;
- //current_block.block leeren
- fs->free_list[current_data_block_index] = 1; //kennzeichnen als free
- }
- }
- }
- else if(fs->inodes[index].n_type == directory){
- for (int j = 0; j < DIRECT_BLOCKS_COUNT; j++){ //schauen in die daten
- int current_block_index = fs->inodes[index].direct_blocks[j];
- if(current_block_index != -1){
- fs_rm_aux(fs,current_block_index);
- }
- }
- }
- inode_init(fs->inodes+index);
- }
- int
- fs_rm(file_system *fs, char *path)
- {
- if (fs == NULL || path == NULL) return -1;
- int index = get_index_from_path(fs, path);
- if (index == -1) return -1; // object oder sein parent nicht gefunden
- int index_parent = fs->inodes[index].parent;
- fs_rm_aux(fs, index);
- delete_kid(fs,index_parent,index);
- return 0;
- }
- int
- fs_import(file_system *fs, char *int_path, char *ext_path)
- {
- if(fs == NULL || int_path == NULL || ext_path == NULL) return -1;
- FILE* f = fopen(ext_path, "rb"); //read binaries; oeffnen externe datei um sie zu lesen
- if (f == NULL) return -1; // nicht gelungen file zu oefnen
- //size bekommen
- fseek(f, 0L, SEEK_END); //ende file finden
- int size_ext = ftell(f); // position des naechten nach dem letzten byte merken
- fseek(f, 0L, SEEK_SET); // zurueck drehen
- if (size_ext == 0){
- fclose(f);
- return 0;
- } //datei leer, kein fehler aber es gibt nichst zu schreiben
- uint8_t* buffer = (uint8_t*)calloc(size_ext + 1,sizeof(uint8_t)); //memory allocate!
- fread(buffer,1,size_ext, f);
- buffer[size_ext] = 0;
- fclose(f);
- int res = fs_nwritef(fs,int_path,buffer,size_ext); // wenn geschrieben wurde = size of char, wenn nicht - -1 oder -2
- free(buffer);
- return res < 0 ? -1: 0; //return 0 wenn write funktion 0 zurueckgibt (alles laeft gut) oder -1 wenn sie -1 oder -2 zurueckgibt
- }
- int
- fs_export(file_system *fs, char *int_path, char *ext_path)
- {
- if(fs == NULL || int_path == NULL || ext_path == NULL) return -1;
- int n_size = 0;
- uint8_t* buffer = fs_readf(fs,int_path,&n_size);
- if(buffer == NULL) return -1;
- FILE* f = fopen(ext_path, "wb"); //write binaries; oeffnen externe datei um in sie zu schreiben
- int val = 0;
- if(f){
- fwrite(buffer, 1, n_size, f);
- fclose(f);
- }
- else --val;
- free(buffer);
- return val;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement