1 #include "common.h"
2 
3 #include <ctype.h>
4 #include <dirent.h>
5 #include <pwd.h>
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <string.h>
9 #include <unistd.h>
10 #include <sys/stat.h>
11 #include <sys/types.h>
12 
13 #include "file.h"
14 
15 int
__imlib_IsRealFile(const char * s)16 __imlib_IsRealFile(const char *s)
17 {
18    struct stat         st;
19 
20    return (stat(s, &st) != -1) && (S_ISREG(st.st_mode));
21 }
22 
23 char               *
__imlib_FileKey(const char * file)24 __imlib_FileKey(const char *file)
25 {
26    char               *newfile;
27 
28    newfile = malloc(strlen(file) + 1);
29    if (!newfile)
30       return NULL;
31    newfile[0] = 0;
32    {
33       char               *p1, *p2;
34       int                 go;
35 
36       go = 0;
37       p1 = (char *)file;
38       p2 = newfile;
39       while (p1[0])
40         {
41            if (go)
42              {
43                 p2[0] = p1[0];
44                 p2++;
45              }
46            if ((p1[0] == ':') && (p1[1] != ':'))
47               go = 1;
48            if ((p1[0] == ':') && (p1[1] == ':'))
49               p1++;
50            p1++;
51         }
52       p2[0] = p1[0];
53    }
54    if (newfile[0])
55       return newfile;
56    else
57       free(newfile);
58    return NULL;
59 }
60 
61 char               *
__imlib_FileRealFile(const char * file)62 __imlib_FileRealFile(const char *file)
63 {
64    char               *newfile;
65 
66    newfile = malloc(strlen(file) + 1);
67    if (!newfile)
68       return NULL;
69    newfile[0] = 0;
70    {
71       char               *p1, *p2;
72 
73       p1 = (char *)file;
74       p2 = newfile;
75       while (p1[0])
76         {
77            if (p1[0] == ':')
78              {
79                 if (p1[1] == ':')
80                   {
81                      p2[0] = ':';
82                      p2++;
83                      p1++;
84                   }
85                 else
86                   {
87                      p2[0] = 0;
88                      return newfile;
89                   }
90              }
91            else
92              {
93                 p2[0] = p1[0];
94                 p2++;
95              }
96            p1++;
97         }
98       p2[0] = p1[0];
99    }
100    return newfile;
101 }
102 
103 const char         *
__imlib_FileExtension(const char * file)104 __imlib_FileExtension(const char *file)
105 {
106    const char         *p, *s;
107    int                 ch;
108 
109    if (!file)
110       return NULL;
111 
112    for (p = s = file; (ch = *s) != 0; s++)
113      {
114         if (ch == '.' || ch == '/')
115            p = s + 1;
116      }
117    return *p != '\0' ? p : NULL;
118 }
119 
120 int
__imlib_FileStat(const char * file,struct stat * st)121 __imlib_FileStat(const char *file, struct stat *st)
122 {
123    if ((!file) || (!*file))
124       return -1;
125 
126    return stat(file, st);
127 }
128 
129 int
__imlib_FileExists(const char * s)130 __imlib_FileExists(const char *s)
131 {
132    struct stat         st;
133 
134    return __imlib_FileStat(s, &st) == 0;
135 }
136 
137 int
__imlib_FileIsFile(const char * s)138 __imlib_FileIsFile(const char *s)
139 {
140    struct stat         st;
141 
142    if (__imlib_FileStat(s, &st))
143       return 0;
144 
145    return (S_ISREG(st.st_mode)) ? 1 : 0;
146 }
147 
148 int
__imlib_FileIsDir(const char * s)149 __imlib_FileIsDir(const char *s)
150 {
151    struct stat         st;
152 
153    if (__imlib_FileStat(s, &st))
154       return 0;
155 
156    return (S_ISDIR(st.st_mode)) ? 1 : 0;
157 }
158 
159 time_t
__imlib_FileModDate(const char * s)160 __imlib_FileModDate(const char *s)
161 {
162    struct stat         st;
163 
164    if (__imlib_FileStat(s, &st))
165       return 0;
166 
167    return (st.st_mtime > st.st_ctime) ? st.st_mtime : st.st_ctime;
168 }
169 
170 time_t
__imlib_FileModDateFd(int fd)171 __imlib_FileModDateFd(int fd)
172 {
173    struct stat         st;
174 
175    if (fstat(fd, &st) < 0)
176       return 0;
177 
178    return (st.st_mtime > st.st_ctime) ? st.st_mtime : st.st_ctime;
179 }
180 
181 int
__imlib_FileCanRead(const char * s)182 __imlib_FileCanRead(const char *s)
183 {
184    struct stat         st;
185 
186    if (__imlib_FileStat(s, &st))
187       return 0;
188 
189    if (!(st.st_mode & (S_IRUSR | S_IRGRP | S_IROTH)))
190       return 0;
191 
192    return access(s, R_OK) == 0 ? 1 : 0; // ??? TBD
193 }
194 
195 char              **
__imlib_FileDir(const char * dir,int * num)196 __imlib_FileDir(const char *dir, int *num)
197 {
198    int                 i, dirlen;
199    int                 done = 0;
200    DIR                *dirp;
201    char              **names;
202    struct dirent      *dp;
203 
204    if ((!dir) || (!*dir))
205       return 0;
206    dirp = opendir(dir);
207    if (!dirp)
208      {
209         *num = 0;
210         return NULL;
211      }
212    /* count # of entries in dir (worst case) */
213    for (dirlen = 0; (dp = readdir(dirp)); dirlen++);
214    if (!dirlen)
215      {
216         closedir(dirp);
217         *num = dirlen;
218         return NULL;
219      }
220    names = (char **)malloc(dirlen * sizeof(char *));
221 
222    if (!names)
223       return NULL;
224 
225    rewinddir(dirp);
226    for (i = 0; i < dirlen;)
227      {
228         dp = readdir(dirp);
229         if (!dp)
230            break;
231         if ((strcmp(dp->d_name, ".")) && (strcmp(dp->d_name, "..")))
232           {
233              names[i] = strdup(dp->d_name);
234              i++;
235           }
236      }
237 
238    if (i < dirlen)
239       dirlen = i;               /* dir got shorter... */
240    closedir(dirp);
241    *num = dirlen;
242    /* do a simple bubble sort here to alphanumberic it */
243    while (!done)
244      {
245         done = 1;
246         for (i = 0; i < dirlen - 1; i++)
247           {
248              if (strcmp(names[i], names[i + 1]) > 0)
249                {
250                   char               *tmp;
251 
252                   tmp = names[i];
253                   names[i] = names[i + 1];
254                   names[i + 1] = tmp;
255                   done = 0;
256                }
257           }
258      }
259    return names;
260 }
261 
262 void
__imlib_FileFreeDirList(char ** l,int num)263 __imlib_FileFreeDirList(char **l, int num)
264 {
265    if (!l)
266       return;
267    while (num--)
268       if (l[num])
269          free(l[num]);
270    free(l);
271 }
272 
273 void
__imlib_FileDel(const char * s)274 __imlib_FileDel(const char *s)
275 {
276    if ((!s) || (!*s))
277       return;
278    unlink(s);
279 }
280 
281 char               *
__imlib_FileHomeDir(int uid)282 __imlib_FileHomeDir(int uid)
283 {
284    static int          usr_uid = -1;
285    static char        *usr_s = NULL;
286    char               *s;
287    struct passwd      *pwd;
288 
289    s = getenv("HOME");
290    if (s)
291       return strdup(s);
292 
293    if (usr_uid < 0)
294       usr_uid = getuid();
295 
296    if ((uid == usr_uid) && (usr_s))
297      {
298         return strdup(usr_s);
299      }
300 
301    pwd = getpwuid(uid);
302    if (pwd)
303      {
304         s = strdup(pwd->pw_dir);
305         if (uid == usr_uid)
306            usr_s = strdup(s);
307         return s;
308      }
309 
310    return NULL;
311 }
312 
313 int
__imlib_ItemInList(char ** list,int size,char * item)314 __imlib_ItemInList(char **list, int size, char *item)
315 {
316    int                 i;
317 
318    if (!list)
319       return 0;
320    if (!item)
321       return 0;
322 
323    for (i = 0; i < size; i++)
324      {
325         if (!strcmp(list[i], item))
326            return 1;
327      }
328    return 0;
329 }
330