aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/eina/eina_vpath_xdg.c
blob: 0db6e7836dea1fb5a51ddac683a7595d7ceec505 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif

#include <sys/types.h>
#include <pwd.h>

#include <Eina.h>

#include "eina_internal.h"
#include "eina_private.h"

void
eina_xdg_env_init(void)
{
   char home[PATH_MAX], *s;
   Eina_Vpath_Interface_User user;

   eina_vpath_resolve_snprintf(home, sizeof(home), "(:home:)/");
   memset(&user, 0, sizeof(Eina_Vpath_Interface_User));

#define FATAL_SNPRINTF(_buf, _err, _fmt, ...) \
   do { \
      if ((size_t)snprintf(_buf, sizeof(_buf), _fmt, ## __VA_ARGS__) >= (sizeof(_buf) - 1)) { \
         fprintf(stderr, _err"\n", _buf); \
         abort(); \
      } \
   } while (0)

#ifdef _WIN32
# define ENV_DIR_SET(_env, _dir, _meta) \
   char _meta[PATH_MAX + 128]; \
   if (_env) { \
      s = getenv(_env); \
      if (!s) s = home; \
   } else s = home; \
   FATAL_SNPRINTF(_meta, "vpath string '%s' truncated - fatal", "%s\\%s", s, (char *)_dir); \
   (&user)->_meta = _meta;

# define ENV_SET(_env, _meta) \
   char _meta[PATH_MAX + 128]; \
   if (_env) { \
      s = getenv(_env); \
      if (!s) s = home; \
   } else s = home; \
   FATAL_SNPRINTF(_meta, "vpath string '%s' truncated - fatal", "%s\\", s); \
   (&user)->_meta = _meta;

   ENV_DIR_SET(NULL, "Desktop", desktop);
   ENV_DIR_SET(NULL, "Documents", documents);
   ENV_DIR_SET(NULL, "Downloads", downloads);
   ENV_DIR_SET(NULL, "Music", music);
   ENV_DIR_SET(NULL, "Pictures", pictures);
   ENV_SET("PUBLIC", pub);
   ENV_DIR_SET("APPDATA", "Microsoft\\Windows\\Templates", templates);
   ENV_DIR_SET(NULL, "Videos", videos);
   ENV_SET("LOCALAPPDATA", data);
   ENV_DIR_SET("LOCALAPPDATA", "Temp", tmp);
   ENV_SET("APPDATA", config);
   ENV_SET("LOCALAPPDATA", cache);
   if (!(s = getenv("APPDATA")))
     user.run = NULL;
   else
     user.run = s;
#else /* _WIN32 */
# if defined(HAVE_GETUID) && defined(HAVE_GETEUID)
#  define ENV_HOME_SET(_env, _dir, _meta) \
   char _meta [PATH_MAX + 128]; \
   if ((getuid() != geteuid()) || (!(s = getenv(_env)))) { \
      FATAL_SNPRINTF(_meta, "vpath string '%s' truncated - fatal", "%s/"_dir, home); \
      s = _meta; \
   } \
   (&user)->_meta = s;
# else
#  define ENV_HOME_SET(_env, _dir, _meta) \
   char _meta [PATH_MAX + 128]; \
   if (!(s = getenv(_env))) { \
      FATAL_SNPRINTF(_meta, "vpath string '%s' truncated - fatal", "%s/"_dir, home); \
      s = _meta; \
   } \
   (&user)->_meta = s;
# endif
   // $XDG_DESKTOP_DIR="$HOME/Desktop"
   ENV_HOME_SET("XDG_DESKTOP_DIR", "Desktop", desktop);
   // $XDG_DOCUMENTS_DIR="$HOME/Documents"
   ENV_HOME_SET("XDG_DOCUMENTS_DIR", "Documents", documents);
   // $XDG_DOWNLOAD_DIR="$HOME/Downloads"
   ENV_HOME_SET("XDG_DOWNLOAD_DIR", "Downloads", downloads);
   // $XDG_MUSIC_DIR="$HOME/Music"
   ENV_HOME_SET("XDG_MUSIC_DIR", "Music", music);
   // $XDG_PICTURES_DIR="$HOME/Pictures"
   ENV_HOME_SET("XDG_PICTURES_DIR", "Pictures", pictures);
   // $XDG_PUBLICSHARE_DIR="$HOME/Public"
   ENV_HOME_SET("XDG_PUBLICSHARE_DIR", "Public", pub);
   // $XDG_TEMPLATES_DIR="$HOME/.Templates"
   ENV_HOME_SET("XDG_TEMPLATES_DIR", "Templates", templates);
   // $XDG_VIDEOS_DIR="$HOME/Videos"
   ENV_HOME_SET("XDG_VIDEOS_DIR", "Videos", videos);
   // $XDG_DATA_HOME defines the base directory relative to which user
   //   specific data files should be stored. If $XDG_DATA_HOME is either
   //   not set or empty, a default equal to $HOME/.local/share should be
   //   used.
   ENV_HOME_SET("XDG_DATA_HOME", ".local/share", data);
   ENV_HOME_SET("XDG_TMP_HOME", ".local/tmp", tmp);
   // $XDG_CONFIG_HOME defines the base directory relative to which user
   //   specific configuration files should be stored. If $XDG_CONFIG_HOME
   //   is either not set or empty, a default equal to $HOME/.config should
   //   be used.
   ENV_HOME_SET("XDG_CONFIG_HOME", ".config", config);
   // $XDG_CACHE_HOME defines the base directory relative to which
   //   user specific non-essential data files should be stored. If
   //   $XDG_CACHE_HOME is either not set or empty, a default equal to
   //   $HOME/.cache should be used.
   ENV_HOME_SET("XDG_CACHE_HOME", ".cache", cache);

# if defined(HAVE_GETUID) && defined(HAVE_GETEUID)
   if ((getuid() != geteuid()) || (!(s = getenv("XDG_RUNTIME_DIR"))))
# else
   if (!(s = getenv("XDG_RUNTIME_DIR")))
# endif
     user.run = NULL;
   else
     user.run = s;
#endif /* _WIN32 */

   eina_vpath_interface_user_set(&user);
}