version 1.2, 2015/04/20 18:10:13
|
version 1.3, 2015/04/20 18:19:55
|
|
|
*/ | */ |
| |
#include <common.h> | #include <common.h> |
#include <base/args.h> |
|
#include <string> | #include <string> |
#include <vector> | #include <vector> |
#include <base/lib.h> |
#include <pal/shlib.h> |
|
#ifndef _MSC_VER |
#include <unistd.h> | #include <unistd.h> |
#include <base/getopt.h> |
#endif |
|
#include <base/omigetopt.h> |
#include <base/paths.h> | #include <base/paths.h> |
#include <base/dir.h> |
#include <pal/dir.h> |
#include <base/io.h> |
#include <pal/format.h> |
#include <base/file.h> |
#include <pal/file.h> |
#include <base/time.h> |
#include <pal/sleep.h> |
|
#include <base/naming.h> |
|
#ifndef _MSC_VER |
#include <dlfcn.h> | #include <dlfcn.h> |
#include <unistd.h> |
|
#include <sys/wait.h> | #include <sys/wait.h> |
|
#endif |
#include <omiclient/client.h> | #include <omiclient/client.h> |
|
#include <fstream> |
|
|
|
#if defined(CONFIG_ENABLE_WCHAR) |
|
typedef std::wstring ZString; |
|
#else |
|
typedef std::string ZString; |
|
#endif |
| |
using namespace std; | using namespace std; |
| |
static const char USAGE[] = "\ |
#define REG_INDICATION_CLASS "INDICATIONCLASS" |
|
|
|
static const ZChar USAGE[] = MI_T("\ |
Usage: %s [OPTIONS] PROVIDERLIBRARY\n\ | Usage: %s [OPTIONS] PROVIDERLIBRARY\n\ |
\n\ | \n\ |
OVERVIEW:\n\ | OVERVIEW:\n\ |
|
|
-l, --link Mode for developers. Instead of copying library file\n\ | -l, --link Mode for developers. Instead of copying library file\n\ |
link is created in lib directory.\n\ | link is created in lib directory.\n\ |
-o, --hosting HOSTING Use given hosting mode (@requestor@,@inproc@,<user>).\n\ | -o, --hosting HOSTING Use given hosting mode (@requestor@,@inproc@,<user>).\n\ |
|
-i, --instancelifetime LT Changes default lifetime of instances created from\n\ |
|
the MI_Context. Default is until destroyed by the\n\ |
|
provider by calling MI_Instance_Delete or\n\ |
|
MI_Instance_Destruct, but overridable by setting LT to\n\ |
|
CONTEXT such that it will automatically get deleted when\n\ |
|
the MI_Context gets destroyed after the operation.\n\ |
\n\ | \n\ |
EXAMPLES:\n\ | EXAMPLES:\n\ |
The following generates a provider registration file for the provider\n\ | The following generates a provider registration file for the provider\n\ |
|
|
\n\ | \n\ |
$ omireg -n interop -n root/cimv2 libDogProvider.so\n\ | $ omireg -n interop -n root/cimv2 libDogProvider.so\n\ |
\n\ | \n\ |
"; |
"); |
| |
using namespace std; | using namespace std; |
| |
|
|
// | // |
//============================================================================== | //============================================================================== |
| |
PRINTF_FORMAT(1, 2) |
static void FUNCTION_NEVER_RETURNS err(const ZChar* fmt, ...) |
static void FUNCTION_NEVER_RETURNS err(const char* fmt, ...) |
|
{ | { |
fprintf(stderr, "%s: ", arg0); |
Ftprintf(stderr, ZT("%s: "), scs(arg0)); |
| |
va_list ap; | va_list ap; |
va_start(ap, fmt); | va_start(ap, fmt); |
vfprintf(stderr, fmt, ap); |
Vftprintf(stderr, fmt, ap); |
va_end(ap); | va_end(ap); |
| |
fputc('\n', stderr); |
Ftprintf(stderr, ZT("\n")); |
exit(1); | exit(1); |
} | } |
| |
|
|
bool help; | bool help; |
bool devmode; | bool devmode; |
string hosting; | string hosting; |
|
bool instancelifetime; |
vector<string> nsDirs; | vector<string> nsDirs; |
| |
Options() : help(false), devmode(false) |
Options() : help(false), devmode(false), instancelifetime(false) |
{ | { |
} | } |
}; | }; |
|
|
if (strcmp(argv[i], "--destdir") == 0) | if (strcmp(argv[i], "--destdir") == 0) |
{ | { |
if (i + 1 == argc) | if (i + 1 == argc) |
err("missing argument for --destdir option"); |
err(ZT("missing argument for --destdir option")); |
| |
destdir = argv[i+1]; | destdir = argv[i+1]; |
memmove((char*)&argv[i], (char*)&argv[i+2], | memmove((char*)&argv[i], (char*)&argv[i+2], |
|
|
if (destdir) | if (destdir) |
{ | { |
if (SetPath(ID_DESTDIR, destdir) != 0) | if (SetPath(ID_DESTDIR, destdir) != 0) |
err("failed to set destdir"); |
err(ZT("failed to set destdir")); |
} | } |
| |
*argc_ = argc; | *argc_ = argc; |
|
|
"--link", | "--link", |
"-o:", | "-o:", |
"--hosting:", | "--hosting:", |
|
"-i:", |
|
"--instancelifetime:", |
|
"--registerdir:", |
|
"--providerdir:", |
NULL | NULL |
}; | }; |
| |
|
|
break; | break; |
| |
if (r == -1) | if (r == -1) |
err("%s", state.err); |
err(ZT("%s"), scs(state.err)); |
| |
if (strcmp(state.opt, "-h") == 0 || | if (strcmp(state.opt, "-h") == 0 || |
strcmp(state.opt, "--help") == 0) | strcmp(state.opt, "--help") == 0) |
|
|
else if (strcmp(state.opt, "-v") == 0 || | else if (strcmp(state.opt, "-v") == 0 || |
strcmp(state.opt, "--version") == 0) | strcmp(state.opt, "--version") == 0) |
{ | { |
printf("%s: %s\n", arg0, |
#if defined(CONFIG_OS_WINDOWS) |
CONFIG_PRODUCT "-" CONFIG_VERSION " - " CONFIG_DATE); |
Tprintf(ZT("%s: %S\n"), scs(arg0), |
|
tcs(CONFIG_PRODUCT L"-" CONFIG_VERSION L" - " CONFIG_DATE)); |
|
#else |
|
Tprintf(ZT("%s: %s\n"), scs(arg0), |
|
scs(CONFIG_PRODUCT "-" CONFIG_VERSION " - " CONFIG_DATE)); |
|
#endif |
exit(0); | exit(0); |
} | } |
else if (strcmp(state.opt, "-l") == 0 || | else if (strcmp(state.opt, "-l") == 0 || |
|
|
for (size_t i = 0; i < ns.size(); i++) | for (size_t i = 0; i < ns.size(); i++) |
{ | { |
if (ns[i] == '/') | if (ns[i] == '/') |
ns[i] = '#'; |
ns[i] = NAMESPACE_SEPARATOR; |
} | } |
| |
ns = string(GetPath(ID_REGISTERDIR)) + string("/") + ns; |
ns = string(OMI_GetPath(ID_REGISTERDIR)) + string("/") + ns; |
options.nsDirs.push_back(ns); | options.nsDirs.push_back(ns); |
} | } |
else if (strcmp(state.opt, "-o") == 0 || | else if (strcmp(state.opt, "-o") == 0 || |
|
|
{ | { |
options.hosting = state.arg; | options.hosting = state.arg; |
} | } |
|
else if (strcmp(state.opt, "-i") == 0 || |
|
strcmp(state.opt, "--instancelifetime") == 0) |
|
{ |
|
if (Strcasecmp(state.arg, "context") == 0) |
|
{ |
|
options.instancelifetime = true; |
|
} |
|
} |
|
else if (strncmp(state.opt, "--", 2) == 0 && IsNickname(state.opt+2)) |
|
{ |
|
if (SetPathFromNickname(state.opt+2, state.arg) != 0) |
|
err(ZT("SetPathFromNickname() failed")); |
|
} |
} | } |
} | } |
| |
|
|
for (const MI_ClassDecl* p = cd; p; p = p->superClassDecl) | for (const MI_ClassDecl* p = cd; p; p = p->superClassDecl) |
{ | { |
if (p != cd) | if (p != cd) |
fprintf(os, ":"); |
Fprintf(os, ":"); |
fprintf(os, "%s", p->name); |
Fprintf(os, "%T", p->name); |
} | } |
} | } |
| |
static const MI_ClassDecl* FindClassDecl( | static const MI_ClassDecl* FindClassDecl( |
const MI_SchemaDecl* sd, | const MI_SchemaDecl* sd, |
const char* className) |
const ZChar* className) |
{ | { |
|
MI_Uint32 hash = Hash(className); |
for (MI_Uint32 i = 0; i < sd->numClassDecls; i++) | for (MI_Uint32 i = 0; i < sd->numClassDecls; i++) |
{ | { |
const MI_ClassDecl* p = sd->classDecls[i]; | const MI_ClassDecl* p = sd->classDecls[i]; |
| |
if (strcmp(p->name, className) == 0) |
if (hash == p->code && Tcscmp(p->name, className) == 0) |
return p; | return p; |
} | } |
| |
return 0; | return 0; |
} | } |
| |
|
static bool IsASuperClass( |
|
const MI_SchemaDecl* sd, |
|
const ZChar* className) |
|
{ |
|
MI_Uint32 hash = Hash(className); |
|
for (MI_Uint32 i = 0; i < sd->numClassDecls; i++) |
|
{ |
|
const MI_ClassDecl* p = sd->classDecls[i]; |
|
|
|
// Even if we remote the following check code will work fine and not much impact on performance. |
|
if (hash == p->code && Tcscmp(p->name, className) == 0) |
|
continue; |
|
|
|
for(p = p->superClassDecl; p; p = p->superClassDecl) |
|
{ |
|
if(hash == p->code && Tcscmp(p->name, className) == 0) |
|
return true; |
|
} |
|
} |
|
|
|
return false; |
|
} |
|
|
static void GenClassLine( | static void GenClassLine( |
FILE* os, | FILE* os, |
const MI_SchemaDecl* sd, | const MI_SchemaDecl* sd, |
const MI_ClassDecl* cd) | const MI_ClassDecl* cd) |
{ | { |
// Print the class path: CLASS1.CLASS2.CLASS3 | // Print the class path: CLASS1.CLASS2.CLASS3 |
fprintf(os, "CLASS="); |
|
PrintClassPath(os, cd); | PrintClassPath(os, cd); |
| |
// Print the association classes: | // Print the association classes: |
if (cd->flags & MI_FLAG_ASSOCIATION) | if (cd->flags & MI_FLAG_ASSOCIATION) |
{ | { |
fprintf(os, "{"); |
const MI_ClassDecl* rcd1 = NULL; |
|
const MI_ClassDecl* rcd2 = NULL; |
MI_Uint32 n = 0; |
|
|
|
for (MI_Uint32 i = 0; i < cd->numProperties; i++) | for (MI_Uint32 i = 0; i < cd->numProperties; i++) |
{ | { |
const MI_PropertyDecl* pd = cd->properties[i]; | const MI_PropertyDecl* pd = cd->properties[i]; |
|
|
const MI_ClassDecl* rcd = FindClassDecl(sd, pd->className); | const MI_ClassDecl* rcd = FindClassDecl(sd, pd->className); |
| |
if (!rcd) | if (!rcd) |
err("failed to find class: %s", pd->className); |
err(PAL_T("failed to find class: %T"), tcs(pd->className)); |
| |
if (n != 0) |
if (!rcd1) |
fprintf(os, ","); |
rcd1 = rcd; |
PrintClassPath(os, rcd); |
else if (!rcd2) |
n++; |
rcd2 = rcd; |
|
else |
|
err(PAL_T("invalid assocation class: %T, which has more than two reference properties"), tcs(cd->name)); |
} | } |
} | } |
| |
fprintf(os, "}"); |
if (!rcd2) |
} |
err(PAL_T("invalid assocation class: %T, which has less than two reference properties"), tcs(cd->name)); |
|
|
|
Fprintf(os, "{"); |
|
PrintClassPath(os, rcd1); |
|
Fprintf(os, ","); |
|
PrintClassPath(os, rcd2); |
| |
fprintf(os, "\n"); |
Fprintf(os, "}"); |
|
} |
|
Fprintf(os, "\n"); |
} | } |
| |
static MI_Module* LoadModule(const char* path) | static MI_Module* LoadModule(const char* path) |
{ | { |
const char FUNC[] = "MI_Main"; | const char FUNC[] = "MI_Main"; |
|
TChar Tpath[PAL_MAX_PATH_SIZE]; |
|
|
|
if (TcsStrlcpy(Tpath, path, PAL_MAX_PATH_SIZE) >= PAL_MAX_PATH_SIZE) |
|
err(ZT("failed to load library: %s\n"), scs(path)); |
| |
// Load the library: | // Load the library: |
void* handle = Lib_Open(path); |
Shlib* handle = Shlib_Open(Tpath); |
if (!handle) | if (!handle) |
{ | { |
char* msg = Lib_Err(); |
TChar* msg = Shlib_Err(); |
err("failed to load library: %s\n", msg); |
err(ZT("failed to load library: %T\n"), tcs(msg)); |
Lib_Free(msg); |
|
} | } |
| |
// Load the MI_Main() entry point: | // Load the MI_Main() entry point: |
void* sym = Lib_Sym(handle, FUNC); |
void* sym = Shlib_Sym(handle, FUNC); |
if (!sym) | if (!sym) |
{ | { |
err("failed to find symbol '%s' in library '%s'\n", FUNC, path); |
err(ZT("failed to find symbol '%s' in library '%s'\n"), |
|
scs(FUNC), scs(path)); |
} | } |
| |
// Call MI_Main() to get MI_Module object. | // Call MI_Main() to get MI_Module object. |
|
|
MI_Module* module = (*main)(NULL); | MI_Module* module = (*main)(NULL); |
if (!module) | if (!module) |
{ | { |
err("%s:%s() failed", path, FUNC); |
err(ZT("%s:%s() failed"), scs(path), scs(FUNC)); |
} | } |
|
|
// Check character size: | // Check character size: |
if (module->charSize != sizeof(MI_Char)) |
if (module->charSize != sizeof(ZChar)) |
|
{ |
|
err(ZT("Char size required for provider (%u) different from OMI server char size (%u), see --enable-wchar in omi configuration help"), |
|
module->charSize, (int)sizeof(ZChar)); |
|
} |
|
|
|
// Check version |
|
if (module->version > MI_VERSION) |
{ | { |
err("provider char size (%u) does not match %s char size (%u)", |
MI_Uint32 v = module->version; |
module->charSize, arg0, (int)sizeof(MI_Char)); |
err(ZT("provider version (%d.%d.%d) newer than server version (%d.%d.%d), which is not supported"), |
|
MI_VERSION_GET_MAJOR(v), MI_VERSION_GET_MINOR(v), MI_VERSION_GET_REVISION(v), MI_MAJOR, MI_MINOR, MI_REVISION); |
} | } |
| |
return module; | return module; |
} | } |
| |
|
static ZString _ToZString(const char* str) |
|
{ |
|
ZString r; |
|
|
|
while (*str) |
|
r += ZChar(*str++); |
|
|
|
return r; |
|
} |
|
|
static void GenRegFile( | static void GenRegFile( |
FILE* os, | FILE* os, |
int argc, | int argc, |
|
|
MI_SchemaDecl* sd = module->schemaDecl; | MI_SchemaDecl* sd = module->schemaDecl; |
if (!sd) | if (!sd) |
{ | { |
err("MI_Module.schemaDecl is null"); |
err(ZT("MI_Module.schemaDecl is null")); |
} | } |
| |
// Generate header line. | // Generate header line. |
fprintf(os, "# "); |
Fprintf(os, "# "); |
for (int i = 0; i < argc; i++) | for (int i = 0; i < argc; i++) |
{ | { |
string arg; | string arg; |
|
|
else | else |
arg = argv[i]; | arg = argv[i]; |
| |
fprintf(os, "%s", arg.c_str()); |
Fprintf(os, "%s", scs(arg.c_str())); |
if (i + 1 != argc) | if (i + 1 != argc) |
fprintf(os, " "); |
Fprintf(os, " "); |
} | } |
fprintf(os, "\n"); |
Fprintf(os, "\n"); |
| |
// Write library name: | // Write library name: |
fprintf(os, "LIBRARY=%s\n", baseName.c_str()); |
Fprintf(os, "LIBRARY=%s\n", scs(baseName.c_str())); |
| |
// Hosting | // Hosting |
if (!opts.hosting.empty()) | if (!opts.hosting.empty()) |
{ | { |
fprintf(os, "HOSTING=%s\n", opts.hosting.c_str()); |
Fprintf(os, "HOSTING=%s\n", scs(opts.hosting.c_str())); |
|
} |
|
if (opts.instancelifetime) |
|
{ |
|
Fprintf(os, "INSTANCELIFETIME=CONTEXT\n"); |
} | } |
| |
// Find providers: | // Find providers: |
|
|
const MI_ClassDecl* cd = sd->classDecls[i]; | const MI_ClassDecl* cd = sd->classDecls[i]; |
| |
if (!cd) | if (!cd) |
err("null classDecl element"); |
err(ZT("null classDecl element")); |
| |
// If it has a provider, print the class line. |
|
if (cd->providerFT) | if (cd->providerFT) |
{ | { |
|
if (cd->flags & MI_FLAG_INDICATION) |
|
{ |
|
Fprintf(os, REG_INDICATION_CLASS); |
|
// If it is a provider implemented indication class, print the class line |
|
Fprintf(os, "="); |
|
GenClassLine(os, sd, cd); |
|
} |
|
else |
|
{ |
|
// If it is a provider implemented class, print the class line as CLASS=class1:class2:class3 |
|
Fprintf(os, "CLASS="); |
GenClassLine(os, sd, cd); | GenClassLine(os, sd, cd); |
} | } |
} | } |
|
else |
|
{ |
|
// Noting down all non implemented classes which are not a super class. |
|
// With this all the classes present in a provider either implemented or not implemeted will be listed in .reg file. |
|
// EXTRACLASS=class1:class2:class3 |
|
|
|
// Checking if the class is a super class of any other class (implemented or not-implemented) |
|
if(! IsASuperClass(sd, cd->name)) |
|
{ |
|
Fprintf(os, "EXTRACLASS="); |
|
GenClassLine(os, sd, cd); |
|
} |
|
} |
|
} |
} | } |
| |
static bool Inhale(const char* path, vector<char>& data) | static bool Inhale(const char* path, vector<char>& data) |
{ | { |
FILE* is = Fopen(path, "r"); |
bool Ret = false; |
|
std::ifstream inputFile(path, std::ios::in | std::ios::binary); |
| |
if (!is) |
if (inputFile.is_open()) |
return false; |
{ |
|
// get length of file: |
size_t n; |
int Length = 0; |
char buf[4096]; |
|
| |
while ((n = fread(buf, 1, sizeof(buf), is)) != 0) |
// Ask the operating system how big the file is. It should have |
|
// the information in cache, since we just opened it. |
|
struct stat fileStat; |
|
if (0 == stat(path, &fileStat)) |
{ | { |
data.insert(data.end(), buf, buf + n); |
Length = fileStat.st_size; |
} |
data.resize(Length+1, '\0'); |
| |
data.push_back('\0'); |
// read data as a block: |
|
inputFile.read (&data[0], Length); |
|
inputFile.close(); |
| |
fclose(is); |
data[Length] = '\0'; |
| |
return true; |
Ret = true; |
|
} |
|
} |
|
|
|
return Ret; |
} | } |
| |
static void _RefreshServer() | static void _RefreshServer() |
{ | { |
// check if server is running |
#ifndef _MSC_VER |
mi::Client cl; | mi::Client cl; |
const MI_Uint64 TIMEOUT = 500 * 1000; | const MI_Uint64 TIMEOUT = 500 * 1000; |
| |
if (cl.Connect(GetPath(ID_SOCKETFILE), MI_T(""), MI_T(""), TIMEOUT)) |
const char* sockfile = OMI_GetPath(ID_SOCKETFILE); |
|
|
|
if (!sockfile) |
|
{ |
|
err(ZT("OMI_GetPath(ID_SOCKETFILE) failed")); |
|
} |
|
|
|
ZString socketFile = _ToZString(OMI_GetPath(ID_SOCKETFILE)); |
|
|
|
if (cl.Connect(socketFile.c_str(), MI_T(""), MI_T(""), TIMEOUT)) |
{ | { |
// reload server's config | // reload server's config |
pid_t child = fork(); | pid_t child = fork(); |
if (!child) | if (!child) |
{ | { |
execl(GetPath(ID_SERVERPROGRAM), GetPath(ID_SERVERPROGRAM), "-r", |
execl(OMI_GetPath(ID_SERVERPROGRAM), OMI_GetPath(ID_SERVERPROGRAM), "-r", |
NULL ); | NULL ); |
exit(1); // never get here... if everything is ok | exit(1); // never get here... if everything is ok |
} | } |
|
|
// wait for server to restart | // wait for server to restart |
for ( int i = 0; i < 30; i++ ) | for ( int i = 0; i < 30; i++ ) |
{ | { |
if (cl.Connect(GetPath(ID_SOCKETFILE), MI_T(""), MI_T(""), TIMEOUT)) |
if (cl.Connect(socketFile.c_str(), MI_T(""), MI_T(""), TIMEOUT)) |
break; | break; |
| |
Time_Sleep(50); |
Sleep_Milliseconds(50); |
} | } |
} | } |
|
#endif |
} | } |
| |
int main(int argc, const char** argv) |
int MI_MAIN_CALL main(int argc, const char** argv) |
{ | { |
arg0 = argv[0]; | arg0 = argv[0]; |
| |
|
|
| |
// Get command-line options. | // Get command-line options. |
Options opts; | Options opts; |
|
|
GetCommandLineOptions(argc, argv, opts); | GetCommandLineOptions(argc, argv, opts); |
| |
if (opts.nsDirs.size() == 0) | if (opts.nsDirs.size() == 0) |
|
|
for (size_t i = 0; i < ns.size(); i++) | for (size_t i = 0; i < ns.size(); i++) |
{ | { |
if (ns[i] == '/') | if (ns[i] == '/') |
ns[i] = '#'; |
ns[i] = NAMESPACE_SEPARATOR; |
} | } |
| |
ns = string(GetPath(ID_REGISTERDIR)) + string("/") + ns; |
ns = string(OMI_GetPath(ID_REGISTERDIR)) + string("/") + ns; |
opts.nsDirs.push_back(ns); | opts.nsDirs.push_back(ns); |
} | } |
| |
// Check arguments. | // Check arguments. |
if (opts.help) | if (opts.help) |
{ | { |
fprintf(stderr, USAGE, arg0); |
Ftprintf(stderr, USAGE, arg0); |
exit(1); | exit(1); |
} | } |
| |
// Check number of arguments. | // Check number of arguments. |
if (argc != 2) | if (argc != 2) |
{ | { |
fprintf(stderr, "Usage: %s PROVIDERLIBRARY\n", arg0); |
Ftprintf(stderr, ZT("Usage: %s PROVIDERLIBRARY\n"), scs(arg0)); |
fprintf(stderr, "Try '%s --help' for help\n\n", arg0); |
Ftprintf(stderr, ZT("Try '%s --help' for help\n\n"), scs(arg0)); |
exit(1); | exit(1); |
} | } |
| |
|
|
const string path = opts.nsDirs[i]; | const string path = opts.nsDirs[i]; |
| |
if (!Isdir(path.c_str())) | if (!Isdir(path.c_str())) |
err("no such namespace directory: %s", path.c_str()); |
{ |
|
if (Mkdir(path.c_str(), 0755) != 0) |
|
{ |
|
err(ZT("Failed to create namespace directory: %s "), scs(path.c_str())); |
|
} |
|
else |
|
{ |
|
Tprintf(ZT("Created namespace directory: %s\n"), scs(path.c_str())); |
|
} |
|
} |
| |
if (access(path.c_str(), W_OK) != 0) | if (access(path.c_str(), W_OK) != 0) |
err("namespace directory is not writable: %s", path.c_str()); |
err(ZT("namespace directory is not writable: %s"), |
|
scs(path.c_str())); |
|
} |
|
|
|
char argv1[PAL_MAX_PATH_SIZE]; |
|
Strlcpy(argv1, argv[1], PAL_MAX_PATH_SIZE); |
|
#ifdef CONFIG_OS_WINDOWS |
|
// Translate backward to forward slashes in the argv[1] |
|
char* p; |
|
|
|
for (p = argv1; *p; p++) |
|
{ |
|
if (*p == '\\') |
|
*p = '/'; |
} | } |
|
#endif |
|
|
| |
#ifdef CONFIG_OS_HPUX | #ifdef CONFIG_OS_HPUX |
// HP is the only platform that locks loaded binary files | // HP is the only platform that locks loaded binary files |
|
|
_RefreshServer(); | _RefreshServer(); |
#endif | #endif |
| |
// Copy library to provider directory (avoid copy if file is identical |
|
// since the path could be the same). |
|
{ | { |
|
|
|
#ifndef _MSC_VER |
vector<char> data1; | vector<char> data1; |
| |
if (!Inhale(argv[1], data1)) |
if (!Inhale(argv1, data1)) |
err("cannot read provider library: %s", argv[1]); |
err(ZT("cannot read provider library: %s"), scs(argv1)); |
|
#endif |
| |
string path = GetPath(ID_PROVIDERDIR); |
string path = OMI_GetPath(ID_PROVIDERDIR); |
path += "/"; | path += "/"; |
path += Basename(argv[1]); |
path += Basename(argv1); |
| |
|
#ifndef _MSC_VER |
if (opts.devmode) | if (opts.devmode) |
{ | { |
|
if (argv[1][0] != '/') |
|
{ |
|
err(ZT("expected absolute path: '%s'"), scs(argv1)); |
|
} |
|
|
unlink(path.c_str()); | unlink(path.c_str()); |
if (symlink(argv[1], path.c_str()) != 0) |
|
err("failed to symlink '%s' to '%s'", argv[1], path.c_str()); |
if (symlink(argv1, path.c_str()) != 0) |
|
{ |
|
err(ZT("failed to symlink '%s' to '%s'"), |
|
scs(argv1), scs(path.c_str())); |
|
} |
} | } |
else | else |
{ | { |
if (File_Copy(argv[1], path.c_str()) != 0) |
#endif |
err("failed to copy '%s' to '%s'", argv[1], path.c_str()); |
if (File_Copy(argv1, path.c_str()) != 0) |
|
err(ZT("failed to copy '%s' to '%s'"), |
|
scs(argv1), scs(path.c_str())); |
| |
|
#ifndef _MSC_VER |
// set mod explicitly | // set mod explicitly |
// w by owner only; RX for all. | // w by owner only; RX for all. |
chmod(path.c_str(), | chmod(path.c_str(), |
S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH); | S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH); |
|
#endif |
| |
printf("Created %s\n", path.c_str()); |
Tprintf(ZT("Created %s\n"), scs(path.c_str())); |
|
#ifndef _MSC_VER |
} | } |
|
#endif |
} | } |
| |
// Load module: | // Load module: |
MI_Module* module = LoadModule(argv[1]); |
MI_Module* module = LoadModule(argv1); |
if (!module) | if (!module) |
err("failed to load provider library: %s", argv[1]); |
err(ZT("failed to load provider library: %s"), scs(argv1)); |
| |
// Generate .reg file in each namespace directory: | // Generate .reg file in each namespace directory: |
for (size_t i = 0; i < opts.nsDirs.size(); i++) | for (size_t i = 0; i < opts.nsDirs.size(); i++) |
{ | { |
// Open output file (using basename of library): | // Open output file (using basename of library): |
string baseLibName = BaseLibName(argv[1]); |
string baseLibName = BaseLibName(argv1); |
string regFileName = baseLibName + ".reg"; | string regFileName = baseLibName + ".reg"; |
| |
string path = opts.nsDirs[i]; | string path = opts.nsDirs[i]; |
|
|
FILE* os = fopen(path.c_str(), "wb"); | FILE* os = fopen(path.c_str(), "wb"); |
| |
if (!os) | if (!os) |
err("failed to open: %s", path.c_str()); |
err(ZT("failed to open: %s"), scs(path.c_str())); |
| |
// Generate the registration file. | // Generate the registration file. |
GenRegFile(os, argc, argv, baseLibName, module, opts); | GenRegFile(os, argc, argv, baseLibName, module, opts); |
| |
printf("Created %s\n", path.c_str()); |
Tprintf(ZT("Created %s\n"), scs(path.c_str())); |
| |
fclose(os); | fclose(os); |
} | } |