├── vfs_posix.h ├── vfs_descriptors.h ├── vfs_watchdog_hooks.h ├── README ├── vfs_directory_hooks.h ├── vfs_properties.h ├── vfs_lists.h ├── vfs_properties.c ├── vfs_lists.c ├── vfs_iohook.h ├── vfs.h ├── vfs_posix.c └── vfs.c /vfs_posix.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | /* 3 | * Copyright (C) 2010-2011 Tobias Arrskog 4 | * https://github.com/topfs2/libvfs 5 | * 6 | * This Program is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 2, or (at your option) 9 | * any later version. 10 | * 11 | * This Program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with XBMC; see the file COPYING. If not, write to 18 | * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 19 | * http://www.gnu.org/copyleft/gpl.html 20 | * 21 | */ 22 | 23 | #include "vfs_iohook.h" 24 | 25 | extern const struct vfs_iohook vfs_posix_iohooks; 26 | -------------------------------------------------------------------------------- /vfs_descriptors.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | /* 3 | * Copyright (C) 2010-2011 Tobias Arrskog 4 | * https://github.com/topfs2/libvfs 5 | * 6 | * This Program is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 2, or (at your option) 9 | * any later version. 10 | * 11 | * This Program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with XBMC; see the file COPYING. If not, write to 18 | * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 19 | * http://www.gnu.org/copyleft/gpl.html 20 | * 21 | */ 22 | 23 | #include "vfs_iohook.h" 24 | #include "vfs_lists.h" 25 | #include 26 | #include 27 | 28 | struct vfs_context_t 29 | { 30 | struct vfs_list *iohook_list; 31 | }; 32 | 33 | struct vfs_file_descriptor_t 34 | { 35 | void *fp; 36 | struct vfs_iohook *iohook; 37 | }; 38 | 39 | struct vfs_directory_descriptor_t 40 | { 41 | void *dp; 42 | struct vfs_iohook *iohook; 43 | 44 | pthread_t readdir_thread; 45 | }; 46 | 47 | struct vfs_watchdog_descriptor_t 48 | { 49 | void *wp; 50 | struct vfs_iohook *iohook; 51 | }; 52 | -------------------------------------------------------------------------------- /vfs_watchdog_hooks.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | /* 3 | * Copyright (C) 2010-2011 Tobias Arrskog 4 | * https://github.com/topfs2/libvfs 5 | * 6 | * This Program is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 2, or (at your option) 9 | * any later version. 10 | * 11 | * This Program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with XBMC; see the file COPYING. If not, write to 18 | * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 19 | * http://www.gnu.org/copyleft/gpl.html 20 | * 21 | */ 22 | 23 | #include 24 | 25 | typedef void (*vfs_file_added_hook) (void *cls, const char *file); 26 | typedef void (*vfs_file_removed_hook) (void *cls, const char *file); 27 | typedef void (*vfs_file_updated_hook) (void *cls, const char *file); 28 | typedef void (*vfs_file_moved_hook) (void *cls, const char *from, const char *to); 29 | 30 | struct vfs_notification_callbacks 31 | { 32 | vfs_file_added_hook file_added; 33 | vfs_file_removed_hook file_removed; 34 | vfs_file_updated_hook file_updated; 35 | vfs_file_moved_hook file_moved; 36 | }; 37 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | This vfs library is designed to work the same way as if you were to use posix io. The library will fallback to local reading and is not needed to be added as a iohook for usage. 2 | 3 | To use the library use it exactly like any posix io: 4 | 5 | struct vfs_file_descriptor *fp = vfs_open("temp", O_RDONLY); 6 | 7 | char buffer[1024]; 8 | buffer[0] = '\0'; 9 | 10 | vfs_read(buffer, 1, 16, fp); 11 | buffer[16] = '\0'; 12 | 13 | printf("%s\n", buffer); 14 | 15 | vfs_close(fp); 16 | 17 | Directories can be read and all content they have will have some set of mandatory properties but can have any number of extra metadata, this allows for extending the vfs hooks to provide metadata with the files. Its important though that the property gets freed after used, it will not be garbage collected. 18 | 19 | struct vfs_directory_descriptor *dp = vfs_opendir("/foo/bar/"); 20 | struct vfs_properties *dir; 21 | 22 | while ((dir = vfs_readdir(dp)) != NULL) 23 | { 24 | printf("%s\n", dir->name); 25 | vfs_free_properties(dir); 26 | } 27 | 28 | vfs_closedir(dp); 29 | 30 | The library will have some iohook available but the library is designed around you choosing what you want to initialize, this way you are free to just use the library as a structure and add all iohooks you want. You can also use it only with compiled and available iohooks. Here is an example how you can initialize with all compiled in modules. 31 | 32 | if (vfs_initialize_iohooks(vfs_all_iohooks)) 33 | printf("Failed to initialize all or some iohooks\n"); 34 | -------------------------------------------------------------------------------- /vfs_directory_hooks.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | /* 3 | * Copyright (C) 2010-2011 Tobias Arrskog 4 | * https://github.com/topfs2/libvfs 5 | * 6 | * This Program is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 2, or (at your option) 9 | * any later version. 10 | * 11 | * This Program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with XBMC; see the file COPYING. If not, write to 18 | * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 19 | * http://www.gnu.org/copyleft/gpl.html 20 | * 21 | */ 22 | 23 | #include "vfs.h" 24 | #include 25 | 26 | struct vfs_properties *properties; 27 | struct vfs_metadata *metadata; 28 | 29 | typedef int (*vfs_directory_callback_item) (void *cls, struct vfs_properties *properties); 30 | typedef int (*vfs_directory_callback_item_update) (void *cls, const char *file, struct vfs_metadata *extended_metadata); 31 | typedef void (*vfs_directory_callback_eof) (void *cls); 32 | 33 | struct vfs_directory_callbacks 34 | { 35 | vfs_directory_callback_item item; 36 | vfs_directory_callback_item_update item_update; 37 | vfs_directory_callback_eof eof; 38 | }; 39 | -------------------------------------------------------------------------------- /vfs_properties.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | /* 3 | * Copyright (C) 2010-2011 Tobias Arrskog 4 | * https://github.com/topfs2/libvfs 5 | * 6 | * This Program is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 2, or (at your option) 9 | * any later version. 10 | * 11 | * This Program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with XBMC; see the file COPYING. If not, write to 18 | * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 19 | * http://www.gnu.org/copyleft/gpl.html 20 | * 21 | */ 22 | 23 | #include "vfs_lists.h" 24 | 25 | struct vfs_metadata 26 | { 27 | const char *key; 28 | const char *value; 29 | }; 30 | 31 | struct vfs_properties 32 | { 33 | const char *name; 34 | off_t size; 35 | int hidden; 36 | 37 | struct vfs_list *metadata_list; 38 | int more_metadata_exist; 39 | }; 40 | 41 | struct vfs_metadata * vfs_metadata_create (const char *key, const char *value); 42 | void vfs_metadata_free (struct vfs_metadata *metadata); 43 | 44 | struct vfs_properties * vfs_properties_create (const char *name, int size, int hidden, struct vfs_list *metadata_list); 45 | void vfs_properties_free (struct vfs_properties *properties); 46 | -------------------------------------------------------------------------------- /vfs_lists.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | /* 3 | * Copyright (C) 2010-2011 Tobias Arrskog 4 | * https://github.com/topfs2/libvfs 5 | * 6 | * This Program is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 2, or (at your option) 9 | * any later version. 10 | * 11 | * This Program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with XBMC; see the file COPYING. If not, write to 18 | * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 19 | * http://www.gnu.org/copyleft/gpl.html 20 | * 21 | */ 22 | 23 | #include 24 | 25 | struct vfs_list_node 26 | { 27 | void *data; 28 | struct vfs_list_node *next; 29 | }; 30 | 31 | struct vfs_list 32 | { 33 | struct vfs_list_node *first; 34 | struct vfs_list_node *last; 35 | int size; 36 | }; 37 | 38 | //#define FOREACH(itr, li) for (li = itr; itr ; li = itr = itr->next) 39 | #define FOREACH(itr, li) for (li = (itr ? itr->data : NULL) ; itr ; li = ((itr = itr->next) ? itr->data : NULL) ) 40 | 41 | typedef void (*vfs_list_free_item) (void *item); 42 | 43 | struct vfs_list * vfs_list_create (); 44 | void vfs_list_free (struct vfs_list *list, vfs_list_free_item free_item); 45 | 46 | void vfs_list_append (struct vfs_list *list, void *data); 47 | struct vfs_list * vfs_list_merge (struct vfs_list *a, struct vfs_list *b); 48 | 49 | struct vfs_list_node * vfs_list_begin (struct vfs_list *list); 50 | -------------------------------------------------------------------------------- /vfs_properties.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010-2011 Tobias Arrskog 3 | * https://github.com/topfs2/libvfs 4 | * 5 | * This Program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2, or (at your option) 8 | * any later version. 9 | * 10 | * This Program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with XBMC; see the file COPYING. If not, write to 17 | * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 18 | * http://www.gnu.org/copyleft/gpl.html 19 | * 20 | */ 21 | 22 | #include "vfs_properties.h" 23 | #include 24 | 25 | struct vfs_metadata *vfs_metadata_create(const char *key, const char *value) 26 | { 27 | if (key && value) 28 | { 29 | struct vfs_metadata *metadata = malloc(sizeof(struct vfs_metadata)); 30 | 31 | metadata->key = malloc(sizeof(char) * strlen(key)); 32 | metadata->value = malloc(sizeof(char) * strlen(value)); 33 | 34 | strcpy((char *)metadata->key, key); 35 | strcpy((char *)metadata->value, value); 36 | 37 | return metadata; 38 | } 39 | else 40 | return NULL; 41 | } 42 | 43 | void vfs_metadata_free(struct vfs_metadata *metadata) 44 | { 45 | if (metadata) 46 | { 47 | free((char *)metadata->key); 48 | free((char *)metadata->value); 49 | free(metadata); 50 | } 51 | } 52 | 53 | struct vfs_properties *vfs_properties_create(const char *name, int size, int hidden, struct vfs_list *metadata_list) 54 | { 55 | struct vfs_properties *properties = malloc(sizeof(struct vfs_properties)); 56 | 57 | if (name) 58 | { 59 | properties->name = malloc(sizeof(char) * strlen(name)); 60 | strcpy((char *)properties->name, name); 61 | } 62 | 63 | properties->size = size; 64 | properties->hidden = hidden; 65 | properties->metadata_list = metadata_list; 66 | 67 | return properties; 68 | } 69 | 70 | void vfs_metadata_void_free(void *ptr) 71 | { 72 | vfs_metadata_free((struct vfs_metadata *)ptr); 73 | } 74 | 75 | void vfs_properties_free(struct vfs_properties *properties) 76 | { 77 | if (properties) 78 | { 79 | vfs_list_free(properties->metadata_list, vfs_metadata_void_free); 80 | free((char *)properties->name); 81 | free(properties); 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /vfs_lists.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010-2011 Tobias Arrskog 3 | * https://github.com/topfs2/libvfs 4 | * 5 | * This Program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2, or (at your option) 8 | * any later version. 9 | * 10 | * This Program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with XBMC; see the file COPYING. If not, write to 17 | * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 18 | * http://www.gnu.org/copyleft/gpl.html 19 | * 20 | */ 21 | 22 | #include "vfs_lists.h" 23 | 24 | struct vfs_list *vfs_list_create() 25 | { 26 | struct vfs_list *list = malloc(sizeof(struct vfs_list)); 27 | 28 | list->first = NULL; 29 | list->last = NULL; 30 | list->size = 0; 31 | 32 | return list; 33 | } 34 | 35 | void vfs_list_free_node(struct vfs_list_node *node, vfs_list_free_item free_item) 36 | { 37 | if (node) 38 | { 39 | vfs_list_free_node(node->next, free_item); 40 | 41 | if (free_item && node->data) 42 | free_item(node->data); 43 | 44 | free(node); 45 | } 46 | } 47 | 48 | void vfs_list_free(struct vfs_list *list, vfs_list_free_item free_item) 49 | { 50 | if (list) 51 | { 52 | vfs_list_free_node(list->first, free_item); 53 | free(list); 54 | } 55 | } 56 | 57 | void vfs_list_append(struct vfs_list *list, void *data) 58 | { 59 | if (list) 60 | { 61 | struct vfs_list_node *item = malloc(sizeof(struct vfs_list_node)); 62 | item->data = data; 63 | 64 | if (list->last) 65 | { 66 | list->last->next = item; 67 | list->last = item; 68 | } 69 | else // Should only happen if first is also NULL 70 | list->last = list->first = item; 71 | 72 | list->size++; 73 | } 74 | } 75 | 76 | struct vfs_list *vfs_list_merge(struct vfs_list *a, struct vfs_list *b) 77 | { 78 | if (a) 79 | { 80 | if (b) 81 | { 82 | if (a->last) 83 | { 84 | a->last->next = b->first; 85 | a->last = b->last; 86 | } 87 | else 88 | { 89 | a->first = b->first; 90 | a->last = b->last; 91 | } 92 | 93 | a->size += b->size; 94 | } 95 | 96 | return a; 97 | } 98 | else 99 | return b; 100 | } 101 | 102 | struct vfs_list_node *vfs_list_begin(struct vfs_list *list) 103 | { 104 | if (list) 105 | return list->first; 106 | else 107 | return NULL; 108 | } 109 | -------------------------------------------------------------------------------- /vfs_iohook.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | /* 3 | * Copyright (C) 2010-2011 Tobias Arrskog 4 | * https://github.com/topfs2/libvfs 5 | * 6 | * This Program is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 2, or (at your option) 9 | * any later version. 10 | * 11 | * This Program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with XBMC; see the file COPYING. If not, write to 18 | * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 19 | * http://www.gnu.org/copyleft/gpl.html 20 | * 21 | */ 22 | 23 | #include 24 | 25 | struct vfs_file_descriptor; 26 | struct vfs_directory_descriptor; 27 | struct vfs_watch_descriptor; 28 | struct vfs_properties; 29 | struct vfs_metadata; 30 | 31 | typedef void * (*vfs_open_hook) (const char *filepath, int flags); 32 | typedef size_t (*vfs_read_hook) (void *fp, void *buffer, size_t size, size_t count); 33 | typedef size_t (*vfs_write_hook) (void *fp, const void *buffer, size_t size, size_t count); 34 | typedef int (*vfs_seek_hook) (void *fp, long int offset, int origin); 35 | typedef long int (*vfs_tell_hook) (void *fp); 36 | typedef struct vfs_properties * (*vfs_stat_hook) (const char *filepath); 37 | typedef int (*vfs_flush_hook) (void *fp); 38 | typedef int (*vfs_close_hook) (void *fp); 39 | 40 | typedef void * (*vfs_opendir_hook) (const char *directorypath); 41 | typedef void (*vfs_readdir_hook) (void *dp, void *cls, struct vfs_directory_callbacks callback); 42 | typedef int (*vfs_closedir_hook) (void *dp); 43 | 44 | typedef void * (*vfs_add_watch_hook) (const char *watchpath, struct vfs_notification_callbacks callbacks, void *cls); 45 | typedef int (*vfs_remove_watch_hook) (void *wp); 46 | 47 | struct vfs_iohook 48 | { 49 | // File hooks 50 | vfs_open_hook open; 51 | vfs_read_hook read; 52 | vfs_write_hook write; 53 | vfs_seek_hook seek; 54 | vfs_tell_hook tell; 55 | vfs_stat_hook stat; 56 | vfs_flush_hook flush; 57 | vfs_close_hook close; 58 | 59 | // Directory hooks 60 | vfs_opendir_hook opendir; 61 | vfs_readdir_hook readdir; 62 | vfs_closedir_hook closedir; 63 | 64 | // Watchdog hooks (optional) 65 | vfs_add_watch_hook add_watch; 66 | vfs_remove_watch_hook remove_watch; 67 | 68 | void *cls; 69 | }; 70 | -------------------------------------------------------------------------------- /vfs.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | /* 3 | * Copyright (C) 2010-2011 Tobias Arrskog 4 | * https://github.com/topfs2/libvfs 5 | * 6 | * This Program is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 2, or (at your option) 9 | * any later version. 10 | * 11 | * This Program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with XBMC; see the file COPYING. If not, write to 18 | * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 19 | * http://www.gnu.org/copyleft/gpl.html 20 | * 21 | */ 22 | 23 | #include "vfs_lists.h" 24 | #include "vfs_directory_hooks.h" 25 | #include "vfs_watchdog_hooks.h" 26 | #include 27 | 28 | enum vfs_available_iohooks 29 | { 30 | vfs_none = 0x00, 31 | vfs_file = 0x01 32 | }; 33 | 34 | extern const int vfs_default_iohooks; 35 | extern const int vfs_all_iohooks; 36 | 37 | // The opaque structs 38 | typedef struct vfs_context_t * vfs_context; 39 | typedef struct vfs_file_descriptor_t * vfs_file_descriptor; 40 | typedef struct vfs_directory_descriptor_t * vfs_directory_descriptor; 41 | typedef struct vfs_watchdog_descriptor_t * vfs_watchdog_descriptor; 42 | 43 | typedef struct vfs_readdir_control_t * vfs_readdir_control; 44 | 45 | struct vfs_iohook; 46 | 47 | // Context methods 48 | vfs_context vfs_initialize (int iohooks); 49 | int vfs_add_iohook (vfs_context ctx, const char *protocol, struct vfs_iohook *hook); 50 | 51 | // File methods 52 | vfs_file_descriptor vfs_open (vfs_context ctx, const char *filepath, int flags); 53 | size_t vfs_read (vfs_file_descriptor fp, void *buffer, size_t size, size_t count); 54 | size_t vfs_write (vfs_file_descriptor fp, const void *buffer, size_t size, size_t count); 55 | int vfs_seek (vfs_file_descriptor fp, long int offset, int origin); 56 | long int vfs_tell (vfs_file_descriptor fp); 57 | struct vfs_properties * vfs_stat (vfs_context ctx, const char *filepath); 58 | int vfs_flush (vfs_file_descriptor fp); 59 | int vfs_close (vfs_file_descriptor fp); 60 | 61 | // Directory methods 62 | vfs_directory_descriptor vfs_opendir (vfs_context ctx, const char *directorypath); 63 | void vfs_readdir_sync (vfs_directory_descriptor dp, struct vfs_directory_callbacks callbacks, void *cls); 64 | int vfs_closedir (vfs_directory_descriptor dp); 65 | 66 | // Watchdog methods 67 | vfs_watchdog_descriptor vfs_add_watch (vfs_context ctx, const char *watchpath, struct vfs_notification_callbacks callbacks, void *cls); 68 | int vfs_remove_watch (vfs_watchdog_descriptor wp); 69 | -------------------------------------------------------------------------------- /vfs_posix.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010-2011 Tobias Arrskog 3 | * https://github.com/topfs2/libvfs 4 | * 5 | * This Program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2, or (at your option) 8 | * any later version. 9 | * 10 | * This Program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with XBMC; see the file COPYING. If not, write to 17 | * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 18 | * http://www.gnu.org/copyleft/gpl.html 19 | * 20 | */ 21 | 22 | #include "vfs.h" 23 | #include "vfs_posix.h" 24 | #include "vfs_properties.h" 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | const char *strip_protocol(const char *path) 32 | { 33 | return strncmp("file://", path, 7) == 0 ? path + 7 : path; 34 | } 35 | 36 | void *vfs_posix_open(const char *filepath, int flags); 37 | size_t vfs_posix_read(void *fp, void *buffer, size_t size, size_t count); 38 | size_t vfs_posix_write(void *fp, const void *buffer, size_t size, size_t count); 39 | int vfs_posix_seek(void *fp, long int offset, int origin); 40 | long int vfs_posix_tell(void *fp); 41 | struct vfs_properties *vfs_posix_stat(const char *filepath); 42 | int vfs_posix_flush(void *fp); 43 | int vfs_posix_close(void *fp); 44 | void *vfs_posix_opendir(const char *directorypath); 45 | void vfs_posix_readdir(void *dp, void *cls, struct vfs_directory_callbacks callbacks); 46 | int vfs_posix_closedir(void *dp); 47 | void *vfs_posix_add_watch(const char *watchpath, struct vfs_notification_callbacks callbacks, void *cls); 48 | int vfs_posix_remove_watch(void *cls); 49 | 50 | void *vfs_posix_open(const char *filepath, int flags) 51 | { 52 | const char *stripped_filepath = strip_protocol(filepath); 53 | struct stat buffer; 54 | if (flags & O_EXCL && flags & O_CREAT && stat(stripped_filepath, &buffer) == 0) 55 | return NULL; 56 | 57 | char mode[16]; 58 | int i = 0; 59 | 60 | if (!(flags & O_WRONLY) || flags & O_RDWR) 61 | mode[i++] = 'r'; 62 | if (flags & O_WRONLY || flags & O_RDWR) 63 | mode[i++] = 'w'; 64 | 65 | mode[i++] = 'b'; 66 | 67 | if (flags & O_APPEND) 68 | mode[i++] = 'a'; 69 | if (flags & O_CREAT) 70 | mode[i++] = '+'; 71 | 72 | mode[i] = '\0'; 73 | 74 | FILE *fp = fopen(stripped_filepath, mode); 75 | if (fp) 76 | { 77 | if (flags & O_APPEND) 78 | vfs_posix_seek(fp, 0, SEEK_END); 79 | 80 | return fp; 81 | } 82 | else 83 | return NULL; 84 | } 85 | 86 | size_t vfs_posix_read(void *fp, void *buffer, size_t size, size_t count) 87 | { 88 | return fread(buffer, size, count, (FILE *)fp); 89 | } 90 | 91 | size_t vfs_posix_write(void *fp, const void *buffer, size_t size, size_t count) 92 | { 93 | return fwrite(buffer, size, count, (FILE *)fp); 94 | } 95 | 96 | int vfs_posix_seek(void *fp, long int offset, int origin) 97 | { 98 | return fseek((FILE *)fp, offset, origin); 99 | } 100 | 101 | long int vfs_posix_tell(void *fp) 102 | { 103 | return ftell((FILE *)fp); 104 | } 105 | 106 | struct vfs_properties *vfs_posix_stat(const char *filepath) 107 | { 108 | // TODO name and hidden should be proper 109 | struct stat buffer; 110 | if (stat(strip_protocol(filepath), &buffer) == 0) 111 | return (struct vfs_properties *)vfs_properties_create(NULL, 0, 0, NULL); 112 | else 113 | return NULL; 114 | } 115 | 116 | int vfs_posix_flush(void *fp) 117 | { 118 | return fflush((FILE *)fp); 119 | } 120 | 121 | int vfs_posix_close(void *fp) 122 | { 123 | return fclose((FILE *)fp); 124 | } 125 | 126 | void *vfs_posix_opendir(const char *directorypath) 127 | { 128 | DIR *dp = opendir(strip_protocol(directorypath)); 129 | if (dp) 130 | return dp; 131 | 132 | return NULL; 133 | } 134 | 135 | void vfs_posix_readdir(void *dp, void *cls, struct vfs_directory_callbacks callbacks) 136 | { 137 | struct dirent *dir; 138 | 139 | do 140 | { 141 | dir = readdir(dp); 142 | if (dir) 143 | callbacks.item(cls, vfs_properties_create(dir->d_name, 0, 0, NULL)); 144 | 145 | } while (dir != NULL); 146 | 147 | callbacks.eof(cls); 148 | } 149 | 150 | int vfs_posix_closedir(void *dp) 151 | { 152 | return closedir((DIR *)dp); 153 | } 154 | 155 | void *vfs_posix_add_watch(const char *watchpath, struct vfs_notification_callbacks callbacks, void *cls) 156 | { 157 | return NULL; 158 | } 159 | 160 | int vfs_posix_remove_watch(void *cls) 161 | { 162 | return 0; 163 | } 164 | 165 | const struct vfs_iohook vfs_posix_iohooks = 166 | { 167 | vfs_posix_open, 168 | vfs_posix_read, 169 | vfs_posix_write, 170 | vfs_posix_seek, 171 | vfs_posix_tell, 172 | vfs_posix_stat, 173 | vfs_posix_flush, 174 | vfs_posix_close, 175 | 176 | vfs_posix_opendir, 177 | vfs_posix_readdir, 178 | vfs_posix_closedir, 179 | 180 | vfs_posix_add_watch, 181 | vfs_posix_remove_watch, 182 | 183 | NULL 184 | }; 185 | -------------------------------------------------------------------------------- /vfs.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010-2011 Tobias Arrskog 3 | * https://github.com/topfs2/libvfs 4 | * 5 | * This Program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2, or (at your option) 8 | * any later version. 9 | * 10 | * This Program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with XBMC; see the file COPYING. If not, write to 17 | * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 18 | * http://www.gnu.org/copyleft/gpl.html 19 | * 20 | */ 21 | 22 | #include "vfs.h" 23 | #include "vfs_descriptors.h" 24 | #include "vfs_posix.h" 25 | #include 26 | 27 | const int vfs_default_iohooks = vfs_file; 28 | const int vfs_all_iohooks = vfs_file; 29 | 30 | struct vfs_module 31 | { 32 | const char *protocol; 33 | struct vfs_iohook *iohook; 34 | }; 35 | 36 | struct vfs_module_node 37 | { 38 | enum vfs_available_iohooks flag; 39 | struct vfs_module module; 40 | }; 41 | 42 | struct vfs_module_node vfs_static_vfs_modules[] = 43 | { 44 | { vfs_file, { "file", &vfs_posix_iohooks } }, 45 | { vfs_none, { NULL, NULL } } 46 | }; 47 | 48 | /* Helper methods, should be moved later */ 49 | struct vfs_module *vfs_create_module(const char *protocol, struct vfs_iohook *iohook) 50 | { 51 | struct vfs_module *module = malloc(sizeof(struct vfs_module)); 52 | 53 | int len = strlen(protocol) + 1; 54 | 55 | module->protocol = malloc(sizeof(char) * len); 56 | strncpy((char *)module->protocol, protocol, len); 57 | module->iohook = iohook; 58 | 59 | return module; 60 | } 61 | 62 | struct vfs_iohook *vfs_find_iohooks(vfs_context ctx, const char *filepath) 63 | { 64 | if (ctx) 65 | { 66 | struct vfs_module *li; 67 | struct vfs_list_node *itr = vfs_list_begin(ctx->iohook_list); 68 | FOREACH(itr, li) 69 | { 70 | if (strncmp(filepath, li->protocol, strlen(li->protocol)) == 0) 71 | return li->iohook; 72 | } 73 | } 74 | 75 | return NULL; 76 | } 77 | 78 | /* Normal methods which belongs in vfs.c */ 79 | 80 | vfs_context vfs_initialize(int iohooks) 81 | { 82 | int failed = 0; 83 | vfs_context ctx = malloc(sizeof(struct vfs_context_t)); 84 | ctx->iohook_list = vfs_list_create(); 85 | 86 | struct vfs_module_node *itr = vfs_static_vfs_modules; 87 | while (itr->flag != vfs_none) 88 | { 89 | if (!(itr->flag & iohooks && vfs_add_iohook(ctx, itr->module.protocol, itr->module.iohook) == 0)) 90 | failed |= itr->flag; 91 | 92 | itr++; 93 | } 94 | 95 | return ctx; 96 | } 97 | 98 | int vfs_add_iohook(vfs_context ctx, const char *protocol, struct vfs_iohook *iohook) 99 | { 100 | if (ctx) 101 | { 102 | struct vfs_module *module = vfs_create_module(protocol, iohook); 103 | vfs_list_append(ctx->iohook_list, module); 104 | 105 | return 0; 106 | } 107 | 108 | return 1; 109 | } 110 | 111 | vfs_file_descriptor vfs_open(vfs_context ctx, const char *filepath, int flags) 112 | { 113 | struct vfs_iohook *iohook = vfs_find_iohooks(ctx, filepath); 114 | 115 | if (iohook && iohook->open) 116 | { 117 | vfs_file_descriptor fp = malloc(sizeof(struct vfs_file_descriptor_t)); 118 | 119 | fp->fp = iohook->open(filepath, flags); 120 | fp->iohook = iohook; 121 | 122 | if (fp->fp) 123 | return fp; 124 | else 125 | free(fp); 126 | } 127 | 128 | return NULL; 129 | } 130 | 131 | size_t vfs_read(vfs_file_descriptor fp, void *buffer, size_t size, size_t count) 132 | { 133 | if (fp) 134 | { 135 | struct vfs_iohook *iohook = fp->iohook; 136 | 137 | if (iohook && iohook->read) 138 | return iohook->read(fp->fp, buffer, size, count); 139 | } 140 | return 0; 141 | } 142 | 143 | size_t vfs_write(vfs_file_descriptor fp, const void *buffer, size_t size, size_t count) 144 | { 145 | if (fp) 146 | { 147 | struct vfs_iohook *iohook = fp->iohook; 148 | 149 | if (iohook && iohook->write) 150 | return iohook->write(fp->fp, buffer, size, count); 151 | } 152 | 153 | return 0; 154 | } 155 | 156 | int vfs_seek(vfs_file_descriptor fp, long int offset, int origin) 157 | { 158 | if (fp) 159 | { 160 | struct vfs_iohook *iohook = fp->iohook; 161 | 162 | if (iohook && iohook->seek) 163 | return iohook->seek(fp->fp, offset, origin); 164 | } 165 | 166 | return 0; 167 | } 168 | 169 | long int vfs_tell(vfs_file_descriptor fp) 170 | { 171 | if (fp) 172 | { 173 | struct vfs_iohook *iohook = fp->iohook; 174 | 175 | if (iohook && iohook->tell) 176 | return iohook->tell(fp->fp); 177 | } 178 | 179 | return 0; 180 | } 181 | 182 | struct vfs_properties *vfs_stat(vfs_context ctx, const char *filepath) 183 | { 184 | struct vfs_iohook *iohook = vfs_find_iohooks(ctx, filepath); 185 | 186 | if (iohook && iohook->stat) 187 | return iohook->stat(filepath); 188 | 189 | return NULL; 190 | } 191 | 192 | int vfs_flush(vfs_file_descriptor fp) 193 | { 194 | if (fp) 195 | { 196 | struct vfs_iohook *iohook = fp->iohook; 197 | 198 | if (iohook && iohook->flush) 199 | return iohook->flush(fp->fp); 200 | } 201 | 202 | return 0; 203 | } 204 | 205 | int vfs_close(vfs_file_descriptor fp) 206 | { 207 | if (fp) 208 | { 209 | struct vfs_iohook *iohook = fp->iohook; 210 | 211 | if (iohook && iohook->close) 212 | { 213 | int result = iohook->close(fp->fp); 214 | free(fp); 215 | return result; 216 | } 217 | } 218 | 219 | return 0; 220 | } 221 | 222 | vfs_directory_descriptor vfs_opendir(vfs_context ctx, const char *directorypath) 223 | { 224 | struct vfs_iohook *iohook = vfs_find_iohooks(ctx, directorypath); 225 | 226 | if (iohook && iohook->opendir) 227 | { 228 | vfs_directory_descriptor dp = malloc(sizeof(struct vfs_directory_descriptor_t)); 229 | 230 | dp->dp = iohook->opendir(directorypath); 231 | dp->iohook = iohook; 232 | 233 | if (dp->dp) 234 | return dp; 235 | else 236 | free(dp); 237 | } 238 | 239 | return NULL; 240 | } 241 | 242 | void vfs_readdir_sync(vfs_directory_descriptor dp, struct vfs_directory_callbacks callbacks, void *cls) 243 | { 244 | if (dp) 245 | { 246 | struct vfs_iohook *iohook = dp->iohook; 247 | 248 | if (iohook && iohook->readdir) 249 | iohook->readdir(dp->dp, cls, callbacks); 250 | } 251 | } 252 | 253 | void vfs_readdir_async(vfs_directory_descriptor dp, struct vfs_directory_callbacks callbacks, void *cls) 254 | { 255 | if (dp) 256 | { 257 | struct vfs_iohook *iohook = dp->iohook; 258 | 259 | if (iohook && iohook->readdir) 260 | iohook->readdir(dp->dp, cls, callbacks); 261 | } 262 | } 263 | 264 | int vfs_closedir(vfs_directory_descriptor dp) 265 | { 266 | if (dp) 267 | { 268 | struct vfs_iohook *iohook = dp->iohook; 269 | 270 | if (iohook && iohook->closedir) 271 | { 272 | int result = iohook->closedir(dp->dp); 273 | free(dp); 274 | return result; 275 | } 276 | } 277 | 278 | return 0; 279 | } 280 | 281 | vfs_watchdog_descriptor vfs_add_watch(vfs_context ctx, const char *watchpath, struct vfs_notification_callbacks callbacks, void *cls) 282 | { 283 | return NULL; 284 | } 285 | 286 | int vfs_remove_watch(vfs_watchdog_descriptor wp) 287 | { 288 | return 0; 289 | } 290 | --------------------------------------------------------------------------------