00001
00013 #include <stdio.h>
00014 #include <stdlib.h>
00015 #include <errno.h>
00016 #include <libgen.h>
00017 #include <string.h>
00018
00019 #include "Include/fat.h"
00020 #include "Include/util.h"
00021 #include "Include/sfaterror.h"
00022
00064 static int percorso(FILE *fs, struct fat_ctrl *f_ctrl, char *path);
00065
00066 int parsing(FILE *fs, struct fat_ctrl *f_ctrl, char *path, Action azione){
00067 char *dirc, *basec, *bname, *dname;
00068 int ret_val;
00069
00070 if (!(fs) || !(f_ctrl) || !(path)) return EBDP;
00071
00072
00073 fseek(fs, f_ctrl->blk_base, SEEK_SET);
00074
00075
00076 if (!(dirc = strdup(path))) return STDLIBERR;
00077
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
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:
00091 case RDFILE:
00092 case WRFILE:
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 }
00103
00104 static int percorso(FILE *fs, struct fat_ctrl *f_ctrl, char *path){
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 }
00126
00127
00128 int find(FILE *fs, struct fat_ctrl *f_ctrl, char *path, Action azione){
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
00136 if ((azione==LS) && !strcmp(path, "/")) return 0;
00137
00138
00139 MAX_ENTRY = f_ctrl->b_sector.block_size/sizeof(struct dir_entry);
00140
00141 fs_pos = ftell(fs);
00142
00143 if (!(fread(&cart_p, sizeof(struct dir_entry), 1, fs))) return ERBD;
00144 numero_entry = cart_p.len/sizeof(struct dir_entry);
00145
00146
00147 indice_fat = cart_p.index;
00148 if (indice_fat > f_ctrl->b_sector.num_block) return ERFCD;
00149
00150
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
00159
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
00163
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
00167 indice_fat = f_ctrl->fat_ptr[indice_fat];
00168
00169 j=1;
00170 }
00171
00172 fs_pos = ftell(fs);
00173
00174 if (!(fread(&cart_p, sizeof(struct dir_entry), 1, fs))) return ERBD;
00175
00176 if ((azione==LS) && !strcmp(cart_p.name, path) && (cart_p.attr == SUB_ENTRY)) break;
00177
00178 if ((azione==MKDIR) && !strcmp(cart_p.name, path) && (cart_p.attr ==SUB_ENTRY)) return EDAEX;
00179
00180 if ((azione==MKFILE) && !strcmp(cart_p.name, path) && (cart_p.attr==FILE_ENTRY)) return EDAEX;
00181
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
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
00191
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
00198 if (strcmp(cart_p.name, path) || (cart_p.attr!=FILE_ENTRY)) return ENSFD;
00199
00200
00201 fseek(fs, fs_pos, SEEK_SET);
00202 break;
00203 case MKFILE:
00204 case MKDIR:
00205
00206
00207 if (j==MAX_ENTRY){
00208
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
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
00216 f_ctrl->fat_ptr[indice_fat]= new_index;
00217
00218 fseek(fs, fs_pos, SEEK_SET);
00219 }
00220 break;
00221 }
00222 return 0;
00223 }