1 /*
2 Copyright 2021 Northern.tech AS
3
4 This file is part of CFEngine 3 - written and maintained by Northern.tech AS.
5
6 This program is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; version 3.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
18
19 To the extent this program is licensed as part of the Enterprise
20 versions of CFEngine, the applicable Commercial Open Source License
21 (COSL) may apply to this file if you as a licensee so wish it. See
22 included file COSL.txt.
23 */
24
25 #include "../config.h"
26 #include <known_dirs.h>
27 #include <definitions.h>
28 #include <file_lib.h>
29
30 static char OVERRIDE_BINDIR[PATH_MAX] = {0};
31
32 #if defined(__CYGWIN__) || defined(__ANDROID__)
33
34 #define GET_DEFAULT_DIRECTORY_DEFINE(FUNC, GLOBAL) \
35 static const char *GetDefault##FUNC##Dir(void) \
36 { \
37 return GLOBAL; \
38 }
39
40 /* getpwuid() on Android returns /data,
41 * so use compile-time default instead */
GET_DEFAULT_DIRECTORY_DEFINE(Work,WORKDIR)42 GET_DEFAULT_DIRECTORY_DEFINE(Work, WORKDIR)
43 GET_DEFAULT_DIRECTORY_DEFINE(Bin, BINDIR)
44 GET_DEFAULT_DIRECTORY_DEFINE(Data, CF_DATADIR)
45 GET_DEFAULT_DIRECTORY_DEFINE(Log, LOGDIR)
46 GET_DEFAULT_DIRECTORY_DEFINE(Pid, PIDDIR)
47 GET_DEFAULT_DIRECTORY_DEFINE(Input, INPUTDIR)
48 GET_DEFAULT_DIRECTORY_DEFINE(Master, MASTERDIR)
49 GET_DEFAULT_DIRECTORY_DEFINE(State, STATEDIR)
50
51 #elif !defined(__MINGW32__)
52
53 const char *GetDefaultDir_helper(char dir[PATH_MAX], const char *root_dir,
54 const char *append_dir)
55 {
56 assert(dir != NULL);
57
58 if (getuid() > 0)
59 {
60 if (dir[0] == '\0')
61 {
62 struct passwd *mpw = getpwuid(getuid());
63
64 if (mpw == NULL)
65 {
66 return NULL;
67 }
68
69 if ( append_dir == NULL )
70 {
71 if (snprintf(dir, PATH_MAX, "%s/.cfagent",
72 mpw->pw_dir) >= PATH_MAX)
73 {
74 return NULL;
75 }
76 }
77 else
78 {
79 if (snprintf(dir, PATH_MAX, "%s/.cfagent/%s",
80 mpw->pw_dir, append_dir) >= PATH_MAX)
81 {
82 return NULL;
83 }
84 }
85 }
86 return dir;
87 }
88 else
89 {
90 return root_dir;
91 }
92 }
93
94 #endif
95
96 #define GET_DEFAULT_DIRECTORY_DEFINE(FUNC, STATIC, GLOBAL, FOLDER) \
97 const char *GetDefault##FUNC##Dir(void) \
98 { \
99 static char STATIC##dir[PATH_MAX]; /* GLOBAL_C */ \
100 return GetDefaultDir_helper(STATIC##dir, GLOBAL, FOLDER); \
101 }
102
103 #if !defined(__CYGWIN__) && !defined(__ANDROID__)
104 GET_DEFAULT_DIRECTORY_DEFINE(Work, work, WORKDIR, NULL)
105 GET_DEFAULT_DIRECTORY_DEFINE(Bin, bin, BINDIR, "bin")
106 GET_DEFAULT_DIRECTORY_DEFINE(Data, data, CF_DATADIR, "data")
107 GET_DEFAULT_DIRECTORY_DEFINE(Log, log, LOGDIR, "log")
108 GET_DEFAULT_DIRECTORY_DEFINE(Pid, pid, PIDDIR, NULL)
109 GET_DEFAULT_DIRECTORY_DEFINE(Master, master, MASTERDIR, "masterfiles")
110 GET_DEFAULT_DIRECTORY_DEFINE(Input, input, INPUTDIR, "inputs")
111 GET_DEFAULT_DIRECTORY_DEFINE(State, state, STATEDIR, "state")
112 #endif
113
114
115 /*******************************************************************/
116
117 const char *GetWorkDir(void)
118 {
119 const char *workdir = getenv("CFENGINE_TEST_OVERRIDE_WORKDIR");
120
121 return workdir == NULL ? GetDefaultWorkDir() : workdir;
122 }
123
GetBinDir(void)124 const char *GetBinDir(void)
125 {
126 const char *workdir = getenv("CFENGINE_TEST_OVERRIDE_WORKDIR");
127
128 if (workdir == NULL)
129 {
130 #ifdef __MINGW32__
131 /* Compile-time default bindir doesn't work on windows because during
132 * the build /var/cfengine/bin is used and only when the package is
133 * created, things are shuffled around */
134 snprintf(OVERRIDE_BINDIR, PATH_MAX, "%s%cbin",
135 GetDefaultWorkDir(), FILE_SEPARATOR);
136 return OVERRIDE_BINDIR;
137 #else
138 return GetDefaultBinDir();
139 #endif
140 }
141 else
142 {
143 snprintf(OVERRIDE_BINDIR, PATH_MAX, "%s%cbin",
144 workdir, FILE_SEPARATOR);
145 return OVERRIDE_BINDIR;
146 }
147 }
148
GetLogDir(void)149 const char *GetLogDir(void)
150 {
151 const char *logdir = getenv("CFENGINE_TEST_OVERRIDE_WORKDIR");
152
153 return logdir == NULL ? GetDefaultLogDir() : logdir;
154 }
155
GetPidDir(void)156 const char *GetPidDir(void)
157 {
158 const char *piddir = getenv("CFENGINE_TEST_OVERRIDE_WORKDIR");
159
160 return piddir == NULL ? GetDefaultPidDir() : piddir;
161 }
162
163 #define GET_DIRECTORY_DEFINE_FUNC_BODY(FUNC, VAR, GLOBAL, FOLDER) \
164 { \
165 const char *VAR##dir = getenv("CFENGINE_TEST_OVERRIDE_WORKDIR"); \
166 \
167 static char workbuf[CF_BUFSIZE]; \
168 \
169 if (VAR##dir != NULL) \
170 { \
171 snprintf(workbuf, CF_BUFSIZE, "%s/" #FOLDER, VAR##dir); \
172 } \
173 else if (strcmp(GLOBAL##DIR, "default") == 0 ) \
174 { \
175 snprintf(workbuf, CF_BUFSIZE, "%s/" #FOLDER, GetWorkDir()); \
176 } \
177 else /* VAR##dir defined at compile-time */ \
178 { \
179 return GetDefault##FUNC##Dir(); \
180 } \
181 \
182 return MapName(workbuf); \
183 }
184
185 const char *GetInputDir(void)
186 GET_DIRECTORY_DEFINE_FUNC_BODY(Input, input, INPUT, inputs)
187 const char *GetMasterDir(void)
188 GET_DIRECTORY_DEFINE_FUNC_BODY(Master, master, MASTER, masterfiles)
189 const char *GetStateDir(void)
190 GET_DIRECTORY_DEFINE_FUNC_BODY(State, state, STATE, state)
191 const char *GetDataDir(void)
192 GET_DIRECTORY_DEFINE_FUNC_BODY(Data, data, CF_DATA, data)
193