diff --git a/pandora_agents/embedded/ChangeLog b/pandora_agents/embedded/ChangeLog index 4b3dac33e2..83a14b10f9 100644 --- a/pandora_agents/embedded/ChangeLog +++ b/pandora_agents/embedded/ChangeLog @@ -1,3 +1,12 @@ +2011-02-03 Javier Lanz + * 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 * pandora_agent.c: Uses pandora_types.h instead module_types.h diff --git a/pandora_agents/embedded/pandora_agent.c b/pandora_agents/embedded/pandora_agent.c index ab7d32f464..ffc51772e8 100755 --- a/pandora_agents/embedded/pandora_agent.c +++ b/pandora_agents/embedded/pandora_agent.c @@ -32,27 +32,29 @@ int main(int argc, char **argv) { - DIR *pDIR; - struct dirent *pDirEnt; - struct pandora_setup *pandorasetup; - char *config_file; - char *fullpath; - char *buffer; - long int id_audit; - char c; - char *xml_filename; + DIR *pDIR=NULL; + struct dirent *pDirEnt=NULL; + struct pandora_setup *pandorasetup=NULL; + struct pandora_module *list=NULL; + char *config_file=NULL; + char *fullpath=NULL; + char *buffer=NULL; + long int id_audit; + char c; + char *xml_filename=NULL; printf ("Pandora FMS Embedded Agent v%s (c) 2011 http://pandorafms.org\n", VERSION); config_file = NULL; - - if (argc < 2 && argc > 3){ + list=NULL; + + if (argc < 2 || argc > 3){ printf ("Syntax is:\n\n pandora_agent \n\n"); exit (0); } - char *cmd = *argv++; + char *cmd = *argv++; config_file = *argv++; if (config_file == NULL) { @@ -61,12 +63,17 @@ main(int argc, char **argv) { } 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 init_parameters (pandorasetup); // 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); pandora_log (3, buffer, pandorasetup); @@ -86,7 +93,7 @@ main(int argc, char **argv) { while (1){ // Main loop - xml_filename = pandora_write_xml_disk (pandorasetup); + xml_filename = pandora_write_xml_disk (pandorasetup, list); if (pandorasetup->debug == 1){ printf ("Debug mode activated. Exiting now! \n"); exit (0); @@ -101,7 +108,5 @@ main(int argc, char **argv) { pandora_free(xml_filename); sleep(pandorasetup->interval); } - - pandora_free(config_file); return (0); } diff --git a/pandora_agents/embedded/pandora_agent.conf b/pandora_agents/embedded/pandora_agent.conf index 0c9d178307..c7fe355aac 100644 --- a/pandora_agents/embedded/pandora_agent.conf +++ b/pandora_agents/embedded/pandora_agent.conf @@ -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 diff --git a/pandora_agents/embedded/pandora_config.c b/pandora_agents/embedded/pandora_config.c index 9fce3620e4..b8b9d01e9d 100644 --- a/pandora_agents/embedded/pandora_config.c +++ b/pandora_agents/embedded/pandora_config.c @@ -40,88 +40,229 @@ init_parameters (struct pandora_setup* pandorasetup) pandorasetup->verbosity=5; } - - 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]; - - FILE *fp = fopen (config_file, "r"); - if (fp == NULL){ - return -1; - } - /* Read next line */ - while ((s = fgets (buff, sizeof buff, fp) )){ - /* Skip blank lines and comments */ - if (buff[0] == '\n' || buff[0] == '#') - continue; - - /* Parse name/value pair from line */ - char name[MAXLEN], value[MAXLEN]; - s = strtok (buff, " "); - - if (s==NULL){ - continue; - } else { - strncpy (name, s, MAXLEN); - } - trim (name); // Purge blank spaces - s = strtok (NULL, "="); - - if (s==NULL) { - continue; - } else { - strncpy (value, s, MAXLEN); - } - trim (value); // Purge blank spaces - - /* Copy into correct entry in parameters struct */ - if (strcmp(name, "verbosity")==0){ - pandorasetup->verbosity = atoi(value); - } - else if (strcmp(name, "debug")==0){ - pandorasetup->debug = atoi(value); - } - else if (strcmp(name, "interval")==0){ - pandorasetup->interval = atoi(value); - } - else if (strcmp(name, "autotime")==0){ - pandorasetup->autotime = atoi(value); - } - else if (strcmp(name, "remote_config")==0){ - pandorasetup->remote_config = atoi(value); - } - else if (strcmp(name, "server_port")==0){ - pandorasetup->server_port = atoi(value); - } - else if (strcmp(name, "agent_name")==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; + if (!field) + return 0; + if (!*field) + return 0; + + if (strcmp(field, "logfile")==0) { + pandora_free(ps->logfile); + asprintf(&ps->logfile, value); + return 1; + } + else if (strcmp(field, "debug")==0) { + ps->debug=atoi(value); + return 1; + } + else if (strcmp(field, "interval")==0) { + ps->interval=atoi(value); + return 1; + } + else if (strcmp(field, "autotime")==0) { + ps->autotime=atoi(value); + return 1; + } + else if (strcmp(field, "verbosity")==0) { + ps->verbosity=atoi(value); + return 1; + } + else if (strcmp(field, "agent_name")==0) { + pandora_free(ps->agent_name); + asprintf(&ps->agent_name, value); + return 1; + } + else if (strcmp(field, "server_ip")==0) { + pandora_free(ps->server_ip); + asprintf(&ps->server_ip, value); + return 1; + } + else if (strcmp(field, "temporal")==0) { + pandora_free(ps->temporal); + asprintf(&ps->temporal, value); + return 1; + } + else if (strcmp(field, "server_port")==0) { + ps->server_port=atoi(value); + return 1; + } + else if (strcmp(field, "remote_config")==0) { + ps->remote_config=atoi(value); + return 1; + } + else + 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; +} diff --git a/pandora_agents/embedded/pandora_config.h b/pandora_agents/embedded/pandora_config.h index 82fdf06ff6..661f399bde 100644 --- a/pandora_agents/embedded/pandora_config.h +++ b/pandora_agents/embedded/pandora_config.h @@ -15,10 +15,13 @@ void init_parameters (struct pandora_setup* pandorasetup); -char * -trim (char * s); +int +fill_pandora_setup (struct pandora_setup *ps, char *field, char *value); 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); diff --git a/pandora_agents/embedded/pandora_type.h b/pandora_agents/embedded/pandora_type.h index 16a77d85e7..f74fc30765 100644 --- a/pandora_agents/embedded/pandora_type.h +++ b/pandora_agents/embedded/pandora_type.h @@ -30,6 +30,7 @@ struct pandora_module { char *module_exec; char *module_data; char *module_plugin; + struct pandora_module *next; }; struct pandora_setup { diff --git a/pandora_agents/embedded/pandora_util.c b/pandora_agents/embedded/pandora_util.c index 12ead1dc58..bf5645b815 100644 --- a/pandora_agents/embedded/pandora_util.c +++ b/pandora_agents/embedded/pandora_util.c @@ -26,7 +26,8 @@ void pandora_free (void *pointer){ - if (pointer != NULL){ + if (pointer != NULL) + { free(pointer); } } @@ -63,31 +64,40 @@ pandora_return_unixtime () { } -/* - * trim: get rid of trailing and leading whitespace... - * ...including the annoying "\n" from fgets() - */ +char* rtrim(char* string, char junk) +{ + 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 * trim (char * s) { - /* Initialize start, end pointers */ - char *s1 = s, *s2 = &s[strlen (s) - 1]; - - /* Trim and delimit right side */ - while ( (isspace (*s2)) && (s2 >= s1) ) - s2--; - *(s2+1) = '\0'; - - /* Trim left side */ - while ( (isspace (*s1)) && (s1 < s2) ) - s1++; - - /* Copy finished string */ - strcpy (s, s1); - return s; + s=rtrim(s, ' '); + s=rtrim(s, '\t'); + s=rtrim(s, '\n'); + s=ltrim(s, ' '); + s=ltrim(s, '\t'); + s=ltrim(s, '\n'); } // ========================================================================== @@ -95,16 +105,18 @@ trim (char * s) 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]; + char buffer[MAXBUF]; /* Open output of execution as a readonline file handle */ /* 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)) ; - 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); @@ -137,12 +151,13 @@ pandora_exec (char *commandline) { void 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); - printf ("DEBUG CMD: %s", cmd); - pandora_exec (cmd); + aux=pandora_exec (cmd); + pandora_free(aux); pandora_free (cmd); } @@ -153,23 +168,24 @@ tentacle_copy (char *filename, struct pandora_setup *pandorasetup){ char * pandora_write_xml_header (struct pandora_setup *pandorasetup) { - char *os_version; - char *date; - char *buffer; - char *buffer2; - char *buffer3; - - os_version = trim(pandora_exec ("uname -m")); - - if (pandorasetup->autotime == 1){ + 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 { + } + else + { date = return_time("%Y/%m/%d %H:%M:%S"); } - - + asprintf (&buffer, "\n"); - asprintf (&buffer2, "\n", os_version, pandorasetup->interval, date, pandorasetup->agent_name); + asprintf (&buffer2, "\n", os_version, pandorasetup->interval, date, pandorasetup->agent_name); asprintf (&buffer3, "%s%s",buffer, buffer2); pandora_free (os_version); @@ -185,7 +201,7 @@ pandora_write_xml_header (struct pandora_setup *pandorasetup) { char * pandora_write_xml_footer () { - char *buffer; + char *buffer=NULL; asprintf (&buffer, "\n"); 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\n\t\n\t\n\t%s\n\t\n\t\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){ +pandora_write_xml_disk (struct pandora_setup *pandorasetup, struct pandora_module *list){ int fileseed; - char *filename; - char *header; - char *footer; + char *filename=NULL; + char *header=NULL; + char *buffer=NULL; + char *footer=NULL; FILE *pandora_xml; // Set pseudorandom number @@ -212,38 +271,43 @@ pandora_write_xml_disk (struct pandora_setup *pandorasetup){ 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 xmlile at %s for writing. ABORTING\n", filename); + printf ("ERROR: Cannot open xmlfile at %s for writing. ABORTING\n", filename); exit (-1); } - + header = pandora_write_xml_header (pandorasetup); - - fprintf (pandora_xml, header); - - // (TODO): Write here each module output - - // This is a just a concept to execute and put the results of a single plugin execution - - char *sancho_test_buffer; - sancho_test_buffer = pandora_exec (pandorasetup->sancho_test); - fprintf (pandora_xml, sancho_test_buffer); - pandora_free (sancho_test_buffer); - - // End of crap code :-) + + 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, footer); + fprintf (pandora_xml, "%s", footer); fclose (pandora_xml); pandora_free (header); pandora_free (footer); - return (filename); + return filename; } @@ -302,7 +366,7 @@ pandora_log (int level, char *message, struct pandora_setup *pandorasetup ){ exit(-1); } - fprintf (pandora_log, buff_timedate2); + fprintf (pandora_log, "%s", buff_timedate2); // Free mem diff --git a/pandora_agents/embedded/pandora_util.h b/pandora_agents/embedded/pandora_util.h index 94a4c2f609..94633d0235 100644 --- a/pandora_agents/embedded/pandora_util.h +++ b/pandora_agents/embedded/pandora_util.h @@ -18,6 +18,15 @@ pandora_log (int level, char *message, struct pandora_setup *pandorasetup ); void pandora_free (void *pointer); +char * +rtrim(char* string, char junk); + +char * +ltrim(char *string, char junk); + +char * +trim (char * s); + int isdatafile (char *filename);