[Xymon] Update on 4.4 (Alpha1 release)

Tom Schmidt tom at 4schmidts.com
Tue Oct 3 22:06:25 CEST 2023


J.C.,
     Thank you again J.C. for reviving the updates for Xymon.  I am willing
to help update it as well, even though I am now retired and only have a
small install of Xymon 4.3.30 at home for my home network.  I have
contributed to Xymon several times in the past when I had it installed in a
large corporate environment before I retired.

J.C. and 4.4-alpha1 testers,
    I have done a little bit of testing of 4.4-alpha1 on Rocky Linux 8.8
(server and client) and on a busybox Linux install on a NAS.  I looked into
the gcc 8.5.0 compiler warnings that I got on Rocky Linux, and have
corrected them, or silenced the ones that should not be an issue.  Attached
are two context diff patch files, one to fix the compiler warnings, and one
to make a couple updates that I had applied to 4.3.30 previously.  My
updates fix the busybox Linux client build, and enhance the temperature
graph to optionally display both Celsius and Fahrenheit readings.

    I have not fully tested 4.4-alpha1 yet, but wanted to get these first
patches released for 4.4-alpha2.

Tom Schmidt

On Wed, Sep 20, 2023 at 2:38 PM J.C. Cleaver <cleaver at terabithia.org> wrote:

> Hello all! Just wanted to update everyone on a few things.
>
> Going through the 4.x codebase re-familiarizing myself again with the
> state of everything, I recalled that I'd actually built a release artifact
> before development was paused, including a testing RPM that has actually
> been running unbeknownst on a VM for quite a while. Unfortunately, while
> validating that compiles from source worked I ran into what looked like
> showstopper bugs. These weren't showing up in the package, so I had to
> pore through a lot more code* than I expected to try to figure out where
> the package was accidentally fixing it.
>
> (*message-sending code, which changes a lot in 4.4 to support compression,
> TLS, HTTP, and size-prefixed messages)
>
> Fortunately, it ended up being a relatively simple issue (isn't it
> always?), with easy-enough validation and workaround (given below).
> Although more fixes could be put in (and I'm sure will be needed!), I
> believe there's some benefit to having a stable starting point using a
> build artifact from 2019.
>
> As a result, I'm pleased to announce the first alpha for Xymon 4.4! As
> this is an alpha release, this is absolutely NOT suitable for production
> use and is intended mainly for smoketesting by source users. (And I expect
> there will be smoke.) The release tarball is available now at:
>
>
> https://sourceforge.net/projects/xymon/files/Xymon/4.4-alpha/xymon-4.4-alpha1.tar.gz
>
>
> Major improvements are too many to list here but are noted in the Changes
> and RELEASENOTES files. README documents for compression, TLS, and IPv6
> are in progress.
>
> Some of the changes and improvements other than TLS support have been in
> the Terabithia packages (to some extent) for a while, so there will be
> less of a delta for those users to this alpha.
>
> For the moment, I'd like to focus on source tarball users and others
> running xymon from scratch to help fix underlying issues and any smoketest
> failures, which I expect may crop up particularly on untested non-Linux
> platforms. Once the lower-hanging fruit is fixed and more patches are
> upstreamed and cleaned up, I'll release an alpha2 release at which point
> packages may be released to help with testing iteration and downstream
> distributors.
>
> Please flag bug reports or patches as related to "alpha1" in the subject
> line to help keep things clear.
>
>
> Thank you to everyone in the community for remaining part of it -- and
> xymon users! -- during this interregnum. Restarting development has been a
> process, but I'm glad to take this important first step to our next
> release.
>
>
> Regards,
> -jc
>
>
>
> *** KNOWN ISSUES -- IMPORTANT ***
>
> The configure script is likely setting XYMONHOME/XYMONCLIENTHOME and
> XYMSRV/XYMSERVERS/XYMONSERVERS incorrectly, which will prevent xymonlaunch
> from correctly launching anything. Double check the xymon environment
> files (xymonserver/xymonclient.cfg) before starting either the server or
> client.
>
> The tools/xymon-client.default and tools/xymonlaunch files may be placed
> into /etc/{sysconfig,default}/{xymon-client,xymonlaunch} to more easily
> set $XYMONSERVERS
>
> Revealed by the above issue is a bug causing a crash in the client (or
> anywhere) when given an empty string as the destination argument (instead
> of 0, 127.0.0.1 or no variable set). Don't do this --> [ xymon '' "ping" ]
>
> The client and logfetch binary may be being re-compiled during 'make
> install'
>
> Compilation may fail if c-ares and at least one compression library is not
> present (lzo/lz4/zlib are all options). xxHash libraries are also highly
> recommended as the plan is for xxhash to replace md5 for checksumming
> functionality. libtirpc may be necessary on some platforms, and it's
> possible the build code is still expecting traditional (Sun) RPC
>
>
>
>
> _______________________________________________
> Xymon mailing list
> Xymon at xymon.com
> http://lists.xymon.com/mailman/listinfo/xymon
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.xymon.com/pipermail/xymon/attachments/20231003/b0284bde/attachment.htm>
-------------- next part --------------
*** ./xymond/client/linux.c.orig	2016-02-02 13:15:30.000000000 -0700
--- ./xymond/client/linux.c	2023-09-25 10:01:42.623378869 -0600
***************
*** 62,68 ****
  			whostr, 0, psstr, 0, topstr);
  	unix_disk_report(hostname, clienttype, os, hinfo, fromline, timestr, "Available", "Capacity", "Mounted", dfstr);
  	unix_inode_report(hostname, clienttype, os, hinfo, fromline, timestr, "IFree", "IUse%", "Mounted", inodestr);
! 	unix_procs_report(hostname, clienttype, os, hinfo, fromline, timestr, "CMD", NULL, psstr);
  	unix_ports_report(hostname, clienttype, os, hinfo, fromline, timestr, 3, 4, 5, portsstr);
  
  	msgs_report(hostname, clienttype, os, hinfo, fromline, timestr, msgsstr);
--- 62,69 ----
  			whostr, 0, psstr, 0, topstr);
  	unix_disk_report(hostname, clienttype, os, hinfo, fromline, timestr, "Available", "Capacity", "Mounted", dfstr);
  	unix_inode_report(hostname, clienttype, os, hinfo, fromline, timestr, "IFree", "IUse%", "Mounted", inodestr);
! 	/* Linux busybox ps header could have "COMMAND" instead of "CMD" */
! 	unix_procs_report(hostname, clienttype, os, hinfo, fromline, timestr, "CMD", "COMMAND", psstr);
  	unix_ports_report(hostname, clienttype, os, hinfo, fromline, timestr, 3, 4, 5, portsstr);
  
  	msgs_report(hostname, clienttype, os, hinfo, fromline, timestr, msgsstr);
*** ./xymond/rrd/do_memory.c.orig	2019-08-13 16:50:32.000000000 -0600
--- ./xymond/rrd/do_memory.c	2023-09-25 10:01:45.173409431 -0600
***************
*** 41,49 ****
  	snprintf(rrdvalues, sizeof(rrdvalues), "%d:%d", (int)tstamp, physval);
  	create_and_update_rrd(hostname, testname, classname, pagepaths, memory_params, memory_tpl);
  
! 	setupfn2("%s.%s.rrd", "memory", "swap");
! 	snprintf(rrdvalues, sizeof(rrdvalues), "%d:%d", (int)tstamp, swapval);
! 	create_and_update_rrd(hostname, testname, classname, pagepaths, memory_params, memory_tpl);
  
  	if (actval >= 0) {
  		setupfn2("%s.%s.rrd", "memory", "actual");
--- 41,51 ----
  	snprintf(rrdvalues, sizeof(rrdvalues), "%d:%d", (int)tstamp, physval);
  	create_and_update_rrd(hostname, testname, classname, pagepaths, memory_params, memory_tpl);
  
! 	if (swapval >= 0) {
! 		setupfn2("%s.%s.rrd", "memory", "swap");
! 		snprintf(rrdvalues, sizeof(rrdvalues), "%d:%d", (int)tstamp, swapval);
! 		create_and_update_rrd(hostname, testname, classname, pagepaths, memory_params, memory_tpl);
! 	}
  
  	if (actval >= 0) {
  		setupfn2("%s.%s.rrd", "memory", "actual");
*** ./web/showgraph.c.orig	2019-09-23 17:24:19.000000000 -0600
--- ./web/showgraph.c	2023-09-25 10:02:29.763943852 -0600
***************
*** 652,657 ****
--- 652,688 ----
  			}
  			inp += 10;
  		}
