2011-02-03 Javier Lanz <javier.lanz@artica.es>

* pandora_agent.c: Solved some leaks
	* pandora_agent.conf: Added some example modules
	* pandora_config.c: Added parse_config, fill module & fill setup functions
	* pandora_config.h: Fixed function prototypes
	* pandora_util.c: Added xml writer & trim functions
	* pandora_util.h: Added trim functions prototype 
	* pandora_type.h: Added pointer for the link list


git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@3799 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
This commit is contained in:
javilanz 2011-02-03 17:25:38 +00:00
parent 0d5fc9e1de
commit 6d10cb1cc4
8 changed files with 411 additions and 165 deletions

View File

@ -1,3 +1,12 @@
2011-02-03 Javier Lanz <javier.lanz@artica.es>
* pandora_agent.c: Solved some leaks
* pandora_agent.conf: Added some example modules
* pandora_config.c: Added parse_config, fill module & fill setup functions
* pandora_config.h: Fixed function prototypes
* pandora_util.c: Added xml writer & trim functions
* pandora_util.h: Added trim functions prototype
* pandora_type.h: Added pointer for the link list
2011-01-22 Sancho Lerena <slerena@artica.es> 2011-01-22 Sancho Lerena <slerena@artica.es>
* pandora_agent.c: Uses pandora_types.h instead module_types.h * pandora_agent.c: Uses pandora_types.h instead module_types.h

View File

