Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package cacti-spine for openSUSE:Factory checked in at 2023-09-06 18:59:28 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/cacti-spine (Old) and /work/SRC/openSUSE:Factory/.cacti-spine.new.1766 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "cacti-spine" Wed Sep 6 18:59:28 2023 rev:40 rq:1109186 version:1.2.25 Changes: -------- --- /work/SRC/openSUSE:Factory/cacti-spine/cacti-spine.changes 2023-02-28 12:49:24.984765362 +0100 +++ /work/SRC/openSUSE:Factory/.cacti-spine.new.1766/cacti-spine.changes 2023-09-06 19:03:44.179414603 +0200 @@ -1,0 +2,22 @@ +Wed Sep 6 05:57:17 UTC 2023 - Andreas Stieger <andreas.stie...@gmx.de> + +- cacti-spine 1.2.25: + * Spine should see if script to be executed is executable + * Enhance number recognition + * When polling devices, sort by larger number of items first + * Log format may be corrupted when timeout occurs + * Compile warning appears due to GCC flag on RHEL7/RHEL8 + * Downed device detection only checks one of the two uptime OIDs + * Compile error appears due to execinfo.h on FreeBSD + * Bootstrap shell script contains some PHP cruft + * Padding is not always removed from the start of non-numeric + strings + * Improve SNMP result handling for non-numeric results + * Further improve SNMP result handling for non-numeric results + * Remove check for the max_oids column which has been present + since Cacti v1.0 + * Minimize Sorting when fetching poller records for maximum + performance + * Spine should see if script to be executed is executable + +------------------------------------------------------------------- Old: ---- cacti-spine-1.2.24.tar.gz New: ---- cacti-spine-1.2.25.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ cacti-spine.spec ++++++ --- /var/tmp/diff_new_pack.qUXH2H/_old 2023-09-06 19:03:45.231452106 +0200 +++ /var/tmp/diff_new_pack.qUXH2H/_new 2023-09-06 19:03:45.235452248 +0200 @@ -18,12 +18,12 @@ %{!?make_build: %define make_build make %{?_smp_mflags}} Name: cacti-spine -Version: 1.2.24 +Version: 1.2.25 Release: 0 Summary: Threaded poller for Cacti written in C License: LGPL-2.1-or-later URL: https://www.cacti.net/spine_info.php -Source: https://www.cacti.net/downloads/spine/%{name}-%{version}.tar.gz +Source: http://files.cacti.net/spine/%{name}-%{version}.tar.gz BuildRequires: help2man BuildRequires: libtool BuildRequires: mysql-devel ++++++ cacti-spine-1.2.24.tar.gz -> cacti-spine-1.2.25.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cacti-spine-1.2.24/CHANGELOG new/cacti-spine-1.2.25/CHANGELOG --- old/cacti-spine-1.2.24/CHANGELOG 2023-02-27 14:59:43.000000000 +0100 +++ new/cacti-spine-1.2.25/CHANGELOG 2023-09-05 01:57:16.000000000 +0200 @@ -1,5 +1,21 @@ The Cacti Group | spine +1.2.25 +-issue#234: Spine should see if script to be executed is executable +-issue#291: Enhance number recognition +-issue#294: When polling devices, sort by larger number of items first +-issue#298: Log format may be corrupted when timeout occurs +-issue#303: Compile warning appears due to GCC flag on RHEL7/RHEL8 +-issue#304: Downed device detection only checks one of the two uptime OIDs +-issue#305: Compile error appears due to execinfo.h on FreeBSD +-issue#306: Bootstrap shell script contains some PHP cruft +-issue#308: Padding is not always removed from the start of non-numeric strings +-issue#311: Improve SNMP result handling for non-numeric results +-issue#312: Further improve SNMP result handling for non-numeric results +-issue#313: Remove check for the max_oids column which has been present since Cacti v1.0 +-issue#314: Minimize Sorting when fetching poller records for maximum performance +-feature#234: Spine should see if script to be executed is executable + 1.2.24 -issue#296: When ignoring older OIDs, segmentation faults can be caused diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cacti-spine-1.2.24/bootstrap new/cacti-spine-1.2.25/bootstrap --- old/cacti-spine-1.2.24/bootstrap 2023-02-27 14:59:43.000000000 +0100 +++ new/cacti-spine-1.2.25/bootstrap 2023-09-05 01:57:16.000000000 +0200 @@ -1,5 +1,4 @@ #!/bin/sh -<?php # +-------------------------------------------------------------------------+ # | Copyright (C) 2004-2023 The Cacti Group | # | | diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cacti-spine-1.2.24/configure.ac new/cacti-spine-1.2.25/configure.ac --- old/cacti-spine-1.2.24/configure.ac 2023-02-27 14:59:43.000000000 +0100 +++ new/cacti-spine-1.2.25/configure.ac 2023-09-05 01:57:16.000000000 +0200 @@ -20,7 +20,7 @@ # +-------------------------------------------------------------------------+ AC_PREREQ([2.63]) -AC_INIT([Spine Poller],[1.2.24],[http://www.cacti.net/issues.php]) +AC_INIT([Spine Poller],[1.2.25],[http://www.cacti.net/issues.php]) AC_CONFIG_AUX_DIR(config) AC_SUBST(ac_aux_dir) @@ -129,7 +129,6 @@ AC_CHECK_HEADERS(sys/socket.h sys/select.h sys/wait.h sys/time.h) AC_CHECK_HEADERS(assert.h ctype.h errno.h signal.h math.h malloc.h netdb.h) AC_CHECK_HEADERS(signal.h stdarg.h stdio.h syslog.h) -AC_CHECK_HEADERS(execinfo.h) AC_CHECK_HEADERS( netinet/in_systm.h netinet/in.h netinet/ip.h netinet/ip_icmp.h, [], diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cacti-spine-1.2.24/ping.c new/cacti-spine-1.2.25/ping.c --- old/cacti-spine-1.2.24/ping.c 2023-02-27 14:59:43.000000000 +0100 +++ new/cacti-spine-1.2.25/ping.c 2023-09-05 01:57:16.000000000 +0200 @@ -76,7 +76,7 @@ } else if (host->availability_method == AVAIL_PING) { snprintf(ping->ping_status, 50, "0.000"); snprintf(ping->ping_response, SMALL_BUFSIZE, "PING: Device is Unknown or is IPV6. Please use the SNMP ping options only."); - return HOST_DOWN; + ping_result = HOST_DOWN; } } else { snprintf(ping->ping_status, 50, "0.000"); @@ -90,57 +90,34 @@ (host->availability_method == AVAIL_SNMP_GET_SYSDESC) || (host->availability_method == AVAIL_SNMP_GET_NEXT) || (host->availability_method == AVAIL_SNMP_AND_PING) || - ((host->availability_method == AVAIL_SNMP_OR_PING) && (ping_result != HOST_UP))) { - snmp_result = ping_snmp(host, ping); + (host->availability_method == AVAIL_SNMP_OR_PING)) { + + /* If we are in AND mode and already have a failed ping result, we don't need SNMP */ + if ((ping_result == HOST_DOWN) && (host->availability_method == AVAIL_SNMP_AND_PING)) { + snmp_result = ping_result; + } else { + /* Lets assume the host is up because if we are in OR mode then we have already + * pinged the host successfully, or some when silly people have not entered an + * snmp_community under v1/2, we assume that this was successfully anyway */ + snmp_result = HOST_UP; + if ((host->availability_method != AVAIL_SNMP_OR_PING) && + ((strlen(host->snmp_community) > 0) || (host->snmp_version >= 3))) { + snmp_result = ping_snmp(host, ping); + } + } } switch (host->availability_method) { case AVAIL_SNMP_AND_PING: - if (strlen(host->snmp_community) == 0 && host->snmp_version < 3) { - if (ping_result == HOST_UP) { - return HOST_UP; - } else { - return HOST_DOWN; - } - } - - if ((snmp_result == HOST_UP) && (ping_result == HOST_UP)) { - return HOST_UP; - } else { - return HOST_DOWN; - } + return ((ping_result == HOST_UP) && (snmp_result == HOST_UP)) ? HOST_UP : HOST_DOWN; case AVAIL_SNMP_OR_PING: - if (strlen(host->snmp_community) == 0 && host->snmp_version < 3) { - if (ping_result == HOST_UP) { - return HOST_UP; - } else { - return HOST_DOWN; - } - } - - if (snmp_result == HOST_UP) { - return HOST_UP; - } - - if (ping_result == HOST_UP) { - return HOST_UP; - } else { - return HOST_DOWN; - } + return ((ping_result == HOST_UP) || (snmp_result == HOST_UP)) ? HOST_UP : HOST_DOWN; case AVAIL_SNMP: case AVAIL_SNMP_GET_NEXT: case AVAIL_SNMP_GET_SYSDESC: - if (snmp_result == HOST_UP) { - return HOST_UP; - } else { - return HOST_DOWN; - } + return (snmp_result == HOST_UP) ? HOST_UP : HOST_DOWN; case AVAIL_PING: - if (ping_result == HOST_UP) { - return HOST_UP; - } else { - return HOST_DOWN; - } + return (ping_result == HOST_UP) ? HOST_UP : HOST_DOWN; case AVAIL_NONE: return HOST_UP; default: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cacti-spine-1.2.24/poller.c new/cacti-spine-1.2.25/poller.c --- old/cacti-spine-1.2.24/poller.c 2023-02-27 14:59:43.000000000 +0100 +++ new/cacti-spine-1.2.25/poller.c 2023-09-05 01:57:16.000000000 +0200 @@ -150,7 +150,6 @@ char query10[BUFSIZE]; char query11[BUFSIZE]; char *query12 = NULL; - char query13[BUFSIZE]; char posuffix[BUFSIZE]; int query1_len = 0; @@ -278,16 +277,28 @@ /* single polling interval query for items */ if (set.poller_id == 0) { - snprintf(query1, BUFSIZE, - "SELECT SQL_NO_CACHE action, hostname, snmp_community, " - "snmp_version, snmp_username, snmp_password, " - "rrd_name, rrd_path, arg1, arg2, arg3, local_data_id, " - "rrd_num, snmp_port, snmp_timeout, " - "snmp_auth_protocol, snmp_priv_passphrase, snmp_priv_protocol, snmp_context, snmp_engine_id " - " FROM poller_item" - " WHERE host_id = %i" - " AND deleted = ''" - " ORDER BY snmp_port %s", host_id, limits); + if (set.total_snmp_ports == 1) { + snprintf(query1, BUFSIZE, + "SELECT SQL_NO_CACHE action, hostname, snmp_community, " + "snmp_version, snmp_username, snmp_password, " + "rrd_name, rrd_path, arg1, arg2, arg3, local_data_id, " + "rrd_num, snmp_port, snmp_timeout, " + "snmp_auth_protocol, snmp_priv_passphrase, snmp_priv_protocol, snmp_context, snmp_engine_id " + " FROM poller_item" + " WHERE host_id = %i" + " AND deleted = '' %s", host_id, limits); + } else { + snprintf(query1, BUFSIZE, + "SELECT SQL_NO_CACHE action, hostname, snmp_community, " + "snmp_version, snmp_username, snmp_password, " + "rrd_name, rrd_path, arg1, arg2, arg3, local_data_id, " + "rrd_num, snmp_port, snmp_timeout, " + "snmp_auth_protocol, snmp_priv_passphrase, snmp_priv_protocol, snmp_context, snmp_engine_id " + " FROM poller_item" + " WHERE host_id = %i" + " AND deleted = ''" + " ORDER BY snmp_port %s", host_id, limits); + } /* host structure for uptime checks */ snprintf(query2, BIG_BUFSIZE, @@ -402,16 +413,28 @@ " GROUP BY snmp_port %s", host_id, limits); } } else { - snprintf(query1, BUFSIZE, - "SELECT SQL_NO_CACHE action, hostname, snmp_community, " - "snmp_version, snmp_username, snmp_password, " - "rrd_name, rrd_path, arg1, arg2, arg3, local_data_id, " - "rrd_num, snmp_port, snmp_timeout, " - "snmp_auth_protocol, snmp_priv_passphrase, snmp_priv_protocol, snmp_context, snmp_engine_id " - " FROM poller_item" - " WHERE host_id = %i" - " AND poller_id=%i" - " ORDER BY snmp_port %s", host_id, set.poller_id, limits); + if (set.total_snmp_ports == 1) { + snprintf(query1, BUFSIZE, + "SELECT SQL_NO_CACHE action, hostname, snmp_community, " + "snmp_version, snmp_username, snmp_password, " + "rrd_name, rrd_path, arg1, arg2, arg3, local_data_id, " + "rrd_num, snmp_port, snmp_timeout, " + "snmp_auth_protocol, snmp_priv_passphrase, snmp_priv_protocol, snmp_context, snmp_engine_id " + " FROM poller_item" + " WHERE host_id = %i" + " AND poller_id=%i %s", host_id, set.poller_id, limits); + } else { + snprintf(query1, BUFSIZE, + "SELECT SQL_NO_CACHE action, hostname, snmp_community, " + "snmp_version, snmp_username, snmp_password, " + "rrd_name, rrd_path, arg1, arg2, arg3, local_data_id, " + "rrd_num, snmp_port, snmp_timeout, " + "snmp_auth_protocol, snmp_priv_passphrase, snmp_priv_protocol, snmp_context, snmp_engine_id " + " FROM poller_item" + " WHERE host_id = %i" + " AND poller_id=%i" + " ORDER BY snmp_port %s", host_id, set.poller_id, limits); + } /* host structure for uptime checks */ snprintf(query2, BIG_BUFSIZE, @@ -436,28 +459,53 @@ /* multiple polling interval query for items */ if (set.active_profiles != 1) { - snprintf(query5, BUFSIZE, - "SELECT SQL_NO_CACHE action, hostname, snmp_community, " - "snmp_version, snmp_username, snmp_password, " - "rrd_name, rrd_path, arg1, arg2, arg3, local_data_id, " - "rrd_num, snmp_port, snmp_timeout, " - "snmp_auth_protocol, snmp_priv_passphrase, snmp_priv_protocol, snmp_context, snmp_engine_id " - " FROM poller_item" - " WHERE host_id = %i" - " AND rrd_next_step <= 0" - " AND poller_id = %i" - " ORDER by snmp_port %s", host_id, set.poller_id, limits); + if (set.total_snmp_ports == 1) { + snprintf(query5, BUFSIZE, + "SELECT SQL_NO_CACHE action, hostname, snmp_community, " + "snmp_version, snmp_username, snmp_password, " + "rrd_name, rrd_path, arg1, arg2, arg3, local_data_id, " + "rrd_num, snmp_port, snmp_timeout, " + "snmp_auth_protocol, snmp_priv_passphrase, snmp_priv_protocol, snmp_context, snmp_engine_id " + " FROM poller_item" + " WHERE host_id = %i" + " AND rrd_next_step <= 0" + " AND poller_id = %i %s", host_id, set.poller_id, limits); + } else { + snprintf(query5, BUFSIZE, + "SELECT SQL_NO_CACHE action, hostname, snmp_community, " + "snmp_version, snmp_username, snmp_password, " + "rrd_name, rrd_path, arg1, arg2, arg3, local_data_id, " + "rrd_num, snmp_port, snmp_timeout, " + "snmp_auth_protocol, snmp_priv_passphrase, snmp_priv_protocol, snmp_context, snmp_engine_id " + " FROM poller_item" + " WHERE host_id = %i" + " AND rrd_next_step <= 0" + " AND poller_id = %i" + " ORDER BY snmp_port %s", host_id, set.poller_id, limits); + } } else { - snprintf(query5, BUFSIZE, - "SELECT SQL_NO_CACHE action, hostname, snmp_community, " - "snmp_version, snmp_username, snmp_password, " - "rrd_name, rrd_path, arg1, arg2, arg3, local_data_id, " - "rrd_num, snmp_port, snmp_timeout, " - "snmp_auth_protocol, snmp_priv_passphrase, snmp_priv_protocol, snmp_context, snmp_engine_id " - " FROM poller_item" - " WHERE host_id = %i" - " AND poller_id = %i" - " ORDER by snmp_port %s", host_id, set.poller_id, limits); + if (set.total_snmp_ports == 1) { + snprintf(query5, BUFSIZE, + "SELECT SQL_NO_CACHE action, hostname, snmp_community, " + "snmp_version, snmp_username, snmp_password, " + "rrd_name, rrd_path, arg1, arg2, arg3, local_data_id, " + "rrd_num, snmp_port, snmp_timeout, " + "snmp_auth_protocol, snmp_priv_passphrase, snmp_priv_protocol, snmp_context, snmp_engine_id " + " FROM poller_item" + " WHERE host_id = %i" + " AND poller_id = %i %s", host_id, set.poller_id, limits); + } else { + snprintf(query5, BUFSIZE, + "SELECT SQL_NO_CACHE action, hostname, snmp_community, " + "snmp_version, snmp_username, snmp_password, " + "rrd_name, rrd_path, arg1, arg2, arg3, local_data_id, " + "rrd_num, snmp_port, snmp_timeout, " + "snmp_auth_protocol, snmp_priv_passphrase, snmp_priv_protocol, snmp_context, snmp_engine_id " + " FROM poller_item" + " WHERE host_id = %i" + " AND poller_id = %i" + " ORDER BY snmp_port %s", host_id, set.poller_id, limits); + } } /* query to setup the next polling interval in cacti */ @@ -1115,7 +1163,7 @@ } if ((assert_fail) && - ((!strcmp(reindex->op, "<")) || (!strcmp(reindex->arg1,".1.3.6.1.2.1.1.3.0")))) { + ((!strcmp(reindex->op, "<")) || (!strcmp(reindex->arg1,".1.3.6.1.2.1.1.3.0") && !strcmp(reindex->arg1, ".1.3.6.1.6.3.10.2.1.3.0")))) { spike_kill = TRUE; if (is_debug_device(host->id) || set.spine_log_level == 2) { @@ -1451,7 +1499,7 @@ /* is valid output, continue */ } else { /* remove double or single quotes from string */ - snprintf(temp_result, RESULTS_BUFFER, "%s", snmp_oids[j].result); + snprintf(temp_result, RESULTS_BUFFER, "%s", strip_alpha(trim(snmp_oids[j].result))); snprintf(snmp_oids[j].result , RESULTS_BUFFER, "%s", temp_result); /* detect erroneous non-numeric result */ @@ -2165,6 +2213,11 @@ int sem_err = 0; int needs_cleanup = 0; + /* used for checking executable status */ + char executable[BUFSIZE]; + char *saveptr = NULL; + char *token; + pthread_cleanup_push(child_cleanup_script, NULL); // use the script server timeout value, allow for 50% leeway @@ -2197,117 +2250,140 @@ /* record start time */ begin_time = get_time_as_double(); - #ifdef USING_TPOPEN - fd = popen((char *)proc_command, "r"); - cmd_fd = fileno(fd); - if (is_debug_device(current_host->id)) { - SPINE_LOG(("DEBUG: Device[%i] DEBUG: The POPEN returned the following File Descriptor %i", current_host->id, cmd_fd)); - } else { - SPINE_LOG_DEBUG(("DEBUG: Device[%i] DEBUG: The POPEN returned the following File Descriptor %i", current_host->id, cmd_fd)); - } - #else - cmd_fd = nft_popen((char *)proc_command, "r"); - if (is_debug_device(current_host->id)) { - SPINE_LOG(("DEBUG: Device[%i] DEBUG: The NIFTY POPEN returned the following File Descriptor %i", current_host->id, cmd_fd)); - } else { - SPINE_LOG_DEBUG(("DEBUG: Device[%i] DEBUG: The NIFTY POPEN returned the following File Descriptor %i", current_host->id, cmd_fd)); + /* peel the executable from the command */ + saveptr = proc_command; + sprintf(executable, "%s", proc_command); + token = strtok_r(executable, " ", &saveptr); + + /* cheesy little hack to add /usr/bin/ if its not included */ + if (strstr(executable, "/") == NULL) { + saveptr = proc_command; + sprintf(executable, "/usr/bin/%s", proc_command); + token = strtok_r(executable, " ", &saveptr); } - #endif - if (cmd_fd > 0) { - retry: + SPINE_LOG_DEBUG(("The executable is '%s' in \'%s\'", executable, proc_command)); - /* Initialize File Descriptors to Review for Input/Output */ - FD_ZERO(&fds); - FD_SET(cmd_fd, &fds); - - /* wait x seconds for pipe response */ - switch (select(FD_SETSIZE, &fds, NULL, NULL, &timeout)) { - case -1: - switch (errno) { - case EBADF: - SPINE_LOG(("Device[%i] ERROR: One or more of the file descriptor sets specified a file descriptor that is not a valid open file descriptor.", current_host->id)); - SET_UNDEFINED(result_string); - close_fd = FALSE; - break; - case EINTR: - #ifndef SOLAR_THREAD - /* take a moment */ - usleep(2000); - #endif + if (access(executable, X_OK | F_OK) != -1) { + #ifdef USING_TPOPEN + fd = popen((char *)proc_command, "r"); + cmd_fd = fileno(fd); + if (is_debug_device(current_host->id)) { + SPINE_LOG(("DEBUG: Device[%i] DEBUG: The POPEN returned the following File Descriptor %i", current_host->id, cmd_fd)); + } else { + SPINE_LOG_DEBUG(("DEBUG: Device[%i] DEBUG: The POPEN returned the following File Descriptor %i", current_host->id, cmd_fd)); + } + #else + cmd_fd = nft_popen((char *)proc_command, "r"); + if (is_debug_device(current_host->id)) { + SPINE_LOG(("DEBUG: Device[%i] DEBUG: The NIFTY POPEN returned the following File Descriptor %i", current_host->id, cmd_fd)); + } else { + SPINE_LOG_DEBUG(("DEBUG: Device[%i] DEBUG: The NIFTY POPEN returned the following File Descriptor %i", current_host->id, cmd_fd)); + } + #endif - /* record end time */ - end_time = get_time_as_double(); + if (cmd_fd > 0) { + retry: - /* re-establish new timeout value */ - timeout.tv_sec = rint(floor(script_timeout-(end_time-begin_time))); - remaining_usec = set.script_timeout - timeout.tv_sec - (end_time - begin_time); + /* Initialize File Descriptors to Review for Input/Output */ + FD_ZERO(&fds); + FD_SET(cmd_fd, &fds); + + /* wait x seconds for pipe response */ + switch (select(FD_SETSIZE, &fds, NULL, NULL, &timeout)) { + case -1: + switch (errno) { + case EBADF: + SPINE_LOG(("Device[%i] ERROR: One or more of the file descriptor sets specified a file descriptor that is not a valid open file descriptor.", current_host->id)); + SET_UNDEFINED(result_string); + close_fd = FALSE; + break; + case EINTR: + #ifndef SOLAR_THREAD + /* take a moment */ + usleep(2000); + #endif + + /* record end time */ + end_time = get_time_as_double(); + + /* re-establish new timeout value */ + timeout.tv_sec = rint(floor(script_timeout-(end_time-begin_time))); + remaining_usec = set.script_timeout - timeout.tv_sec - (end_time - begin_time); - if (remaining_usec > 0) { - timeout.tv_usec = rint(remaining_usec * 1000000); - } else { - timeout.tv_usec = 0; - } + if (remaining_usec > 0) { + timeout.tv_usec = rint(remaining_usec * 1000000); + } else { + timeout.tv_usec = 0; + } + timeout.tv_sec = rint(floor(script_timeout-(end_time-begin_time))); + timeout.tv_usec = rint((script_timeout-(end_time-begin_time)-timeout.tv_sec)*1000000); + + if (timeout.tv_sec + timeout.tv_usec > 0) { + goto retry; + } else { + SPINE_LOG(("WARNING: A script timed out while processing EINTR's.")); + SET_UNDEFINED(result_string); + close_fd = FALSE; + } + break; + case EINVAL: + SPINE_LOG(("Device[%i] ERROR: Possible invalid timeout specified in select() statement.", current_host->id)); + SET_UNDEFINED(result_string); + close_fd = FALSE; + break; + default: + SPINE_LOG(("Device[%i] ERROR: The script/command select() failed", current_host->id)); + SET_UNDEFINED(result_string); + close_fd = FALSE; + break; + } + + break; + case 0: + #ifdef USING_TPOPEN + SPINE_LOG_MEDIUM(("Device[%i] ERROR: The POPEN timed out", current_host->id)); - if (timeout.tv_sec + timeout.tv_usec > 0) { - goto retry; - } else { - SPINE_LOG(("WARNING: A script timed out while processing EINTR's.")); - SET_UNDEFINED(result_string); - close_fd = FALSE; - } - break; - case EINVAL: - SPINE_LOG(("Device[%i] ERROR: Possible invalid timeout specified in select() statement.", current_host->id)); - SET_UNDEFINED(result_string); close_fd = FALSE; - break; - default: - SPINE_LOG(("Device[%i] ERROR: The script/command select() failed", current_host->id)); + #else + SPINE_LOG_MEDIUM(("Device[%i] ERROR: The NIFTY POPEN timed out", current_host->id)); + + pid = nft_pchild(cmd_fd); + kill(pid, SIGKILL); + #endif + SET_UNDEFINED(result_string); - close_fd = FALSE; break; + default: + /* get only one line of output, we will ignore the rest */ + bytes_read = read(cmd_fd, result_string, RESULTS_BUFFER-1); + if (bytes_read > 0) { + result_string[bytes_read] = '\0'; + } else { + if (STRIMATCH(type,"DS")) { + SPINE_LOG(("Device[%i] DS[%i] ERROR: Empty result [%s]: '%s'", current_host->id, id, current_host->hostname, command)); + } else { + SPINE_LOG(("Device[%i] DQ[%i] ERROR: Empty result [%s]: '%s'", current_host->id, id, current_host->hostname, command)); + } + SET_UNDEFINED(result_string); + } } - case 0: - #ifdef USING_TPOPEN - SPINE_LOG_MEDIUM(("Device[%i] ERROR: The POPEN timed out", current_host->id)); - close_fd = FALSE; + /* close pipe */ + #ifdef USING_TPOPEN + /* we leave the old fd open if it timed out. It will have to exit on it's own */ + if (close_fd) { + pclose(fd); + } #else - SPINE_LOG_MEDIUM(("Device[%i] ERROR: The NIFTY POPEN timed out", current_host->id)); - - pid = nft_pchild(cmd_fd); - kill(pid, SIGKILL); + nft_pclose(cmd_fd); #endif - + } else { + SPINE_LOG(("Device[%i] ERROR: Problem executing POPEN [%s]: '%s'", current_host->id, current_host->hostname, command)); SET_UNDEFINED(result_string); - break; - default: - /* get only one line of output, we will ignore the rest */ - bytes_read = read(cmd_fd, result_string, RESULTS_BUFFER-1); - if (bytes_read > 0) { - result_string[bytes_read] = '\0'; - } else { - if (STRIMATCH(type,"DS")) { - SPINE_LOG(("Device[%i] DS[%i] ERROR: Empty result [%s]: '%s'", current_host->id, id, current_host->hostname, command)); - } else { - SPINE_LOG(("Device[%i] DQ[%i] ERROR: Empty result [%s]: '%s'", current_host->id, id, current_host->hostname, command)); - } - SET_UNDEFINED(result_string); - } } - - /* close pipe */ - #ifdef USING_TPOPEN - /* we leave the old fd open if it timed out. It will have to exit on it's own */ - if (close_fd) { - pclose(fd); - } - #else - nft_pclose(cmd_fd); - #endif } else { - SPINE_LOG(("Device[%i] ERROR: Problem executing POPEN [%s]: '%s'", current_host->id, current_host->hostname, command)); + SPINE_LOG(("Device[%i] ERROR: Problem executing POPEN. File '%s' does not exist or is not executable.", current_host->id, command)); SET_UNDEFINED(result_string); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cacti-spine-1.2.24/spine.c new/cacti-spine-1.2.25/spine.c --- old/cacti-spine-1.2.24/spine.c 2023-02-27 14:59:43.000000000 +0100 +++ new/cacti-spine-1.2.25/spine.c 2023-09-05 01:57:16.000000000 +0200 @@ -6,7 +6,7 @@ | This program is free software; you can redistribute it and/or | | modify it under the terms of the GNU Lesser General Public | | License as published by the Free Software Foundation; either | - | version 2.1 of the License, or (at your option) any later version. | + | version 2.1 of the License, or (at your option) any later version. | | | | This program is distributed in the hope that it will be useful, | | but WITHOUT ANY WARRANTY; without even the implied warranty of | @@ -602,37 +602,21 @@ } db_free_result(result); - /* determine if the device_threads field exists in the host table */ - result = db_query(&mysql, LOCAL, "SHOW COLUMNS FROM host LIKE 'device_threads'"); - if (mysql_num_rows(result)) { - set.device_threads_exists = TRUE; - } else { - set.device_threads_exists = FALSE; - } - db_free_result(result); - - if (set.device_threads_exists) { - SPINE_LOG_MEDIUM(("Spine will support multithread device polling.")); - } else { - SPINE_LOG_MEDIUM(("Spine did not detect multithreaded device polling.")); - } - /* obtain the list of hosts to poll */ - if (set.device_threads_exists) { - qp += sprintf(qp, "SELECT SQL_NO_CACHE id, device_threads FROM host"); - } else { - qp += sprintf(qp, "SELECT SQL_NO_CACHE id, '1' as device_threads FROM host"); - } - qp += sprintf(qp, " WHERE disabled=''"); + qp += sprintf(qp, "SELECT SQL_NO_CACHE id, device_threads, picount, picount/device_threads AS tppi FROM host INNER JOIN (SELECT host_id, COUNT(*) AS picount FROM poller_item GROUP BY host_id) AS pi ON host.id = pi.host_id"); + qp += sprintf(qp, " WHERE disabled = ''"); + if (!strlen(set.host_id_list)) { qp += append_hostrange(qp, "id"); /* AND id BETWEEN a AND b */ } else { qp += sprintf(qp, " AND id IN(%s)", set.host_id_list); } + if (set.poller_id_exists) { - qp += sprintf(qp, " AND host.poller_id=%i", set.poller_id); + qp += sprintf(qp, " AND host.poller_id = %i", set.poller_id); } - qp += sprintf(qp, " ORDER BY polling_time DESC"); + + qp += sprintf(qp, " ORDER BY picount DESC"); result = db_query(&mysql, LOCAL, querybuf); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cacti-spine-1.2.24/spine.h new/cacti-spine-1.2.25/spine.h --- old/cacti-spine-1.2.24/spine.h 2023-02-27 14:59:43.000000000 +0100 +++ new/cacti-spine-1.2.25/spine.h 2023-09-05 01:57:16.000000000 +0200 @@ -345,13 +345,12 @@ /* general configuration/runtime settings */ int poller_id; int poller_id_exists; - int device_threads_exists; int poller_interval; int parent_fork; int num_parent_processes; int script_timeout; int active_profiles; - int total_snmp_ports;; + int total_snmp_ports; int threads; int logfile_processed; int boost_enabled; @@ -377,7 +376,7 @@ unsigned int db_port; char dbversion[SMALL_BUFSIZE]; int dbonupdate; - int cacti_version; + int cacti_version; /* path information */ char path_logfile[DBL_BUFSIZE]; char path_php[BUFSIZE]; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cacti-spine-1.2.24/util.c new/cacti-spine-1.2.25/util.c --- old/cacti-spine-1.2.24/util.c 2023-02-27 14:59:43.000000000 +0100 +++ new/cacti-spine-1.2.25/util.c 2023-09-05 01:57:16.000000000 +0200 @@ -1558,9 +1558,12 @@ */ char *strip_alpha(char *string) { int i; + int j; i = strlen(string); + j = 0; + /* trim trailing characters */ while (i >= 0) { if (isdigit((int)string[i])) { break; @@ -1570,6 +1573,21 @@ i--; } + /* trim leading characters */ + while (j < i) { + if (isdigit((int)string[j])) { + break; + } else if (string[j] == '-') { + break; + } else if (string[j] == '+') { + j++; + } else { + j++; + } + } + + string = &string[j]; + return string; } @@ -1635,7 +1653,9 @@ * */ #pragma GCC diagnostic push +#if (defined(__GNUC__) && (__GNUC__ > 7)) || (__GNUC__ == 7 && defined(__GNUC_MINOR__) && __GNUC_MINOR__ > 1) #pragma GCC diagnostic ignored "-Wstringop-overflow" +#endif char *strncopy(char *dst, const char *src, size_t obuf) { assert(dst != 0); assert(src != 0); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cacti-spine-1.2.24/util.h new/cacti-spine-1.2.25/util.h --- old/cacti-spine-1.2.24/util.h 2023-02-27 14:59:43.000000000 +0100 +++ new/cacti-spine-1.2.25/util.h 2023-09-05 01:57:16.000000000 +0200 @@ -96,3 +96,6 @@ /* start time for spine */ extern double start_time; + +/* the version of Cacti as a decimal */ +int get_cacti_version(MYSQL *psql, int mode);