int similar(char p[], char q[], short condition) { TREEPTR node1, node2; double p_mean, q_mean, p_deviation, q_deviation, difference; node1=get_leaf(p); node2=get_leaf(q); p_mean = node1->mean; q_mean = node2->mean; p_deviation = get_deviation(node1->mean,node1->sqr_mean); q_deviation = get_deviation(node2->mean,node2->sqr_mean); /* This is to avoid very little regions not to get merged because */ /* a null standar daviation */ if (p_deviation==0) p_deviation=0.5; if (q_deviation==0) q_deviation=0.5; difference = p_mean-q_mean; return ( (abs(difference)<=condition*p_deviation) || (abs(difference)<=condition*q_deviation) ); }
TREEPTR split(short deviation, short x, short y, short level) { short i, j, height, width, intensity; long size; double mean, sqr_mean; float dev, dev1, variance; XPoint region_points[4]; TREEPTR new_node; /* Allocate memory for the new defined region */ new_node = (TREEPTR)malloc(sizeof(TREE)); new_node->region = NULL; new_node->subreg0 = NULL; new_node->subreg1 = NULL; new_node->subreg2 = NULL; new_node->subreg3 = NULL; new_node->pmerge = NULL; new_node->included = no; new_node->mean=0; new_node->sqr_mean=0; new_node->level=level; /* Get the size of the region according to the level */ height = IMAGE_HEIGHT/pow(2,level); width = IMAGE_WIDTH /pow(2,level); size = height*width; /* Initialize some variables */ mean=0; sqr_mean=0; /*Compute the mean and the mean of the squared pixels intensity*/ for (i=x; i<x+width; i++) for (j=y; j<y+height; j++) { intensity=XGetPixel(theXImage_1,i,j); XPutPixel(theXImage_2,i,j,intensity); mean=mean+intensity; sqr_mean=sqr_mean+pow(intensity,2); }; mean = mean/size; sqr_mean = sqr_mean/size; /*Store the mean and sqr_mean values*/ new_node->mean = mean; new_node->sqr_mean = sqr_mean; /*Compute standard deviation of the region*/ dev = get_deviation(mean,sqr_mean); /*Recursive splitting process*/ if (dev>deviation) { /*The condition is not satisfied so split region*/ num_split++; new_node->subreg0 = split(deviation,x,y,level+1); new_node->subreg1 = split(deviation,x+(width/2),y,level+1); new_node->subreg2 = split(deviation,x,y+(height/2),level+1); new_node->subreg3 = split(deviation,x+(width/2),y+(height/2),level+1); } else { /*Condition satisfied. Insert region in the quadtree structure*/ num_reg++; region_points[0].x=x; region_points[0].y=y; region_points[1].x=x; region_points[1].y=y+height; region_points[2].x=x+width; region_points[2].y=y+height; region_points[3].x=x+width; region_points[3].y=y; new_node->region = XPolygonRegion (region_points, 4, WindingRule); } return (new_node); }
int main(int argc, char *argv[]) { FILE *command = NULL; char *command_line = NULL; char *line = NULL; char *line_bkp = NULL; char *baseline_perfdata = NULL; char *baseline_perfdata_aux = NULL; char *ini_path; char *aux = NULL; struct metric_t *mt; struct metric_t *aux_mt; struct metric_t *metrics_root; struct deviation_t *deviation; int exit_code = OK; int ret = 0; int min_entries = 0; int collected_entries = 0; int allow_negatives = TRUE; float tolerance = 0; unsigned int name_last_pos = 0; dictionary *ini; extern char **environ; if (argc <= 1) { printf("Invalid check command supplied\n"); return UNKNOWN; } // search for hostname and servicedescription macros line = *(environ + ret++); while(line) { aux = strtok(line,"="); if (!strcmp(aux,"NAGIOS_HOSTNAME")) { host_name = strtok(NULL,"="); } else if (!strcmp(aux,"NAGIOS_SERVICEDESC")) { service_description = strtok(NULL,"="); } ret++; line = *(environ + ret); } line = NULL; if (!host_name || !service_description) { printf("Unable to locate NAGIOS_HOSTNAME and NAGIOS_SERVICEDESC macros\n"); return UNKNOWN; } asprintf(&ini_path,"%s/baseline.ini",INSTALLPATH); ini = iniparser_load(ini_path); if (ini == NULL) { printf("Unable to process %s file\n",ini_path); return UNKNOWN; } // i personally dont like to use 'extern' variables // with this approach we can easily provide more backends support aux = iniparser_getstring(ini, "database:host", NULL); ret = (aux) ? db_set_dbserver(aux) : db_set_dbserver("localhost"); if (ret != OK) goto memory_allocation_error; aux = iniparser_getstring(ini, "database:user", NULL); ret = (aux) ? db_set_dbuser(aux) : db_set_dbuser("root"); if (ret != OK) goto memory_allocation_error; aux = iniparser_getstring(ini, "database:password", NULL); ret = (aux) ? db_set_dbpassword(aux) : db_set_dbpassword(""); if (ret != OK) goto memory_allocation_error; aux = iniparser_getstring(ini, "general:baselinealgorithm", "standard_deviation"); baseline_algorithm = STANDARDDEVIATION; if (strstr(aux,"exponential_smoothing")) baseline_algorithm = EXPONENTIALSMOOTH; aux = iniparser_getstring(ini, "database:dbname", NULL); ret = (aux) ? db_set_dbname(aux) : db_set_dbname("nada"); if (ret != OK) goto memory_allocation_error; db_set_max_entries( iniparser_getint(ini, "general:maxentries", MAXENTRIESTODEVIATION) ); db_set_sazonality( iniparser_getint(ini, "general:sazonality", SAZONALITY) ); min_entries = iniparser_getint(ini, "general:minentries", MINENTRIESTODEVIATION); allow_negatives = iniparser_getboolean(ini, "general:allownegatives", TRUE); tolerance = (float)iniparser_getint(ini, "general:tolerance", DEVIATIONTOLERANCE) / 100 + 1; // we no longer need dictionary iniparser_freedict(ini); free(ini_path); command_line = read_command_line(argc,argv); if (command_line == NULL) { printf("Error getting command line\n"); return UNKNOWN; } command = popen(command_line,"r"); if (!command) { printf("Unable to run supplied command\n"); free(command_line); return UNKNOWN; } line = malloc(MAXPLUGINOUTPUT + 1); if (line == NULL) { free(command_line); pclose(command); goto memory_allocation_error; } if (fgets(line, MAXPLUGINOUTPUT,command) == NULL) { printf("Unable to read plugin output\n"); free(command_line); pclose(command); free(line); return UNKNOWN; } if (strstr(line,"|") == NULL) { printf("%s",line); free(command_line); pclose(command); free(line); return OK; } // plugin output returned value becames // our default output return code exit_code = WEXITSTATUS(pclose(command)); if ((line_bkp = malloc(strlen(line) + 1)) == NULL) { free(command_line); free(line); goto memory_allocation_error; } strcpy(line_bkp,line); line[strlen(line) - 1] = '\x0'; strtok(line_bkp,"|"); metrics_root = parse_perfdata(strtok(NULL,"|")); if (metrics_root == NULL) { printf("Error parsing metric data - %s\n",line); free(command_line); free(line_bkp); return UNKNOWN; } ret = db_open_conn(); if (ret != OK) { printf("Unable to connect to database\n"); free(command_line); free(line); free(line_bkp); return UNKNOWN; } if ((baseline_perfdata = malloc(1)) == NULL) { free(command_line); free(line); free(line_bkp); goto memory_allocation_error; } *baseline_perfdata = '\x0'; for(mt=metrics_root; mt != NULL; mt=mt->next) { deviation = get_deviation( command_line, mt, &collected_entries, tolerance, allow_negatives ); if (collected_entries > min_entries) { // baseline has been broken if (mt->value < deviation->bottom || mt->value > deviation->top) { // change return code exit_code = CRITICAL; } } /* XXX * this certainly is not the more * appropriate way to do it */ name_last_pos = strlen(mt->name) - 1; if (mt->name[name_last_pos] == '\'') { mt->name[name_last_pos] = '\x0'; asprintf( &baseline_perfdata_aux," %s_top'=%.3f%s;;;; %s_bottom'=%.3f%s;;;; ", mt->name, deviation->top, mt->unit, mt->name, deviation->bottom, mt->unit ); } else if (mt->name[name_last_pos] == '"') { mt->name[name_last_pos] = '\x0'; asprintf( &baseline_perfdata_aux," %s_top\"=%.3f%s;;;; %s_bottom\"=%.3f%s;;;; ", mt->name, deviation->top, mt->unit, mt->name, deviation->bottom, mt->unit ); } else { asprintf( &baseline_perfdata_aux," %s_top=%.3f%s;;;; %s_bottom=%.3f%s;;;; ", mt->name, deviation->top, mt->unit, mt->name, deviation->bottom, mt->unit ); } baseline_perfdata = realloc(baseline_perfdata, strlen(baseline_perfdata) + strlen(baseline_perfdata_aux) + 1); strcat(baseline_perfdata,baseline_perfdata_aux); free(baseline_perfdata_aux); free(deviation); } printf( "%s %s\n", line, baseline_perfdata); mt = metrics_root; while(mt) { aux_mt = mt->next; free(mt->name); free(mt->unit); free(mt); mt = aux_mt; } free(command_line); free(line); free(line_bkp); free(baseline_perfdata); db_close_conn(); return exit_code; memory_allocation_error: fprintf(stderr,"Memory allocation error\n"); return CRITICAL; }