]> git.llucax.com Git - z.facultad/75.06/emufs.git/blob - emufs/emufs.c
File Type 2 Test Added. Por ahora solo agrega registros y arma el indice. Ahora toy...
[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 /* Duplica una cadena de caracteres y devuelve la copia.  */
52 char *str_dup(const char *s)
53 {
54         char *tmp;
55         if (s == NULL) return NULL;
56         tmp = (char *)malloc(sizeof(char)*(strlen(s)+1));
57         strcpy(tmp, s);
58         return tmp;
59 }
60
61 /* Objetivo: Crea un archivo de nombre y extension dadas. */
62 int emufs_crear_archivo_auxiliar(const char* name, const char* ext)
63 {
64         FILE* f;
65         char* filename;
66
67         filename = (char*) malloc(sizeof(char) * (strlen(name) + strlen(ext) + 1));
68         if (filename == NULL) {
69                 /* TODO Manejo de errores */
70                 return -1;
71         }
72         strcpy(filename, name);
73         strcat(filename, ext);
74         f = fopen(filename, "w");
75         free(filename);
76         if (f == NULL) {
77                 /* TODO Manejo de errores */
78                 return -1;
79         }
80         fclose(f);
81         return 0;
82 }
83
84 /* Crea un archivo de tipo dado y devuelve una estructura con las rutinas de handling de dicho archivo. */
85 EMUFS *emufs_crear(const char *filename, EMUFS_TYPE tipo,
86                 EMUFS_BLOCK_SIZE tam_bloque, EMUFS_REG_SIZE tam_reg)
87 {
88         char name[255];
89         FILE *fp;
90         EMUFS *efs;
91
92         /* Si no es un tipo conocido, sale. */
93         if ((tipo != T1) && (tipo != T2) && (tipo != T3)) {
94                 return NULL;
95         }
96
97         /* Inicializa parámetros comunes. */
98         efs = (EMUFS*) malloc(sizeof(EMUFS));
99         if (efs == NULL) {
100                 return NULL;
101         }
102         efs->tipo = tipo;
103         efs->tam_bloque = tam_bloque;
104         efs->tam_reg = tam_reg;
105         efs->nombre = str_dup(filename);
106
107         /* Abre archivo de datos. */
108         strcpy(name, filename);
109         strcat(name, ".dat");
110         fp = fopen(name, "w");
111         if (fp == NULL) {
112                 /* TODO ERROR */
113                 free(efs->nombre);
114                 free(efs);
115                 return NULL;
116         }
117
118         /* Guarda cabecera común. */
119         fwrite(&tipo, sizeof(EMUFS_TYPE), 1, fp);
120
121         /* Crea archivo de índice. */
122         if (emufs_idx_crear(efs)) {
123                 /* TODO ERROR */
124                 free(efs->nombre);
125                 free(efs);
126                 return NULL;
127         }
128
129         /* Crea archivo de control de espacio libre. */
130         if (emufs_fsc_crear(efs)) {
131                 /* TODO ERROR */
132                 free(efs->nombre);
133                 free(efs);
134                 return NULL;
135         }
136
137         /* Crea archivo de identificadores borrados (recuperables). */
138         if (emufs_did_crear(efs)) {
139                 /* TODO ERROR */
140                 free(efs->nombre);
141                 free(efs);
142                 return NULL;
143         }
144
145         /* Termina de realizar el trabajo según el tipo de archivo. */
146         switch (tipo) {
147
148                 case T1:
149                         emufs_tipo1_inicializar(efs);
150
151                         /* Guarda cabeceras propias. */
152                         fwrite(&tam_bloque, sizeof(EMUFS_BLOCK_SIZE), 1, fp);
153
154                         break;
155
156                 case T2:
157                         /* Asigna punteros a funciones. */
158                         efs->grabar_registro = emufs_tipo2_grabar_registro;           
159             efs->borrar_registro = emufs_tipo2_borrar_registro;
160                         efs->nombre = str_dup(filename);
161                     /*efs->leer_registro = emufs_tipo2_leer_registro;*/                                         
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->grabar_registro = emufs_tipo3_grabar_registro;
169                         /*efs->borrar_registro = emufs_tipo3_borrar_registro;*/
170
171                         /* Guarda cabeceras propias. */
172                         fwrite(&tam_bloque, sizeof(EMUFS_BLOCK_SIZE), 1, fp);
173                         fwrite(&tam_reg, sizeof(EMUFS_REG_SIZE), 1, fp);                        
174                         break;
175
176         }
177
178         fclose(fp);
179         return efs;
180 }
181
182 /* Realiza la apertura de un archivo dado, identifica el tipo de archivo y devuelve la estructura de handling. */
183 EMUFS *emufs_abrir(const char *filename)
184 {
185         EMUFS *efs;
186         char name[255];
187         char tipo;
188         FILE *fp;
189
190         strcpy(name, filename);
191         strcat(name, ".dat");
192
193         /* Trato de determinar el tipo de archivo */
194         fp = fopen(name, "r");
195         if (fp == NULL) return NULL;
196         fread(&tipo, sizeof(EMUFS_TYPE), 1, fp);
197
198         /* Si no es un tipo conocido, sale. */
199         if ((tipo != T1) && (tipo != T2) && (tipo != T3)) {
200                 fclose(fp);
201                 return NULL;
202         }
203         
204         /* Inicializa parámetros comunes. */
205         efs = (EMUFS*) malloc(sizeof(EMUFS));
206         if (efs == NULL) {
207                 fclose(fp);
208                 return NULL;
209         }
210         efs->tipo = tipo;
211         efs->nombre = str_dup(filename);
212
213         switch (tipo) {
214                 case T1:
215                         emufs_tipo1_inicializar(efs);
216                         /* Lee cabeceras propias. */
217                         if (!fread(&(efs->tam_bloque), sizeof(EMUFS_BLOCK_SIZE), 1, fp)) {
218                                 free(efs->nombre);
219                                 free(efs);
220                                 fclose(fp);
221                                 return NULL;
222                         }
223                         break;
224                 case T2:
225                         break;
226                 case T3:
227                         if ((!fread(&(efs->tam_bloque), sizeof(EMUFS_BLOCK_SIZE), 1, fp)) ||
228                            (!fread(&(efs->tam_reg), sizeof(EMUFS_REG_SIZE), 1, fp)))
229                                 {
230                                 free(efs->nombre);
231                                 free(efs);
232                                 fclose(fp);
233                                 return NULL;
234                         }                       
235                         efs->leer_bloque = emufs_tipo3_leer_bloque;
236                         efs->leer_registro = emufs_tipo3_leer_registro;
237                         efs->grabar_registro = emufs_tipo3_grabar_registro;
238                         /*efs->borrar_registro = emufs_tipo3_borrar_registro;*/
239                         break;
240         }
241
242         fclose(fp);
243         return efs;
244 }
245
246 /* Objetivo: Rutina llamada al destruir la aplicacion para librerar  */
247 int emufs_destruir(EMUFS *e)
248 {
249         if (e == NULL) return 1;
250         free(e->nombre);
251         free(e);
252         return 0;
253 }
254
255 /* Visualiza espacios libres de un archivo?? */
256 int ver_archivo_FS(EMUFS *emu)
257 {
258         FILE *f_block_free;
259         EMUFS_FSC reg;
260         char name_f_block_free[255];
261         
262         strcpy(name_f_block_free,emu->nombre);
263         strcat(name_f_block_free,".fsc");
264
265         if ( (f_block_free = fopen(name_f_block_free,"r"))==NULL ){
266                 printf("no pude abrir el archivo %s\n",name_f_block_free);
267                 return -1;
268         }
269         fread(&reg,sizeof(reg),1,f_block_free);
270         while ( !feof(f_block_free) ){
271                 printf(" Bloque = %li   Espacio libre = %li\n",reg.n_Marker, reg.n_FreeSpace);
272                 fread(&reg,sizeof(reg),1,f_block_free);
273         }
274         
275         fclose(f_block_free);
276
277         /* Imprimo la lista de bloques/registros */
278         printf("BLOQUES Y REGISTROS\n");
279         strcpy(name_f_block_free,emu->nombre);
280         strcat(name_f_block_free,".idx");
281         {
282                 EMUFS_IDX r;
283                 f_block_free = fopen(name_f_block_free, "r");
284                 fread(&r, sizeof(EMUFS_IDX), 1, f_block_free);
285                 while (!feof(f_block_free)) {
286                         printf("ID %li en bloque %li\n", r.n_IdReg, r.n_Location);
287                         fread(&r, sizeof(EMUFS_IDX), 1, f_block_free);
288                 }
289                 fclose(f_block_free);
290         }
291         
292         
293         return 0;
294 }