@ -32,27 +32,29 @@
int int
main(int argc, char **argv) { main(int argc, char **argv) {
DIR *pDIR; DIR *pDIR=NULL;
struct dirent *pDirEnt; struct dirent *pDirEnt=NULL;
struct pandora_setup *pandorasetup; struct pandora_setup *pandorasetup=NULL;
char *config_file; struct pandora_module *list=NULL;
char *fullpath; char *config_file=NULL;
char *buffer; char *fullpath=NULL;
long int id_audit; char *buffer=NULL;
char c; long int id_audit;
char *xml_filename; char c;
char *xml_filename=NULL;
printf ("Pandora FMS Embedded Agent v%s (c) 2011 http://pandorafms.org\n", VERSION); printf ("Pandora FMS Embedded Agent v%s (c) 2011 http://pandorafms.org\n", VERSION);
config_file = NULL; config_file = NULL;
list=NULL;
if (argc < 2 && argc > 3){
if (argc < 2 || argc > 3){
printf ("Syntax is:\n\n pandora_agent <path_to_pandora_agent.conf> \n\n"); printf ("Syntax is:\n\n pandora_agent <path_to_pandora_agent.conf> \n\n");
exit (0); exit (0);
} }
char *cmd = *argv++; char *cmd = *argv++;
config_file = *argv++; config_file = *argv++;
if (config_file == NULL) { if (config_file == NULL) {
@ -61,12 +63,17 @@ main(int argc, char **argv) {
} }
pandorasetup = malloc(sizeof(struct pandora_setup)); pandorasetup = malloc(sizeof(struct pandora_setup));
pandorasetup->logfile=NULL;
pandorasetup->agent_name=NULL;
pandorasetup->server_ip=NULL;
pandorasetup->temporal=NULL;
pandorasetup->sancho_test=NULL;
// Initialize to default parameters // Initialize to default parameters
init_parameters (pandorasetup); init_parameters (pandorasetup);
// Load config file using first parameter // Load config file using first parameter
parse_config (pandorasetup, config_file); parse_config (pandorasetup, &list, config_file);
asprintf (&buffer,"Starting %s v%s", PACKAGE_NAME, VERSION); asprintf (&buffer,"Starting %s v%s", PACKAGE_NAME, VERSION);
pandora_log (3, buffer, pandorasetup); pandora_log (3, buffer, pandorasetup);
@ -86,7 +93,7 @@ main(int argc, char **argv) {
while (1){ // Main loop while (1){ // Main loop
xml_filename = pandora_write_xml_disk (pandorasetup); xml_filename = pandora_write_xml_disk (pandorasetup, list);
if (pandorasetup->debug == 1){ if (pandorasetup->debug == 1){
printf ("Debug mode activated. Exiting now! \n"); printf ("Debug mode activated. Exiting now! \n");
exit (0); exit (0);
@ -101,7 +108,5 @@ main(int argc, char **argv) {
pandora_free(xml_filename); pandora_free(xml_filename);
sleep(pandorasetup->interval); sleep(pandorasetup->interval);
} }
pandora_free(config_file);
return (0); return (0);
} }

View File

@ -42,5 +42,19 @@ server_port 41121
# ------------------------------------------------------------------------------- # -------------------------------------------------------------------------------
# #
module_begin
module_name memfree
module_type generic_data
module_exec cat /proc/meminfo | grep MemFree | awk '{ print $2 }'
module_end
module_begin
module_name Load Average
module_type generic_data
module_exec cat /proc/loadavg | cut -d' ' -f1
module_description Average process in CPU (Last minute)
module_end
#module_plugin /etc/pandora/plugins/pandora_df
module_plugin /etc/pandora/plugins/pandora_df module_plugin /etc/pandora/plugins/pandora_df

View File

@ -40,88 +40,229 @@ init_parameters (struct pandora_setup* pandorasetup)
pandorasetup->verbosity=5; pandorasetup->verbosity=5;
} }
int int
parse_config (struct pandora_setup* pandorasetup, char *config_file) fill_pandora_setup (struct pandora_setup *ps, char *field, char *value)
{ {
char *s, buff[MAXLEN]; if (!field)
return 0;
FILE *fp = fopen (config_file, "r"); if (!*field)
if (fp == NULL){ return 0;
return -1;
} if (strcmp(field, "logfile")==0) {
/* Read next line */ pandora_free(ps->logfile);
while ((s = fgets (buff, sizeof buff, fp) )){ asprintf(&ps->logfile, value);
/* Skip blank lines and comments */ return 1;
if (buff[0] == '\n' || buff[0] == '#') }
continue; else if (strcmp(field, "debug")==0) {
ps->debug=atoi(value);
/* Parse name/value pair from line */ return 1;
char name[MAXLEN], value[MAXLEN]; }
s = strtok (buff, " "); else if (strcmp(field, "interval")==0) {
ps->interval=atoi(value);
if (s==NULL){ return 1;
continue; }
} else { else if (strcmp(field, "autotime")==0) {
strncpy (name, s, MAXLEN); ps->autotime=atoi(value);
} return 1;
trim (name); // Purge blank spaces }
s = strtok (NULL, "="); else if (strcmp(field, "verbosity")==0) {
ps->verbosity=atoi(value);
if (s==NULL) { return 1;
continue; }
} else { else if (strcmp(field, "agent_name")==0) {
strncpy (value, s, MAXLEN); pandora_free(ps->agent_name);
} asprintf(&ps->agent_name, value);
trim (value); // Purge blank spaces return 1;
}
/* Copy into correct entry in parameters struct */ else if (strcmp(field, "server_ip")==0) {
if (strcmp(name, "verbosity")==0){ pandora_free(ps->server_ip);
pandorasetup->verbosity = atoi(value); asprintf(&ps->server_ip, value);
} return 1;
else if (strcmp(name, "debug")==0){ }
pandorasetup->debug = atoi(value); else if (strcmp(field, "temporal")==0) {
} pandora_free(ps->temporal);
else if (strcmp(name, "interval")==0){ asprintf(&ps->temporal, value);
pandorasetup->interval = atoi(value); return 1;
} }
else if (strcmp(name, "autotime")==0){ else if (strcmp(field, "server_port")==0) {
pandorasetup->autotime = atoi(value); ps->server_port=atoi(value);
} return 1;
else if (strcmp(name, "remote_config")==0){ }
pandorasetup->remote_config = atoi(value); else if (strcmp(field, "remote_config")==0) {
} ps->remote_config=atoi(value);
else if (strcmp(name, "server_port")==0){ return 1;
pandorasetup->server_port = atoi(value); }
} else
else if (strcmp(name, "agent_name")==0){ return 0;
free(pandorasetup->agent_name);
asprintf(&pandorasetup->agent_name, value);
}
else if (strcmp(name, "temporal")==0){
free(pandorasetup->temporal);
asprintf(&pandorasetup->temporal, value);
}
else if (strcmp(name, "server_ip")==0){
free(pandorasetup->server_ip);
asprintf(&pandorasetup->server_ip, value);
}
else if (strcmp(name, "logfile")==0){
free(pandorasetup->logfile);
asprintf(&pandorasetup->logfile, value);
}
// (TODO) do here a real config parsing.
// This code is just a concept to read the first module_plugin entry and doesnt support blank spaces
else if (strcmp(name, "module_plugin")==0){
free(pandorasetup->sancho_test);
asprintf(&pandorasetup->sancho_test, value);
}
}
fclose (fp);
return 0;
} }
int
fill_pandora_module (struct pandora_module *pm, char *field, char *value)
{
if (!field)
return 0;
if (!*field)
return 0;
if (strcmp(field, "module_name")==0)
{
pandora_free(pm->module_name);
asprintf(&pm->module_name, value);
return 1;
}
else if (strcmp(field, "module_type")==0)
{
pandora_free(pm->module_type);
asprintf(&pm->module_type, value);
return 1;
}
else if (strcmp(field, "module_description")==0)
{
pandora_free(pm->module_description);
asprintf(&pm->module_description, value);
return 1;
}
else if (strcmp(field, "module_exec")==0)
{
pandora_free(pm->module_exec);
asprintf(&pm->module_exec, value);
return 1;
}
else if (strcmp(field, "module_data")==0)
{
pandora_free(pm->module_data);
asprintf(&pm->module_data, value);
return 1;
}
else if (strcmp(field, "module_plugin")==0)
{
pandora_free(pm->module_plugin);
asprintf(&pm->module_plugin, value);
return 1;
}
else
return 0;
}
int
parse_config (struct pandora_setup *pandorasetup, struct pandora_module **list , char *config_file)
{
char *line=NULL;
char *auxline=NULL;
char buff[MAXLEN];
char *field=NULL;
char *value=NULL;
struct pandora_module *module;
FILE *fileconfig;
//Open .conf file in read-only mode
fileconfig = fopen (config_file, "r");
//If there is an error opening the config file
if (fileconfig == NULL)
{
printf ("Error opening 'pandora_agent.conf'\n");
exit(-1);
}
//Get full line
line = (char*) calloc(MAXLEN, sizeof(char));
if (line == NULL)
{
printf ("Error on calloc'\n");
exit(-1);
}
line = fgets (buff, sizeof(buff), fileconfig);
while (!feof(fileconfig))
{
if (buff[0] != '#' && !isspace(buff[0])) //Skip commented and blank lines
{
asprintf(&auxline, line);
asprintf (&field, strtok (auxline, " \t\r\v\f"));
trim(field);
if (strchr (line, ' ')!=NULL)
{
asprintf(&value, strchr (line, ' '));
trim(value);
}
//START TO GET MODULE LINES
if (strcmp (field, "module_begin")==0)
{
module = (struct pandora_module*) calloc (1, sizeof(struct pandora_module));
if (module == NULL)
{
printf ("Error on calloc'\n");
exit(-1);
}
line = fgets (buff, sizeof(buff), fileconfig); //Get next full line
asprintf(&auxline, line);
asprintf (&field, strtok (auxline, " \t\r\v\f"));
trim(field);
while (strcmp(field, "module_end")!=0)
{
if (strchr (line, ' ')!=NULL)
{
asprintf(&value, strchr (line, ' '));
trim(value);
}
fill_pandora_module (module, field, value);
line = fgets (buff, sizeof(buff), fileconfig);
asprintf(&auxline, line);
asprintf (&field, strtok (auxline, " \t\r\v\f"));
trim(field);
}
//LINKED LIST
if (*list==NULL)
{
*list=module;
module->next=NULL;
}
else
{
struct pandora_module *ptaux=*list;
while (ptaux->next!=NULL)
ptaux=ptaux->next;
ptaux->next=module;
module->next=NULL;
}
} //END OF GETTING MODULE LINES
else if (strcmp(field, "module_plugin")==0)
{
module = (struct pandora_module*) calloc (1, sizeof(struct pandora_module));
if (module == NULL)
{
printf ("Error on calloc'\n");
exit(-1);
}
fill_pandora_module(module, field, value);
//LINKED LIST
if (*list==NULL)
{
*list=module;
module->next=NULL;
}
else
{
struct pandora_module *ptaux=*list;
while (ptaux->next!=NULL)
ptaux=ptaux->next;
ptaux->next=module;
module->next=NULL;
}
}
else
{
fill_pandora_setup(pandorasetup, field, value);
}
}
line = fgets (buff, sizeof(buff), fileconfig);
}
pandora_free(line);
pandora_free(auxline);
pandora_free(field);
pandora_free(value);
//END READING .CONF FILE
fclose(fileconfig);
return 0;
}

View File

@ -15,10 +15,13 @@
void void
init_parameters (struct pandora_setup* pandorasetup); init_parameters (struct pandora_setup* pandorasetup);
char * int
trim (char * s); fill_pandora_setup (struct pandora_setup *ps, char *field, char *value);
int int
parse_config (struct pandora_setup* pandorasetup, char *config_file); fill_pandora_module (struct pandora_module *pm, char *field, char *value);
int
parse_config (struct pandora_setup *pandorasetup, struct pandora_module **list, char *config_file);

View File

@ -30,6 +30,7 @@ struct pandora_module {
char *module_exec; char *module_exec;
char *module_data; char *module_data;
char *module_plugin; char *module_plugin;
struct pandora_module *next;
}; };
struct pandora_setup { struct pandora_setup {

View File

@ -26,7 +26,8 @@
void void
pandora_free (void *pointer){ pandora_free (void *pointer){
if (pointer != NULL){ if (pointer != NULL)
{
free(pointer); free(pointer);
} }
} }
@ -63,31 +64,40 @@ pandora_return_unixtime () {
} }
/* char* rtrim(char* string, char junk)
* trim: get rid of trailing and leading whitespace... {
* ...including the annoying "\n" from fgets() char* original = string + strlen(string);
*/ while(original != string && *--original == junk);
*(original + 1) = '\0';
return string;
}
// (TODO) I think is function is a memory hole (leak), check it out ! 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 * char *
trim (char * s) trim (char * s)
{ {
/* Initialize start, end pointers */ s=rtrim(s, ' ');
char *s1 = s, *s2 = &s[strlen (s) - 1]; s=rtrim(s, '\t');
s=rtrim(s, '\n');
/* Trim and delimit right side */ s=ltrim(s, ' ');
while ( (isspace (*s2)) && (s2 >= s1) ) s=ltrim(s, '\t');
s2--; s=ltrim(s, '\n');
*(s2+1) = '\0';
/* Trim left side */
while ( (isspace (*s1)) && (s1 < s2) )
s1++;
/* Copy finished string */
strcpy (s, s1);
return s;
} }
// ========================================================================== // ==========================================================================
@ -95,16 +105,18 @@ trim (char * s)
char * char *
pandora_exec (char *commandline) { pandora_exec (char *commandline) {
//printf("CommandLine :%s:\n", commandline);
/* Output buffer */ /* Output buffer */
char *data = NULL; char *data = NULL;
int read;
/* File descriptor */ /* File descriptor */
FILE *fc = NULL; FILE *fc = NULL;
int MAXBUF = 8192; // I will only read the first 8192 bytes of output. int MAXBUF = 8192; // I will only read the first 8192 bytes of output.
char buffer[MAXBUF]; char buffer[MAXBUF];
/* Open output of execution as a readonline file handle */ /* Open output of execution as a readonline file handle */
/* if NULL is a problem in the execution or empty exec output */ /* if NULL is a problem in the execution or empty exec output */
@ -122,7 +134,9 @@ pandora_exec (char *commandline) {
data = malloc ((MAXBUF + 1) * sizeof(char)) ; data = malloc ((MAXBUF + 1) * sizeof(char)) ;
fread (data, sizeof(char), MAXBUF, fc); /* Read the entire file, buffers are for weaks :-) */ read = fread (data, sizeof(char), MAXBUF, fc); /* Read the entire file, buffers are for weaks :-) */
data[read]='\0';
pclose (fc); pclose (fc);
@ -137,12 +151,13 @@ pandora_exec (char *commandline) {
void void
tentacle_copy (char *filename, struct pandora_setup *pandorasetup){ tentacle_copy (char *filename, struct pandora_setup *pandorasetup){
char * cmd; char * cmd=NULL;
char * aux=NULL;
asprintf (&cmd, "tentacle_client -a %s -p %d %s", pandorasetup->server_ip, pandorasetup->server_port, filename); asprintf (&cmd, "tentacle_client -a %s -p %d %s", pandorasetup->server_ip, pandorasetup->server_port, filename);
printf ("DEBUG CMD: %s", cmd);
pandora_exec (cmd); aux=pandora_exec (cmd);
pandora_free(aux);
pandora_free (cmd); pandora_free (cmd);
} }
@ -153,23 +168,24 @@ tentacle_copy (char *filename, struct pandora_setup *pandorasetup){
char * char *
pandora_write_xml_header (struct pandora_setup *pandorasetup) { pandora_write_xml_header (struct pandora_setup *pandorasetup) {
char *os_version; char *os_version=NULL;
char *date; char *date=NULL;
char *buffer; char *buffer=NULL;
char *buffer2; char *buffer2=NULL;
char *buffer3; char *buffer3=NULL;
os_version=pandora_exec ("uname -m");
os_version = trim(pandora_exec ("uname -m")); trim(os_version);
if (pandorasetup->autotime == 1)
if (pandorasetup->autotime == 1){ {
asprintf (&date, "AUTO"); asprintf (&date, "AUTO");
} else { }
else
{
date = return_time("%Y/%m/%d %H:%M:%S"); date = return_time("%Y/%m/%d %H:%M:%S");
} }
asprintf (&buffer, "<?xml version='1.0' encoding='ISO-8859-1'?>\n"); 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 (&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); asprintf (&buffer3, "%s%s",buffer, buffer2);
pandora_free (os_version); pandora_free (os_version);
@ -185,7 +201,7 @@ pandora_write_xml_header (struct pandora_setup *pandorasetup) {
char * char *
pandora_write_xml_footer () { pandora_write_xml_footer () {
char *buffer; char *buffer=NULL;
asprintf (&buffer, "</agent_data>\n"); asprintf (&buffer, "</agent_data>\n");
return buffer; return buffer;
} }
@ -193,13 +209,56 @@ pandora_write_xml_footer () {
// ========================================================================== // ==========================================================================
// ========================================================================== // ==========================================================================
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 * char *
pandora_write_xml_disk (struct pandora_setup *pandorasetup){ pandora_write_xml_disk (struct pandora_setup *pandorasetup, struct pandora_module *list){
int fileseed; int fileseed;
char *filename; char *filename=NULL;
char *header; char *header=NULL;
char *footer; char *buffer=NULL;
char *footer=NULL;
FILE *pandora_xml; FILE *pandora_xml;
// Set pseudorandom number // Set pseudorandom number
@ -212,38 +271,43 @@ pandora_write_xml_disk (struct pandora_setup *pandorasetup){
if (pandorasetup->debug == 1){ if (pandorasetup->debug == 1){
printf ("[DEBUG] XML Filename is %s \n", filename); printf ("[DEBUG] XML Filename is %s \n", filename);
} }
pandora_xml = fopen (filename, "w"); pandora_xml = fopen (filename, "w");
if (pandora_xml == NULL){ if (pandora_xml == NULL){
printf ("ERROR: Cannot open xmlile at %s for writing. ABORTING\n", filename); printf ("ERROR: Cannot open xmlfile at %s for writing. ABORTING\n", filename);
exit (-1); exit (-1);
} }
header = pandora_write_xml_header (pandorasetup); header = pandora_write_xml_header (pandorasetup);
fprintf (pandora_xml, header); fprintf (pandora_xml, "%s", header);
struct pandora_module *ptaux=list;
// (TODO): Write here each module output while (ptaux!=NULL)
{
// This is a just a concept to execute and put the results of a single plugin execution if (ptaux->module_type!=NULL)
{
char *sancho_test_buffer; buffer = pandora_write_xml_module(ptaux);
sancho_test_buffer = pandora_exec (pandorasetup->sancho_test); fprintf(pandora_xml, "%s", buffer);
fprintf (pandora_xml, sancho_test_buffer); }
pandora_free (sancho_test_buffer); else if (ptaux->module_plugin!=NULL)
{
// End of crap code :-) buffer = pandora_write_xml_module_plugin(ptaux);
fprintf(pandora_xml, "%s", buffer);
}
ptaux=ptaux->next;
pandora_free(buffer);
}
footer = pandora_write_xml_footer (); footer = pandora_write_xml_footer ();
fprintf (pandora_xml, footer); fprintf (pandora_xml, "%s", footer);
fclose (pandora_xml); fclose (pandora_xml);
pandora_free (header); pandora_free (header);
pandora_free (footer); pandora_free (footer);
return (filename); return filename;
} }
@ -302,7 +366,7 @@ pandora_log (int level, char *message, struct pandora_setup *pandorasetup ){
exit(-1); exit(-1);
} }
fprintf (pandora_log, buff_timedate2); fprintf (pandora_log, "%s", buff_timedate2);
// Free mem // Free mem

View File

@ -18,6 +18,15 @@ pandora_log (int level, char *message, struct pandora_setup *pandorasetup );
void void
pandora_free (void *pointer); pandora_free (void *pointer);
char *
rtrim(char* string, char junk);
char *
ltrim(char *string, char junk);
char *
trim (char * s);
int int
isdatafile (char *filename); isdatafile (char *filename);