mirror of
https://github.com/Cacti/spine.git
synced 2026-10-23 03:27:10 +09:00
## Summary Consolidates the connector/build work from #613 and the broader test-infrastructure work extracted from #597 into one review: - discover MariaDB Connector/C first while retaining MySQL and Percona-compatible support - test MariaDB and MySQL Connector/C with strict GCC and Clang builds on Ubuntu 24.04 - add a real macOS 15 build and unit-test lane with portable Autotools platform detection - run unit tests under ASan/UBSan and ThreadSanitizer - enforce the measured 7% global coverage baseline and 70% changed-line coverage - add libFuzzer coverage for output parsing alongside the existing hostname parser - exercise the SNMPv3 integration suite against MariaDB and MySQL 8.4 - add cppcheck, shellcheck, DCO verification, CODEOWNERS, distcheck, and Linux-capability checks while retaining the repository-managed default CodeQL setup - expose a stable `CI / required` aggregate check for branch protection - pin runners and third-party actions and keep workflow permissions read-only by default ## Correctness fixes found by the new gates - reject truncated capability strings and poller-output SQL tuples instead of publishing partial data - make `bootstrap` fail closed and select `libtoolize`/`glibtoolize` portably - use Autoconf's canonical host for Darwin detection instead of an empty native-build alias - remove stale initialization/name-shadow findings and make read-only interfaces const-correct - make the ICMP parser test portable across Linux and BSD header names ## Verification - strict GCC and Clang builds: 4/4 unit targets passed - ASan/UBSan: 4/4 passed - ThreadSanitizer: 4/4 passed - macOS Clang/Homebrew build: 4/4 passed - MariaDB integration: passed - MySQL 8.4 integration: passed - both libFuzzer targets: passed sustained local runs - coverage: 7.2% global and 84% on changed lines - cppcheck, shellcheck, actionlint, DCO verification, and `git diff --check`: passed locally ## Post-merge repository settings After these workflows exist on `develop`, an administrator should require `CI / required`, Fuzz, Integration, Rocky Linux, and the repository-managed CodeQL/code-scanning result in the active ruleset; enable code-owner approval; and require the branch to be current (or use a merge queue). Enabling those settings before this PR merges would create required checks that the base branch cannot yet emit. Consolidates and supersedes #613. Closes #612. --------- Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> Signed-off-by: TheWitness <thewitness@cacti.net> Signed-off-by: TheWitness <copilot@users.noreply.github.com> Co-authored-by: TheWitness <thewitness@cacti.net> Co-authored-by: TheWitness <copilot@users.noreply.github.com>
139 lines
6.0 KiB
C
139 lines
6.0 KiB
C
/*
|
|
ex: set tabstop=4 shiftwidth=4 autoindent:*
|
|
+-------------------------------------------------------------------------+
|
|
| Copyright (C) 2004-2026 The Cacti Group |
|
|
| |
|
|
| 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. |
|
|
| |
|
|
| 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 Lesser General Public License for more details. |
|
|
| |
|
|
| You should have received a copy of the GNU Lesser General Public |
|
|
| License along with this library; if not, write to the Free Software |
|
|
| Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA |
|
|
| 02110-1301, USA |
|
|
| |
|
|
+-------------------------------------------------------------------------+
|
|
| spine: a backend data gatherer for cacti |
|
|
+-------------------------------------------------------------------------+
|
|
| This poller would not have been possible without: |
|
|
| - Larry Adams (current development and enhancements) |
|
|
| - Rivo Nurges (rrd support, mysql poller cache, misc functions) |
|
|
| - RTG (core poller code, pthreads, snmp, autoconf examples) |
|
|
| - Brady Alleman/Doug Warner (threading ideas, implementation details) |
|
|
+-------------------------------------------------------------------------+
|
|
| - Cacti - http://www.cacti.net/ |
|
|
+-------------------------------------------------------------------------+
|
|
*/
|
|
|
|
#ifndef SPINE_UTIL_H
|
|
#define SPINE_UTIL_H
|
|
/* cacti config reading functions */
|
|
extern void read_config_options(void);
|
|
extern int read_spine_config(const char *file);
|
|
extern void config_defaults(void);
|
|
|
|
/* cacti logging function */
|
|
extern int spine_log(const char *format, ...)
|
|
__attribute__((format(printf, 1, 2)));
|
|
|
|
extern void die(const char *format, ...)
|
|
__attribute__((noreturn))
|
|
__attribute__((format(printf, 1, 2)));
|
|
|
|
/* option processing function */
|
|
extern void set_option(const char *setting, const char *value);
|
|
|
|
/* number validation functions */
|
|
extern int is_numeric(char *string);
|
|
extern int is_ipaddress(const char *string);
|
|
extern int all_digits(const char *str);
|
|
extern int is_hexadecimal(const char * str, const short ignore_special);
|
|
|
|
/* determine if a device is a debug device */
|
|
extern int is_debug_device(int device_id);
|
|
|
|
/* string and file functions */
|
|
extern char *add_slashes(const 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);
|
|
extern char *trim(char *str);
|
|
extern char *rtrim(char *str);
|
|
extern char *ltrim(char *str);
|
|
extern char *reverse(char *str);
|
|
extern int strpos(const char *haystack, const char *needle);
|
|
extern int char_count(const char *str, int chr);
|
|
|
|
/* convert a delimited hexadecimal value without conflating overflow with 0 */
|
|
int hex2dec(const char *str, unsigned long long *result);
|
|
|
|
/* custom regex replace to return a value if matches */
|
|
#define MAX_MATCHES 5
|
|
#define REGEX_NUMBER "([-+]*)([0-9]*)([.][0-9]+)"
|
|
#define CAPABILITY_PROTOCOL_LIST_MAX 480
|
|
const char *regex_replace(const char *exp, const char *value);
|
|
int format_spine_capabilities(char *output, size_t output_size,
|
|
const char *auth_protocols, const char *priv_protocols);
|
|
|
|
/* macro to copy string to string with an ending null */
|
|
#define STRNCOPY(dst, src) strncopy((dst), (src), sizeof(dst))
|
|
#define USTRNCOPY(dst, src) ustrncopy((dst), (src), sizeof(dst))
|
|
|
|
/* macro to duplicate string and die if fails */
|
|
#define STRDUP_OR_DIE(dst, src, reason) \
|
|
if ((dst = strdup(src)) == NULL) {\
|
|
die("FATAL: malloc() failed during strdup() for %s", reason);\
|
|
}\
|
|
|
|
|
|
/* get highres time as double */
|
|
extern double get_time_as_double(void);
|
|
|
|
/* function to check to see if program has capability to use raw socket with
|
|
out uid = 0 */
|
|
extern int hasCaps(void);
|
|
|
|
/* see if we can do things as root */
|
|
extern void checkAsRoot(void);
|
|
|
|
/* log format */
|
|
extern void set_date_format(void);
|
|
extern char *get_date_format(void);
|
|
|
|
/* remote/main server synchronization */
|
|
extern void poller_push_data_to_main(void);
|
|
|
|
/* MySQL supports INSERT row aliases from 8.0.20; MariaDB does not. */
|
|
extern int db_row_alias_upsert_supported(const char *version, unsigned long version_number);
|
|
|
|
/* start time for spine */
|
|
extern double start_time;
|
|
|
|
/* the version of Cacti as a decimal */
|
|
int get_cacti_version(MYSQL *psql, int mode);
|
|
|
|
/*! \fn int spine_appendf(char **cursor, size_t *remaining, const char *fmt, ...)
|
|
* \brief append to a bounded buffer without walking off the end
|
|
*
|
|
* snprintf() returns the length it would have written, so `p += snprintf(p,
|
|
* remaining, ...)` moves the cursor past the buffer the first time a value is
|
|
* truncated. The next `remaining` is then negative, and as a size_t it is
|
|
* effectively unbounded, at a destination already out of bounds.
|
|
*
|
|
* This advances the cursor by what was actually written, stops on the
|
|
* terminator when the text does not fit, and says so.
|
|
*
|
|
* \return TRUE when the whole string was appended, FALSE on truncation or a
|
|
* formatting error, in which case the buffer stays NUL-terminated
|
|
*/
|
|
extern int spine_appendf(char **cursor, size_t *remaining, const char *fmt, ...)
|
|
__attribute__((format(printf, 3, 4)));
|
|
|
|
#endif /* SPINE_UTIL_H */
|