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