#include "sffisico.h" #include "errores.h" #include <fcntl.h> #include <string.h> #include <stdlib.h> #include <errno.h> /* Dependencias del sistema */ #ifdef __MSDOS__ #include <io.h> #include <sys/stat.h> #define PERMISOS_DISCO (S_IREAD|S_IWRITE) #define MODO (O_RDWR|O_BINARY) #else #include <unistd.h> #define PERMISOS_DISCO 0644 #define MODO O_RDWR #endif enum Errores Error_SF; /* Variables internas del módulo */ static int Disco = -1; static WORD TamBloqueFisico = 0; static DWORD NumBloquesFisicos = 0; /* Instalación de un disco */ int FabricaDisco (const char* nombre_fichero,WORD tam_bloque,DWORD num_bloques) { struct Superbloque bl; DWORD tam_total = tam_bloque*num_bloques; int err; int fd; if ( tam_total>MAX_TAMDISCO || tam_bloque>MAX_TAMBLOQUE || tam_total<num_bloques ) { Error_SF = ERR_RANGO; return -1; } #ifdef __MSDOS__ _fmode=O_BINARY; #endif /* Crea el fichero */ fd = creat (nombre_fichero,PERMISOS_DISCO); if ( fd==-1 ) { switch (errno) { case EACCES: Error_SF = ERR_PERMISOS; return -1; default: Error_SF = ERR_DISCO; return -1; } } #ifdef __MSDOS__ err=chsize (fd,tam_total); #else err=ftruncate (fd,tam_total); #endif if (err==-1) { Error_SF=ERR_DISCO; return -1; } /* Escribe los datos del superbloque */ strcpy(bl.magico,MAGICO); bl.tam_bloque_fisico = tam_bloque; bl.num_bloques_fisicos = num_bloques; write(fd,&bl,TAM_SUPERBLOQUE); close(fd); Error_SF = ERR_SINERROR; return 0; } /* FabricaDisco */ /* Monta un disco para su uso */ /* se ignora el parámetro nbloques_cache */ int MontaDisco ( const char* nombre_fichero, int nbloques_cache ) { struct Superbloque bl; int ok; if (Disco!=-1) close(Disco); Disco = open(nombre_fichero,MODO); if ( Disco==-1 ) { switch (errno) { case EACCES: Error_SF=ERR_PERMISOS; case ENOENT: Error_SF=ERR_NOEXISTE; default: Error_SF=ERR_DISCO; } return -1; } /* Lee información del bloque cero */ ok=LeeDatosDisco (&TamBloqueFisico,&NumBloquesFisicos); if (ok==-1) return -1; Error_SF=ERR_SINERROR; return 0; } /* MontaDisco */ int DesmontaDisco (void) { int ok; if (Disco==-1) { Error_SF=ERR_INACTIVO; return -1; } ok = close(Disco); if (ok==-1) { Error_SF=ERR_DISCO; return -1; } else { Error_SF=ERR_SINERROR; return 0; } } /* Acceso a un bloque físico (lectura o escritura) */ enum { LECTURA, ESCRITURA }; int AccedeBloqueFisico ( DWORD nbloque, void* bufer,enum ModoAccesoFisico modo ) { Error_SF=ERR_SINERROR; #ifdef DEBUG printf("[%s:%d] ",modo==ACCESO_FISICO_LECTURA?"R":"W",nbloque); #endif if ( Disco==-1 ) { Error_SF=ERR_INACTIVO; return -1; } if ( nbloque>=NumBloquesFisicos ) { Error_SF=ERR_RANGO; return -1; } lseek (Disco,nbloque*TamBloqueFisico,SEEK_SET); switch (modo) { case ACCESO_FISICO_ESCRITURA: return write ( Disco,bufer,TamBloqueFisico ) ==TamBloqueFisico; case ACCESO_FISICO_LECTURA: return read ( Disco,bufer,TamBloqueFisico ) ==TamBloqueFisico; default: Error_SF=ERR_CORRUPTO; return -1; } } int LeeBloqueFisico ( DWORD nbloque, void* bufer ) { return AccedeBloqueFisico(nbloque,bufer,LECTURA); } int EscribeBloqueFisico ( DWORD nbloque, const void* bufer ) { return AccedeBloqueFisico(nbloque,(void*)bufer,ESCRITURA); } /* Acceso al superbloque (datos del disco) */ int LeeDatosDisco ( WORD* tam_bloque, DWORD* num_bloques ) { struct Superbloque sb; if (Disco==-1) { Error_SF=ERR_INACTIVO; return -1; } /* Recoge el superbloque */ lseek(Disco,0,SEEK_SET); read(Disco,&sb,TAM_SUPERBLOQUE); /* Verifica que el disco tiene la "palabra mágica" */ if ( strcmp(sb.magico,MAGICO) ) { Error_SF=ERR_FORMATO; return -1; } /* Verifica que el tamaño de bloque físico es correcto */ if ( sb.tam_bloque_fisico<MIN_TAMBLOQUE || sb.tam_bloque_fisico>MAX_TAMBLOQUE || sb.num_bloques_fisicos==0 ) { Error_SF = ERR_FORMATO; return -1; } *tam_bloque = sb.tam_bloque_fisico; *num_bloques = sb.num_bloques_fisicos; Error_SF = ERR_SINERROR; return 0; }