diff options
Diffstat (limited to 'src/file.c')
-rw-r--r-- | src/file.c | 197 |
1 files changed, 197 insertions, 0 deletions
diff --git a/src/file.c b/src/file.c new file mode 100644 index 0000000..4f42a5d --- /dev/null +++ b/src/file.c @@ -0,0 +1,197 @@ +/* + * AUTHOR + * N. Nielsen + * + * LICENSE + * This software is in the public domain. + * + * The software is provided "as is", without warranty of any kind, + * express or implied, including but not limited to the warranties + * of merchantability, fitness for a particular purpose, and + * noninfringement. In no event shall the author(s) be liable for any + * claim, damages, or other liability, whether in an action of + * contract, tort, or otherwise, arising from, out of, or in connection + * with the software or the use or other dealings in the software. + * + * SUPPORT + * Send bug reports to: <nielsen@memberwebs.com> + */ + +#include <sys/stat.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#include "common/compat.h" +#include "file.h" + + +#if HAVE_UNISTD_H && HAVE_DIRENT_H + +int dir_next(DIR* handle, const char* wildcard, struct dirent* entry) +{ + struct dirent* ent = 0; + +#ifndef HAVE_FNMATCH + if(wildcard != NULL) + { + errno = EOPNOTSUPPORTED; + return 0; + } +#endif + + if(!wildcard) + wildcard = "*"; + + do + { + ent = readdir(handle); + if(ent == NULL) + { + errno = ENOENT; + break; + } + } +#ifdef HAVE_FNMATCH + while(0); +#else + while(fnmatch(wildcard, ent->d_name, FNM_PATHNAME) == FNM_NOMATCH); +#endif + + if(ent) + memcpy(entry, ent, sizeof(struct dirent)); + + return ent != NULL; +} + +DIR* dir_first(const char* folder, const char* wildcard, struct dirent* entry) +{ + DIR* handle = opendir((folder && strlen(folder) > 0) ? folder : "."); + if(handle == NULL) + return INVALID_DIR; + + if(dir_next(handle, wildcard, entry)) + return handle; + else + { + errno = ENOENT; + dir_close(handle); + return INVALID_DIR; + } +} + +void dir_close(DIR* handle) +{ + closedir(handle); +} + + +#else + +#include <direct.h> +#include <io.h> + +static void copyDirStruct(struct _finddata_t* findinfo, struct dirent* entry) +{ + /* Copy the structure */ + memset(entry, 0, sizeof(struct dirent)); + entry->d_fileno = ~0; + entry->d_reclen = ~0; + strcpy(entry->d_name, findinfo->name); + entry->d_namlen = strlen(findinfo->name); + + if(findinfo->attrib & _A_SUBDIR) + entry->d_type |= DT_DIR; + else + entry->d_type |= DT_REG; +} + +DIR* dir_first(const char* folder, const char* wildcard, struct dirent* entry) +{ + DIR* handle; + char buff[MAX_PATH * 2]; + struct _finddata_t findinfo; + + if(!wildcard) + wildcard = "*.*"; + + /* Check against buffer overflow hacks */ + if(strlen(folder) + strlen(wildcard) + 1 > MAX_PATH * 2) + { + errno = ENAMETOOLONG; + return INVALID_DIR; + } + + if(!(handle = malloc(sizeof(DIR)))) + { + errno = ENOMEM; + return INVALID_DIR; + } + + strcpy(buff, folder); + strcat(buff, strlen(folder) ? "\\" : ""); + strcat(buff, wildcard); + + /* Okay get the first file */ + *handle = _findfirst(buff, &findinfo); + + if(*handle == -1) + { + free(handle); + return INVALID_DIR; + } + else + { + copyDirStruct(&findinfo, entry); + return handle; + } +} + +int dir_next(DIR* handle, const char* wildcard, struct dirent* entry) +{ + struct _finddata_t findinfo; + int ret = _findnext(*handle, &findinfo) == 0; + if(ret) + copyDirStruct(&findinfo, entry); + + return ret; +} + +void dir_close(DIR* handle) +{ + if(handle) + { + _findclose(*handle); + free(handle); + } +} + +#endif + +const char* getFilename(const char* path) +{ + const char* filename = strrchr(path, '\\'); + const char* filename2 = strrchr(path, '/'); + if(filename2 > filename) + filename = filename2; + return filename ? filename : path; +} + +const char* getExtension(const char* path) +{ + return strrchr(path, '.'); +} + +int isDots(const char* path) +{ + const char* filename = getFilename(path); + return (filename[0] == '.' && (filename[1] == '.' || filename[1] == '\0')); +} + +int isDirectory(const char* path) +{ + struct stat st; + if(stat(path, &st) == -1) + return 0; + + return (st.st_mode & S_IFDIR) ? 1 : 0; +} |