// Pandora FMS Embedded Agent // (c) Pandora FMS 2011-2023 // (c) Sancho Lerena // 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 #include #include #include #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, "\n"); asprintf (&buffer2, "\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, "\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\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, 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; }