diff options
Diffstat (limited to 'src/libs/uio/fstypes.c')
-rw-r--r-- | src/libs/uio/fstypes.c | 272 |
1 files changed, 272 insertions, 0 deletions
diff --git a/src/libs/uio/fstypes.c b/src/libs/uio/fstypes.c new file mode 100644 index 0000000..d940e8f --- /dev/null +++ b/src/libs/uio/fstypes.c @@ -0,0 +1,272 @@ +/* + * Copyright (C) 2003 Serge van den Boom + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * Nota bene: later versions of the GNU General Public License do not apply + * to this program. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include <errno.h> +#include <stdio.h> + +#include "iointrn.h" +#include "uioport.h" +#include "fstypes.h" +#include "mem.h" +#include "defaultfs.h" +#ifdef uio_MEM_DEBUG +# include "memdebug.h" +#endif + + +static uio_bool uio_validFileSystemHandler(uio_FileSystemHandler *handler); +static uio_FileSystemInfo *uio_FileSystemInfo_new(uio_FileSystemID id, + uio_FileSystemHandler *handler, char *name); +static uio_FileSystemInfo **uio_getFileSystemInfoPtr(uio_FileSystemID id); + +static inline uio_FileSystemInfo *uio_FileSystemInfo_alloc(void); + +static inline void uio_FileSystemInfo_free( + uio_FileSystemInfo *fileSystemInfo); + + +uio_FileSystemInfo *uio_fileSystems = NULL; + // list sorted by id + + + +void +uio_registerDefaultFileSystems(void) { + int i; + int num; + uio_FileSystemID registerResult; + + num = uio_numDefaultFileSystems(); + for (i = 0; i < num; i++) { + registerResult = uio_registerFileSystem( + defaultFileSystems[i].id, + defaultFileSystems[i].name, + defaultFileSystems[i].handler); + switch (registerResult) { + case 0: + fprintf(stderr, "Warning: Default file system '%s' is " + "already registered.\n", + defaultFileSystems[i].name); + break; + case -1: + fprintf(stderr, "Error: Could not register '%s' file \n" + "system: %s\n", defaultFileSystems[i].name, + strerror(errno)); + break; + default: + assert(registerResult == defaultFileSystems[i].id); + break; + } + } +} + +void +uio_unRegisterDefaultFileSystems(void) { + int i; + int num; + + num = uio_numDefaultFileSystems(); + for (i = 0; i < num; i++) { + if (uio_unRegisterFileSystem(defaultFileSystems[i].id) == -1) { + fprintf(stderr, "Could not unregister '%s' file system: %s\n", + defaultFileSystems[i].name, strerror(errno)); + } + } +} + +// if wantedID = 0, just pick one +// if wantedID != 0, 0 will be returned if that id wasn't available +// a copy of 'name' is made +uio_FileSystemID +uio_registerFileSystem(uio_FileSystemID wantedID, const char *name, + uio_FileSystemHandler *handler) { + uio_FileSystemInfo **ptr; + + if (!uio_validFileSystemHandler(handler)) { + errno = EINVAL; + return -1; + } + if (wantedID == 0) { + // Search for the first free id >= uio_FIRST_CUSTOM_ID + // it is put in wantedID + + for (ptr = &uio_fileSystems; *ptr != NULL; ptr = &(*ptr)->next) + if ((*ptr)->id >= uio_FS_FIRST_CUSTOM_ID) + break; + + wantedID = uio_FS_FIRST_CUSTOM_ID; + while (*ptr != NULL) { + if ((*ptr)->id != wantedID) { + // wantedID is not in use + break; + } + wantedID++; + ptr = &(*ptr)->next; + } + // wantedID contains the new ID + } else { + // search for the place in the list where to insert the wanted + // id, keeping the list sorted + for (ptr = &uio_fileSystems; *ptr != NULL; ptr = &(*ptr)->next) { + if ((*ptr)->id <= wantedID) { + if ((*ptr)->id == wantedID) + return 0; + break; + } + } + + } + // ptr points to the place where the new link can inserted + + if (handler->init != NULL && handler->init() == -1) { + // errno is set + return -1; + } + + { + uio_FileSystemInfo *newInfo; + + newInfo = uio_FileSystemInfo_new(wantedID, handler, uio_strdup(name)); + newInfo->next = *ptr; + *ptr = newInfo; + return wantedID; + } +} + +int +uio_unRegisterFileSystem(uio_FileSystemID id) { + uio_FileSystemInfo **ptr; + uio_FileSystemInfo *temp; + + ptr = uio_getFileSystemInfoPtr(id); + if (ptr == NULL) { + errno = EINVAL; + return -1; + } + if ((*ptr)->ref > 1) { + errno = EBUSY; + return -1; + } + + if ((*ptr)->handler->unInit != NULL && + ((*ptr)->handler->unInit() == -1)) { + // errno is set + return -1; + } + + temp = *ptr; + *ptr = (*ptr)->next; + +// uio_FileSystemHandler_unref(temp->handler); + uio_free(temp->name); + uio_FileSystemInfo_free(temp); + + return 0; +} + +static uio_bool +uio_validFileSystemHandler(uio_FileSystemHandler *handler) { + // Check for the essentials + if (handler->mount == NULL || + handler->umount == NULL || + handler->open == NULL || + handler->close == NULL || + handler->read == NULL || + handler->openEntries == NULL || + handler->readEntries == NULL || + handler->closeEntries == NULL) { +#ifdef DEBUG + fprintf(stderr, "Invalid file system handler.\n"); +#endif + return false; + } + return true; +} + +uio_FileSystemHandler * +uio_getFileSystemHandler(uio_FileSystemID id) { + uio_FileSystemInfo *ptr; + + for (ptr = uio_fileSystems; ptr != NULL; ptr = ptr->next) { + if (ptr->id == id) + return ptr->handler; + } + return NULL; +} + +uio_FileSystemInfo * +uio_getFileSystemInfo(uio_FileSystemID id) { + uio_FileSystemInfo *ptr; + + for (ptr = uio_fileSystems; ptr != NULL; ptr = ptr->next) { + if (ptr->id == id) + return ptr; + } + return NULL; +} + +static uio_FileSystemInfo ** +uio_getFileSystemInfoPtr(uio_FileSystemID id) { + uio_FileSystemInfo **ptr; + + for (ptr = &uio_fileSystems; *ptr != NULL; ptr = &(*ptr)->next) { + if ((*ptr)->id == id) + return ptr; + } + return NULL; +} + +// sets ref to 1 +static uio_FileSystemInfo * +uio_FileSystemInfo_new(uio_FileSystemID id, uio_FileSystemHandler *handler, + char *name) { + uio_FileSystemInfo *result; + + result = uio_FileSystemInfo_alloc(); + result->id = id; + result->handler = handler; + result->name = name; + result->ref = 1; + return result; +} + +// *** Allocators *** + +static inline uio_FileSystemInfo * +uio_FileSystemInfo_alloc(void) { + uio_FileSystemInfo *result = uio_malloc(sizeof (uio_FileSystemInfo)); +#ifdef uio_MEM_DEBUG + uio_MemDebug_debugAlloc(uio_FileSystemInfo, (void *) result); +#endif + return result; +} + + +// *** Deallocators *** + +static inline void +uio_FileSystemInfo_free(uio_FileSystemInfo *fileSystemInfo) { +#ifdef uio_MEM_DEBUG + uio_MemDebug_debugFree(uio_FileSystemInfo, (void *) fileSystemInfo); +#endif + uio_free(fileSystemInfo); +} + + |