(file) Return to omireg.cpp CVS log (file) (dir) Up to [OMI] / omi / omireg

  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 <common.h>
 26           #include <string>
 27           #include <vector>
 28 krisbash 1.3 #include <pal/shlib.h>
 29              #ifndef _MSC_VER
 30 mike     1.1 #include <unistd.h>
 31 krisbash 1.3 #endif
 32              #include <base/omigetopt.h>
 33 mike     1.1 #include <base/paths.h>
 34 krisbash 1.3 #include <pal/dir.h>
 35              #include <pal/format.h>
 36              #include <pal/file.h>
 37              #include <pal/sleep.h>
 38              #include <base/naming.h>
 39              #ifndef _MSC_VER
 40 mike     1.1 #include <dlfcn.h>
 41              #include <sys/wait.h>
 42 krisbash 1.3 #endif
 43 mike     1.1 #include <omiclient/client.h>
 44 krisbash 1.3 #include <fstream>
 45              
 46              #if defined(CONFIG_ENABLE_WCHAR)
 47              typedef std::wstring ZString;
 48              #else
 49              typedef std::string ZString;
 50              #endif
 51 mike     1.1 
 52              using namespace std;
 53              
 54 krisbash 1.3 #define REG_INDICATION_CLASS "INDICATIONCLASS"
 55              
 56              static const ZChar USAGE[] = MI_T("\
 57 mike     1.1 Usage: %s [OPTIONS] PROVIDERLIBRARY\n\
 58              \n\
 59              OVERVIEW:\n\
 60                  This program generates a provider registration file (.reg) from\n\
 61                  information read from a provider library.\n\
 62              \n\
 63              OPTIONS:\n\
 64                  -h, --help                  Print this help message.\n\
 65                  -v, --version               Print version information.\n\
 66                  -n, --namespace NAME        Register provider for this namespace (option\n\
 67                                              may be repeated to specify multiple\n\
 68                                              nsDirs).\n\
 69                  -l, --link                  Mode for developers. Instead of copying library file\n\
 70                                              link is created in lib directory.\n\
 71                  -o, --hosting HOSTING       Use given hosting mode (@requestor@,@inproc@,<user>).\n\
 72 krisbash 1.3     -i, --instancelifetime LT   Changes default lifetime of instances created from\n\
 73                                              the MI_Context. Default is until destroyed by the\n\
 74                                              provider by calling MI_Instance_Delete or\n\
 75                                              MI_Instance_Destruct, but overridable by setting LT to\n\
 76                                              CONTEXT such that it will automatically get deleted when\n\
 77                                              the MI_Context gets destroyed after the operation.\n\
 78 mike     1.1 \n\
 79              EXAMPLES:\n\
 80                  The following generates a provider registration file for the provider\n\
 81                  contained in 'libDogProvider.so'. It then copies the .reg file and\n\
 82                  the provider to the installed locations.\n\
 83              \n\
 84                      $ omireg -n interop -n root/cimv2 libDogProvider.so\n\
 85              \n\
 86 krisbash 1.3 ");
 87 mike     1.1 
 88              using namespace std;
 89              
 90              static const char* arg0;
 91              
 92              //==============================================================================
 93              //
 94              // err()
 95              //
 96              //     Writes a formatted error message to standard error (preceded by argv[0])
 97              //     and then exists.
 98              //
 99              //==============================================================================
100              
101 krisbash 1.3 static void FUNCTION_NEVER_RETURNS err(const ZChar* fmt, ...)
102 mike     1.1 {
103 krisbash 1.3     Ftprintf(stderr, ZT("%s: "), scs(arg0));
104 mike     1.1 
105                  va_list ap;
106                  va_start(ap, fmt);
107 krisbash 1.3     Vftprintf(stderr, fmt, ap);
108 mike     1.1     va_end(ap);
109              
110 krisbash 1.3     Ftprintf(stderr, ZT("\n"));
111 mike     1.1     exit(1);
112              }
113              
114              //==============================================================================
115              //
116              // GetCommandLineOptions()
117              //
118              //     This function processes command line options.
119              //
120              //==============================================================================
121              
122              struct Options
123              {
124                  bool help;
125                  bool devmode;
126                  string  hosting;
127 krisbash 1.3     bool instancelifetime;
128 mike     1.1     vector<string> nsDirs;
129              
130 krisbash 1.3     Options() : help(false), devmode(false), instancelifetime(false)
131 mike     1.1     {
132                  }
133              }; 
134              
135              static void GetCommandLineDestDirOption(
136                  int* argc_,
137                  const char* argv[])
138              {
139                  int argc = *argc_;
140                  int i;
141                  const char* destdir = NULL;
142              
143                  for (i = 1; i < argc; )
144                  {
145                      if (strcmp(argv[i], "--destdir") == 0)
146                      {
147                          if (i + 1 == argc)
148 krisbash 1.3                 err(ZT("missing argument for --destdir option"));
149 mike     1.1 
150                          destdir = argv[i+1];
151                          memmove((char*)&argv[i], (char*)&argv[i+2], 
152                              sizeof(char*) * (argc-i-1));
153                          argc -= 2;
154                      }
155                      else if (strncmp(argv[i], "--destdir=", 10) == 0)
156                      {
157                          destdir = argv[i] + 10;
158                          memmove((char*)&argv[i], (char*)&argv[i+1], 
159                              sizeof(char*) * (argc-i));
160              
161                          argc -= 1;
162                      }
163                      else
164                          i++;
165                  }
166              
167                  if (destdir)
168                  {
169                      if (SetPath(ID_DESTDIR, destdir) != 0)
170 krisbash 1.3             err(ZT("failed to set destdir"));
171 mike     1.1     }
172              
173                  *argc_ = argc;
174              }
175              
176              static void GetCommandLineOptions( 
177                  int& argc, 
178                  const char**& argv, 
179                  Options& options)
180              {
181                  GetOptState state = GETOPTSTATE_INITIALIZER;
182                  const char* opts[] =
183                  {
184                      "-h",
185                      "--help",
186                      "-v",
187                      "--version",
188                      "-n:",
189                      "--namespace:",
190                      "-l",
191                      "--link",
192 mike     1.1         "-o:",
193                      "--hosting:",
194 krisbash 1.3         "-i:",
195                      "--instancelifetime:",
196                      "--registerdir:",
197                      "--providerdir:",
198 mike     1.1         NULL
199                  };
200              
201                  /* For each argument */
202                  for (;;)
203                  {
204                      int r = GetOpt(&argc, (const char**)argv, opts, &state);
205              
206                      if (r == 1)
207                          break;
208              
209                      if (r == -1)
210 krisbash 1.3             err(ZT("%s"), scs(state.err));
211 mike     1.1 
212                      if (strcmp(state.opt, "-h") == 0 || 
213                          strcmp(state.opt, "--help") == 0)
214                      {
215                          options.help = true;
216                      }
217                      else if (strcmp(state.opt, "-v") == 0 ||
218                               strcmp(state.opt, "--version") == 0)
219                      {
220 krisbash 1.3 #if defined(CONFIG_OS_WINDOWS)
221                          Tprintf(ZT("%s: %S\n"), scs(arg0),
222                              tcs(CONFIG_PRODUCT L"-" CONFIG_VERSION L" - " CONFIG_DATE));
223              #else
224                          Tprintf(ZT("%s: %s\n"), scs(arg0),
225                              scs(CONFIG_PRODUCT "-" CONFIG_VERSION " - " CONFIG_DATE));
226              #endif
227 mike     1.1             exit(0);
228                      }
229                      else if (strcmp(state.opt, "-l") == 0 || 
230                          strcmp(state.opt, "--link") == 0)
231                      {
232                          options.devmode = true;
233                      }
234                      else if (strcmp(state.opt, "-n") == 0 || 
235                          strcmp(state.opt, "--namespace") == 0)
236                      {
237                          string ns = state.arg;
238              
239                          for (size_t i = 0; i < ns.size(); i++)
240                          {
241                              if (ns[i] == '/')
242 krisbash 1.3                     ns[i] = NAMESPACE_SEPARATOR;
243 mike     1.1             }
244              
245 krisbash 1.3             ns = string(OMI_GetPath(ID_REGISTERDIR)) + string("/") + ns;
246 mike     1.1             options.nsDirs.push_back(ns);
247                      }
248                      else if (strcmp(state.opt, "-o") == 0 || 
249                          strcmp(state.opt, "--hosting") == 0)
250                      {
251                          options.hosting = state.arg;
252                      }
253 krisbash 1.3         else if (strcmp(state.opt, "-i") == 0 ||
254                          strcmp(state.opt, "--instancelifetime") == 0)
255                      {
256                          if (Strcasecmp(state.arg, "context") == 0)
257                          {
258                              options.instancelifetime = true;
259                          }
260                      }
261                      else if (strncmp(state.opt, "--", 2) == 0 && IsNickname(state.opt+2))
262                      {
263                          if (SetPathFromNickname(state.opt+2, state.arg) != 0)
264                              err(ZT("SetPathFromNickname() failed"));
265                      }
266 mike     1.1     }
267              }
268              
269              typedef MI_Module* (*MainProc)(MI_Server* server);
270              
271              static string BaseName(const string& str)
272              {
273                  const char* start = strrchr(str.c_str(), '/');
274              
275                  if (start)
276                      start++;
277                  else
278                      start = str.c_str();
279              
280                  return string(start);
281              }
282              
283              static string BaseLibName(const string& str)
284              {
285                  const char* start = strrchr(str.c_str(), '/');
286              
287 mike     1.1     if (start)
288                      start++;
289                  else
290                      start = str.c_str();
291              
292                  if (strncmp(start, "lib", 3) == 0)
293                      start += 3;
294              
295                  const char* p = start;
296              
297                  while (*p && *p != '.')
298                      p++;
299              
300                  return string(start, p - start);
301              }
302              
303              static void PrintClassPath(FILE* os, const MI_ClassDecl* cd)
304              {
305                  for (const MI_ClassDecl* p = cd; p; p = p->superClassDecl)
306                  {
307                      if (p != cd)
308 krisbash 1.3             Fprintf(os, ":");
309                      Fprintf(os, "%T", p->name);        
310 mike     1.1     }
311              }
312              
313              static const MI_ClassDecl* FindClassDecl(
314                  const MI_SchemaDecl* sd, 
315 krisbash 1.3     const ZChar* className)
316 mike     1.1 {
317 krisbash 1.3     MI_Uint32 hash = Hash(className);
318 mike     1.1     for (MI_Uint32 i = 0; i < sd->numClassDecls; i++)
319                  {
320                      const MI_ClassDecl* p = sd->classDecls[i];
321              
322 krisbash 1.3         if (hash == p->code && Tcscmp(p->name, className) == 0)
323 mike     1.1             return p;
324                  }
325              
326                  return 0;
327              }
328              
329 krisbash 1.3 static bool IsASuperClass(
330                  const MI_SchemaDecl* sd, 
331                  const ZChar* className)
332              {
333                  MI_Uint32 hash = Hash(className);
334                  for (MI_Uint32 i = 0; i < sd->numClassDecls; i++)
335                  {
336                      const MI_ClassDecl* p = sd->classDecls[i];
337              
338                      // Even if we remote the following check code will work fine and not much impact on performance.
339                      if (hash == p->code && Tcscmp(p->name, className) == 0)
340                          continue;
341              
342                      for(p = p->superClassDecl; p; p = p->superClassDecl)
343                      {
344                          if(hash == p->code && Tcscmp(p->name, className) == 0)
345                              return true;
346                      }
347                  }
348              
349                  return false;
350 krisbash 1.3 }
351              
352 mike     1.1 static void GenClassLine(
353                  FILE* os, 
354                  const MI_SchemaDecl* sd, 
355                  const MI_ClassDecl* cd)
356              {
357                  // Print the class path: CLASS1.CLASS2.CLASS3
358                  PrintClassPath(os, cd);
359              
360                  // Print the association classes:
361                  if (cd->flags & MI_FLAG_ASSOCIATION)
362                  {
363 krisbash 1.3         const MI_ClassDecl* rcd1 = NULL;
364                      const MI_ClassDecl* rcd2 = NULL;
365 mike     1.1         for (MI_Uint32 i = 0; i < cd->numProperties; i++)
366                      {
367                          const MI_PropertyDecl* pd = cd->properties[i];
368              
369                          if (pd->type == MI_REFERENCE && pd->className)
370                          {
371                              const MI_ClassDecl* rcd = FindClassDecl(sd, pd->className);
372              
373                              if (!rcd)
374 krisbash 1.3                     err(PAL_T("failed to find class: %T"), tcs(pd->className));
375 mike     1.1 
376 krisbash 1.3                 if (!rcd1)
377                                  rcd1 = rcd;
378                              else if (!rcd2)
379                                  rcd2 = rcd;
380                              else
381                                  err(PAL_T("invalid assocation class: %T, which has more than two reference properties"), tcs(cd->name));
382 mike     1.1             }
383                      }
384              
385 krisbash 1.3         if (!rcd2)
386                          err(PAL_T("invalid assocation class: %T, which has less than two reference properties"), tcs(cd->name));
387              
388                      Fprintf(os, "{");
389                      PrintClassPath(os, rcd1);
390                      Fprintf(os, ",");
391                      PrintClassPath(os, rcd2);
392              
393                      Fprintf(os, "}");
394 mike     1.1     }
395 krisbash 1.3     Fprintf(os, "\n");
396 mike     1.1 }
397              
398              static MI_Module* LoadModule(const char* path)
399              {
400                  const char FUNC[] = "MI_Main";
401 krisbash 1.3     TChar Tpath[PAL_MAX_PATH_SIZE];
402              
403                  if (TcsStrlcpy(Tpath, path, PAL_MAX_PATH_SIZE) >= PAL_MAX_PATH_SIZE)
404                      err(ZT("failed to load library: %s\n"), scs(path));
405 mike     1.1 
406                  // Load the library:
407 krisbash 1.3     Shlib* handle = Shlib_Open(Tpath);
408 mike     1.1     if (!handle)
409                  {
410 krisbash 1.3         TChar* msg = Shlib_Err();
411                      err(ZT("failed to load library: %T\n"), tcs(msg));
412 mike     1.1     }
413              
414                  // Load the MI_Main() entry point:
415 krisbash 1.3     void* sym = Shlib_Sym(handle, FUNC);
416 mike     1.1     if (!sym)
417                  {
418 krisbash 1.3         err(ZT("failed to find symbol '%s' in library '%s'\n"), 
419                          scs(FUNC), scs(path));
420 mike     1.1     }
421              
422                  // Call MI_Main() to get MI_Module object.
423                  MainProc main = (MainProc)sym;
424                  MI_Module* module = (*main)(NULL);
425                  if (!module)
426                  {
427 krisbash 1.3         err(ZT("%s:%s() failed"), scs(path), scs(FUNC));
428                  }
429                      // Check character size:
430                  if (module->charSize != sizeof(ZChar))
431                  {           
432                      err(ZT("Char size required for provider (%u) different from OMI server char size (%u), see --enable-wchar in omi configuration help"), 
433                          module->charSize, (int)sizeof(ZChar));
434 mike     1.1     }
435              
436 krisbash 1.3     // Check version
437                  if (module->version > MI_VERSION)
438 mike     1.1     {
439 krisbash 1.3         MI_Uint32 v =  module->version;
440                      err(ZT("provider version (%d.%d.%d) newer than server version (%d.%d.%d), which is not supported"),
441                          MI_VERSION_GET_MAJOR(v), MI_VERSION_GET_MINOR(v), MI_VERSION_GET_REVISION(v), MI_MAJOR, MI_MINOR, MI_REVISION);
442 mike     1.1     }
443              
444                  return module;
445              }
446              
447 krisbash 1.3 static ZString _ToZString(const char* str)
448              {
449                  ZString r;
450              
451                  while (*str)
452                      r += ZChar(*str++);
453              
454                  return r;
455              }
456              
457 mike     1.1 static void GenRegFile(
458                  FILE* os, 
459                  int argc, 
460                  const char** argv, 
461                  const string& baseName,
462                  MI_Module* module,
463                  const Options& opts)
464              {
465                  // Get schemaDecl:
466                  MI_SchemaDecl* sd = module->schemaDecl;
467                  if (!sd)
468                  {
469 krisbash 1.3         err(ZT("MI_Module.schemaDecl is null"));
470 mike     1.1     }
471              
472                  // Generate header line.
473 krisbash 1.3     Fprintf(os, "# ");
474 mike     1.1     for (int i = 0; i < argc; i++)
475                  {
476                      string arg;
477              
478                      if (i == 0)
479                          arg = BaseName(argv[i]);
480                      else
481                          arg = argv[i];
482              
483 krisbash 1.3         Fprintf(os, "%s", scs(arg.c_str()));
484 mike     1.1         if (i + 1 != argc)
485 krisbash 1.3             Fprintf(os, " ");
486 mike     1.1     }
487 krisbash 1.3     Fprintf(os, "\n");
488 mike     1.1 
489                  // Write library name:
490 krisbash 1.3     Fprintf(os, "LIBRARY=%s\n", scs(baseName.c_str()));
491 mike     1.1 
492                  // Hosting
493                  if (!opts.hosting.empty())
494                  {
495 krisbash 1.3         Fprintf(os, "HOSTING=%s\n", scs(opts.hosting.c_str()));
496                  }
497                  if (opts.instancelifetime)
498                  {
499                      Fprintf(os, "INSTANCELIFETIME=CONTEXT\n");
500 mike     1.1     }
501              
502                  // Find providers:
503                  for (MI_Uint32 i = 0; i < sd->numClassDecls; i++)
504                  {
505                      const MI_ClassDecl* cd = sd->classDecls[i];
506              
507                      if (!cd)
508 krisbash 1.3             err(ZT("null classDecl element"));
509 mike     1.1 
510                      if (cd->providerFT)
511                      {
512 krisbash 1.3             if (cd->flags & MI_FLAG_INDICATION)
513                          {
514                              Fprintf(os, REG_INDICATION_CLASS);
515                              // If it is a provider implemented indication class, print the class line
516                              Fprintf(os, "=");
517                              GenClassLine(os, sd, cd);
518                          }
519                          else
520                          {
521                              // If it is a provider implemented class, print the class line as CLASS=class1:class2:class3
522                              Fprintf(os, "CLASS=");
523                              GenClassLine(os, sd, cd);
524                          }
525                      }
526                      else
527                      {
528                          // Noting down all non implemented classes which are not a super class.
529                          // With this all the classes present in a provider either implemented or not implemeted will be listed in .reg file.
530                          // EXTRACLASS=class1:class2:class3
531              
532                          // Checking if the class is a super class of any other class (implemented or not-implemented)
533 krisbash 1.3             if(! IsASuperClass(sd, cd->name))
534                          {
535                              Fprintf(os, "EXTRACLASS=");
536                              GenClassLine(os, sd, cd);
537                          }
538 mike     1.1         }
539                  }
540              }
541              
542              static bool Inhale(const char* path, vector<char>& data)
543              {
544 krisbash 1.3     bool Ret = false;
545                  std::ifstream inputFile(path, std::ios::in | std::ios::binary);
546 mike     1.1 
547 krisbash 1.3     if (inputFile.is_open())
548                  {
549                      // get length of file:
550                      int Length = 0;
551 mike     1.1 
552 krisbash 1.3         // Ask the operating system how big the file is.  It should have
553                      // the information in cache, since we just opened it.
554                      struct stat fileStat;
555                      if (0 == stat(path, &fileStat))
556                      {
557                          Length = fileStat.st_size;
558                          data.resize(Length+1, '\0');
559 mike     1.1 
560 krisbash 1.3             // read data as a block:
561                          inputFile.read (&data[0], Length);
562                          inputFile.close();
563                  
564                          data[Length] = '\0';
565                  
566                          Ret = true;
567                      }
568 mike     1.1     }
569              
570 krisbash 1.3     return Ret;
571 mike     1.1 }
572              
573              static void _RefreshServer()
574              {
575 krisbash 1.3 #ifndef _MSC_VER
576 mike     1.1     mi::Client cl;
577                  const MI_Uint64 TIMEOUT = 500 * 1000;
578              
579 krisbash 1.3     const char* sockfile = OMI_GetPath(ID_SOCKETFILE);
580              
581                  if (!sockfile)
582                  {
583                      err(ZT("OMI_GetPath(ID_SOCKETFILE) failed"));
584                  }
585              
586                  ZString socketFile = _ToZString(OMI_GetPath(ID_SOCKETFILE));
587              
588                  if (cl.Connect(socketFile.c_str(), MI_T(""), MI_T(""), TIMEOUT))
589 mike     1.1     {
590                      // reload server's config
591                      pid_t child = fork();
592                      if (!child)
593                      {
594 krisbash 1.3             execl(OMI_GetPath(ID_SERVERPROGRAM), OMI_GetPath(ID_SERVERPROGRAM), "-r",
595 mike     1.1                 NULL );
596                          exit(1); // never get here... if everything is ok
597                      }
598                      else if (child > 0)
599                      {
600                          /* wait for child */
601                          int s;
602                          waitpid(child, &s, 0);
603                      }
604              
605                      // wait until it restarts
606                      cl.NoOp(TIMEOUT);
607              
608                      // wait for server to restart
609                      for ( int i = 0; i < 30; i++ )
610                      {
611 krisbash 1.3             if (cl.Connect(socketFile.c_str(), MI_T(""), MI_T(""), TIMEOUT))
612 mike     1.1                 break;
613              
614 krisbash 1.3             Sleep_Milliseconds(50);
615 mike     1.1         }
616                  }
617 krisbash 1.3 #endif
618 mike     1.1 }
619              
620 krisbash 1.3 int MI_MAIN_CALL main(int argc, const char** argv)
621 mike     1.1 {
622                  arg0 = argv[0];
623              
624                  // Get --destdir command-line option.
625                  GetCommandLineDestDirOption(&argc, argv);
626              
627                  // Get command-line options.
628                  Options opts;
629 krisbash 1.3 
630 mike     1.1     GetCommandLineOptions(argc, argv, opts);
631              
632                  if (opts.nsDirs.size() == 0)
633                  {
634                      string ns = CONFIG_NAMESPACE;
635              
636                      for (size_t i = 0; i < ns.size(); i++)
637                      {
638                          if (ns[i] == '/')
639 krisbash 1.3                 ns[i] = NAMESPACE_SEPARATOR;
640 mike     1.1         }
641              
642 krisbash 1.3         ns = string(OMI_GetPath(ID_REGISTERDIR)) + string("/") + ns;
643 mike     1.1         opts.nsDirs.push_back(ns);
644                  }
645              
646                  // Check arguments.
647                  if (opts.help)
648                  {
649 krisbash 1.3         Ftprintf(stderr, USAGE, arg0);
650 mike     1.1         exit(1);
651                  }
652                  
653                  // Check number of arguments.
654                  if (argc != 2)
655                  {
656 krisbash 1.3         Ftprintf(stderr, ZT("Usage: %s PROVIDERLIBRARY\n"), scs(arg0));
657                      Ftprintf(stderr, ZT("Try '%s --help' for help\n\n"), scs(arg0));
658 mike     1.1         exit(1);
659                  }
660              
661                  // Check that namespace directories are writable.
662                  for (size_t i = 0; i < opts.nsDirs.size(); i++)
663                  {
664                      const string path = opts.nsDirs[i];
665              
666                      if (!Isdir(path.c_str()))
667 krisbash 1.3         {
668                          if (Mkdir(path.c_str(), 0755) != 0)
669                          {
670                              err(ZT("Failed to create namespace directory: %s "), scs(path.c_str()));
671                          }
672                          else
673                          {
674                              Tprintf(ZT("Created namespace directory: %s\n"), scs(path.c_str()));
675                          }
676                      }
677 mike     1.1 
678                      if (access(path.c_str(), W_OK) != 0)
679 krisbash 1.3             err(ZT("namespace directory is not writable: %s"), 
680                              scs(path.c_str()));
681 mike     1.1     }
682              
683 krisbash 1.3     char argv1[PAL_MAX_PATH_SIZE];
684                  Strlcpy(argv1, argv[1], PAL_MAX_PATH_SIZE);
685              #ifdef CONFIG_OS_WINDOWS
686                  // Translate backward to forward slashes in the argv[1]       
687                  char* p;
688              
689                  for (p = argv1; *p; p++)
690                  {
691                      if (*p == '\\')
692                          *p = '/';
693                  }
694              #endif
695              
696              
697 mike     1.1 #ifdef CONFIG_OS_HPUX
698                  // HP is the only platform that locks loaded binary files 
699                  // so if provider is already loaded unlink/copy will fail 
700                  // force server to unload all providers before copying
701                  _RefreshServer();
702              #endif
703              
704                  {
705 krisbash 1.3 
706              #ifndef _MSC_VER
707 mike     1.1         vector<char> data1;
708              
709 krisbash 1.3         if (!Inhale(argv1, data1))
710                          err(ZT("cannot read provider library: %s"), scs(argv1));
711              #endif
712 mike     1.1 
713 krisbash 1.3         string path = OMI_GetPath(ID_PROVIDERDIR);
714                              path += "/";
715                      path += Basename(argv1);
716 mike     1.1 
717 krisbash 1.3 #ifndef _MSC_VER
718 mike     1.1         if (opts.devmode)
719                      {
720 krisbash 1.3             if (argv[1][0] != '/')
721                          {
722                              err(ZT("expected absolute path: '%s'"), scs(argv1));
723                          }
724              
725 mike     1.1             unlink(path.c_str());
726 krisbash 1.3 
727                          if (symlink(argv1, path.c_str()) != 0)
728                          {
729                              err(ZT("failed to symlink '%s' to '%s'"), 
730                                  scs(argv1), scs(path.c_str()));
731                          }
732 mike     1.1         }
733                      else
734                      {
735 krisbash 1.3 #endif
736                          if (File_Copy(argv1, path.c_str()) != 0)
737                              err(ZT("failed to copy '%s' to '%s'"), 
738                                  scs(argv1), scs(path.c_str()));
739 mike     1.1 
740 krisbash 1.3 #ifndef _MSC_VER
741 mike     1.1             // set mod explicitly
742                          // w by owner only; RX for all.
743                          chmod(path.c_str(), 
744                              S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH);
745 krisbash 1.3 #endif
746 mike     1.1 
747 krisbash 1.3             Tprintf(ZT("Created %s\n"), scs(path.c_str()));
748              #ifndef _MSC_VER
749 mike     1.1         }
750 krisbash 1.3 #endif
751 mike     1.1     }
752              
753                  // Load module:
754 krisbash 1.3     MI_Module* module = LoadModule(argv1);
755 mike     1.1     if (!module)
756 krisbash 1.3         err(ZT("failed to load provider library: %s"), scs(argv1));
757 mike     1.1 
758                  // Generate .reg file in each namespace directory:
759                  for (size_t i = 0; i < opts.nsDirs.size(); i++)
760                  {
761                      // Open output file (using basename of library):
762 krisbash 1.3         string baseLibName = BaseLibName(argv1);
763 mike     1.1         string regFileName = baseLibName + ".reg";
764              
765                      string path = opts.nsDirs[i];
766                      path += "/";
767                      path += regFileName;
768              
769                      FILE* os = fopen(path.c_str(), "wb");
770              
771                      if (!os)
772 krisbash 1.3             err(ZT("failed to open: %s"), scs(path.c_str()));
773 mike     1.1 
774                      // Generate the registration file.
775                      GenRegFile(os, argc, argv, baseLibName, module, opts);
776              
777 krisbash 1.3         Tprintf(ZT("Created %s\n"), scs(path.c_str()));
778 mike     1.1 
779                      fclose(os);
780                  }
781              
782                  // ask server to re-read configuration
783                  _RefreshServer();
784              
785                  return 0;
786              }

ViewCVS 0.9.2