version 1.1.2.21, 2006/12/29 17:47:30
|
version 1.1.2.22, 2006/12/29 22:22:03
|
|
|
| |
//============================================================================== | //============================================================================== |
// | // |
// SigTermHandler() |
// SetBit() |
// | // |
// Signal handler for SIGTERM. |
// Set the n-th bit the the given mask. |
|
// |
|
//============================================================================== |
|
|
|
inline void SetBit(unsigned long& mask, int n) |
|
{ |
|
mask |= (1 << n); |
|
} |
|
|
|
//============================================================================== |
|
// |
|
// ClrBit() |
|
// |
|
// Clear the n-th bit the the given mask. |
// | // |
//============================================================================== | //============================================================================== |
| |
static bool _caughtSigTerm = false; |
inline void ClrBit(unsigned long& mask, int n) |
|
{ |
|
mask &= ~(1 << n); |
|
} |
|
|
|
//============================================================================== |
|
// |
|
// TstBit() |
|
// |
|
// Test the n-th bit the the given mask. |
|
// |
|
//============================================================================== |
| |
void SigTermHandler(int signum) |
inline bool TstBit(unsigned long mask, int n) |
{ | { |
_caughtSigTerm = true; |
return mask & (1 << n); |
} | } |
| |
//============================================================================== | //============================================================================== |
// | // |
// SigIntHandler() |
// SigHandler() |
// | // |
// Signal handler for SIGINT. |
// Signal handler for SIGTERM. |
// | // |
//============================================================================== | //============================================================================== |
| |
static bool _caughtSigInt = false; |
static unsigned long _signalMask = 0; |
| |
void SigIntHandler(int signum) |
void SigHandler(int signum) |
{ | { |
_caughtSigInt = true; |
SetBit(_signalMask, signum); |
} | } |
| |
//============================================================================== | //============================================================================== |
|
|
{ | { |
int status = WaitForReadEnable(sock, TIMEOUT_MSEC); | int status = WaitForReadEnable(sock, TIMEOUT_MSEC); |
| |
if (_caughtSigTerm || _caughtSigInt) |
if (TstBit(_signalMask, SIGTERM) || TstBit(_signalMask, SIGINT)) |
{ | { |
// Terminated with SIGTERM or SIGINT. | // Terminated with SIGTERM or SIGINT. |
return 0; | return 0; |
|
|
EXECUTOR_RESTART(read(sock, p, r), n); | EXECUTOR_RESTART(read(sock, p, r), n); |
| |
if (n == -1 && errno == EINTR) | if (n == -1 && errno == EINTR) |
{ |
|
if (_caughtSigTerm) |
|
{ |
|
Log(LOG_INFO, "Caught sigterm"); |
|
} |
|
continue; | continue; |
} |
|
| |
if (n == -1) | if (n == -1) |
{ | { |
|
|
// ATTN: handle this or not? | // ATTN: handle this or not? |
int status = WaitForWriteEnable(sock, TIMEOUT_MSEC); | int status = WaitForWriteEnable(sock, TIMEOUT_MSEC); |
| |
if (_caughtSigTerm) |
if (TstBit(_signalMask, SIGTERM) || TstBit(_signalMask, SIGINT)) |
{ | { |
// ATTN: ignore? |
// Ignore! |
} | } |
| |
if (status == 0) | if (status == 0) |
|
|
| |
static int GetHomedPath( | static int GetHomedPath( |
const char* name, | const char* name, |
char path[EXECUTOR_MAX_PATH_LENGTH]) |
char path[EXECUTOR_BUFFER_SIZE]) |
{ | { |
// If absolute, then use the name as is. | // If absolute, then use the name as is. |
| |
if (name[0] == '/') | if (name[0] == '/') |
{ | { |
STRLCPY(path, name, EXECUTOR_MAX_PATH_LENGTH); |
STRLCPY(path, name, EXECUTOR_BUFFER_SIZE); |
return 0; | return 0; |
} | } |
| |
|
|
if (!home) | if (!home) |
return -1; | return -1; |
| |
STRLCPY(path, home, EXECUTOR_MAX_PATH_LENGTH); |
STRLCPY(path, home, EXECUTOR_BUFFER_SIZE); |
STRLCAT(path, "/", EXECUTOR_MAX_PATH_LENGTH); |
STRLCAT(path, "/", EXECUTOR_BUFFER_SIZE); |
STRLCAT(path, name, EXECUTOR_MAX_PATH_LENGTH); |
STRLCAT(path, name, EXECUTOR_BUFFER_SIZE); |
| |
return 0; | return 0; |
} | } |
|
|
| |
// Build full path name for this file: | // Build full path name for this file: |
| |
char buffer[EXECUTOR_MAX_PATH_LENGTH]; |
char buffer[EXECUTOR_BUFFER_SIZE]; |
STRLCPY(buffer, path, EXECUTOR_MAX_PATH_LENGTH); |
STRLCPY(buffer, path, EXECUTOR_BUFFER_SIZE); |
STRLCAT(buffer, "/", EXECUTOR_MAX_PATH_LENGTH); |
STRLCAT(buffer, "/", EXECUTOR_BUFFER_SIZE); |
STRLCAT(buffer, name, EXECUTOR_MAX_PATH_LENGTH); |
STRLCAT(buffer, name, EXECUTOR_BUFFER_SIZE); |
| |
// Determine file type (skip soft links and directories). | // Determine file type (skip soft links and directories). |
| |
|
|
// | // |
//============================================================================== | //============================================================================== |
| |
static void GetPegasusInternalBinDir(char path[EXECUTOR_MAX_PATH_LENGTH]) |
static void GetPegasusInternalBinDir(char path[EXECUTOR_BUFFER_SIZE]) |
{ | { |
// Make a copy of PEGASUS_PROVIDER_AGENT_PROC_NAME: | // Make a copy of PEGASUS_PROVIDER_AGENT_PROC_NAME: |
| |
char buffer[EXECUTOR_MAX_PATH_LENGTH]; |
char buffer[EXECUTOR_BUFFER_SIZE]; |
STRLCPY(buffer, PEGASUS_PROVIDER_AGENT_PROC_NAME, sizeof(buffer)); | STRLCPY(buffer, PEGASUS_PROVIDER_AGENT_PROC_NAME, sizeof(buffer)); |
| |
// Remove "cimprovagt" suffix. | // Remove "cimprovagt" suffix. |
|
|
| |
if (buffer[0] == '/') | if (buffer[0] == '/') |
{ | { |
STRLCAT(path, buffer, EXECUTOR_MAX_PATH_LENGTH); |
STRLCAT(path, buffer, EXECUTOR_BUFFER_SIZE); |
} | } |
else | else |
{ | { |
|
|
if (!home) | if (!home) |
Fatal(FL, "Failed to locate the internal Pegasus bin directory"); | Fatal(FL, "Failed to locate the internal Pegasus bin directory"); |
| |
STRLCPY(path, home, EXECUTOR_MAX_PATH_LENGTH); |
STRLCPY(path, home, EXECUTOR_BUFFER_SIZE); |
STRLCAT(path, "/", EXECUTOR_MAX_PATH_LENGTH); |
STRLCAT(path, "/", EXECUTOR_BUFFER_SIZE); |
STRLCAT(path, buffer, EXECUTOR_MAX_PATH_LENGTH); |
STRLCAT(path, buffer, EXECUTOR_BUFFER_SIZE); |
} | } |
| |
// Fail if no such directory. | // Fail if no such directory. |
|
|
| |
static void GetInternalPegasusProgramPath( | static void GetInternalPegasusProgramPath( |
const char* program, | const char* program, |
char path[EXECUTOR_MAX_PATH_LENGTH]) |
char path[EXECUTOR_BUFFER_SIZE]) |
{ | { |
GetPegasusInternalBinDir(path); | GetPegasusInternalBinDir(path); |
STRLCAT(path, "/", EXECUTOR_MAX_PATH_LENGTH); |
STRLCAT(path, "/", EXECUTOR_BUFFER_SIZE); |
STRLCAT(path, program, EXECUTOR_MAX_PATH_LENGTH); |
STRLCAT(path, program, EXECUTOR_BUFFER_SIZE); |
} | } |
| |
//============================================================================== | //============================================================================== |
|
|
// | // |
//============================================================================== | //============================================================================== |
| |
static int GetUserName(int uid, char username[EXECUTOR_MAX_PATH_LENGTH]) |
static int GetUserName(int uid, char username[EXECUTOR_BUFFER_SIZE]) |
{ | { |
struct passwd pwd; | struct passwd pwd; |
const unsigned int PWD_BUFF_SIZE = 4096; | const unsigned int PWD_BUFF_SIZE = 4096; |
|
|
return -1; | return -1; |
} | } |
| |
STRLCPY(username, ptr->pw_name, EXECUTOR_MAX_PATH_LENGTH); |
STRLCPY(username, ptr->pw_name, EXECUTOR_BUFFER_SIZE); |
return 0; | return 0; |
} | } |
| |
|
|
int argc, | int argc, |
char** argv, | char** argv, |
const char* name, | const char* name, |
char value[EXECUTOR_MAX_PATH_LENGTH]) |
char value[EXECUTOR_BUFFER_SIZE]) |
{ | { |
size_t n = strlen(name); | size_t n = strlen(name); |
| |
|
|
if (strncmp(argv[i], name, n) == 0 && argv[i][n] == '=') | if (strncmp(argv[i], name, n) == 0 && argv[i][n] == '=') |
{ | { |
const char* p = argv[i] + n + 1; | const char* p = argv[i] + n + 1; |
STRLCPY(value, argv[i] + n + 1, EXECUTOR_MAX_PATH_LENGTH); |
STRLCPY(value, argv[i] + n + 1, EXECUTOR_BUFFER_SIZE); |
return 0; | return 0; |
} | } |
} | } |
|
|
static int FindConfigFileOption( | static int FindConfigFileOption( |
const char* path, | const char* path, |
const char* name, | const char* name, |
char value[EXECUTOR_MAX_PATH_LENGTH]) |
char value[EXECUTOR_BUFFER_SIZE]) |
{ | { |
FILE* is = fopen(path, "r"); | FILE* is = fopen(path, "r"); |
| |
if (!is) | if (!is) |
return -1; | return -1; |
| |
char buffer[EXECUTOR_MAX_PATH_LENGTH]; |
char buffer[EXECUTOR_BUFFER_SIZE]; |
const size_t n = strlen(name); | const size_t n = strlen(name); |
| |
while (fgets(buffer, sizeof(buffer), is) != 0) | while (fgets(buffer, sizeof(buffer), is) != 0) |
|
|
| |
if (strncmp(buffer, name, n) == 0 && buffer[n] == '=') | if (strncmp(buffer, name, n) == 0 && buffer[n] == '=') |
{ | { |
STRLCPY(value, buffer + n + 1, EXECUTOR_MAX_PATH_LENGTH); |
STRLCPY(value, buffer + n + 1, EXECUTOR_BUFFER_SIZE); |
fclose(is); | fclose(is); |
return 0; | return 0; |
} | } |
|
|
int argc, | int argc, |
char** argv, | char** argv, |
const char* name, | const char* name, |
char value[EXECUTOR_MAX_PATH_LENGTH]) |
char value[EXECUTOR_BUFFER_SIZE]) |
{ | { |
// (1) First check command line. | // (1) First check command line. |
| |
|
|
| |
// ATTN: Is this right. Should we check the current or the planned? | // ATTN: Is this right. Should we check the current or the planned? |
| |
char path[EXECUTOR_MAX_PATH_LENGTH]; |
char path[EXECUTOR_BUFFER_SIZE]; |
| |
if (GetHomedPath(PEGASUS_PLANNED_CONFIG_FILE_PATH, path) == 0 && | if (GetHomedPath(PEGASUS_PLANNED_CONFIG_FILE_PATH, path) == 0 && |
FindConfigFileOption(path, name, value) == 0) | FindConfigFileOption(path, name, value) == 0) |
|
|
static int LocateRepositoryDirectory( | static int LocateRepositoryDirectory( |
int argc, | int argc, |
char** argv, | char** argv, |
char path[EXECUTOR_MAX_PATH_LENGTH]) |
char path[EXECUTOR_BUFFER_SIZE]) |
{ | { |
if (FindConfigOption(argc, argv, "repositoryDir", path) == 0) | if (FindConfigOption(argc, argv, "repositoryDir", path) == 0) |
return 0; | return 0; |
|
|
int GetServerUser( | int GetServerUser( |
int argc, | int argc, |
char** argv, | char** argv, |
char path[EXECUTOR_MAX_PATH_LENGTH], |
char path[EXECUTOR_BUFFER_SIZE], |
int& uid, | int& uid, |
int& gid) | int& gid) |
{ | { |
// (1) First try to find serverUser configuration option. | // (1) First try to find serverUser configuration option. |
| |
char user[EXECUTOR_MAX_PATH_LENGTH]; |
char user[EXECUTOR_BUFFER_SIZE]; |
| |
if (FindConfigOption(argc, argv, "serverUser", user) == 0) | if (FindConfigOption(argc, argv, "serverUser", user) == 0) |
{ | { |
|
|
{ | { |
// Resolve full path of "cimprovagt". | // Resolve full path of "cimprovagt". |
| |
char path[EXECUTOR_MAX_PATH_LENGTH]; |
char path[EXECUTOR_BUFFER_SIZE]; |
GetInternalPegasusProgramPath(CIMPROVAGT, path); | GetInternalPegasusProgramPath(CIMPROVAGT, path); |
| |
// Create "to-agent" pipe: | // Create "to-agent" pipe: |
|
|
} | } |
} | } |
| |
char username[EXECUTOR_MAX_PATH_LENGTH]; |
char username[EXECUTOR_BUFFER_SIZE]; |
| |
if (GetUserName(getuid(), username) != 0) | if (GetUserName(getuid(), username) != 0) |
Fatal(FL, "failed to resolve username for uid=%d", getuid()); | Fatal(FL, "failed to resolve username for uid=%d", getuid()); |
|
|
| |
// Catch SIGTERM: | // Catch SIGTERM: |
| |
signal(SIGTERM, SigTermHandler); |
signal(SIGTERM, SigHandler); |
| |
// Set current directory to root: | // Set current directory to root: |
| |
|
|
{ | { |
// Handle Ctrl-C. | // Handle Ctrl-C. |
| |
signal(SIGINT, SigIntHandler); |
signal(SIGINT, SigHandler); |
|
signal(SIGTERM, SigHandler); |
| |
// Save child PID globally; it is used by Exit() function. | // Save child PID globally; it is used by Exit() function. |
| |
|
|
| |
// Reached due to socket EOF or SIGTERM. | // Reached due to socket EOF or SIGTERM. |
| |
if (_caughtSigTerm) |
|
Log(LOG_INFO, "caught SIGTERM"); |
|
|
|
Exit(0); | Exit(0); |
} | } |
| |
|
|
static void Child( | static void Child( |
int argc, | int argc, |
char** argv, | char** argv, |
char path[EXECUTOR_MAX_PATH_LENGTH], |
char path[EXECUTOR_BUFFER_SIZE], |
int uid, | int uid, |
int gid, | int gid, |
int sock) | int sock) |
{ | { |
// Locate repository directory. | // Locate repository directory. |
| |
char repositoryDir[EXECUTOR_MAX_PATH_LENGTH]; |
char repositoryDir[EXECUTOR_BUFFER_SIZE]; |
| |
if (LocateRepositoryDirectory(argc, argv, repositoryDir) != 0) | if (LocateRepositoryDirectory(argc, argv, repositoryDir) != 0) |
Fatal(FL, "failed to locate repository directory"); | Fatal(FL, "failed to locate repository directory"); |
|
|
| |
// Log user info. | // Log user info. |
| |
char username[EXECUTOR_MAX_PATH_LENGTH]; |
char username[EXECUTOR_BUFFER_SIZE]; |
| |
if (GetUserName(uid, username) != 0) | if (GetUserName(uid, username) != 0) |
Fatal(FL, "cannot resolve user from uid=%d", uid); | Fatal(FL, "cannot resolve user from uid=%d", uid); |
|
|
// socket to child process. | // socket to child process. |
| |
{ | { |
char buffer[EXECUTOR_MAX_PATH_LENGTH]; |
char buffer[EXECUTOR_BUFFER_SIZE]; |
sprintf(buffer, "PEGASUS_EXECUTOR_SOCKET=%d", pair[0]); | sprintf(buffer, "PEGASUS_EXECUTOR_SOCKET=%d", pair[0]); |
putenv(buffer); | putenv(buffer); |
} | } |
|
|
| |
// Print user info. | // Print user info. |
| |
char username[EXECUTOR_MAX_PATH_LENGTH]; |
char username[EXECUTOR_BUFFER_SIZE]; |
| |
if (GetUserName(getuid(), username) != 0) | if (GetUserName(getuid(), username) != 0) |
Fatal(FL, "cannot resolve user from uid=%d", getuid()); | Fatal(FL, "cannot resolve user from uid=%d", getuid()); |
|
|
| |
// Get cimservermain program name. | // Get cimservermain program name. |
| |
char cimservermainPath[EXECUTOR_MAX_PATH_LENGTH]; |
char cimservermainPath[EXECUTOR_BUFFER_SIZE]; |
GetInternalPegasusProgramPath(CIMSERVERMAIN, cimservermainPath); | GetInternalPegasusProgramPath(CIMSERVERMAIN, cimservermainPath); |
| |
// Determine user for running cimservermain. | // Determine user for running cimservermain. |