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