Advertisement
madegoff

sysprog2ha

Jul 12th, 2023 (edited)
184
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 19.13 KB | None | 0 0
  1. #include "../lib/operations.h"
  2. #include <stddef.h>
  3. #include <stdint.h>
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <string.h>
  7.  
  8. int get_index_parent_from_path(file_system *fs, char *path){
  9.  
  10.     //printf("ANFANG GET INDEX PARENT\n");
  11.     //printf("PATH = %s\n", path);
  12.  
  13.     int index_current = fs->root_node; //fangen beim wurzel an
  14.     //printf("INDEX CURRENT = %d\n", index_current);
  15.     char* path_temp = strdup(path);
  16.  
  17.     char* token = NULL;
  18.     char* last_token = (char *)strrchr(path_temp, '/')+1;
  19.     //printf("last_token = %s\n", last_token);
  20.     token = strtok(path_temp, "/");
  21.     //printf("token = %s\n", token);
  22.     if(last_token == token) {
  23.             //printf("gleich, return 0\n");
  24.             return 0;
  25.     }
  26.     //bei pfad /root/home/folder/...
  27.  
  28.     while (token!=last_token){ //durchlaufen path
  29.  
  30.         //printf("TOCKEN = %s\n", token);
  31.  
  32.         int flag = 0; //zeigt, ob wir das kind von current_node gefunden haben
  33.  
  34.         for (int i=0; i<DIRECT_BLOCKS_COUNT; i++){
  35.  
  36.             //printf("i = %d\n", i);
  37.  
  38.             int block_num = fs->inodes[index_current].direct_blocks[i]; //schauen in direct_blocks von root
  39.  
  40.             //printf("BLOCK_NUM = %d\n", block_num);
  41.                 //printf("index_current = %d\n", index_current);
  42.  
  43.             if (block_num != -1){ //if block exist
  44.                 if(fs->inodes[block_num].n_type == directory){ //schauen nur auf verzeichnisse
  45.  
  46.                     if (strcmp(fs->inodes[block_num].name, token) == 0){ // wenn inodes name = home
  47.  
  48.                         //printf("CHILD GEFUNDEN\n");
  49.                         index_current = block_num;
  50.                         flag = 1;
  51.                         token = strtok(NULL, "/");
  52.                         break; //for schleife beenden
  53.                     }
  54.                 }
  55.             }
  56.             else if(i>=DIRECT_BLOCKS_COUNT-1) flag = 0;
  57.         }
  58.         //printf("WEITER GEHTS\n");
  59.  
  60.         if(flag != 1){ //es wurde in current directory kein kind gefunden
  61.             index_current = -1;
  62.             break; // etwas schief, raus aus while schleife
  63.         }
  64.     }
  65.     //printf("index_current = %d\n", index_current);
  66.     free(path_temp);
  67.     return index_current;
  68. }
  69.  
  70. int get_index_from_path(file_system *fs, char *filename){
  71.  
  72.     char* filename_temp = strdup(filename);
  73.     char* file_name = (char *)strrchr(filename_temp, '/')+1;
  74.  
  75.     int index_parent = get_index_parent_from_path(fs, filename);
  76.     if (index_parent == -1) return -1;
  77.     int index_file = -1;
  78.  
  79.     int exist = 0; //zeigt, ob die datei existiert
  80.  
  81.     for (int i = 0; i < fs->s_block->num_blocks; i++){
  82.  
  83.         int current_block_index = fs->inodes[index_parent].direct_blocks[i];
  84.         //printf("current_block_index = %d\n", current_block_index);
  85.         if (current_block_index !=-1){ //es gibt einen block, schauen rein
  86.             //printf("current_block_name = %s\n", fs->inodes[current_block_index].name);
  87.             if(strcmp(fs->inodes[current_block_index].name, file_name)==0){ //datei existiert
  88.                 index_file = current_block_index;
  89.                 break;
  90.             }
  91.         }
  92.     }
  93.     free(filename_temp);
  94.     return index_file;
  95. }
  96.  
  97. int set_kid(file_system* fs, int index_parent, int index_kind){
  98.  
  99.     //size of array direct_blocks
  100.         for (int j = 0; j<DIRECT_BLOCKS_COUNT; j++){
  101.                 if (fs->inodes[index_parent].direct_blocks[j] == -1){ //no block
  102.                         fs->inodes[index_parent].direct_blocks[j] = index_kind;
  103.                         //printf("......\n");
  104.                         return 0;
  105.                 }
  106.             }
  107.         return -1;
  108. }
  109.  
  110. void delete_kid(file_system* fs, int index_parent, int index_kind){
  111.  
  112.     //size of array direct_blocks
  113.         for (int j = 0; j<DIRECT_BLOCKS_COUNT; j++){
  114.                 if (fs->inodes[index_parent].direct_blocks[j] == index_kind){ //child gefunden
  115.                         fs->inodes[index_parent].direct_blocks[j] = -1;
  116.                 }
  117.             }
  118. }
  119.  
  120. int find_free_datablock(file_system *fs){
  121.  
  122.     int block_num = -1;
  123.     //data blocks in free list durchgehen
  124.     for (int i = 0; i<fs->s_block->num_blocks; i++){
  125.  
  126.         if (fs->free_list[i] == 1){ //block free
  127.             block_num = i;
  128.             break; //free block mit geringstem index gefunden
  129.         }
  130.     }
  131.  
  132.     return block_num;
  133.  
  134. }
  135.  
  136. 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
  137.  
  138.     if (size_text < 0) size_text = strlen(text); //wenn die write funktion fuer binaries benutzt wird - keine strlen operation moeglich
  139.     //entweder definieren wir size direkt, oder durch srlen wenn nicht fuer binaries
  140.     int size_written = 0;
  141.  
  142.     int first_occupied_bytes = fs->data_blocks[block_num].size;
  143.     //printf("size of first block = %d\n",first_occupied_bytes);
  144.  
  145.     int first_free_bytes = BLOCK_SIZE-first_occupied_bytes;
  146.  
  147.     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
  148.     int max_file_size_available = DIRECT_BLOCKS_COUNT * BLOCK_SIZE - fs->inodes[file_index].size;
  149.     //maximale anzahl bits die belegt werden koennen
  150.  
  151.     //wenn size_text > max_size_array return NULL
  152.     if ((size_text > max_size_array) || (size_text > max_file_size_available)) return -2;
  153.  
  154.     char* part_text = text;
  155.  
  156.     if(flag){ //block nicht leer
  157.  
  158.         int temp_size = size_text > first_free_bytes ? first_free_bytes : size_text; // wie viel wir schreiben
  159.  
  160.         memcpy(fs->data_blocks[block_num].block+first_occupied_bytes, part_text, temp_size);
  161.         size_written += temp_size;
  162.  
  163.         fs->data_blocks[block_num].size = first_occupied_bytes+temp_size; //maximaler size fuer den block gesetzt
  164.         part_text+=temp_size;
  165.         size_text-=temp_size;
  166.  
  167.         if(size_text > 0){ //wenn etwas noch zu schreiben ist
  168.             block_num = find_free_datablock(fs);
  169.             if(block_num == -1) return -1; // und kein freier block gefunden
  170.         }
  171.  
  172.     }
  173.  
  174.     int a = size_text/BLOCK_SIZE; //wie viele male passt text in block = vie viele bloecke man verwenden soll
  175.  
  176.     while(a > 0){ //gehen die blocks durch
  177.  
  178.         memcpy(fs->data_blocks[block_num].block, part_text, BLOCK_SIZE);
  179.         size_written += BLOCK_SIZE;
  180.  
  181.         fs->data_blocks[block_num].size = BLOCK_SIZE; //maximaler size fuer den block gesetzt
  182.         fs->free_list[block_num] = 0; //block is jz besetzt
  183.         --fs->s_block->free_blocks;
  184.         set_kid(fs,file_index,block_num);
  185.  
  186.         part_text+=BLOCK_SIZE;
  187.         size_text-=BLOCK_SIZE;
  188.         --a;
  189.  
  190.         if(size_text > 0){ //wenn etwas noch zu schreiben ist
  191.             block_num = find_free_datablock(fs);
  192.             if(block_num == -1) return -1; // und kein freier block gefunden
  193.         }
  194.     }
  195.  
  196.  
  197.     if(size_text>0){ // wenn etwas uebrig geblieben ist
  198.  
  199.         memcpy(fs->data_blocks[block_num].block, part_text, size_text); //text in data kopieren
  200.         size_written += size_text;
  201.  
  202.         fs->data_blocks[block_num].size = size_text;
  203.         fs->free_list[block_num] = 0; //block is jz besetzt
  204.         set_kid(fs,file_index,block_num);
  205.         --fs->s_block->free_blocks;
  206.     }
  207.     return size_written; //wenn alles gut ist
  208. }
  209.  
  210. int duplicate_directory(file_system *fs, int parent_index, char* path, enum node_type n_type){ //return 1 wenn directory schon existiert
  211.  
  212.     char* path_temp = strdup(path);
  213.     char* child_name = (char *)strrchr(path_temp, '/')+1;
  214.     for (int i=0; i<DIRECT_BLOCKS_COUNT; i++){
  215.         int index_current = fs->inodes[parent_index].direct_blocks[i];
  216.         if (index_current != -1){
  217.             if((strcmp(fs->inodes[index_current].name, child_name) == 0) && (fs->inodes[index_current].n_type == n_type)){
  218.                 free(path_temp);
  219.                 return 1; //existiert bereits, also duplicate
  220.             }
  221.         }
  222.     }
  223.     free(path_temp);
  224.     return 0;
  225. }
  226.  
  227. int fs_mkdir(file_system *fs, char *path)
  228. {
  229.     if (fs == NULL || path == NULL) return -1;
  230.  
  231.     if (path[0] != '/') return -1; //wenn path kein absoluter pfad ist
  232.  
  233.     int index_parent = get_index_parent_from_path(fs,path);
  234.     if (index_parent == -1) return -1; //kein parent gefunden
  235.  
  236.     //pruefen ob es nicht schonmal ein ordner mit solchem namen gibt
  237.     if(duplicate_directory(fs,index_parent,path,directory)) return -1;
  238.  
  239.     int index = find_free_inode(fs);
  240.  
  241.     if(index==-1) return -1; //es gibt keinen freien inode
  242.  
  243.     if(set_kid(fs, index_parent, index)) return -1;
  244.     fs->inodes[index].n_type = directory; //type = directory
  245.     fs->inodes[index].size = 0;
  246.     strncpy(fs->inodes[index].name, strrchr(path, '/')+1, NAME_MAX_LENGTH);
  247.  
  248.     //printf("root index = %d\n", fs->root_node);
  249.     //printf("index parent = %d\n", fs->root_node);
  250.  
  251.     fs->inodes[index].parent = index_parent;
  252.  
  253.     return 0; //wenn diese stelle erreicht alles gut
  254. }
  255.  
  256. int
  257. fs_mkfile(file_system *fs, char *path_and_name)
  258. {
  259.     if (fs == NULL || path_and_name == NULL){
  260.         return -1;
  261.     }
  262.  
  263.     if (path_and_name[0] != '/') return -1; //wenn path kein absoluter pfad ist
  264.  
  265.     int index_parent = get_index_parent_from_path(fs,path_and_name);
  266.     if (index_parent == -1) return -1; //kein parent gefunden
  267.  
  268.     if(duplicate_directory(fs,index_parent,path_and_name,reg_file)) return -2;
  269.  
  270.     int index = find_free_inode(fs);
  271.  
  272.     if(index==-1) return -1; //es gibt keinen freien inode
  273.  
  274.     if(set_kid(fs, index_parent, index)) return -1;
  275.     fs->inodes[index].n_type = reg_file; //type = directory
  276.     fs->inodes[index].size = 0;
  277.     strncpy(fs->inodes[index].name, strrchr(path_and_name, '/')+1, NAME_MAX_LENGTH);
  278.  
  279.     //printf("root index = %d\n", fs->root_node);
  280.     //printf("index parent = %d\n", fs->root_node);
  281.  
  282.     fs->inodes[index].parent = index_parent;
  283.  
  284.     return 0; //wenn diese stelle erreicht alles gut
  285. }
  286.  
  287. char *
  288. fs_list(file_system *fs, char *path)
  289. {
  290.     if(fs == NULL || path == NULL) return NULL;
  291.  
  292.     int index_current = fs->root_node; //fangen beim wurzel an
  293.     //printf("INDEX CURRENT = %d\n", index_current);
  294.     char* path_temp = strdup(path);
  295.     char* token = strtok(path_temp, "/");
  296.  
  297.     //bei pfad /root/home/folder/...
  298.  
  299.     while (token!=NULL){ //durchlaufen path
  300.  
  301.         //printf("TOCKEN = %s\n", token);
  302.  
  303.         int flag = 0; //zeigt, ob wir das kind von current_node gefunden haben
  304.  
  305.         for (int i=0; i<DIRECT_BLOCKS_COUNT; i++){
  306.  
  307.             //printf("i = %d\n", i);
  308.  
  309.             int block_num = fs->inodes[index_current].direct_blocks[i]; //schauen in direct_blocks von root
  310.  
  311.             //printf("BLOCK_NUM = %d\n", block_num);
  312.                 //printf("index_current = %d\n", index_current);
  313.  
  314.             if (block_num != -1){ //if block exist
  315.                 if(fs->inodes[block_num].n_type == directory){ //schauen nur auf verzeichnisse
  316.  
  317.                     if (strcmp(fs->inodes[block_num].name, token) == 0){ // wenn inodes name = home
  318.  
  319.                         //printf("CHILD GEFUNDEN\n");
  320.                         index_current = block_num;
  321.                         flag = 1;
  322.                         token = strtok(NULL, "/");
  323.                         break; //for schleife beenden
  324.                     }
  325.                 }
  326.             }
  327.             else if(i>=DIRECT_BLOCKS_COUNT-1) flag = 0;
  328.         }
  329.         //printf("WEITER GEHTS\n");
  330.  
  331.         if(flag != 1){ //es wurde in current directory kein kind gefunden
  332.             index_current = -1;
  333.  
  334.             return NULL; // etwas schief, raus aus while schleife
  335.         }
  336.     }
  337.     char* str = (char*)calloc(1,sizeof(char));
  338.     for (int j = 0; j<fs->s_block->num_blocks; j++){
  339.  
  340.         if(fs->inodes[j].parent == index_current){
  341.             if(fs->inodes[j].n_type == directory){
  342.                 str = (char*)realloc(str,5+strlen(str)+strnlen(fs->inodes[j].name, NAME_MAX_LENGTH));
  343.                 strcat(str, "DIR ");
  344.                 strcat(str, fs->inodes[j].name);
  345.                 strcat(str, "\n");
  346.             }
  347.             else if(fs->inodes[j].n_type == reg_file){
  348.                 str = (char*)realloc(str,5+strlen(str)+strnlen(fs->inodes[j].name, NAME_MAX_LENGTH));
  349.                 strcat(str, "FIL ");
  350.                 strcat(str, fs->inodes[j].name);
  351.                 strcat(str, "\n");
  352.             }
  353.         }
  354.     }
  355.     free(path_temp);
  356.     return str;
  357. }
  358.  
  359. int
  360. fs_nwritef(file_system* fs, char* filename, char* text, int size_text) //write funktion, die noch size_text benoetigt
  361. {
  362.     int res = 0;
  363.  
  364.     if (fs == NULL || filename == NULL) return -1;
  365.  
  366.     int index_file = get_index_from_path(fs, filename);
  367.     if (index_file == -1) return -1; //file nicht gefunden oder sein parent nicht gefunden
  368.  
  369.     int flag = 0; //zeigt, ob in datei schon etwas liegt
  370.     int block_num; //nummer blocks in den geschrieben wird
  371.  
  372.     for (int j = 0; j < DIRECT_BLOCKS_COUNT; j++) {
  373.  
  374.         if (fs->inodes[index_file].direct_blocks[j] != -1) { //es gibt einen block schon - datei nicht leer
  375.  
  376.             flag = 1;
  377.             block_num = fs->inodes[index_file].direct_blocks[j];
  378.             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
  379.             break;
  380.         }
  381.     }
  382.  
  383.     if (!flag) { //wenn datei leer
  384.  
  385.         block_num = find_free_datablock(fs); //finden den kleinstmöglichen block
  386.         //printf("block in den wir schreiben = %d\n", block_num);
  387.         if (block_num == -1) return -1; //wenn freier block nicht gefunden
  388.         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
  389.     }
  390.  
  391.     //size von file setzen
  392.  
  393.     int file_actual_size = 0;
  394.     for(int i = 0; i < DIRECT_BLOCKS_COUNT; ++i) {
  395.     if (fs->inodes[index_file].direct_blocks[i] != -1) {
  396.         file_actual_size += fs->data_blocks[fs->inodes[index_file].direct_blocks[i]].size;
  397.     }
  398.     }
  399.     fs->inodes[index_file].size = file_actual_size;
  400.  
  401.     return res; //wenn alles gut
  402.  
  403. }
  404.  
  405.  
  406. int
  407. fs_writef(file_system *fs, char *filename, char *text)
  408. {
  409.     return fs_nwritef(fs, filename, text, -1); //-1 weil wir nicht mit binaries arbeiten und size_text mit strlen spaeter bestimmen wollen
  410. }
  411.  
  412. uint8_t *
  413. fs_readf(file_system *fs, char *filename, int *file_size)
  414. {
  415.     //printf("ANFANG TEST\n");
  416.     if(filename == NULL || fs == NULL) return NULL;
  417.  
  418.     int index_file = get_index_from_path(fs, filename);
  419.     if (index_file == -1) return NULL; //file nicht gefunden oder parent nicht gefunden
  420.  
  421.     int total_size = 0;
  422.     int leer = 1; //zeigt ob file leer ist
  423.     //printf("start for schleife\n");
  424.  
  425.     for (int j = 0; j < DIRECT_BLOCKS_COUNT; j++){ //schauen in die daten, bestimmen size
  426.  
  427.         int current_data_block_index = fs->inodes[index_file].direct_blocks[j];
  428.         //printf("current index of datablock = %d\n",current_data_block_index);
  429.         if (current_data_block_index != -1){ //es liegt etwas im block
  430.             data_block current_block = fs->data_blocks[current_data_block_index];
  431.             leer = 0;
  432.             //printf("size of this datablock = %d\n", current_block.size);
  433.             total_size+=current_block.size;
  434.  
  435.         }
  436.     }
  437.  
  438.     uint8_t* buffer = (uint8_t*)calloc(total_size,sizeof(uint8_t)); //memory allocate!!!!!!!
  439.  
  440.     int offs = 0;
  441.  
  442.     for (int j = 0; j < DIRECT_BLOCKS_COUNT; j++){ //schauen in die daten
  443.  
  444.         int current_data_block_index = fs->inodes[index_file].direct_blocks[j];
  445.         //printf("current index of datablock = %d\n",current_data_block_index);
  446.         if (current_data_block_index != -1){ //es liegt etwas im block
  447.             data_block current_block = fs->data_blocks[current_data_block_index];
  448.  
  449.             memcpy(buffer+offs, current_block.block, current_block.size);
  450.             offs+=current_block.size;
  451.             //printf("buffer = %s\n",buffer);
  452.         }
  453.         //printf("---------------------------\n");
  454.     }
  455.     //printf("end for schleife\n");
  456.     //printf("total size = %d\n", total_size);
  457.     if (leer) return NULL;
  458.     *file_size = total_size;
  459.     //printf("%u", file_size);
  460.     return buffer;
  461. }
  462.  
  463. void fs_rm_aux(file_system *fs, int index){ //hilfefunktion fuer fs_rm
  464.  
  465.     if(fs->inodes[index].n_type == reg_file){ //wenn datei zu loeschen ist
  466.  
  467.         for (int j = 0; j < DIRECT_BLOCKS_COUNT; j++){ //schauen in die daten
  468.  
  469.             int current_data_block_index = fs->inodes[index].direct_blocks[j];
  470.             if (current_data_block_index != -1){ //es liegt etwas im block
  471.  
  472.                 data_block current_block = fs->data_blocks[current_data_block_index];
  473.                 current_block.size = 0;
  474.                 //current_block.block leeren
  475.                 fs->free_list[current_data_block_index] = 1; //kennzeichnen als free
  476.             }
  477.         }
  478.     }
  479.  
  480.     else if(fs->inodes[index].n_type == directory){
  481.  
  482.         for (int j = 0; j < DIRECT_BLOCKS_COUNT; j++){ //schauen in die daten
  483.  
  484.             int current_block_index = fs->inodes[index].direct_blocks[j];
  485.  
  486.             if(current_block_index != -1){
  487.  
  488.                 fs_rm_aux(fs,current_block_index);
  489.             }
  490.         }
  491.     }
  492.     inode_init(fs->inodes+index);
  493. }
  494.  
  495. int
  496. fs_rm(file_system *fs, char *path)
  497. {
  498.     if (fs == NULL || path == NULL) return -1;
  499.  
  500.     int index = get_index_from_path(fs, path);
  501.     if (index == -1) return -1; // object oder sein parent nicht gefunden
  502.     int index_parent = fs->inodes[index].parent;
  503.  
  504.     fs_rm_aux(fs, index);
  505.  
  506.     delete_kid(fs,index_parent,index);
  507.  
  508.     return 0;
  509. }
  510.  
  511. int
  512. fs_import(file_system *fs, char *int_path, char *ext_path)
  513. {
  514.     if(fs == NULL || int_path == NULL || ext_path == NULL) return -1;
  515.     FILE* f = fopen(ext_path, "rb"); //read binaries; oeffnen externe datei um sie zu lesen
  516.     if (f == NULL) return -1; // nicht gelungen file zu oefnen
  517.  
  518.     //size bekommen
  519.     fseek(f, 0L, SEEK_END); //ende file finden
  520.     int size_ext = ftell(f); // position des naechten nach dem letzten byte merken
  521.     fseek(f, 0L, SEEK_SET); // zurueck drehen
  522.  
  523.     if (size_ext == 0){
  524.         fclose(f);
  525.         return 0;
  526.     }  //datei leer, kein fehler aber es gibt nichst zu schreiben
  527.  
  528.     uint8_t* buffer = (uint8_t*)calloc(size_ext + 1,sizeof(uint8_t)); //memory allocate!
  529.  
  530.     fread(buffer,1,size_ext, f);
  531.     buffer[size_ext] = 0;
  532.     fclose(f);
  533.  
  534.     int res = fs_nwritef(fs,int_path,buffer,size_ext); // wenn geschrieben wurde = size of char, wenn nicht - -1 oder -2
  535.  
  536.     free(buffer);
  537.     return res < 0 ? -1: 0; //return 0 wenn write funktion 0 zurueckgibt (alles laeft gut) oder -1 wenn sie -1 oder -2 zurueckgibt
  538. }
  539.  
  540. int
  541. fs_export(file_system *fs, char *int_path, char *ext_path)
  542. {
  543.     if(fs == NULL || int_path == NULL || ext_path == NULL) return -1;
  544.  
  545.     int n_size = 0;
  546.     uint8_t* buffer = fs_readf(fs,int_path,&n_size);
  547.     if(buffer == NULL) return -1;
  548.  
  549.     FILE* f = fopen(ext_path, "wb"); //write binaries; oeffnen externe datei um in sie zu schreiben
  550.     int val = 0;
  551.     if(f){
  552.         fwrite(buffer, 1, n_size, f);
  553.         fclose(f);
  554.     }
  555.     else --val;
  556.     free(buffer);
  557.     return val;
  558. }
  559.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement