50 mike 1.1
51 BEGIN_EXTERNC
52
53 typedef struct _PathInfo
54 {
55 char* nickname;
56 char* str;
57 MI_Boolean dynamic;
58 }
59 PathInfo;
60
61 static PathInfo _paths[] =
62 {
63 { "prefix", CONFIG_PREFIX, MI_FALSE },
64 { "libdir", CONFIG_LIBDIR, MI_FALSE },
65 { "bindir", CONFIG_BINDIR, MI_FALSE },
66 { "localstatedir", CONFIG_LOCALSTATEDIR, MI_FALSE },
67 { "sysconfdir", CONFIG_SYSCONFDIR, MI_FALSE },
68 { "providerdir", CONFIG_PROVIDERDIR, MI_FALSE },
69 { "certsdir", CONFIG_CERTSDIR, MI_FALSE },
70 { "datadir", CONFIG_DATADIR, MI_FALSE },
71 mike 1.1 { "rundir", RUNDIR, MI_FALSE },
72 { "logdir", LOGDIR, MI_FALSE },
73 { "schemadir", SCHEMADIR, MI_FALSE },
74 { "schemafile", SCHEMAFILE, MI_FALSE },
75 { "pidfile", PIDFILE, MI_FALSE },
76 { "logfile", LOGFILE, MI_FALSE },
77 { "registerdir", REGISTERDIR, MI_FALSE },
78 { "pemfile", PEMFILE, MI_FALSE },
79 { "keyfile", KEYFILE, MI_FALSE },
80 { "agentprogram", AGENTPROGRAM, MI_FALSE },
81 { "serverprogram", SERVERPROGRAM, MI_FALSE },
82 { "includedir", CONFIG_INCLUDEDIR, MI_FALSE },
83 { "configfile", CONFIGFILE, MI_FALSE },
84 #if defined(CONFIG_OS_WINDOWS)
85 { "socketfile", "7777", MI_FALSE },
86 #else
87 { "socketfile", SOCKETFILE, MI_FALSE },
88 #endif
89 { "tmpdir", CONFIG_TMPDIR, MI_FALSE },
90 { "destdir", "/", MI_FALSE },
|
94 mike 1.1 };
95
96 #if defined(CONFIG_OS_WINDOWS)
97 static int _GetFullProgramPath(
98 const char* programName,
99 char path[MAX_PATH_SIZE])
100 {
101 /* Get full path of the current module (library or program). */
102 {
103 DWORD r = GetModuleFileNameA(NULL, path, MAX_PATH_SIZE);
104
105 if (r < 1 || r >= MAX_PATH_SIZE)
106 return -1;
107 }
108
109 /* Replace name with name parameter */
110 {
111 char* end;
112
113 end = strrchr(path, '\\');
114
115 mike 1.1 if (!end)
116 return -1;
117
118 if (programName)
119 {
120 end[1] = '\0';
121
122 if (Strlcat(path, programName, MAX_PATH_SIZE) >= MAX_PATH_SIZE)
123 return -1;
124 }
125 else
126 end[0] = '\0';
127 }
128
129 /* Translate backward to forward slashes */
130 {
131 char* p;
132
133 for (p = path; *p; p++)
134 {
135 if (*p == '\\')
136 mike 1.1 *p = '/';
137 }
138 }
139
140 return 0;
141 }
142 #endif /* defined(CONFIG_OS_WINDOWS) */
143
144 #if defined(CONFIG_OS_WINDOWS)
145 static int _ResolvePrefixPath(char path[MAX_PATH_SIZE])
146 {
147 char* p;
148
149 /* Get path of directory containing current module */
150 if (_GetFullProgramPath(NULL, path) != 0)
151 return -1;
152
153 /* Work down directory hierarchy, looking for '.prefix' file */
154 for (;;)
155 {
156 char buf[MAX_PATH_SIZE];
157 mike 1.1
158 /* Format path to .prefix file */
159 Strlcpy(buf, path, sizeof(buf));
160 Strlcat(buf, "/.prefix", sizeof(buf));
161
162 /* If .prefix file exists, return success */
163 if (access(buf, F_OK) == 0)
164 {
165 FILE* is;
166 const char UUID[] = "E4349DE8-6E94-4CB6-AE44-45D8A61C489E";
167 char uuid[36];
168
169 /* Open .prefix file */
170 is = Fopen(buf, "rb");
171 if (!is)
172 continue;
173
174 /* Read UUID from file */
175 if (fread(uuid, 1, sizeof(uuid), is) != sizeof(uuid))
176 {
177 fclose(is);
178 mike 1.1 continue;
179 }
180
181 /* Check whether UUID is the expected one */
182 if (memcmp(uuid, UUID, sizeof(uuid)) != 0)
183 {
184 fclose(is);
185 continue;
186 }
187
188 /* Success! */
189 fclose(is);
190 return 0;
191 }
192
193 /* Remove next level from path */
194 p = strrchr(path, '/');
195 if (!p)
196 {
197 /* Not found! */
198 break;
199 mike 1.1 }
200
201 *p = '\0';
202 }
203
204 /* repeat these steps from current directory:
205 needed for nightly builds, since they build in
206 standalone directory, outisde of 'source' */
207
208 /* Get current directory */
209 if (_getcwd(path, MAX_PATH_SIZE) == 0)
210 return -1;
211
212 /* Translate backward to forward slashes */
213 {
214 for (p = path; *p; p++)
215 {
216 if (*p == '\\')
217 *p = '/';
218 }
219 }
220 mike 1.1
221
222 /* Work down directory hierarchy, looking for '.prefix' file */
223 for (;;)
224 {
225 char buf[MAX_PATH_SIZE];
226
227 /* Format path to .prefix file */
228 Strlcpy(buf, path, sizeof(buf));
229 Strlcat(buf, "/.prefix", sizeof(buf));
230
231 /* If .prefix file exists, return success */
232 if (access(buf, F_OK) == 0)
233 {
234 FILE* is;
235 const char UUID[] = "E4349DE8-6E94-4CB6-AE44-45D8A61C489E";
236 char uuid[36];
237
238 /* Open .prefix file */
239 is = Fopen(buf, "rb");
240 if (!is)
241 mike 1.1 continue;
242
243 /* Read UUID from file */
244 if (fread(uuid, 1, sizeof(uuid), is) != sizeof(uuid))
245 {
246 fclose(is);
247 continue;
248 }
249
250 /* Check whether UUID is the expected one */
251 if (memcmp(uuid, UUID, sizeof(uuid)) != 0)
252 {
253 fclose(is);
254 continue;
255 }
256
257 /* Success! */
258 fclose(is);
259 return 0;
260 }
261
262 mike 1.1 /* Remove next level from path */
263 p = strrchr(path, '/');
264 if (!p)
265 {
266 /* Not found! */
267 break;
268 }
269
270 *p = '\0';
271 }
272
273 /* Not found! */
274 return -1;
275 }
276 #endif /* defined(CONFIG_OS_WINDOWS) */
277
278 const char* GetPath(PathID id)
279 {
280 int i = ((int)id) % MI_COUNT(_paths);
281
282 #if defined(CONFIG_OS_WINDOWS)
283 mike 1.1 /* Look for Windows programs in same directory as this module */
284 if (id == ID_SERVERPROGRAM)
285 {
286 static char path[MAX_PATH_SIZE];
287
288 if (path[0] == '\0')
289 {
290 if (_GetFullProgramPath("omiserver", path) != 0)
291 return NULL;
292 }
293
294 return path;
295 }
296 else if (id == ID_PREFIX)
297 {
298 static char path[MAX_PATH_SIZE];
299
300 if (path[0] == '\0')
301 {
302 if (_ResolvePrefixPath(path) != 0)
303 return CONFIG_PREFIX;
304 mike 1.1 }
305
306 return path;
307 }
308
309 /* Although id is defined in enumeration and will always be less than
310 * MI_COUNT(_paths), VS prefast tool is compalining about buffer overrun
311 */
312 #endif
313
314 #if defined(CONFIG_OS_WINDOWS)
315 if (_paths[i].str[0] == '.' && !_paths[i].dynamic)
316 {
317 char buf[MAX_PATH_SIZE];
318 Strlcpy(buf, GetPath(ID_PREFIX), sizeof(buf));
319 Strlcat(buf, _paths[i].str + 1, sizeof(buf));
320 _paths[i].str = Strdup(buf);
321 _paths[i].dynamic = MI_TRUE;
322 }
323 #endif
324
325 mike 1.1 return _paths[i].str;
326
327 }
328
329 int SetPath(PathID id, const char* path)
330 {
331 /* First prepend 'destdir' to all other paths */
332 if (id == ID_DESTDIR)
333 {
334 size_t i = 0;
335
336 for (i = 0; i < MI_COUNT(_paths); i++)
337 {
338 char buf[MAX_PATH_SIZE];
339
340 if (i == (size_t)ID_DESTDIR)
341 continue;
342
343 if (strcmp(_paths[i].nickname, "destdir") == 0)
344 continue;
345
346 mike 1.1 Strlcpy(buf, path, sizeof(buf));
347 Strlcat(buf, "/", sizeof(buf));
348 Strlcat(buf, _paths[i].str, sizeof(buf));
349
350 if (SetPath((PathID)i, buf) != 0)
351 return -1;
352 }
353 }
354
355 /* Set the path */
356 {
357 size_t i = (size_t)((int)id) % MI_COUNT(_paths);
358 char* str = Strdup(path);
359
360 if (!str)
361 return -1;
362
363 if (_paths[i].dynamic)
364 free(_paths[i].str);
365
366 _paths[i].str = str;
367 mike 1.1 _paths[i].dynamic = MI_TRUE;
368 }
369
370 return 0;
371 }
372
373 void PrintPaths()
374 {
375 size_t i;
376
377 for (i = 0; i < MI_COUNT(_paths); i++)
378 {
379 PathID id = (PathID)i;
380 printf("%s=%s\n", _paths[i].nickname, GetPath(id));
381 }
382 }
383
384 int SetPathFromNickname(const char* nickname, const char* path)
385 {
386 size_t i;
387
388 mike 1.1 for (i = 0; i < MI_COUNT(_paths); i++)
389 {
390 if (strcmp(_paths[i].nickname, nickname) == 0)
391 return SetPath((PathID)i, path);
392 }
393
394 return -1;
395 }
396
397 MI_Boolean IsNickname(const char* nickname)
398 {
399 size_t i;
400
401 for (i = 0; i < MI_COUNT(_paths); i++)
402 {
403 if (strcmp(_paths[i].nickname, nickname) == 0)
404 {
405 return MI_TRUE;
406 }
407 }
408
409 mike 1.1 /* Not found */
410 return MI_FALSE;
411 }
412
413 END_EXTERNC
|