+ 		else if (strncmp(inp, "@RRDPARAM_SPACE@", 16) == 0) {
+ 			/* 
+ 			 * Like @RRDPARAM@ above, but change underscores to spaces
+ 			 */
+ 			if (rrddbs[rrdidx].rrdparam) {
+ 				char *val, *p;
+ 				int vallen;
+ 				SBUF_DEFINE(resultstr);
+ 
+ 				val = colon_escape(rrddbs[rrdidx].rrdparam);
+ 				p = val; while ((p = strchr(p, ',')) != NULL) *p = '/';
+ 				p = val; while ((p = strchr(p, '_')) != NULL) *p = ' ';
+ 
+ 				/* rrdparam strings may be very long. */
+ 				if (strlen(val) > 100) *(val+100) = '\0';
+ 
+ 				/*
+ 				 * "paramlen" holds the longest string of the any of the matching files' rrdparam.
+ 				 * However, because this goes through colon_escape(), the actual string length 
+ 				 * passed to librrd functions may be longer (since ":" must be escaped as "\:").
+ 				 */
+ 				vallen = strlen(val);
+ 				if (vallen < paramlen) vallen = paramlen;
+ 
+ 				SBUF_MALLOC(resultstr, vallen + 1);
+ 				snprintf(resultstr, resultstr_buflen, "%-*s", paramlen, val);
+ 				addtobuffer(result, resultstr);
+ 				xfree(resultstr);
+ 			}
+ 			inp += 16;
+ 		}
  		else if (strncmp(inp, "@RRDMETA@", 9) == 0) {
  			/* 
  			 * We do a colon-escape first, then change all commas to slashes as
*** ./xymond/etcfiles/graphs.cfg.orig	2017-01-05 19:21:41.000000000 -0700
--- ./xymond/etcfiles/graphs.cfg	2023-09-25 09:30:46.441132397 -0600
***************
*** 16,23 ****
  # When FNPATTERN is used, you can use "@RRDFN@" in the RRDtool definitions
  # to pick up each filename. "@RRDIDX@" is an index (starting at 0) for each
  # file in the set. "@RRDPARAM@" contains the first word extracted from the
! # pattern of files (see e.g. "[memory]" how this is used). "@COLOR@" picks
! # a new color for each graph automatically.
  #
  # The "foo-multi" graph definitions are used by the "Metrics report"
  # utility. The have an FNPATTERN definition, but in this case you can NOT
--- 16,25 ----
  # When FNPATTERN is used, you can use "@RRDFN@" in the RRDtool definitions
  # to pick up each filename. "@RRDIDX@" is an index (starting at 0) for each
  # file in the set. "@RRDPARAM@" contains the first word extracted from the
! # pattern of files (see e.g. "[memory]" how this is used). "@RRDPARAM_SPACE"
! # is like "@RRDPARAM@", but also changes underscores to spaces (see e.g.
! # "[temperature]" how this is used for a sensor such as "CPU 0 Core 0").
! # "@COLOR@" picks a new color for each graph automatically.
  #
  # The "foo-multi" graph definitions are used by the "Metrics report"
  # utility. The have an FNPATTERN definition, but in this case you can NOT
***************
*** 959,982 ****
  	TITLE Temperature
  	YAXIS Celsius
  	DEF:p at RRDIDX@=@RRDFN@:temperature:AVERAGE
! 	LINE2:p at RRDIDX@#@COLOR@:@RRDPARAM@
  	GPRINT:p at RRDIDX@:LAST: \: %5.1lf (cur)
  	GPRINT:p at RRDIDX@:MAX: \: %5.1lf (max)
  	GPRINT:p at RRDIDX@:MIN: \: %5.1lf (min)
  	GPRINT:p at RRDIDX@:AVERAGE: \: %5.1lf (avg)\n
  
! # If you want your temperature graphs in Fahrenheit,
  # comment out the [temperature] section above, and 
  # uncomment this definition.
  #
  #[temperature]
  #	FNPATTERN ^temperature.(.+).rrd
  #	TITLE Temperature
! #	YAXIS Fahrenheit
! #	DEF:p at RRDIDX@=@RRDFN@:temperature:AVERAGE
! #	CDEF:tempf at RRDIDX@=9,5,/,p at RRDIDX@,*,32,+
! #	LINE2:tempf at RRDIDX@#@COLOR@:@RRDPARAM@
! #	GPRINT:tempf at RRDIDX@:LAST: \: %5.1lf (cur)
  #	GPRINT:tempf at RRDIDX@:MAX: \: %5.1lf (max)
  #	GPRINT:tempf at RRDIDX@:MIN: \: %5.1lf (min)
  #	GPRINT:tempf at RRDIDX@:AVERAGE: \: %5.1lf (avg)\n
--- 961,989 ----
  	TITLE Temperature
  	YAXIS Celsius
  	DEF:p at RRDIDX@=@RRDFN@:temperature:AVERAGE
! 	LINE2:p at RRDIDX@#@COLOR@:@RRDPARAM_SPACE@
  	GPRINT:p at RRDIDX@:LAST: \: %5.1lf (cur)
  	GPRINT:p at RRDIDX@:MAX: \: %5.1lf (max)
  	GPRINT:p at RRDIDX@:MIN: \: %5.1lf (min)
  	GPRINT:p at RRDIDX@:AVERAGE: \: %5.1lf (avg)\n
  
! # If you want your temperature graphs to also report Fahrenheit,
  # comment out the [temperature] section above, and 
  # uncomment this definition.
  #
  #[temperature]
  #	FNPATTERN ^temperature.(.+).rrd
  #	TITLE Temperature
! #	YAXIS Celsius (°C)
! #	DEF:tempc at RRDIDX@=@RRDFN@:temperature:AVERAGE
! #	CDEF:tempf at RRDIDX@=tempc at RRDIDX@,9,*,5,/,32,+
! #	LINE2:tempc at RRDIDX@#@COLOR@:@RRDPARAM_SPACE@
! #	COMMENT:\n
! #	GPRINT:tempc at RRDIDX@:LAST:  °C \: %5.1lf (cur)
! #	GPRINT:tempc at RRDIDX@:MAX: \: %5.1lf (max)
! #	GPRINT:tempc at RRDIDX@:MIN: \: %5.1lf (min)
! #	GPRINT:tempc at RRDIDX@:AVERAGE: \: %5.1lf (avg)\n
! #	GPRINT:tempf at RRDIDX@:LAST:  °F \: %5.1lf (cur)
  #	GPRINT:tempf at RRDIDX@:MAX: \: %5.1lf (max)
  #	GPRINT:tempf at RRDIDX@:MIN: \: %5.1lf (min)
  #	GPRINT:tempf at RRDIDX@:AVERAGE: \: %5.1lf (avg)\n
*** ./web/graphs.cfg.5.orig	2019-04-29 11:27:59.000000000 -0600
--- ./web/graphs.cfg.5	2023-09-25 10:08:47.338469109 -0600
***************
*** 34,41 ****
  When FNPATTERN is used, you can use "@RRDFN@" in the RRDtool definitions
  to pick up each filename. "@RRDIDX@" is an index (starting at 0) for each
  file in the set. "@RRDPARAM@" contains the first word extracted from the
! pattern of files (see e.g. "[memory]" how this is used). "@COLOR@" picks
! a new color for each graph automatically.
  
  The remainder of the lines in each definition are passed directly to the
  RRDtool rrd_graph() routine.
--- 34,43 ----
  When FNPATTERN is used, you can use "@RRDFN@" in the RRDtool definitions
  to pick up each filename. "@RRDIDX@" is an index (starting at 0) for each
  file in the set. "@RRDPARAM@" contains the first word extracted from the
! pattern of files (see e.g. "[memory]" how this is used). "@RRDPARAM_SPACE"
! is like "@RRDPARAM@", but also changes underscores to spaces (see e.g.
! "[temperature]" how this is used for a sensor such as "CPU 0 Core 0").
! "@COLOR@" picks a new color for each graph automatically.
  
  The remainder of the lines in each definition are passed directly to the
  RRDtool rrd_graph() routine.
***************
*** 102,108 ****
  case you can setup the TITLE definition so that it runs a custom
  script to determine the graph title. Like this:
  .sp
! 	TITLE exec:/usr/local/bin/graphitle
  .sp
  The \fB/usr/local/bin/graphtitle\fR command is then called with 
  the hostname, the graphtype, the period string, and all of the 
--- 104,110 ----
  case you can setup the TITLE definition so that it runs a custom
  script to determine the graph title. Like this:
  .sp
! 	TITLE exec:/usr/local/bin/graphtitle
  .sp
  The \fB/usr/local/bin/graphtitle\fR command is then called with 
  the hostname, the graphtype, the period string, and all of the 
*** ./docs/manpages/man5/graphs.cfg.5.html.orig	2015-11-02 09:16:57.000000000 -0700
--- ./docs/manpages/man5/graphs.cfg.5.html	2023-09-25 10:11:41.750559450 -0600
***************
*** 51,58 ****
  When FNPATTERN is used, you can use "@RRDFN@" in the RRDtool definitions
  to pick up each filename. "@RRDIDX@" is an index (starting at 0) for each
  file in the set. "@RRDPARAM@" contains the first word extracted from the
! pattern of files (see e.g. "[memory]" how this is used). "@COLOR@" picks
! a new color for each graph automatically.
  <P>
  The remainder of the lines in each definition are passed directly to the
  RRDtool rrd_graph() routine.
--- 51,60 ----
  When FNPATTERN is used, you can use "@RRDFN@" in the RRDtool definitions
  to pick up each filename. "@RRDIDX@" is an index (starting at 0) for each
  file in the set. "@RRDPARAM@" contains the first word extracted from the
! pattern of files (see e.g. "[memory]" how this is used). "@RRDPARAM_SPACE"
! is like "@RRDPARAM@", but also changes underscores to spaces (see e.g.
! "[temperature]" how this is used for a sensor such as "CPU 0 Core 0").
! "@COLOR@" picks a new color for each graph automatically.
  <P>
  The remainder of the lines in each definition are passed directly to the
  RRDtool rrd_graph() routine.
***************
*** 139,145 ****
  case you can setup the TITLE definition so that it runs a custom
  script to determine the graph title. Like this:
  <P>
! <TT>       </TT>TITLE exec:/usr/local/bin/graphitle<BR>
  <P>
  The <B>/usr/local/bin/graphtitle</B> command is then called with 
  the hostname, the graphtype, the period string, and all of the 
--- 141,147 ----
  case you can setup the TITLE definition so that it runs a custom
  script to determine the graph title. Like this:
  <P>
! <TT>       </TT>TITLE exec:/usr/local/bin/graphtitle<BR>
  <P>
  The <B>/usr/local/bin/graphtitle</B> command is then called with 
  the hostname, the graphtype, the period string, and all of the 
-------------- next part --------------
*** ./client/logfetch.c.orig	2019-04-09 03:35:17.000000000 -0600
--- ./client/logfetch.c	2023-09-28 11:07:30.156167454 -0600
***************
*** 326,333 ****
--- 326,341 ----
  
  			dbgprintf(" - Last position was %u, found curpos location at %u in current buffer.\n", logdef->lastpos[1], bytesin);
  			t = strdup(fillpos);	/* need shuffle about to insert before this line */
+ #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
+ 			#pragma GCC diagnostic push
+ 			#pragma GCC diagnostic ignored "-Wstringop-truncation"
+ 			#pragma GCC diagnostic ignored "-Wstringop-overflow"
+ #endif  // __GNUC__
  			strncpy(fillpos, curpostxt, strlen(curpostxt));		/* add in the CURRENT + \n */
  			strncpy(fillpos+strlen(curpostxt), t, strlen(t));	/* add in whatever this line originally was */
+ #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
+ 			#pragma GCC diagnostic pop
+ #endif  // __GNUC__
  			*(fillpos+strlen(curpostxt)+strlen(t)) = '\0';		/* and terminate it */
  			xfree(t);						/* free temp */
  			curpos = fillpos;					/* leave curpos to the beginning of the CURRENT flag */
***************
*** 496,506 ****
--- 504,522 ----
  		       for (i = 0, pos = replacement; i < triggerptrs_count; i++) {
  		               dbgprintf("Copying buffer content for trigger %i.\n", (i + 1));
  
+ #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
+ 				#pragma GCC diagnostic push
+ 				#pragma GCC diagnostic ignored "-Wstringop-truncation"
+ 				#pragma GCC diagnostic ignored "-Wstringop-overflow"
+ #endif  // __GNUC__
  		               strncpy(pos, skiptxt, strlen(skiptxt));
  		               pos += strlen(skiptxt);
  
  		               size = strlen(triggerptrs[i][0]) - strlen(triggerptrs[i][1]);
  		               strncpy(pos, triggerptrs[i][0], size);
+ #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
+ 				#pragma GCC diagnostic pop
+ #endif  // __GNUC__
  		               pos += size;
  		       }
  
***************
*** 533,539 ****
--- 549,563 ----
  
  				if (finalstartptr > lasttriggerptr) {
  					/* Add the final skip for completeness */
+ #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
+ 					#pragma GCC diagnostic push
+ 					#pragma GCC diagnostic ignored "-Wstringop-truncation"
+ 					#pragma GCC diagnostic ignored "-Wstringop-overflow"
+ #endif  // __GNUC__
  					strncpy(pos, skiptxt, strlen(skiptxt));
+ #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
+ 					#pragma GCC diagnostic pop
+ #endif  // __GNUC__
  					pos += strlen(skiptxt);
  				}
  
*** ./common/xymonlaunch.c.orig	2016-02-23 08:25:14.000000000 -0700
--- ./common/xymonlaunch.c	2023-09-27 21:14:30.421143986 -0600
***************
*** 200,206 ****
--- 200,213 ----
  					char *newcmd = xcalloc(1, l1+l2+1);
  
  					strncpy(newcmd,curtask->cmd,l1);
+ #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
+ 					#pragma GCC diagnostic push
+ 					#pragma GCC diagnostic ignored "-Wstringop-truncation"
+ #endif  // __GNUC__
  					strncpy(newcmd+l1,p,l2);
+ #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
+ 					#pragma GCC diagnostic pop
+ #endif  // __GNUC__
  					newcmd[l1]=' '; /* this also overwrites the + */
  
  					/* free and assign new */
*** ./lib/acknowledgementslog.c.orig	2019-08-30 15:27:45.000000000 -0600
--- ./lib/acknowledgementslog.c	2023-09-27 16:33:32.369606977 -0600
***************
*** 222,233 ****
  		    p = strrchr(host, '.');
  		    if (p) {
                          *p = '\0';
! 			strncpy(svc,p+1,  sizeof(svc));
                      }
  		    /* Xymon uses \n in the ack message, for the "acked by" data. Cut it off. */
  		    p = strstr(message, "\\nAcked by:");
  		    if (p) {
! 			strncpy(recipient,p+12, sizeof(recipient));
                          *(p-1) = '\0';
  		    }
  		    else {
--- 222,235 ----
  		    p = strrchr(host, '.');
  		    if (p) {
                          *p = '\0';
! 			strncpy(svc, p+1, sizeof(svc));
! 			svc[sizeof(svc)-1] = '\0'; /* Make sure it is null terminated */
                      }
  		    /* Xymon uses \n in the ack message, for the "acked by" data. Cut it off. */
  		    p = strstr(message, "\\nAcked by:");
  		    if (p) {
! 			strncpy(recipient, p+12, sizeof(recipient));
! 			recipient[sizeof(recipient)-1] = '\0'; /* Make sure it is null terminated */
                          *(p-1) = '\0';
  		    }
  		    else {
*** ./lib/links.c.orig	2019-08-30 15:27:45.000000000 -0600
--- ./lib/links.c	2023-09-27 13:48:13.252415194 -0600
***************
*** 143,148 ****
--- 143,149 ----
  	if (xgetenv("XYMONHELPDIR")) strcpy(dirname, xgetenv("XYMONHELPDIR"));
  	else {
  		strncpy(dirname, xgetenv("XYMONNOTESDIR"), sizeof(dirname));
+ 		dirname[sizeof(dirname)-1] = '\0'; /* Make sure it is null terminated */
  		p = strrchr(dirname, '/'); *p = '\0'; strncat(dirname, "/help", (sizeof(dirname) - strlen(dirname)));
  	}
  	load_links(dirname, helpskin, 0);
*** ./lib/loadalerts.c.orig	2019-08-30 15:27:45.000000000 -0600
--- ./lib/loadalerts.c	2023-09-28 10:07:48.794876921 -0600
***************
*** 199,205 ****
  	rule_t *currule = NULL;
  	recip_t *currcp = NULL, *rcptail = NULL;
  
! 	if (configfn) strncpy(fn, configfn, sizeof(fn)); else snprintf(fn, sizeof(fn), "%s/etc/alerts.cfg", xgetenv("XYMONHOME"));
  
  	/* First check if there were no modifications at all */
  	if (configfiles) {
--- 199,210 ----
  	rule_t *currule = NULL;
  	recip_t *currcp = NULL, *rcptail = NULL;
  
! 	if (configfn) {
! 		strncpy(fn, configfn, sizeof(fn));
! 		fn[sizeof(fn)-1] = '\0'; /* Make sure it is null terminated */
! 	}
! 	else
! 		snprintf(fn, sizeof(fn), "%s/etc/alerts.cfg", xgetenv("XYMONHOME"));
  
  	/* First check if there were no modifications at all */
  	if (configfiles) {
***************
*** 853,859 ****
--- 858,872 ----
  
  		if ((alert->groups && (*(alert->groups)))) {
  			SBUF_MALLOC(grouplist, strlen(alert->groups));
+ #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
+ 			#pragma GCC diagnostic push
+ 			#pragma GCC diagnostic ignored "-Wstringop-truncation"
+ 			#pragma GCC diagnostic ignored "-Wstringop-overflow"
+ #endif  // __GNUC__
  			strncpy(grouplist, alert->groups, grouplist_buflen);
+ #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
+ 			#pragma GCC diagnostic pop
+ #endif  // __GNUC__
  		}
  
  		if (crit->groupspec) {
***************
*** 1202,1212 ****
--- 1215,1232 ----
  		if (recip->method == M_IGNORE) {
  			recip->recipient = "-- ignored --";
  		}
+ #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
+ 		#pragma GCC diagnostic push
+ 		#pragma GCC diagnostic ignored "-Wstringop-overflow"
+ #endif  // __GNUC__
  		if (recip->noalerts) { if (*codes) strncat(codes, ",A", codes_bytesleft); else strncat(codes, "-A", codes_bytesleft); codes_bytesleft -= 2; }
  		if (recovered && !recip->noalerts) { if (*codes) strncat(codes, ",R", codes_bytesleft); else strncat(codes, "R", codes_bytesleft); codes_bytesleft -= 2; }
  		if (notice) { if (*codes) strncat(codes, ",N", codes_bytesleft); else strncat(codes, "N", codes_bytesleft); codes_bytesleft -= 2; }
  		if (recip->stoprule) { if (*codes) strncat(codes, ",S", codes_bytesleft); else strncat(codes, "S", codes_bytesleft); codes_bytesleft -= 2; }
  		if (recip->unmatchedonly) { if (*codes) strncat(codes, ",U", codes_bytesleft); else strncat(codes, "U", codes_bytesleft); codes_bytesleft -= 2; }
+ #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
+ 		#pragma GCC diagnostic pop
+ #endif  // __GNUC__
  
  		if (strlen(codes) == 0)
  			snprintf(l, sizeof(l), "<td><font %s>%s</font></td>", fontspec, recip->recipient);
*** ./lib/loadhosts_file.c.orig	2019-08-30 15:27:45.000000000 -0600
--- ./lib/loadhosts_file.c	2023-09-27 13:04:36.131494593 -0600
***************
*** 114,119 ****
--- 114,120 ----
  	if (contentbuffer) freestrbuffer(contentbuffer);
  	contentbuffer = convertstrbuffer(fdata, 0);
  	strncpy(contentmd5, fhash, sizeof(contentmd5));
+ 	contentmd5[sizeof(contentmd5)-1] = '\0'; /* Make sure it is null terminated */
  
  	return 0;
  }
*** ./lib/locator.c.orig	2019-08-30 15:27:45.000000000 -0600
--- ./lib/locator.c	2023-09-27 13:50:15.713862044 -0600
***************
*** 207,212 ****
--- 207,213 ----
  	int res;
  
  	strncpy(pingbuf, cmd, sizeof(pingbuf));
+ 	pingbuf[sizeof(pingbuf)-1] = '\0'; /* Make sure it is null terminated */
  	res = call_locator(pingbuf, sizeof(pingbuf));
  
  	return (res == 0) ? pingbuf : NULL;
*** ./lib/misc.c.orig	2019-08-30 17:03:11.000000000 -0600
--- ./lib/misc.c	2023-09-28 10:01:13.330317497 -0600
***************
*** 162,167 ****
--- 162,171 ----
  	STATIC_SBUF_DEFINE(s);
  	char *p;
  
+ #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
+ 	#pragma GCC diagnostic push
+ 	#pragma GCC diagnostic ignored "-Wstringop-overflow"
+ #endif  // __GNUC__
  	if (s == NULL) {
  		SBUF_MALLOC(s, strlen(hostname)+1);
  		strncpy(s, hostname, s_buflen);
***************
*** 174,179 ****
--- 178,186 ----
  	else {
  		strncpy(s, hostname, s_buflen);
  	}
+ #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
+ 	#pragma GCC diagnostic pop
+ #endif  // __GNUC__
  
  	for (p = strchr(s, '.'); (p); p = strchr(s, '.')) *p = ',';
  	return s;
*** ./lib/sig.c.orig	2019-08-30 20:05:50.000000000 -0600
--- ./lib/sig.c	2023-09-27 13:51:32.144765055 -0600
***************
*** 91,98 ****
--- 91,101 ----
  	 * advance.
  	 */
  	strncpy(signal_xymoncmd, (getenv("XYMON") ? getenv("XYMON") : "xymon"), sizeof(signal_xymoncmd));
+ 	signal_xymoncmd[sizeof(signal_xymoncmd)-1] = '\0'; /* Make sure it is null terminated */
  	strncpy(signal_xymondserver, (getenv("XYMSRV") ? getenv("XYMSRV") : "0.0.0.0"), sizeof(signal_xymondserver));
+ 	signal_xymondserver[sizeof(signal_xymondserver)-1] = '\0'; /* Make sure it is null terminated */
  	strncpy(signal_tmpdir, (getenv("XYMONTMP") ? getenv("XYMONTMP") : "/tmp"), sizeof(signal_tmpdir));
+ 	signal_tmpdir[sizeof(signal_tmpdir)-1] = '\0'; /* Make sure it is null terminated */
  	snprintf(signal_msg, sizeof(signal_msg), "status+1d/group:signal %s.xymond red %s program crashed\n\nFatal signal caught!\n",
  		(getenv("MACHINE") ? getenv("MACHINE") : (getenv("HOSTNAME") ? getenv("HOSTNAME") : "localhost") ), programname);
  
*** ./lib/stackio.c.orig	2019-09-02 17:06:47.000000000 -0600
--- ./lib/stackio.c	2023-09-27 16:26:59.714967865 -0600
***************
*** 203,212 ****
  		stackfd_mode = strdup(mode);
  
  		strncpy(stackfd_filename, filename, sizeof(stackfd_filename));
  	}
  	else {
! 		if (*filename == '/')
  			strncpy(stackfd_filename, filename, sizeof(stackfd_filename));
  		else
  			snprintf(stackfd_filename, sizeof(stackfd_filename), "%s/%s", stackfd_base, filename);
  	}
--- 203,215 ----
  		stackfd_mode = strdup(mode);
  
  		strncpy(stackfd_filename, filename, sizeof(stackfd_filename));
+ 		stackfd_filename[sizeof(stackfd_filename)-1] = '\0'; /* Make sure it is null terminated */
  	}
  	else {
! 		if (*filename == '/') {
  			strncpy(stackfd_filename, filename, sizeof(stackfd_filename));
+ 			stackfd_filename[sizeof(stackfd_filename)-1] = '\0'; /* Make sure it is null terminated */
+ 		}
  		else
  			snprintf(stackfd_filename, sizeof(stackfd_filename), "%s/%s", stackfd_base, filename);
  	}
***************
*** 331,337 ****
  	int fnsz = 0;
  	int i;
  
! 	if (*dirname == '/') strncpy(dirfn, dirname, sizeof(dirfn)); else snprintf(dirfn, sizeof(dirfn), "%s/%s", stackfd_base, dirname);
  
  	if ((dirfd = opendir(dirfn)) == NULL) {
  		if (!is_optional) errprintf("WARNING: Cannot open directory %s\n", dirfn);
--- 334,345 ----
  	int fnsz = 0;
  	int i;
  
! 	if (*dirname == '/') {
! 		strncpy(dirfn, dirname, sizeof(dirfn));
! 		dirfn[sizeof(dirfn)-1] = '\0'; /* Make sure it is null terminated */
! 	}
! 	else
! 		snprintf(dirfn, sizeof(dirfn), "%s/%s", stackfd_base, dirname);
  
  	if ((dirfd = opendir(dirfn)) == NULL) {
  		if (!is_optional) errprintf("WARNING: Cannot open directory %s\n", dirfn);
*** ./lib/stdopt.c.orig	2016-03-02 19:05:55.000000000 -0700
--- ./lib/stdopt.c	2023-09-27 09:28:00.642949439 -0600
***************
*** 14,19 ****
--- 14,20 ----
  static char rcsid[] = "$Id: stdopt.c 7008 2012-06-02 09:22:02Z storner $";
  
  #include <string.h>
+ #include <stdlib.h>
  #include <stdio.h>
  #include <libgen.h>
  #include <limits.h>
*** ./lib/tcplib.c.orig	2019-04-10 15:33:08.000000000 -0600
--- ./lib/tcplib.c	2023-09-27 10:24:39.049167773 -0600
***************
*** 408,414 ****
  
  		e = X509_NAME_get_entry(subj, cnpos);
  		if (e) d = X509_NAME_ENTRY_get_data(e);
! 		if (d) cn = strdup(ASN1_STRING_data(d));
  	}
  
  	if (peercert) X509_free(peercert);
--- 408,414 ----
  
  		e = X509_NAME_get_entry(subj, cnpos);
  		if (e) d = X509_NAME_ENTRY_get_data(e);
! 		if (d) cn = strdup(ASN1_STRING_get0_data(d));
  	}
  
  	if (peercert) X509_free(peercert);
*** ./lib/xymonrrd.c.orig	2019-08-30 21:22:45.000000000 -0600
--- ./lib/xymonrrd.c	2023-09-28 10:02:00.270858688 -0600
***************
*** 87,93 ****
--- 87,100 ----
  	/* Get the tcp services, and count how many there are */
  	services = init_tcp_services();
  	SBUF_MALLOC(tcptests, strlen(services)+1);
+ #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
+ 	#pragma GCC diagnostic push
+ 	#pragma GCC diagnostic ignored "-Wstringop-overflow"
+ #endif  // __GNUC__
  	strncpy(tcptests, services, tcptests_buflen);
+ #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
+ 	#pragma GCC diagnostic pop
+ #endif  // __GNUC__
  	count = 0; p = strtok(tcptests, " "); while (p) { count++; p = strtok(NULL, " "); }
  	strncpy(tcptests, services, tcptests_buflen);
  
***************
*** 242,247 ****
--- 249,255 ----
  	}
  	else {
  		strncpy(rrdservicename, graphdef->xymonrrdname, sizeof(rrdservicename));
+ 		rrdservicename[sizeof(rrdservicename)-1] = '\0'; /* Make sure it is null terminated */
  	}
  
  	SBUF_MALLOC(svcurl, 
*** ./web/confreport.c.orig	2019-08-30 15:27:45.000000000 -0600
--- ./web/confreport.c	2023-09-27 13:53:26.926121167 -0600
***************
*** 124,129 ****
--- 124,130 ----
  	while ((de = readdir(d)) != NULL) {
  		if (strncmp(de->d_name, "disk,", 5) == 0) {
  			strncpy(fn, de->d_name + 4, sizeof(fn));
+ 			fn[sizeof(fn)-1] = '\0'; /* Make sure it is null terminated */
  			p = strstr(fn, ".rrd"); if (!p) continue;
  			*p = '\0';
  			p = fn; while ((p = strchr(p, ',')) != NULL) *p = '/';
*** ./web/svcstatus.c.orig	2019-09-02 12:12:23.000000000 -0600
--- ./web/svcstatus.c	2023-09-28 09:59:49.719353523 -0600
***************
*** 156,162 ****
--- 156,169 ----
  
  		req = getenv("SCRIPT_NAME");
  		SBUF_MALLOC(clienturi, strlen(req) + 10 + strlen(hostquoted));
+ #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
+ 		#pragma GCC diagnostic push
+ 		#pragma GCC diagnostic ignored "-Wstringop-overflow"
+ #endif  // __GNUC__
  		strncpy(clienturi, req, clienturi_buflen);
+ #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
+ 		#pragma GCC diagnostic pop
+ #endif  // __GNUC__
  		p = strchr(clienturi, '?'); if (p) *p = '\0'; else p = clienturi + strlen(clienturi);
  		snprintf(p, (clienturi_buflen - (clienturi - p)), "?CLIENT=%s", hostquoted);
  	}
*** ./xymond/client/darwin.c.orig	2016-02-02 13:15:30.000000000 -0700
--- ./xymond/client/darwin.c	2023-09-27 10:01:11.854170667 -0600
***************
*** 81,93 ****
  
  		if (pgsize != -1) {
  			p = strstr(meminfostr, "\nPages free:");
! 			if (p) p = strchr(p, ':'); if (p) pagesfree = atol(p+1);
  			p = strstr(meminfostr, "\nPages active:");
! 			if (p) p = strchr(p, ':'); if (p) pagesactive = atol(p+1);
  			p = strstr(meminfostr, "\nPages inactive:");
! 			if (p) p = strchr(p, ':'); if (p) pagesinactive = atol(p+1);
  			p = strstr(meminfostr, "\nPages wired down:");
! 			if (p) p = strchr(p, ':'); if (p) pageswireddown = atol(p+1);
  
  			if ((pagesfree >= 0) && (pagesactive >= 0) && (pagesinactive >= 0) && (pageswireddown >= 0)) {
  				unsigned long memphystotal, memphysused;
--- 81,97 ----
  
  		if (pgsize != -1) {
  			p = strstr(meminfostr, "\nPages free:");
! 			if (p) p = strchr(p, ':');
! 			if (p) pagesfree = atol(p+1);
  			p = strstr(meminfostr, "\nPages active:");
! 			if (p) p = strchr(p, ':');
! 			if (p) pagesactive = atol(p+1);
  			p = strstr(meminfostr, "\nPages inactive:");
! 			if (p) p = strchr(p, ':');
! 			if (p) pagesinactive = atol(p+1);
  			p = strstr(meminfostr, "\nPages wired down:");
! 			if (p) p = strchr(p, ':');
! 			if (p) pageswireddown = atol(p+1);
  
  			if ((pagesfree >= 0) && (pagesactive >= 0) && (pagesinactive >= 0) && (pageswireddown >= 0)) {
  				unsigned long memphystotal, memphysused;
*** ./xymond/client/zvse.c.orig	2015-03-21 09:00:40.000000000 -0600
--- ./xymond/client/zvse.c	2023-09-27 21:02:28.692465298 -0600
***************
*** 532,537 ****
--- 532,538 ----
                  q = strchr(jinfo, '-');              /* Check if jobname passed  */
                  if (q) {
                          strncpy(pid, jinfo, 2);          /*  Copy partition ID  */
+ 			pid[sizeof(pid)-1] = '\0';       /*  Make sure it is null terminated */
                          q++;                             /*  Increment pointer  */
  			strcpy(jobname,q);		 /*  Copy jobname       */
                          }
*** ./xymond/combostatus.c.orig	2019-09-03 15:48:43.000000000 -0600
--- ./xymond/combostatus.c	2023-09-28 09:58:54.358715254 -0600
***************
*** 351,357 ****
--- 351,364 ----
  	result = compute(expr, &error);
  
  	if (error) {
+ #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
+ 		#pragma GCC diagnostic push
+ 		#pragma GCC diagnostic ignored "-Wformat-overflow"
+ #endif  // __GNUC__
  		sprintf(errtext, "compute(%s) returned error %d\n", expr, error);
+ #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
+ 		#pragma GCC diagnostic pop
+ #endif  // __GNUC__
  		if (*errbuf == NULL) {
  			*errbuf = strdup(errtext);
  		}
*** ./xymond/do_rrd.c.orig	2016-01-23 13:53:59.000000000 -0700
--- ./xymond/do_rrd.c	2023-09-27 20:31:22.540025070 -0600
***************
*** 292,298 ****
--- 292,305 ----
  	}
  
  	/* Watch out here - "rrdfn" may be very large. */
+ #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
+ 	#pragma GCC diagnostic push
+ 	#pragma GCC diagnostic ignored "-Wformat-truncation"
+ #endif  // __GNUC__
  	snprintf(filedir, sizeof(filedir)-1, "%s/%s/%s", rrddir, hostname, rrdfn);
+ #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
+ 	#pragma GCC diagnostic pop
+ #endif  // __GNUC__
  	filedir[sizeof(filedir)-1] = '\0'; /* Make sure it is null terminated */
  
  	/* 
***************
*** 603,609 ****
--- 610,623 ----
  	unsigned long steptime, dscount;
  	rrd_value_t *rrddata;
  
+ #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
+ 	#pragma GCC diagnostic push
+ 	#pragma GCC diagnostic ignored "-Wformat-truncation"
+ #endif  // __GNUC__
  	snprintf(filedir, sizeof(filedir)-1, "%s/%s/%s", rrddir, hostname, rrdfn);
+ #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
+ 	#pragma GCC diagnostic pop
+ #endif  // __GNUC__
  	filedir[sizeof(filedir)-1] = '\0';
  	if (stat(filedir, &st) == -1) return 0;
  
*** ./xymond/rrd/do_netstat.c.orig	2019-03-21 13:25:19.000000000 -0600
--- ./xymond/rrd/do_netstat.c	2023-09-27 10:08:24.318779636 -0600
***************
*** 415,421 ****
  			while (ln && (ln > msg) && (*ln != '\n')) ln--;
  			if (ln) {
  				int numlen;
! 				if (*ln == '\n') ln++; ln += strspn(ln, " \t");
  				numlen = strspn(ln, "0123456789");
  				*outp = ':'; outp++; memcpy(outp, ln, numlen); outp += numlen; *outp = '\0';
  				gotany = gotval = 1;
--- 415,422 ----
  			while (ln && (ln > msg) && (*ln != '\n')) ln--;
  			if (ln) {
  				int numlen;
! 				if (*ln == '\n') ln++;
! 				ln += strspn(ln, " \t");
  				numlen = strspn(ln, "0123456789");
  				*outp = ':'; outp++; memcpy(outp, ln, numlen); outp += numlen; *outp = '\0';
  				gotany = gotval = 1;
*** ./xymond/trimhistory.c.orig	2016-01-22 16:34:09.000000000 -0700
--- ./xymond/trimhistory.c	2023-09-28 09:58:08.858190666 -0600
***************
*** 333,339 ****
--- 333,346 ----
  
  					ltime = logtime(lent->d_name);
  					if ((ltime > 0) && (ltime < cutoff)) {
+ #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
+ 						#pragma GCC diagnostic push
+ 						#pragma GCC diagnostic ignored "-Wformat-overflow"
+ #endif  // __GNUC__
  						sprintf(fn2, "%s/%s", fn1, lent->d_name);
+ #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
+ 						#pragma GCC diagnostic pop
+ #endif  // __GNUC__
  						if (unlink(fn2) == -1) {
  							errprintf("Failed to unlink %s: %s\n", fn2, strerror(errno));
  						}
*** ./xymond/xymond_client.c.orig	2019-09-02 20:28:31.000000000 -0600
--- ./xymond/xymond_client.c	2023-09-27 10:05:54.207179830 -0600
***************
*** 1927,1933 ****
  		oldhinfo = hinfo;
  
  		printf("Test (cpu, mem, disk, proc, log, port): "); fflush(stdout); 
! 		if (!fgets(s, sizeof(s), stdin)) return; clean_instr(s);
  		if (strcmp(s, "cpu") == 0) {
  			float loadyellow, loadred;
  			int recentlimit, ancientlimit, uptimecolor;
--- 1927,1934 ----
  		oldhinfo = hinfo;
  
  		printf("Test (cpu, mem, disk, proc, log, port): "); fflush(stdout); 
! 		if (!fgets(s, sizeof(s), stdin)) return;
! 		clean_instr(s);
  		if (strcmp(s, "cpu") == 0) {
  			float loadyellow, loadred;
  			int recentlimit, ancientlimit, uptimecolor;
***************
*** 1955,1961 ****
  			char *groups;
  
  			printf("Filesystem: "); fflush(stdout);
! 			if (!fgets(s, sizeof(s), stdin)) return; clean_instr(s);
  			get_disk_thresholds(hinfo, clientclass, s, &warnlevel, &paniclevel, 
  						   &abswarn, &abspanic, &ignored, &groups);
  			if (ignored) 
--- 1956,1963 ----
  			char *groups;
  
  			printf("Filesystem: "); fflush(stdout);
! 			if (!fgets(s, sizeof(s), stdin)) return;
! 			clean_instr(s);
  			get_disk_thresholds(hinfo, clientclass, s, &warnlevel, &paniclevel, 
  						   &abswarn, &abspanic, &ignored, &groups);
  			if (ignored) 
***************
*** 1980,1986 ****
  			printf("To read 'ps' data from a file, enter '@FILENAME' at the prompt\n");
  			do {
  				printf("ps command string: "); fflush(stdout);
! 				if (!fgets(s, sizeof(s), stdin)) return; clean_instr(s);
  				if (*s == '@') {
  					fd = fopen(s+1, "r");
  					while (fd && fgets(s, sizeof(s), fd)) {
--- 1982,1989 ----
  			printf("To read 'ps' data from a file, enter '@FILENAME' at the prompt\n");
  			do {
  				printf("ps command string: "); fflush(stdout);
! 				if (!fgets(s, sizeof(s), stdin)) return;
! 				clean_instr(s);
  				if (*s == '@') {
  					fd = fopen(s+1, "r");
  					while (fd && fgets(s, sizeof(s), fd)) {
***************
*** 2006,2012 ****
  			int logcolor;
  
  			printf("log filename: "); fflush(stdout);
! 			if (!fgets(s, sizeof(s), stdin)) return; clean_instr(s);
  			sectname = (char *)malloc(strlen(s) + 20);
  			sprintf(sectname, "msgs:%s", s);
  
--- 2009,2016 ----
  			int logcolor;
  
  			printf("log filename: "); fflush(stdout);
! 			if (!fgets(s, sizeof(s), stdin)) return;
! 			clean_instr(s);
  			sectname = (char *)malloc(strlen(s) + 20);
  			sprintf(sectname, "msgs:%s", s);
  
***************
*** 2017,2023 ****
  			printf("To read log data from a file, enter '@FILENAME' at the prompt\n");
  			do {
  				printf("log line: "); fflush(stdout);
! 				if (!fgets(s, sizeof(s), stdin)) return; clean_instr(s);
  				if (*s == '@') {
  					fd = fopen(s+1, "r");
  					while (fd && fgets(s, sizeof(s), fd)) {
--- 2021,2028 ----
  			printf("To read log data from a file, enter '@FILENAME' at the prompt\n");
  			do {
  				printf("log line: "); fflush(stdout);
! 				if (!fgets(s, sizeof(s), stdin)) return;
! 				clean_instr(s);
  				if (*s == '@') {
  					fd = fopen(s+1, "r");
  					while (fd && fgets(s, sizeof(s), fd)) {
***************
*** 2054,2066 ****
  
  			printf("Need to know netstat columns for 'Local address', 'Remote address' and 'State'\n");
  			printf("Enter columns [%d %d %d]: ", localcol, remotecol, statecol); fflush(stdout);
! 			if (!fgets(s, sizeof(s), stdin)) return; clean_instr(s);
  			if (*s) sscanf(s, "%d %d %d", &localcol, &remotecol, &statecol);
  
  			printf("To read 'netstat' data from a file, enter '@FILENAME' at the prompt\n");
  			do {
  				printf("netstat line: "); fflush(stdout);
! 				if (!fgets(s, sizeof(s), stdin)) return; clean_instr(s);
  				if (*s == '@') {
  					FILE *fd;
  
--- 2059,2073 ----
  
  			printf("Need to know netstat columns for 'Local address', 'Remote address' and 'State'\n");
  			printf("Enter columns [%d %d %d]: ", localcol, remotecol, statecol); fflush(stdout);
! 			if (!fgets(s, sizeof(s), stdin)) return;
! 			clean_instr(s);
  			if (*s) sscanf(s, "%d %d %d", &localcol, &remotecol, &statecol);
  
  			printf("To read 'netstat' data from a file, enter '@FILENAME' at the prompt\n");
  			do {
  				printf("netstat line: "); fflush(stdout);
! 				if (!fgets(s, sizeof(s), stdin)) return;
! 				clean_instr(s);
  				if (*s == '@') {
  					FILE *fd;
  
*** ./xymond/xymond.c.orig	2019-09-23 17:16:14.000000000 -0600
--- ./xymond/xymond.c	2023-09-27 10:13:46.622214568 -0600
***************
*** 2031,2065 ****
  	}
  	else dbgprintf(" - parse of modify statement; source=%s, type=%d, validnum=%d, expires=%d, cause=%s\n", sourcename, type, validity, validtime, cause);
  
! 		/* Got all tokens - find the modifier, if this is just an update */
! 		n = strlen(sourcename);
! 		for (mwalk = log->modifiers; (mwalk && strncmp(mwalk->source, sourcename, n)); mwalk = mwalk->next);
! 
! 			if (!mwalk) {
! 				/* New modifier record */
! 				dbgprintf(" - creating new modify record for '%s'\n", sourcename);
! 				isnewcause = 1;
! 				mwalk = (modifier_t *)calloc(1, sizeof(modifier_t));
! 				mwalk->source = strdup(sourcename);
! 				mwalk->next = log->modifiers;
! 				log->modifiers = mwalk;
! 			}
! 
! 			mwalk->color = color;
! 			mwalk->validtime = validtime;	/* 0 if unset */
! 			mwalk->valid = (validity ? validity : DEFAULT_MODIFY_VALIDITY); /* if duration ONLY, this will be < 0 */
! 			mwalk->type = type;
! 			if (mwalk->cause) xfree(mwalk->cause);
! 			mwalk->cause = (char *)malloc(strlen(cause) + 10); /* 10 for maxlength of colorname + markers */
! 			sprintf(mwalk->cause, "&%s %s\n", colnames[mwalk->color], cause);
  
! 		
! 		/*
! 		 * Modify messages always get sent to handle_status for evaluation.
! 		 * It's possible a status change will result, or just a new status message.
! 		 */
! 			handle_status(log->message, log->sender,  
! 				log->host->hostname, log->test->name, log->grouplist, log, log->color, NULL, (isnewcause ? 2 : 1) );
  
  	dbgprintf("<-handle_modify\n");
  }
--- 2031,2064 ----
  	}
  	else dbgprintf(" - parse of modify statement; source=%s, type=%d, validnum=%d, expires=%d, cause=%s\n", sourcename, type, validity, validtime, cause);
  
! 	/* Got all tokens - find the modifier, if this is just an update */
! 	n = strlen(sourcename);
! 	for (mwalk = log->modifiers; (mwalk && strncmp(mwalk->source, sourcename, n)); mwalk = mwalk->next);
! 
! 	if (!mwalk) {
! 		/* New modifier record */
! 		dbgprintf(" - creating new modify record for '%s'\n", sourcename);
! 		isnewcause = 1;
! 		mwalk = (modifier_t *)calloc(1, sizeof(modifier_t));
! 		mwalk->source = strdup(sourcename);
! 		mwalk->next = log->modifiers;
! 		log->modifiers = mwalk;
! 	}
! 
! 	mwalk->color = color;
! 	mwalk->validtime = validtime;	/* 0 if unset */
! 	mwalk->valid = (validity ? validity : DEFAULT_MODIFY_VALIDITY); /* if duration ONLY, this will be < 0 */
! 	mwalk->type = type;
! 	if (mwalk->cause) xfree(mwalk->cause);
! 	mwalk->cause = (char *)malloc(strlen(cause) + 10); /* 10 for maxlength of colorname + markers */
! 	sprintf(mwalk->cause, "&%s %s\n", colnames[mwalk->color], cause);
  
! 	/*
! 	 * Modify messages always get sent to handle_status for evaluation.
! 	 * It's possible a status change will result, or just a new status message.
! 	 */
! 	handle_status(log->message, log->sender,  
! 		log->host->hostname, log->test->name, log->grouplist, log, log->color, NULL, (isnewcause ? 2 : 1) );
  
  	dbgprintf("<-handle_modify\n");
  }
***************
*** 4926,4932 ****
  		else if (strncmp(line1, "clientconfig", 12) == 0) process_clientmsg = 0;
  
  		p = strtok(line1, " \t"); /* Skip the client.* keyword */
! 		if (p) collectorid = strchr(p, '/'); if (collectorid) collectorid++;
  		if (p) hostname = strtok(NULL, " \t"); /* Actually, HOSTNAME.CLIENTOS */
  		if (hostname) {
  			clientos = strrchr(hostname, '.'); 
--- 4925,4932 ----
  		else if (strncmp(line1, "clientconfig", 12) == 0) process_clientmsg = 0;
  
  		p = strtok(line1, " \t"); /* Skip the client.* keyword */
! 		if (p) collectorid = strchr(p, '/');
! 		if (collectorid) collectorid++;
  		if (p) hostname = strtok(NULL, " \t"); /* Actually, HOSTNAME.CLIENTOS */
  		if (hostname) {
  			clientos = strrchr(hostname, '.'); 
*** ./xymond/xymond_hostdata.c.orig	2015-11-12 11:16:58.000000000 -0700
--- ./xymond/xymond_hostdata.c	2023-09-28 09:57:17.037593211 -0600
***************
*** 207,213 ****
--- 207,220 ----
  
  				sprintf(hostdir, "%s/%s", clientlogdir, metadata[3]);
  				mkdir(hostdir, S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH);
+ #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
+ 				#pragma GCC diagnostic push
+ 				#pragma GCC diagnostic ignored "-Wformat-overflow"
+ #endif  // __GNUC__
  				sprintf(fn, "%s/%s", hostdir, metadata[4]);
+ #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
+ 				#pragma GCC diagnostic pop
+ #endif  // __GNUC__
  				fd = fopen(fn, "w");
  				if (fd == NULL) {
  					errprintf("Cannot create file %s: %s\n", fn, strerror(errno));
*** ./xymongen/pagegen.c.orig	2019-09-02 17:16:47.000000000 -0600
--- ./xymongen/pagegen.c	2023-09-28 10:39:49.777024470 -0600
***************
*** 648,655 ****
--- 648,662 ----
  								pagepath, h->hostname, e->column->name, htmlextension);
  							sprintf(textrepfn, "%savail-%s-%s.txt",
  								pagepath, h->hostname, e->column->name);
+ #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
+ 							#pragma GCC diagnostic push
+ 							#pragma GCC diagnostic ignored "-Wformat-overflow"
+ #endif  // __GNUC__
  							sprintf(textrepurl, "%s/%s", 
  								xgetenv("XYMONWEB"), textrepfn);
+ #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
+ 							#pragma GCC diagnostic pop
+ #endif  // __GNUC__
  
  							htmlrep = fopen(htmlrepfn, "w");
  							if (!htmlrep) {
***************
*** 932,937 ****
--- 939,948 ----
  		output = stdout;
  	}
  	else {
+ #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
+ 		#pragma GCC diagnostic push
+ 		#pragma GCC diagnostic ignored "-Wformat-overflow"
+ #endif  // __GNUC__
  		if (page->parent == NULL) {
  			char	indexfilename[PATH_MAX];
  
***************
*** 960,965 ****
--- 971,979 ----
  		}
  		sprintf(tmpfilename, "%s.tmp", filename);
  		sprintf(tmprssfilename, "%s.tmp", rssfilename);
+ #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
+ 		#pragma GCC diagnostic pop
+ #endif  // __GNUC__
  
  
  		/* Try creating the output file. If it fails, we may need to create the directories */
***************
*** 1264,1270 ****
--- 1278,1291 ----
  		break;
  	}
  
+ #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
+ 	#pragma GCC diagnostic push
+ 	#pragma GCC diagnostic ignored "-Wformat-overflow"
+ #endif  // __GNUC__
  	sprintf(tmpfilename, "%s.tmp", filename);
+ #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
+ 	#pragma GCC diagnostic pop
+ #endif  // __GNUC__
  	output = fopen(tmpfilename, "w");
  	if (output == NULL) {
  		errprintf("Cannot create file %s: %s\n", tmpfilename, strerror(errno));
***************
*** 1272,1278 ****
--- 1293,1306 ----
  	}
  
  	if (wantrss) {
+ #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
+ 		#pragma GCC diagnostic push
+ 		#pragma GCC diagnostic ignored "-Wformat-overflow"
+ #endif  // __GNUC__
  		sprintf(tmprssfilename, "%s.tmp", rssfilename);
+ #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
+ 		#pragma GCC diagnostic pop
+ #endif  // __GNUC__
  		rssoutput = fopen(tmprssfilename, "w");
  		if (rssoutput == NULL) {
  			errprintf("Cannot create RSS file %s: %s\n", tmpfilename, strerror(errno));
*** ./xymongen/process.c.orig	2016-03-11 20:37:27.000000000 -0700
--- ./xymongen/process.c	2023-09-27 10:09:53.579730930 -0600
***************
*** 107,113 ****
  						     (e->color > color) &&
  						     wantedcolumn(e->column->name, g->onlycols) )
  							color = e->color;
! 							oldage &= e->oldage;
  					}
  
  					/* Blue and clear is not propagated upwards */
--- 107,113 ----
  						     (e->color > color) &&
  						     wantedcolumn(e->column->name, g->onlycols) )
  							color = e->color;
! 						oldage &= e->oldage;
  					}
  
  					/* Blue and clear is not propagated upwards */
***************
*** 127,133 ****
  						     (e->color > color) &&
  						     !wantedcolumn(e->column->name, g->exceptcols) )
  							color = e->color;
! 							oldage &= e->oldage;
  					}
  
  					/* Blue and clear is not propagated upwards */
--- 127,133 ----
  						     (e->color > color) &&
  						     !wantedcolumn(e->column->name, g->exceptcols) )
  							color = e->color;
! 						oldage &= e->oldage;
  					}
  
  					/* Blue and clear is not propagated upwards */
*** ./xymongen/util.c.orig	2011-09-04 00:02:41.000000000 -0600
--- ./xymongen/util.c	2023-09-28 09:35:29.482518037 -0600
***************
*** 43,49 ****
--- 43,56 ----
  		sprintf(pagelink, "%s%s", ((xymongen_page_t *)host->parent)->name, htmlextension);
  		for (pgwalk = host->parent; (pgwalk); pgwalk = pgwalk->parent) {
  			if (strlen(pgwalk->name)) {
+ #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
+ 				#pragma GCC diagnostic push
+ 				#pragma GCC diagnostic ignored "-Wformat-overflow"
+ #endif  // __GNUC__
  				sprintf(tmppath, "%s/%s", pgwalk->name, pagelink);
+ #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
+ 				#pragma GCC diagnostic pop
+ #endif  // __GNUC__
  				strcpy(pagelink, tmppath);
  			}
  		}
*** ./xymongen/wmlgen.c.orig	2019-03-13 16:05:16.000000000 -0600
--- ./xymongen/wmlgen.c	2023-09-28 09:52:12.404081005 -0600
***************
*** 123,129 ****
--- 123,136 ----
  	nextline = msg;
  	l[MAX_LINE_LEN - 1] = '\0';
  
+ #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
+ 	#pragma GCC diagnostic push
+ 	#pragma GCC diagnostic ignored "-Wformat-overflow"
+ #endif  // __GNUC__
  	sprintf(fn, "%s/%s.%s.wml", wmldir, host->hostname, entry->column->name);
+ #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
+ 	#pragma GCC diagnostic pop
+ #endif  // __GNUC__
  	fd = fopen(fn, "w");
  	if (fd == NULL) {
  		errprintf("Cannot create file %s\n", fn);
***************
*** 316,322 ****
--- 323,336 ----
  	}
  
  	/* Start the non-green WML card */
+ #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
+ 	#pragma GCC diagnostic push
+ 	#pragma GCC diagnostic ignored "-Wformat-overflow"
+ #endif  // __GNUC__
  	sprintf(nongreenfn, "%s/nongreen.wml.tmp", wmldir);
+ #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
+ 	#pragma GCC diagnostic pop
+ #endif  // __GNUC__
  	nongreenfd = fopen(nongreenfn, "w");
  	if (nongreenfd == NULL) {
  		errprintf("Cannot open non-green WML file %s\n", nongreenfn);
***************
*** 340,346 ****
--- 354,367 ----
  		if (h->hostentry->anywaps) {
  
  			/* Create the host WAP card, with links to individual test results */
+ #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
+ 			#pragma GCC diagnostic push
+ 			#pragma GCC diagnostic ignored "-Wformat-overflow"
+ #endif  // __GNUC__
  			sprintf(hostfn, "%s/%s.wml", wmldir, h->hostentry->hostname);
+ #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
+ 			#pragma GCC diagnostic pop
+ #endif  // __GNUC__
  			hostfd = fopen(hostfn, "w");
  			if (hostfd == NULL) {
  				errprintf("Cannot create file %s\n", hostfn);
***************
*** 390,396 ****
--- 411,424 ----
  				fclose(nongreenfd);
  
  				/* Start a new Nongreen WML card */
+ #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
+ 				#pragma GCC diagnostic push
+ 				#pragma GCC diagnostic ignored "-Wformat-overflow"
+ #endif  // __GNUC__
  				sprintf(nongreenfn, "%s/nongreen-%d.wml", wmldir, nongreenpart);
+ #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
+ 				#pragma GCC diagnostic pop
+ #endif  // __GNUC__
  				nongreenfd = fopen(nongreenfn, "w");
  				if (nongreenfd == NULL) {
  					errprintf("Cannot open Nongreen WML file %s\n", nongreenfd);
*** ./xymonnet/beastat.c.orig	2019-08-30 15:27:45.000000000 -0600
--- ./xymonnet/beastat.c	2023-09-27 13:53:46.316350258 -0600
***************
*** 104,109 ****
--- 104,110 ----
  		eol = strchr(p, '\n');
  		if (eol) *eol = '\0';
  		strncpy(result, p, sizeof(result));
+ 		result[sizeof(result)-1] = '\0'; /* Make sure it is null terminated */
  		if (eol) *eol = '\n';
  	}
  
*** ./xymonnet/xymonnet.c.orig	2019-09-02 20:28:31.000000000 -0600
--- ./xymonnet/xymonnet.c	2023-09-28 10:41:34.008226181 -0600
***************
*** 1078,1083 ****
--- 1078,1084 ----
  	use_sntp = (p != NULL);
  
  	strncpy(cmdpath, (use_sntp ? xgetenv("SNTP") : xgetenv("NTPDATE")), sizeof(cmdpath));
+ 	cmdpath[sizeof(cmdpath)-1] = '\0'; /* Make sure it is null terminated */
  
  	for (t=service->items; (t); t = t->next) {
  		/* Do not run NTP test if host does not resolve in DNS or is down */
***************
*** 1104,1109 ****
--- 1105,1111 ----
  
  	p = xgetenv("RPCINFO");
  	strncpy(cmdpath, (p ? p : "rpcinfo"), sizeof(cmdpath));
+ 	cmdpath[sizeof(cmdpath)-1] = '\0'; /* Make sure it is null terminated */
  	for (t=service->items; (t); t = t->next) {
  		/* Do not run RPCINFO test if host does not resolve in DNS or is down */
  		if (!t->host->dnserror && (t->host->downcount == 0) && !t->host->pingerror) {
***************
*** 1314,1320 ****
  		#pragma GCC diagnostic push
  		#pragma GCC diagnostic ignored "-Wformat-truncation"
  #endif  // __GNUC__
- 
  		/* Open the new ping result file */
  		snprintf(fn, sizeof(fn), "%s.%02d", pinglog, i);
  		logfd = fopen(fn, "r");
--- 1316,1321 ----
***************
*** 1326,1331 ****
--- 1327,1335 ----
  
  		/* Copy error messages to the Xymon logfile */
  		snprintf(fn, PATH_MAX, "%s.%02d", pingerrlog, i);
+ #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
+ 		#pragma GCC diagnostic pop
+ #endif  // __GNUC__
  		if (failed) {
  			FILE *errfd;
  			char buf[1024];
***************
*** 1337,1345 ****
  			if (errfd) fclose(errfd);
  		}
  		if (!debug) unlink(fn);
- #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
- 		#pragma GCC diagnostic pop
- #endif  // __GNUC__
  
  		if (failed) {
  			/* Flag all ping tests as "undecided" */
--- 1341,1346 ----
***************
*** 1396,1401 ****
--- 1397,1403 ----
  			testitem_t *router;
  
  			strncpy(l, t->host->routerdeps, sizeof(l));
+ 			l[sizeof(l)-1] = '\0'; /* Make sure it is null terminated */
  			p = strtok(l, ",");
  			while (p && (t->host->deprouterdown == NULL)) {
  				for (router=service->items; 
***************
*** 2431,2436 ****
--- 2433,2439 ----
  			for (t = s->items; (t); t = t->next) {
  				if (!t->host->dnserror) {
  					strncpy(tname, s->testname, sizeof(tname));
+ 					tname[sizeof(tname)-1] = '\0'; /* Make sure it is null terminated */
  					if (s->namelen) tname[s->namelen] = '\0';
  					t->privdata = (void *)add_tcp_test(ip_to_test(t->host), s->portnum, tname, NULL,
  									   t->srcip,
*** ./xymonproxy/xymonproxy.c.orig	2019-09-02 20:28:31.000000000 -0600
--- ./xymonproxy/xymonproxy.c	2023-09-28 10:18:35.622334378 -0600
***************
*** 533,539 ****
  			int ccount = 0;
  			unsigned long bufspace = 0;
  			unsigned long avgtime;	/* In millisecs */
! 			char runtime_s[30];
  			unsigned long runt = (unsigned long) (now-startuptime);
  			char *p;
  			unsigned long msgs_sent = msgs_total - msgs_total_last;
--- 533,539 ----
  			int ccount = 0;
  			unsigned long bufspace = 0;
  			unsigned long avgtime;	/* In millisecs */
! 			char runtime_s[31];	/* Include room for null termination */
  			unsigned long runt = (unsigned long) (now-startuptime);
  			char *p;
  			unsigned long msgs_sent = msgs_total - msgs_total_last;


More information about the Xymon mailing list