#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <libgen.h>
#include <string.h>
#include "Include/fat.h"
#include "Include/util.h"
#include "Include/sfaterror.h"
Vai al codice sorgente di questo file.
Funzioni | |
static int | percorso (FILE *fs, struct fat_ctrl *f_ctrl, char *path) |
int | parsing (FILE *fs, struct fat_ctrl *f_ctrl, char *path, Action azione) |
int | find (FILE *fs, struct fat_ctrl *f_ctrl, char *path, Action azione) |
This program is free software; you can redistribuite it and/or modify it under the terms of the GNU/General Pubblic License as published the Free software Foundation; either version 2 of the License, or (at your opinion) any later version.
Definizione nel file util.c.
static int percorso | ( | FILE * | fs, | |
struct fat_ctrl * | f_ctrl, | |||
char * | path | |||
) | [static] |
Funzione ricorsiva - parsing effettivo della path
Questa funzione scinde il path in 'path element', richiamandosi ricorsivamente fin tanto che il caso base non e' verificato.
Caso base: path element == ".", o path element == "/".
In fase di chiusura la funzione richiama su ogni path element scisso, la funzione find, controllando sempre che il valore di ritorno sia zero.
Se il valore di ritorno e' diverso da zero, siamo in un caso di errore e la funzione ritorna, chiudendo tutte le sue istanze, l'errore al chiamante.
fs | il FILE pointer che consente di acceddre al file dove il filesystem e' memorizzato. | |
f_ctrl | puntatore alla struttura che mantiene tutte le informazioni di controllo del filesystem. | |
path | la stringa che contiene il path assoluto del file che deve essere creato. |
Definizione alla linea 104 del file util.c.
00104 { 00105 char *dirc, *basec, *bname, *dname; 00106 int ret_val = 0; 00107 00108 if (!(fs) || !(f_ctrl) || !(path) ) return EBDP; 00109 if (!(dirc = strdup(path))) return STDLIBERR; 00110 if (!(basec = strdup(path))) return STDLIBERR; 00111 dname = dirname(dirc); 00112 bname = basename(basec); 00113 00114 if (strlen(bname) > MAX_LEN_NAME) ret_val = ENTL; 00115 00116 if (!ret_val && strcmp(dname, ".") && strcmp(dname, "/")) 00117 ret_val = percorso(fs, f_ctrl, dname); 00118 00119 if (!ret_val && !strcmp(dname, ".")) ret_val = EBDP; 00120 if (!ret_val) ret_val = find(fs, f_ctrl, bname, LS); 00121 00122 free(dirc); 00123 free(basec); 00124 return ret_val; 00125 }
Questa funzione ha come obbiettivo eseguire il parsing della “path”, controllando che il percorso sia corretto ed esistente, lasciando il file pointer del filesystem “fs” nel punto più opportuno per la funzione chiamante.
Per ulteriori approfondimenti sulla funzione riferirsi alla relazione sul progetto.
fs | il FILE pointer che consente di acceddre al file dove il filesystem e' memorizzato. | |
f_ctrl | puntatore alla struttura che mantiene tutte le informazioni di controllo del filesystem. | |
path | la stringa che contiene il path assoluto del file che deve essere creato. | |
azione | l'azione che deve essere intrapesa dalla funzione, specializzando il comportamento della funzione a seconda delle esigenze. |
Definizione alla linea 66 del file util.c.
00066 { 00067 char *dirc, *basec, *bname, *dname; 00068 int ret_val; 00069 00070 if (!(fs) || !(f_ctrl) || !(path)) return EBDP; 00071 00072 /* Metto il puntatore fs all'inizio della data region */ 00073 fseek(fs, f_ctrl->blk_base, SEEK_SET); 00074 00075 /* Faccio una copia della path */ 00076 if (!(dirc = strdup(path))) return STDLIBERR; 00077 /* Elimino l'ultimo 'path element' */ 00078 dname = dirname(dirc); 00079 ret_val = percorso(fs, f_ctrl, dname); 00080 00081 free(dirc); 00082 if (ret_val) return ret_val; 00083 00084 /* Reperisco l'ultimo 'path element' */ 00085 if (!(basec = strdup(path))) return STDLIBERR; 00086 bname = basename(basec); 00087 if (strlen(bname)>MAX_LEN_NAME){free(basec); return ENTL;} 00088 00089 switch(azione){ 00090 case LS: /* ritorna settando 'fs' sull'entry della cartella cercata */ 00091 case RDFILE:/* ritorna settando 'fs' sull'entry del file cercato */ 00092 case WRFILE:/* ritorna settando 'fs' sull'entry del file cercato */ 00093 ret_val = find(fs, f_ctrl, bname, azione); 00094 break; 00095 case MKFILE: 00096 case MKDIR: 00097 ; 00098 break; 00099 } 00100 free(basec); 00101 return ret_val; 00102 }
Questa funzione ha come obbiettivo eseguire il parsing della “path”, controllando che il percorso sia corretto ed esistente, lasciando il file pointer del filesystem “fs” nel punto più opportuno per la funzione chiamante.
Per ulteriori approfondimenti sulla funzione riferirsi alla relazione sul progetto.
fs | il FILE pointer che consente di acceddre al file dove il filesystem e' memorizzato. | |
f_ctrl | puntatore alla struttura che mantiene tutte le informazioni di controllo del filesystem. | |
path | la stringa che contiene il path assoluto del file che deve essere creato. | |
azione | l'azione che deve essere intrapesa dalla funzione, specializzando il comportamento della funzione a seconda delle esigenze. |
Definizione alla linea 128 del file util.c.
00128 { 00129 struct dir_entry cart_p; 00130 int numero_entry, i, j, MAX_ENTRY; 00131 unsigned int indice_fat, new_index; 00132 long fs_pos; 00133 00134 if (!(fs) || !(f_ctrl) || !(path)) return EBDP; 00135 /* Se sono nella radice ritorna */ 00136 if ((azione==LS) && !strcmp(path, "/")) return 0; 00137 /* Calcolo qual'e' il numero massimo di entry memorizzabile in un 00138 * blocco, in realazione alla dimensione del blocco stesso */ 00139 MAX_ENTRY = f_ctrl->b_sector.block_size/sizeof(struct dir_entry); 00140 00141 fs_pos = ftell(fs); 00142 /* Leggo la dir_entry "." */ 00143 if (!(fread(&cart_p, sizeof(struct dir_entry), 1, fs))) return ERBD; 00144 numero_entry = cart_p.len/sizeof(struct dir_entry); 00145 /* Ricorda l'indice della fat memorizzato nel blocco della entry iniziale '.' 00146 * della cartella in cui noi stiamo ciclando */ 00147 indice_fat = cart_p.index; 00148 if (indice_fat > f_ctrl->b_sector.num_block) return ERFCD; 00149 00150 /* Relative path navigation "/." (Solo in caso di listing delle cartelle) */ 00151 if ((azione==LS) && !strcmp(cart_p.name, path) && (cart_p.attr == SUB_ENTRY)){ 00152 fseek(fs, fs_pos, SEEK_SET); 00153 return 0; 00154 } 00155 00156 for (i=1, j=1; i<numero_entry; i++, j++){ 00157 if (j==MAX_ENTRY){ 00158 /* Ho letto tutte le entry del blocco. 00159 * Devo controllare il blocco DATA REGION successivo nella fat */ 00160 if (f_ctrl->fat_ptr[indice_fat] == BLOCK_FREE) return ERFCD; 00161 if (f_ctrl->fat_ptr[indice_fat] == LAST_BLOCK) return ERFCD; 00162 /* La posizione successiva di 'fs' e' uguale a blk_base + 00163 * la posizione indicata nell'array della FAT * la dimensione dei blocchi. */ 00164 fs_pos = f_ctrl->blk_base + f_ctrl->fat_ptr[indice_fat] * f_ctrl->b_sector.block_size; 00165 fseek(fs, fs_pos, SEEK_SET); 00166 /* Aggiorno l'indice della FAT col nuovo valore memorizzato nella locazione stessa della FAT */ 00167 indice_fat = f_ctrl->fat_ptr[indice_fat]; 00168 /* if (indice_fat > f_ctrl->b_sector.num_block) return ERFCD; */ 00169 j=1; 00170 } 00171 /* Salvo la posizione dell'entry del file. Utile solo per le azioni WRFILE e RDFILE */ 00172 fs_pos = ftell(fs); 00173 /* Leggo la dir_entry successiva */ 00174 if (!(fread(&cart_p, sizeof(struct dir_entry), 1, fs))) return ERBD; 00175 /* Ho trovato il nome che cercavo ed e' una cartella (condizione di uscita) */ 00176 if ((azione==LS) && !strcmp(cart_p.name, path) && (cart_p.attr == SUB_ENTRY)) break; 00177 /* Ho trovato il nome che cercavo ed e' una cartella ma non avrei dovuto trovarlo!! */ 00178 if ((azione==MKDIR) && !strcmp(cart_p.name, path) && (cart_p.attr ==SUB_ENTRY)) return EDAEX; 00179 /* Ho trovato il nome che cercavo ed e' un file ma non avrei dovuto trovarlo!! */ 00180 if ((azione==MKFILE) && !strcmp(cart_p.name, path) && (cart_p.attr==FILE_ENTRY)) return EDAEX; 00181 /* Ho trovato il nome che cercavo ed e' un file (condizione di uscita) */ 00182 if ((azione==WRFILE || azione==RDFILE) && !strcmp(cart_p.name, path) && (cart_p.attr==FILE_ENTRY)) break; 00183 } 00184 00185 switch(azione){ 00186 case LS: 00187 /* Cartella non trovata (Error Not Such File or Directory) */ 00188 if (strcmp(cart_p.name, path)) return ENSFD; 00189 else if (!strcmp(cart_p.name, path) && (cart_p.attr==FILE_ENTRY)) return ENSFD; 00190 /* Posiziono il file pointer fs all'inizio del blocco che contiene la prima 00191 * porzione della Directory Table relativa alla cartella cercata */ 00192 fs_pos = f_ctrl->blk_base + cart_p.index * f_ctrl->b_sector.block_size; 00193 fseek(fs, fs_pos, SEEK_SET); 00194 break; 00195 case RDFILE: 00196 case WRFILE: 00197 /* File non trovato (Error Not Such File or Directory) */ 00198 if (strcmp(cart_p.name, path) || (cart_p.attr!=FILE_ENTRY)) return ENSFD; 00199 /* Posiziono il file pointer fs all'inizio dell'entry del file su cui devo 00200 * andare a scrivere (o a leggere) */ 00201 fseek(fs, fs_pos, SEEK_SET); 00202 break; 00203 case MKFILE: 00204 case MKDIR: 00205 /* La funzione ritorna settando 'fs' sul primo spazio vuoto del blocco dalla 00206 * data region di modo che la write della nuova entry sia nel punto corretto */ 00207 if (j==MAX_ENTRY){ 00208 /* Cerco un nuovo indice di blocco libero nella FAT */ 00209 for (new_index=0; new_index<f_ctrl->b_sector.num_block; new_index++) 00210 if (f_ctrl->fat_ptr[new_index] == BLOCK_FREE) break; 00211 if (new_index>=f_ctrl->b_sector.num_block) return ENMSD; 00212 /* Imposto il blocco libero trovato della FAT ad LAST_BLOCK. */ 00213 f_ctrl->fat_ptr[new_index] = LAST_BLOCK; 00214 fs_pos = f_ctrl->blk_base + new_index * f_ctrl->b_sector.block_size; 00215 /* Aggiorno la locazione della fat puntata dal vecchio indice */ 00216 f_ctrl->fat_ptr[indice_fat]= new_index; 00217 /* Setto il puntatore 'fs' al nuovo blocco libero della fat */ 00218 fseek(fs, fs_pos, SEEK_SET); 00219 } 00220 break; 00221 } 00222 return 0; 00223 }