(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           
 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

ViewCVS 0.9.2