Riferimenti per il file util.c

#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)

Descrizione dettagliata

Autore:
Tranchida Giulio, No Matricola 241732
Si dichiara che il contenuto di questo file e', in ogni sua parte, opera originale dell'autore.

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.


Documentazione delle funzioni

static int percorso ( FILE *  fs,
struct fat_ctrl f_ctrl,
char *  path 
) [static]

Percorso

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.

Parametri:
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.
Restituisce:
  • EBDP (Error Bad Directory Path) se il path specificato non e' assoluto, ossia non inizia con il carattere '/'
  • ENTL (Error Name Too Long) uno degli elementi del pathname supera la lunghezza consentita (MAX_LEN_NAME).
  • ENSFD (Error Not Such File or Directory) se un elemento del pah non siste o non e' una directory.
  • ENMSD (Error No More Space on Device) se non ci sono piu' blocchi disponibili e quindi ci troviamo in una condizione di Filesystem Full.
  • ERFCD (Error Reading Fat Control Data) se si verifica un errore leggendo le strutture di controllo del filesystem Fat.
  • EWFCD (Error Writing Fat Control Data) se si verifica un errore durante la scrittura delle strutture di controllo del filesystem Fat.
  • ERDB (Error Reading Block Data) se si verifica un errore di lettura su un blocco della Data Region
  • EDAEX (Error File/Directory Already Exists) se si verifica che il file o la cartella esiste gia'.
  • SDLIBERROR se si verifica un altro tipo di errore generico.
  • 0 (zero) in caso di successo

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 }

int parsing ( FILE *  fs,
struct fat_ctrl f_ctrl,
char *  path,
Action  azione 
)

Parsing

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.

Parametri:
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.
Restituisce:
  • EBDP (Error Bad Directory Path) se il path specificato non e' assoluto, ossia non inizia con il carattere '/'
  • ENTL (Error Name Too Long) uno degli elementi del pathname supera la lunghezza consentita (MAX_LEN_NAME).
  • ENSFD (Error Not Such File or Directory) se un elemento del pah non siste o non e' una directory.
  • ENMSD (Error No More Space on Device) se non ci sono piu' blocchi disponibili e quindi ci troviamo in una condizione di Filesystem Full.
  • ERFCD (Error Reading Fat Control Data) se si verifica un errore leggendo le strutture di controllo del filesystem Fat.
  • EWFCD (Error Writing Fat Control Data) se si verifica un errore durante la scrittura delle strutture di controllo del filesystem Fat.
  • ERDB (Error Reading Block Data) se si verifica un errore di lettura su un blocco della Data Region
  • EDAEX (Error File/Directory Already Exists) se si verifica che il file o la cartella esiste gia'.
  • SDLIBERROR se si verifica un altro tipo di errore generico.
  • 0 (zero) in caso di successo

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 }

int find ( FILE *  fs,
struct fat_ctrl f_ctrl,
char *  path,
Action  azione 
)

Find

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.

Parametri:
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.
Restituisce:
  • EBDP (Error Bad Directory Path) se il path specificato non e' assoluto, ossia non inizia con il carattere '/'
  • ENTL (Error Name Too Long) uno degli elementi del pathname supera la lunghezza consentita (MAX_LEN_NAME).
  • ENSFD (Error Not Such File or Directory) se un elemento del pah non siste o non e' una directory.
  • ENMSD (Error No More Space on Device) se non ci sono piu' blocchi disponibili e quindi ci troviamo in una condizione di Filesystem Full.
  • ERFCD (Error Reading Fat Control Data) se si verifica un errore leggendo le strutture di controllo del filesystem Fat.
  • EWFCD (Error Writing Fat Control Data) se si verifica un errore durante la scrittura delle strutture di controllo del filesystem Fat.
  • ERDB (Error Reading Block Data) se si verifica un errore di lettura su un blocco della Data Region
  • EDAEX (Error File/Directory Already Exists) se si verifica che il file o la cartella esiste gia'.
  • SDLIBERROR se si verifica un altro tipo di errore generico.
  • 0 (zero) in caso di successo

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 }

Generato il Fri Jan 28 22:16:31 2011 per SFAT: Simplified File Allocation Table Project da  doxygen 1.6.3