Files
spine/php.c
T
Larry Adams c3d57cc2de logging updates. Almost done.
git-svn-id: svn+ssh://repo.cacti.net/var/data/svnroot/cacti/trunk/cactid_unix@1719 860744bd-22fc-0310-8c96-e9fe5004b5ca
2004-07-15 17:27:10 +00:00

244 lines
7.7 KiB
C

/*
+-------------------------------------------------------------------------+
| Copyright (C) 2004 Ian Berry |
| |
| This program is free software; you can redistribute it and/or |
| modify it under the terms of the GNU General Public License |
| as published by the Free Software Foundation; either version 2 |
| of the License, or (at your option) any later version. |
| |
| This program is distributed in the hope that it will be useful, |
| but WITHOUT ANY WARRANTY; without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| GNU General Public License for more details. |
+-------------------------------------------------------------------------+
| cactid: a backend data gatherer for cacti |
+-------------------------------------------------------------------------+
| This poller would not have been possible without: |
| - Rivo Nurges (rrd support, mysql poller cache, misc functions) |
| - RTG (core poller code, pthreads, snmp, autoconf examples) |
| - Brady Alleman/Doug Warner (threading ideas, implimentation details) |
+-------------------------------------------------------------------------+
| - raXnet - http://www.raxnet.net/ |
+-------------------------------------------------------------------------+
*/
#include <sys/wait.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/select.h>
#include <stdio.h>
#include <unistd.h>
#include <assert.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include "php.h"
#include "common.h"
#include "cactid.h"
#include "locks.h"
#include "util.h"
extern char **environ;
/******************************************************************************/
/* php_cmd() - Send a command to the Script Server */
/******************************************************************************/
char *php_cmd(char *php_command) {
char *result_string;
char *spaceloc;
char command[BUFSIZE+5];
/* pad command with CR-LF */
sprintf(command,php_command,strlen(php_command));
strcat(command,"\r\n");
thread_mutex_lock(LOCK_PHP);
/* send command to the script server */
write(php_pipes.php_write_fd, command, strlen(command));
/* read the result from the php_command */
result_string = php_readpipe();
/* Clean garbage from string. Don't know why it's there... */
spaceloc = strchr(result_string, ' ');
if (spaceloc != 0) {
*spaceloc = '\0';
spaceloc = strchr(result_string, ' ');
if (spaceloc != 0)
*spaceloc = '\0';
}
thread_mutex_unlock(LOCK_PHP);
return result_string;
}
/******************************************************************************/
/* php_readpipe - Read a line from the PHP Script Server */
/******************************************************************************/
char *php_readpipe() {
char *result_string = (char *) malloc(BUFSIZE);
char result[BUFSIZE] = "";
fd_set fds;
int rescode, numfds;
struct timeval timeout;
/* Initialize File Descriptors to Review for Input/Output */
FD_ZERO(&fds);
FD_SET(php_pipes.php_read_fd,&fds);
FD_SET(php_pipes.php_write_fd,&fds);
if (php_pipes.php_read_fd > php_pipes.php_write_fd)
numfds = php_pipes.php_read_fd + 1;
else
numfds = php_pipes.php_write_fd + 1;
/* Establish Timeout of 1 Second to Have PHP Script Server Respond */
timeout.tv_sec = 5;
timeout.tv_usec = 0;
/* Wait for A Response on The Pipes */
select(numfds, &fds, NULL, NULL, &timeout);
/* Check to See Which Pipe Talked and Take Action */
/* Should only be the READ Pipe */
if (FD_ISSET(php_pipes.php_read_fd, &fds)) {
rescode = read(php_pipes.php_read_fd, result_string, BUFSIZE);
if (rescode > 0)
snprintf(result_string, rescode, "%s", result_string);
else
snprintf(result_string, 2, "%s", "U");
} else {
cacti_log("ERROR: The PHP Script Server Did not Respond in Time\n");
snprintf(result_string, 2, "%s", "U");
}
return result_string;
}
/******************************************************************************/
/* php_init() - Initialize the PHP Script Server */
/******************************************************************************/
int php_init() {
int cacti2php_pdes[2];
int php2cacti_pdes[2];
char logmessage[255];
int i = 0;
int pid;
char *argv[4];
int check;
int cancel_state;
char *result_string;
if (set.verbose >= DEBUG) {
cacti_log("CACTID: PHP Script Server Routine Started.\n");
}
/* create the output pipes from cactid to php*/
if (pipe(cacti2php_pdes) < 0) {
cacti_log("ERROR: Could not allocate php server pipes\n");
return -1;
}
/* create the input pipes from php to cactid */
if (pipe(php2cacti_pdes) < 0) {
cacti_log("ERROR: Could not allocate php server pipes\n");
return -1;
}
/* Disable thread cancellation from this point forward. */
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cancel_state);
/* establish arguments for script server execution */
argv[0] = set.phppath;
argv[1] = set.path_php_server;
argv[2] = "cactid";
argv[3] = NULL;
/* fork a child process */
if (set.verbose >= DEBUG) {
cacti_log("CACTID: PHP Script Server About to FORK Child Process.\n");
}
pid = fork();
/* check the pid status and process as required */
switch (pid) {
case -1: /* ERROR: Could not fork() */
if (set.verbose >= DEBUG) {
cacti_log("CACTID: PHP Script Server Child FORK Failed.\n");
}
close(php2cacti_pdes[0]);
close(php2cacti_pdes[1]);
close(cacti2php_pdes[0]);
close(cacti2php_pdes[1]);
cacti_log("ERROR: Could not fork php script server\n");
pthread_setcancelstate(cancel_state, NULL);
return -1;
/* NOTREACHED */
case 0: /* SUCCESS: I am now the child */
/* Set the standard input/output channels of the new process. */
dup2(cacti2php_pdes[0], STDIN_FILENO);
dup2(php2cacti_pdes[1], STDOUT_FILENO);
/* Close Unneeded Pipes */
(void)close(php2cacti_pdes[0]);
(void)close(php2cacti_pdes[1]);
(void)close(cacti2php_pdes[0]);
(void)close(cacti2php_pdes[1]);
/* start the php script server process */
execve(argv[0], argv, environ);
_exit(127);
/* NOTREACHED */
default: /* I am the parent process */
if (set.verbose >= DEBUG) {
cacti_log("CACTID: PHP Script Server Child FORK Success.\n");
}
}
/* Parent */
/* Close Unneeded Pipes */
close(cacti2php_pdes[0]);
close(php2cacti_pdes[1]);
php_pipes.php_write_fd = cacti2php_pdes[1];
php_pipes.php_read_fd = php2cacti_pdes[0];
/* Restore caller's cancellation state. */
pthread_setcancelstate(cancel_state, NULL);
/* Check pipe to insure startup took place */
result_string = php_readpipe();
free(result_string);
if ((set.verbose == DEBUG) && (strstr(result_string, "Started")))
cacti_log("CACTID: Confirmed PHP Script Server Running\n");
return 1;
}
/******************************************************************************/
/* php_close - Close the pipes and wait for the status of the child. */
/******************************************************************************/
int php_close() {
int i;
char command[255];
char logmessage[255];
fd_set fds;
int numfds;
if (set.verbose >= DEBUG) {
cacti_log("CACTID: PHP Script Server Shutdown Started.\n");
}
/* tell the script server to close */
write(php_pipes.php_write_fd, "quit\r\n", sizeof("quit\r\n"));
/* close file descriptors */
close(php_pipes.php_write_fd);
close(php_pipes.php_read_fd);
}