1 /* os dependent file code. for unix-y like fs's only for now */
2 /* if your os doesn't use unix-like fs starting with "/" for the root and */
3 /* the file path separator isn't "/" then you may need to help out by */
4 /* adding in a new set of functions here */
5 
6 #ifdef HAVE_CONFIG_H
7 # include <config.h>
8 #endif
9 
10 #include <limits.h>
11 #include <stdlib.h>
12 #include <sys/types.h>
13 #include <sys/stat.h>
14 /* get the casefold feature! */
15 #include <fnmatch.h>
16 #include <unistd.h>
17 #include <sys/param.h>
18 
19 #ifdef _WIN32
20 # include <evil_private.h> /* evil_path_is_absolute */
21 #endif
22 
23 #include "evas_common_private.h"
24 #include "evas_private.h"
25 
26 #ifdef _WIN32
27 # define EVAS_PATH_SEPARATOR "\\"
28 #else
29 # define EVAS_PATH_SEPARATOR "/"
30 #endif
31 
32 int
evas_file_path_is_full_path(const char * path)33 evas_file_path_is_full_path(const char *path)
34 {
35    if (!path) return 0;
36 #ifdef _WIN32
37    if (evil_path_is_absolute(path)) return 1;
38 #else
39    if (path[0] == '/') return 1;
40 #endif
41    return 0;
42 }
43 
44 char *
evas_file_path_join(const char * path,const char * end)45 evas_file_path_join(const char *path, const char *end)
46 {
47    char *res = NULL;
48    size_t len;
49 
50    if ((!path) && (!end)) return NULL;
51    if (!path) return strdup(end);
52    if (!end) return strdup(path);
53    len = strlen(path);
54    len += strlen(end);
55    len += strlen(EVAS_PATH_SEPARATOR);
56    res = malloc(len + 1);
57    if (!res) return NULL;
58    strcpy(res, path);
59    strcat(res, EVAS_PATH_SEPARATOR);
60    strcat(res, end);
61    return res;
62 }
63 
64 int
evas_file_path_exists(const char * path)65 evas_file_path_exists(const char *path)
66 {
67    struct stat st;
68 
69    if (!stat(path, &st)) return 1;
70    return 0;
71 }
72 
73 int
evas_file_path_is_file(const char * path)74 evas_file_path_is_file(const char *path)
75 {
76    struct stat st;
77 
78    if (stat(path, &st) == -1) return 0;
79    if (S_ISREG(st.st_mode)) return 1;
80    return 0;
81 }
82 
83 int
evas_file_path_is_dir(const char * path)84 evas_file_path_is_dir(const char *path)
85 {
86    struct stat st;
87 
88    if (stat(path, &st) == -1) return 0;
89    if (S_ISDIR(st.st_mode)) return 1;
90    return 0;
91 }
92 
93 Eina_List *
evas_file_path_list(char * path,const char * match,int match_case)94 evas_file_path_list(char *path, const char *match, int match_case)
95 {
96    Eina_File_Direct_Info *info;
97    Eina_Iterator *it;
98    Eina_List *files = NULL;
99    int flags;
100 
101    flags = FNM_PATHNAME;
102 #ifdef FNM_CASEFOLD
103    if (!match_case)
104      flags |= FNM_CASEFOLD;
105 #elif defined FNM_IGNORECASE
106    if (!match_case)
107      flags |= FNM_IGNORECASE;
108 #else
109 /*#warning "Your libc does not provide case-insensitive matching!"*/
110 #endif
111 
112    it = eina_file_direct_ls(path);
113    EINA_ITERATOR_FOREACH(it, info)
114      {
115         if (match)
116           {
117              if (fnmatch(match, info->path + info->name_start, flags) == 0)
118                files = eina_list_append(files, strdup(info->path + info->name_start));
119           }
120         else
121           files = eina_list_append(files, strdup(info->path + info->name_start));
122      }
123    if (it) eina_iterator_free(it);
124    return files;
125 }
126 
127 DATA64
evas_file_modified_time(const char * file)128 evas_file_modified_time(const char *file)
129 {
130    struct stat st;
131 
132    if (stat(file, &st) < 0) return 0;
133    if (st.st_ctime > st.st_mtime) return (DATA64)st.st_ctime;
134    else return (DATA64)st.st_mtime;
135    return 0;
136 }
137 
138 char *
evas_file_path_resolve(const char * file)139 evas_file_path_resolve(const char *file)
140 {
141 #if 0
142    char buf[PATH_MAX], *buf2;
143 #endif
144 
145    return strdup(file);
146 #if 0
147    if (!realpath(file, buf)) return NULL;
148    buf2 = strdup(buf);
149    return buf2;
150 #endif
151 }
152