]> git.llucax.com Git - z.facultad/75.06/emufs.git/blob - emufs/fsc.c
344adb645c36eab8fd6d91f5e59d51c2ee206152
[z.facultad/75.06/emufs.git] / emufs / fsc.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:  vie abr  9 16:17:50 ART 2004
22  * Autores: Nicolás Dimov <sagardua@uolsinectis.com.ar>
23  *          Leandro Lucarella <llucare@fi.uba.ar>
24  *----------------------------------------------------------------------------
25  *
26  * $Id$
27  *
28  */
29
30 /** \file
31  *
32  * Archivo para administrar el espacio libre disponible.
33  * 
34  * Implementación del archivo para administrar el espacio libre disponible.
35  *
36  */
37
38 #include "fsc.h"
39 #include "error.h"
40 #include "common.h"
41 #include <unistd.h>
42 #include <string.h>
43
44 /* Crea un archivo de Gaps o Espacio Libre en Bloque */
45 int emufs_fsc_crear(EMUFS* efs)
46 {
47         return emufs_crear_archivo_auxiliar(efs->nombre, EMUFS_FSC_EXT);
48 }
49
50 /* Agrega un registro al archivo de espacio libre en bloque. */
51 int emufs_fsc_agregar(EMUFS *emu, EMUFS_BLOCK_ID marker, EMUFS_FREE freespace)
52 {
53         FILE *f_fsc;
54         EMUFS_FSC reg;
55         char name_f_fsc[255];
56         
57         strcpy(name_f_fsc,emu->nombre);
58         strcat(name_f_fsc, EMUFS_FSC_EXT);
59         
60         /* Lo guardo en el archivo al final "a+"*/
61         PERR(name_f_fsc);
62         if ( (f_fsc = fopen(name_f_fsc,"r+"))==NULL ) return -1;
63         /* lo busco.. si esta lo modifico y si no lo agrego */
64         fseek(f_fsc,0,SEEK_SET);
65         while ( !feof(f_fsc) ){
66                 if ( fread(&reg,sizeof(EMUFS_FSC),1,f_fsc) != 1) continue;
67                 if ( reg.marker == marker ){
68                         fseek(f_fsc,-sizeof(EMUFS_FSC),SEEK_CUR);
69                         reg.freespace = freespace;
70                         fwrite(&reg,sizeof(EMUFS_FSC),1,f_fsc);
71                         fclose(f_fsc);
72                         return 0;
73                 }
74         }
75         /* Cargo el registro */
76         reg.marker = marker;
77         reg.freespace = freespace;
78         fwrite(&reg,sizeof(EMUFS_FSC),1,f_fsc);
79         fclose(f_fsc);
80         return 0;
81 }
82
83 /* Agrega un GAP en el archivo de Gaps para Filetype 2 */
84 int emufs_fsc_agregar_gap(EMUFS *emu, EMUFS_OFFSET marker, EMUFS_FREE freespace)
85 {
86         FILE *f_fsc;
87         EMUFS_FSC gap_aux,gap_before,gap_after,gap_new;
88         char name_f_fsc[255];
89         EMUFS_REG_ID pos_gap_before = 0, pos_gap_after = 0;
90         unsigned long source,destination,limit,file_size,reg_count = 0,cant_moved = 0;
91         char found = 0;
92
93         strcpy(name_f_fsc,emu->nombre);
94         strcat(name_f_fsc, EMUFS_FSC_EXT);
95
96         gap_before.marker = -1;
97         gap_after.marker = -1;
98
99         /* Busco si hay un GAP por delante y/o por detras del que se esta por crear */
100         /* para en dicho caso realizar un merge! */
101         if ( (f_fsc = fopen(name_f_fsc,"r+")) == NULL) return -1; 
102         while ( !feof(f_fsc) ){
103                 if ( fread(&gap_aux,sizeof(EMUFS_FSC),1,f_fsc) != 1) continue;
104
105                 /* Chequeo si es un gap justo anterior al nuestro */
106                 if (gap_aux.marker+gap_aux.freespace == marker) {
107                         gap_before.marker = gap_aux.marker;
108                         gap_before.freespace = gap_aux.freespace;
109                         pos_gap_before = reg_count;
110                 }
111
112                 /* Chequeo si es un gap justo posterior al nuestro */           
113                 if (gap_aux.marker == marker+freespace) {
114                         gap_after.marker = gap_aux.marker;
115                         gap_after.freespace = gap_aux.freespace;
116                         pos_gap_after = reg_count;
117                 }               
118                 reg_count += 1;
119         }
120
121         /* Si no encontre gaps ni por delante ni por detras */
122         if ((gap_before.marker == -1) && (gap_after.marker == -1)) {
123                 /* Lo guardo ordenado donde deba ir */
124                 gap_new.marker = marker;
125                 gap_new.freespace = freespace;
126                 /* Busco el gap que sucede a este */
127                 fseek(f_fsc,0,SEEK_SET);
128                 while (!feof(f_fsc)) {
129                         if (fread(&gap_aux,sizeof(EMUFS_FSC),1,f_fsc) != 1) continue;
130                         if (gap_aux.marker > gap_new.marker) {
131                                 found = 1;
132                                 break;
133                         }
134                 }
135                 if (found == 1) {
136                         /* Movemos todos los gaps desde el sucesor hasta el final, una pos adelante */
137                         limit = ftell(f_fsc) - sizeof(EMUFS_FSC);
138                         fseek(f_fsc,0,SEEK_END);
139                         reg_count = (ftell(f_fsc) - limit) / sizeof(EMUFS_FSC);                 
140                         source = ftell(f_fsc) - sizeof(EMUFS_FSC);
141
142                         while (cant_moved < reg_count)
143                         {
144                                 fseek(f_fsc,source,SEEK_SET);
145                                 fread(&gap_aux,sizeof(EMUFS_FSC),1,f_fsc);
146                                 fwrite(&gap_aux,sizeof(EMUFS_FSC),1,f_fsc);
147                                 source -= sizeof(EMUFS_FSC);
148                                 ++cant_moved;
149                         }
150                         /* Agrego el nuevo registro */
151                         fseek(f_fsc,limit,SEEK_SET);
152                         fwrite(&gap_new,sizeof(EMUFS_FSC),1,f_fsc);
153                 }
154                 else {
155                         fseek(f_fsc,0,SEEK_END);
156                         fwrite(&gap_new,sizeof(EMUFS_FSC),1,f_fsc);
157                 }
158
159                 fclose(f_fsc);          
160         }
161
162         /* Si encuentro un GAP Justo por delante pero no por detras */
163         if ((gap_before.marker != -1) && (gap_after.marker == -1))
164         {
165                 /* Me posiciono en el registro que indica dicho gap y lo reescribo con */
166                 /* la suma de los espacios libres */      
167                 fseek(f_fsc,sizeof(EMUFS_FSC)*pos_gap_before,0);
168                 gap_new.marker = gap_before.marker;
169                 gap_new.freespace = gap_before.freespace + freespace;
170                 fwrite(&gap_new,sizeof(EMUFS_FSC),1,f_fsc);
171                 fclose(f_fsc);
172         }
173
174         /* Si encuentro un GAP Justo por detras pero no por delante */
175         if ((gap_before.marker == -1) && (gap_after.marker != -1))
176         {  
177                 /* Me posiciono en el registro que indica dicho gap y lo reescribo con */
178                 /* los datos actualizados de offset y espacio */
179                 fseek(f_fsc,sizeof(EMUFS_FSC)*pos_gap_after,0);
180                 gap_new.marker = gap_after.marker - freespace;
181                 gap_new.freespace = gap_after.freespace + freespace;
182                 fwrite(&gap_new,sizeof(EMUFS_FSC),1,f_fsc);
183                 fclose(f_fsc);
184         }
185
186         /* Finalmente, si encuentro Justo por delante y por detras..*/
187         if ((gap_before.marker != -1) && (gap_after.marker != -1))
188         { 
189                 /* Guardo el nuevo GAP que posee los tres espacios sumados */
190                 if (pos_gap_before < pos_gap_after) {
191                         fseek(f_fsc,sizeof(EMUFS_FSC)*pos_gap_before,0);
192                         destination = sizeof(EMUFS_FSC)*pos_gap_after;
193                 }
194                 else {
195                         fseek(f_fsc,sizeof(EMUFS_FSC)*pos_gap_after,0);
196                         destination = sizeof(EMUFS_FSC)*pos_gap_before;
197                 }
198                 gap_new.marker = gap_before.marker;
199                 gap_new.freespace = gap_before.freespace + freespace + gap_after.freespace;
200                 fwrite(&gap_new,sizeof(EMUFS_FSC),1,f_fsc);
201
202                 /* Preparo el escenario para la movida de registros */
203                 source = destination+sizeof(EMUFS_FSC); /* Salteo el gap que elimino! */
204                 fseek(f_fsc,0,SEEK_END);
205                 file_size = ftell(f_fsc);
206                 reg_count = (file_size - source) / sizeof(EMUFS_FSC);
207
208                 /* Comienzo a mover */
209                 while (cant_moved < reg_count) {
210                         fseek(f_fsc,source,0);
211                         fread(&gap_new,sizeof(EMUFS_FSC),1,f_fsc);
212                         fseek(f_fsc,-sizeof(EMUFS_FSC)*2,SEEK_CUR);
213                         fwrite(&gap_new,sizeof(EMUFS_FSC),1,f_fsc);
214                         source += sizeof(EMUFS_FSC);            
215                         ++cant_moved;
216                 }
217                 fclose(f_fsc);
218                 truncate(name_f_fsc, file_size - sizeof(EMUFS_FSC));
219         }       
220
221     return 0;
222 }
223
224 /* Elimina un registro GAP del archivo de espacios libres (gaps) */
225 int emufs_fsc_remove_gap(EMUFS *emu, EMUFS_OFFSET marker)
226 {
227         FILE *f_fsc;
228         EMUFS_FSC gap_aux;
229         char name_f_fsc[255];
230     unsigned long source,destination,file_size,reg_count = 0,cant_moved = 0;    
231                 
232         strcpy(name_f_fsc,emu->nombre);
233         strcat(name_f_fsc, EMUFS_FSC_EXT);
234         
235         /* Busco el Gap en el .fsc */
236     if ((f_fsc = fopen(name_f_fsc,"r+")) == NULL) return -1; 
237         while ( !feof(f_fsc) ){
238                 if ( fread(&gap_aux,sizeof(EMUFS_FSC),1,f_fsc) != 1) continue;
239                 if ( gap_aux.marker == marker ) break;
240         }
241         
242         /* Preparo el escenario para la movida de registros */
243         fseek(f_fsc,-sizeof(EMUFS_FSC),SEEK_CUR);
244         destination = ftell(f_fsc);
245         source = destination+sizeof(EMUFS_FSC); /* Salteo el gap a eliminar! */
246         fseek(f_fsc,0,SEEK_END);
247         file_size = ftell(f_fsc);
248         reg_count = (file_size - source) / sizeof(EMUFS_FSC);
249                 
250         /* Comienzo a mover */
251         while (cant_moved < reg_count) {
252           fseek(f_fsc,source,0);
253       fread(&gap_aux,sizeof(EMUFS_FSC),1,f_fsc);
254           fseek(f_fsc,-sizeof(EMUFS_FSC)*2,SEEK_CUR);
255           fwrite(&gap_aux,sizeof(EMUFS_FSC),1,f_fsc);
256           source += sizeof(EMUFS_FSC);          
257           ++cant_moved;
258         }
259         fclose(f_fsc);
260         truncate(name_f_fsc, file_size - sizeof(EMUFS_FSC));
261         
262         return 0;
263 }
264
265 /* Objetivo: Actualiza un registro de espacio libre de acorde al FType */
266 int emufs_fsc_actualizar(EMUFS *emu, EMUFS_BLOCK_ID marker, EMUFS_FREE freespace)
267 {
268         FILE *f_fsc;
269         EMUFS_FSC reg;
270         char name_f_fsc[255];
271         
272         strcpy(name_f_fsc,emu->nombre);
273         strcat(name_f_fsc, EMUFS_FSC_EXT);
274
275         /*busco el bloque o gap que modifique*/
276         if ( (f_fsc = fopen(name_f_fsc,"r+")) == NULL) return -1; 
277         while ( !feof(f_fsc) ){
278                 if ( fread(&reg,sizeof(EMUFS_FSC),1,f_fsc) != 1) continue;
279                 if ( reg.marker == marker ){
280                         reg.freespace = freespace;
281                         fseek(f_fsc,-sizeof(EMUFS_FSC),SEEK_CUR);
282                         fwrite(&reg,sizeof(EMUFS_FSC),1,f_fsc);
283                         break;
284                 }
285         }
286         fclose(f_fsc);
287         return 0;
288 }
289
290 /* Actualiza un registro de gap, en el archivo de Gaps en Disco */
291 int emufs_fsc_actualizar_gap(EMUFS *emu, EMUFS_OFFSET marker, EMUFS_FREE freespace)
292 {
293         FILE *f_fsc;
294         EMUFS_FSC gap_aux;
295         char name_f_fsc[255];
296         
297         strcpy(name_f_fsc,emu->nombre);
298         strcat(name_f_fsc, EMUFS_FSC_EXT);
299
300         /*busco el bloque o gap que modifique*/
301         if ( (f_fsc = fopen(name_f_fsc,"r+")) == NULL) return -1; 
302         while ( !feof(f_fsc) ){
303                 if ( fread(&gap_aux,sizeof(EMUFS_FSC),1,f_fsc) != 1) continue;
304                 if ( gap_aux.marker == marker ){
305                         gap_aux.marker = marker + gap_aux.freespace - freespace;
306                         gap_aux.freespace = freespace;
307                         fseek(f_fsc,-sizeof(EMUFS_FSC),SEEK_CUR);
308                         fwrite(&gap_aux,sizeof(EMUFS_FSC),1,f_fsc);
309                         break;
310                 }
311         }
312         fclose(f_fsc);
313         return 0;
314 }
315
316 /* Me devuelve el ID del bloque u Offset del Gap donde quepa un registro, y guarda en n_freespace el espacio libre actualizado */
317 EMUFS_BLOCK_ID emufs_fsc_buscar_lugar(EMUFS *emu, EMUFS_FREE reg_size, EMUFS_FREE *freespace)
318 {
319         FILE *f_fsc;
320         EMUFS_FSC reg;
321         char name_f_fsc[255];
322         char found = 0;
323         
324         strcpy(name_f_fsc,emu->nombre);
325         strcat(name_f_fsc, EMUFS_FSC_EXT);
326
327         if ( (f_fsc = fopen(name_f_fsc,"r"))==NULL ) return EMUFS_NOT_FOUND;
328
329         if ( emu->tam_reg > emu->tam_bloque-sizeof(EMUFS_REG_ID) ){
330                 fseek(f_fsc,0,SEEK_SET);
331                 while(!feof(f_fsc)){
332                         if (fread(&reg,sizeof(EMUFS_FSC),1,f_fsc) != 1) continue;
333                         if (reg.freespace == emu->tam_bloque) {
334                                 fclose(f_fsc);
335                                 *freespace = reg.freespace;
336                                 return reg.marker;
337                         }
338                 }
339         }       
340         /* Inicializamos la estructura para devolver algun valor en concreto */
341         /* en caso de que no se halle un espacio libre apropiado */
342         while(!feof(f_fsc)){
343                 if (fread(&reg,sizeof(EMUFS_FSC),1,f_fsc) != 1) continue;
344                 if (reg.freespace >= reg_size) {
345                         found = 1;
346                         break;
347                 }
348         }
349         
350         /* Si salio por error o por fin de archivo y no encontro space... */
351         if (!found) {
352           reg.marker = EMUFS_NOT_FOUND;
353           *freespace = emu->tam_bloque; 
354         }
355         else *freespace = reg.freespace;
356         
357         fclose(f_fsc);
358         return reg.marker;
359 }
360
361 /** Busca n lugares consecutivos devolviendo el id del primer bloque. */
362 EMUFS_BLOCK_ID emufs_fsc_buscar_n_lugares(EMUFS* efs, size_t n,
363                 EMUFS_FREE size, EMUFS_FREE *freespace, int* err)
364 {
365         FILE *f_fsc;
366         EMUFS_FSC reg;
367         char name_f_fsc[255];
368
369         /* chequeo que al menos se busque un lugar */
370         if (!n) {
371                 PERR("Se debe buscar al menos un lugar");
372                 *err = EMUFS_ERROR_WRONG_ARGUMENT;
373                 return EMUFS_NOT_FOUND;
374         }
375
376         /* abre archivo */
377         strcpy(name_f_fsc, efs->nombre);
378         strcat(name_f_fsc, EMUFS_FSC_EXT);
379         if (!(f_fsc = fopen(name_f_fsc, "rb"))) {
380                 PERR("No se puede abrir archivo");
381                 *err = EMUFS_ERROR_CANT_OPEN_FILE;
382                 return EMUFS_NOT_FOUND;
383         }
384
385         /* busca el espacio libre */
386         while(!feof(f_fsc)) {
387                 if ((fread(&reg, sizeof(EMUFS_FSC), 1, f_fsc) != 1)) {
388                         if (feof(f_fsc)) break;
389                         PERR("No se puede leer el archivo");
390                         *err = EMUFS_ERROR_FILE_READ;
391                         fclose(f_fsc);
392                         return EMUFS_NOT_FOUND;
393                 }
394                 if (reg.freespace >= size) {
395                         int found = 1;
396                         EMUFS_BLOCK_ID first_id = reg.marker;
397                         *freespace = reg.freespace;
398                         while (--n) {
399                                 if (fread(&reg, sizeof(EMUFS_FSC), 1, f_fsc) != 1) {
400                                         if (feof(f_fsc)) break;
401                                         PERR("No se puede leer el archivo");
402                                         *err = EMUFS_ERROR_FILE_READ;
403                                         fclose(f_fsc);
404                                         return EMUFS_NOT_FOUND;
405                                 }
406                                 /* no hay otro lugar consecutivo */
407                                 if (reg.freespace < size) {
408                                         found = 0;
409                                         break;
410                                 }
411                         }
412                         if (found) {
413                                 fclose(f_fsc);
414                                 return first_id;
415                         }
416                 }
417         }
418         /* no se encontró espacio libre */
419         *freespace = efs->tam_bloque;
420         return EMUFS_NOT_FOUND;
421 }
422
423 /* Devuelve el espacio libre de un Bloque o Gap dado */
424 EMUFS_FREE emufs_fsc_get_fs(EMUFS *emu, EMUFS_BLOCK_ID marker)
425 {
426         FILE *f_fsc;
427         EMUFS_FSC reg;
428         char name_f_fsc[255];
429         
430         strcpy(name_f_fsc,emu->nombre);
431         strcat(name_f_fsc, EMUFS_FSC_EXT);
432
433         /* Busco el Bloque o Gap pedido y obtengo su espacio libre */
434         if ( (f_fsc = fopen(name_f_fsc,"r"))==NULL ) return -1;
435         while ( !feof(f_fsc) ){
436                 if ( fread(&reg,sizeof(EMUFS_FSC),1,f_fsc) != 1 ) continue;
437                 if ( reg.marker == marker )
438                         break;
439         }
440                 
441         fclose(f_fsc);
442         return reg.freespace;
443 }
444
445 EMUFS_FREE emufs_fsc_get_total_fs(EMUFS *emu)
446 {
447         FILE *f_fsc;
448         EMUFS_FSC reg;
449         char name_f_fsc[255];
450         EMUFS_FREE total;
451         
452         strcpy(name_f_fsc,emu->nombre);
453         strcat(name_f_fsc, EMUFS_FSC_EXT);
454
455         if ( (f_fsc = fopen(name_f_fsc,"r"))==NULL ) return -1;
456         total = 0;
457         while ( !feof(f_fsc) ){
458                 if ( fread(&reg, sizeof(EMUFS_FSC), 1, f_fsc) != 1) continue;
459                 if ( reg.freespace > 0 )
460                         total += reg.freespace;
461         }
462         fclose(f_fsc);
463         return total;
464 }
465
466 int emufs_fsc_get_max_min_fs(EMUFS *emu, EMUFS_FREE *min, EMUFS_FREE *max)
467 {
468         FILE *f_fsc;
469         EMUFS_FSC reg;
470         char name_f_fsc[255];
471         
472         strcpy(name_f_fsc,emu->nombre);
473         strcat(name_f_fsc, EMUFS_FSC_EXT);
474
475         if ( (f_fsc = fopen(name_f_fsc,"r"))==NULL ) return -1;
476                 
477         /* Si el file esta vacio, devuelvo valores nulos */
478         fseek(f_fsc,0,SEEK_END);
479         if (ftell(f_fsc) == 0) {
480                 *min = 0;
481                 *max = 0;
482                 return 0;               
483         }
484         else
485         {
486                 /* Busco Min y Max */
487                 *min = ULONG_MAX;
488                 *max = 0;               
489                 fseek(f_fsc,0,SEEK_SET);                
490                 while ( !feof(f_fsc) ){
491                         if ( fread(&reg, sizeof(EMUFS_FSC), 1, f_fsc) != 1) continue;
492                         if (  reg.freespace < *min )
493                                 *min = reg.freespace;
494                         if ( reg.freespace > *max )
495                                 *max = reg.freespace;
496                 }
497                 fclose(f_fsc);
498                 return 0;               
499         }
500 }
501
502 EMUFS_FREE emufs_fsc_get_media_fs(EMUFS *emu)
503 {
504         FILE *f_fsc;
505         EMUFS_FSC reg;
506         char name_f_fsc[255];
507         EMUFS_FREE total_fs = 0;
508         EMUFS_REG_ID gap_count = 0;
509         
510         strcpy(name_f_fsc,emu->nombre);
511         strcat(name_f_fsc, EMUFS_FSC_EXT);
512
513         if ( (f_fsc = fopen(name_f_fsc,"r"))==NULL ) return -1;
514         
515         while ( !feof(f_fsc) ){
516                 if ( fread(&reg, sizeof(EMUFS_FSC), 1, f_fsc) != 1) continue;           
517                 total_fs += reg.freespace;
518                 ++gap_count;
519         }
520
521         fclose(f_fsc);
522         
523         if (gap_count > 0) return total_fs/gap_count;
524         else return 0;
525 }
526
527 EMUFS_BLOCK_ID emufs_fsc_get_cant_bloques_vacios(EMUFS *emu)
528 {
529         FILE *f_fsc;
530         EMUFS_FSC reg;
531         char name_f_fsc[255];
532         EMUFS_BLOCK_ID cant=0;
533         
534         strcpy(name_f_fsc,emu->nombre);
535         strcat(name_f_fsc, EMUFS_FSC_EXT);
536
537         if ( (f_fsc = fopen(name_f_fsc,"r"))==NULL ) return -1;
538         while ( !feof(f_fsc) ){
539                 fread(&reg, sizeof(EMUFS_FSC), 1, f_fsc);
540                 if ( reg.freespace == emu->tam_bloque )
541                         cant++;
542         }
543                 
544         fclose(f_fsc);
545         return cant;
546 }
547
548 int emufs_fsc_truncate(EMUFS* efs, EMUFS_BLOCK_ID blocks)
549 {
550         char name_f_fsc[255];
551
552         strcpy(name_f_fsc, efs->nombre);
553         strcat(name_f_fsc, EMUFS_FSC_EXT);
554         return truncate(name_f_fsc, blocks * sizeof(EMUFS_FSC));
555 }
556
557 EMUFS_BLOCK_ID emufs_fsc_get_num_blocks(EMUFS* efs)
558 {
559         FILE *f_fsc;
560         char name_f_fsc[255];
561         EMUFS_BLOCK_ID cant = 0;
562         
563         strcpy(name_f_fsc, efs->nombre);
564         strcat(name_f_fsc, EMUFS_FSC_EXT);
565
566         if (!(f_fsc = fopen(name_f_fsc, "ab"))) {
567                 PERR("error al abrir archivo .fsc");
568                 return EMUFS_NOT_FOUND;
569         }
570         cant = ftell(f_fsc) / sizeof(EMUFS_FSC);
571         fclose(f_fsc);
572         return cant;
573 }
574
575 long emufs_fsc_get_file_size(EMUFS* efs, int* err)
576 {
577         char name[255];
578         strcpy(name, efs->nombre);
579         strcat(name, EMUFS_FSC_EXT);
580         return emufs_common_get_file_size(name, err);
581 }