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