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