(file) Return to paths.c CVS log (file) (dir) Up to [OMI] / omi / base

  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 mike  1.2 #define HTTPSENDTRACEFILE LOGDIR "/omiserver-send.trc"
 49           #define HTTPRECVTRACEFILE LOGDIR "/omiserver-recv.trc"
 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 },
 91 mike  1.2     { "authdir", CONFIG_AUTHDIR, MI_FALSE },
 92               { "httpsendtracefile", HTTPSENDTRACEFILE, MI_FALSE },
 93               { "httprecvtracefile", HTTPRECVTRACEFILE, 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

ViewCVS 0.9.2