ctdb-scripts: Update statd-callout to try several configuration files
[vlendec/samba-autobuild/.git] / ctdb / common / path.c
1 /*
2    Construct runtime paths
3
4    Copyright (C) Amitay Isaacs  2018
5
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 3 of the License, or
9    (at your option) any later version.
10
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with this program; if not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include "replace.h"
21 #include "system/filesys.h"
22
23 #include "lib/util/debug.h"
24
25 #include "common/path.h"
26
27 #define CTDB_CONFIG_FILE        "ctdb.conf"
28
29 struct {
30         char *basedir;
31         char datadir[PATH_MAX];
32         char etcdir[PATH_MAX];
33         char rundir[PATH_MAX];
34         char vardir[PATH_MAX];
35         bool test_mode;
36         bool basedir_set;
37         bool datadir_set;
38         bool etcdir_set;
39         bool rundir_set;
40         bool vardir_set;
41 } ctdb_paths = {
42         .datadir = CTDB_DATADIR,
43         .etcdir = CTDB_ETCDIR,
44         .rundir = CTDB_RUNDIR,
45         .vardir = CTDB_VARDIR,
46 };
47
48 static void path_set_basedir(void)
49 {
50         const char *t;
51
52         t = getenv("CTDB_TEST_MODE");
53         if (t == NULL) {
54                 goto done;
55         }
56
57         ctdb_paths.test_mode = true;
58
59         ctdb_paths.basedir = getenv("CTDB_BASE");
60         if (ctdb_paths.basedir == NULL) {
61                 D_ERR("Broken CTDB setup, CTDB_BASE not set in test mode\n");
62                 abort();
63         }
64
65 done:
66         ctdb_paths.basedir_set = true;
67 }
68
69 static bool path_construct(char *path, const char *subdir)
70 {
71         char p[PATH_MAX];
72         int len;
73
74         if (! ctdb_paths.basedir_set) {
75                 path_set_basedir();
76         }
77
78         if (! ctdb_paths.test_mode) {
79                 return true;
80         }
81
82         if (subdir == NULL) {
83                 len = snprintf(p, sizeof(p), "%s", ctdb_paths.basedir);
84         } else {
85                 len = snprintf(p,
86                                sizeof(p),
87                                "%s/%s",
88                                ctdb_paths.basedir,
89                                subdir);
90         }
91
92         if (len >= sizeof(p)) {
93                 return false;
94         }
95
96         strncpy(path, p, PATH_MAX);
97         return true;
98 }
99
100 const char *path_datadir(void)
101 {
102         bool ok;
103
104         if (! ctdb_paths.datadir_set) {
105                 ok = path_construct(ctdb_paths.datadir, "share");
106                 if (!ok) {
107                         D_ERR("Failed to construct DATADIR\n");
108                 } else {
109                         ctdb_paths.datadir_set = true;
110                 }
111         }
112
113         return ctdb_paths.datadir;
114 }
115
116 const char *path_etcdir(void)
117 {
118         bool ok;
119
120         if (! ctdb_paths.etcdir_set) {
121                 ok = path_construct(ctdb_paths.etcdir, NULL);
122                 if (!ok) {
123                         D_ERR("Failed to construct ETCDIR\n");
124                 } else {
125                         ctdb_paths.etcdir_set = true;
126                 }
127         }
128
129         return ctdb_paths.etcdir;
130 }
131
132 const char *path_rundir(void)
133 {
134         bool ok;
135
136         if (! ctdb_paths.rundir_set) {
137                 ok = path_construct(ctdb_paths.rundir, "run");
138                 if (!ok) {
139                         D_ERR("Failed to construct RUNDIR\n");
140                 } else {
141                         ctdb_paths.rundir_set = true;
142                 }
143         }
144
145         return ctdb_paths.rundir;
146 }
147
148 const char *path_vardir(void)
149 {
150         bool ok;
151
152         if (! ctdb_paths.vardir_set) {
153                 ok = path_construct(ctdb_paths.vardir, "var");
154                 if (!ok) {
155                         D_ERR("Failed to construct VARDIR\n");
156                 } else {
157                         ctdb_paths.vardir_set = true;
158                 }
159         }
160
161         return ctdb_paths.vardir;
162 }
163
164 char *path_datadir_append(TALLOC_CTX *mem_ctx, const char *path)
165 {
166         return talloc_asprintf(mem_ctx, "%s/%s", path_datadir(), path);
167 }
168
169 char *path_etcdir_append(TALLOC_CTX *mem_ctx, const char *path)
170 {
171         return talloc_asprintf(mem_ctx, "%s/%s", path_etcdir(), path);
172 }
173
174 char *path_rundir_append(TALLOC_CTX *mem_ctx, const char *path)
175 {
176         return talloc_asprintf(mem_ctx, "%s/%s", path_rundir(), path);
177 }
178
179 char *path_vardir_append(TALLOC_CTX *mem_ctx, const char *path)
180 {
181         return talloc_asprintf(mem_ctx, "%s/%s", path_vardir(), path);
182 }
183
184 char *path_config(TALLOC_CTX *mem_ctx)
185 {
186         return path_etcdir_append(mem_ctx, CTDB_CONFIG_FILE);
187 }
188
189 char *path_socket(TALLOC_CTX *mem_ctx, const char *daemon)
190 {
191         if (strcmp(daemon, "ctdbd") == 0) {
192                 const char *t = getenv("CTDB_SOCKET");
193
194                 if (t != NULL) {
195                         return talloc_strdup(mem_ctx, t);
196                 }
197         }
198
199         return talloc_asprintf(mem_ctx,
200                                "%s/%s.socket",
201                                path_rundir(),
202                                daemon);
203 }
204
205 char *path_pidfile(TALLOC_CTX *mem_ctx, const char *daemon)
206 {
207         return talloc_asprintf(mem_ctx,
208                                "%s/%s.pid",
209                                path_rundir(),
210                                daemon);
211 }