summaryrefslogtreecommitdiff
path: root/src/file.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/file.c')
-rw-r--r--src/file.c197
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;
+}