diff -ruBbd cacti-spine-0.8.7g.old/ChangeLog cacti-spine-0.8.7g/ChangeLog --- cacti-spine-0.8.7g.old/ChangeLog 2010-07-09 19:25:56.000000000 -0400 +++ cacti-spine-0.8.7g/ChangeLog 2010-08-31 20:21:22.000000000 -0400 @@ -1,5 +1,13 @@ The Cacti Group | spine +Patched 0.8.7g +-bug#0001669: Problems with getting data from script using SPINE on Windows Server 2003 x32 +-bug#0001829: Wrong string numerical value got from Spine SNMP poller +-bug: Net-snmp API issues cause spine crashes with some SNMP agents +-bug: Host list not properly initialized +-bug: Mutex locking issues cause deadlocks in Windows +-bug: Escape windows type back slashes in scripts + 0.8.7g -feature: Multi threaded host polling diff -ruBbd cacti-spine-0.8.7g.old/poller.c cacti-spine-0.8.7g/poller.c --- cacti-spine-0.8.7g.old/poller.c 2010-07-09 17:39:53.000000000 -0400 +++ cacti-spine-0.8.7g/poller.c 2010-08-31 20:18:58.000000000 -0400 @@ -57,21 +57,26 @@ host_data_ids = poller_details.host_data_ids; snprintf(host_time, SMALL_BUFSIZE, "%s", poller_details.host_time); - thread_mutex_unlock(LOCK_THREAD); - free(arg); + thread_ready = TRUE; + SPINE_LOG_DEBUG(("DEBUG: In Poller, About to Start Polling of Host")); poll_host(host_id, host_thread, last_host_thread, host_data_ids, host_time); - thread_mutex_lock(LOCK_THREAD); - + while (TRUE) { + if (thread_mutex_trylock(LOCK_THREAD) == 0) { active_threads--; + thread_mutex_unlock(LOCK_THREAD); - SPINE_LOG_DEBUG(("DEBUG: The Value of Active Threads is %i" ,active_threads)); + break; + } - thread_mutex_unlock(LOCK_THREAD); + usleep(100); + } + + SPINE_LOG_DEBUG(("DEBUG: The Value of Active Threads is %i" ,active_threads)); /* end the thread */ pthread_exit(0); @@ -965,7 +970,7 @@ poll_result = exec_poll(host, poller_items[i].arg1); /* process the result */ - if ((is_numeric(poll_result)) || (is_multipart_output(poll_result))) { + if ((is_numeric(poll_result)) || (is_multipart_output(trim(poll_result)))) { snprintf(poller_items[i].result, RESULTS_BUFFER, "%s", poll_result); }else if (is_hexadecimal(snmp_oids[j].result, TRUE)) { snprintf(poller_items[i].result, RESULTS_BUFFER, "%lld", hex2dec(poll_result)); @@ -998,7 +1003,7 @@ poll_result = php_cmd(poller_items[i].arg1, php_process); /* process the output */ - if ((is_numeric(poll_result)) || (is_multipart_output(poll_result))) { + if ((is_numeric(poll_result)) || (is_multipart_output(trim(poll_result)))) { snprintf(poller_items[i].result, RESULTS_BUFFER, "%s", poll_result); }else if (is_hexadecimal(snmp_oids[j].result, TRUE)) { snprintf(poller_items[i].result, RESULTS_BUFFER, "%lld", hex2dec(poll_result)); @@ -1247,7 +1252,7 @@ if (is_numeric(result)) { return TRUE; }else{ - if (is_multipart_output(result)) { + if (is_multipart_output(trim(result))) { return TRUE; }else{ return FALSE; @@ -1290,7 +1295,7 @@ /* compensate for back slashes in arguments */ #if defined(__CYGWIN__) - proc_command = add_slashes(command, 2); + proc_command = add_slashes(command); #else proc_command = command; #endif @@ -1340,7 +1345,7 @@ FD_SET(cmd_fd, &fds); /* wait x seonds for pipe response */ - switch (select(cmd_fd+1, &fds, NULL, NULL, &timeout)) { + switch (select(FD_SETSIZE, &fds, NULL, NULL, &timeout)) { case -1: switch (errno) { case EBADF: @@ -1381,11 +1386,13 @@ break; } case 0: + #ifdef USING_TPOPEN SPINE_LOG(("Host[%i] ERROR: The POPEN timed out", current_host->id)); - #ifdef USING_TPOPEN close_fd = FALSE; #else + SPINE_LOG(("Host[%i] ERROR: The NIFTY POPEN timed out", current_host->id)); + pid = nft_pchild(cmd_fd); kill(pid, SIGKILL); #endif diff -ruBbd cacti-spine-0.8.7g.old/snmp.c cacti-spine-0.8.7g/snmp.c --- cacti-spine-0.8.7g.old/snmp.c 2010-07-09 17:39:53.000000000 -0400 +++ cacti-spine-0.8.7g/snmp.c 2010-08-31 20:18:58.000000000 -0400 @@ -499,13 +499,9 @@ size_t out_len = 0; if ((buf = (u_char *) calloc(buf_len, 1)) != 0) { - if (sprint_realloc_value(&buf, &buf_len, &out_len, 1, - objid, objidlen, variable)) { + sprint_realloc_by_type(&buf, &buf_len, &out_len, 1, variable, NULL, NULL, NULL); snprintf(obuf, buf_len, "%s", buf); }else{ - snprintf(obuf, buf_len, "%s [TRUNCATED]", buf); - } - }else{ SET_UNDEFINED(obuf); } @@ -528,6 +524,7 @@ int i; int array_count; int index_count; + char temp_result[RESULTS_BUFFER]; struct nameStruct { oid name[MAX_OID_LEN]; @@ -570,11 +567,13 @@ for(i = 0; i < num_oids && vars; i++) { if (!IS_UNDEFINED(snmp_oids[i].result)) { #ifdef USE_NET_SNMP - snmp_snprint_value(snmp_oids[i].result, RESULTS_BUFFER, vars->name, vars->name_length, vars); + snmp_snprint_value(temp_result, RESULTS_BUFFER, vars->name, vars->name_length, vars); #else - sprint_value(snmp_oids[i].result, vars->name, vars->name_length, vars); + sprint_value(temp_result, vars->name, vars->name_length, vars); #endif + snprintf(snmp_oids[i].result, RESULTS_BUFFER, "%s", trim(temp_result)); + vars = vars->next_variable; } } diff -ruBbd cacti-spine-0.8.7g.old/spine.c cacti-spine-0.8.7g/spine.c --- cacti-spine-0.8.7g.old/spine.c 2010-07-09 17:39:53.000000000 -0400 +++ cacti-spine-0.8.7g/spine.c 2010-08-31 20:18:58.000000000 -0400 @@ -94,6 +94,7 @@ int num_hosts = 0; int active_threads = 0; int active_scripts = 0; +int thread_ready = FALSE; config_t set; php_t *php_processes = 0; @@ -134,7 +135,7 @@ int poller_counter = 0; int last_active_threads = 0; int valid_conf_file = FALSE; - long int EXTERNAL_THREAD_SLEEP = 5000; + long int EXTERNAL_THREAD_SLEEP = 50; long int internal_thread_sleep; char querybuf[BIG_BUFSIZE], *qp = querybuf; char *host_time = NULL; @@ -196,6 +197,7 @@ /* we attempt to support scripts better in cygwin */ #if defined(__CYGWIN__) + setenv("CYGWIN", "nodosfilewarning", 1); if (file_exists("./sh.exe")) { set.cygwinshloc = 0; printf("NOTE: The Shell Command Exists in the current directory\n"); @@ -281,7 +283,7 @@ else if (STRMATCH(arg, "-H") || STRIMATCH(arg, "--hostlist")) { - snprintf(set.host_id_list, BIG_BUFSIZE, getarg(opt, &argv)); + snprintf(set.host_id_list, BIG_BUFSIZE, "%s", getarg(opt, &argv)); } else if (STRMATCH(arg, "-h") || @@ -584,6 +586,11 @@ poller_details->host_data_ids = itemsPT; poller_details->host_time = host_time; + /* this variable tells us that the child had loaded the poller + * poller_details structure and we can move on to the next thread + */ + thread_ready = FALSE; + /* create child process */ thread_status = pthread_create(&threads[device_counter], &attr, child, poller_details); @@ -596,6 +603,11 @@ } active_threads++; + /* wait for the child to read and process the structure */ + while (!thread_ready) { + usleep(internal_thread_sleep); + } + SPINE_LOG_DEBUG(("DEBUG: The Value of Active Threads is %i", active_threads)); break; @@ -603,7 +615,7 @@ SPINE_LOG(("ERROR: The System Lacked the Resources to Create a Thread")); break; case EFAULT: - SPINE_LOG(("ERROR: The Thread or Attribute Was Invalid")); + SPINE_LOG(("ERROR: The Thread or Attribute were Invalid")); break; case EINVAL: SPINE_LOG(("ERROR: The Thread Attribute is Not Initialized")); @@ -613,6 +625,8 @@ break; } + thread_mutex_unlock(LOCK_THREAD); + /* get current time and exit program if time limit exceeded */ if (poller_counter >= 20) { current_time = get_time_as_double(); diff -ruBbd cacti-spine-0.8.7g.old/spine.h cacti-spine-0.8.7g/spine.h --- cacti-spine-0.8.7g.old/spine.h 2010-07-09 17:39:53.000000000 -0400 +++ cacti-spine-0.8.7g/spine.h 2010-08-31 20:18:58.000000000 -0400 @@ -504,5 +504,6 @@ extern char start_datetime[20]; extern char config_paths[CONFIG_PATHS][BUFSIZE]; extern int active_threads; +extern int thread_ready; #endif /* not _SPINE_H_ */ diff -ruBbd cacti-spine-0.8.7g.old/util.c cacti-spine-0.8.7g/util.c --- cacti-spine-0.8.7g.old/util.c 2010-07-09 17:39:53.000000000 -0400 +++ cacti-spine-0.8.7g/util.c 2010-08-31 20:18:58.000000000 -0400 @@ -755,7 +755,7 @@ /* empty string is not all digits */ if ( *string == '\0' ) return FALSE; - while ( isdigit(*string) ) + while ( isdigit((int)*string) ) string++; return *string == '\0'; @@ -773,7 +773,7 @@ */ int is_ipaddress(const char *string) { while (*string) { - if ((isdigit(*string)) || + if ((isdigit((int)*string)) || (*string == '.') || (*string == ':')) { string++; @@ -887,7 +887,7 @@ i = strlen(string); while (i >= 0) { - if (isdigit(string[i])) { + if (isdigit((int)string[i])) { break; }else{ string[i] = '\0'; @@ -898,17 +898,15 @@ return string; } -/*! \fn char *add_slashes(char *string, int arguments_2_strip) - * \brief change all backslashes to forward slashes for the first n arguements. +/*! \fn char *add_slashes(char *string) + * \brief add escaping to back slashes on for Windows type commands. * \param string the string to replace slashes - * \param arguments_2_strip the number of space delimited arguments to reverse * * \return a pointer to the modified string. Variable must be freed by parent. * */ -char *add_slashes(char *string, int arguments_2_strip) { +char *add_slashes(char *string) { int length; - int space_count; int position; int new_position; char *return_str; @@ -919,9 +917,8 @@ return_str[0] = '\0'; length = strlen(string); - space_count = 0; position = 0; - new_position = position; + new_position = 0; /* simply return on blank string */ if (!length) { @@ -931,17 +928,9 @@ while (position < length) { /* backslash detected, change to forward slash */ if (string[position] == '\\') { - /* only add slashes for first x arguments */ - if (space_count < arguments_2_strip) { - return_str[new_position] = '/'; - }else{ - return_str[new_position] = string[position]; - } - /* end of argument detected */ - }else if (string[position] == ' ') { - return_str[new_position] = ' '; - space_count++; - /* normal character detected */ + return_str[new_position] = '\\'; + new_position++; + return_str[new_position] = '\\'; }else{ return_str[new_position] = string[position]; } @@ -1248,7 +1237,7 @@ seteuid(0); if (geteuid() != 0) { - SPINE_LOG_DEBUG(("WARNING: Spine NOT running asroot. This is require if using ICMP. Please run \"chmod +s;chown root:root spine\" to resolve.")); + SPINE_LOG_DEBUG(("WARNING: Spine NOT running asroot. This is required if using ICMP. Please run \"chmod +s;chown root:root spine\" to resolve.")); set.icmp_avail = FALSE; }else{ SPINE_LOG_DEBUG(("DEBUG: Spine is running asroot.")); diff -ruBbd cacti-spine-0.8.7g.old/util.h cacti-spine-0.8.7g/util.h --- cacti-spine-0.8.7g.old/util.h 2010-07-09 17:39:53.000000000 -0400 +++ cacti-spine-0.8.7g/util.h 2010-08-31 20:18:58.000000000 -0400 @@ -54,7 +54,7 @@ extern int is_hexadecimal(const char * str, const short ignore_space); /* string and file functions */ -extern char *add_slashes(char *string, int arguments_2_strip); +extern char *add_slashes(char *string); extern int file_exists(const char *filename); extern char *strip_alpha(char *string); extern char *strncopy(char *dst, const char *src, size_t n);