]> git.llucax.com Git - z.facultad/75.06/emufs.git/blob - emufs/tipo3.c
* Agrego clave STRING a los indices. Para ello guardo el string
[z.facultad/75.06/emufs.git] / emufs / tipo3.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  *----------------------------------------------------------------------------
24  *
25  * $Id$
26  *
27  */
28
29 /** \file
30  *
31  * Archivo con bloques y registros de longitud parametrizada.
32  * 
33  * Implementación del archivo con bloques y registros de longitud
34  * parametrizada.
35  *
36  */
37
38 #include "tipo3.h"
39 #include "error.h"
40 #include "common.h"
41 #include <unistd.h>
42 #include <stdio.h>
43 #include <string.h>
44
45 /** Leo un registro del archivo, devuelve NULL si no lo encuentra.**/
46 void* emufs_tipo3_leer_registro(EMUFS *emu, CLAVE clave,
47                 EMUFS_REG_SIZE* reg_size, int* err)
48 {
49         INDICE_DATO dato;
50         char* bloque;
51         char* registro; /* registro a leer */
52         EMUFS_BLOCK_ID block;
53         EMUFS_REG_ID ID_aux, ID;
54         EMUFS_BLOCK_SIZE iterador = 0;
55         int cant_bloques = 0, resto, i, copiado=0;
56
57         cant_bloques = (emu->tam_reg / (emu->tam_bloque-sizeof(EMUFS_REG_ID))) + 1;
58         if ( emu->tam_reg+sizeof(EMUFS_REG_ID) == emu->tam_bloque ) 
59                 cant_bloques = 1;
60         
61         /*si existe, lo busco en el archivo de bloques*/
62         if (emu->indices != NULL) {
63                 /* TODO : Verificar donde esta el indice primario */
64                 dato = emu->indices->existe_entrada(emu->indices, clave);
65                 block = dato.bloque;
66                 ID = dato.id;
67         } else {
68                 /* Si no tengo claves, uso el campo entero para pasar un ID
69                  * directamente.
70                  */
71                 ID = clave.i_clave;
72                 block = emufs_idx_buscar_registro(emu,ID); /*me devuelve el nro de bloque al que pertenece el registro*/
73         }
74         if ( block == EMUFS_NOT_FOUND ){
75                 PERR("No se encontro el bloque");
76                 *err = -1;
77                 return NULL;
78         }
79         
80         registro = (char*) malloc(emu->tam_reg);
81         if (registro == NULL) {
82                 PERR("No hay memoria");
83                 *err = EMUFS_ERROR_OUT_OF_MEMORY;
84                 return NULL;
85         }
86
87         resto = emu->tam_bloque - sizeof(EMUFS_REG_ID);
88         for (i=0; i<cant_bloques; i++){
89                 if ((bloque = emufs_tipo3_leer_bloque(emu, block+i, err)) == NULL) {
90                         /* TODO Manejo de errores, queda en el codigo de error lo que devolvio
91                          * emufs_tipo3_leer_bloque() */
92                         PERR("no se pudo leer el bloque");
93                         free(registro);
94                         return NULL; /*No se pudo leer el bloque*/
95                 }
96                 ID_aux = -1;
97                 iterador = 0;
98                 while ( iterador < emu->tam_bloque ) {
99                         memcpy(&ID_aux, bloque+iterador, sizeof(EMUFS_REG_ID));
100                         iterador += sizeof(EMUFS_REG_ID);
101                         if ( ID_aux == ID ){
102                                 if ( cant_bloques == 0 )
103                                         memcpy(registro,bloque+iterador,emu->tam_reg);
104                                 else {
105                                         if ( cant_bloques-1 == i ) 
106                                                 resto = emu->tam_reg - copiado;
107                                         memcpy(registro+(emu->tam_bloque-sizeof(EMUFS_REG_ID))*i,bloque+iterador,resto);
108                                         copiado += resto;
109                                         break;
110                                 }
111                                 *reg_size = emu->tam_reg;
112                         }
113                         iterador += emu->tam_reg;
114                 }
115                 free(bloque);
116         }
117
118         return registro;
119 }
120
121 /*leo el bloque "ID" del archivo que viene en "emu->nombre", y lo almaceno en "ptr"*/
122 void* emufs_tipo3_leer_bloque(EMUFS *emu, EMUFS_BLOCK_ID ID, int* err)
123 {
124         FILE* file;
125         char* block; /* bloque leido (en donde está el registro a leer) */
126         char name_f[255];
127         
128         strcpy(name_f,emu->nombre);
129         strcat(name_f,".dat");
130         
131         if ((file = fopen(name_f, "r")) == NULL) {
132                 PERR("No se pudo abrir el archivo de datos");
133                 *err = EMUFS_ERROR_CANT_OPEN_FILE;
134                 return NULL;
135         }
136         fseek(file,sizeof(EMUFS_Tipo)+sizeof(EMUFS_BLOCK_SIZE)+sizeof(EMUFS_REG_SIZE),SEEK_SET);
137         /*FIXME: verificar que no se pase de fin de archivo*/
138         if (fseek(file,ID*emu->tam_bloque,SEEK_CUR) != 0){
139                 PERR("Fallo la busqueda del bloque");
140                 *err=3;
141                 return NULL;
142         }
143         
144         block = (char*) malloc(emu->tam_bloque);
145         if (block == NULL) {
146                 PERR("No hay memoria");
147                 *err = EMUFS_ERROR_OUT_OF_MEMORY;
148                 return NULL;
149         }
150         if (fread(block, emu->tam_bloque, 1, file) != 1) {
151                 /* TODO Manejo de errores */
152                 free(block);
153                 PERR("Error al leer bloque");
154                 *err = EMUFS_ERROR_FILE_READ;
155                 return NULL;
156         }
157
158         fclose(file);
159         return block;
160 }
161
162 EMUFS_REG_ID emufs_tipo3_grabar_registro(EMUFS *emu, void *ptr, EMUFS_REG_SIZE tam, int* err)
163 {
164         INDICE_DATO idx_data;
165         EMUFS_REG_ID ID_aux;
166         EMUFS_FREE fs, new_fs;
167         EMUFS_BLOCK_ID num_bloque;
168         EMUFS_BLOCK_SIZE cant;
169         FILE *file;
170         char name_f[255];
171         char* bloque = NULL;
172         int cant_bloques, resto, i=0;
173         
174         strcpy(name_f,emu->nombre);
175         strcat(name_f,".dat");
176         
177         cant_bloques = (emu->tam_reg / (emu->tam_bloque-sizeof(EMUFS_REG_ID))) + 1;
178         if ( emu->tam_reg+sizeof(EMUFS_REG_ID) == emu->tam_bloque ) 
179                 cant_bloques = 1;
180         
181         resto = emu->tam_bloque - sizeof(EMUFS_REG_ID);
182
183
184         
185         if ( cant_bloques == 1 ) 
186                 /* me devuelve el ID del bloque donde quepa un registro y el espacio libre en "fs"*/
187                 num_bloque = emufs_fsc_buscar_lugar(emu, emu->tam_reg+sizeof(EMUFS_REG_ID), &fs);
188         else 
189                 /* me devuelve el ID del bloque donde quepan n registros y el espacio libre en "fs"*/
190                 num_bloque = emufs_fsc_buscar_n_lugares(emu, cant_bloques, emu->tam_bloque, &fs, err);
191
192         /*si no hay bloques con suficiente espacio creo un bloque nuevo */
193         if (num_bloque == EMUFS_NOT_FOUND) {
194                 if ( (file = fopen(name_f,"a+"))==NULL ) return -1; /*ERROR*/
195                 /*tengo que buscar un ID valido para el nuevo registro*/
196                 ID_aux = emufs_idx_get_new_id(emu, err);
197                 /* El free esta al final de la funcion! */
198                 bloque = (char*)malloc(emu->tam_bloque);
199                 for (i=0; i<cant_bloques; i++) {
200                         /*crear un nuevo bloque en memoria */
201                         memset(bloque, 0, emu->tam_bloque);
202                         /* grabar el registro al principio del bloque */
203                         /*grabo el id en el bloque*/
204                         memcpy(bloque,&ID_aux,sizeof(EMUFS_REG_ID));
205                         /*grabo el registro en el bloque*/
206                         if ( cant_bloques == 1 ){
207                                 memcpy(bloque+sizeof(EMUFS_REG_ID),ptr,emu->tam_reg);
208                         } else {
209                                 if ( cant_bloques-1 == i )
210                                         resto = emu->tam_reg - i*(emu->tam_bloque - sizeof(EMUFS_REG_ID));
211                                 memcpy(bloque+sizeof(EMUFS_REG_ID),((char*)ptr)+i*(emu->tam_bloque-sizeof(EMUFS_REG_ID)),resto);
212                         }
213                         /* me paro al final del archivo */
214                         fseek(file, 0, SEEK_END);
215                         /* grabo el bloque en el final del archivo */
216                         fwrite(bloque,emu->tam_bloque,1,file);
217                         /*tengo que buscar la cantidad de bloques que existen*/
218                         fseek(file, 0, SEEK_END); /* Me paro al final */
219                         cant = (ftell(file)-(sizeof(EMUFS_Tipo)+sizeof(EMUFS_REG_SIZE)+sizeof(EMUFS_BLOCK_SIZE))) / emu->tam_bloque;
220                         cant--; /* Resto uno porque el numero de bloque debe empezar en 0 */
221                         num_bloque = cant;
222
223                         if (i == 0) {
224                                 /* Tengo que agregar el primer bloque en IDX */
225                                 if ( emufs_idx_agregar(emu, ID_aux, num_bloque) != 0 ){
226                                         free(bloque);
227                                         return -1;
228                                 }
229                                 idx_data.id = ID_aux;
230                                 idx_data.bloque = num_bloque;
231                                 emufs_indice_agregar(emu->indices, ptr, idx_data);
232                         }
233                 
234                         /* grabo el nuevo registro en el archivo de espacios libres */
235                         if ( emu->tam_bloque-sizeof(EMUFS_REG_ID) < emu->tam_reg ) 
236                                 new_fs = emu->tam_bloque - sizeof(EMUFS_REG_ID) - resto ;
237                         else new_fs = emu->tam_bloque - sizeof(EMUFS_REG_ID) - emu->tam_reg ;
238                         if ( emufs_fsc_agregar(emu, num_bloque+i, new_fs) ) {
239                                 fclose(file);
240                                 free(bloque);
241                                 return -1;
242                         }
243                 }
244                 fclose(file);
245         } else {
246                 /*tengo que buscar un ID valido para el nuevo registro*/
247                 ID_aux = emufs_idx_get_new_id(emu, err);
248                 for (i=0; i<cant_bloques; i++){
249                         resto = emu->tam_bloque-sizeof(EMUFS_REG_ID);
250                         /*cargo el bloque en "bloque"*/
251                         if (!(bloque = emufs_tipo3_leer_bloque(emu, num_bloque+i, err))) {
252                                 /* TODO Manejo de errores */
253                                 PERR("no se pudo leer el bloque");
254                                 return -1;
255                         }
256                         /*El error puede haberse producido porque la funcion leer_bloque devolvio -1, el cual es un bloque invalido*/
257                         /*insertar el registro en el bloque*/
258                         /*grabo el id en el bloque*/
259                         /*veo el espacio libre que queda*/ 
260                         fs = emufs_fsc_get_fs(emu, num_bloque+i);
261                         if (emu->tam_bloque-sizeof(EMUFS_REG_ID) < emu->tam_reg)
262                                 memcpy(bloque,&ID_aux,sizeof(EMUFS_REG_ID));
263                         else
264                                 memcpy(bloque+emu->tam_bloque-fs,&ID_aux,sizeof(EMUFS_REG_ID));
265                         /*grabo el registro en el bloque*/
266                         if ( cant_bloques == 1 ){
267                                 memcpy(bloque+emu->tam_bloque-fs+sizeof(EMUFS_REG_ID),ptr,emu->tam_reg);
268                         } else {
269                                 if ( cant_bloques-1 == i )
270                                         resto = emu->tam_reg - i*(emu->tam_bloque - sizeof(EMUFS_REG_ID));
271                                 memcpy(bloque+sizeof(EMUFS_REG_ID),((char*)ptr)+i*(emu->tam_bloque-sizeof(EMUFS_REG_ID)),resto);
272                         }                               
273                         
274                         /*grabo el bloque en el archivo*/
275                         if ( emufs_tipo3_grabar_bloque(emu, bloque, num_bloque+i) != 0) {
276                                 PERR("error al grabar bloque");
277                                 if (bloque) free(bloque);
278                                 return -1; /* se produjo un error */    
279                         }
280                         
281                         /*actualizo el archivo de espacios libres*/
282                         if ( emu->tam_bloque-sizeof(EMUFS_REG_ID) < emu->tam_reg ){
283                                 /*Si el registro ocupa mas de un bloque  (original) resto = emu->tam_bloque-sizeof(EMUFS_REG_ID)*/
284                                 resto += sizeof(EMUFS_REG_ID);
285                                 /*resto = emu->tam_reg - i*(emu->tam_bloque - sizeof(EMUFS_REG_ID)) + sizeof(EMUFS_REG_ID);*/
286                                 if ( cant_bloques-1 == i )
287                                         resto = emu->tam_reg - i*(emu->tam_bloque - sizeof(EMUFS_REG_ID))+sizeof(EMUFS_REG_ID);
288                                 /*printf("fs-resto = %d\n", fs-resto);*/
289                                 if ( emufs_fsc_agregar(emu, num_bloque+i, fs-resto) !=0 ){
290                                         fclose(file);
291                                         if (bloque) free(bloque);
292                                         return -1;
293                                 }
294                         } else {        
295                                 /* si ocupa menos de un bloque*/
296                                 resto = emu->tam_reg;
297                                 if ( emufs_fsc_agregar(emu, num_bloque, fs - resto - sizeof(EMUFS_REG_ID) ) != 0 ) {
298                                         fclose(file);
299                                         if (bloque) free(bloque);
300                                         return -1;
301                                 }
302                         }
303                         if ( i == 0 ){
304                                 if ( emufs_idx_agregar(emu, ID_aux, num_bloque) != 0 ){
305                                         if (bloque) free(bloque);
306                                         return -1;
307                                 }
308                                 idx_data.id = ID_aux;
309                                 idx_data.bloque = num_bloque;
310                                 emufs_indice_agregar(emu->indices, ptr, idx_data);
311                         }
312                 }
313         }
314         if (bloque) free(bloque);
315         return ID_aux;
316 }
317
318 /*Graba un bloque en el archivo*/
319 int emufs_tipo3_grabar_bloque(EMUFS *emu, void *ptr, EMUFS_BLOCK_ID num)
320 {
321         FILE* file;
322         char name_f[255];
323         
324         strcpy(name_f,emu->nombre);
325         strcat(name_f,".dat");
326         
327         if ( (file = fopen(name_f,"r+"))==NULL ) return -1; /*ERROR*/
328         /* Salto el header del archivo */
329         fseek(file, sizeof(EMUFS_Tipo)+sizeof(EMUFS_REG_SIZE)+sizeof(EMUFS_BLOCK_SIZE), SEEK_SET);
330         fseek(file, num*emu->tam_bloque, SEEK_CUR);     
331         fwrite(ptr, emu->tam_bloque, 1, file);
332         
333         fclose(file);
334         return 0;
335 }
336
337 /*borra un registro de un bloque y acomoda los registros que quedan*/
338 int emufs_tipo3_borrar_registro(EMUFS *emu, CLAVE k)
339 {
340         EMUFS_BLOCK_SIZE num_bloque;
341         EMUFS_BLOCK_SIZE ptr_elim;
342         EMUFS_BLOCK_SIZE ptr_mov;
343         EMUFS_REG_ID ID_aux, ID;
344         EMUFS_FREE fs;
345         INDICE_DATO dato;
346         char *bloque;
347         int err = 0, i, cant_bloques;
348
349         /*cantidad de bloques que ocupa un registro*/
350         cant_bloques = emu->tam_reg/(emu->tam_bloque-sizeof(EMUFS_REG_ID))+1;
351         if ( emu->tam_reg+sizeof(EMUFS_REG_ID) == emu->tam_bloque ) 
352                 cant_bloques = 1;
353
354         PERR("Buscando datos del registro en el indice");
355         dato = emu->indices->existe_entrada(emu->indices, k);
356         num_bloque = dato.bloque; /*emufs_idx_buscar_registro(emu, ID);*/
357         ID = dato.id;
358
359         if (!(bloque = emufs_tipo3_leer_bloque(emu, num_bloque, &err))) {
360                 /* TODO Manejo de errores */
361                 PERR("no se pudo leer el bloque");
362                 return -1;
363         }
364
365         PERR("Borrando clave");
366         /* TODO Borrar en todos los indices!! */
367         emu->indices->borrar_entrada(emu->indices, k);
368         /*apunto al registro que voy a eliminar*/
369         ptr_elim = 0;
370         while ( ptr_elim < emu->tam_bloque ){
371                 memcpy(&ID_aux, bloque+ptr_elim, sizeof(EMUFS_REG_ID));
372                 if ( ID_aux == ID )
373                         break;
374                 ptr_elim += emu->tam_reg + sizeof(EMUFS_REG_ID);
375         }
376
377         /*apunto al registro que voy a mover*/
378         ptr_mov = ptr_elim + emu->tam_reg + sizeof(EMUFS_REG_ID);
379         
380         while ( (ptr_mov+sizeof(EMUFS_REG_ID)+emu->tam_reg) < emu->tam_bloque ){
381                 memcpy(bloque+ptr_elim, bloque+ptr_mov, sizeof(EMUFS_REG_ID)+emu->tam_reg);
382                 /* Blanqueo el area que movi */
383                 memset(bloque+ptr_mov, 0, sizeof(EMUFS_REG_ID)+emu->tam_reg);
384                 ptr_elim = ptr_mov;
385                 ptr_mov += sizeof(EMUFS_REG_ID) + emu->tam_reg;
386         }
387
388         /*grabo el bloque en el archivo*/       
389         if ( emu->tam_bloque-sizeof(EMUFS_REG_ID) < emu->tam_reg ) 
390                 memset(bloque, 0, emu->tam_bloque);
391         if ( emufs_tipo3_grabar_bloque(emu, bloque, num_bloque) == -1 ){
392                 free(bloque);
393                 PERR("No se pudo grabar el bloque"); 
394                 return -1;
395         }
396         
397         /*actualizo archivo .fsc*/
398         if ( emu->tam_bloque-sizeof(EMUFS_REG_ID) < emu->tam_reg ) {
399                 for (i=0; i<cant_bloques; i++)
400                         if (emufs_fsc_agregar(emu, num_bloque+i, emu->tam_bloque)) {
401                                 PERR("no se pudo agregar fsc"); 
402                                 free(bloque);
403                                 return -1;
404                         }
405         } else { 
406                 fs = emufs_fsc_get_fs(emu, num_bloque);
407                 if (emufs_fsc_agregar(emu, num_bloque, fs + emu->tam_reg + sizeof(EMUFS_REG_ID))) {
408                         PERR("no se pudo agregar fsc"); 
409                         free(bloque);
410                         return -1;
411                 }
412         }
413         /*actualizo archivo .did*/
414         if (emufs_did_agregar(emu, ID)) {
415                 PERR("no se pudo agregar did"); 
416                 free(bloque);
417                 return -1;
418         }
419                 
420         /*actualizo archivo .idx*/
421         if (emufs_idx_borrar(emu, ID)) {
422                 PERR("no se pudo agregar idx"); 
423                 free(bloque);
424                 return -1;
425         }
426
427         free(bloque);
428         return 0;
429 }
430
431 EMUFS_Estadisticas emufs_tipo3_leer_estadisticas(EMUFS *emu)
432 {
433         int err = 0,err1 = 0, err2 = 0, err3 = 0;
434         EMUFS_Estadisticas stats;
435         memset(&stats,0,sizeof(EMUFS_Estadisticas));
436         
437         { /* obtengo tamaño del archivo en bytes */
438                 char name_f[255];
439                 strcpy(name_f, emu->nombre);
440                 strcat(name_f, ".dat");
441                 stats.tam_archivo = emufs_common_get_file_size(name_f, &err);
442                 if (err) {
443                         PERR("no se pudo obtener el tamaño del archivo");
444                         return stats;
445                 }
446         }
447         
448         /* obtengo la cantidad de bloques en el archivo */
449         stats.cant_bloques = (stats.tam_archivo-sizeof(EMUFS_Tipo)-sizeof(EMUFS_BLOCK_SIZE)-sizeof(EMUFS_REG_SIZE))/
450                                                   emu->tam_bloque;
451
452         /* obtengo la cantidad de registros en el archivo */
453         {
454                 EMUFS_REG_ID *tmp = emufs_idx_get(emu, &stats.cant_registros);
455                 if (tmp) free(tmp); /* libera memoria innecesaria */
456         }
457
458         /* obtengo información de control que guarda el archivo .dat */
459         stats.tam_info_control_dat = stats.cant_registros*sizeof(EMUFS_REG_ID)+sizeof(EMUFS_Tipo)+
460                                                  sizeof(EMUFS_BLOCK_SIZE)+sizeof(EMUFS_REG_SIZE);
461
462         /* Obtengo las stats de FSC */
463         stats.total_fs = emufs_fsc_get_total_fs(emu);
464         stats.media_fs = emufs_fsc_get_media_fs(emu);
465         emufs_fsc_get_max_min_fs(emu,&stats.min_fs,&stats.max_fs);
466         
467         /* obtengo informacion de control guardada por los archivos auxiliares */
468         stats.tam_archivos_aux = emufs_idx_get_file_size(emu,&err1) + emufs_fsc_get_file_size(emu,&err2)
469                                                         + emufs_did_get_file_size(emu,&err3);
470         if (err1 || err2 || err3) {
471                 PERR("Hubo problemas en lectura de filesize archivos auxiliares");
472                 return stats;
473         }               
474
475         return stats;   
476 }
477
478 EMUFS_REG_ID emufs_tipo3_modificar_registro(EMUFS *emu, EMUFS_REG_ID id, void *data, EMUFS_REG_SIZE size, int *error)
479 {
480         /*emufs_tipo3_borrar_registro(emu, id);*/
481         return emufs_tipo3_grabar_registro(emu, data, size, error);
482 }
483
484 void* emufs_tipo3_leer_registro_raw(EMUFS *emu, EMUFS_REG_ID ID, EMUFS_REG_SIZE *size, int *pos)
485 {
486         char* bloque;
487         EMUFS_BLOCK_ID block;
488         EMUFS_REG_ID ID_aux;
489         EMUFS_BLOCK_SIZE iterador = 0;
490         int err;
491         
492         bloque = NULL;
493                 
494         /* Aca estoy en el caso de que 1 registro entra en 1 solo bloque */
495         block = emufs_idx_buscar_registro(emu,ID);
496         if ( block == EMUFS_NOT_FOUND ) {
497                 return NULL;
498         }
499         if ((bloque = emufs_tipo3_leer_bloque(emu, block, &err)) == NULL) {
500                 return NULL;
501         }
502                 
503         ID_aux = -1;
504         iterador = 0;
505         
506         /* Busco el offset desde el comienzo desde donde arranca el registro
507          * buscado, para luego resaltarlo en al GUI
508          */
509         while ( iterador < emu->tam_bloque ) {
510                 memcpy(&ID_aux, bloque+iterador, sizeof(EMUFS_REG_ID));
511                 if ( ID_aux == ID ){
512                         *pos = iterador; 
513                         *size = emu->tam_bloque;
514                         break;
515                 }
516                 iterador += sizeof(EMUFS_REG_ID);
517                 iterador += emu->tam_reg;
518         }
519         return bloque;
520 }
521
522 void emufs_tipo3_compactar(EMUFS *emu)
523 {
524 /* TODO ARREGLAR */
525 #ifdef PEPITO_EL_GALAN 
526         EMUFS_REG_ID *tmp, max_id;
527         EMUFS_BLOCK_ID block_id;
528         EMUFS_REG_SIZE size;
529         EMUFS_FREE fs;
530         char name[255];
531         char *reg;
532         int err=0, ID_aux, i;
533         
534         strcpy(name, emu->nombre);
535         strcat(name, ".dat");
536
537         tmp = emufs_idx_get(emu, &max_id);
538         if (tmp) free(tmp);
539         for( i=0; i<max_id; i++){
540                 /* si el id no existe paso al siguiente*/
541                 if ( emufs_idx_existe_id(emu, i) != 0 ) continue;
542                 reg = emufs_tipo3_leer_registro(emu, i, &size, &err);
543                 if (err){
544                         PERR("No se pudo leer el registro para reacomodar");
545                         return;
546                 }
547                 emufs_tipo3_borrar_registro(emu, i);
548                 ID_aux = emufs_tipo3_grabar_registro(emu, reg, emu->tam_reg, &err);
549                 free(reg);
550         }
551         /*trunco el archivo sacando los bloques vacios*/
552         block_id = emufs_fsc_buscar_lugar(emu, emu->tam_bloque, &fs);
553         size = sizeof(EMUFS_Tipo)+sizeof(EMUFS_REG_SIZE)+sizeof(EMUFS_BLOCK_SIZE)+block_id*emu->tam_bloque;
554         if (truncate(name, size)!=0)
555                 PERR("NO TRUNQUE NADA");
556         /*hay que truncar el fsc!!!*/
557         if(emu->tam_bloque-sizeof(EMUFS_REG_ID) < emu->tam_reg) block_id = block_id/2;
558         if (emufs_fsc_truncate(emu, block_id)!= 0)
559                 PERR("NO TURNQUE EL FSC");
560 #endif
561 }
562
563 void emufs_tipo3_leer_bloque_raw(EMUFS *efs, EMUFS_BLOCK_ID id, char **actual, char **anterior, char **siguiente,
564                                                                  EMUFS_BLOCK_SIZE *size1, EMUFS_BLOCK_SIZE *size2, EMUFS_BLOCK_SIZE *size3)
565 {
566         int err;
567         (*actual) = emufs_tipo3_leer_bloque(efs, id, &err);
568         (*anterior) = emufs_tipo3_leer_bloque(efs, id-1, &err);
569         (*siguiente) = emufs_tipo3_leer_bloque(efs, id+1, &err);
570         if (!(*anterior)) {
571                 (*anterior) = (char *)malloc(efs->tam_bloque);
572                 memset(*anterior, 0, efs->tam_bloque);          
573         }       
574         if (!(*siguiente)) {
575                 (*siguiente) = (char *)malloc(efs->tam_bloque);
576                 memset(*siguiente, 0, efs->tam_bloque);         
577         }
578         (*size1) = (*size2) = (*size3) = efs->tam_bloque;
579 }
580
581 int emufs_tipo3_insertar_ordenado(EMUFS *emu, void *ptr, CLAVE clave, int offset, EMUFS_BLOCK_ID num_bloque, int *err)
582 {
583         return 0;
584 }