/* IRCfs - IRC FileServ for *nix. * Copyright (C) 2002 Nick 'Zaf' Clifford * For licensing details, refer to the LICENSE file in the source * code directory. */ #ifndef __file_h__ #define __file_h__ #include #include #include struct file_handler; struct file; struct fileset; struct dir_handler; struct dir; int register_file_handler(struct file_handler *fh); int register_dir_handler(struct dir_handler *fh); struct file_handler *find_file_handler(const char *name); struct dir_handler *find_dir_handler(const char *name); struct fileset { const char *name; struct dir *root_dir; }; struct file { int unqid; struct file_handler *handler; void *appdata; void *data; }; struct dir { int unqid; struct dir_handler *handler; void *appdata; void *data; }; typedef int (*dir_traverse_files_t)(struct dir *, const char *, void *); typedef int (*dir_traverse_dirs_t)(struct dir *, const char *, void *); struct dir_handler { /* name of the directory handler */ const char *name; /* Returns a string representing the dir name, not including * full path */ const char *(*get_name)(struct dir *file); /* Returns a string representing the dirs full name and path * in the system. */ const char *(*get_full_name)(struct dir *file); /* Returns a string representing the dirs relative name and path * Relative to the root of the virtual file system */ const char *(*get_relative_name)(struct dir *file); struct dir *(*create)(struct dir *parent, const char *name); struct dir *(*open)(struct dir *parent, const char *name); int (*close)(struct dir *dir); int (*list_files)(struct dir *dir, dir_traverse_files_t, void *data); int (*list_dirs)(struct dir *dir, dir_traverse_dirs_t, void *data); /* Gets and sets application specific data. Does NOT * free this data in any way when the file is closed */ void (*set_app_data)(struct dir *,void *appdata); void *(*get_app_data)(struct dir *); }; enum file_callback_type { file_can_read, file_can_write }; typedef int (*file_callback_t)(struct file *, enum file_callback_type type); enum file_flags { file_flag_none = 0x00, /* The file is opened for read only */ file_flag_readonly = 0x01, /* The file is opened for reading and writing. * If neither nosmash nor smash have been supplied, then * the file position is set the the beginning of the file, but * the contents remain intact */ file_flag_readwrite = 0x02, /* Don't overwrite an existing file. * If creating a file with this flag, then don't overwrite * a file that already exists. */ file_flag_nosmash = 0x04, /* Overwrite any existing file. * If opening an existing file for write, set the file size to 0 * first. * If creating a file, overwrite any existing file. * Not valid with readonly (makes no sense) */ file_flag_smash = 0x08, /* Create the file if it doesn't exist. Doesn't need to be * passed to create */ file_flag_create = 0x10 }; struct file_handler { /* name of the file handler */ const char *name; /* Returns a string representing the files name, not including * full path */ const char *(*get_name)(struct file *file); /* Returns a string representing the files full name and path * in the system. */ const char *(*get_full_name)(struct file *file); /* Returns a string representing the files relative name and path * Relative to the root of the virtual file system */ const char *(*get_relative_name)(struct file *file); /* Gets and sets application specific data. Does NOT * free this data in any way when the file is closed */ void (*set_app_data)(struct file *,void *appdata); void *(*get_app_data)(struct file *); /* Returns 0 if given filename is a valid name consisting of * valid charactesr for this filehandlers. * Returns -1 otherwise */ int (*validate_name)(const char *filename); /* Create a file inside the specified dir, named "name" * You must supply atleast either flag_flag_readonly or * file_flag_readwrite. */ struct file *(*create)(struct dir *dir, const char *name, enum file_flags flags); /* Open a file in the current directory named "name" * You must supply atleast either flag_flag_readonly or * file_flag_readwrite. */ struct file *(*open)(struct dir *dir, const char *name, enum file_flags flags); int (*exists)(struct dir *dir, const char *name); /* Close the file. Don't refer to file * again after this */ int (*close)(struct file *); /* Returns 1 if the file position is at the end of file */ int (*eof)(struct file *); /* Get/Set a string statistic for a file */ int (*set_str_statistic)(struct file *file, const char *name, const char *value); int (*get_str_statistic)(struct file *file, const char *name, char *buffer, size_t buff_size); /* Get/Set an integer statistic for a file */ int (*set_int_statistic)(struct file *file, const char *name, int value); int (*get_int_statistic)(struct file *file, int *buffer); size_t (*get_size)(struct file *file); /* Read from the file. * Returns -1 on error. * Returns 0 if at EOF or if action would block. * Returns number of bytes read otherwise. */ int (*read)(struct file *file, char *buffer, size_t size); /* Write to the file * Returns -1 on error. * Returns 0 if action would block, or size == 0 * Returns number of bytes written otherwise (may be less than size!) */ int (*write)(struct file *file, char *buffer, size_t size); /* Sets the current position in the file. * Whence can be one of: * SEEK_SET: position is absolute * SEEK_END: position is from the end of file * SEEK_CUR: position is relative to current position */ int (*lseek)(struct file *file, int whence, u_int32_t position); /* Register a callback on this file waiting util it can read/write * When the file is ready, it calls the specified function. * multiple callback handlers for the same type are NOT supported. */ int (*set_callback)(struct file *file, enum file_callback_type type, file_callback_t func); }; void file_set_app_data(struct file *f, void *appdata); void *file_get_app_data(struct file *f); void dir_set_app_data(struct dir *f, void *appdata); void *dir_get_app_data(struct dir *f); #endif