]> git.llucax.com Git - z.facultad/75.06/emufs.git/blob - emufs/emufs.c
* BUGFIX : Estaba siendo olvidado verificar de no sobrepasar
[z.facultad/75.06/emufs.git] / emufs / emufs.c
1 /* vim: set noexpandtab tabstop=4 shiftwidth=4:
2  *----------------------------------------------------------------------------
3  *                                  emufs
4  *----------------------------------------------------------------------------
5  * This file is part of emufs.
6  *
7  * emufs is free software; you can redistribute it and/or modify it under the
8  * terms of the GNU General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option) any later
10  * version.
11  *
12  * emufs is distributed in the hope that it will be useful, but WITHOUT ANY
13  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
15  * details.
16  *
17  * You should have received a copy of the GNU General Public License along
18  * with emufs; if not, write to the Free Software Foundation, Inc., 59 Temple
19  * Place, Suite 330, Boston, MA  02111-1307  USA
20  *----------------------------------------------------------------------------
21  * Creado:  mié mar 31 17:26:46 ART 2004
22  * Autores: Nicolás Dimov <sagardua@uolsinectis.com.ar>
23  *          Ricardo Markiewicz <rmarkie@fi.uba.ar>
24  *          Leandro Lucarella <llucare@fi.uba.ar>
25  *----------------------------------------------------------------------------
26  *
27  * $Id$
28  *
29  */
30
31 /** \file
32  *
33  * Estructura general de un archivo <em>abstracto</em> de emufs.
34  * 
35  * Implementación de la estructura abstracta que representa cualquiera de los
36  * tipos de archivo implementados. Se incluyen funciones tipo <em>factory</em>
37  * para crear un archivo, abrirlo y destruirlo.
38  *
39  */
40
41 #include "emufs.h"
42 #include "tipo1.h"
43 #include "tipo2.h"
44 #include "tipo3.h"
45 #include "did.h"
46 #include "fsc.h"
47 #include "idx.h"
48
49 char *str_dup(const char *s);
50
51 char *str_dup(const char *s)
52 {
53         char *tmp;
54         if (s == NULL) return NULL;
55         tmp = (char *)malloc(sizeof(char)*(strlen(s)+1));
56         strcpy(tmp, s);
57         return tmp;
58 }
59
60 int emufs_crear_archivo_auxiliar(const char* name, const char* ext)
61 {
62         FILE* f;
63         char* filename;
64
65         filename = (char*) malloc(sizeof(char) * (strlen(name) + strlen(ext) + 1));
66         if (filename == NULL) {
67                 /* TODO Manejo de errores */
68                 return -1;
69         }
70         strcpy(filename, name);
71         strcat(filename, ext);
72         f = fopen(filename, "w");
73         free(filename);
74         if (f == NULL) {
75                 /* TODO Manejo de errores */
76                 return -1;
77         }
78         fclose(f);
79         return 0;
80 }
81
82 EMUFS *emufs_crear(const char *filename, EMUFS_Tipo tipo, EMUFS_BLOCK_SIZE tam_bloque, EMUFS_REG_SIZE tam_reg)
83 {
84         char name[255];
85         FILE *fp;
86         EMUFS *efs;
87         int err = 0;
88
89         /* Si no es un tipo conocido, sale. */
90         if ((tipo != T1) && (tipo != T2) && (tipo != T3)) {
91                 return NULL;
92         }
93
94         /* Inicializa parámetros comunes. */
95         efs = (EMUFS*) malloc(sizeof(EMUFS));
96         if (efs == NULL) {
97                 return NULL;
98         }
99         efs->tipo = tipo;
100         efs->tam_bloque = tam_bloque;
101         efs->tam_reg = tam_reg;
102         efs->nombre = str_dup(filename);
103
104         /* Abre archivo de datos. */
105         strcpy(name, filename);
106         strcat(name, ".dat");
107         fp = fopen(name, "w");
108         if (fp == NULL) {
109                 /* TODO ERROR */
110                 free(efs->nombre);
111                 free(efs);
112                 return NULL;
113         }
114
115         /* Guarda cabecera común. */
116         fwrite(&tipo, sizeof(EMUFS_Tipo), 1, fp);
117
118         /* Crea archivo de índice. */
119         if (emufs_idx_crear(efs)) {
120                 /* TODO ERROR */
121                 free(efs->nombre);
122                 free(efs);
123                 return NULL;
124         }
125
126         /* Crea archivo de control de espacio libre. */
127         if (emufs_fsc_crear(efs)) {
128                 /* TODO ERROR */
129                 free(efs->nombre);
130                 free(efs);
131                 return NULL;
132         }
133
134         /* Crea archivo de identificadores borrados (recuperables). */
135         if (emufs_did_crear(efs)) {
136                 /* TODO ERROR */
137                 free(efs->nombre);
138                 free(efs);
139                 return NULL;
140         }
141
142         /* Termina de realizar el trabajo según el tipo de archivo. */
143         switch (tipo) {
144
145                 case T1:
146                         /* Asigna punteros a funciones. */
147                         if ((err = emufs_tipo1_inicializar(efs))) {
148                                 PERR("No se pudo inicializar el EMUFS de tipo1");
149                                 free(efs->nombre);
150                                 free(efs);
151                                 return NULL;
152                         }
153
154                         /* Guarda cabeceras propias. */
155                         fwrite(&tam_bloque, sizeof(EMUFS_BLOCK_SIZE), 1, fp);
156
157                         break;
158
159                 case T2:
160                         /* Asigna punteros a funciones. */
161                         emufs_tipo2_inicializar(efs);
162                         break;
163
164                 case T3:
165                         /* Asigna punteros a funciones. */
166                         efs->leer_bloque = emufs_tipo3_leer_bloque;
167                         efs->leer_registro = emufs_tipo3_leer_registro;
168                         efs->leer_registro_raw = emufs_tipo3_leer_registro_raw;
169                         efs->grabar_registro = emufs_tipo3_grabar_registro;
170                         efs->borrar_registro = emufs_tipo3_borrar_registro;
171                         efs->leer_estadisticas = emufs_tipo3_leer_estadisticas;
172                         efs->modificar_registro = emufs_tipo3_modificar_registro;
173                         efs->compactar = emufs_tipo3_compactar;
174                         efs->leer_bloque_raw = emufs_tipo3_leer_bloque_raw;
175                         /* Guarda cabeceras propias. */
176                         fwrite(&tam_bloque, sizeof(EMUFS_BLOCK_SIZE), 1, fp);
177                         fwrite(&tam_reg, sizeof(EMUFS_REG_SIZE), 1, fp);                        
178                         break;
179
180         }
181
182         fclose(fp);
183         return efs;
184 }
185
186 EMUFS *emufs_abrir(const char *filename)
187 {
188         EMUFS *efs;
189         char name[255];
190         char tipo;
191         FILE *fp;
192         int err = 0;
193
194         strcpy(name, filename);
195         strcat(name, ".dat");
196
197         /* Trato de determinar el tipo de archivo */
198         fp = fopen(name, "r");
199         if (fp == NULL) return NULL;
200         fread(&tipo, sizeof(EMUFS_Tipo), 1, fp);
201
202         /* Si no es un tipo conocido, sale. */
203         if ((tipo != T1) && (tipo != T2) && (tipo != T3)) {
204                 fclose(fp);
205                 return NULL;
206         }
207         
208         /* Inicializa parámetros comunes. */
209         efs = (EMUFS*) malloc(sizeof(EMUFS));
210         if (efs == NULL) {
211                 fclose(fp);
212                 return NULL;
213         }
214         efs->tipo = tipo;
215         efs->nombre = str_dup(filename);
216         
217         switch (tipo) {
218                 case T1:
219                         /* Lee cabeceras propias. */
220                         if (!fread(&(efs->tam_bloque), sizeof(EMUFS_BLOCK_SIZE), 1, fp)) {
221                                 free(efs->nombre);
222                                 free(efs);
223                                 fclose(fp);
224                                 return NULL;
225                         }
226                         /* Asigna punteros a funciones. */
227                         if ((err = emufs_tipo1_inicializar(efs))) {
228                                 PERR("No se pudo inicializar el EMUFS de tipo1");
229                                 fclose(fp);
230                                 return NULL;
231                         }
232                         break;
233                 case T2:
234                         /* Asigna punteros a funciones. */
235                         emufs_tipo2_inicializar(efs);                   
236                         break;
237                 case T3:
238                         if ((!fread(&(efs->tam_bloque), sizeof(EMUFS_BLOCK_SIZE), 1, fp)) ||
239                            (!fread(&(efs->tam_reg), sizeof(EMUFS_REG_SIZE), 1, fp)))
240                                 {
241                                 free(efs->nombre);
242                                 free(efs);
243                                 fclose(fp);
244                                 return NULL;
245                         }                       
246                         /* Asigna punteros a funciones. */                      
247                         efs->leer_bloque = emufs_tipo3_leer_bloque;
248                         efs->leer_registro_raw = emufs_tipo3_leer_registro_raw;
249                         efs->leer_registro = emufs_tipo3_leer_registro;
250                         efs->grabar_registro = emufs_tipo3_grabar_registro;
251                         efs->borrar_registro = emufs_tipo3_borrar_registro;
252                         efs->leer_estadisticas = emufs_tipo3_leer_estadisticas;
253                         efs->modificar_registro = emufs_tipo3_modificar_registro;
254                         efs->compactar = emufs_tipo3_compactar;
255                         efs->leer_bloque_raw = emufs_tipo3_leer_bloque_raw;
256                         break;
257         }
258
259         fclose(fp);
260         return efs;
261 }
262
263 int emufs_destruir(EMUFS *e)
264 {
265         if (e == NULL) return 1;
266         free(e->nombre);
267         free(e);
268         return 0;
269 }
270
271 int ver_archivo_FS(EMUFS *emu)
272 {
273         FILE *f_block_free;
274         EMUFS_FSC reg;
275         char name_f_block_free[255];
276         
277         strcpy(name_f_block_free,emu->nombre);
278         strcat(name_f_block_free,".fsc");
279
280         if ( (f_block_free = fopen(name_f_block_free,"r"))==NULL ){
281                 fprintf(stderr, "no pude abrir el archivo %s\n",name_f_block_free);
282                 return -1;
283         }
284         fprintf(stderr,"BOQUES Y ESPACIO LIBRE\n");
285         fread(&reg,sizeof(reg),1,f_block_free);
286         while ( !feof(f_block_free) ){
287                 fprintf(stderr, "Bloque = %li   Espacio libre = %li\n",reg.marker, reg.freespace);
288                 fread(&reg,sizeof(reg),1,f_block_free);
289         }
290         
291         fclose(f_block_free);
292
293         /* Imprimo la lista de bloques/registros */
294         fprintf(stderr, "BLOQUES Y REGISTROS\n");
295         strcpy(name_f_block_free,emu->nombre);
296         strcat(name_f_block_free,".idx");
297         f_block_free = fopen(name_f_block_free, "r");
298         {
299                 EMUFS_IDX r;
300                 while (!feof(f_block_free)) {
301                         if (fread(&r, sizeof(EMUFS_IDX), 1, f_block_free) != 1) continue;
302                         fprintf(stderr, "ID %li en bloque %li\n", r.id_reg, r.location);
303                 }
304         }
305         fclose(f_block_free);
306         
307         return 0;
308 }