1 #include "xdg.h"
2 
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <string.h>
6 #include <stdbool.h>
7 #include <wchar.h>
8 #include <unistd.h>
9 #include <limits.h>
10 
11 #include <sys/types.h>
12 #include <sys/stat.h>
13 #include <dirent.h>
14 #include <fcntl.h>
15 #include <pwd.h>
16 
17 #define LOG_MODULE "xdg"
18 #define LOG_ENABLE_DBG 0
19 #include "log.h"
20 
21 xdg_data_dirs_t
xdg_data_dirs(void)22 xdg_data_dirs(void)
23 {
24     xdg_data_dirs_t ret = tll_init();
25 
26     const char *xdg_data_home = getenv("XDG_DATA_HOME");
27     if (xdg_data_home != NULL)
28         tll_push_back(ret, strdup(xdg_data_home));
29     else {
30         static const char *const local = ".local/share";
31         const struct passwd *pw = getpwuid(getuid());
32 
33         char *path = malloc(strlen(pw->pw_dir) + 1 + strlen(local) + 1);
34         sprintf(path, "%s/%s", pw->pw_dir, local);
35         tll_push_back(ret, path);
36     }
37 
38     const char *_xdg_data_dirs = getenv("XDG_DATA_DIRS");
39 
40     if (_xdg_data_dirs != NULL) {
41 
42         char *ctx = NULL;
43         char *copy = strdup(_xdg_data_dirs);
44 
45         for (const char *tok = strtok_r(copy, ":", &ctx);
46              tok != NULL;
47              tok = strtok_r(NULL, ":", &ctx))
48         {
49             tll_push_back(ret, strdup(tok));
50         }
51 
52         free(copy);
53     } else {
54         tll_push_back(ret, strdup("/usr/local/share"));
55         tll_push_back(ret, strdup("/usr/local/share"));
56     }
57 
58     return ret;
59 }
60 
61 void
xdg_data_dirs_destroy(xdg_data_dirs_t dirs)62 xdg_data_dirs_destroy(xdg_data_dirs_t dirs)
63 {
64     tll_foreach(dirs, it) {
65         free(it->item);
66         tll_remove(dirs, it);
67     }
68 }
69 
70 const char *
xdg_cache_dir(void)71 xdg_cache_dir(void)
72 {
73     const char *xdg_cache_home = getenv("XDG_CACHE_HOME");
74     if (xdg_cache_home != NULL)
75         return xdg_cache_home;
76 
77     static char path[PATH_MAX];
78     const struct passwd *pw = getpwuid(getuid());
79     snprintf(path, sizeof(path), "%s/.cache", pw->pw_dir);
80     return path;
81 }
82