374 lines
7.6 KiB
C
374 lines
7.6 KiB
C
#include "evas_common.h"
|
|
#include "evas_private.h"
|
|
|
|
/* os dependant file code. for unix-y like fs's only for now */
|
|
/* if your os doesn't use unix-like fs starting with "/" for the root and */
|
|
/* the file path separator isn't "/" then you may need to help out by */
|
|
/* adding in a new set of functions here */
|
|
|
|
#ifndef _WIN32_WCE
|
|
|
|
#include <limits.h>
|
|
#include <unistd.h>
|
|
#include <stdlib.h>
|
|
#include <sys/param.h>
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
/* get the casefold feature! */
|
|
#define _GNU_SOURCE
|
|
#include <fnmatch.h>
|
|
#include <dirent.h>
|
|
|
|
int
|
|
evas_file_path_is_full_path(char *path)
|
|
{
|
|
if (!path) return 0;
|
|
if (path[0] == '/') return 1;
|
|
return 0;
|
|
}
|
|
|
|
char *
|
|
evas_file_path_join(char *path, char *end)
|
|
{
|
|
char *res = NULL;
|
|
int len;
|
|
|
|
if ((!path) && (!end)) return NULL;
|
|
if (!path) return strdup(end);
|
|
if (!end) return strdup(path);
|
|
len = strlen(path);
|
|
len += strlen(end);
|
|
len += strlen("/");
|
|
res = malloc(len + 1);
|
|
if (!res) return NULL;
|
|
strcpy(res, path);
|
|
strcat(res, "/");
|
|
strcat(res, end);
|
|
return res;
|
|
}
|
|
|
|
int
|
|
evas_file_path_exists(char *path)
|
|
{
|
|
struct stat st;
|
|
|
|
if (stat(path, &st) != -1) return 0;
|
|
return 1;
|
|
}
|
|
|
|
int
|
|
evas_file_path_is_file(char *path)
|
|
{
|
|
struct stat st;
|
|
|
|
if (stat(path, &st) != -1) return 0;
|
|
if (S_ISREG(st.st_mode)) return 1;
|
|
return 0;
|
|
}
|
|
|
|
int
|
|
evas_file_path_is_dir(char *path)
|
|
{
|
|
struct stat st;
|
|
|
|
if (stat(path, &st) != -1) return 0;
|
|
if (S_ISDIR(st.st_mode)) return 1;
|
|
return 0;
|
|
}
|
|
|
|
Evas_List *
|
|
evas_file_path_list(char *path, char *match, int match_case)
|
|
{
|
|
Evas_List *files = NULL;
|
|
DIR *dir;
|
|
|
|
dir = opendir(path);
|
|
if (!dir) return NULL;
|
|
{
|
|
struct dirent *dp;
|
|
int flags;
|
|
|
|
flags = FNM_PATHNAME;
|
|
#ifdef FNM_CASEFOLD
|
|
if (!match_case)
|
|
flags |= FNM_CASEFOLD;
|
|
#else
|
|
#warning "Your libc does not provide case-insensitive matching!"
|
|
#endif
|
|
while ((dp = readdir(dir)))
|
|
{
|
|
if ((!strcmp(dp->d_name, ".")) || (!strcmp(dp->d_name, "..")))
|
|
continue;
|
|
if (match)
|
|
{
|
|
if (fnmatch(match, dp->d_name, flags) == 0)
|
|
files = evas_list_append(files, strdup(dp->d_name));
|
|
}
|
|
else
|
|
files = evas_list_append(files, strdup(dp->d_name));
|
|
}
|
|
closedir(dir);
|
|
}
|
|
return files;
|
|
}
|
|
|
|
DATA64
|
|
evas_file_modified_time(const char *file)
|
|
{
|
|
struct stat st;
|
|
|
|
if (stat(file, &st) < 0) return 0;
|
|
if (st.st_ctime > st.st_mtime) return (DATA64)st.st_ctime;
|
|
else return (DATA64)st.st_mtime;
|
|
return 0;
|
|
}
|
|
|
|
char *
|
|
evas_file_path_resolve(const char *file)
|
|
{
|
|
char buf[PATH_MAX], *buf2;
|
|
|
|
if (!realpath(file, buf)) return NULL;
|
|
buf2 = strdup(buf);
|
|
return buf2;
|
|
}
|
|
|
|
#else
|
|
|
|
/* Forward declarations */
|
|
|
|
static DWORD winstat(char *path);
|
|
static wchar_t *convert_utf_unicode(const char* putf);
|
|
static char *convert_unicode_utf(const wchar_t* punicode);
|
|
|
|
|
|
/* Unicode to utf and utf to unicode conversion functions */
|
|
static wchar_t *
|
|
convert_utf_unicode(const char *putf)
|
|
{
|
|
int len;
|
|
wchar_t *punicode;
|
|
|
|
len = strlen(putf)+ 1; //add one for safety
|
|
|
|
punicode = (wchar_t *)malloc(len * sizeof(wchar_t));
|
|
|
|
if (punicode == NULL) return NULL;
|
|
|
|
#ifdef UNICODE
|
|
strcpy(punicode,putf);
|
|
#else
|
|
if (mbstowcs(punicode,putf,len) < 0)
|
|
{
|
|
free(punicode);
|
|
return NULL;
|
|
}
|
|
#endif
|
|
return punicode;
|
|
}
|
|
|
|
static char *
|
|
convert_unicode_utf(const wchar_t *punicode)
|
|
{
|
|
int len;
|
|
char *putf;
|
|
|
|
/* add one for safety */
|
|
len = wcslen(punicode) + 1;
|
|
|
|
/* this will alloc too many bytes */
|
|
putf = (char *)malloc(len * sizeof(wchar_t));
|
|
|
|
if (putf == NULL) return NULL;
|
|
|
|
#ifdef UNICODE
|
|
strcpy(putf,punicode);
|
|
#else
|
|
if (wcstombs(putf,punicode,len) < 0)
|
|
{
|
|
free(putf);
|
|
return NULL;
|
|
}
|
|
#endif
|
|
return putf;
|
|
}
|
|
|
|
/*
|
|
* win"stat"
|
|
* This is like the stat function except that it reurns a bitmask (DWORD)
|
|
* Since this library is complied using MBCS then the path is multibyte
|
|
*/
|
|
static DWORD
|
|
winstat(char *path)
|
|
{
|
|
DWORD fa;
|
|
wchar_t *pwpath; /* A wide character type */
|
|
|
|
pwpath = convert_utf_unicode(path);
|
|
/* 0xFFFFFFFF is the error return val for the GetFile Attributes Function */
|
|
/* so I am usin this as an error return up here */
|
|
if (pwpath == NULL) return 0xFFFFFFFF;
|
|
/* this function needed the wide string"*/
|
|
/* I dont think that WinCe has mbcs equiv functions and only provides UNICODE*/
|
|
fa = GetFileAttributesW(pwpath);
|
|
free(pwpath);
|
|
return fa;
|
|
}
|
|
|
|
int
|
|
evas_file_path_is_full_path(char *path)
|
|
{
|
|
if (!path) return 0;
|
|
if (path[0] == '\\') return 1;
|
|
return 0;
|
|
}
|
|
|
|
char *
|
|
evas_file_path_join(char *path, char *end)
|
|
{
|
|
char *res = NULL;
|
|
int len;
|
|
|
|
if ((!path) && (!end)) return NULL;
|
|
if (!path) return strdup(end);
|
|
if (!end) return strdup(path);
|
|
len = strlen(path);
|
|
len += strlen(end);
|
|
len += strlen("\\");
|
|
res = malloc(len + 1);
|
|
if (!res) return NULL;
|
|
strcpy(res, path);
|
|
strcat(res, "\\");
|
|
strcat(res, end);
|
|
return res;
|
|
}
|
|
|
|
int
|
|
evas_file_path_exists(char *path)
|
|
{
|
|
DWORD fa;
|
|
|
|
fa = winstat(path);
|
|
if (fa == 0xFFFFFFFF) return 0;
|
|
return 1;
|
|
}
|
|
|
|
int
|
|
evas_file_path_is_file(char *path)
|
|
{
|
|
DWORD fa;
|
|
|
|
fa = winstat(path);
|
|
if (fa == 0xFFFFFFFF) return 0;
|
|
if (fa & FILE_ATTRIBUTE_DIRECTORY) return 0;
|
|
return 1;
|
|
}
|
|
|
|
int
|
|
evas_file_path_is_dir(char *path)
|
|
{
|
|
DWORD fa;
|
|
|
|
fa = winstat(path);
|
|
if (fa == 0xFFFFFFFF) return 0;
|
|
if (fa & FILE_ATTRIBUTE_DIRECTORY) return 1;
|
|
return 0;
|
|
}
|
|
|
|
Evas_List *
|
|
evas_file_path_list(char *path, char *match, int match_case)
|
|
{
|
|
Evas_List *files = NULL;
|
|
WIN32_FIND_DATAW find;
|
|
HANDLE fh;
|
|
int fullpathlen;
|
|
char *pfp; /* full path pointer */
|
|
wchar_t *pfup; /* full unicode path pointer */
|
|
|
|
/*
|
|
* work out the full path length of the combined patch and match
|
|
* if we are looking for a specific match eg *.txt then we will will add
|
|
* the length of *.txt and \\ to the string
|
|
* if we are not looking for a match then we want to list the whole
|
|
* directory and we find the length of \\*.*
|
|
*/
|
|
fullpathlen = strlen(path);
|
|
if (match)
|
|
{
|
|
fullpathlen += strlen("\\");
|
|
fullpathlen += strlen(match);
|
|
}
|
|
else
|
|
fullpathlen += strlen("\\*.*");
|
|
|
|
/* Create the full search path */
|
|
|
|
pfp = (char *)malloc(fullpathlen + 1); /* add one for safety*/
|
|
if (pfp == NULL) return NULL;
|
|
|
|
/* construct the full path */
|
|
strcpy(pfp, path);
|
|
if (match)
|
|
{
|
|
strcat(pfp,"\\");
|
|
strcat(pfp,match);
|
|
}
|
|
else
|
|
strcat(pfp,"\\*.*");
|
|
|
|
/* pfp now contains the fully constructed path*/
|
|
|
|
pfup = convert_utf_unicode(pfp);
|
|
free(pfp); /* chuck it away now as we don't need it, we have a unicode version */
|
|
if (pfup == NULL) return NULL;
|
|
|
|
fh = FindFirstFileW(pfup,&find);
|
|
free(pfup); /* chuck it away now as we don't need it, we have a handle */
|
|
if (fh == INVALID_HANDLE_VALUE) return NULL;
|
|
|
|
/* OK now go through the directory picking up filenames */
|
|
do
|
|
{
|
|
if (!(find.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
|
|
files = evas_list_append(files,convert_unicode_utf(find.cFileName));
|
|
|
|
}
|
|
while (FindNextFileW(fh,&find));
|
|
FindClose(fh);
|
|
|
|
return files;
|
|
}
|
|
|
|
DATA64
|
|
evas_file_modified_time(const char *file)
|
|
{
|
|
WIN32_FIND_DATAW find;
|
|
HANDLE fh;
|
|
ULARGE_INTEGER modtime;
|
|
wchar_t *pufile;
|
|
|
|
pufile = convert_utf_unicode(file);
|
|
if (pufile == NULL) return 0;
|
|
|
|
fh = FindFirstFileW(pufile,&find);
|
|
if (fh == INVALID_HANDLE_VALUE)
|
|
{
|
|
free(pufile);
|
|
return 0;
|
|
}
|
|
FindClose(fh);
|
|
free(pufile);
|
|
|
|
modtime.u.HighPart = find.ftCreationTime.dwHighDateTime;
|
|
modtime.u.LowPart = find.ftCreationTime.dwLowDateTime;
|
|
|
|
return modtime.QuadPart;
|
|
}
|
|
|
|
char *
|
|
evas_file_path_resolve(const char *file)
|
|
{
|
|
return strdup(file);
|
|
}
|
|
#endif
|