pandorafms/pandora_agents/embedded/pandora_util.c

407 lines
9.9 KiB
C

// Pandora FMS Embedded Agent
// (c) Artica Soluciones Tecnológicas S.L 2011
// (c) Sancho Lerena <slerena@artica.es>
// 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.
//
// 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.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include "pandora_type.h"
#include "pandora_util.h"
// ==========================================================================
// pandora_free: Free pointers
// ==========================================================================
void
pandora_free (void *pointer){
if (pointer != NULL)
{
free(pointer);
}
}
char *
return_time (char *formatstring) {
char buffer[256];
char *output;
time_t curtime;
struct tm *loctime;
curtime = time (NULL);
loctime = localtime (&curtime);
strftime (buffer, 256, formatstring, loctime);
asprintf (&output, buffer);
return output;
}
int
pandora_return_unixtime () {
char outstr[200];
int value;
time_t t;
struct tm *tmp;
t = time(NULL);
tmp = localtime(&t);
strftime(outstr, sizeof(outstr), "%s", tmp);
value = atoi (outstr);
return value;
}
char* rtrim(char* string, char junk)
{
char* original = string + strlen(string);
while(original != string && *--original == junk);
*(original + 1) = '\0';
return string;
}
char* ltrim(char *string, char junk)
{
char* original = string;
char *p = original;
int trimmed = 0;
do
{
if (*original != junk || trimmed)
{
trimmed = 1;
*p++ = *original;
}
}
while (*original++ != '\0');
return string;
}
char *
trim (char * s)
{
s=rtrim(s, ' ');
s=rtrim(s, '\t');
s=rtrim(s, '\n');
s=ltrim(s, ' ');
s=ltrim(s, '\t');
s=ltrim(s, '\n');
}
// ==========================================================================
// ==========================================================================
char *
pandora_exec (char *commandline) {
//printf("CommandLine :%s:\n", commandline);
/* Output buffer */
char *data = NULL;
int read;
/* File descriptor */
FILE *fc = NULL;
int MAXBUF = 8192; // I will only read the first 8192 bytes of output.
char buffer[MAXBUF];
/* Open output of execution as a readonline file handle */
/* if NULL is a problem in the execution or empty exec output */
fc = popen (commandline, "r");
if (fc == NULL)
{
return NULL;
}
// With popen I sometimes cannot get the file size, so I need to read until find the EOF
// Don't try to use the usual methods to get filesize, it doesnt work on all cases, so I
// use a fixed buffer to avoid problems, 8K should be enough for most pandora data results
data = malloc ((MAXBUF + 1) * sizeof(char)) ;
read = fread (data, sizeof(char), MAXBUF, fc); /* Read the entire file, buffers are for weaks :-) */
data[read]='\0';
pclose (fc);
return data;
}
// ==========================================================================
// Copy the XML using tentacle to the server
// ==========================================================================
void
tentacle_copy (char *filename, struct pandora_setup *pandorasetup){
char * cmd=NULL;
char * aux=NULL;
asprintf (&cmd, "tentacle_client -a %s -p %d %s", pandorasetup->server_ip, pandorasetup->server_port, filename);
aux=pandora_exec (cmd);
pandora_free(aux);
pandora_free (cmd);
}
// ==========================================================================
// ==========================================================================
char *
pandora_write_xml_header (struct pandora_setup *pandorasetup) {
char *os_version=NULL;
char *date=NULL;
char *buffer=NULL;
char *buffer2=NULL;
char *buffer3=NULL;
os_version=pandora_exec ("uname -m");
trim(os_version);
if (pandorasetup->autotime == 1)
{
asprintf (&date, "AUTO");
}
else
{
date = return_time("%Y/%m/%d %H:%M:%S");
}
asprintf (&buffer, "<?xml version='1.0' encoding='ISO-8859-1'?>\n");
asprintf (&buffer2, "<agent_data os_name='embedded' os_version='%s' interval='%d' version='4.0dev' timestamp='%s' agent_name='%s'>\n", os_version, pandorasetup->interval, date, pandorasetup->agent_name);
asprintf (&buffer3, "%s%s",buffer, buffer2);
pandora_free (os_version);
pandora_free (buffer2);
pandora_free (buffer);
pandora_free (date);
return buffer3;
}
// ==========================================================================
// ==========================================================================
char *
pandora_write_xml_footer () {
char *buffer=NULL;
asprintf (&buffer, "</agent_data>\n");
return buffer;
}
// ==========================================================================
// ==========================================================================
char *
pandora_write_xml_module (struct pandora_module *ptmodule)
{
char *data=NULL;
char *buffer=NULL;
char *name=NULL;
char *type=NULL;
char *desc=NULL;
if (ptmodule->module_name==NULL)
asprintf(&name, "");
else
asprintf(&name, ptmodule->module_name);
if (ptmodule->module_type==NULL)
asprintf(&type, "");
else
asprintf(&type, ptmodule->module_type);
if (ptmodule->module_description==NULL)
asprintf(&desc, "");
else
asprintf(&desc, ptmodule->module_description);
data=pandora_exec(ptmodule->module_exec);
trim(data);
asprintf (&buffer, "\t<module>\n\t<name><![CDATA[%s]]></name>\n\t<description><![CDATA[%s]]></description>\n\t<type>%s</type>\n\t<data><![CDATA[%s]]></data>\n\t</module>\n", name, desc, type, data);
pandora_free(data);
pandora_free(name);
pandora_free(type);
pandora_free(desc);
return buffer;
}
char *
pandora_write_xml_module_plugin (struct pandora_module *ptmodule)
{
char *buffer=pandora_exec(ptmodule->module_plugin);
return buffer;
}
char *
pandora_write_xml_disk (struct pandora_setup *pandorasetup, struct pandora_module *list){
int fileseed;
char *filename=NULL;
char *header=NULL;
char *buffer=NULL;
char *footer=NULL;
FILE *pandora_xml;
// Set pseudorandom number
fileseed = pandora_return_unixtime ();
// Set XML filename
asprintf (&filename, "%s/%s.%d.data", pandorasetup->temporal, pandorasetup->agent_name, fileseed);
// (DEBUG)
if (pandorasetup->debug == 1){
printf ("[DEBUG] XML Filename is %s \n", filename);
}
pandora_xml = fopen (filename, "w");
if (pandora_xml == NULL){
printf ("ERROR: Cannot open xmlfile at %s for writing. ABORTING\n", filename);
exit (-1);
}
header = pandora_write_xml_header (pandorasetup);
fprintf (pandora_xml, "%s", header);
struct pandora_module *ptaux=list;
while (ptaux!=NULL)
{
if (ptaux->module_type!=NULL)
{
buffer = pandora_write_xml_module(ptaux);
fprintf(pandora_xml, "%s", buffer);
}
else if (ptaux->module_plugin!=NULL)
{
buffer = pandora_write_xml_module_plugin(ptaux);
fprintf(pandora_xml, "%s", buffer);
}
ptaux=ptaux->next;
pandora_free(buffer);
}
footer = pandora_write_xml_footer ();
fprintf (pandora_xml, "%s", footer);
fclose (pandora_xml);
pandora_free (header);
pandora_free (footer);
return filename;
}
// ==========================================================================
// pandora_log
// --------------------------------------------------------------------------
// Desc: Create an entry in text logfile, based on verbosity and inserting
// date and time values.
// Return: void
// Param: level of message, message and pandorasetup struct
// ==========================================================================
void
pandora_log (int level, char *message, struct pandora_setup *pandorasetup ){
// Level of messages
// 0 - Critical error (FAILURE)
// 1 - User error (ERROR)
// 2 - Warning
// 3 - Notice
// 4 - Info
// 5 - Verbose
// 6 - 10 - Different levels of debug message
if (level <= pandorasetup->verbosity) { // Only for my verbose level or lower.
FILE *pandora_log;
char *buff_timedate;
char *buff_timedate2;
char *buff_level;
time_t now;
struct tm *gmtime;
// Assign NULL to this pointers
buff_timedate = NULL;
buff_timedate2 = NULL;
buff_level=NULL;
now = time(NULL);
gmtime = localtime(&now);
switch (level){
case 0: asprintf (&buff_level,"[F]"); break;
case 1: asprintf (&buff_level,"[E]"); break;
case 2: asprintf (&buff_level,"[W]"); break;
case 3: asprintf (&buff_level,"[N]"); break;
case 4: asprintf (&buff_level,"[I]"); break;
case 5: asprintf (&buff_level,"[V]"); break;
default: asprintf (&buff_level,"[D]");
};
buff_timedate = malloc(256);
strftime (buff_timedate, 256, "%m-%d-%y %H:%M:%S", gmtime);
asprintf (&buff_timedate2, "%s %s %s\n", buff_timedate, buff_level,message);
pandora_log = fopen (pandorasetup->logfile, "a");
if (pandora_log == NULL){
printf ("ERROR: Cannot open logfile at %s. ABORTING\n", pandorasetup->logfile);
exit(-1);
}
fprintf (pandora_log, "%s", buff_timedate2);
// Free mem
fclose (pandora_log);
pandora_free (buff_timedate);
buff_timedate = NULL;
pandora_free (buff_timedate2);
buff_timedate2 = NULL;
pandora_free (buff_level);
buff_level = NULL;
}
}
// ==========================================================================
// Check for a filename end in ".data" string
// BEWARE of UPPERCASE filenames.
// ==========================================================================
int
isdatafile (char *filename){
int valid;
char *token; // reference to a position in *filename memory
valid = -1;
token = strtok(filename,".");
while (token != NULL){
if (strcmp(token,"data")==0)
valid=0;
else
valid=-1;
token = strtok(NULL,".");
}
return valid;
}