[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#987488: unblock: irssi/20210314-1



Package: release.debian.org
User: release.debian.org@packages.debian.org
Usertags: unblock
Severity: normal

Please unblock package irssi

There was a QA Upload done by Daniel Echeverri fixing a security / RC bug (CVE-2021-29376)

[ Reason ]
The version fixes a serious security issue.

[ Impact ]
The security issue will not get fixed and to we should not ship irssi with bullseye.

[ Tests ]
No tests don on my side, dunno if Daniel did some.

[ Risks ]
While the diffstat looks huge, a significant part is removed code.

[ Checklist ]
  [x] all changes are documented in the d/changelog
  [ ] I reviewed all changes and I approve them
  [x] attach debdiff against the package in testing

unblock irssi/20210314-1

Thanks, Jan.
--
Never write mail to <waja@spamfalle.info>, you have been warned!
-----BEGIN GEEK CODE BLOCK-----
Version: 3.12
GIT d-- s+: a C+++ UL++++ P+ L+++ E--- W+++ N+++ o++ K++ w--- O M+ V- PS PE Y++
PGP++ t-- 5 X R tv- b+ DI D+ G++ e++ h---- r+++ y++++
------END GEEK CODE BLOCK------
diff -Nru ircii-20190117/ChangeLog ircii-20210314/ChangeLog
--- ircii-20190117/ChangeLog	2019-01-18 11:31:26.000000000 +0100
+++ ircii-20210314/ChangeLog	2021-03-14 19:32:27.000000000 +0100
@@ -4,13 +4,232 @@
  *
  * Matthew Green, 1993.
  *
- * Copyright(c) 1993-2019
+ * Copyright(c) 1993-2021
  *
  * See the COPYRIGHT file, or do a HELP IRCII COPYRIGHT
  *
- * @(#)$eterna: ChangeLog,v 2.779 2019/01/18 10:31:26 mrg Exp $
+ * @(#)$eterna: ChangeLog,v 2.812 2021/03/14 18:22:30 mrg Exp $
  */
 
+20210314
+Sun Mar 14 11:19:32 PDT 2021 - matthew green <mrg@eterna.com.au>
+	 configure, configure.in, include/defs.h.in, include/irc_std.h:
+		finish removing RFC2553 / addrinfo checks.
+	 source/ctcp.c:
+		call sl_free() in do_clientinfo().  from michael ortmann
+		<ortmann@posteo.de>.
+	 source/ircaux.c, source/server.c:
+		be sure to free addrinfo structures.  picked up by the
+		leak sanitizer.
+
+20210302
+Tue Mar  2 13:43:11 PST 2021 - matthew green <mrg@eterna.com.au>
+	source/ctcp.c, source/edit.c, source/mail.c, source/menu.c:
+		make sure final character is \n before removing it.
+		ensure that ctime() does not return NULL.  reported by
+		michael ortmann <ortmann@posteo.de>.
+
+Tue Mar  2 13:02:05 PST 2021 - matthew green <mrg@eterna.com.au>
+	source/ctcp.c:
+		avoid accessing a variable after it goes out of scope.
+		from sanitizer, via michael ortmann <ortmann@posteo.de>.
+20210301
+Tue Mar  2 03:03:05 PST 2021 - matthew green <mrg@eterna.com.au>
+	Makefile.in, configure, configure.in, include/defs.h.in,
+	source/getaddrinfo.c, source/getnameinfo.c, source/inet_ntop.c,
+	source/inet_pton.c, source/snprintf.c:
+		assume host provides working implementations of
+		functions getnameinfo()/getaddrinfo()/snprintf().
+
+Tue Mar  2 02:14:31 PST 2021 - matthew green <mrg@eterna.com.au>
+	source/exec.c:
+		in close_all_exec() call kill_process() before
+		delete_process() so that kill_process() can find info
+		about the process before it is removed.
+	source/ircaux.c:
+		convert from sigblock() to sigprocmask().  also block
+		SIGUSR2 as well as SIGUSR1, and also block them when
+		calling malloc() and realloc() as well as free().
+
+Sun Feb 28 23:46:10 UTC 2021 - matthew green <mrg@eterna.com.au>
+	configure.in, configure:
+		support combining sanitizers.  asan+ubsan, lsan+ubsan
+		are ok, but since asan includes lsan, including both
+		crashes, so don't allow that.  allow calling them
+		asan/address, lsan/leak, and ubsan/undefined.
+
+Sun Feb 28 22:43:32 UTC 2021 - matthew green <mrg@eterna.com.au>
+	help/bind/refresh_window_lastlog:
+		add missing documentation for new-in-2017 bindable key.
+
+Sat Feb 27 15:02:39 PST 2021 - matthew green <mrg@eterna.com.au>
+	source/crypt.c:
+		avoid C99's "for (type var = 0; ...)" feature.  this trips
+		up defaults on older GCCs while can compile the rest of
+		the C99-using parts of ircii without any fault.
+
+Sat Feb 27 14:36:30 PST 2021 - matthew green <mrg@eterna.com.au>
+	include/debug.h, include/irc.h, source/debug.c, source/irc.c:
+		remove get_log_fp() and move all the log handling into
+		debug.c.  avoid wanting a static definition of 'stderr'
+		and fix compliation issues on some platforms.
+
+20210226
+Fri Feb 26 23:54:16 PST 2021 - matthew green <mrg@eterna.com.au>
+	include/irc.h, source/debug.c, source/irc.c:
+		convert open_log_file() to not override what 'stderr' is,
+		since this conflicts with address sanitizer's use of stderr.
+		add get_log_fp() and use it in debug.c to find the FILE *
+		for the log now that 'stderr' is not it.
+
+Fri Feb 26 23:49:15 PST 2021 - matthew green <mrg@eterna.com.au>
+	source/window.c:
+		fix a memory leak triggered by wrapped lines and the
+		cursor indent is missing or is too long, found by
+		by -fsanitize=address leak sanitizer.
+
+Fri Feb 26 23:11:14 PST 2021 - matthew green <mrg@eterna.com.au>
+	fix four bugs reported by michael ortmann <ortmann@posteo.de>:
+	source/icb.c:
+		fix a logic error that would crash if hit.
+	source/newio.c:
+		avoid overflowing the buffer passed to dgets() by 1 byte.
+	source/parse.c:
+		avoid underflowing the buffer passed to irc2_parse_server()
+		by 1 byte, if it sees a line with just "\n".
+	source/queue.c:
+		fix a crash in "/queue -delete <queue>" by defining this
+		operation as delete all the entries in the named queue.
+
+Wed Feb 24 23:35:54 UTC 2021 - matthew green <mrg@eterna.com.au>
+	configure.in, configure:
+		add support for the leak sanitizer.  fix the
+		getaddrinfo() works test which was leaking memory.
+
+Wed Feb 24 23:24:40 UTC 2021 - matthew green <mrg@eterna.com.au>
+	source/alias.c, source/irc.c, source/hook.c:
+		make sure numerics are in valid range, and buffers are
+		impossible to overrun (shouldn't happen, but the
+		compiler/sanitizer can't tell from what it can see.)
+
+Wed Feb 24 11:53:38 PST 2021 - matthew green <mrg@eterna.com.au>
+	configure.in, configure:
+		add --with-sanitizer[=<asan|ubsan>] support to configure.
+	source/ircflush.c:
+		avoid an extremely unlikely buffer overflow.
+	source/ircaux.c:
+		appease undefined sanitizer and ensure a format passed to
+		vsnprintf() is not NULL.
+
+Wed Feb 24 11:52:02 PST 2021 - matthew green <mrg@eterna.com.au>
+	source/parse.c:
+		make sure all unused elements of TrueArgs[] are NULL.
+
+20210224
+Wed Feb 24 02:25:44 PST 2021 - matthew green <mrg@eterna.com.au>
+	include/parse.h, source/funny.c, source/notice.c, source/numbers.c,
+	source/parse.c, source/whois.c:
+		consolidate most of the arg checking and calls to new
+		irc2_odd_server_stuff() into check_params().  fix the check
+		in p_kick().
+
+Wed Feb 24 02:00:11 PST 2021 - matthew green <mrg@eterna.com.au>
+	include/edit.h, include/funny.h, include/notice.h, include/numbers.h,
+	include/parse.h, include/whois.h, source/edit.c, source/funny.c,
+	source/notice.c, source/numbers.c, source/parse.c, source/whois.c:
+		avoid NULL derefs, and accessing previous stack contents,
+		triggerable by a malicious IRC server.  fix the do_hook()
+		call in whoreply_check() to not pass potentially random,
+		but likely duplicated data to /ON WHO.  ensure that
+		break_args() always NULL-ends the array, a zero length input
+		would leave the ArgList uninitialised.  check all consumers
+		in irc2_parse_server() and numbered_command() properly check
+		the arguments they expect before using them, and document
+		the assumptions and requirements.  original issues reported
+		by michael ortmann <ortmann@posteo.de>, with further
+		investigation by mrg.  i was only able to trigger crashes
+		with NULL dereferences, not control any other effect.
+	source/edit.c:
+		rename version() to e_version() to avoid human-conflict
+		with the also static version() in irc.c.
+
+Wed Feb 24 01:13:10 PST 2021 - matthew green <mrg@eterna.com.au>
+	source/numbers.c:
+		call save_message_from() before calling
+		restore_message_from() when handling non-special numerics.
+
+Wed Feb 24 00:57:43 PST 2021 - matthew green <mrg@eterna.com.au>
+	source/exec.c, source/icb.c:
+		use my_strcmp() and my_strlen() to avoid warnings.
+	source/numbers.c:
+		consistently use ArgList[0] over *ArgList.
+
+Tue Feb 16 18:37:13 PST 2021 - matthew green <mrg@eterna.com.au>
+	source/icb.c:
+		avoid reading one byte beyond "" in two places.
+		picked up by -fsanitize=address.
+
+Tue Feb 16 17:50:36 PST 2021 - matthew green <mrg@eterna.com.au>
+	source/exec.c:
+		avoid one byte buffer underflow write of a 0 byte,
+		picked up by -fsanitize=address.  looking at a couple
+		of stack layouts for this function, the written byte
+		is currently dead space so very unlikely exploitable.
+
+20201117
+Tue Nov 17 00:22:18 PST 2020 - matthew green <mrg@eterna.com.au>
+	source/aes.c, source/cast.c, source/crypt.c:
+		introduce crypt_get_random_data() and use it to obtain
+		more than one byte at a time if available.
+
+Tue Nov 17 00:05:45 PST 2020 - matthew green <mrg@eterna.com.au>
+	include/exec.h, include/signals.h, source/exec.c, source/irc.c,
+	source/mksignals.pl, source/signals.c:
+		move all the signal data into signals.c, and access it
+		via new get_signal().
+	source/alias.c, source/hook.c, source/server.c, source/term.c,
+	source/translat.c, source/window.c:
+		mark local variables static.
+
+Fri Jul 31 13:22:28 PDT 2020 - matthew green <mrg@eterna.com.au>
+	source/server.c:
+		display SSL information in the server list.
+	configure.in, configure:
+		fix indentation and display of [] in --help.  fix error
+		handling message when looking for socks5.
+
+Thu Apr 30 20:13:04 PDT 2020 - matthew green <mrg@eterna.com.au>
+	source/dcc.c:
+		initialised buf to NULL.  fixes free() of random data,
+		and thus likely crash.  reported by michael ortmann
+		<ortmann@posteo.de>.
+
+Fri Mar 13 05:13:38 PDT 2020 - matthew green <mrg@eterna.com.au>
+	source/status.c:
+		avoid negative hour/minutes causing buffer overflow.
+
+Thu Apr 25 17:06:08 PDT 2019 - matthew green <mrg@eterna.com.au>
+	source/newio.c:
+		initialise nfds to avoid the case where no FDs are
+		persent in the fd_sets.
+	source/server.c:
+		fix 13 year old bug: $IRCSERVERS tries to new_free()
+		data in the environment which does not work.
+
+Tue Mar 12 19:45:15 PDT 2019 - glen mccready <gkm@pobox.com>
+	source/newio.c:
+		mac os didn't like unsigned < (int)-1 with the
+		change below. slight change to how we calculate
+		nfds.
+
+Sat Mar  9 16:19:16 PST 2019 - matthew green <mrg@eterna.com.au>
+	source/newio.c:
+		use unsigned for array index.
+
+Mon Feb  4 17:35:12 PST 2019 - matthew green <mrg@eterna.com.au>
+	source/hook.c, source/ircflush.c, source/server.c:
+		fix potential snprintf() truncation issues.
+
 20190117
 Thu Jan 17 17:16:10 PST 2019 - matthew green <mrg@eterna.com.au>
 	doc/ircii.spec:
@@ -2091,6 +2310,7 @@
 	source/icb.c:
 		in icb_put_public(), split the line at a space boundary
 		if it exists within the last 10 characters.
+
 Wed Sep 27 17:26:35 EST 2006 - matthew green <mrg@eterna.com.au>
 	source/server.c:
 		in connect_to_server_direct() reorder some code to avoid
diff -Nru ircii-20190117/Makefile.in ircii-20210314/Makefile.in
--- ircii-20190117/Makefile.in	2019-01-18 11:29:41.000000000 +0100
+++ ircii-20210314/Makefile.in	2021-03-14 19:32:27.000000000 +0100
@@ -2,7 +2,7 @@
 #
 # Copyright (c) 1991 Michael Sandrof.
 # Copyright (c) 1991, 1992 Troy Rollo.
-# Copyright (c) 1993-2019 Matthew R. Green.
+# Copyright (c) 1993-2021 Matthew R. Green.
 # Copyright (c) 1995 Scott Reynolds.
 # All rights reserved.
 #
@@ -32,7 +32,7 @@
 # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 # SUCH DAMAGE.
 #
-# @(#)$eterna: Makefile.in,v 1.128 2019/01/16 07:47:45 mrg Exp $
+# @(#)$eterna: Makefile.in,v 1.129 2021/03/02 21:41:52 mrg Exp $
 
 # targets recognised by this makefile:
 #   all, everything	- compiles ircii, ircio, ircflush and wserv
@@ -281,8 +281,7 @@
 	ssl.o status.o strsep.o strcasestr.o \
 	term.o translat.o \
 	vars.o \
-	whois.o window.o \
-	@EXTRA_OBJECTS@
+	whois.o window.o
 
 RIJNDAEL_SOURCES = rijndael-alg-ref.c rijndael-api-ref.c
 SOURCES = \
@@ -305,11 +304,10 @@
 	ssl.c status.c strsep.c strcasestr.c \
 	term.c translat.c \
 	vars.c \
-	whois.c window.c \
-	@EXTRA_SOURCES@
+	whois.c window.c
 
-IRCIO_OBJECTS = ircio.o newio.o ircsig.o @EXTRA_IRCIO_OBJECTS@
-IRCIO_SOURCES = ircio.c @EXTRA_IRCIO_SOURCES@
+IRCIO_OBJECTS = ircio.o newio.o ircsig.o
+IRCIO_SOURCES = ircio.c
 
 WSERV_OBJECTS = wserv.o wterm.o ircsig.o
 WSERV_SOURCES = wserv.c wterm.c
diff -Nru ircii-20190117/NEWS ircii-20210314/NEWS
--- ircii-20190117/NEWS	2019-01-18 11:41:59.000000000 +0100
+++ ircii-20210314/NEWS	2021-03-14 19:42:16.000000000 +0100
@@ -1,4 +1,19 @@
-@(#)$eterna: NEWS,v 1.143 2019/01/18 10:41:31 mrg Exp $
+@(#)$eterna: NEWS,v 1.148 2021/03/14 18:42:16 mrg Exp $
+
+Changes in ircII 20210314:
+
+  o  fix two memory leaks, one from michael ortmann <ortmann@posteo.de>.
+  o  removed support for non-host getaddrinfo(), getnameinfo(),
+     inet_pton(), inet_ntop(), and snprintf().  all are part of C99.
+  o  fixes for various issues by michael ortmann <ortmann@posteo.de>.
+
+Changes in ircII 20210225:
+
+  o  new --with-sanitizer=<asan|ubsan|lsan> configure support
+  o  many fixes for fuzzer and sanitizer found issues
+  o  the $IRCSERVERS variable no longer triggers some library asserts 
+  o  avoid displaying negative hours/minutes
+  o  fix a potential messages goes to wrong window issue in numerics
 
 Changes in ircII 20190117:
 
@@ -19,7 +34,7 @@
      (poorly so far) formatted html pages, many help issues pages fixed
   o  restore case-insensitive /lastlog, accidentally broken in 20161207
   o  fix input line scrolling problem where it would not keep any of the
-     existing input line.
+     existing input line
 
 Changes in ircII 20170704:
 
@@ -110,7 +125,7 @@
   o  scrolling is much faster now
   o  fix compile time errors in on modern glibc systems
   o  add /nuser command
-  o  wserv and ircio move into "libexec" dir.
+  o  wserv and ircio move into "libexec" dir
 
 Changes in ircII 20110228:
 
@@ -121,7 +136,7 @@
   o  revert the utf-8 changes for large lastlog performance reasons.
      there should be a re-implementation coming in the future.
   o  make /on nickname, /on channel_nick, $chanusers() and $onchannel()
-     work with ICB.
+     work with ICB
   o  make /save save /ignore'd things
 
 Changes in ircII 20060725:
@@ -154,11 +169,11 @@
   o  various documentation updates
   o  ircii now requires an ANSI C compiler (such as GCC) to compile
   o  new /set switch_to_quiet_channels that allows switch_channels binding
-     to ignore "quiet" channels.
+     to ignore "quiet" channels
   o  fixed the --without-emacs-meta-keys option to really be the default
   o  /hush support in ICB
   o  new example script ``multichan'' for maintaining multiple server
-     and channel configurations.
+     and channel configurations
   o  renamed /ON ICB_MOTD to ICB_CMDOUT and fixed it as well
   o  removed old "SED" useless encryption
   o  add /ON TOPIC support for ICB
@@ -170,7 +185,7 @@
   o  /DCC RAW works when disconnected again
   o  several bugs fixed
   o  new /set dccport and /set bind_local_dcchost variables to give
-     the user full control over how dcc requests are sent.
+     the user full control over how dcc requests are sent
   o  new /on os_signal to give user-access to receiving UNIX signals
   o  /set beep_on_msg now works for ICB messages and groups (public)
   o  the --without-emacs-meta-keys configure option is now the default
diff -Nru ircii-20190117/configure ircii-20210314/configure
--- ircii-20190117/configure	2019-01-18 11:29:41.000000000 +0100
+++ ircii-20210314/configure	2021-03-14 19:32:27.000000000 +0100
@@ -1,5 +1,5 @@
 #! /bin/sh
-# From configure.in Revision: 1.221 .
+# From configure.in Revision: 1.227 .
 # Guess values for system-dependent variables and create Makefiles.
 # Generated by GNU Autoconf 2.69.
 #
@@ -625,10 +625,6 @@
 LN
 RM
 SENDMAIL
-EXTRA_IRCIO_SOURCES
-EXTRA_IRCIO_OBJECTS
-EXTRA_SOURCES
-EXTRA_OBJECTS
 ZCAT
 INSTALL_HELP_CMD
 COPY_DIRECTORY
@@ -697,6 +693,7 @@
 with_debugging
 with_warnings
 with_warning_errors
+with_sanitizer
 with_emacs_meta_keys
 with_paranoid
 with_default_server
@@ -705,7 +702,6 @@
 with_socks5
 with_socks4
 with_non_blocking
-enable_ipv6
 '
       ac_precious_vars='build_alias
 host_alias
@@ -1319,30 +1315,24 @@
 
   cat <<\_ACEOF
 
-Optional Features:
-  --disable-option-checking  ignore unrecognized --enable/--with options
-  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
-  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
-  --enable-ipv6           Enable ipv6 (with ipv4) support
-  --disable-ipv6          Disable ipv6 support
-
 Optional Packages:
   --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
   --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
-  --with-prefix-paths                Add include and library diectories from prefix
-  --with-efence=PATH                 Compile with the ElectricFence debugging library
-  --with-openssl=PATH                Compile with OpenSSL
-  --with-debugging=flags             Build with debugging support
-  --with-warnings=flags              Build with GCC warnings
-  --with-warning-errors=flags        Turn warnings into errors
-  --with-emacs-meta-keys             Enable Emacs meta key support
-  --with-paranoid                    Sets the compile-time paranoid flag
-  --with-default-server=SERVER:PORT  Connect to SERVER by default
-  --with-default-resize-method=type  Either "old" or "new"
-  --with-socks                       Compile with SOCKS firewall traversal support
-  --with-socks5=PATH                 Compile with SOCKS5 firewall traversal support
-  --with-socks4=PATH                 Compile with SOCKS4 firewall traversal support
-  --with-non-blocking=TYPE           Use TYPE non-blocking, yes or no
+  --with-prefix-paths                  Add include and library diectories from prefix
+  --with-efence[=PATH]                 Compile with the ElectricFence debugging library.
+  --with-openssl[=PATH]                Compile with OpenSSL.
+  --with-debugging[=flags]             Build with debugging support.
+  --with-warnings[=flags]              Build with GCC warnings.
+  --with-warning-errors[=flags]        Turn warnings into errors.
+  --with-sanitizer[=<list>]            Use sanitizers, default ASAN.
+  --with-emacs-meta-keys               Enable Emacs meta key support.
+  --with-paranoid                      Sets the compile-time paranoid flag.
+  --with-default-server=SERVER[:PORT]  Connect to SERVER by default.
+  --with-default-resize-method=type    Either "old" or "new"
+  --with-socks                         Compile with SOCKS firewall traversal support
+  --with-socks5[=PATH]                 Compile with SOCKS5 firewall traversal support.
+  --with-socks4[=PATH]                 Compile with SOCKS4 firewall traversal support.
+  --with-non-blocking=[TYPE]           Use TYPE non-blocking, yes or no.
 
 Some influential environment variables:
   CC          C compiler command
@@ -2199,7 +2189,7 @@
 CATEGORIES='build change-request doc pending runtime'
 
 
-echo '$eterna: configure,v 2.186 2019/01/16 00:38:50 mrg Exp $' > /dev/null
+echo '$eterna: configure,v 2.193 2021/03/14 18:22:30 mrg Exp $' > /dev/null
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for prefix paths" >&5
 $as_echo_n "checking for prefix paths... " >&6; }
@@ -3593,7 +3583,7 @@
 for ac_func in \
 	getpgid getsid memmove scandir setsid strftime writev \
 	snprintf vsnprintf fputc fwrite setenv unsetenv \
-	gethostbyname2 inet_pton inet_ntop tzset waitpid iconv_open
+	tzset waitpid iconv_open
 do :
   as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
 ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
@@ -3607,13 +3597,7 @@
 
 
 
-ac_fn_c_check_func "$LINENO" "getaddrinfo" "ac_cv_func_getaddrinfo"
-if test "x$ac_cv_func_getaddrinfo" = xyes; then :
-
-$as_echo "#define HAVE_GETADDRINFO 1" >>confdefs.h
-
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for getaddrinfo in -lmedia" >&5
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for getaddrinfo in -lmedia" >&5
 $as_echo_n "checking for getaddrinfo in -lmedia... " >&6; }
 if ${ac_cv_lib_media_getaddrinfo+:} false; then :
   $as_echo_n "(cached) " >&6
@@ -3653,15 +3637,6 @@
   LIBS="$LIBS -lmedia"
 fi
 
-fi
-
-ac_fn_c_check_func "$LINENO" "getnameinfo" "ac_cv_func_getnameinfo"
-if test "x$ac_cv_func_getnameinfo" = xyes; then :
-
-$as_echo "#define HAVE_GETNAMEINFO 1" >>confdefs.h
-
-fi
-
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether time.h and sys/time.h may both be included" >&5
 $as_echo_n "checking whether time.h and sys/time.h may both be included... " >&6; }
@@ -3818,47 +3793,6 @@
 
 
 
-	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for struct addrinfo" >&5
-$as_echo_n "checking for struct addrinfo... " >&6; }
-if ${ircii_cv_HAVE_ADDRINFO+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-
-		cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netdb.h>
-int
-main ()
-{
-  struct addrinfo X
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-   ircii_cv_HAVE_ADDRINFO=yes
-else
-   ircii_cv_HAVE_ADDRINFO=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ircii_cv_HAVE_ADDRINFO" >&5
-$as_echo "$ircii_cv_HAVE_ADDRINFO" >&6; }
-	if test "x$ircii_cv_HAVE_ADDRINFO" = "xyes"; then
-
-$as_echo "#define HAVE_ADDRINFO 1" >>confdefs.h
-
-	else
-
-		:
-	fi
-
-
-
 	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for socklen_t" >&5
 $as_echo_n "checking for socklen_t... " >&6; }
 if ${ircii_cv_HAVE_SOCKLEN_T+:} false; then :
@@ -4689,6 +4623,82 @@
 
 
 
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sanitizers" >&5
+$as_echo_n "checking for sanitizers... " >&6; }
+
+# Check whether --with-sanitizer was given.
+if test "${with_sanitizer+set}" = set; then :
+  withval=$with_sanitizer;  case "$withval" in
+  no)
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+    LIBSANI=
+    ;;
+  *)
+    if test "x$withval" = xyes; then
+      withval='address'
+    fi
+    have_asan=0
+    have_lsan=0
+    have_ubsan=0
+    for val in `echo "$withval" | sed "s/,/ /"`
+    do
+      LIBSANI=
+      case "$val" in
+      asan|address)
+        FSANI=address
+        LIBSANI=asan
+        have_asan=1
+        ;;
+      lsan|leak)
+        FSANI=leak
+        LIBSANI=lsan
+        have_lsan=1
+        ;;
+      ubsan|undefined)
+        FSANI=undefined
+        LIBSANI=ubsan
+        have_ubsan=1
+        ;;
+      *)
+        as_fn_error leak "Sanitizer support for address" "$LINENO" 5
+        ;;
+      esac
+    done
+    if test "$have_asan" -eq 1 -a "$have_lsan" -eq 1; then
+      as_fn_error $? "Do not combine address and leak sanitizers." "$LINENO" 5
+    fi
+    list=""
+    sep=""
+    if test "$have_asan" -eq 1; then
+      CFLAGS="$CFLAGS -fsanitize=address"
+      LIBS="$LIBS -lasan"
+      list="$list$sep"address
+      sep=" "
+    fi
+    if test "$have_lsan" -eq 1; then
+      CFLAGS="$CFLAGS -fsanitize=leak"
+      LIBS="$LIBS -llsan"
+      list="$list$sep"leak
+      sep=" "
+    fi
+    if test "$have_ubsan" -eq 1; then
+      CFLAGS="$CFLAGS -fsanitize=undefined"
+      LIBS="$LIBS -lubsan"
+      list="$list$sep"undefined
+      sep=" "
+    fi
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $list" >&5
+$as_echo "$list" >&6; }
+    ;;
+  esac
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+
+
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for emacs meta keys" >&5
 $as_echo_n "checking for emacs meta keys... " >&6; }
 
@@ -5085,8 +5095,9 @@
 	    { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
 $as_echo "yes" >&6; }
 	    socks=5
+	    socks5lib=""
 	    if test "x$withval" = "xyes"; then
-	      withval="-lsocks5"
+	      socks5lib="-lsocks5"
 	    else
 	      if test -d "$withval"; then
 		if test -d "$withval/include"; then
@@ -5095,13 +5106,15 @@
 		  CFLAGS="$CFLAGS -I$withval"
 		fi
 	        if test -d "$withval/lib"; then
-		  withval="-L$withval/lib -lsocks5"
+		  socks5lib="-L$withval/lib -lsocks5"
 		else
-		  withval="-L$withval -lsocks5"
+		  socks5lib="-L$withval -lsocks5"
 		fi
+	      else
+		socks5lib="$withval"
 	      fi
 	    fi
-	    LIBS="$withval $LIBS"
+	    LIBS="$socks5lib $LIBS"
 	    # If Socks was compiled with Kerberos support, we will need
 	    # to link against kerberos libraries.  Temporarily append
 	    # to LIBS.  This is harmless if there is no kerberos support.
@@ -5244,247 +5257,6 @@
 
 fi
 
-have_rfc2553_netdb=no
-if test $ac_cv_func_getaddrinfo = yes -a ! -n "$socks"; then
-
-	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for AI_NUMERICHOST" >&5
-$as_echo_n "checking for AI_NUMERICHOST... " >&6; }
-if ${ircii_cv_have_ai_numerichost+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-
-		cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netdb.h>
-int
-main ()
-{
-  int X = AI_NUMERICHOST
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-   ircii_cv_have_ai_numerichost=yes
-else
-   ircii_cv_have_ai_numerichost=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ircii_cv_have_ai_numerichost" >&5
-$as_echo "$ircii_cv_have_ai_numerichost" >&6; }
-	if test "x$ircii_cv_have_ai_numerichost" = "xyes"; then
-		 have_rfc2553_netdb=yes
-	else
-
-		:
-	fi
-
-fi
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable ipv6" >&5
-$as_echo_n "checking whether to enable ipv6... " >&6; }
-if test "x$socks" = "x4" -o "x$socks" = "x5"; then
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-else
-  # Check whether --enable-ipv6 was given.
-if test "${enable_ipv6+set}" = set; then :
-  enableval=$enable_ipv6;  case "$enableval" in
-  no)
-       { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-       ipv6=no
-       ;;
-  *)   { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
-       ipv6=yes
-       ;;
-  esac
-fi
-
-
-
-	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for AF_INET6" >&5
-$as_echo_n "checking for AF_INET6... " >&6; }
-if ${ircii_cv_HAVE_AF_INET6+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-
-		cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-
-#include <sys/types.h>
-#include <sys/socket.h>
-int
-main ()
-{
-  if (socket(AF_INET6, SOCK_STREAM, 0) < 0)
-        exit(1);
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-   ircii_cv_HAVE_AF_INET6=yes
-else
-   ircii_cv_HAVE_AF_INET6=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ircii_cv_HAVE_AF_INET6" >&5
-$as_echo "$ircii_cv_HAVE_AF_INET6" >&6; }
-	if test "x$ircii_cv_HAVE_AF_INET6" = "xyes"; then
-		ipv6=yes
-	else
-
-		:
-	fi
-
-
-if test -n "$ipv6"
-then
-
-$as_echo "#define INET6 1" >>confdefs.h
-
-fi
-
-fi # socks = x[45]
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for working getaddrinfo()" >&5
-$as_echo_n "checking for working getaddrinfo()... " >&6; }
-if test $have_rfc2553_netdb = yes; then
-
-$as_echo "#define HAVE_RFC2553_NETDB 1" >>confdefs.h
-
-  if test "$cross_compiling" = yes; then :
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: buggy" >&5
-$as_echo "buggy" >&6; }
-  buggygetaddrinfo=yes
-else
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-
-#include <sys/types.h>
-#include <netdb.h>
-#include <string.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-
-main()
-{
-  int passive, gaierr, inet4 = 0, inet6 = 0;
-  struct addrinfo hints, *ai, *aitop;
-  char straddr[INET6_ADDRSTRLEN], strport[16];
-
-  for (passive = 0; passive <= 1; passive++) {
-    memset(&hints, 0, sizeof(hints));
-    hints.ai_family = AF_UNSPEC;
-    hints.ai_flags = passive ? AI_PASSIVE : 0;
-    hints.ai_socktype = SOCK_STREAM;
-    if ((gaierr = getaddrinfo(NULL, "54321", &hints, &aitop)) != 0) {
-      (void)gai_strerror(gaierr);
-      goto bad;
-    }
-    for (ai = aitop; ai; ai = ai->ai_next) {
-      if (ai->ai_addr == NULL ||
-          ai->ai_addrlen == 0 ||
-          getnameinfo(ai->ai_addr, ai->ai_addrlen,
-                      straddr, sizeof(straddr), strport, sizeof(strport),
-                      NI_NUMERICHOST|NI_NUMERICSERV) != 0) {
-        goto bad;
-      }
-      switch (ai->ai_family) {
-      case AF_INET:
-        if (strcmp(strport, "54321") != 0) {
-          goto bad;
-        }
-        if (passive) {
-          if (strcmp(straddr, "0.0.0.0") != 0) {
-            goto bad;
-          }
-        } else {
-          if (strcmp(straddr, "127.0.0.1") != 0) {
-            goto bad;
-          }
-        }
-        inet4++;
-        break;
-      case AF_INET6:
-        if (strcmp(strport, "54321") != 0) {
-          goto bad;
-        }
-        if (passive) {
-          if (strcmp(straddr, "::") != 0) {
-            goto bad;
-          }
-        } else {
-          if (strcmp(straddr, "::1") != 0) {
-            goto bad;
-          }
-        }
-        inet6++;
-        break;
-      case AF_UNSPEC:
-        goto bad;
-        break;
-      default:
-        /* another family support? */
-        break;
-      }
-    }
-  }
-
-  if (inet4 != 0 && inet4 != 2)
-    goto bad;
-  if (inet6 != 0 && inet6 != 2)
-    goto bad;
-
-  if (aitop)
-    freeaddrinfo(aitop);
-  exit(0);
-
- bad:
-  if (aitop)
-    freeaddrinfo(aitop);
-  exit(1);
-}
-_ACEOF
-if ac_fn_c_try_run "$LINENO"; then :
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: good" >&5
-$as_echo "good" >&6; }
-  buggygetaddrinfo=no
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: buggy" >&5
-$as_echo "buggy" >&6; }
-  buggygetaddrinfo=yes
-fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
-  conftest.$ac_objext conftest.beam conftest.$ac_ext
-fi
-
-
-  if test "x$buggygetaddrinfo" = "xyes"; then
-	echo 'Using local version of getaddrinfo()'
-	ac_cv_func_getaddrinfo=no
-  fi
-
-else
-  if test $ac_cv_func_getaddrinfo = yes; then
-	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no - using local version" >&5
-$as_echo "no - using local version" >&6; }
-  else
-	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: using local version" >&5
-$as_echo "using local version" >&6; }
-  fi
-  ac_cv_func_getaddrinfo=no
-fi # have_rfc2553_netdb = yes
-
 if test -n "$hpux"
 then
 	# HP-UX's pax is broken
@@ -5678,46 +5450,6 @@
 
 fi
 
-EXTRA_OBJECTS=
-EXTRA_SOURCES=
-EXTRA_IRCIO_OBJECTS=
-EXTRA_IRCIO_SOURCES=
-if test x$ac_cv_func_snprintf != xyes || test x$ac_cv_func_vsnprintf != xyes
-then
-  EXTRA_OBJECTS="$EXTRA_OBJECTS snprintf.o"
-  EXTRA_SOURCES="$EXTRA_SOURCES snprintf.c"
-  EXTRA_IRCIO_OBJECTS="$EXTRA_IRCIO_OBJECTS snprintf.o"
-  EXTRA_IRCIO_SOURCES="$EXTRA_IRCIO_SOURCES snprintf.c"
-fi
-if test x$ac_cv_func_getaddrinfo != xyes
-then
-  EXTRA_OBJECTS="$EXTRA_OBJECTS getaddrinfo.o"
-  EXTRA_SOURCES="$EXTRA_SOURCES getaddrinfo.c"
-  EXTRA_IRCIO_OBJECTS="$EXTRA_IRCIO_OBJECTS getaddrinfo.o"
-  EXTRA_IRCIO_SOURCES="$EXTRA_IRCIO_SOURCES getaddrinfo.c"
-  if test x$ac_cv_func_inet_pton != xyes
-  then
-    EXTRA_OBJECTS="$EXTRA_OBJECTS inet_pton.o"
-    EXTRA_SOURCES="$EXTRA_SOURCES inet_pton.c"
-    EXTRA_IRCIO_OBJECTS="$EXTRA_IRCIO_OBJECTS inet_pton.o"
-    EXTRA_IRCIO_SOURCES="$EXTRA_IRCIO_SOURCES inet_pton.c"
-  fi
-fi
-if test x$ac_cv_func_getnameinfo != xyes
-then
-  EXTRA_OBJECTS="$EXTRA_OBJECTS getnameinfo.o"
-  EXTRA_SOURCES="$EXTRA_SOURCES getnameinfo.c"
-  if test x$ac_cv_func_inet_ntop != xyes
-  then
-    EXTRA_OBJECTS="$EXTRA_OBJECTS inet_ntop.o"
-    EXTRA_SOURCES="$EXTRA_SOURCES inet_ntop.c"
-  fi
-fi
-
-
-
-
-
 if test x/usr/sbin:/usr/lib:/usr/ucblib:/usr/local/sbin:/usr/pkg/sbin = x; then _PATH=$PATH; else _PATH=/usr/sbin:/usr/lib:/usr/ucblib:/usr/local/sbin:/usr/pkg/sbin; fi
 if test -z "$SENDMAIL"; then
   # Extract the first word of `sendmail', so it can be a program name with args.
diff -Nru ircii-20190117/configure.in ircii-20210314/configure.in
--- ircii-20190117/configure.in	2019-01-18 11:29:41.000000000 +0100
+++ ircii-20210314/configure.in	2021-03-14 19:32:27.000000000 +0100
@@ -1,6 +1,6 @@
 # configure.in for ircii
 dnl
-dnl Copyright (c) 1993-2019 Matthew R. Green.
+dnl Copyright (c) 1993-2021 Matthew R. Green.
 dnl All rights reserved.
 dnl
 dnl Redistribution and use in source and binary forms, with or without
@@ -31,10 +31,10 @@
 dnl thanks to the screen 3.3 configure.in for giving me examples to
 dnl work from and steal ;)
 dnl
-dnl @(#)$eterna: configure.in,v 1.221 2019/01/16 00:38:00 mrg Exp $
+dnl @(#)$eterna: configure.in,v 1.228 2021/03/14 18:22:31 mrg Exp $
 
 AC_PREREQ([2.69])
-AC_REVISION($Revision: 1.221 $)dnl
+AC_REVISION($Revision: 1.228 $)dnl
 AC_INIT(${srcdir}/source/irc.c)
 AC_CONFIG_HEADER(defs.h:include/defs.h.in)
 
@@ -51,12 +51,12 @@
 AC_SUBST(CATEGORIES)
 
 dnl so that the generated configure has an id.
-echo '$eterna: configure.in,v 1.221 2019/01/16 00:38:00 mrg Exp $' > /dev/null
+echo '$eterna: configure.in,v 1.228 2021/03/14 18:22:31 mrg Exp $' > /dev/null
 
 dnl So many systems seem to need this that it is better do it here automatically.
 AC_MSG_CHECKING(for prefix paths)
 AC_ARG_WITH(prefix_paths,
-[  --with-prefix-paths                Add include and library diectories from prefix],
+[  --with-prefix-paths                  Add include and library diectories from prefix],
 [ case "$withval" in
   no)
     AC_MSG_RESULT(no)
@@ -166,15 +166,13 @@
 AC_CHECK_FUNCS(\
 	getpgid getsid memmove scandir setsid strftime writev \
 	snprintf vsnprintf fputc fwrite setenv unsetenv \
-	gethostbyname2 inet_pton inet_ntop tzset waitpid iconv_open)
+	tzset waitpid iconv_open)
 
 dnl
 dnl look for get*info in libmedia
 dnl
 
-AC_CHECK_FUNC(getaddrinfo, AC_DEFINE([HAVE_GETADDRINFO], 1, [define this if you have getaddrinfo(3)]),
-  AC_CHECK_LIB(media, getaddrinfo, LIBS="$LIBS -lmedia"))
-AC_CHECK_FUNC(getnameinfo, AC_DEFINE([HAVE_GETNAMEINFO], 1, [define this if you have getnameinfo(3)]),)
+AC_CHECK_LIB(media, getaddrinfo, LIBS="$LIBS -lmedia")
 
 AC_HEADER_TIME
 
@@ -192,13 +190,6 @@
     int X = sin.sin_len ],
   [AC_DEFINE([HAVE_SOCKADDR_SA_LEN], 1, [define this if your struct sockaddr has a sa_len member])])
 
-AC_MSG_TRY_COMPILE(for struct addrinfo, ircii_cv_HAVE_ADDRINFO, [
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netdb.h> ],
-  [ struct addrinfo X ],
-  [AC_DEFINE([HAVE_ADDRINFO], 1, [define this if you have struct addrinfo])])
-
 AC_MSG_TRY_COMPILE(for socklen_t, ircii_cv_HAVE_SOCKLEN_T, [
 #include <sys/types.h>
 #include <sys/socket.h> ], [ socklen_t X ], [AC_DEFINE([HAVE_SOCKLEN_T], 1, [define this if you have socklen_t])])
@@ -327,7 +318,7 @@
 
 AC_MSG_CHECKING(for ElectricFence library)
 AC_ARG_WITH(efence,
-[  --with-efence[=PATH]                 Compile with the ElectricFence debugging library],
+[changequote(, )  --with-efence[=PATH]                 Compile with the ElectricFence debugging library.changequote([, ])],
 [ case "$withval" in
   no)
     AC_MSG_RESULT(no)
@@ -356,7 +347,7 @@
 checkopenssl=no
 ssl_path=
 AC_ARG_WITH(openssl,
-[  --with-openssl[=PATH]                Compile with OpenSSL],
+[changequote(, )  --with-openssl[=PATH]                Compile with OpenSSL.changequote([, ])],
 [ case "$withval" in
   no)
     ;;		
@@ -400,7 +391,7 @@
 
 AC_MSG_CHECKING(for debug flags)
 AC_ARG_WITH(debugging,
-[  --with-debugging[=flags]             Build with debugging support],
+[changequote(, )  --with-debugging[=flags]             Build with debugging support.changequote([, ])],
 [ case "$withval" in
   no)
     AC_MSG_RESULT(no)
@@ -434,7 +425,7 @@
 
 AC_MSG_CHECKING(for warning flags)
 AC_ARG_WITH(warnings,
-[  --with-warnings[=flags]              Build with GCC warnings],
+[changequote(, )  --with-warnings[=flags]              Build with GCC warnings.changequote([, ])],
 [ case "$withval" in
   no)
     AC_MSG_RESULT(no)
@@ -454,7 +445,7 @@
 
 AC_MSG_CHECKING(for warnings as errors)
 AC_ARG_WITH(warning-errors,
-[  --with-warning-errors[=flags]        Turn warnings into errors],
+[changequote(, )  --with-warning-errors[=flags]        Turn warnings into errors.changequote([, ])],
 [ case "$withval" in
   no)
     AC_MSG_RESULT(no)
@@ -472,9 +463,77 @@
 )
 AC_SUBST(ERRORFLAGS)
 
+AC_MSG_CHECKING(for sanitizers)
+AC_ARG_WITH(sanitizer,
+[changequote(, )  --with-sanitizer[=<list>]            Use sanitizers, default ASAN.changequote([, ])],
+[ case "$withval" in
+  no)
+    AC_MSG_RESULT(no)
+    LIBSANI=
+    ;;		
+  *)
+    if test "x$withval" = xyes; then
+      withval='address'
+    fi
+    have_asan=0
+    have_lsan=0
+    have_ubsan=0
+    for val in `echo "$withval" | sed "s/,/ /"`
+    do
+      LIBSANI=
+      case "$val" in
+      asan|address)
+        FSANI=address
+        LIBSANI=asan
+        have_asan=1
+        ;;
+      lsan|leak)
+        FSANI=leak
+        LIBSANI=lsan
+        have_lsan=1
+        ;;
+      ubsan|undefined)
+        FSANI=undefined
+        LIBSANI=ubsan
+        have_ubsan=1
+        ;;
+      *)
+        AC_MSG_ERROR(Sanitizer support for address, leak, and undefined behaviour only.)
+        ;;
+      esac
+    done
+    if test "$have_asan" -eq 1 -a "$have_lsan" -eq 1; then
+      AC_MSG_ERROR(Do not combine address and leak sanitizers.)
+    fi
+    list=""
+    sep=""
+    if test "$have_asan" -eq 1; then
+      CFLAGS="$CFLAGS -fsanitize=address"
+      LIBS="$LIBS -lasan"
+      list="$list$sep"address
+      sep=" "
+    fi
+    if test "$have_lsan" -eq 1; then
+      CFLAGS="$CFLAGS -fsanitize=leak"
+      LIBS="$LIBS -llsan"
+      list="$list$sep"leak
+      sep=" "
+    fi
+    if test "$have_ubsan" -eq 1; then
+      CFLAGS="$CFLAGS -fsanitize=undefined"
+      LIBS="$LIBS -lubsan"
+      list="$list$sep"undefined
+      sep=" "
+    fi
+    AC_MSG_RESULT($list)
+    ;;
+  esac ],
+  AC_MSG_RESULT(no)
+)
+
 AC_MSG_CHECKING(for emacs meta keys)
 AC_ARG_WITH(emacs-meta-keys,
-[  --with-emacs-meta-keys             Enable Emacs meta key support],
+[changequote(, )  --with-emacs-meta-keys               Enable Emacs meta key support.changequote([, ])],
 [ case "$withval" in
   no)
     AC_MSG_RESULT(no)
@@ -489,7 +548,7 @@
 
 AC_MSG_CHECKING(paranoia status)
 AC_ARG_WITH(paranoid,
-[  --with-paranoid                    Sets the compile-time paranoid flag],
+[changequote(, )  --with-paranoid                      Sets the compile-time paranoid flag.changequote([, ])],
 [ AC_MSG_RESULT(yes)
   AC_DEFINE_UNQUOTED([PARANOID], 1, [define this if you want to be paranoid]) ],
   AC_MSG_RESULT(none)
@@ -520,10 +579,10 @@
 
 AC_MSG_CHECKING(for default server)
 AC_ARG_WITH(default-server,
-[  --with-default-server=SERVER[:PORT]  Connect to SERVER by default],
+[changequote(, )  --with-default-server=SERVER[:PORT]  Connect to SERVER by default.changequote([, ])],
 [ if test "$withval"; then
     AC_MSG_RESULT($withval)
-    AC_DEFINE_UNQUOTED([DEFAULT_SERVER], ["$withval"], [define this to be the name[:port] of the default server])
+    AC_DEFINE_UNQUOTED([DEFAULT_SERVER], ["$withval"], [define this to be the name<:port> of the default server])
   else
     AC_MSG_RESULT(none)
   fi ],
@@ -537,7 +596,7 @@
 AC_MSG_CHECKING(for default window resize method)
 defval=1
 AC_ARG_WITH(default-resize-method,
-[  --with-default-resize-method[=type]  Either "old" or "new"],
+[  --with-default-resize-method[=type]    Either "old" or "new"],
 [ case "$withval" in
   new|old)
     AC_MSG_RESULT($withval)
@@ -579,7 +638,7 @@
 
 AC_MSG_CHECKING(whether to support SOCKS)
 AC_ARG_WITH(socks,
-[  --with-socks                       Compile with SOCKS firewall traversal support],
+[  --with-socks                         Compile with SOCKS firewall traversal support],
 [ case "$withval" in
   no)
     AC_MSG_RESULT(no)
@@ -601,7 +660,7 @@
 if test "x$socks" = "x"; then
 	AC_MSG_CHECKING(whether to support SOCKS5)
 	AC_ARG_WITH(socks5,
-	[  --with-socks5[=PATH]                 Compile with SOCKS5 firewall traversal support],
+	[changequote(, )  --with-socks5[=PATH]                 Compile with SOCKS5 firewall traversal support.changequote([, ])],
 	[ case "$withval" in
 	  no)
 	    AC_MSG_RESULT(no)
@@ -609,8 +668,9 @@
 	  *)
 	    AC_MSG_RESULT(yes)
 	    socks=5
+	    socks5lib=""
 	    if test "x$withval" = "xyes"; then
-	      withval="-lsocks5"
+	      socks5lib="-lsocks5"
 	    else
 	      if test -d "$withval"; then
 		if test -d "$withval/include"; then
@@ -619,13 +679,15 @@
 		  CFLAGS="$CFLAGS -I$withval"
 		fi
 	        if test -d "$withval/lib"; then
-		  withval="-L$withval/lib -lsocks5"
+		  socks5lib="-L$withval/lib -lsocks5"
 		else
-		  withval="-L$withval -lsocks5"
+		  socks5lib="-L$withval -lsocks5"
 		fi
+	      else
+		socks5lib="$withval"
 	      fi
 	    fi
-	    LIBS="$withval $LIBS"
+	    LIBS="$socks5lib $LIBS"
 	    # If Socks was compiled with Kerberos support, we will need
 	    # to link against kerberos libraries.  Temporarily append
 	    # to LIBS.  This is harmless if there is no kerberos support.
@@ -645,7 +707,7 @@
 if test "x$socks" = "x"; then
 	AC_MSG_CHECKING(whether to support SOCKS4)
 	AC_ARG_WITH(socks4,
-	[  --with-socks4[=PATH]                 Compile with SOCKS4 firewall traversal support],
+	[changequote(, )  --with-socks4[=PATH]                 Compile with SOCKS4 firewall traversal support.changequote([, ])],
 	[ case "$withval" in
 	  no)
 	    AC_MSG_RESULT(no)
@@ -685,7 +747,7 @@
 
 AC_MSG_CHECKING(for non-blocking)
 AC_ARG_WITH(non-blocking,
-[  --with-non-blocking=[TYPE]           Use TYPE non-blocking, yes or no],
+[changequote(, )  --with-non-blocking=[TYPE]           Use TYPE non-blocking, yes or no.changequote([, ])],
 [
   case "$withval" in
   no|none)
@@ -711,156 +773,6 @@
   AC_DEFINE([NON_BLOCKING_CONNECTS], 1, [define this to use non-blocking connects. Precluded by SOCKS])
 fi
 
-have_rfc2553_netdb=no
-if test $ac_cv_func_getaddrinfo = yes -a ! -n "$socks"; then
-	AC_MSG_TRY_COMPILE(for AI_NUMERICHOST,
-	    ircii_cv_have_ai_numerichost, [
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netdb.h> ],
-	    [ int X = AI_NUMERICHOST ], [ have_rfc2553_netdb=yes ])
-fi
-
-AC_MSG_CHECKING([whether to enable ipv6])
-if test "x$socks" = "x4" -o "x$socks" = "x5"; then
-AC_MSG_RESULT(no, bacause you enabled SOCKS$socks support)
-else
-  AC_ARG_ENABLE(ipv6,
-[  --enable-ipv6           Enable ipv6 (with ipv4) support
-  --disable-ipv6          Disable ipv6 support],
-[ case "$enableval" in
-  no)
-       AC_MSG_RESULT(no)
-       ipv6=no
-       ;;
-  *)   AC_MSG_RESULT(yes)
-       ipv6=yes
-       ;;
-  esac ])
-
-  AC_MSG_TRY_COMPILE(for AF_INET6, ircii_cv_HAVE_AF_INET6, [
-#include <sys/types.h>
-#include <sys/socket.h> ],
-    [ if (socket(AF_INET6, SOCK_STREAM, 0) < 0)
-        exit(1); ],
-    [ipv6=yes])
-
-if test -n "$ipv6"
-then
-  AC_DEFINE([INET6], 1, [define this if you have IPv6 API support])
-fi
-
-fi # socks = x[45]
-
-AC_MSG_CHECKING(for working getaddrinfo())
-if test $have_rfc2553_netdb = yes; then
-	AC_DEFINE([HAVE_RFC2553_NETDB], 1, [define this if you have RFC 2553 <netdb.h> (IPv6)])
-  AC_TRY_RUN([
-#include <sys/types.h>
-#include <netdb.h>
-#include <string.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-
-main()
-{
-  int passive, gaierr, inet4 = 0, inet6 = 0;
-  struct addrinfo hints, *ai, *aitop;
-  char straddr[INET6_ADDRSTRLEN], strport[16];
-
-  for (passive = 0; passive <= 1; passive++) {
-    memset(&hints, 0, sizeof(hints));
-    hints.ai_family = AF_UNSPEC;
-    hints.ai_flags = passive ? AI_PASSIVE : 0;
-    hints.ai_socktype = SOCK_STREAM;
-    if ((gaierr = getaddrinfo(NULL, "54321", &hints, &aitop)) != 0) {
-      (void)gai_strerror(gaierr);
-      goto bad;
-    }
-    for (ai = aitop; ai; ai = ai->ai_next) {
-      if (ai->ai_addr == NULL ||
-          ai->ai_addrlen == 0 ||
-          getnameinfo(ai->ai_addr, ai->ai_addrlen,
-                      straddr, sizeof(straddr), strport, sizeof(strport),
-                      NI_NUMERICHOST|NI_NUMERICSERV) != 0) {
-        goto bad;
-      }
-      switch (ai->ai_family) {
-      case AF_INET:
-        if (strcmp(strport, "54321") != 0) {
-          goto bad;
-        }
-        if (passive) {
-          if (strcmp(straddr, "0.0.0.0") != 0) {
-            goto bad;
-          }
-        } else {
-          if (strcmp(straddr, "127.0.0.1") != 0) {
-            goto bad;
-          }
-        }
-        inet4++;
-        break;
-      case AF_INET6:
-        if (strcmp(strport, "54321") != 0) {
-          goto bad;
-        }
-        if (passive) {
-          if (strcmp(straddr, "::") != 0) {
-            goto bad;
-          }
-        } else {
-          if (strcmp(straddr, "::1") != 0) {
-            goto bad;
-          }
-        }
-        inet6++;
-        break;
-      case AF_UNSPEC:
-        goto bad;
-        break;
-      default:
-        /* another family support? */
-        break;
-      }
-    }
-  }
-
-  if (inet4 != 0 && inet4 != 2)
-    goto bad;
-  if (inet6 != 0 && inet6 != 2)
-    goto bad;
-
-  if (aitop)
-    freeaddrinfo(aitop);
-  exit(0);
-
- bad:
-  if (aitop)
-    freeaddrinfo(aitop);
-  exit(1);
-}],
-  AC_MSG_RESULT(good)
-  buggygetaddrinfo=no,
-  AC_MSG_RESULT(buggy)
-  buggygetaddrinfo=yes,
-  AC_MSG_RESULT(buggy)
-  buggygetaddrinfo=yes)
-
-  if test "x$buggygetaddrinfo" = "xyes"; then
-	echo 'Using local version of getaddrinfo()'
-	ac_cv_func_getaddrinfo=no
-  fi
-
-else
-  if test $ac_cv_func_getaddrinfo = yes; then
-	AC_MSG_RESULT(no - using local version)
-  else
-	AC_MSG_RESULT(using local version)
-  fi
-  ac_cv_func_getaddrinfo=no
-fi # have_rfc2553_netdb = yes
-
 if test -n "$hpux"
 then
 	# HP-UX's pax is broken
@@ -919,49 +831,6 @@
   AC_DEFINE_UNQUOTED([ZARGS],["$ZARGS"], [define these to the ZCAT args of your choice])
 fi
 
-dnl
-dnl check if we need snprintf.c, getaddrinfo.c or getnameinfo.c
-dnl
-EXTRA_OBJECTS=
-EXTRA_SOURCES=
-EXTRA_IRCIO_OBJECTS=
-EXTRA_IRCIO_SOURCES=
-if test x$ac_cv_func_snprintf != xyes || test x$ac_cv_func_vsnprintf != xyes
-then
-  EXTRA_OBJECTS="$EXTRA_OBJECTS snprintf.o"
-  EXTRA_SOURCES="$EXTRA_SOURCES snprintf.c"
-  EXTRA_IRCIO_OBJECTS="$EXTRA_IRCIO_OBJECTS snprintf.o"
-  EXTRA_IRCIO_SOURCES="$EXTRA_IRCIO_SOURCES snprintf.c"
-fi
-if test x$ac_cv_func_getaddrinfo != xyes
-then
-  EXTRA_OBJECTS="$EXTRA_OBJECTS getaddrinfo.o"
-  EXTRA_SOURCES="$EXTRA_SOURCES getaddrinfo.c"
-  EXTRA_IRCIO_OBJECTS="$EXTRA_IRCIO_OBJECTS getaddrinfo.o"
-  EXTRA_IRCIO_SOURCES="$EXTRA_IRCIO_SOURCES getaddrinfo.c"
-  if test x$ac_cv_func_inet_pton != xyes
-  then
-    EXTRA_OBJECTS="$EXTRA_OBJECTS inet_pton.o"
-    EXTRA_SOURCES="$EXTRA_SOURCES inet_pton.c"
-    EXTRA_IRCIO_OBJECTS="$EXTRA_IRCIO_OBJECTS inet_pton.o"
-    EXTRA_IRCIO_SOURCES="$EXTRA_IRCIO_SOURCES inet_pton.c"
-  fi
-fi
-if test x$ac_cv_func_getnameinfo != xyes
-then
-  EXTRA_OBJECTS="$EXTRA_OBJECTS getnameinfo.o"
-  EXTRA_SOURCES="$EXTRA_SOURCES getnameinfo.c"
-  if test x$ac_cv_func_inet_ntop != xyes
-  then
-    EXTRA_OBJECTS="$EXTRA_OBJECTS inet_ntop.o"
-    EXTRA_SOURCES="$EXTRA_SOURCES inet_ntop.c"
-  fi
-fi
-AC_SUBST(EXTRA_OBJECTS)
-AC_SUBST(EXTRA_SOURCES)
-AC_SUBST(EXTRA_IRCIO_OBJECTS)
-AC_SUBST(EXTRA_IRCIO_SOURCES)
-
 AC_FIND_PROGRAM(SENDMAIL,sendmail,/usr/sbin:/usr/lib:/usr/ucblib:/usr/local/sbin:/usr/pkg/sbin)
 
 AC_SUBST(RM)
diff -Nru ircii-20190117/debian/changelog ircii-20210314/debian/changelog
--- ircii-20190117/debian/changelog	2019-02-21 05:35:56.000000000 +0100
+++ ircii-20210314/debian/changelog	2021-04-11 18:19:42.000000000 +0200
@@ -1,3 +1,30 @@
+ircii (20210314-1) unstable; urgency=medium
+
+  * QA Upload.
+  [ Debian Janitor ]
+  * Set debhelper-compat version in Build-Depends.
+  * Changes Urgency by urgency in changelog file.
+
+  * New upstream release.
+    Fix (CVE-2021-29376). (Closes: #986214).
+  * debian/control
+    + Bump Standards-Version to 4.5.1. (no changes).
+    + Bump Debhelper-compat to 13.
+    + Add Rules-Requires-Root: no.
+  * debian/patches
+    + Refresh:
+      + 0008-fix-spelling-error.diff
+      + 0003-Add-ioption-to-local-include-paths-so-they-do-not-co.patch
+      + 0004-absolute-path-for-motd-and-servers-file-and-other-de.patch
+      + 0006-fix-some-spelling-errors.patch
+  * debian/rules
+    + Remove --as-needed linker flag.
+  * debian/watch
+    + Update to version 4.
+  * Update copyright file.
+
+ -- Daniel Echeverri <epsilon@debian.org>  Sun, 11 Apr 2021 11:19:42 -0500
+
 ircii (20190117-1) unstable; urgency=medium
 
   * QA upload.
@@ -242,25 +269,25 @@
 
  -- Bernd Eckenfels <ecki@debian.org>  Wed,  8 Aug 2001 02:55:50 +0200
 
-ircii (20010612-3) unstable; Urgency=low
+ircii (20010612-3) unstable; urgency=low
 
   * added resize fix bug from matthew (Closes: 107763)
 
  -- Bernd Eckenfels <ecki@debian.org>  Mon,  6 Aug 2001 19:20:10 +0200
 
-ircii (20010612-2) unstable; Urgency=low
+ircii (20010612-2) unstable; urgency=low
 
   * fixed build dependency on curses (Closes: #107110)
 
  -- Bernd Eckenfels <ecki@debian.org>  Tue, 31 Jul 2001 01:18:51 +0200
 
-ircii (20010612-1) unstable; Urgency=low
+ircii (20010612-1) unstable; urgency=low
 
   * new upstream version, may fix a lot of bugs (colour)
 
  -- Bernd Eckenfels <ecki@debian.org>  Sun, 29 Jul 2001 00:44:19 +0200
 
-ircii (4.4Z-3) unstable; Urgency=high
+ircii (4.4Z-3) unstable; urgency=high
 
   * Security: this release will remove . from the LOAD_PATH. Note: it
     still has "~/.irc" as the first element to actually allow to overwrite
@@ -270,20 +297,20 @@
 
  -- Bernd Eckenfels <ecki@debian.org>  Mon, 12 Feb 2001 03:13:48 +0100
 
-ircii (4.4Z-2) unstable; Urgency=low
+ircii (4.4Z-2) unstable; urgency=low
 
   * added strmcpy patch to keep it from segfaulting from David Murn
     fixes bug #72799. Reported Upstream.
 
  -- Bernd Eckenfels <ecki@debian.org>  Sat, 30 Sep 2000 02:35:17 +0200
 
-ircii (4.4Z-1) unstable; Urgency=low
+ircii (4.4Z-1) unstable; urgency=low
 
   * new upstream version, closes bug #71496
 
  -- Bernd Eckenfels <ecki@debian.org>  Wed, 13 Sep 2000 02:10:55 +0200
 
-ircii (4.4U-2) unstable; Urgency=low
+ircii (4.4U-2) unstable; urgency=low
 
   * new upstream version
   * includes IPv6 support now!
@@ -291,7 +318,7 @@
 
  -- Bernd Eckenfels <ecki@debian.org>  Sat,  1 Jul 2000 14:43:01 +0200
 
-ircii (4.4M-1) frozen unstable; Urgency=high
+ircii (4.4M-1) frozen unstable; urgency=high
 
   * fixed dcc chat exploit from bladi & aLmUDeNa
   * still contains noinfect patch and additional support for absolute path
@@ -302,31 +329,31 @@
 
 Old Changelog:
 
-ircii (4.4L-6) unstable; Urgency=low, Closes=35198
+ircii (4.4L-6) unstable; urgency=low, Closes=35198
 
   * upstream colour support is activated by SET COLOUR (#50521)
 
  -- Bernd Eckenfels <ecki@debian.org>  Sat, 20 Nov 1999 19:37:26 +0100
 
-ircii (4.4L-5) unstable; Urgency=low, Closes=35198
+ircii (4.4L-5) unstable; urgency=low, Closes=35198
 
   * use protocols/talkd.h (#35198)
 
  -- Bernd Eckenfels <ecki@debian.org>  Wed,  3 Nov 1999 03:46:36 +0100
 
-ircii (4.4L-4) unstable; Urgency=low, Closes=37097 44700
+ircii (4.4L-4) unstable; urgency=low, Closes=37097 44700
 
   * reupload because of missing source in first try to non-us
 
  -- Bernd Eckenfels <ecki@debian.org>  Sun,  3 Oct 1999 23:07:39 +0200
 
-ircii (4.4L-3) unstable; Urgency=low, Closes=37097 44700
+ircii (4.4L-3) unstable; urgency=low, Closes=37097 44700
 
   * remove old link in /isr/lib/irc/ircII.servers before any other checks
 
  -- Bernd Eckenfels <ecki@debian.org>  Sat, 25 Sep 1999 23:08:11 +0200
 
-ircii (4.4L-2) unstable; Urgency=low, Closes=37097 44700
+ircii (4.4L-2) unstable; urgency=low, Closes=37097 44700
 
   * fixed bug in my bufffer-overflow fix which made /on fail
 
diff -Nru ircii-20190117/debian/compat ircii-20210314/debian/compat
--- ircii-20190117/debian/compat	2019-02-21 05:16:27.000000000 +0100
+++ ircii-20210314/debian/compat	1970-01-01 01:00:00.000000000 +0100
@@ -1 +0,0 @@
-12
diff -Nru ircii-20190117/debian/control ircii-20210314/debian/control
--- ircii-20190117/debian/control	2019-02-21 05:16:22.000000000 +0100
+++ ircii-20210314/debian/control	2021-04-11 18:19:42.000000000 +0200
@@ -3,13 +3,14 @@
 Priority: optional
 Maintainer: Debian QA Group <packages@qa.debian.org>
 Build-Depends:
- debhelper (>= 12),
+ debhelper-compat (= 13),
  libncurses5-dev,
  libssl-dev,
-Standards-Version: 4.3.0
+Standards-Version: 4.5.1
 Homepage: http://www.eterna.com.au/ircii/
 Vcs-Git: https://salsa.debian.org/debian/ircii.git
 Vcs-Browser: https://salsa.debian.org/debian/ircii
+Rules-Requires-Root: no
 
 Package: ircii
 Architecture: any
diff -Nru ircii-20190117/debian/copyright ircii-20210314/debian/copyright
--- ircii-20190117/debian/copyright	2019-02-09 02:16:29.000000000 +0100
+++ ircii-20210314/debian/copyright	2021-04-11 18:19:42.000000000 +0200
@@ -26,23 +26,6 @@
 Copyright: 2014 Douglas A. Lewis <dalewis@cs.Buffalo.EDU>
 License: public-domain
 
-Files: source/getaddrinfo.c
-Copyright: 1995, 1996, 1997, and 1998 WIDE Project.
-License: BSD-3-Clause
-
-Files: source/snprintf.c
-Copyright: 1995 Patrick Powell <papowell@astart.com>
- 1996-1997 Brandon Long <blong@fiction.net>
- 1998 Thomas Roessler <roessler@guug.de>
- 1998 Michael Elkins <me@cs.hmc.edu>
- 1998 Andrew Tridgell <tridge@samba.org>
- 1999 Luke Mewburn <lukem@netbsd.org>
-License: BSD-3-Clause
-
-Files: source/inet_ntop.c source/inet_pton.c
-Copyright: 1996 Internet Software Consortium
-License: MIT-Old-Style-with-legal-disclaimer-2
-
 Files: source/scandir.c
 Copyright: 1983 Regents of the University of California
 License: Custom
@@ -135,17 +118,3 @@
  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  POSSIBILITY OF SUCH DAMAGE.
-
-License: MIT-Old-Style-with-legal-disclaimer-2
- Permission to use, copy, modify, and distribute this software for any
- purpose with or without fee is hereby granted, provided that the above
- copyright notice and this permission notice appear in all copies.
- .
- THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
- ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
- OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
- CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
- DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
- PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
- ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
- SOFTWARE.
diff -Nru ircii-20190117/debian/patches/0003-Add-ioption-to-local-include-paths-so-they-do-not-co.patch ircii-20210314/debian/patches/0003-Add-ioption-to-local-include-paths-so-they-do-not-co.patch
--- ircii-20190117/debian/patches/0003-Add-ioption-to-local-include-paths-so-they-do-not-co.patch	2019-02-09 02:19:30.000000000 +0100
+++ ircii-20210314/debian/patches/0003-Add-ioption-to-local-include-paths-so-they-do-not-co.patch	2021-04-11 18:19:42.000000000 +0200
@@ -13,7 +13,7 @@
 
 --- a/Makefile.in
 +++ b/Makefile.in
-@@ -317,7 +317,7 @@
+@@ -315,7 +315,7 @@
  IRCFLUSH_SOURCES = ircflush.c
  IRCFLUSH_OBJECTS = ircflush.o ircsig.o
  
diff -Nru ircii-20190117/debian/patches/0004-absolute-path-for-motd-and-servers-file-and-other-de.patch ircii-20210314/debian/patches/0004-absolute-path-for-motd-and-servers-file-and-other-de.patch
--- ircii-20190117/debian/patches/0004-absolute-path-for-motd-and-servers-file-and-other-de.patch	2019-02-09 02:29:37.000000000 +0100
+++ ircii-20210314/debian/patches/0004-absolute-path-for-motd-and-servers-file-and-other-de.patch	2021-04-11 18:19:42.000000000 +0200
@@ -13,7 +13,7 @@
 
 --- a/source/irc.c
 +++ b/source/irc.c
-@@ -1021,8 +1021,13 @@
+@@ -1001,8 +1001,13 @@
  		u_char	*motd = NULL;
  		int	des;
  
diff -Nru ircii-20190117/debian/patches/0006-fix-some-spelling-errors.patch ircii-20210314/debian/patches/0006-fix-some-spelling-errors.patch
--- ircii-20190117/debian/patches/0006-fix-some-spelling-errors.patch	2019-02-09 02:31:18.000000000 +0100
+++ ircii-20210314/debian/patches/0006-fix-some-spelling-errors.patch	2021-04-11 18:19:42.000000000 +0200
@@ -64,7 +64,7 @@
  					new_free(&cmd);
  					return;
  				}
-@@ -1551,7 +1551,7 @@
+@@ -1554,7 +1554,7 @@
  		{
  			if (!(nick = recv_nick))
  			{
@@ -95,7 +95,7 @@
  
 --- a/source/menu.c
 +++ b/source/menu.c
-@@ -220,7 +220,7 @@
+@@ -223,7 +223,7 @@
  					OptionsList[FuncNum].func;
  		}
  		else
diff -Nru ircii-20190117/debian/patches/0008-fix-spelling-error.diff ircii-20210314/debian/patches/0008-fix-spelling-error.diff
--- ircii-20190117/debian/patches/0008-fix-spelling-error.diff	2019-02-09 02:18:32.000000000 +0100
+++ ircii-20210314/debian/patches/0008-fix-spelling-error.diff	2021-04-11 18:19:42.000000000 +0200
@@ -15,7 +15,7 @@
  	}
 --- a/source/server.c
 +++ b/source/server.c
-@@ -1653,8 +1653,8 @@
+@@ -1654,8 +1654,8 @@
  		{
  		case -2:
  			/* shouldn't happen! SSL retry */
diff -Nru ircii-20190117/debian/rules ircii-20210314/debian/rules
--- ircii-20190117/debian/rules	2019-02-21 04:47:03.000000000 +0100
+++ ircii-20210314/debian/rules	2021-04-11 18:19:42.000000000 +0200
@@ -5,7 +5,6 @@
 
 # see FEATURE AREAS in dpkg-buildflags(1)
 export DEB_BUILD_MAINT_OPTIONS = hardening=+all
-export DEB_LDFLAGS_MAINT_APPEND = -Wl,--as-needed
 
 include /usr/share/dpkg/pkg-info.mk
 
diff -Nru ircii-20190117/debian/watch ircii-20210314/debian/watch
--- ircii-20190117/debian/watch	2019-02-09 02:40:39.000000000 +0100
+++ ircii-20210314/debian/watch	2021-04-11 18:19:42.000000000 +0200
@@ -1,3 +1,3 @@
-version=3
+version=4
 http://ircii.warped.com/ircii-(\d\S+)\.tar\.(?:bz2|gz|xz) 
 
diff -Nru ircii-20190117/doc/Copyright ircii-20210314/doc/Copyright
--- ircii-20190117/doc/Copyright	2019-01-18 11:29:41.000000000 +0100
+++ ircii-20210314/doc/Copyright	2021-03-14 19:32:27.000000000 +0100
@@ -1,9 +1,9 @@
-/*	$eterna: Copyright,v 1.22 2019/01/15 07:44:05 mrg Exp $	*/
+/*	$eterna: Copyright,v 1.24 2021/03/02 21:41:52 mrg Exp $	*/
 
 /*
  * Copyright (c) 1990 Michael Sandrof.
  * Copyright (c) 1991, 1992 Troy Rollo.
- * Copyright (c) 1992-2019 Matthew R. Green.
+ * Copyright (c) 1992-2021 Matthew R. Green.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -Nru ircii-20190117/doc/ircii.spec ircii-20210314/doc/ircii.spec
--- ircii-20190117/doc/ircii.spec	2019-01-18 11:42:40.000000000 +0100
+++ ircii-20210314/doc/ircii.spec	2021-03-14 19:42:38.000000000 +0100
@@ -1,11 +1,11 @@
 # $eterna: ircii.spec.in,v 1.2 2019/01/18 01:39:36 mrg Exp $
 Summary: ircII is an IRC and ICB client that runs under most UNIX platforms
 Name: ircii
-Version: 20190117
+Version: 20210314
 Release: 1
 License: BSD
 Group: Networking/Chat
-Source: ftp://ircii.warped.com/pub/ircII/ircii-20190117.tar.bz2
+Source: ftp://ircii.warped.com/pub/ircII/ircii-20210314.tar.bz2
 URL: http://www.eterna.com.au/ircii/
 Vendor: The ircII Project
 Packager: The ircII Project <ircii@eterna.com.au>
@@ -30,7 +30,7 @@
 
 %files
 /usr/local/bin/irc
-/usr/local/bin/irc-20190117
+/usr/local/bin/irc-20210314
 /usr/local/bin/ircbug
 /usr/local/bin/ircflush
 /usr/local/libexec/ircio
diff -Nru ircii-20190117/help/bind/refresh_window_lastlog ircii-20210314/help/bind/refresh_window_lastlog
--- ircii-20190117/help/bind/refresh_window_lastlog	1970-01-01 01:00:00.000000000 +0100
+++ ircii-20210314/help/bind/refresh_window_lastlog	2021-03-14 19:32:27.000000000 +0100
@@ -0,0 +1,9 @@
+!	 $eterna: refresh_window_lastlog,v 1.1 2021/02/28 22:45:11 mrg Exp $
+!
+! Copyright (c) 2021  Matthew Green.
+!
+! All rights reserved.  See the HELP IRCII COPYRIGHT file for more
+! information.
+!
+Usage: BIND <key> REFRESH_WINDOW_LASTLOG
+  Redraw the window filling it from what is in the saved lastlog.
diff -Nru ircii-20190117/include/debug.h ircii-20210314/include/debug.h
--- ircii-20190117/include/debug.h	2019-01-18 11:29:41.000000000 +0100
+++ ircii-20210314/include/debug.h	2021-03-14 19:32:27.000000000 +0100
@@ -27,7 +27,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * @(#)$eterna: debug.h,v 1.32 2017/07/04 03:57:08 mrg Exp $
+ * @(#)$eterna: debug.h,v 1.33 2021/02/27 22:38:42 mrg Exp $
  */
 
 #ifndef irc__debug_h_
@@ -62,9 +62,11 @@
 	void    debug(int, char *, ...)
 			__attribute__((__format__ (__printf__, 2, 3)));
 	void	setdlevel(u_char *);
+	void	open_log_file(u_char *file);
 
 # else
 #  define Debug(level, fmt, ...)
+#  define open_log_file(file) do { /* empty */ } while (0)
 # endif /* DEBUG */
 
 #endif /* irc__debug_h_ */
diff -Nru ircii-20190117/include/defs.h.in ircii-20210314/include/defs.h.in
--- ircii-20190117/include/defs.h.in	2019-01-18 11:29:41.000000000 +0100
+++ ircii-20210314/include/defs.h.in	2021-03-14 19:32:27.000000000 +0100
@@ -6,15 +6,12 @@
 /* Use default window resize method. 0 for old method. */
 #undef DEFAULT_RESIZE_METHOD
 
-/* define this to be the name[:port] of the default server */
+/* define this to be the name<:port> of the default server */
 #undef DEFAULT_SERVER
 
 /* Define this to the random device to use */
 #undef DEV_RANDOM_PATH
 
-/* define this if you have struct addrinfo */
-#undef HAVE_ADDRINFO
-
 /* define this if you have crypt(3) */
 #undef HAVE_CRYPT
 
@@ -33,15 +30,6 @@
 /* Define to 1 if you have the `fwrite' function. */
 #undef HAVE_FWRITE
 
-/* define this if you have getaddrinfo(3) */
-#undef HAVE_GETADDRINFO
-
-/* Define to 1 if you have the `gethostbyname2' function. */
-#undef HAVE_GETHOSTBYNAME2
-
-/* define this if you have getnameinfo(3) */
-#undef HAVE_GETNAMEINFO
-
 /* Define to 1 if you have the `getpgid' function. */
 #undef HAVE_GETPGID
 
@@ -54,12 +42,6 @@
 /* Define to 1 if you have the `iconv_open' function. */
 #undef HAVE_ICONV_OPEN
 
-/* Define to 1 if you have the `inet_ntop' function. */
-#undef HAVE_INET_NTOP
-
-/* Define to 1 if you have the `inet_pton' function. */
-#undef HAVE_INET_PTON
-
 /* Define to 1 if you have the <inttypes.h> header file. */
 #undef HAVE_INTTYPES_H
 
@@ -75,9 +57,6 @@
 /* Define to 1 if you have the <process.h> header file. */
 #undef HAVE_PROCESS_H
 
-/* define this if you have RFC 2553 <netdb.h> (IPv6) */
-#undef HAVE_RFC2553_NETDB
-
 /* Define to 1 if you have the `scandir' function. */
 #undef HAVE_SCANDIR
 
@@ -168,9 +147,6 @@
 /* define this if you have usable curses.h */
 #undef INCLUDE_CURSES_H
 
-/* define this if you have IPv6 API support */
-#undef INET6
-
 /* define this if you need fchmod() */
 #undef NEED_FCHMOD
 
diff -Nru ircii-20190117/include/edit.h ircii-20210314/include/edit.h
--- ircii-20190117/include/edit.h	2019-01-18 11:29:41.000000000 +0100
+++ ircii-20210314/include/edit.h	2021-03-14 19:32:27.000000000 +0100
@@ -5,7 +5,7 @@
  *
  * Copyright (c) 1990 Michael Sandrof.
  * Copyright (c) 1991, 1992 Troy Rollo.
- * Copyright (c) 1992-2014 Matthew R. Green.
+ * Copyright (c) 1992-2021 Matthew R. Green.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,7 +31,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * @(#)$eterna: edit.h,v 1.46 2014/03/11 08:59:36 mrg Exp $
+ * @(#)$eterna: edit.h,v 1.47 2021/02/24 10:01:34 mrg Exp $
  */
 
 #ifndef irc__edit_h_
@@ -95,8 +95,7 @@
 	void	load_global(void);
 	int	loading_global(void);
 	int	whoreply_check(u_char *, u_char *, u_char *, u_char *,
-			       u_char *, u_char *, u_char *, u_char **,
-			       u_char *);
+			       u_char *, u_char *, u_char *, u_char *);
 	int	is_away_set(void);
 	u_char	*alias_buffer(void);
 	u_char	*get_invite_channel(void);
diff -Nru ircii-20190117/include/exec.h ircii-20210314/include/exec.h
--- ircii-20190117/include/exec.h	2019-01-18 11:29:41.000000000 +0100
+++ ircii-20210314/include/exec.h	2021-03-14 19:32:27.000000000 +0100
@@ -5,7 +5,7 @@
  *
  * Copyright (c) 1990 Michael Sandrof.
  * Copyright (c) 1991, 1992 Troy Rollo.
- * Copyright (c) 1992-2014 Matthew R. Green.
+ * Copyright (c) 1992-2020 Matthew R. Green.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,7 +31,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * @(#)$eterna: exec.h,v 1.35 2014/02/28 01:34:59 mrg Exp $
+ * @(#)$eterna: exec.h,v 1.36 2020/11/17 08:11:56 mrg Exp $
  */
 
 #ifndef irc__exec_h_
@@ -55,6 +55,5 @@
 	void	close_all_exec(void);
 	int	logical_to_index(u_char *);
 	void	execcmd(u_char *, u_char *, u_char *);
-	const u_char *my_sigstr(int);
 
 #endif /* irc__exec_h_ */
diff -Nru ircii-20190117/include/funny.h ircii-20210314/include/funny.h
--- ircii-20190117/include/funny.h	2019-01-18 11:29:41.000000000 +0100
+++ ircii-20210314/include/funny.h	2021-03-14 19:32:27.000000000 +0100
@@ -5,7 +5,7 @@
  *
  * Copyright (c) 1990 Michael Sandrof.
  * Copyright (c) 1991, 1992 Troy Rollo.
- * Copyright (c) 1992-2014 Matthew R. Green.
+ * Copyright (c) 1992-2021 Matthew R. Green.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,7 +31,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * @(#)$eterna: funny.h,v 1.17 2014/02/05 12:00:02 mrg Exp $
+ * @(#)$eterna: funny.h,v 1.18 2021/02/24 10:01:34 mrg Exp $
  */
 
 #ifndef irc__funny_h_
@@ -48,9 +48,9 @@
 	void	funny_match(u_char *);
 	void	reinstate_user_modes(void);
 	void	funny_print_widelist(void);
-	void	funny_list(u_char *, u_char **);
+	void	funny_list(u_char *, u_char *, u_char **);
 	void	funny_mode(u_char *, u_char **);
-	void	funny_namreply(u_char *, u_char **);
+	void	funny_namreply(u_char *, u_char *, u_char **);
 	void	update_user_mode(u_char *);
 
 #endif /* irc__funny_h_ */
diff -Nru ircii-20190117/include/irc.h ircii-20210314/include/irc.h
--- ircii-20190117/include/irc.h	2019-01-18 11:29:41.000000000 +0100
+++ ircii-20210314/include/irc.h	2021-03-14 19:32:27.000000000 +0100
@@ -31,7 +31,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * @(#)$eterna: irc.h,v 1.128 2019/01/16 00:38:00 mrg Exp $
+ * @(#)$eterna: irc.h,v 1.130 2021/02/27 22:38:42 mrg Exp $
  */
 
 #ifndef irc__irc_h
diff -Nru ircii-20190117/include/irc_std.h ircii-20210314/include/irc_std.h
--- ircii-20190117/include/irc_std.h	2019-01-18 11:29:41.000000000 +0100
+++ ircii-20210314/include/irc_std.h	2021-03-14 19:32:27.000000000 +0100
@@ -30,7 +30,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * @(#)$eterna: irc_std.h,v 1.63 2019/01/16 00:38:00 mrg Exp $
+ * @(#)$eterna: irc_std.h,v 1.64 2021/03/14 18:22:31 mrg Exp $
  */
 
 #ifndef irc__irc_std_h
@@ -85,107 +85,10 @@
 
 #define IS_ABSOLUTE_PATH(file) ((file)[0] == '/')
 
-#if !defined(HAVE_RFC2553_NETDB)
-
-				/* RFC 2553 */
-#undef	EAI_ADDRFAMILY
-#define	EAI_ADDRFAMILY	 1	/* address family for hostname not supported */
-#undef	EAI_AGAIN
-#define	EAI_AGAIN	 2	/* temporary failure in name resolution */
-#undef	EAI_BADFLAGS
-#define	EAI_BADFLAGS	 3	/* invalid value for ai_flags */
-#undef	EAI_FAIL
-#define	EAI_FAIL	 4	/* non-recoverable failure in name resolution */
-#undef	EAI_FAMILY
-#define	EAI_FAMILY	 5	/* ai_family not supported */
-#undef	EAI_MEMORY
-#define	EAI_MEMORY	 6	/* memory allocation failure */
-#undef	EAI_NODATA
-#define	EAI_NODATA	 7	/* no address associated with hostname */
-#undef	EAI_NONAME
-#define	EAI_NONAME	 8	/* hostname nor servname provided, or not known */
-#undef	EAI_SERVICE
-#define	EAI_SERVICE	 9	/* servname not supported for ai_socktype */
-#undef	EAI_SOCKTYPE
-#define	EAI_SOCKTYPE	10	/* ai_socktype not supported */
-#undef	EAI_SYSTEM
-#define	EAI_SYSTEM	11	/* system error returned in errno */
-
-				/* KAME extensions? */
-#undef	EAI_BADHINTS
-#define	EAI_BADHINTS	12
-#undef	EAI_PROTOCOL
-#define	EAI_PROTOCOL	13
-#undef	EAI_MAX
-#define	EAI_MAX		14
-
-				/* RFC 2553 */
-#undef	NI_MAXHOST
-#define	NI_MAXHOST	1025
-#undef	NI_MAXSERV
-#define	NI_MAXSERV	32
-
-#undef	NI_NOFQDN
-#define	NI_NOFQDN	0x00000001
-#undef	NI_NUMERICHOST
-#define	NI_NUMERICHOST	0x00000002
-#undef	NI_NAMEREQD
-#define	NI_NAMEREQD	0x00000004
-#undef	NI_NUMERICSERV
-#define	NI_NUMERICSERV	0x00000008
-#undef	NI_DGRAM
-#define	NI_DGRAM	0x00000010
-
-				/* RFC 2553 */
-#undef	AI_PASSIVE
-#define	AI_PASSIVE	0x00000001 /* get address to use bind() */
-#undef	AI_CANONNAME
-#define	AI_CANONNAME	0x00000002 /* fill ai_canonname */
-
-				/* KAME extensions ? */
-#undef	AI_NUMERICHOST
-#define	AI_NUMERICHOST	0x00000004 /* prevent name resolution */
-#undef	AI_MASK
-#define	AI_MASK		(AI_PASSIVE | AI_CANONNAME | AI_NUMERICHOST)
-
-				/* RFC 2553 */
-#undef	AI_ALL
-#define	AI_ALL		0x00000100 /* IPv6 and IPv4-mapped (with AI_V4MAPPED) */
-#undef	AI_V4MAPPED_CFG
-#define	AI_V4MAPPED_CFG	0x00000200 /* accept IPv4-mapped if kernel supports */
-#undef	AI_ADDRCONFIG
-#define	AI_ADDRCONFIG	0x00000400 /* only if any address is assigned */
-#undef	AI_V4MAPPED
-#define	AI_V4MAPPED	0x00000800 /* accept IPv4-mapped IPv6 address */
-
-#endif /* ! HAVE_RFC2553_NETDB */
-
 #if !defined(HAVE_SOCKLEN_T)
 typedef unsigned int socklen_t;
 #endif /* HAVE_SOCKLEN_T */
 
-#if !defined(HAVE_RFC2553_NETDB) && !defined(HAVE_ADDRINFO)
-
-struct addrinfo {
-	int	ai_flags;	/* AI_PASSIVE, AI_CANONNAME, AI_NUMERICHOST */
-	int	ai_family;	/* PF_xxx */
-	int	ai_socktype;	/* SOCK_xxx */
-	int	ai_protocol;	/* 0 or IPPROTO_xxx for IPv4 and IPv6 */
-	size_t	ai_addrlen;	/* length of ai_addr */
-	char	*ai_canonname;	/* canonical name for hostname */
-	struct sockaddr *ai_addr;	/* binary address */
-	struct addrinfo *ai_next;	/* next structure in linked list */
-};
-
-int     getaddrinfo(const char *, const char *,
-		const struct addrinfo *, struct addrinfo **);
-int     getnameinfo(const struct sockaddr *, socklen_t, char *,
-		size_t, char *, size_t, int);
-void    freeaddrinfo(struct addrinfo *);
-char   *gai_strerror(int);
-
-#endif /* ! HAVE_RFC2553_NETDB && ! HAVE_ADDRINFO */
-
 #ifndef HAVE_SNPRINTF
 int snprintf(char *str, size_t count, const char *fmt, ...);
 #endif /* HAVE_SNPRINTF */
diff -Nru ircii-20190117/include/notice.h ircii-20210314/include/notice.h
--- ircii-20190117/include/notice.h	2019-01-18 11:29:41.000000000 +0100
+++ ircii-20210314/include/notice.h	2021-03-14 19:32:27.000000000 +0100
@@ -3,7 +3,7 @@
  *
  * written by matthew green
  * 
- * Copyright (c) 2014 Matthew R. Green.
+ * Copyright (c) 2014-2021 Matthew R. Green.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -29,13 +29,13 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * @(#)$eterna: notice.h,v 1.1 2014/02/05 07:20:11 mrg Exp $
+ * @(#)$eterna: notice.h,v 1.2 2021/02/24 10:01:34 mrg Exp $
  */
 
 #ifndef irc__notice_h_
 # define irc__notice_h_
 
-	void	parse_notice(u_char *, u_char **);
+	void	parse_notice(u_char *, u_char *, u_char **);
 	void	load_ircrc(void);
 	void	load_ircquick(void);
 	void	got_initial_version(u_char *);
diff -Nru ircii-20190117/include/numbers.h ircii-20210314/include/numbers.h
--- ircii-20190117/include/numbers.h	2019-01-18 11:29:41.000000000 +0100
+++ ircii-20210314/include/numbers.h	2021-03-14 19:32:27.000000000 +0100
@@ -5,7 +5,7 @@
  *
  * Copyright (c) 1990 Michael Sandrof.
  * Copyright (c) 1991, 1992 Troy Rollo.
- * Copyright (c) 1992-2014 Matthew R. Green.
+ * Copyright (c) 1992-2021 Matthew R. Green.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,7 +31,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * @(#)$eterna: numbers.h,v 1.18 2014/02/28 23:31:48 mrg Exp $
+ * @(#)$eterna: numbers.h,v 1.19 2021/02/24 10:01:34 mrg Exp $
  */
 
 #ifndef irc__numbers_h_
@@ -39,7 +39,7 @@
 
 	u_char	*numeric_banner(void);
 	void	display_msg(u_char *, u_char **);
-	void	numbered_command(u_char *, int, u_char **);
+	void	numbered_command(u_char *, u_char *, int, u_char **);
 	int	current_numeric(void);
 
 #endif /* irc__numbers_h_ */
diff -Nru ircii-20190117/include/parse.h ircii-20210314/include/parse.h
--- ircii-20190117/include/parse.h	2019-01-18 11:29:41.000000000 +0100
+++ ircii-20210314/include/parse.h	2021-03-14 19:32:27.000000000 +0100
@@ -3,7 +3,7 @@
  *
  * written by matthew green
  * 
- * Copyright (c) 1993-2016 Matthew R. Green.
+ * Copyright (c) 1993-2021 Matthew R. Green.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -29,20 +29,23 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * @(#)$eterna: parse.h,v 1.18 2016/12/04 21:40:48 gkm Exp $
+ * @(#)$eterna: parse.h,v 1.20 2021/02/24 10:38:03 mrg Exp $
  */
 
 #ifndef irc__parse_h_
 # define irc__parse_h_
 
-	u_char	*paste_args(u_char **, int);
-	void	irc2_parse_server(u_char *);
-	int	is_channel(u_char *);
-	void	beep_em(int);
-	int	doing_privmsg(void);
-	u_char	*from_user_host(void);
-	void	set_from_user_host(u_char *);
-	u_char	*get_public_nick(void);
-	u_char	*get_joined_nick(void);
+u_char	*paste_args(u_char **, int);
+void	irc2_parse_server(u_char *);
+int	is_channel(u_char *);
+void	beep_em(int);
+int	doing_privmsg(void);
+u_char	*from_user_host(void);
+void	set_from_user_host(u_char *);
+u_char	*get_public_nick(void);
+u_char	*get_joined_nick(void);
+void	irc2_odd_server_stuff(u_char *, u_char *, u_char **);
+int	check_params(u_char *comm, u_char *from, int check_from,
+		     u_char **args, unsigned arg_count);
 
 #endif /* irc__parse_h_ */
diff -Nru ircii-20190117/include/signals.h ircii-20210314/include/signals.h
--- ircii-20190117/include/signals.h	2019-01-18 11:29:41.000000000 +0100
+++ ircii-20210314/include/signals.h	2021-03-14 19:32:27.000000000 +0100
@@ -3,7 +3,7 @@
  *
  * written by matthew green
  *
- * Copyright (c) 2019 Matthew R. Green.
+ * Copyright (c) 2019-2020 Matthew R. Green.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -29,13 +29,12 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * @(#)$eterna: signals.h,v 1.2 2019/01/15 11:18:48 mrg Exp $
+ * @(#)$eterna: signals.h,v 1.3 2020/11/17 08:11:56 mrg Exp $
  */
 
 #ifndef irc__signals_h_
 # define irc__signals_h_
 
-extern	const u_char	*signals[];
-extern	const int	 max_signo;
+const u_char	*get_signal(int, int);
 
 #endif /* irc__signals_h_ */
diff -Nru ircii-20190117/include/whois.h ircii-20210314/include/whois.h
--- ircii-20190117/include/whois.h	2019-01-18 11:29:41.000000000 +0100
+++ ircii-20210314/include/whois.h	2021-03-14 19:32:27.000000000 +0100
@@ -5,7 +5,7 @@
  *
  * Copyright (c) 1990 Michael Sandrof.
  * Copyright (c) 1991, 1992 Troy Rollo.
- * Copyright (c) 1992-2014 Matthew R. Green.
+ * Copyright (c) 1992-2021 Matthew R. Green.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,7 +31,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * @(#)$eterna: whois.h,v 1.27 2014/03/01 02:51:44 mrg Exp $
+ * @(#)$eterna: whois.h,v 1.28 2021/02/24 10:01:34 mrg Exp $
  */
 
 #ifndef irc__whois_h_
@@ -59,12 +59,12 @@
 
 	void	add_to_whois_queue(u_char *, void (*) (WhoisStuff *, u_char *, u_char *), char *, ...);
 	void	add_ison_to_whois(u_char *, void (*) (WhoisStuff *, u_char *, u_char *));
-	void	whois_name(u_char *, u_char **);
-	void	whowas_name(u_char *, u_char **);
-	void	whois_channels(u_char *, u_char **);
+	void	whois_name(u_char *, u_char *, u_char **);
+	void	whowas_name(u_char *, u_char *, u_char **);
+	void	whois_channels(u_char *, u_char *, u_char **);
 	void	whois_server(u_char *, u_char **);
 	void	whois_oper(u_char *, u_char **);
-	void	whois_lastcom(u_char *, u_char **);
+	void	whois_lastcom(u_char *, u_char *, u_char **);
 	void	whois_nickname(WhoisStuff *, u_char *, u_char *);
 	void	whois_ignore_msgs(WhoisStuff *, u_char *, u_char *);
 	void	whois_ignore_notices(WhoisStuff *, u_char *, u_char *);
@@ -75,7 +75,7 @@
 	void	clean_whois_queue(void);
 	void	set_beep_on_msg(u_char *);
 	void    userhost_cmd_returned(WhoisStuff *, u_char *, u_char *);
-	void	user_is_away(u_char *, u_char **);
+	void	user_is_away(u_char *, u_char *, u_char **);
 	void	userhost_returned(u_char *, u_char **);
 	void	ison_returned(u_char *, u_char **);
 	void	whois_chop(u_char *, u_char **);
@@ -83,7 +83,7 @@
 	void	whoreply(u_char *, u_char **);
 	void	convert_to_whois(void);
 	void	ison_notify(WhoisStuff *, u_char *, u_char *);
-	void	no_such_nickname(u_char *, u_char **);
+	void	no_such_nickname(u_char *, u_char *, u_char **);
 	int	do_beep_on_level(int);
 
 #define	WHOIS_WHOIS	0x01
diff -Nru ircii-20190117/source/aes.c ircii-20210314/source/aes.c
--- ircii-20190117/source/aes.c	2019-01-18 11:29:41.000000000 +0100
+++ ircii-20210314/source/aes.c	2021-03-14 19:32:27.000000000 +0100
@@ -32,7 +32,7 @@
 
 /* XXX THIS DOES NOT WORK XXX */
 
-IRCII_RCSID_NAMED("@(#)$eterna: aes.c,v 1.8 2014/03/14 01:57:15 mrg Exp $", aes_rcsid);
+IRCII_RCSID_NAMED("@(#)$eterna: aes.c,v 1.9 2020/11/17 08:24:32 mrg Exp $", aes_rcsid);
 
 #include "rijndael-api-ref.h"
 
@@ -145,8 +145,7 @@
 
 	if (key->cookie == NULL)
 	{
-		for (i = 0, s = IV; i < RJLEN / 2; i++)
-			s[i] = (u_char)GET_RANDOM_BYTE;
+		crypt_get_random_data(IV, sizeof IV);
 
 		rv = aes_setkey(key, my_strlen(key->key), s);
 		if (rv < 0)
diff -Nru ircii-20190117/source/alias.c ircii-20210314/source/alias.c
--- ircii-20190117/source/alias.c	2019-01-18 11:29:41.000000000 +0100
+++ ircii-20210314/source/alias.c	2021-03-14 19:32:27.000000000 +0100
@@ -5,7 +5,7 @@
  *
  * Copyright (c) 1990 Michael Sandrof.
  * Copyright (c) 1991, 1992 Troy Rollo.
- * Copyright (c) 1992-2017 Matthew R. Green.
+ * Copyright (c) 1992-2021 Matthew R. Green.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -33,7 +33,7 @@
  */
 
 #include "irc.h"
-IRCII_RCSID("@(#)$eterna: alias.c,v 1.180 2017/07/03 12:44:25 mrg Exp $");
+IRCII_RCSID("@(#)$eterna: alias.c,v 1.183 2021/02/27 08:02:14 mrg Exp $");
 
 #include "alias.h"
 #include "dcc.h"
@@ -282,7 +282,7 @@
 };
 
 /* alias_illegals: characters that are illegal in alias names */
-	u_char	alias_illegals[] = " #+-*/\\()={}[]<>!@$%^~`,?;:|'\"";
+static	u_char	alias_illegals[] = " #+-*/\\()={}[]<>!@$%^~`,?;:|'\"";
 
 static	Alias	*alias_list[] =
 {
@@ -2152,7 +2152,7 @@
 static	u_char	*
 alias_current_numeric(void)
 {
-	static	u_char	number[4];
+	static	u_char	number[12];
 	
 	snprintf(CP(number), sizeof number, "%03d", -current_numeric());
 	return (number);
diff -Nru ircii-20190117/source/cast.c ircii-20210314/source/cast.c
--- ircii-20190117/source/cast.c	2019-01-18 11:29:41.000000000 +0100
+++ ircii-20210314/source/cast.c	2021-03-14 19:32:27.000000000 +0100
@@ -30,7 +30,7 @@
  * SUCH DAMAGE.
  */
 
-IRCII_RCSID_NAMED("@(#)$eterna: cast.c,v 2.47 2014/03/14 08:40:46 mrg Exp $", cast_rcsid);
+IRCII_RCSID_NAMED("@(#)$eterna: cast.c,v 2.48 2020/11/17 08:24:32 mrg Exp $", cast_rcsid);
 
 static	int	cast_encrypt_str(crypt_key *, u_char **, size_t *);
 static	int	cast_decrypt_str(crypt_key *, u_char **, size_t *);
@@ -372,7 +372,7 @@
 {
 	u_char	*s, *newstr;
 	int	i;
-	size_t	nlen;
+	size_t	nlen, padlen;
 
 	/*
 	 * pad the string to 64bit block boundary.  we use the same
@@ -386,13 +386,11 @@
 	 */
 	nlen = (*len + 8 + 8) & ~7UL;
 	newstr = new_malloc(nlen + 1);
-	my_strcpy(newstr + 8, *str);
-	/* XXX this can read upto 15 1 byte chunks.. lame */
-	for (i = 0; i < 8; i++)
-		newstr[i] = (u_char)GET_RANDOM_BYTE;
-	for (i = *len + 8; i < nlen - 1; i++)
-		newstr[i] = (u_char)GET_RANDOM_BYTE;
-	newstr[nlen - 1] = nlen - *len - 1 - 8;
+	memmove(newstr + 8, *str, *len);
+	crypt_get_random_data(newstr, 8);
+	padlen = nlen - *len - 1 - 8;
+	crypt_get_random_data(newstr + *len + 8, padlen);
+	newstr[nlen - 1] = padlen;
 	newstr[nlen] = '\0';
 
 	/*
diff -Nru ircii-20190117/source/crypt.c ircii-20210314/source/crypt.c
--- ircii-20190117/source/crypt.c	2019-01-18 11:29:41.000000000 +0100
+++ ircii-20210314/source/crypt.c	2021-03-14 19:32:27.000000000 +0100
@@ -33,7 +33,7 @@
  */
 
 #include "irc.h"
-IRCII_RCSID("@(#)$eterna: crypt.c,v 1.82 2014/08/14 01:51:25 mrg Exp $");
+IRCII_RCSID("@(#)$eterna: crypt.c,v 1.84 2021/02/27 23:03:57 mrg Exp $");
 
 #include "irccrypt.h"
 #include "vars.h"
@@ -48,14 +48,7 @@
 static	void	add_to_crypt(u_char *, u_char *, CryptFunc, CryptFunc, u_char *);
 static	int	remove_crypt(u_char *);
 static	u_char	*do_crypt(u_char *, crypt_key *, int, u_char **);
-
-#ifdef HAVE_DEV_RANDOM
-static	int	crypt_dev_random_byte(void);
-#define GET_RANDOM_BYTE	crypt_dev_random_byte()
-#else
-/* gotta use the sucky one */
-#define GET_RANDOM_BYTE	(random() & 255)
-#endif
+static	void	crypt_get_random_data(u_char *, size_t);
 
 #include "cast.c"
 #if 0
@@ -411,14 +404,16 @@
 static void
 alarmer(int dummy)
 {
-
 }
+#endif
 
-static int
-crypt_dev_random_byte(void)
+static void
+crypt_get_random_data(u_char *buf, size_t buflen)
 {
+	size_t	i;
+#ifdef HAVE_DEV_RANDOM
 	static	int	devrndfd = -1;
-	u_char	c;
+	size_t	remain = buflen;
 
 	if (devrndfd == -1)
 	{
@@ -426,38 +421,48 @@
 
 		if (devrndfd == -1)
 		{
-			yell("--- HELP!!!! crypt_dev_random_byte: can not open %s: %s",
-			    DEV_RANDOM_PATH, strerror(errno));
-			yell("--- using random()");
-			devrndfd = -2;
+			static int first = 1;
+
+			if (first)
+			{
+				first = 0;
+				yell("--- HELP!!!! crypt_dev_random_byte: can not open %s: %s",
+				    DEV_RANDOM_PATH, strerror(errno));
+				goto do_random_instead_no_alarm;
+			}
 		}
 	}
 	if (devrndfd == -2)
-		goto do_random_instead;
+		goto do_random_instead_no_alarm;
 
 	(void)MY_SIGNAL(SIGALRM, (sigfunc *) alarmer, 0);
-	alarm(2);
-	if (read(devrndfd, &c, 1) != 1)
-	{
+	for (; remain > 0;) {
+		alarm(2);
+		ssize_t rv = read(devrndfd, buf, remain);
 		alarm(0);
+		if (rv > 0) {
+			remain -= rv;
+			continue;
+		}
 		(void)MY_SIGNAL(SIGALRM, (sigfunc *) SIG_DFL, 0);
 		/* if we were just interrupted, don't bail on /dev/random */
 		if (errno == EINTR)
-		{
-			yell("--- crypt_dev_random_byte: timeout, using random()");
-			goto do_random_instead;
-		}
-		yell("--- HELP!  crypt_dev_random_byte: read of one byte on %s failed: %s",
-		    DEV_RANDOM_PATH, strerror(errno));
+			yell("--- crypt_dev_random_byte: interrupt -- "
+			     "using random()");
+		else
+			yell("--- HELP!  crypt_dev_random_byte(): read of %zu "
+			     "bytes on %s failed: %s",
+			     buflen, DEV_RANDOM_PATH, strerror(errno));
 		yell("--- using random()");
-		devrndfd = -2;
-		goto do_random_instead;
+		break;
 	}
+
 	alarm(0);
 	(void)MY_SIGNAL(SIGALRM, (sigfunc *) SIG_DFL, 0);
-	return ((int)c);
-
-do_random_instead:
-	return (random() & 255);
-}
+do_random_instead_no_alarm:
 #endif
+	for (i = 0; i < buflen; i++)
+	{
+		buf[i] = (random() & 255);
+	}
+}
diff -Nru ircii-20190117/source/ctcp.c ircii-20210314/source/ctcp.c
--- ircii-20190117/source/ctcp.c	2019-01-18 11:29:41.000000000 +0100
+++ ircii-20210314/source/ctcp.c	2021-03-14 19:32:27.000000000 +0100
@@ -33,7 +33,7 @@
  */
 
 #include "irc.h"
-IRCII_RCSID("@(#)$eterna: ctcp.c,v 1.107 2017/11/02 00:41:42 mrg Exp $");
+IRCII_RCSID("@(#)$eterna: ctcp.c,v 1.110 2021/03/14 18:22:31 mrg Exp $");
 
 #include <pwd.h>
 
@@ -342,6 +342,7 @@
 			"%s :Use CLIENTINFO <COMMAND> to get more specific information",
 			buffer);
 		new_free(&buffer);
+		sl_free(sl, 0);
 	}
 	return NULL;
 }
@@ -536,12 +537,23 @@
 {
 	time_t	tm;
 	u_char	*date = NULL;
+	char	*curtime;
 
 	if (!args || !*args)
 		return NULL;
 	tm = my_atol(args);
-	malloc_strcpy(&date, UP(ctime(&tm)));
-	date[my_strlen(date)-1] = '\0';
+	curtime = ctime(&tm);
+	if (curtime)
+	{
+		u_char *s = my_index(curtime, '\n');
+		if (s)
+			*s = '\0';
+
+		malloc_strcpy(&date, UP(curtime));
+	}
+	else
+		/* if we can't find a time, just return the number */
+		malloc_strcpy(&date, args);
 	return date;
 }
 
@@ -807,9 +819,10 @@
 		if (do_hook(CTCP_REPLY_LIST, "%s %s %s %s", from, to, cmd,
 				args) && !(flags & CTCP_NOREPLY))
 		{
+			u_char	buf[20];
+
 			if (!my_strcmp(cmd, "PING"))
 			{
-				u_char	buf[20];
 				time_t	timediff,
 					currenttime;
 
diff -Nru ircii-20190117/source/dcc.c ircii-20210314/source/dcc.c
--- ircii-20190117/source/dcc.c	2019-01-18 11:29:41.000000000 +0100
+++ ircii-20210314/source/dcc.c	2021-03-14 19:32:27.000000000 +0100
@@ -4,7 +4,7 @@
  * Written By Troy Rollo <troy@cbme.unsw.oz.au> 
  *
  * Copyright (c) 1991, 1992 Troy Rollo.
- * Copyright (c) 1992-2017 Matthew R. Green.
+ * Copyright (c) 1992-2020 Matthew R. Green.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -32,7 +32,7 @@
  */
 
 #include "irc.h"
-IRCII_RCSID("@(#)$eterna: dcc.c,v 1.186 2019/01/16 07:47:45 mrg Exp $");
+IRCII_RCSID("@(#)$eterna: dcc.c,v 1.188 2020/11/17 08:12:34 mrg Exp $");
 
 #include <sys/stat.h>
 
@@ -1548,7 +1548,7 @@
 dcc_time(time_t the_time)
 {
 	struct	tm	*btime;
-	u_char	*buf;
+	u_char	*buf = NULL;
 	static	char	*months[] =
 	{
 		"Jan", "Feb", "Mar", "Apr", "May", "Jun",
diff -Nru ircii-20190117/source/debug.c ircii-20210314/source/debug.c
--- ircii-20190117/source/debug.c	2019-01-18 11:29:41.000000000 +0100
+++ ircii-20210314/source/debug.c	2021-03-14 19:32:27.000000000 +0100
@@ -1,7 +1,7 @@
 /*
  * debug.c - generic debug routines.
  *
- * Copyright (c) 1993-2017 Matthew R. Green.
+ * Copyright (c) 1993-2021 Matthew R. Green.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -35,7 +35,7 @@
  */
 
 #include "irc.h"		/* This is where DEBUG is defined or not */
-IRCII_RCSID("@(#)$eterna: debug.c,v 1.36 2017/07/04 03:57:08 mrg Exp $");
+IRCII_RCSID("@(#)$eterna: debug.c,v 1.39 2021/02/27 22:38:42 mrg Exp $");
 
 #ifdef DEBUG
 
@@ -63,6 +63,8 @@
 	{ DB_MISC, 		UP("misc"),		0 },
 };
 
+static	FILE	*log_fp;
+
 void
 setdlevel(u_char *level)
 {
@@ -79,7 +81,7 @@
 	va_list vlist;
 	struct timeval tv;
 	struct tm tm_store, *tm;
-
+	
 	if (level > ARRAY_SIZE(debug_levels) ||
 	    debug_levels[level].dlevel == 0)
 		return;
@@ -94,11 +96,28 @@
 	}
 
 	va_start(vlist, format);
-	fprintf(stderr, "%04u-%02u-%02u %02u:%02u:%02u.%06u ",
+	fprintf(log_fp, "%04u-%02u-%02u %02u:%02u:%02u.%06u ",
 	       1990+tm->tm_year, tm->tm_mon, tm->tm_mday,
 	       tm->tm_hour, tm->tm_min, tm->tm_sec, (unsigned)tv.tv_usec);
-	vfprintf(stderr, format, vlist);
-	fputc('\n', stderr);
-	fflush(stderr);
+	vfprintf(log_fp, format, vlist);
+	fputc('\n', log_fp);
+	fflush(log_fp);
+}
+
+void
+open_log_file(u_char *file)
+{
+	if (!file)
+	{
+		printf("irc: need filename for -o\n");
+		exit(-1);
+	}
+	log_fp = fopen(CP(file), "w");
+	if (!log_fp)
+	{
+		printf("irc: can not open %s: %s\n", file,
+		       errno ? "" : strerror(errno));
+		exit(-1);
+	}
 }
 #endif /* DEBUG */
diff -Nru ircii-20190117/source/edit.c ircii-20210314/source/edit.c
--- ircii-20190117/source/edit.c	2019-01-18 11:29:41.000000000 +0100
+++ ircii-20210314/source/edit.c	2021-03-14 19:32:27.000000000 +0100
@@ -6,7 +6,7 @@
  *
  * Copyright (c) 1990 Michael Sandrof.
  * Copyright (c) 1991, 1992 Troy Rollo.
- * Copyright (c) 1992-2018 Matthew R. Green.
+ * Copyright (c) 1992-2021 Matthew R. Green.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -34,7 +34,7 @@
  */
 
 #include "irc.h"
-IRCII_RCSID("@(#)$eterna: edit.c,v 1.273 2018/06/04 19:54:57 mrg Exp $");
+IRCII_RCSID("@(#)$eterna: edit.c,v 1.276 2021/03/02 21:47:06 mrg Exp $");
 
 #include <sys/stat.h>
 
@@ -217,7 +217,7 @@
 static	void	e_nick(u_char *, u_char *, u_char *);
 static	void	commentcmd(u_char *, u_char *, u_char *);
 static	void	sleepcmd(u_char *, u_char *, u_char *);
-static	void	version(u_char *, u_char *, u_char *);
+static	void	e_version(u_char *, u_char *, u_char *);
 static	void	ctcp(u_char *, u_char *, u_char *);
 static	void	dcc(u_char *, u_char *, u_char *);
 static	void	deop(u_char *, u_char *, u_char *);
@@ -392,7 +392,7 @@
 #endif
 	{ "USERHOST",	NULL,		userhost,		SERVERREQ|NOICB },
 	{ "USERS",	"USERS",	send_comm,		SERVERREQ|NOICB },
-	{ "VERSION",	"VERSION",	version,		0 },
+	{ "VERSION",	"VERSION",	e_version,		0 },
 	{ "VOICE",	"VOICE",	e_privmsg,		SERVERREQ },
 	{ "WAIT",	NULL,		waitcmd,		SERVERREQ },
 	{ "WALL",	"WALL",		e_wall,			SERVERREQ|NOICB },
@@ -1092,9 +1092,9 @@
 		server_set_nickname(get_window_server(0), nick);
 }
 
-/* version: does the /VERSION command with some IRCII version stuff */
+/* e_version: does the /VERSION command with some IRCII version stuff */
 static	void
-version(u_char *command, u_char *args, u_char *subargs)
+e_version(u_char *command, u_char *args, u_char *subargs)
 {
 	u_char	*host;
 	const	int	from_server = get_from_server();
@@ -1454,8 +1454,7 @@
 
 int
 whoreply_check(u_char *channel, u_char *user, u_char *host, u_char *server,
-	       u_char *nick, u_char *status, u_char *name, u_char **ArgList,
-	       u_char *format)
+	       u_char *nick, u_char *status, u_char *name, u_char *format)
 {
 	WhoInfo	*wi = server_get_who_info();
 	int ok = 1;
@@ -1465,12 +1464,13 @@
 		FILE *fp = NULL;
 
 		channel = UP("Channel");
-		if ((wi->who_mask & WHO_FILE) == 0 || (fp = fopen(CP(wi->who_file), "r")))
+		if ((wi->who_mask & WHO_FILE) == 0 ||
+		    (fp = fopen(CP(wi->who_file), "r")))
 		{
-			if (do_hook(WHO_LIST, "%s %s %s %s %s %s", channel,
-					nick, status, user, host, ArgList[6]))
+			if (do_hook(WHO_LIST, "%s %s %s %s %s", channel,
+					nick, status, user, host))
 				put_it(CP(format), channel, nick, status, user,
-					host, ArgList[6]);
+					host);
 			if (fp)
 				fclose(fp);
 			/* whoreply() does nothing here */
@@ -1513,7 +1513,10 @@
 				while (fgets ((char *)buf_data, BUFSIZ, fip) !=
 								NULL)
 				{
-					buf_data[my_strlen(buf_data)-1] = '\0';
+					u_char *s = my_index(buf_data, '\n');
+
+					if (s)
+						*s = '\0';
 					ok = ok || wild_match(buf_data, nick);
 				}
 				fclose (fip);
@@ -4037,7 +4040,7 @@
 			window_set_server(-1, from_server, 1);
 		}
 		else
-			say("Unable to reconnect. Use /SERVER to conenct.");
+			say("Unable to reconnect. Use /SERVER to connect.");
 	}
 	else
 		say("You must specify a username and, optionally, an IRCNAME");
diff -Nru ircii-20190117/source/exec.c ircii-20210314/source/exec.c
--- ircii-20190117/source/exec.c	2019-01-18 11:29:41.000000000 +0100
+++ ircii-20210314/source/exec.c	2021-03-14 19:32:27.000000000 +0100
@@ -5,7 +5,7 @@
  *
  * Copyright (c) 1990 Michael Sandrof.
  * Copyright (c) 1991, 1992 Troy Rollo.
- * Copyright (c) 1992-2019 Matthew R. Green.
+ * Copyright (c) 1992-2021 Matthew R. Green.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -33,7 +33,7 @@
  */
 
 #include "irc.h"
-IRCII_RCSID("@(#)$eterna: exec.c,v 1.104 2019/01/16 00:38:00 mrg Exp $");
+IRCII_RCSID("@(#)$eterna: exec.c,v 1.108 2021/03/02 10:20:53 mrg Exp $");
 
 #include <sys/wait.h>
 
@@ -300,12 +300,14 @@
 					proc->counter++;
 					exec_buffer[sizeof(exec_buffer) - 1] = '\0';	/* blah... */
 					ptr = exec_buffer + my_strlen(exec_buffer) - 1;
-					if ((*ptr == '\n') || (*ptr == '\r'))
+					if (ptr >= exec_buffer && (*ptr == '\n' || *ptr == '\r'))
 					{
 						*ptr = '\0';
-						ptr = exec_buffer + my_strlen(exec_buffer) - 1;
-						if ((*ptr == '\n') || (*ptr == '\r'))
-							*ptr = '\0';
+						if (ptr > exec_buffer) {
+							--ptr;
+							if (*ptr == '\n' || *ptr == '\r')
+								*ptr = '\0';
+						}
 					}
 					if (proc->logical)
 						flag = do_hook(EXEC_LIST, "%s %s", proc->logical, exec_buffer);
@@ -517,7 +519,7 @@
 				{
 					if (dead->termsig)
 						say("Process %d (%s) terminated with signal %s (%d)",
-						    process, dead->name, my_sigstr(dead->termsig), dead->termsig);
+						    process, dead->name, get_signal(dead->termsig, 0), dead->termsig);
 					else
 						say("Process %d (%s) terminated with return code %d",
 						    process, dead->name, dead->retcode);
@@ -624,7 +626,7 @@
 		pid_t	pgid;
 
 		say("Sending signal %s (%d) to process %d: %s",
-		    my_sigstr(sig), sig, kill_index, process_list[kill_index]->name);
+		    get_signal(sig, 0), sig, kill_index, process_list[kill_index]->name);
 #ifdef HAVE_GETPGID
 		pgid = getpgid(process_list[kill_index]->pid);
 #else
@@ -1052,7 +1054,8 @@
 			}
 			else
 			{
-				u_char	*cmd2 = NULL;
+				u_char		*cmd2 = NULL;
+				const u_char	*signame;
 
 				if ((i = get_process_index(&args)) == -1)
 				{
@@ -1061,19 +1064,17 @@
 				}
 				if ((sig = my_atoi(flag)) > 0)
 				{
-					if (sig > 0 && sig < max_signo)
+					if (get_signal(sig, 1) != NULL)
 						kill_process(i, sig);
 					else
-						say("Signal number can be from 1 to %d", max_signo);
+						say("Invalid signal number: %d", sig);
 					goto out;
 				}
 				malloc_strcpy(&cmd2, flag);
 				upper(cmd2);
-				for (sig = 1; sig < max_signo; sig++)
+				for (sig = 1; (signame = get_signal(sig, 1)) != NULL; sig++)
 				{
-					if (my_sigstr(sig) == NULL)
-						continue;
-					if (!my_strnicmp(my_sigstr(sig), flag, len))
+					if (!my_strnicmp(signame, flag, len))
 					{
 						kill_process(i, sig);
 						goto out2;
@@ -1198,8 +1199,8 @@
 				new_close(process_list[i]->p_stdout);
 			if (process_list[i]->p_stderr)
 				new_close(process_list[i]->p_stderr);
-			delete_process(i);
 			kill_process(i, SIGKILL);
+			delete_process(i);
 		}
 	set_display(display);
 }
@@ -1213,18 +1214,3 @@
 		if (process_list[j] && process_list[j]->server >= i)
 			process_list[j]->server--;
 }
-
-const u_char *
-my_sigstr(int signo)
-{
-	if (signo <= max_signo) {
-		if (signals[signo] == NULL) {
-			u_char *newsig = NULL;
-
-			malloc_snprintf(&newsig, "SIG%d", signo);
-			signals[signo] = newsig;
-		}
-		return signals[signo];
-	}
-	return UP("(NOSIG)");
-}
diff -Nru ircii-20190117/source/funny.c ircii-20210314/source/funny.c
--- ircii-20190117/source/funny.c	2019-01-18 11:29:41.000000000 +0100
+++ ircii-20210314/source/funny.c	2021-03-14 19:32:27.000000000 +0100
@@ -5,7 +5,7 @@
  *
  * Copyright (c) 1990 Michael Sandrof.
  * Copyright (c) 1991, 1992 Troy Rollo.
- * Copyright (c) 1992-2017 Matthew R. Green.
+ * Copyright (c) 1992-2021 Matthew R. Green.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -33,7 +33,7 @@
  */
 
 #include "irc.h"
-IRCII_RCSID("@(#)$eterna: funny.c,v 1.56 2017/07/04 06:48:26 mrg Exp $");
+IRCII_RCSID("@(#)$eterna: funny.c,v 1.58 2021/02/24 10:38:03 mrg Exp $");
 
 #include "ircaux.h"
 #include "hook.h"
@@ -169,7 +169,7 @@
 }
 
 void
-funny_list(u_char *from, u_char **ArgList)
+funny_list(u_char *comm, u_char *from, u_char **args)
 {
 	u_char	*channel,
 		*user_cnt,
@@ -179,6 +179,9 @@
 	static	u_char	format[25];
 	static	int	last_width = -1;
 
+	if (check_params(comm, from, 0, args, 3))
+		return;
+
 	if (last_width != get_int_var(CHANNEL_NAME_WIDTH_VAR))
 	{
 		if ((last_width = get_int_var(CHANNEL_NAME_WIDTH_VAR)) != 0)
@@ -188,9 +191,9 @@
 		else
 			my_strmcpy(format, "*** %s\t%-5s  %s", sizeof format);
 	}
-	channel = ArgList[0];
-	user_cnt = ArgList[1];
-	line = paste_args(ArgList, 2);
+	channel = args[0];
+	user_cnt = args[1];
+	line = paste_args(args, 2);
 	if (funny_flags & FUNNY_TOPIC && !(line && *line))
 		return;
 	cnt = my_atoi(user_cnt);
@@ -243,7 +246,7 @@
 }
 
 void
-funny_namreply(u_char *from, u_char **Args)
+funny_namreply(u_char *comm, u_char *from, u_char **args)
 {
 	u_char	*type,
 		*nick,
@@ -254,10 +257,13 @@
 	u_char	*ptr;
 	u_char	*line;
 
-	paste_args(Args, 2);
-	type = Args[0];
-	channel = Args[1];
-	line = Args[2];
+	if (check_params(comm, from, 0, args, 3))
+		return;
+
+	paste_args(args, 2);
+	type = args[0];
+	channel = args[1];
+	line = args[2];
 	save_message_from();
 	message_from(channel, LOG_CRAP);
 	if (channel_mode_lookup(channel, CHAN_NAMES | CHAN_MODE, CHAN_NAMES))
@@ -326,23 +332,23 @@
 }
 
 void
-funny_mode(u_char *from, u_char **ArgList)
+funny_mode(u_char *from, u_char **args)
 {
 	u_char	*mode, *channel;
 
-	if (!ArgList[0])
-		return;
 	if (server_get_version(parsing_server()) < Server2_6)
 	{
+		paste_args(args, 0);
 		channel = NULL;
-		mode = ArgList[0];
-		paste_args(ArgList, 0);
+		mode = args[0];
 	}
 	else
 	{
-		channel = ArgList[0];
-		mode = ArgList[1];
-		paste_args(ArgList, 1);
+		if (!args[1])
+			return;
+		paste_args(args, 1);
+		channel = args[0];
+		mode = args[1];
 	}
 	/* if (ignore_mode) */
 	if (channel && channel_mode_lookup(channel, CHAN_NAMES | CHAN_MODE, CHAN_MODE))
diff -Nru ircii-20190117/source/getaddrinfo.c ircii-20210314/source/getaddrinfo.c
--- ircii-20190117/source/getaddrinfo.c	2019-01-18 11:29:41.000000000 +0100
+++ ircii-20210314/source/getaddrinfo.c	1970-01-01 01:00:00.000000000 +0100
@@ -1,1095 +0,0 @@
-/*	Id: getaddrinfo.c,v 1.6 2000/09/23 04:43:21 lukem Exp 	*/
-/*	$KAME: getaddrinfo.c,v 1.77 2000/07/09 04:35:14 itojun Exp $	*/
-
-/*
- * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the project nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-/*
- * Issues to be discussed:
- * - Thread safe-ness must be checked.
- * - Return values.  There are nonstandard return values defined and used
- *   in the source code.  This is because RFC2553 is silent about which error
- *   code must be returned for which situation.
- * - IPv4 classful (shortened) form.  RFC2553 is silent about it.  XNET 5.2
- *   says to use inet_aton() to convert IPv4 numeric to binary (alows
- *   classful form as a result).
- *   current code - disallow classful form for IPv4 (due to use of inet_pton).
- * - freeaddrinfo(NULL).  RFC2553 is silent about it.  XNET 5.2 says it is
- *   invalid.
- *   current code - SEGV on freeaddrinfo(NULL)
- * Note:
- * - We use getipnodebyname() just for thread-safeness.  There's no intent
- *   to let it do PF_UNSPEC (actually we never pass PF_UNSPEC to
- *   getipnodebyname().
- * - The code filters out AFs that are not supported by the kernel,
- *   when globbing NULL hostname (to loopback, or wildcard).  Is it the right
- *   thing to do?  What is the relationship with post-RFC2553 AI_ADDRCONFIG
- *   in ai_flags?
- * - (post-2553) semantics of AI_ADDRCONFIG itself is too vague.
- *   (1) what should we do against numeric hostname (2) what should we do
- *   against NULL hostname (3) what is AI_ADDRCONFIG itself.  AF not ready?
- *   non-loopback address configured?  global address configured?
- * - The code makes use of following calls when asked to resolver with
- *   ai_family  = PF_UNSPEC:
- *	getipnodebyname(host, AF_INET6);
- *	getipnodebyname(host, AF_INET);
- *   This will result in the following queries if the node is configure to
- *   prefer /etc/hosts than DNS:
- *	lookup /etc/hosts for IPv6 address
- *	lookup DNS for IPv6 address
- *	lookup /etc/hosts for IPv4 address
- *	lookup DNS for IPv4 address
- *   which may not meet people's requirement.
- *   The right thing to happen is to have underlying layer which does
- *   PF_UNSPEC lookup (lookup both) and return chain of addrinfos.
- *   This would result in a bit of code duplicate with _dns_ghbyname() and
- *   friends.
- */
-
-#include "irc.h"
-IRCII_RCSID("@(#)$eterna: getaddrinfo.c,v 2.10 2016/12/15 06:31:09 mrg Exp $");
-
-#ifndef HAVE_GETADDRINFO
-
-#define SUCCESS 0
-#define ANY 0
-#define YES 1
-#define NO  0
-
-static const char in_addrany[] = { 0, 0, 0, 0 };
-static const char in_loopback[] = { 127, 0, 0, 1 };
-#ifdef INET6
-static const char in6_addrany[] = {
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-};
-static const char in6_loopback[] = {
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1
-};
-#endif
-
-#define   myoffsetof(type, member)  ((size_t)(unsigned long)(&(NULL)->member))
-
-static const struct afd {
-	int a_af;
-	int a_addrlen;
-	int a_socklen;
-	int a_off;
-	const char *a_addrany;
-	const char *a_loopback;	
-	int a_scoped;
-} afdl [] = {
-#ifdef INET6
-	{PF_INET6, sizeof(struct in6_addr),
-	 sizeof(struct sockaddr_in6),
-	 myoffsetof(struct sockaddr_in6, sin6_addr),
-	 in6_addrany, in6_loopback, 1},
-#endif
-	{PF_INET, sizeof(struct in_addr),
-	 sizeof(struct sockaddr_in),
-	 myoffsetof(struct sockaddr_in, sin_addr),
-	 in_addrany, in_loopback, 0},
-	{0, 0, 0, 0, NULL, NULL, 0},
-};
-
-struct explore {
-	int e_af;
-	int e_socktype;
-	int e_protocol;
-	const char *e_protostr;
-	int e_wild;
-#define WILD_AF(ex)		((ex)->e_wild & 0x01)
-#define WILD_SOCKTYPE(ex)	((ex)->e_wild & 0x02)
-#define WILD_PROTOCOL(ex)	((ex)->e_wild & 0x04)
-};
-
-static const struct explore explore[] = {
-#if 0
-	{ PF_LOCAL, 0, ANY, ANY, NULL, 0x01 },
-#endif
-#ifdef INET6
-	{ PF_INET6, SOCK_DGRAM, IPPROTO_UDP, "udp", 0x07 },
-	{ PF_INET6, SOCK_STREAM, IPPROTO_TCP, "tcp", 0x07 },
-	{ PF_INET6, SOCK_RAW, ANY, NULL, 0x05 },
-#endif
-	{ PF_INET, SOCK_DGRAM, IPPROTO_UDP, "udp", 0x07 },
-	{ PF_INET, SOCK_STREAM, IPPROTO_TCP, "tcp", 0x07 },
-	{ PF_INET, SOCK_RAW, ANY, NULL, 0x05 },
-	{ -1, 0, 0, NULL, 0 },
-};
-
-#ifdef INET6
-#define PTON_MAX	16
-#else
-#define PTON_MAX	4
-#endif
-
-
-static int str_isnumber(const char *);
-static int explore_fqdn(const struct addrinfo *, const char *,
-	const char *, struct addrinfo **);
-static int explore_null(const struct addrinfo *,
-	const char *, struct addrinfo **);
-static int explore_numeric(const struct addrinfo *, const char *,
-	const char *, struct addrinfo **);
-static int explore_numeric_scope(const struct addrinfo *, const char *,
-	const char *, struct addrinfo **);
-static int get_canonname(const struct addrinfo *,
-	struct addrinfo *, const char *);
-static struct addrinfo *get_ai(const struct addrinfo *,
-	const struct afd *, const char *);
-static int get_portmatch(const struct addrinfo *, const char *);
-static int get_port(struct addrinfo *, const char *, int);
-static const struct afd *find_afd(int);
-static int addrconfig(const struct addrinfo *);
-#ifdef INET6
-static int ip6_str2scopeid(char *, struct sockaddr_in6 *);
-#endif
-
-static char *ai_errlist[] = {
-	"Success",
-	"Address family for hostname not supported",	/* EAI_ADDRFAMILY */
-	"Temporary failure in name resolution",		/* EAI_AGAIN      */
-	"Invalid value for ai_flags",		       	/* EAI_BADFLAGS   */
-	"Non-recoverable failure in name resolution", 	/* EAI_FAIL       */
-	"ai_family not supported",			/* EAI_FAMILY     */
-	"Memory allocation failure", 			/* EAI_MEMORY     */
-	"No address associated with hostname", 		/* EAI_NODATA     */
-	"hostname nor servname provided, or not known",	/* EAI_NONAME     */
-	"servname not supported for ai_socktype",	/* EAI_SERVICE    */
-	"ai_socktype not supported", 			/* EAI_SOCKTYPE   */
-	"System error returned in errno", 		/* EAI_SYSTEM     */
-	"Invalid value for hints",			/* EAI_BADHINTS	  */
-	"Resolved protocol is unknown",			/* EAI_PROTOCOL   */
-	"Unknown error", 				/* EAI_MAX        */
-};
-
-/* macros that make external reference is BAD. */
-
-#define GET_AI(ai, afd, addr) \
-do { \
-	/* external reference: pai, error, and label free */ \
-	(ai) = get_ai(pai, (afd), (addr)); \
-	if ((ai) == NULL) { \
-		error = EAI_MEMORY; \
-		goto free; \
-	} \
-} while (/*CONSTCOND*/0)
-
-#define GET_PORT(ai, serv) \
-do { \
-	/* external reference: error and label free */ \
-	error = get_port((ai), (serv), 0); \
-	if (error != 0) \
-		goto free; \
-} while (/*CONSTCOND*/0)
-
-#define GET_CANONNAME(ai, str) \
-do { \
-	/* external reference: pai, error and label free */ \
-	error = get_canonname(pai, (ai), (str)); \
-	if (error != 0) \
-		goto free; \
-} while (/*CONSTCOND*/0)
-
-#define ERR(err) \
-do { \
-	/* external reference: error, and label bad */ \
-	error = (err); \
-	goto bad; \
-	/*NOTREACHED*/ \
-} while (/*CONSTCOND*/0)
-
-#define MATCH_FAMILY(x, y, w) \
-	((x) == (y) || (/*CONSTCOND*/(w) && ((x) == PF_UNSPEC || (y) == PF_UNSPEC)))
-#define MATCH(x, y, w) \
-	((x) == (y) || (/*CONSTCOND*/(w) && ((x) == ANY || (y) == ANY)))
-
-char *
-gai_strerror(int ecode)
-{
-	if (ecode < 0 || ecode > EAI_MAX)
-		ecode = EAI_MAX;
-	return ai_errlist[ecode];
-}
-
-void
-freeaddrinfo(struct addrinfo *ai)
-{
-	struct addrinfo *next;
-
-	do {
-		next = ai->ai_next;
-		if (ai->ai_canonname)
-			free(ai->ai_canonname);
-		/* no need to free(ai->ai_addr) */
-		free(ai);
-		ai = next;
-	} while (ai);
-}
-
-static int
-str_isnumber(const char *p)
-{
-	char *ep;
-	long l;
-
-	if (*p == '\0')
-		return NO;
-	ep = NULL;
-	l = strtol(p, &ep, 10);
-	if (ep && *ep == '\0' && l >= 0)
-		return YES;
-	else
-		return NO;
-}
-
-int
-getaddrinfo(const char *hostname, const char *servname, const struct addrinfo *hints, struct addrinfo **res)
-{
-	struct addrinfo sentinel;
-	struct addrinfo *cur;
-	int error = 0;
-	struct addrinfo ai;
-	struct addrinfo ai0;
-	struct addrinfo *pai;
-	const struct afd *afd;
-	const struct explore *ex;
-
-	memset(&sentinel, 0, sizeof(sentinel));
-	cur = &sentinel;
-	pai = &ai;
-	pai->ai_flags = 0;
-	pai->ai_family = PF_UNSPEC;
-	pai->ai_socktype = ANY;
-	pai->ai_protocol = ANY;
-	pai->ai_addrlen = 0;
-	pai->ai_canonname = NULL;
-	pai->ai_addr = NULL;
-	pai->ai_next = NULL;
-	
-	if (hostname == NULL && servname == NULL)
-		return EAI_NONAME;
-	if (hints) {
-		/* error check for hints */
-		if (hints->ai_addrlen || hints->ai_canonname ||
-		    hints->ai_addr || hints->ai_next)
-			ERR(EAI_BADHINTS); /* xxx */
-		if (hints->ai_flags & ~AI_MASK)
-			ERR(EAI_BADFLAGS);
-		switch (hints->ai_family) {
-		case PF_UNSPEC:
-		case PF_INET:
-#ifdef INET6
-		case PF_INET6:
-#endif
-			break;
-		default:
-			ERR(EAI_FAMILY);
-		}
-		memcpy(pai, hints, sizeof(*pai));
-
-		/*
-		 * if both socktype/protocol are specified, check if they
-		 * are meaningful combination.
-		 */
-		if (pai->ai_socktype != ANY && pai->ai_protocol != ANY) {
-			for (ex = explore; ex->e_af >= 0; ex++) {
-				if (pai->ai_family != ex->e_af)
-					continue;
-				if (ex->e_socktype == ANY)
-					continue;
-				if (ex->e_protocol == ANY)
-					continue;
-				if (pai->ai_socktype == ex->e_socktype
-				 && pai->ai_protocol != ex->e_protocol) {
-					ERR(EAI_BADHINTS);
-				}
-			}
-		}
-	}
-
-	/*
-	 * post-2553: AI_ALL and AI_V4MAPPED are effective only against
-	 * AF_INET6 query.  They needs to be ignored if specified in other
-	 * occassions.
-	 */
-	switch (pai->ai_flags & (AI_ALL | AI_V4MAPPED)) {
-	case AI_V4MAPPED:
-	case AI_ALL | AI_V4MAPPED:
-#ifdef INET6
-		if (pai->ai_family != AF_INET6)
-			pai->ai_flags &= ~(AI_ALL | AI_V4MAPPED);
-		break;
-#endif
-	case AI_ALL:
-#if 1
-		/* illegal */
-		ERR(EAI_BADFLAGS);
-#else
-		pai->ai_flags &= ~(AI_ALL | AI_V4MAPPED);
-#endif
-		break;
-	}
-
-	/*
-	 * check for special cases.  (1) numeric servname is disallowed if
-	 * socktype/protocol are left unspecified. (2) servname is disallowed
-	 * for raw and other inet{,6} sockets.
-	 */
-	if (MATCH_FAMILY(pai->ai_family, PF_INET, 1)
-#ifdef PF_INET6
-	 || MATCH_FAMILY(pai->ai_family, PF_INET6, 1)
-#endif
-	    ) {
-		ai0 = *pai;	/* backup *pai */
-
-		if (pai->ai_family == PF_UNSPEC) {
-#ifdef PF_INET6
-			pai->ai_family = PF_INET6;
-#else
-			pai->ai_family = PF_INET;
-#endif
-		}
-		error = get_portmatch(pai, servname);
-		if (error)
-			ERR(error);
-
-		*pai = ai0;
-	}
-
-	ai0 = *pai;
-
-	/* NULL hostname, or numeric hostname */
-	for (ex = explore; ex->e_af >= 0; ex++) {
-		*pai = ai0;
-
-		if (!MATCH_FAMILY(pai->ai_family, ex->e_af, WILD_AF(ex)))
-			continue;
-		if (!MATCH(pai->ai_socktype, ex->e_socktype, WILD_SOCKTYPE(ex)))
-			continue;
-		if (!MATCH(pai->ai_protocol, ex->e_protocol, WILD_PROTOCOL(ex)))
-			continue;
-
-		if (pai->ai_family == PF_UNSPEC)
-			pai->ai_family = ex->e_af;
-		if (pai->ai_socktype == ANY && ex->e_socktype != ANY)
-			pai->ai_socktype = ex->e_socktype;
-		if (pai->ai_protocol == ANY && ex->e_protocol != ANY)
-			pai->ai_protocol = ex->e_protocol;
-
-		if (hostname == NULL)
-			error = explore_null(pai, servname, &cur->ai_next);
-		else
-			error = explore_numeric_scope(pai, hostname, servname, &cur->ai_next);
-
-		if (error)
-			goto free;
-
-		while (cur && cur->ai_next)
-			cur = cur->ai_next;
-	}
-
-	/*
-	 * If numreic representation of AF1 can be interpreted as FQDN
-	 * representation of AF2, we need to think again about the code below.
-	 */
-	if (sentinel.ai_next)
-		goto good;
-
-	if (pai->ai_flags & AI_NUMERICHOST)
-		ERR(EAI_NODATA);
-	if (hostname == NULL)
-		ERR(EAI_NODATA);
-
-	/*
-	 * hostname as alphabetical name.
-	 * we would like to prefer AF_INET6 than AF_INET, so we'll make a
-	 * outer loop by AFs.
-	 */
-	for (afd = afdl; afd->a_af; afd++) {
-		*pai = ai0;
-
-		if (!MATCH_FAMILY(pai->ai_family, afd->a_af, 1))
-			continue;
-
-		for (ex = explore; ex->e_af >= 0; ex++) {
-			*pai = ai0;
-
-			if (pai->ai_family == PF_UNSPEC)
-				pai->ai_family = afd->a_af;
-
-			if (!MATCH_FAMILY(pai->ai_family, ex->e_af, WILD_AF(ex)))
-				continue;
-			if (!MATCH(pai->ai_socktype, ex->e_socktype,
-					WILD_SOCKTYPE(ex))) {
-				continue;
-			}
-			if (!MATCH(pai->ai_protocol, ex->e_protocol,
-					WILD_PROTOCOL(ex))) {
-				continue;
-			}
-
-			if (pai->ai_family == PF_UNSPEC)
-				pai->ai_family = ex->e_af;
-			if (pai->ai_socktype == ANY && ex->e_socktype != ANY)
-				pai->ai_socktype = ex->e_socktype;
-			if (pai->ai_protocol == ANY && ex->e_protocol != ANY)
-				pai->ai_protocol = ex->e_protocol;
-
-			error = explore_fqdn(pai, hostname, servname,
-				&cur->ai_next);
-
-			while (cur && cur->ai_next)
-				cur = cur->ai_next;
-		}
-	}
-
-	if (sentinel.ai_next)
-		error = 0;
-
-	if (error)
-		goto free;
-	if (error == 0) {
-		if (sentinel.ai_next) {
- good:
-			*res = sentinel.ai_next;
-			return SUCCESS;
-		} else
-			error = EAI_FAIL;
-	}
- free:
- bad:
-	if (sentinel.ai_next)
-		freeaddrinfo(sentinel.ai_next);
-	*res = NULL;
-	return error;
-}
-
-/*
- * FQDN hostname, DNS lookup
- */
-static int
-explore_fqdn(const struct addrinfo *pai, const char *hostname, const char *servname, struct addrinfo **res)
-{
-	struct hostent *hp;
-	int h_error;
-	int af;
-	char **aplist = NULL, *apbuf = NULL;
-	char *ap;
-	struct addrinfo sentinel, *cur;
-	int i;
-#ifndef USE_GETIPNODEBY
-	int naddrs;
-#endif
-	const struct afd *afd;
-	int error = 0;
-#if 0
-	struct addrinfo pai4;
-#ifdef INET6
-	struct addrinfo pai6;
-#endif
-#endif
-
-	*res = NULL;
-	sentinel.ai_next = NULL;
-	cur = &sentinel;
-
-	/*
-	 * If AI_ADDRCONFIG is specified, check if we are expected to
-	 * return the address family or not.
-	 * assumes PF_UNSPEC = PF_INET + PF_INET6.
-	 *
-	 * NOTE: PF_UNSPEC case is for future use.
-	 */
-	if ((pai->ai_flags & AI_ADDRCONFIG) != 0) {
-		switch (pai->ai_family) {
-#if 0
-		case PF_UNSPEC:
-			pai4 = pai6 = *pai;
-			pai4.ai_family = PF_INET;
-#ifndef INET6
-			if (!addrconfig(&pai4))
-				return 0;
-#else
-			pai6.ai_family = PF_INET6;
-			if (!addrconfig(&pai4)) {
-				if (!addrconfig(&pai6))
-					return 0;
-				pai = &pai6;
-			} else {
-				if (!addrconfig(&pai6))
-					pai = &pai4;
-				else
-					; /* as is */
-			}
-#endif
-			break;
-#endif
-		default:
-			if (!addrconfig(pai))
-				return 0;
-			break;
-		}
-	}
-
-	/*
-	 * if the servname does not match socktype/protocol, ignore it.
-	 */
-	if (get_portmatch(pai, servname) != 0)
-		return 0;
-
-	afd = find_afd(pai->ai_family);
-	if (afd == NULL)
-		return 0;
-
-#ifdef USE_GETIPNODEBY
-	hp = getipnodebyname(hostname, pai->ai_family,
-	    pai->ai_flags & AI_ADDRCONFIG, &h_error);
-#else
-#if HAVE_GETHOSTBYNAME2
-	hp = gethostbyname2(hostname, pai->ai_family);
-#else
-	if (pai->ai_family != AF_INET)
-		return 0;
-	hp = gethostbyname(hostname);
-#endif /*HAVE_GETHOSTBYNAME2*/
-#if HAVE_H_ERRNO
-	h_error = h_errno;
-#else
-	h_error = EINVAL;
-#endif
-#endif /*USE_GETIPNODEBY*/
-
-	if (hp == NULL) {
-		switch (h_error) {
-		case HOST_NOT_FOUND:
-		case NO_DATA:
-			error = EAI_NODATA;
-			break;
-		case TRY_AGAIN:
-			error = EAI_AGAIN;
-			break;
-		case NO_RECOVERY:
-#ifdef NETDB_INTERNAL
-		case NETDB_INTERNAL:
-#endif
-		default:
-			error = EAI_FAIL;
-			break;
-		}
-	} else if ((hp->h_name == NULL) || (hp->h_name[0] == 0)
-			|| (hp->h_addr_list[0] == NULL)) {
-#ifdef USE_GETIPNODEBY
-		freehostent(hp);
-#endif
-		hp = NULL;
-		error = EAI_FAIL;
-	}
-
-	if (hp == NULL)
-		goto free;
-
-#ifdef USE_GETIPNODEBY
-	aplist = hp->h_addr_list;
-#else
-	/*
-	 * hp will be overwritten if we use gethostbyname2().
-	 * always deep copy for simplification.
-	 */
-	for (naddrs = 0; hp->h_addr_list[naddrs] != NULL; naddrs++)
-		;
-	naddrs++;
-	aplist = (char **)malloc(sizeof(aplist[0]) * naddrs);
-	apbuf = (char *)malloc((size_t)hp->h_length * naddrs);
-	if (aplist == NULL || apbuf == NULL) {
-		error = EAI_MEMORY;
-		goto free;
-	}
-	memset(aplist, 0, sizeof(aplist[0]) * naddrs);
-	for (i = 0; i < naddrs; i++) {
-		if (hp->h_addr_list[i] == NULL) {
-			aplist[i] = NULL;
-			continue;
-		}
-		memcpy(&apbuf[i * hp->h_length], hp->h_addr_list[i],
-			(size_t)hp->h_length);
-		aplist[i] = &apbuf[i * hp->h_length];
-	}
-#endif
-
-	for (i = 0; aplist[i] != NULL; i++) {
-		af = hp->h_addrtype;
-		ap = aplist[i];
-#ifdef INET6
-		if (af == AF_INET6
-		 && IN6_IS_ADDR_V4MAPPED((struct in6_addr *)ap)) {
-			af = AF_INET;
-			ap = ap + sizeof(struct in6_addr)
-				- sizeof(struct in_addr);
-		}
-#endif
-
-		if (af != pai->ai_family)
-			continue;
-
-		GET_AI(cur->ai_next, afd, ap);
-		GET_PORT(cur->ai_next, servname);
-		if ((pai->ai_flags & AI_CANONNAME) != 0) {
-			/*
-			 * RFC2553 says that ai_canonname will be set only for
-			 * the first element.  we do it for all the elements,
-			 * just for convenience.
-			 */
-			GET_CANONNAME(cur->ai_next, hp->h_name);
-		}
-
-		while (cur && cur->ai_next)
-			cur = cur->ai_next;
-	}
-
-	*res = sentinel.ai_next;
-	return 0;
-
-free:
-#ifdef USE_GETIPNODEBY
-	if (hp)
-		freehostent(hp);
-#endif
-	if (aplist)
-		free(aplist);
-	if (apbuf)
-		free(apbuf);
-	if (sentinel.ai_next)
-		freeaddrinfo(sentinel.ai_next);
-	return error;
-}
-
-/*
- * hostname == NULL.
- * passive socket -> anyaddr (0.0.0.0 or ::)
- * non-passive socket -> localhost (127.0.0.1 or ::1)
- */
-static int
-explore_null(const  struct addrinfo *pai, const char *servname, struct addrinfo **res)
-{
-	const struct afd *afd;
-	struct addrinfo *cur;
-	struct addrinfo sentinel;
-	int error;
-
-	*res = NULL;
-	sentinel.ai_next = NULL;
-	cur = &sentinel;
-
-	/*
-	 * filter out AFs that are not supported by the kernel
-	 */
-	if (!addrconfig(pai))
-		return 0;
-
-	/*
-	 * if the servname does not match socktype/protocol, ignore it.
-	 */
-	if (get_portmatch(pai, servname) != 0)
-		return 0;
-
-	afd = find_afd(pai->ai_family);
-	if (afd == NULL)
-		return 0;
-
-	if (pai->ai_flags & AI_PASSIVE) {
-		GET_AI(cur->ai_next, afd, afd->a_addrany);
-		/* xxx meaningless?
-		 * GET_CANONNAME(cur->ai_next, "anyaddr");
-		 */
-		GET_PORT(cur->ai_next, servname);
-	} else {
-		GET_AI(cur->ai_next, afd, afd->a_loopback);
-		/* xxx meaningless?
-		 * GET_CANONNAME(cur->ai_next, "localhost");
-		 */
-		GET_PORT(cur->ai_next, servname);
-	}
-	cur = cur->ai_next;
-
-	*res = sentinel.ai_next;
-	return 0;
-
-free:
-	if (sentinel.ai_next)
-		freeaddrinfo(sentinel.ai_next);
-	return error;
-}
-
-/*
- * numeric hostname
- */
-static int
-explore_numeric(const struct addrinfo *pai, const char *hostname, const char *servname, struct addrinfo **res)
-{
-	const struct afd *afd;
-	struct addrinfo *cur;
-	struct addrinfo sentinel;
-	int error;
-	char pton[PTON_MAX];
-
-	*res = NULL;
-	sentinel.ai_next = NULL;
-	cur = &sentinel;
-
-	/*
-	 * if the servname does not match socktype/protocol, ignore it.
-	 */
-	if (get_portmatch(pai, servname) != 0)
-		return 0;
-
-	afd = find_afd(pai->ai_family);
-	if (afd == NULL)
-		return 0;
-
-	switch (afd->a_af) {
-#if 0 /*X/Open spec*/
-	case AF_INET:
-		if (inet_aton(hostname, (struct in_addr *)pton) == 1) {
-			if (pai->ai_family == afd->a_af ||
-			    pai->ai_family == PF_UNSPEC /*?*/) {
-				GET_AI(cur->ai_next, afd, pton);
-				GET_PORT(cur->ai_next, servname);
-				while (cur && cur->ai_next)
-					cur = cur->ai_next;
-			} else
-				ERR(EAI_FAMILY);	/*xxx*/
-		}
-		break;
-#endif
-	default:
-		if (inet_pton(afd->a_af, hostname, pton) == 1) {
-			if (pai->ai_family == afd->a_af ||
-			    pai->ai_family == PF_UNSPEC /*?*/) {
-				GET_AI(cur->ai_next, afd, pton);
-				GET_PORT(cur->ai_next, servname);
-				while (cur && cur->ai_next)
-					cur = cur->ai_next;
-			} else
-				ERR(EAI_FAMILY);	/*xxx*/
-		}
-		break;
-	}
-
-	*res = sentinel.ai_next;
-	return 0;
-
-free:
-bad:
-	if (sentinel.ai_next)
-		freeaddrinfo(sentinel.ai_next);
-	return error;
-}
-
-/*
- * numeric hostname with scope
- */
-static int
-explore_numeric_scope(const struct addrinfo *pai, const char *hostname, const char *servname, struct addrinfo **res)
-{
-#if !defined(SCOPE_DELIMITER) || !defined(INET6)
-	return explore_numeric(pai, hostname, servname, res);
-#else
-	const struct afd *afd;
-	struct addrinfo *cur;
-	int error;
-	char *cp, *hostname2 = NULL, *scope, *addr;
-	struct sockaddr_in6 *sin6;
-
-	/*
-	 * if the servname does not match socktype/protocol, ignore it.
-	 */
-	if (get_portmatch(pai, servname) != 0)
-		return 0;
-
-	afd = find_afd(pai->ai_family);
-	if (afd == NULL)
-		return 0;
-
-	if (!afd->a_scoped)
-		return explore_numeric(pai, hostname, servname, res);
-
-	cp = strchr(hostname, SCOPE_DELIMITER);
-	if (cp == NULL)
-		return explore_numeric(pai, hostname, servname, res);
-
-#if 0
-	/*
-	 * Handle special case of <scope id><delimiter><scoped_address>
-	 */
-	hostname2 = strdup(hostname);
-	if (hostname2 == NULL)
-		return EAI_MEMORY;
-	/* terminate at the delimiter */
-	hostname2[cp - hostname] = '\0';
-	scope = hostname2;
-	addr = cp + 1;
-#else
-	/*
-	 * Handle special case of <scoped_address><delimiter><scope id>
-	 */
-	hostname2 = strdup(hostname);
-	if (hostname2 == NULL)
-		return EAI_MEMORY;
-	/* terminate at the delimiter */
-	hostname2[cp - hostname] = '\0';
-	addr = hostname2;
-	scope = cp + 1;
-#endif
-
-	error = explore_numeric(pai, addr, servname, res);
-	if (error == 0) {
-		int scopeid;
-
-		for (cur = *res; cur; cur = cur->ai_next) {
-			if (cur->ai_family != AF_INET6)
-				continue;
-			sin6 = (struct sockaddr_in6 *)(void *)cur->ai_addr;
-			if ((scopeid = ip6_str2scopeid(scope, sin6)) == -1) {
-				free(hostname2);
-				return(EAI_NODATA);
-			}
-			sin6->sin6_scope_id = scopeid;
-		}
-	}
-
-	free(hostname2);
-
-	return error;
-#endif
-}
-
-static int
-get_canonname(const struct addrinfo *pai, struct addrinfo *ai, const char *str)
-{
-	if ((pai->ai_flags & AI_CANONNAME) != 0) {
-		ai->ai_canonname = (char *)malloc(strlen(str) + 1);
-		if (ai->ai_canonname == NULL)
-			return EAI_MEMORY;
-		strcpy(ai->ai_canonname, str);
-	}
-	return 0;
-}
-
-static struct addrinfo *
-get_ai(const struct addrinfo *pai, const struct afd *afd, const char *addr)
-{
-	char *p;
-	struct addrinfo *ai;
-
-	ai = (struct addrinfo *)malloc(sizeof(struct addrinfo)
-		+ (afd->a_socklen));
-	if (ai == NULL)
-		return NULL;
-
-	memcpy(ai, pai, sizeof(struct addrinfo));
-	ai->ai_addr = (struct sockaddr *)(void *)(ai + 1);
-	memset(ai->ai_addr, 0, (size_t)afd->a_socklen);
-#if HAVE_SOCKADDR_SA_LEN
-	ai->ai_addr->sa_len = afd->a_socklen;
-#endif
-	ai->ai_addrlen = afd->a_socklen;
-	ai->ai_addr->sa_family = ai->ai_family = afd->a_af;
-	p = (char *)(void *)(ai->ai_addr);
-	memcpy(p + afd->a_off, addr, (size_t)afd->a_addrlen);
-	return ai;
-}
-
-static int
-get_portmatch(const struct addrinfo *ai, const char *servname)
-{
-
-	/* get_port does not touch first argument. when matchonly == 1. */
-	/* LINTED const cast */
-	return get_port((struct addrinfo *)ai, servname, 1);
-}
-
-static int
-get_port(struct addrinfo *ai, const char *servname, int matchonly)
-{
-	const char *proto;
-	struct servent *sp;
-	int port;
-	int allownumeric;
-
-	if (servname == NULL)
-		return 0;
-	switch (ai->ai_family) {
-	case AF_INET:
-#ifdef AF_INET6
-	case AF_INET6:
-#endif
-		break;
-	default:
-		return 0;
-	}
-
-	switch (ai->ai_socktype) {
-	case SOCK_RAW:
-		return EAI_SERVICE;
-	case SOCK_DGRAM:
-	case SOCK_STREAM:
-		allownumeric = 1;
-		break;
-	case ANY:
-		allownumeric = 0;
-		break;
-	default:
-		return EAI_SOCKTYPE;
-	}
-
-	if (str_isnumber(servname)) {
-		if (!allownumeric)
-			return EAI_SERVICE;
-		port = htons(atoi(servname));
-		if (port < 0 || port > 65535)
-			return EAI_SERVICE;
-	} else {
-		switch (ai->ai_socktype) {
-		case SOCK_DGRAM:
-			proto = "udp";
-			break;
-		case SOCK_STREAM:
-			proto = "tcp";
-			break;
-		default:
-			proto = NULL;
-			break;
-		}
-
-		if ((sp = getservbyname(servname, proto)) == NULL)
-			return EAI_SERVICE;
-		port = sp->s_port;
-	}
-
-	if (!matchonly) {
-		switch (ai->ai_family) {
-		case AF_INET:
-			((struct sockaddr_in *)(void *)
-			    ai->ai_addr)->sin_port = port;
-			break;
-#ifdef INET6
-		case AF_INET6:
-			((struct sockaddr_in6 *)(void *)
-			    ai->ai_addr)->sin6_port = port;
-			break;
-#endif
-		}
-	}
-
-	return 0;
-}
-
-static const struct afd *
-find_afd(int af)
-{
-	const struct afd *afd;
-
-	if (af == PF_UNSPEC)
-		return NULL;
-	for (afd = afdl; afd->a_af; afd++) {
-		if (afd->a_af == af)
-			return afd;
-	}
-	return NULL;
-}
-
-/*
- * post-2553: AI_ADDRCONFIG check.  if we use getipnodeby* as backend, backend
- * will take care of it.
- * the semantics of AI_ADDRCONFIG is not defined well.  we are not sure
- * if the code is right or not.
- */
-static int
-addrconfig(const struct addrinfo *pai)
-{
-#ifdef USE_GETIPNODEBY
-	return 1;
-#else
-	int s;
-
-	s = socket(pai->ai_family, SOCK_DGRAM, 0);
-	if (s < 0) {
-		if (errno != EMFILE)
-			return 0;
-	} else
-		close(s);
-	return 1;
-#endif
-}
-
-#ifdef INET6
-/* convert a string to a IPv6 scope identifier. */
-static int
-ip6_str2scopeid( char *scope, struct sockaddr_in6 *sin6)
-{
-	int scopeid;
-	struct in6_addr *a6 = &sin6->sin6_addr;
-	char *ep;
-
-	/* empty scopeid portion is invalid */
-	if (*scope == '\0')
-		return -1;
-
-	if (IN6_IS_ADDR_LINKLOCAL(a6) || IN6_IS_ADDR_MC_LINKLOCAL(a6)) {
-		/*
-		 * We currently assume a one-to-one mapping between links
-		 * and interfaces, so we simply use interface indices for
-		 * like-local scopes.
-		 */
-		scopeid = if_nametoindex(scope);
-		if (scopeid == 0)
-			goto trynumeric;
-		return(scopeid);
-	}
-
-	/* still unclear about literal, allow numeric only - placeholder */
-	if (IN6_IS_ADDR_SITELOCAL(a6) || IN6_IS_ADDR_MC_SITELOCAL(a6))
-		goto trynumeric;
-	if (IN6_IS_ADDR_MC_ORGLOCAL(a6))
-		goto trynumeric;
-	else
-		goto trynumeric;	/* global */
-
-	/* try to convert to a numeric id as a last resort */
-  trynumeric:
-	scopeid = (int)strtoul(scope, &ep, 10);
-	if (*ep == '\0')
-		return scopeid;
-	else
-		return -1;
-}
-#endif
-
-#endif /* HAVE_GETADDRINFO */
diff -Nru ircii-20190117/source/getnameinfo.c ircii-20210314/source/getnameinfo.c
--- ircii-20190117/source/getnameinfo.c	2019-01-18 11:29:41.000000000 +0100
+++ ircii-20210314/source/getnameinfo.c	1970-01-01 01:00:00.000000000 +0100
@@ -1,352 +0,0 @@
-/*	Id: getnameinfo.c,v 1.4 2001/04/17 07:54:51 lukem Exp 	*/
-/*	$NetBSD: getnameinfo.c,v 1.19 2000/06/12 04:27:58 itojun Exp $	*/
-/*	$KAME: getnameinfo.c,v 1.43 2000/06/12 04:27:03 itojun Exp $	*/
-
-/*
- * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the project nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-/*
- * Issues to be discussed:
- * - Thread safe-ness must be checked
- * - Return values.  There seems to be no standard for return value (RFC2553)
- *   but INRIA implementation returns EAI_xxx defined for getaddrinfo().
- * - RFC2553 says that we should raise error on short buffer.  X/Open says
- *   we need to truncate the result.  We obey RFC2553 (and X/Open should be
- *   modified).
- * - What is "local" in NI_FQDN?
- * - NI_NAMEREQD and NI_NUMERICHOST conflict with each other.
- * - (KAME extension) NI_WITHSCOPEID when called with global address,
- *   and sin6_scope_id filled
- */
-
-#include "irc.h"
-IRCII_RCSID("@(#)$eterna: getnameinfo.c,v 2.10 2014/08/12 20:26:28 mrg Exp $");
-
-#ifndef HAVE_GETNAMEINFO
-
-#define SUCCESS 0
-#define ANY 0
-#define YES 1
-#define NO  0
-
-#define   myoffsetof(type, member)  ((size_t)(unsigned long)(&((type *)0)->member))
-
-static struct afd {
-	int a_af;
-	int a_addrlen;
-	int a_socklen;
-	int a_off;
-} afdl [] = {
-#ifdef INET6
-	{PF_INET6, sizeof(struct in6_addr), sizeof(struct sockaddr_in6),
-		myoffsetof(struct sockaddr_in6, sin6_addr)},
-#endif
-	{PF_INET, sizeof(struct in_addr), sizeof(struct sockaddr_in),
-		myoffsetof(struct sockaddr_in, sin_addr)},
-	{0, 0, 0},
-};
-
-struct sockinet {
-	u_char	si_len;
-	u_char	si_family;
-	u_short	si_port;
-};
-
-#ifdef INET6
-static int ip6_parsenumeric(const struct sockaddr *, const char *, char *,
-				 size_t, int);
-static int ip6_sa2str(const struct sockaddr_in6 *, char *, size_t, int);
-#endif
-
-#define ENI_NOSOCKET 	EAI_FAIL
-#define ENI_NOSERVNAME	EAI_NONAME
-#define ENI_NOHOSTNAME	EAI_NONAME
-#define ENI_MEMORY	EAI_MEMORY
-#define ENI_SYSTEM	EAI_SYSTEM
-#define ENI_FAMILY	EAI_FAMILY
-#define ENI_SALEN	EAI_FAMILY
-
-int
-getnameinfo( const struct sockaddr *sa, socklen_t salen, char *host, size_t hostlen, char *serv, size_t servlen, int flags)
-{
-	struct afd *afd;
-	struct servent *sp;
-	struct hostent *hp;
-	u_short port;
-	int family, i;
-	const char *addr;
-	unsigned int v4a;
-	char numserv[512];
-	char numaddr[512];
-
-	if (sa == NULL)
-		return ENI_NOSOCKET;
-
-#if HAVE_SOCKADDR_SA_LEN
-	if (sa->sa_len != salen)
-		return ENI_SALEN;
-#endif
-	
-	family = sa->sa_family;
-	for (i = 0; afdl[i].a_af; i++)
-		if (afdl[i].a_af == family) {
-			afd = &afdl[i];
-			goto found;
-		}
-	return ENI_FAMILY;
-	
- found:
-	if (salen != afd->a_socklen)
-		return ENI_SALEN;
-	
-	/* network byte order */
-	port = ((const struct sockinet *)sa)->si_port;
-	addr = (const char *)sa + afd->a_off;
-
-	if (serv == NULL || servlen == 0) {
-		/*
-		 * do nothing in this case.
-		 * in case you are wondering if "&&" is more correct than
-		 * "||" here: RFC2553 says that serv == NULL OR servlen == 0
-		 * means that the caller does not want the result.
-		 */
-	} else {
-		if (flags & NI_NUMERICSERV)
-			sp = NULL;
-		else {
-			sp = getservbyport(port,
-				(flags & NI_DGRAM) ? "udp" : "tcp");
-		}
-		if (sp) {
-			if (strlen(sp->s_name) > servlen)
-				return ENI_MEMORY;
-			strcpy(serv, sp->s_name);
-		} else {
-			snprintf(numserv, sizeof(numserv), "%d", ntohs(port));
-			if (strlen(numserv) > servlen)
-				return ENI_MEMORY;
-			strcpy(serv, numserv);
-		}
-	}
-
-	switch (sa->sa_family) {
-	case AF_INET:
-		v4a = (unsigned int)
-		    ntohl(((const struct sockaddr_in *)sa)->sin_addr.s_addr);
-		if (IN_MULTICAST(v4a) || IN_EXPERIMENTAL(v4a))
-			flags |= NI_NUMERICHOST;
-		v4a >>= IN_CLASSA_NSHIFT;
-		if (v4a == 0)
-			flags |= NI_NUMERICHOST;			
-		break;
-#ifdef INET6
-	case AF_INET6:
-	    {
-		const struct sockaddr_in6 *sin6;
-		sin6 = (const struct sockaddr_in6 *)sa;
-		switch (sin6->sin6_addr.s6_addr[0]) {
-		case 0x00:
-			if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr))
-				;
-			else if (IN6_IS_ADDR_LOOPBACK(&sin6->sin6_addr))
-				;
-			else
-				flags |= NI_NUMERICHOST;
-			break;
-		default:
-			if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
-				flags |= NI_NUMERICHOST;
-			}
-			else if (IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr))
-				flags |= NI_NUMERICHOST;
-			break;
-		}
-	    }
-		break;
-#endif
-	}
-	if (host == NULL || hostlen == 0) {
-		/*
-		 * do nothing in this case.
-		 * in case you are wondering if "&&" is more correct than
-		 * "||" here: RFC2553 says that host == NULL OR hostlen == 0
-		 * means that the caller does not want the result.
-		 */
-	} else if (flags & NI_NUMERICHOST) {
-		int numaddrlen;
-
-		/* NUMERICHOST and NAMEREQD conflicts with each other */
-		if (flags & NI_NAMEREQD)
-			return ENI_NOHOSTNAME;
-
-		switch(afd->a_af) {
-#ifdef INET6
-		case AF_INET6:
-		{
-			int error;
-
-			if ((error = ip6_parsenumeric(sa, addr, host,
-						      hostlen, flags)) != 0)
-				return(error);
-			break;
-		}
-#endif
-		default:
-			if (inet_ntop(afd->a_af, addr, numaddr, sizeof(numaddr))
-			    == NULL)
-				return ENI_SYSTEM;
-			numaddrlen = strlen(numaddr);
-			if (numaddrlen + 1 > hostlen) /* don't forget terminator */
-				return ENI_MEMORY;
-			strcpy(host, numaddr);
-			break;
-		}
-	} else {
-		hp = gethostbyaddr(addr, afd->a_addrlen, afd->a_af);
-
-		if (hp) {
-#if 0
-			/*
-			 * commented out, since "for local host" is not
-			 * implemented here - see RFC2553 p30
-			 */
-			if (flags & NI_NOFQDN) {
-				char *p;
-				p = strchr(hp->h_name, '.');
-				if (p)
-					*p = '\0';
-			}
-#endif
-			if (strlen(hp->h_name) > hostlen) {
-				return ENI_MEMORY;
-			}
-			strcpy(host, hp->h_name);
-		} else {
-			if (flags & NI_NAMEREQD)
-				return ENI_NOHOSTNAME;
-			switch(afd->a_af) {
-#ifdef INET6
-			case AF_INET6:
-			{
-				int error;
-
-				if ((error = ip6_parsenumeric(sa, addr, host,
-							      hostlen,
-							      flags)) != 0)
-					return(error);
-				break;
-			}
-#endif
-			default:
-				if (inet_ntop(afd->a_af, addr, host,
-				    hostlen) == NULL)
-					return ENI_SYSTEM;
-				break;
-			}
-		}
-	}
-	return SUCCESS;
-}
-
-#ifdef INET6
-static int
-ip6_parsenumeric(const struct sockaddr *sa, const char *addr, char *host, size_t hostlen, int flags)
-{
-	int numaddrlen;
-	char numaddr[512];
-
-	if (inet_ntop(AF_INET6, addr, numaddr, sizeof(numaddr))
-	    == NULL)
-		return ENI_SYSTEM;
-
-	numaddrlen = strlen(numaddr);
-	if (numaddrlen + 1 > hostlen) /* don't forget terminator */
-		return ENI_MEMORY;
-	strcpy(host, numaddr);
-
-#ifdef NI_WITHSCOPEID
-	if (((const struct sockaddr_in6 *)sa)->sin6_scope_id) {
-		if (flags & NI_WITHSCOPEID)
-		{
-			char scopebuf[MAXHOSTNAMELEN];
-			int scopelen;
-
-			/* ip6_sa2str never fails */
-			scopelen = ip6_sa2str((const struct sockaddr_in6 *)sa,
-					      scopebuf, sizeof(scopebuf),
-					      0);
-			if (scopelen + 1 + numaddrlen + 1 > hostlen)
-				return ENI_MEMORY;
-			/*
-			 * construct <numeric-addr><delim><scopeid>
-			 */
-			memcpy(host + numaddrlen + 1, scopebuf,
-			       scopelen);
-			host[numaddrlen] = SCOPE_DELIMITER;
-			host[numaddrlen + 1 + scopelen] = '\0';
-		}
-	}
-#endif /* NI_WITHSCOPEID */
-
-	return 0;
-}
-
-static int
-ip6_sa2str(const struct sockaddr_in6 *sa6, char *buf, size_t bufsiz, int flags)
-{
-	unsigned int ifindex = (unsigned int)sa6->sin6_scope_id;
-	const struct in6_addr *a6 = &sa6->sin6_addr;
-
-#ifdef notyet
-	if (flags & NI_NUMERICSCOPE) {
-		return(snprintf(buf, bufsiz, "%d", sa6->sin6_scope_id));
-	}
-#endif
-
-		/*
-		 * some systems (MacOS X) don't have IF_NAMESIZE
-		 * or if_indextoname()
-		 */
-#if 0
-	/* if_indextoname() does not take buffer size.  not a good api... */
-	if ((IN6_IS_ADDR_LINKLOCAL(a6) || IN6_IS_ADDR_MC_LINKLOCAL(a6)) &&
-	    bufsiz >= IF_NAMESIZE) {
-		char *p = if_indextoname(ifindex, buf);
-		if (p) {
-			return(strlen(p));
-		}
-	}
-#endif
-
-	/* last resort */
-	return(snprintf(buf, bufsiz, "%u", sa6->sin6_scope_id));
-}
-#endif /* INET6 */
-
-#endif /* HAVE_GETNAMEINFO */
diff -Nru ircii-20190117/source/hook.c ircii-20210314/source/hook.c
--- ircii-20190117/source/hook.c	2019-01-18 11:29:41.000000000 +0100
+++ ircii-20210314/source/hook.c	2021-03-14 19:32:27.000000000 +0100
@@ -5,7 +5,7 @@
  *
  * Copyright (c) 1990 Michael Sandrof.
  * Copyright (c) 1991, 1992 Troy Rollo.
- * Copyright (c) 1992-2017 Matthew R. Green.
+ * Copyright (c) 1992-2021 Matthew R. Green.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -33,7 +33,7 @@
  */
 
 #include "irc.h"
-IRCII_RCSID("@(#)$eterna: hook.c,v 1.93 2019/01/17 04:29:46 mrg Exp $");
+IRCII_RCSID("@(#)$eterna: hook.c,v 1.97 2021/02/27 08:02:14 mrg Exp $");
 
 #include "hook.h"
 #include "vars.h"
@@ -238,7 +238,7 @@
  * A variety of comparison functions used by the hook routines follow.
  */
 
-struct	CmpInfoStruc
+static	struct	CmpInfoStruc
 {
 	int	ServerRequired;
 	int	SerialNumber;
@@ -248,8 +248,6 @@
 #define	CIF_NOSERNUM	0x0001
 #define	CIF_SKIP	0x0002
 
-int	cmpinfodone = 0;
-
 static void
 setup_struct(int ServReq, int SerNum, int flags)
 {
@@ -286,6 +284,11 @@
 	Hook	*new;
 	u_char	buf[4];
 
+	if (numeric < 0 || numeric > 999) {
+		yell("--- numeric is out of range: %d\n", numeric);
+		return;
+	}
+
 	snprintf(CP(buf), sizeof buf, "%3.3u", numeric);
 	if ((entry = (NumericList *) find_in_list((List **)(void *)&numeric_list, buf, 0)) == NULL)
 	{
@@ -393,9 +396,17 @@
 	u_char	buf[4];
 	int	cnt = 0;
 
+	if (numeric < 0 || numeric > 999) {
+		yell("--- numeric is out of range: %d\n", numeric);
+		return cnt;
+	}
+
 	if (numeric)
 	{
-		snprintf(CP(buf), sizeof buf, "%3.3u", numeric);
+		if (snprintf(CP(buf), sizeof buf, "%3.3u", numeric) > sizeof buf)
+		{
+			yell("--- truncated, wanted '%3.3u'", numeric);
+		}
 		if ((tmp = (NumericList *) find_in_list((List **)(void *)&numeric_list, buf, 0))
 				!= NULL)
 		{
@@ -466,6 +477,12 @@
 	Hook *bestmatch = NULL;
 	int nomorethisserial = 0;
 
+	if (which < -999)
+	{
+		yell("do_hook: which (%d) < -999", which);
+		return 0;
+	}
+
 	hook_level++;
 
 	va_start(vl, format);
@@ -475,8 +492,17 @@
 	{
 		NumericList *hook;
 		u_char	buf[4];
+		int numeric = -which;
 
-		snprintf(CP(buf), sizeof buf, "%3.3u", -which);
+		if (numeric < 0 || numeric > 999) {
+			yell("--- numeric is out of range: %d\n", numeric);
+			goto out;
+		}
+
+		if (snprintf(CP(buf), sizeof buf, "%3.3u", numeric) > sizeof buf)
+		{
+			yell("--- truncated, wanted '%3.3u'", numeric);
+		}
 		if ((hook = (NumericList *) find_in_list((List **)(void *)&numeric_list, buf, 0))
 				!= NULL)
 		{
@@ -503,7 +529,6 @@
 	}
 	if (!list)
 	{
-		RetVal = 1;
 		goto out;
 	}
 
@@ -597,7 +622,15 @@
 		*next;
 	u_char	buf[4];
 
-	snprintf(CP(buf), sizeof buf, "%3.3u", numeric);
+	if (numeric < 0 || numeric > 999) {
+		yell("--- numeric is out of range: %d\n", numeric);
+		return;
+	}
+		
+	if (snprintf(CP(buf), sizeof buf, "%3.3u", numeric) > sizeof buf)
+	{
+		yell("--- truncated, wanted '%3.3u'", numeric);
+	}
 	if ((hook = (NumericList *) find_in_list((List **)(void *)&numeric_list, buf,0)) != NULL)
 	{
 		if (nick)
@@ -653,6 +686,11 @@
 	Hook	*tmp,
 		*next;
 
+	if (which < -999)
+	{
+		yell("remove_hook: which (%d) < -999", which);
+		return;
+	}
 	if (which < 0)
 	{
 		remove_numeric_hook(-which, nick, server, sernum, quiet);
diff -Nru ircii-20190117/source/icb.c ircii-20210314/source/icb.c
--- ircii-20190117/source/icb.c	2019-01-18 11:29:41.000000000 +0100
+++ ircii-20210314/source/icb.c	2021-03-14 19:32:27.000000000 +0100
@@ -3,7 +3,7 @@
  *
  * written by matthew green
  *
- * copyright (C) 1995-2014.  Matthew R. Green.
+ * copyright (C) 1995-2021.  Matthew R. Green.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,7 +31,7 @@
  */
 
 #include "irc.h"
-IRCII_RCSID("@(#)$eterna: icb.c,v 2.98 2017/10/31 20:17:33 mrg Exp $");
+IRCII_RCSID("@(#)$eterna: icb.c,v 2.101 2021/02/27 08:00:42 mrg Exp $");
 
 /*
  * ICB protocol is weird.  everything is separated by ASCII 001.  there
@@ -702,7 +702,7 @@
 
 	if (!chan)
 		chan = empty_string();
-	if (!mode && !*mode)
+	if (!mode || !*mode)
 		mode = icb_initial_status;
 	say("You are wasting time.");
 	server_is_connected(server, 1);
@@ -781,8 +781,8 @@
 	u_char *mode, *prefix;
 
 	mode = server_get_icbmode(parsing_server());
-	if (group[0] != '.' && group[1] != '.' &&
-	    mode && mode[1] == 'i') {
+	if (my_strcmp(group, "..") == 0 &&
+	    mode && my_strlen(mode) > 1 && mode[1] == 'i') {
 		/* save previous status */
 		prefix = UP("..");
 	} else
diff -Nru ircii-20190117/source/inet_ntop.c ircii-20210314/source/inet_ntop.c
--- ircii-20190117/source/inet_ntop.c	2019-01-18 11:29:41.000000000 +0100
+++ ircii-20210314/source/inet_ntop.c	1970-01-01 01:00:00.000000000 +0100
@@ -1,199 +0,0 @@
-/*	Id: inet_ntop.c,v 1.4 2001/04/17 07:53:47 lukem Exp 	*/
-/*	$NetBSD: inet_ntop.c,v 1.9 2000/01/22 22:19:16 mycroft Exp $	*/
-
-/* Copyright (c) 1996 by Internet Software Consortium.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
- * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
- * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
- * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
- * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
- * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
- * SOFTWARE.
- */
-
-#include "irc.h"
-IRCII_RCSID("@(#)$eterna: inet_ntop.c,v 1.5 2013/08/27 23:57:04 agc Exp $");
-
-#ifndef HAVE_INET_NTOP
-
-#if HAVE_ARPA_NAMESER_H
-#include <arpa/nameser.h>
-#endif
-
-#ifndef IN6ADDRSZ
-#define	IN6ADDRSZ	16
-#endif
-
-#ifndef INT16SZ
-#define	INT16SZ		2
-#endif
-
-#ifdef SPRINTF_CHAR
-# define SPRINTF(x) strlen(sprintf/**/x)
-#else
-# define SPRINTF(x) ((size_t)sprintf x)
-#endif
-
-/*
- * WARNING: Don't even consider trying to compile this on a system where
- * sizeof(int) < 4.  sizeof(int) > 4 is fine; all the world's not a VAX.
- */
-
-static const char *inet_ntop4(const u_char *src, char *dst, size_t size);
-#ifdef INET6
-static const char *inet_ntop6(const u_char *src, char *dst, size_t size);
-#endif /* INET6 */
-
-/* char *
- * inet_ntop(af, src, dst, size)
- *	convert a network format address to presentation format.
- * return:
- *	pointer to presentation format address (`dst'), or NULL (see errno).
- * author:
- *	Paul Vixie, 1996.
- */
-const char *
-inet_ntop(int af, const void *src, char *dst, size_t size)
-{
-
-	switch (af) {
-	case AF_INET:
-		return (inet_ntop4(src, dst, size));
-#ifdef INET6
-	case AF_INET6:
-		return (inet_ntop6(src, dst, size));
-#endif
-	default:
-		errno = EAFNOSUPPORT;
-		return (NULL);
-	}
-	/* NOTREACHED */
-}
-
-/* const char *
- * inet_ntop4(src, dst, size)
- *	format an IPv4 address, more or less like inet_ntoa()
- * return:
- *	`dst' (as a const)
- * notes:
- *	(1) uses no statics
- *	(2) takes a u_char* not an in_addr as input
- * author:
- *	Paul Vixie, 1996.
- */
-static const char *
-inet_ntop4(const u_char *src, char *dst, size_t size)
-{
-	static const char fmt[] = "%u.%u.%u.%u";
-	char tmp[sizeof "255.255.255.255"];
-
-	if (SPRINTF((tmp, fmt, src[0], src[1], src[2], src[3])) > size) {
-		errno = ENOSPC;
-		return (NULL);
-	}
-	strcpy(dst, tmp);
-	return (dst);
-}
-
-#ifdef INET6
-/* const char *
- * inet_ntop6(src, dst, size)
- *	convert IPv6 binary address into presentation (printable) format
- * author:
- *	Paul Vixie, 1996.
- */
-static const char *
-inet_ntop6(const u_char *src, char *dst, size_t size)
-{
-	/*
-	 * Note that int32_t and int16_t need only be "at least" large enough
-	 * to contain a value of the specified size.  On some systems, like
-	 * Crays, there is no such thing as an integer variable with 16 bits.
-	 * Keep this in mind if you think this function should have been coded
-	 * to use pointer overlays.  All the world's not a VAX.
-	 */
-	char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"], *tp;
-	struct { int base, len; } best, cur;
-	u_int words[IN6ADDRSZ / INT16SZ];
-	int i;
-
-	/*
-	 * Preprocess:
-	 *	Copy the input (bytewise) array into a wordwise array.
-	 *	Find the longest run of 0x00's in src[] for :: shorthanding.
-	 */
-	memset(words, '\0', sizeof words);
-	for (i = 0; i < IN6ADDRSZ; i++)
-		words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3));
-	best.base = -1;
-	cur.base = -1;
-	for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) {
-		if (words[i] == 0) {
-			if (cur.base == -1)
-				cur.base = i, cur.len = 1;
-			else
-				cur.len++;
-		} else {
-			if (cur.base != -1) {
-				if (best.base == -1 || cur.len > best.len)
-					best = cur;
-				cur.base = -1;
-			}
-		}
-	}
-	if (cur.base != -1) {
-		if (best.base == -1 || cur.len > best.len)
-			best = cur;
-	}
-	if (best.base != -1 && best.len < 2)
-		best.base = -1;
-
-	/*
-	 * Format the result.
-	 */
-	tp = tmp;
-	for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) {
-		/* Are we inside the best run of 0x00's? */
-		if (best.base != -1 && i >= best.base &&
-		    i < (best.base + best.len)) {
-			if (i == best.base)
-				*tp++ = ':';
-			continue;
-		}
-		/* Are we following an initial run of 0x00s or any real hex? */
-		if (i != 0)
-			*tp++ = ':';
-		/* Is this address an encapsulated IPv4? */
-		if (i == 6 && best.base == 0 &&
-		    (best.len == 6 || (best.len == 5 && words[5] == 0xffff))) {
-			if (!inet_ntop4(src+12, tp, sizeof tmp - (tp - tmp)))
-				return (NULL);
-			tp += strlen(tp);
-			break;
-		}
-		tp += SPRINTF((tp, "%x", words[i]));
-	}
-	/* Was it a trailing run of 0x00's? */
-	if (best.base != -1 && (best.base + best.len) == (IN6ADDRSZ / INT16SZ))
-		*tp++ = ':';
-	*tp++ = '\0';
-
-	/*
-	 * Check for overflow, copy, and we're done.
-	 */
-	if ((size_t)(tp - tmp) > size) {
-		errno = ENOSPC;
-		return (NULL);
-	}
-	strcpy(dst, tmp);
-	return (dst);
-}
-#endif
-
-#endif /* HAVE_INET_NTOP */
diff -Nru ircii-20190117/source/inet_pton.c ircii-20210314/source/inet_pton.c
--- ircii-20190117/source/inet_pton.c	2019-01-18 11:29:41.000000000 +0100
+++ ircii-20210314/source/inet_pton.c	1970-01-01 01:00:00.000000000 +0100
@@ -1,291 +0,0 @@
-/*	Id: inet_pton.c,v 1.5 2001/04/13 15:24:35 lukem Exp 	*/
-/*	$NetBSD: inet_pton.c,v 1.16 2000/02/07 18:51:02 itojun Exp $	*/
-
-/* Copyright (c) 1996 by Internet Software Consortium.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
- * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
- * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
- * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
- * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
- * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
- * SOFTWARE.
- */
-
-#include "irc.h"
-IRCII_RCSID("@(#)$eterna: inet_pton.c,v 1.5 2013/08/27 23:57:04 agc Exp $");
-
-#ifndef HAVE_INET_PTON
-
-#if HAVE_ARPA_NAMESER_H
-#include <arpa/nameser.h>
-#endif
-
-#ifndef INADDRSZ
-#define	INADDRSZ	4
-#endif
-
-/*
- * WARNING: Don't even consider trying to compile this on a system where
- * sizeof(int) < 4.  sizeof(int) > 4 is fine; all the world's not a VAX.
- */
-
-static int	inet_pton4(const char *src, u_char *dst, int pton);
-#ifdef INET6
-static int	inet_pton6(const char *src, u_char *dst);
-#endif
-
-/* int
- * inet_pton(af, src, dst)
- *	convert from presentation format (which usually means ASCII printable)
- *	to network format (which is usually some kind of binary format).
- * return:
- *	1 if the address was valid for the specified address family
- *	0 if the address wasn't valid (`dst' is untouched in this case)
- *	-1 if some other error occurred (`dst' is untouched in this case, too)
- * author:
- *	Paul Vixie, 1996.
- */
-int
-inet_pton(int af, const char *src, void *dst)
-{
-
-	switch (af) {
-	case AF_INET:
-		return (inet_pton4(src, dst, 1));
-#ifdef INET6
-	case AF_INET6:
-		return (inet_pton6(src, dst));
-#endif
-	default:
-		errno = EAFNOSUPPORT;
-		return (-1);
-	}
-	/* NOTREACHED */
-}
-
-/* int
- * inet_pton4(src, dst, pton)
- *	when last arg is 0: inet_aton(). with hexadecimal, octal and shorthand.
- *	when last arg is 1: inet_pton(). decimal dotted-quad only.
- * return:
- *	1 if `src' is a valid input, else 0.
- * notice:
- *	does not touch `dst' unless it's returning 1.
- * author:
- *	Paul Vixie, 1996.
- */
-static int
-inet_pton4(const char *src, u_char *dst, int pton)
-{
-	u_int val;
-	u_int digit;
-	int base, n;
-	unsigned char c;
-	u_int parts[4];
-	register u_int *pp = parts;
-
-	c = *src;
-	for (;;) {
-		/*
-		 * Collect number up to ``.''.
-		 * Values are specified as for C:
-		 * 0x=hex, 0=octal, isdigit=decimal.
-		 */
-		if (!isdigit(c))
-			return (0);
-		val = 0; base = 10;
-		if (c == '0') {
-			c = *++src;
-			if (c == 'x' || c == 'X')
-				base = 16, c = *++src;
-			else if (isdigit(c) && c != '9')
-				base = 8;
-		}
-		/* inet_pton() takes decimal only */
-		if (pton && base != 10)
-			return (0);
-		for (;;) {
-			if (isdigit(c)) {
-				digit = c - '0';
-				if (digit >= base)
-					break;
-				val = (val * base) + digit;
-				c = *++src;
-			} else if (base == 16 && isxdigit(c)) {
-				digit = c + 10 - (islower(c) ? 'a' : 'A');
-				if (digit >= 16)
-					break;
-				val = (val << 4) | digit;
-				c = *++src;
-			} else
-				break;
-		}
-		if (c == '.') {
-			/*
-			 * Internet format:
-			 *	a.b.c.d
-			 *	a.b.c	(with c treated as 16 bits)
-			 *	a.b	(with b treated as 24 bits)
-			 *	a	(with a treated as 32 bits)
-			 */
-			if (pp >= parts + 3)
-				return (0);
-			*pp++ = val;
-			c = *++src;
-		} else
-			break;
-	}
-	/*
-	 * Check for trailing characters.
-	 */
-	if (c != '\0' && !isspace(c))
-		return (0);
-	/*
-	 * Concoct the address according to
-	 * the number of parts specified.
-	 */
-	n = pp - parts + 1;
-	/* inet_pton() takes dotted-quad only.  it does not take shorthand. */
-	if (pton && n != 4)
-		return (0);
-	switch (n) {
-
-	case 0:
-		return (0);		/* initial nondigit */
-
-	case 1:				/* a -- 32 bits */
-		break;
-
-	case 2:				/* a.b -- 8.24 bits */
-		if (parts[0] > 0xff || val > 0xffffff)
-			return (0);
-		val |= parts[0] << 24;
-		break;
-
-	case 3:				/* a.b.c -- 8.8.16 bits */
-		if ((parts[0] | parts[1]) > 0xff || val > 0xffff)
-			return (0);
-		val |= (parts[0] << 24) | (parts[1] << 16);
-		break;
-
-	case 4:				/* a.b.c.d -- 8.8.8.8 bits */
-		if ((parts[0] | parts[1] | parts[2] | val) > 0xff)
-			return (0);
-		val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
-		break;
-	}
-	if (dst) {
-		val = htonl(val);
-		memcpy(dst, &val, INADDRSZ);
-	}
-	return (1);
-}
-
-#ifdef INET6
-/* int
- * inet_pton6(src, dst)
- *	convert presentation level address to network order binary form.
- * return:
- *	1 if `src' is a valid [RFC1884 2.2] address, else 0.
- * notice:
- *	(1) does not touch `dst' unless it's returning 1.
- *	(2) :: in a full address is silently ignored.
- * credit:
- *	inspired by Mark Andrews.
- * author:
- *	Paul Vixie, 1996.
- */
-static int
-inet_pton6(const char *src, u_char *dst)
-{
-	static const char xdigits_l[] = "0123456789abcdef",
-			  xdigits_u[] = "0123456789ABCDEF";
-	u_char tmp[IN6ADDRSZ], *tp, *endp, *colonp;
-	const char *xdigits, *curtok;
-	int ch, saw_xdigit;
-	u_int val;
-
-	memset((tp = tmp), '\0', IN6ADDRSZ);
-	endp = tp + IN6ADDRSZ;
-	colonp = NULL;
-	/* Leading :: requires some special handling. */
-	if (*src == ':')
-		if (*++src != ':')
-			return (0);
-	curtok = src;
-	saw_xdigit = 0;
-	val = 0;
-	while ((ch = *src++) != '\0') {
-		const char *pch;
-
-		if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL)
-			pch = strchr((xdigits = xdigits_u), ch);
-		if (pch != NULL) {
-			val <<= 4;
-			val |= (pch - xdigits);
-			if (val > 0xffff)
-				return (0);
-			saw_xdigit = 1;
-			continue;
-		}
-		if (ch == ':') {
-			curtok = src;
-			if (!saw_xdigit) {
-				if (colonp)
-					return (0);
-				colonp = tp;
-				continue;
-			} else if (*src == '\0')
-				return (0);
-			if (tp + INT16SZ > endp)
-				return (0);
-			*tp++ = (u_char) (val >> 8) & 0xff;
-			*tp++ = (u_char) val & 0xff;
-			saw_xdigit = 0;
-			val = 0;
-			continue;
-		}
-		if (ch == '.' && ((tp + INADDRSZ) <= endp) &&
-		    inet_pton4(curtok, tp, 1) > 0) {
-			tp += INADDRSZ;
-			saw_xdigit = 0;
-			break;	/* '\0' was seen by inet_pton4(). */
-		}
-		return (0);
-	}
-	if (saw_xdigit) {
-		if (tp + INT16SZ > endp)
-			return (0);
-		*tp++ = (u_char) (val >> 8) & 0xff;
-		*tp++ = (u_char) val & 0xff;
-	}
-	if (colonp != NULL) {
-		/*
-		 * Since some memmove()'s erroneously fail to handle
-		 * overlapping regions, we'll do the shift by hand.
-		 */
-		const int n = tp - colonp;
-		int i;
-
-		if (tp == endp)
-			return (0);
-		for (i = 1; i <= n; i++) {
-			endp[- i] = colonp[n - i];
-			colonp[n - i] = 0;
-		}
-		tp = endp;
-	}
-	if (tp != endp)
-		return (0);
-	memcpy(dst, tmp, IN6ADDRSZ);
-	return (1);
-}
-#endif
-
-#endif /* HAVE_INET_PTON */
diff -Nru ircii-20190117/source/irc.c ircii-20210314/source/irc.c
--- ircii-20190117/source/irc.c	2019-01-18 11:31:26.000000000 +0100
+++ ircii-20210314/source/irc.c	2021-03-14 19:32:27.000000000 +0100
@@ -5,7 +5,7 @@
  * 
  * Copyright (c) 1990 Michael Sandrof.
  * Copyright (c) 1991, 1992 Troy Rollo.
- * Copyright (c) 1992-2019 Matthew R. Green.
+ * Copyright (c) 1992-2021 Matthew R. Green.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -32,10 +32,10 @@
  * SUCH DAMAGE.
  */
 
-#define IRCII_VERSION	"20190117"	/* YYYYMMDD */
+#define IRCII_VERSION	"20210314"	/* YYYYMMDD */
 
 #include "irc.h"
-IRCII_RCSID("@(#)$eterna: irc.c,v 1.404 2019/01/18 10:31:26 mrg Exp $");
+IRCII_RCSID("@(#)$eterna: irc.c,v 1.416 2021/03/14 18:22:31 mrg Exp $");
 
 #include <sys/stat.h>
 #include <pwd.h>
@@ -72,6 +72,7 @@
 #include "strsep.h"
 #include "notice.h"
 #include "icb.h"
+#include "signals.h"
 
 static	int	qflag;			/* set if we ignore .ircrc */
 static	int	bflag;			/* set if we load .ircrc before connecting */
@@ -85,7 +86,7 @@
 		do_refresh_screen,
 		no_full_screen = 0,
 		cur_signal = -1,		/* head of below */
-		occurred_signals[16],		/* got signal which may
+		occurred_signals[64],		/* got signal which may
 						   require /ON action */
 		client_default_icb = 0,		/* default to irc server
 						   connections */
@@ -299,27 +300,6 @@
 	exit (0);
 }
 
-static	void
-open_log_file(u_char *file)
-{
-	FILE	*fp;
-
-	if (!file)
-	{
-		printf("irc: need filename for -o\n");
-		exit(-1);
-	}
-	fflush(stderr);
-	fp = freopen(CP(file), "w", stderr);
-	if (!fp)
-	{
-		printf("irc: can not open %s: %s\n",
-		       file,
-		       errno ? "" : strerror(errno));
-		exit(-1);
-	}
-}
-
 /* get_arg: used by parse_args() to get an argument after a switch */
 static	u_char	*
 get_arg(u_char *arg, u_char *next, int *ac)
@@ -549,7 +529,7 @@
 #endif /* IRCPATH */
 	}
 
-	/* now, open the log file, which redirects stderr */
+	/* now, open the log file */
 	if (log_file)
 		open_log_file(log_file);
 
@@ -849,7 +829,7 @@
 			for (i = 0; i <= cur_signal; i++)
 				if (occurred_signals[i] != 0)
 					do_hook(OS_SIGNAL_LIST, "%s",
-					    my_sigstr(occurred_signals[i]));
+					    get_signal(i, 0));
 			cur_signal = -1;
 			if (!hold_over)
 				cursor_to_input();
diff -Nru ircii-20190117/source/ircaux.c ircii-20210314/source/ircaux.c
--- ircii-20190117/source/ircaux.c	2019-01-18 11:29:41.000000000 +0100
+++ ircii-20210314/source/ircaux.c	2021-03-14 19:32:27.000000000 +0100
@@ -5,7 +5,7 @@
  *
  * Copyright (c) 1990, 1991 Michael Sandrof.
  * Copyright (c) 1991, 1992 Troy Rollo.
- * Copyright (c) 1992-2019 Matthew R. Green.
+ * Copyright (c) 1992-2021 Matthew R. Green.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -33,7 +33,7 @@
  */
 
 #include "irc.h"
-IRCII_RCSID("@(#)$eterna: ircaux.c,v 1.127 2019/01/15 09:59:53 mrg Exp $");
+IRCII_RCSID("@(#)$eterna: ircaux.c,v 1.131 2021/03/14 18:22:31 mrg Exp $");
 
 #ifdef HAVE_SYS_UN_H
 #include <sys/un.h>
@@ -50,6 +50,21 @@
 
 static int bind_local_addr(u_char *, int, int);
 
+#ifdef DO_USER2
+#define MASK_EXTRA	sigaddset(&sigs, SIGUSR2);
+#else
+#define MASK_EXTRA	/* nothing */
+#endif /* DO_USER2 */
+
+#define MASK_DECL	sigset_t sigs, osigs;
+#define MASK_BLOCK	do					\
+{								\
+			sigemptyset(&sigs);			\
+			sigaddset(&sigs, SIGUSR1);		\
+			MASK_EXTRA				\
+			sigprocmask(SIG_BLOCK, &sigs, &osigs);	\
+} while (0);
+#define MASK_UNBLOCK	sigprocmask(SIG_SETMASK, &osigs, NULL);
 
 /*
  * new_free:  Why do this?  Why not?  Saves me a bit of trouble here and
@@ -59,27 +74,16 @@
 new_free(void *iptr)
 {
 	void	**ptr = (void **) iptr;
-#ifdef DO_USER2
-	int	oldmask;
-#endif /* DO_USER2 */
+	MASK_DECL
 
 	/* cheap hack. */
 	if (*ptr == empty_string() || *ptr == zero() || *ptr == one())
 		*ptr = NULL;
 	else if (*ptr)
 	{
-#ifdef DO_USER2
-		oldmask = sigblock(sigmask(SIGUSR2));
-#endif /* DO_USER2 */
-#ifdef FREE_DEBUG
-		if (free(*ptr) < 0)
-			put_it("*debug* free failed '%s'", (u_char *) ptr);
-#else
+		MASK_BLOCK
 		free(*ptr);
-#endif /* FREE_DEBUG */
-#ifdef DO_USER2
-		sigblock(oldmask);
-#endif /* DO_USER2 */
+		MASK_UNBLOCK
 		*ptr = NULL;
 	}
 }
@@ -119,13 +123,16 @@
 new_realloc(void *ptr, size_t size)
 {
 	void	*new_ptr;
+	MASK_DECL
 
+	MASK_BLOCK
 	if ((new_ptr = realloc(ptr, size)) == NULL)
 	{
 		fprintf(stderr, "realloc failed (%d): %s\nIrc Aborted!\n",
 			(int)size, strerror(errno));
 		exit(1);
 	}
+	MASK_UNBLOCK
 	return (new_ptr);
 }
 
@@ -133,7 +140,9 @@
 new_malloc(size_t size)
 {
 	void	*ptr;
+	MASK_DECL
 
+	MASK_BLOCK
 	if ((ptr = malloc(size)) == NULL)
 	{
 		static	char	error[] = "Malloc failed: \nIrc Aborted!\n";
@@ -143,6 +152,7 @@
 		term_reset();
 		exit(1);
 	}
+	MASK_UNBLOCK
 	return (ptr);
 }
 
@@ -187,6 +197,11 @@
 	u_char	*new;
 	char	b;
 
+	if (fmt == NULL)
+	{
+		new_free(ptr);
+		return;
+	}
 	va_start(ap, fmt);
 	va_copy(ap2, ap);
 	rv = vsnprintf(&b, 0, fmt, ap);
@@ -206,6 +221,11 @@
 	u_char	*new;
 	char	b;
 
+	if (fmt == NULL)
+	{
+		new_free(ptr);
+		return;
+	}
 	va_copy(ap2, ap);
 	rv = vsnprintf(&b, 0, fmt, ap);
 	new = new_malloc(rv + 1);
@@ -421,6 +441,8 @@
 			 */
 			if (oldres && oldres0)
 			{
+				if (*oldres0)
+					freeaddrinfo(*oldres0);
 				*oldres = res->ai_next;
 				*oldres0 = res0;
 				res0 = 0;
diff -Nru ircii-20190117/source/ircflush.c ircii-20210314/source/ircflush.c
--- ircii-20190117/source/ircflush.c	2019-01-18 11:29:41.000000000 +0100
+++ ircii-20210314/source/ircflush.c	2021-03-14 19:32:27.000000000 +0100
@@ -6,7 +6,7 @@
  *
  * Copyright (c) 1990 Michael Sandrof.
  * Copyright (c) 1991, 1992 Troy Rollo.
- * Copyright (c) 1992-2014 Matthew R. Green.
+ * Copyright (c) 1992-2021 Matthew R. Green.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -34,7 +34,7 @@
  */
 
 #include "irc.h"
-IRCII_RCSID("@(#)$eterna: ircflush.c,v 1.46 2014/03/17 18:51:42 mrg Exp $");
+IRCII_RCSID("@(#)$eterna: ircflush.c,v 1.49 2021/02/24 21:47:46 mrg Exp $");
 
 #include <sys/wait.h>
 
@@ -68,7 +68,7 @@
 static void
 setup_master_slave(void)
 {
-	char	line[11];
+	char	line[24];
 	char	linec;
 	int	linen;
 
diff -Nru ircii-20190117/source/mail.c ircii-20210314/source/mail.c
--- ircii-20190117/source/mail.c	2019-01-18 11:29:41.000000000 +0100
+++ ircii-20210314/source/mail.c	2021-03-14 19:32:27.000000000 +0100
@@ -33,7 +33,7 @@
  */
 
 #include "irc.h"
-IRCII_RCSID("@(#)$eterna: mail.c,v 1.61 2017/11/02 00:41:42 mrg Exp $");
+IRCII_RCSID("@(#)$eterna: mail.c,v 1.62 2021/03/02 21:47:06 mrg Exp $");
 
 #include <sys/stat.h>
 
@@ -162,7 +162,10 @@
 					{
 						while (dgets(buffer, sizeof buffer, des) > 0 && *buffer != '\0' && *buffer != '\n')
 						{
-							buffer[my_strlen(buffer)-1] = '\0';
+							u_char *s = my_index(buffer, '\n');
+
+							if (s)
+								*s = '\0';
 							if (!my_strncmp(buffer, "From:", 5) || !my_strncmp(buffer, "Subject:", 8))
 								say("%s", buffer);
 						}
diff -Nru ircii-20190117/source/menu.c ircii-20210314/source/menu.c
--- ircii-20190117/source/menu.c	2019-01-18 11:29:41.000000000 +0100
+++ ircii-20210314/source/menu.c	2021-03-14 19:32:27.000000000 +0100
@@ -32,7 +32,7 @@
  */
 
 #include "irc.h"
-IRCII_RCSID("@(#)$eterna: menu.c,v 1.55 2017/07/09 03:58:24 mrg Exp $");
+IRCII_RCSID("@(#)$eterna: menu.c,v 1.56 2021/03/02 21:47:06 mrg Exp $");
 
 #include "menu.h"
 #include "list.h"
@@ -163,7 +163,10 @@
 	}
 	while (fgets(CP(buffer), sizeof buffer, fp))
 	{
-		buffer[my_strlen(buffer)-1] = '\0';
+		u_char *s = my_index(buffer, '\n');
+
+		if (s)
+			*s = '\0';
 		linenum++;
 		line = buffer;
 		while (isspace(*line))
diff -Nru ircii-20190117/source/mksignals.pl ircii-20210314/source/mksignals.pl
--- ircii-20190117/source/mksignals.pl	2019-01-18 11:29:41.000000000 +0100
+++ ircii-20210314/source/mksignals.pl	2021-03-14 19:32:27.000000000 +0100
@@ -2,13 +2,13 @@
 
 # this does not support RT signals yet - big deal
 
-$rcsid = '$eterna: mksignals.pl,v 1.3 2019/01/16 06:26:12 mrg Exp $';
+$rcsid = '$eterna: mksignals.pl,v 1.4 2020/11/17 08:11:57 mrg Exp $';
 ($my_rcsid = $rcsid) =~ s/^\$(.*)\$$/$1/;
 $from_rcsid = "/* This file is generated from: $my_rcsid */\n\n";
 
 $part_one = <<'__eop1__';
 /*
- * Copyright (c) 2003-2019 Matthew R. Green
+ * Copyright (c) 2003-2020 Matthew R. Green
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -36,9 +36,10 @@
  */
 
 #include "irc.h"
-IRCII_RCSID("@(#)$eterna: mksignals.pl,v 1.3 2019/01/16 06:26:12 mrg Exp $");
+IRCII_RCSID("@(#)$eterna: mksignals.pl,v 1.4 2020/11/17 08:11:57 mrg Exp $");
 
 #include "irc_std.h"
+#include "ircaux.h"
 #include "signals.h"
 
 /*
@@ -46,7 +47,7 @@
  * second and later instances from the file.
  */
 
-const u_char * signals[] = {
+static const u_char * signals[] = {
 
 __eop1__
 
@@ -73,7 +74,24 @@
 $part_two = <<'__eop2__';
 };
 
-const int max_signo = ARRAY_SIZE(signals);
+static const int max_signo = ARRAY_SIZE(signals);
+
+const u_char *
+get_signal(int signo, int nullok)
+{
+	if (signo >= 0 && signo <= max_signo) {
+		if (signals[signo] == NULL) {
+			u_char *newsig = NULL;
+
+			malloc_snprintf(&newsig, "SIG%d", signo);
+			signals[signo] = newsig;
+		}
+		return signals[signo];
+	}
+	if (nullok)
+		return NULL;
+	return UP("(NOSIG)");
+}
 __eop2__
 
 &main();
diff -Nru ircii-20190117/source/newio.c ircii-20210314/source/newio.c
--- ircii-20190117/source/newio.c	2019-01-18 11:29:41.000000000 +0100
+++ ircii-20210314/source/newio.c	2021-03-14 19:32:27.000000000 +0100
@@ -10,7 +10,7 @@
  *
  * Copyright (c) 1990 Michael Sandrof.
  * Copyright (c) 1991, 1992 Troy Rollo.
- * Copyright (c) 1992-2014 Matthew R. Green.
+ * Copyright (c) 1992-2021 Matthew R. Green.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -38,7 +38,7 @@
  */
 
 #include "irc.h"
-IRCII_RCSID("@(#)$eterna: newio.c,v 1.71 2016/12/05 18:48:21 mrg Exp $");
+IRCII_RCSID("@(#)$eterna: newio.c,v 1.76 2021/02/27 08:02:14 mrg Exp $");
 
 #include "ircaux.h"
 #include "newio.h"
@@ -219,7 +219,7 @@
 		while (rec->read_pos < rec->write_pos)
 		{
 			char ch = str[cnt++] = ptr[(rec->read_pos)++];
-			if (ch == (char)dgets_separator || cnt == len)
+			if (ch == (char)dgets_separator || cnt == len-1)
 			{
 				dgets_local_errno = 0;
 				str[cnt] = (char) 0;
@@ -236,12 +236,12 @@
 int
 new_select(fd_set *rd, fd_set *wd, struct timeval *time_out)
 {
-	int	i,
-		set = 0;
-		fd_set new;
+	unsigned i;
+	int	set = 0;
+	fd_set  new;
 	struct	timeval	*newtimeout,
 			thetimeout;
-	int	max_fd = -1;
+	int	nfds = 0;
 
 	if (time_out)
 	{
@@ -254,8 +254,8 @@
 	FD_ZERO(&new);
 	for (i = 0; i < IO_ARRAYLEN; i++)
 	{
-		if (i > max_fd && ((rd && FD_ISSET(i, rd)) || (wd && FD_ISSET(i, wd))))
-			max_fd = i;
+		if ((rd && FD_ISSET(i, rd)) || (wd && FD_ISSET(i, wd)))
+			nfds = i+1;
 		if (io_rec[i] && io_rec[i]->read_pos < io_rec[i]->write_pos)
 		{
 			FD_SET(i, &new);
@@ -265,7 +265,7 @@
 	if (set)
 	{
 		set = 0;
-		if (!(select(max_fd + 1, rd, wd, NULL, &right_away) > 0))
+		if (!(select(nfds, rd, wd, NULL, &right_away) > 0))
 			FD_ZERO(rd);
 		for (i = 0; i < IO_ARRAYLEN; i++)
 		{
@@ -279,7 +279,7 @@
 		}
 		return (set);
 	}
-	return (select(max_fd + 1, rd, wd, NULL, newtimeout));
+	return (select(nfds, rd, wd, NULL, newtimeout));
 }
 
 /* new_close: works just like close */
diff -Nru ircii-20190117/source/notice.c ircii-20210314/source/notice.c
--- ircii-20190117/source/notice.c	2019-01-18 11:29:41.000000000 +0100
+++ ircii-20210314/source/notice.c	2021-03-14 19:32:27.000000000 +0100
@@ -5,7 +5,7 @@
  *
  * Copyright (c) 1990 Michael Sandrof.
  * Copyright (c) 1991, 1992 Troy Rollo.
- * Copyright (c) 1992-2017 Matthew R. Green.
+ * Copyright (c) 1992-2021 Matthew R. Green.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -33,7 +33,7 @@
  */
 
 #include "irc.h"
-IRCII_RCSID("@(#)$eterna: notice.c,v 1.81 2017/11/02 00:41:42 mrg Exp $");
+IRCII_RCSID("@(#)$eterna: notice.c,v 1.83 2021/02/24 10:38:03 mrg Exp $");
 
 #include "whois.h"
 #include "ctcp.h"
@@ -189,7 +189,7 @@
 }
 
 void 
-parse_notice(u_char *from, u_char **Args)
+parse_notice(u_char *comm, u_char *from, u_char **args)
 {
 	int	type;
 	u_char	*to;
@@ -199,9 +199,12 @@
 		not_from_server = 1;
 	u_char	*line;
 
-	paste_args(Args, 1);
-	to = Args[0];
-	line = Args[1];
+	if (check_params(comm, from, 0, args, 2))
+		return;
+
+	paste_args(args, 1);
+	to = args[0];
+	line = args[1];
 	if (!to || !line)
 		return;
 	save_message_from();
diff -Nru ircii-20190117/source/numbers.c ircii-20210314/source/numbers.c
--- ircii-20190117/source/numbers.c	2019-01-18 11:29:41.000000000 +0100
+++ ircii-20210314/source/numbers.c	2021-03-14 19:32:27.000000000 +0100
@@ -6,7 +6,7 @@
  *
  * Copyright (c) 1990 Michael Sandrof.
  * Copyright (c) 1991, 1992 Troy Rollo.
- * Copyright (c) 1992-2017 Matthew R. Green.
+ * Copyright (c) 1992-2021 Matthew R. Green.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -34,7 +34,7 @@
  */
 
 #include "irc.h"
-IRCII_RCSID("@(#)$eterna: numbers.c,v 1.102 2017/11/02 00:41:42 mrg Exp $");
+IRCII_RCSID("@(#)$eterna: numbers.c,v 1.106 2021/02/24 10:38:03 mrg Exp $");
 
 #include "input.h"
 #include "edit.h"
@@ -61,8 +61,8 @@
 static	void	channel_topic(u_char *, u_char **);
 static	void	not_valid_channel(u_char *, u_char **);
 static	void	cannot_join_channel(u_char *, u_char **);
-static	void	version(u_char *, u_char **);
-static	void	invite(u_char *, u_char **);
+static	void	version(u_char *, u_char *, u_char **);
+static	void	invite(u_char *, u_char *, u_char **);
 
 static	int	already_doing_reset_nickname = 0;
 static	int	current_numeric_local;	/* this is negative of the
@@ -93,15 +93,14 @@
 display_msg(u_char *from, u_char **ArgList)
 {
 	u_char	*rest;
+	u_char	*name = server_get_itsname(parsing_server());
 
-	rest = paste_args(ArgList, 0);
-	if (from)
-	{
-		u_char	*name = server_get_itsname(parsing_server());
+	if (my_strnicmp(name, from, my_strlen(name)) == 0)
+		from = NULL;
 
-		if (my_strnicmp(name, from, my_strlen(name)) == 0)
-			from = NULL;
-	}
+	rest = paste_args(ArgList, 0);
+	if (rest == NULL)
+		rest = empty_string();
 
 	if (from)
 		put_it("%s %s (from %s)", numeric_banner(), rest, from);
@@ -222,8 +221,9 @@
 	u_char	*channel;
 	u_char	*s;
 
-	if (!(channel = ArgList[0]) || !ArgList[1])
+	if (ArgList[1] == NULL)
 		return;
+	channel = ArgList[0];
 	paste_args(ArgList, 1);
 	s = server_get_name(parsing_server());
 	if (0 == my_strnicmp(s, from, my_strlen(s)))
@@ -238,11 +238,7 @@
 {
 	u_char	*chan, *extra;
 
-	if (ArgList[0])
-		chan = ArgList[0];
-	else
-		return;
-
+	chan = ArgList[0];
 	if (!is_on_channel(chan, parsing_server(),
 			server_get_nickname(parsing_server())))
 		remove_channel(chan, parsing_server());
@@ -250,7 +246,7 @@
 		return;
 
 	paste_args(ArgList, 0);
-	if (do_hook(current_numeric(), "%s %s", from, *ArgList)) {
+	if (do_hook(current_numeric(), "%s %s", from, ArgList[0])) {
 		switch(-current_numeric())
 		{
 		case 471:		/* #define ERR_CHANNELISFULL    471 */
@@ -277,8 +273,11 @@
 
 
 static	void
-version(u_char *from, u_char **ArgList)
+version(u_char *comm, u_char *from, u_char **ArgList)
 {
+	if (check_params(comm, from, 0, ArgList, 2))
+		return;
+
 	if (ArgList[2])
 	{
 		paste_args(ArgList, 2);
@@ -295,12 +294,17 @@
 
 
 static	void
-invite(u_char *from, u_char **ArgList)
+invite(u_char *comm, u_char *from, u_char **ArgList)
 {
 	u_char	*who,
 		*channel;
 
-	if ((who = ArgList[0]) && (channel = ArgList[1]))
+	if (check_params(comm, from, 0, ArgList, 2))
+		return;
+
+	who = ArgList[0];
+	channel = ArgList[1];
+	if (channel)
 	{
 		save_message_from();
 		message_from(channel, LOG_CRAP);
@@ -318,7 +322,7 @@
  * all, but the default case should handle any I missed (sorry) 
  */
 void
-numbered_command(u_char *from, int comm, u_char **ArgList)
+numbered_command(u_char *commstr, u_char *from, int comm, u_char **ArgList)
 {
 	u_char	*user;
 	u_char	none_of_these = 0;
@@ -332,7 +336,7 @@
 		server_cnt;
 #endif /* 0 */
 
-	if (!from || !*from)
+	if (!from || !*from || !*ArgList)
 		return;
 	if (!*ArgList[0])
 		user = NULL;
@@ -340,10 +344,18 @@
 		user = ArgList[0];
 	if (!ArgList[1])
 		return;
+	ArgList++;
+	if (check_params(commstr, from, 0, ArgList, 1))
+		return;
+
+	/*
+	 * At this point, unlike in irc2_parse_server(), ArgList[0] is now
+	 * always valid, making all of commstr, from, and ArgList[0] valid.
+	 */
+
 	lastlog_level = set_lastlog_msg_level(LOG_CRAP);
 	save_message_from();
 	message_from(NULL, LOG_CRAP);
-	ArgList++;
 	current_numeric_local = -comm;	/* must be negative of numeric! */
 	switch (comm)
 	{
@@ -354,7 +366,7 @@
 			yell("=== Setting this servers nickname to \"%s\" from \"%s\"", user, server_get_nickname(from_server));
 			server_set_nickname(from_server, user);
 		}
-		if (do_hook(current_numeric(), "%s %s", from, *ArgList)) 
+		if (do_hook(current_numeric(), "%s %s", from, ArgList[0])) 
 			display_msg(from, ArgList);
 		clean_whois_queue();
 		break;
@@ -363,14 +375,14 @@
 		malloc_snprintf(&blah, "*** %s", ArgList[0]);
 		got_initial_version(blah);
 		new_free(&blah);
-		if (do_hook(current_numeric(), "%s %s", from, *ArgList))
+		if (do_hook(current_numeric(), "%s %s", from, ArgList[0]))
 			display_msg(from, ArgList);
 		break;
 
 /* should do something with this some day, 2.8 had channel/user mode switches */
 	case 004:	/* #define RPL_MYINFO           004 */
 		paste_args(ArgList, 0);
-		if (do_hook(current_numeric(), "%s %s", from, *ArgList))
+		if (do_hook(current_numeric(), "%s %s", from, ArgList[0]))
 			display_msg(from, ArgList);
 		break;
 
@@ -383,11 +395,10 @@
 		display_msg(from, ArgList);
 		if (is_server_connected(from_server))
 			break;
-		if (from_server == get_primary_server() && ((sscanf(ArgList[1],
-		    "There are %d users and %d invisible on %d servers",
-		    &user_cnt, &inv_cnt, &server_cnt) == 3)||(sscanf(ArgList[1],
-		    "There are %d users and %d invisible on %d servers",
-		    &user_cnt, &inv_cnt, &server_cnt) == 3)))
+		if (ArgList[1] != NULL && from_server == get_primary_server() &&
+		    ((sscanf(ArgList[1],
+			     "There are %d users and %d invisible on %d servers",
+			     &user_cnt, &inv_cnt, &server_cnt) == 3)))
 		{
 			user_cnt =+ inv_cnt;
 			if ((server_cnt < get_int_var(MINIMUM_SERVERS_VAR)) ||
@@ -400,7 +411,7 @@
 		break;
 #endif /* 0 */
 	case 301:		/* #define RPL_AWAY             301 */
-		user_is_away(from, ArgList);
+		user_is_away(commstr, from, ArgList);
 		break;
 
 	case 302:		/* #define RPL_USERHOST         302 */
@@ -412,7 +423,7 @@
 		break;
 
 	case 311:		/* #define RPL_WHOISUSER        311 */
-		whois_name(from, ArgList);
+		whois_name(commstr, from, ArgList);
 		break;
 
 	case 312:		/* #define RPL_WHOISSERVER      312 */
@@ -424,7 +435,7 @@
 		break;
 
 	case 314:		/* #define RPL_WHOWASUSER       314 */
-		whowas_name(from, ArgList);
+		whowas_name(commstr, from, ArgList);
 		break;
 
 	case 316:		/* #define RPL_WHOISCHANOP      316 */
@@ -432,7 +443,7 @@
 		break;
 
 	case 317:		/* #define RPL_WHOISIDLE        317 */
-		whois_lastcom(from, ArgList);
+		whois_lastcom(commstr, from, ArgList);
 		break;
 
 	case 318:		/* #define RPL_ENDOFWHOIS       318 */
@@ -440,7 +451,7 @@
 		break;
 
 	case 319:		/* #define RPL_WHOISCHANNELS    319 */
-		whois_channels(from, ArgList);
+		whois_channels(commstr, from, ArgList);
 		break;
 
 	case 321:		/* #define RPL_LISTSTART        321 */
@@ -448,11 +459,11 @@
 		ArgList[1] = ArgList[0] + 8;
 		ArgList[2] = ArgList[1] + 6;
 		ArgList[3] = NULL;
-		funny_list(from, ArgList);
+		funny_list(commstr, from, ArgList);
 		break;
 
 	case 322:		/* #define RPL_LIST             322 */
-		funny_list(from, ArgList);
+		funny_list(commstr, from, ArgList);
 		break;
 
 	case 324:		/* #define RPL_CHANNELMODEIS    324 */
@@ -460,7 +471,7 @@
 		break;
 
 	case 341:		/* #define RPL_INVITING         341 */
-		invite(from, ArgList);
+		invite(commstr, from, ArgList);
 		break;
 
 	case 352:		/* #define RPL_WHOREPLY         352 */
@@ -468,7 +479,7 @@
 		break;
 
 	case 353:		/* #define RPL_NAMREPLY         353 */
-		funny_namreply(from, ArgList);
+		funny_namreply(commstr, from, ArgList);
 		break;
 
 	case 366:		/* #define RPL_ENDOFNAMES       366 */
@@ -492,14 +503,14 @@
 
 	case 381: 		/* #define RPL_YOUREOPER        381 */
 		paste_args(ArgList, 0);
-		if (do_hook(current_numeric(), "%s %s", from, *ArgList))
+		if (do_hook(current_numeric(), "%s %s", from, ArgList[0]))
 			display_msg(from, ArgList);
 		server_set_operator(parsing_server(), 1);
 		update_all_status();	/* fix the status line */
 		break;
 
 	case 401:		/* #define ERR_NOSUCHNICK       401 */
-		no_such_nickname(from, ArgList);
+		no_such_nickname(commstr, from, ArgList);
 		break;
 
 	case 405:		/* #define ERR_TOOMANYCHANNELS  405 */
@@ -512,9 +523,9 @@
 		if (check_wait_command(ArgList[0]))
 			break;
 		paste_args(ArgList, 0);
-		flag = do_hook(current_numeric(), "%s %s", from, *ArgList);
-		if (!my_strncmp("ISON", *ArgList, 4) || !my_strncmp("USERHOST",
-		    *ArgList, 8))
+		flag = do_hook(current_numeric(), "%s %s", from, ArgList[0]);
+		if (!my_strncmp("ISON", ArgList[0], 4) || !my_strncmp("USERHOST",
+		    ArgList[0], 8))
 		{
 			server_set_2_6_2(parsing_server(), 0);
 			convert_to_whois();
@@ -526,16 +537,16 @@
 	case 432:		/* #define ERR_ERRONEUSNICKNAME 432 */
 	case 433:		/* #define ERR_NICKNAMEINUSE    433 */ 
 		paste_args(ArgList, 0);
-		if (do_hook(current_numeric(), "%s %s", from, *ArgList))
+		if (do_hook(current_numeric(), "%s %s", from, ArgList[0]))
 			display_msg(from, ArgList);
 		reset_nickname(from);
 		break;
 
 	case 437:		/* #define ERR_UNAVAILRESOURCE  437 */
 		paste_args(ArgList, 0);
-		if (do_hook(current_numeric(), "%s %s", from, *ArgList))
+		if (do_hook(current_numeric(), "%s %s", from, ArgList[0]))
 			display_msg(from, ArgList);
-		if (!is_channel(*ArgList))
+		if (!is_channel(ArgList[0]))
 			reset_nickname(from);
 		break;
 
@@ -584,7 +595,7 @@
 		break;
 
 	case 484:		/* #define ERR_RESTRICTED       484 */
-		if (do_hook(current_numeric(), "%s %s", from, *ArgList))
+		if (do_hook(current_numeric(), "%s %s", from, ArgList[0]))
 			display_msg(from, ArgList);
 		server_set_flag(parsing_server(), USER_MODE_R, 1);
 		break;
@@ -602,13 +613,13 @@
 				do_message_from = 0;
 			size_t	len;
 
-			for (i = len = 0; ArgList[i]; len += my_strlen(ArgList[i++]))
-				;
+			for (i = len = 0; ArgList[i];)
+				len += 1 + my_strlen(ArgList[i++]);
 			len += (i - 1);
 			ArgSpace = new_malloc(len + 1);
 			ArgSpace[0] = '\0';
 			/* this is cheating */
-			if (ArgList[0] && is_channel(ArgList[0]))
+			if (is_channel(ArgList[0]))
 				do_message_from = 1;
 			for (i = 0; ArgList[i]; i++)
 			{
@@ -617,7 +628,10 @@
 				my_strcat(ArgSpace, ArgList[i]);
 			}
 			if (do_message_from)
+			{
+				save_message_from();
 				message_from(ArgList[0], LOG_CRAP);
+			}
 			i = do_hook(current_numeric(), "%s %s", from, ArgSpace);
 			new_free(&ArgSpace);
 			if (do_message_from)
@@ -644,9 +658,9 @@
 				from = NULL;
 			if (from)
 				put_it("%s %s from (%s)", numeric_banner(),
-					*ArgList, from);
+					ArgList[0], from);
 			else
-				put_it("%s %s", numeric_banner(), *ArgList);
+				put_it("%s %s", numeric_banner(), ArgList[0]);
 			break;
 
 		case 332:		/* #define RPL_TOPIC            332 */
@@ -654,10 +668,12 @@
 			break;
 
 		case 351:		/* #define RPL_VERSION          351 */
-			version(from, ArgList);
+			version(commstr, from, ArgList);
 			break;
 
 		case 364:		/* #define RPL_LINKS            364 */
+			if (check_params(commstr, from, 0, ArgList, 2))
+				return;
 			if (ArgList[2])
 			{
 				paste_args(ArgList, 2);
diff -Nru ircii-20190117/source/parse.c ircii-20210314/source/parse.c
--- ircii-20190117/source/parse.c	2019-01-18 11:29:41.000000000 +0100
+++ ircii-20210314/source/parse.c	2021-03-14 19:32:27.000000000 +0100
@@ -6,7 +6,7 @@
  *
  * Copyright (c) 1990 Michael Sandrof.
  * Copyright (c) 1991, 1992 Troy Rollo.
- * Copyright (c) 1992-2016 Matthew R. Green.
+ * Copyright (c) 1992-2021 Matthew R. Green.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -34,7 +34,7 @@
  */
 
 #include "irc.h"
-IRCII_RCSID("@(#)$eterna: parse.c,v 1.119 2017/11/02 00:41:42 mrg Exp $");
+IRCII_RCSID("@(#)$eterna: parse.c,v 1.123 2021/02/27 08:00:42 mrg Exp $");
 
 #include "server.h"
 #include "names.h"
@@ -66,23 +66,23 @@
 
 #define	MAXPARA	15	/* Taken from the ircd */
 
-static	void	BreakArgs(u_char *, u_char **, u_char **);
-static	void	p_linreply(u_char **);
-static	void	p_ping(u_char **);
-static	void	p_topic(u_char *, u_char **);
-static	void	p_wall(u_char *, u_char **);
+static	void	break_args(u_char *, u_char **, u_char **);
+static	void	p_linreply(u_char *, u_char *, u_char **);
+static	void	p_ping(u_char *, u_char *, u_char **);
+static	void	p_topic(u_char *, u_char *, u_char **);
+static	void	p_wall(u_char *, u_char *, u_char **);
 static	void	p_wallops(u_char *, u_char **);
-static	void	p_privmsg(u_char *, u_char **);
+static	void	p_privmsg(u_char *, u_char *, u_char **);
 static	void	p_quit(u_char *, u_char **);
-static	void	p_pong(u_char *, u_char **);
+static	void	p_pong(u_char *, u_char *, u_char **);
 static	void	p_error(u_char *, u_char **);
-static	void	p_channel(u_char *, u_char **);
+static	void	p_channel(u_char *, u_char *, u_char **);
 static	void	p_invite(u_char *, u_char **);
 static	void	p_server_kill(u_char *, u_char **);
-static	void	p_nick(u_char *, u_char **);
-static	void	p_mode(u_char *, u_char **);
-static	void	p_kick(u_char *, u_char **);
-static	void	p_part(u_char *, u_char **);
+static	void	p_nick(u_char *, u_char *, u_char **);
+static	void	p_mode(u_char *, u_char *, u_char **);
+static	void	p_kick(u_char *, u_char *, u_char **);
+static	void	p_part(u_char *, u_char *, u_char **);
 
 /* User and host information from server 2.7 */
 static	u_char	*FromUserHost = NULL;
@@ -125,6 +125,12 @@
 }
 
 
+/*
+ * paste_args: re-connect a string broken up with break_args(), with a
+ * starting point.  paste_args(ArgList, 2) will end up with 3 strings
+ * in ArgList[0], ArgList[1] the same as post-break_args(), and with
+ * all the remaining arguments in ArgList[2].
+ */
 u_char	*
 paste_args(u_char **Args, int StartPoint)
 {
@@ -140,12 +146,17 @@
 }
 
 /*
- * BreakArgs: breaks up the line from the server, in to where its from,
+ * break_args: breaks up the line from the server, in to where its from,
  * setting FromUserHost if it should be, and returns all the arguements
  * that are there.   Re-written by phone, dec 1992.
+ *
+ * using this function will leave you will a NULL terminated list, and
+ * any attempt to use any argument must ensure that all the previous
+ * entries are not NULL.  eg, do not check or use for ArgList[1] without
+ * first making sure ArgList[0] is not NULL.
  */
 static	void
-BreakArgs(u_char *Input, u_char **Sender, u_char **OutPut)
+break_args(u_char *Input, u_char **Sender, u_char **OutPut)
 {
 	u_char	*s = Input,
 		*t;
@@ -173,32 +184,33 @@
 	else
 		*Sender = empty_string();
 
-	if (!s)
-		return;
-
-	for (;;)
+	if (s)
 	{
-		while (*s == ' ')
-			*s++ = '\0';
+		for (;;)
+		{
+			while (*s == ' ')
+				*s++ = '\0';
 
-		if (!*s)
-			break;
+			if (!*s)
+				break;
 
-		if (*s == ':')
-		{
-			for (t = s; *t; t++)
-				*t = *(t + 1);
+			if (*s == ':')
+			{
+				for (t = s; *t; t++)
+					*t = *(t + 1);
+				OutPut[ArgCount++] = s;
+				break;
+			}
 			OutPut[ArgCount++] = s;
-			break;
-		}
-		OutPut[ArgCount++] = s;
-		if (ArgCount >= MAXPARA)
-			break;
+			if (ArgCount >= MAXPARA)
+				break;
 
-		for (; *s != ' ' && *s; s++)
-			;
+			for (; *s != ' ' && *s; s++)
+				;
+		}
 	}
-	OutPut[ArgCount] = NULL;
+	while (ArgCount <= MAXPARA)
+		OutPut[ArgCount++] = NULL;
 }
 
 /* beep_em: Not hard to figure this one out */
@@ -214,12 +226,13 @@
 
 /* in response to a TOPIC message from the server */
 static	void
-p_topic(u_char *from, u_char **ArgList)
+p_topic(u_char *comm, u_char *from, u_char **ArgList)
 {
 	int	flag;
 
-	if (!from)
+	if (check_params(comm, from, 1, ArgList, 1))
 		return;
+
 	flag = double_ignore(from, from_user_host(), IGNORE_CRAP);
 	if (flag == IGNORED)
 		return;
@@ -242,25 +255,28 @@
 }
 
 static	void
-p_linreply(u_char **ArgList)
+p_linreply(u_char *comm, u_char *from, u_char **ArgList)
 {
+	if (check_params(comm, from, 0, ArgList, 1))
+		return;
+
 	paste_args(ArgList, 0);
 	say("%s", ArgList[0]);
 }
 
 static	void
-p_wall(u_char *from, u_char **ArgList)
+p_wall(u_char *comm, u_char *from, u_char **ArgList)
 {
 	int	flag,
 		level;
 	u_char	*line;
 	u_char	*high;
 
-	if (!from)
+	if (check_params(comm, from, 0, ArgList, 1))
 		return;
+
 	paste_args(ArgList, 0);
-	if (!(line = ArgList[0]))
-		return;
+	line = ArgList[0];
 	flag = double_ignore(from, from_user_host(), IGNORE_WALLS);
 	save_message_from();
 	message_from(from, LOG_WALL);
@@ -379,9 +395,7 @@
 	if (ArgList[i])
 		name = ArgList[i];
 
-	ok = whoreply_check(channel, user, host, server, nick, status, name,
-			    ArgList, format);
-
+	ok = whoreply_check(channel, user, host, server, nick, status, name, format);
 	if (ok)
 	{
 		if (do_hook(WHO_LIST, "%s %s %s %s %s %s", channel, nick,
@@ -407,7 +421,7 @@
 }
 
 static	void
-p_privmsg(u_char *from, u_char **Args)
+p_privmsg(u_char *comm, u_char *from, u_char **ArgList)
 {
 	int	level,
 		flag,
@@ -420,13 +434,12 @@
 	u_char	*high;
 	int	no_flood;
 
-	if (!from)
-		return;
-	paste_args(Args, 1);
-	to = Args[0];
-	ptr = Args[1];
-	if (!to || !ptr)
+	if (check_params(comm, from, 0, ArgList, 2))
 		return;
+
+	paste_args(ArgList, 1);
+	to = ArgList[0];
+	ptr = ArgList[1];
 	save_message_from();
 	if (is_channel(to))
 	{
@@ -562,8 +575,6 @@
 	u_char	*Reason;
 	int	flag;
 
-	if (!from)
-		return;
 	flag = double_ignore(from, from_user_host(), IGNORE_CRAP);
 	save_message_from();
 	if (flag != IGNORED)
@@ -590,12 +601,13 @@
 }
 
 static	void
-p_pong(u_char *from, u_char **ArgList)
+p_pong(u_char *comm, u_char *from, u_char **ArgList)
 {
 	int	flag;
 
-	if (!from)
+	if (check_params(comm, from, 0, ArgList, 1))
 		return;
+
 	flag = double_ignore(from, from_user_host(), IGNORE_CRAP);
 	if (flag == IGNORED)
 		return;
@@ -607,14 +619,14 @@
 static	void
 p_error(u_char *from, u_char **ArgList)
 {
-	paste_args(ArgList, 0);
-	if (!ArgList[0])
+	if (ArgList[0] == NULL)
 		return;
+	paste_args(ArgList, 0);
 	say("%s", ArgList[0]);
 }
 
 static	void
-p_channel(u_char *from, u_char **ArgList)
+p_channel(u_char *comm, u_char *from, u_char **ArgList)
 {
 	int	join;
 	u_char	*channel;
@@ -622,8 +634,9 @@
 	u_char	*s, *ov = NULL;
 	int	chan_oper = 0, chan_voice = 0;
 
-	if (!from)
+	if (check_params(comm, from, 0, ArgList, 1))
 		return;
+
 	flag = double_ignore(from, from_user_host(), IGNORE_CRAP);
 	if (my_strcmp(ArgList[0], zero()))
 	{
@@ -755,7 +768,8 @@
 		say("You have been rejected by server %s", from);
 	else
 		say("You have been killed by operator %s %s", from,
-			ArgList[1] ? ArgList[1] : (u_char *) "(No Reason Given)");
+			ArgList[0] && ArgList[1] ?
+			ArgList[1] : (u_char *) "(No Reason Given)");
 	close_server(parsing_server(), empty_string());
 	window_check_servers();
 	if (!connected_to_server())
@@ -763,14 +777,16 @@
 }
 
 static	void
-p_ping(u_char **ArgList)
+p_ping(u_char *comm, u_char *from, u_char **ArgList)
 {
-	paste_args(ArgList, 0);
-	send_to_server("PONG :%s", ArgList[0]);
+	if (check_params(comm, from, 0, ArgList, 1))
+		return;
+
+	send_to_server("PONG :%s", paste_args(ArgList, 0));
 }
 
 static	void
-p_nick(u_char *from, u_char **ArgList)
+p_nick(u_char *comm, u_char *from, u_char **ArgList)
 {
 	int	one_prints = 0,
 		its_me = 0;
@@ -778,8 +794,9 @@
 	u_char	*line;
 	int	flag;
 
-	if (!from)
+	if (check_params(comm, from, 0, ArgList, 1))
 		return;
+
 	flag = double_ignore(from, from_user_host(), IGNORE_CRAP);
 	line = ArgList[0];
 	if (my_stricmp(from, server_get_nickname(parsing_server())) == 0){
@@ -819,112 +836,110 @@
 }
 
 static	void
-p_mode(u_char *from, u_char **ArgList)
+p_mode(u_char *comm, u_char *from, u_char **ArgList)
 {
 	u_char	*channel;
 	u_char	*line;
 	int	flag;
 
-	if (!from)
+	if (check_params(comm, from, 0, ArgList, 2))
 		return;
-	flag = double_ignore(from, from_user_host(), IGNORE_CRAP);
+
 	paste_args(ArgList, 1);
 	channel = ArgList[0];
 	line = ArgList[1];
+
+	flag = double_ignore(from, from_user_host(), IGNORE_CRAP);
 	save_message_from();
 	message_from(channel, LOG_CRAP);
-	if (channel && line)
+	if (is_channel(channel))
 	{
-		if (is_channel(channel))
-		{
-			if (flag != IGNORED && do_hook(MODE_LIST, "%s %s %s",
-					from, channel, line))
-				say("Mode change \"%s\" on channel %s by %s",
-						line, channel, from);
-			update_channel_mode(channel, parsing_server(), line);
-		}
-		else
-		{
-			if (flag != IGNORED && do_hook(MODE_LIST, "%s %s %s",
-					from, channel, line))
-				say("Mode change \"%s\" for user %s by %s",
-						line, channel, from);
-			update_user_mode(line);
-		}
-		update_all_status();
+		if (flag != IGNORED && do_hook(MODE_LIST, "%s %s %s",
+				from, channel, line))
+			say("Mode change \"%s\" on channel %s by %s",
+					line, channel, from);
+		update_channel_mode(channel, parsing_server(), line);
+	}
+	else
+	{
+		if (flag != IGNORED && do_hook(MODE_LIST, "%s %s %s",
+				from, channel, line))
+			say("Mode change \"%s\" for user %s by %s",
+					line, channel, from);
+		update_user_mode(line);
 	}
+	update_all_status();
 	restore_message_from();
 }
 
 static	void
-p_kick(u_char *from, u_char **ArgList)
+p_kick(u_char *comm, u_char *from, u_char **ArgList)
 {
 	u_char	*channel,
 		*who,
 		*comment;
 
-	if (!from)
+	if (check_params(comm, from, 0, ArgList, 2))
 		return;
+
 	channel = ArgList[0];
 	who = ArgList[1];
 	comment = ArgList[2];
 
-	if (channel && who)
+	save_message_from();
+	message_from(channel, LOG_CRAP);
+	if (my_stricmp(who, server_get_nickname(parsing_server())) == 0)
 	{
-		save_message_from();
-		message_from(channel, LOG_CRAP);
-		if (my_stricmp(who, server_get_nickname(parsing_server())) == 0)
+		if (comment && *comment)
 		{
-			if (comment && *comment)
-			{
-				if (do_hook(KICK_LIST, "%s %s %s %s", who,
-						from, channel, comment))
-					say("You have been kicked off channel %s by %s (%s)",
-						channel, from, comment);
-			}
-			else
-			{
-				if (do_hook(KICK_LIST, "%s %s %s", who, from,
-						channel))
-					say("You have been kicked off channel %s by %s",
-						channel, from);
-			}
-			remove_channel(channel, parsing_server());
-			update_all_status();
+			if (do_hook(KICK_LIST, "%s %s %s %s", who,
+					from, channel, comment))
+				say("You have been kicked off channel %s by %s (%s)",
+					channel, from, comment);
 		}
 		else
 		{
-			if (comment && *comment)
-			{
-				if (do_hook(KICK_LIST, "%s %s %s %s", who,
-						from, channel, comment))
-					say("%s has been kicked off channel %s by %s (%s)",
-						who, channel, from, comment);
-			}
-			else
-			{
-				if (do_hook(KICK_LIST, "%s %s %s", who, from,
-						channel))
-					say("%s has been kicked off channel %s by %s",
-						who, channel, from);
-			}
-			remove_from_channel(channel, who, parsing_server());
+			if (do_hook(KICK_LIST, "%s %s %s", who, from,
+					channel))
+				say("You have been kicked off channel %s by %s",
+					channel, from);
 		}
-		restore_message_from();
+		remove_channel(channel, parsing_server());
+		update_all_status();
+	}
+	else
+	{
+		if (comment && *comment)
+		{
+			if (do_hook(KICK_LIST, "%s %s %s %s", who,
+					from, channel, comment))
+				say("%s has been kicked off channel %s by %s (%s)",
+					who, channel, from, comment);
+		}
+		else
+		{
+			if (do_hook(KICK_LIST, "%s %s %s", who, from,
+					channel))
+				say("%s has been kicked off channel %s by %s",
+					who, channel, from);
+		}
+		remove_from_channel(channel, who, parsing_server());
 	}
+	restore_message_from();
 }
 
 static	void
-p_part(u_char *from, u_char **ArgList)
+p_part(u_char *comm, u_char *from, u_char **ArgList)
 {
 	u_char	*channel;
 	u_char	*comment;
 	int	flag;
 
-	if (!from)
+	if (check_params(comm, from, 0, ArgList, 1))
 		return;
-	flag = double_ignore(from, from_user_host(), IGNORE_CRAP);
+
 	channel = ArgList[0];
+	flag = double_ignore(from, from_user_host(), IGNORE_CRAP);
 	if (!is_on_channel(channel, parsing_server(), from))
 		return;
 	comment = ArgList[1];
@@ -951,6 +966,61 @@
 	set_in_on_who(0);
 }
 
+/*
+ * irc2_odd_server_stuff(): call this if you parse an IRC message and
+ * it doesn't make sense and perhaps should be warned about.
+ */
+void
+irc2_odd_server_stuff(u_char *comm, u_char *from, u_char **ArgList)
+{
+	u_char *args;
+
+	paste_args(ArgList, 0);
+	args = ArgList[0];
+	if (!args)
+		args = empty_string();
+
+	if (from)
+		say("Odd server stuff: \"%s %s\" (%s)", comm, args, from);
+	else
+		say("Odd server stuff: \"%s %s\"", comm, args);
+}
+
+/*
+ * front end to irc2_odd_server_stuff() with argument checking.
+ * 'comm', 'from', and 'args' are passed to irc2_odd_server_stuff()
+ * if check_from is set and from is NULL, or, if any array index
+ * smaller than arg_count is NULL (ie, array must have arg_count
+ * or more entries.)
+ */
+int
+check_params(u_char *comm, u_char *from, int check_from,
+	     u_char **args, unsigned arg_count)
+{
+	int fail = 0;
+
+	if (check_from && from == NULL)
+		fail = 1;
+	else
+	{
+		int i;
+
+		for (i = 0; i < arg_count; i++)
+			if (args[i] == NULL)
+			{
+				fail = 1;
+				break;
+			}
+	}
+
+	if (fail)
+	{
+		irc2_odd_server_stuff(comm, from, args);
+		return 1;
+	}
+
+	return 0;
+}
 
 void
 irc2_parse_server(u_char *line)
@@ -966,11 +1036,19 @@
 	if (NULL == line)
 		return;
 
-	end = my_strlen(line) + line;
-	if (*--end == '\n')
-		*end-- = '\0';
+	end = my_strlen(line) + line - 1;
+	if (*end == '\n') {
+		*end = '\0';
+		if (end > line)
+			end--;
+	}
 	if (*end == '\r')
-		*end-- = '\0';
+		*end = '\0';
+
+	if (end < line)
+	{
+		yell("--- HEY BAD BOO");
+	}
 
 	if (*line == ':')
 	{
@@ -982,68 +1060,68 @@
 
 	malloc_strcpy(&copy, line);
 	ArgList = TrueArgs;
-	BreakArgs(copy, &from, ArgList);
+	break_args(copy, &from, ArgList);
 
 	if (!(comm = (*ArgList++)))
 		goto out;		/* Empty line from server - ByeBye */
 
 	/*
+	 * At this point, from and comm are both valid pointers, but the
+	 * ArgList may start with a NULL.  Not all the functions called
+	 * from here require that the ArgList[0] be a valid string, so each
+	 * must check any consumed ArgList[] component is valid.
+	 */
+
+	/*
 	 * only allow numbers 1 .. 999.
 	 */
 	if ((numeric = my_atoi(comm)) > 0 && numeric < 1000)
-		numbered_command(from, numeric, ArgList);
+		numbered_command(comm, from, numeric, ArgList);
 	else if (my_strcmp(comm, "NAMREPLY") == 0)
-		funny_namreply(from, ArgList);
+		funny_namreply(comm, from, ArgList);
 	else if (my_strcmp(comm, "WHOREPLY") == 0)
 		whoreply(from, ArgList);
 	else if (my_strcmp(comm, "NOTICE") == 0)
-		parse_notice(from, ArgList);
+		parse_notice(comm, from, ArgList);
 	/* everything else is handled locally */
 	else if (my_strcmp(comm, "PRIVMSG") == 0)
-		p_privmsg(from, ArgList);
+		p_privmsg(comm, from, ArgList);
 	else if (my_strcmp(comm, "JOIN") == 0)
-		p_channel(from, ArgList);
+		p_channel(comm, from, ArgList);
 	else if (my_strcmp(comm, "PART") == 0)
-		p_part(from, ArgList);
+		p_part(comm, from, ArgList);
 	else if (my_strcmp(comm, "CHANNEL") == 0)
-		p_channel(from, ArgList);
+		p_channel(comm, from, ArgList);
 	else if (my_strcmp(comm, "QUIT") == 0)
 		p_quit(from, ArgList);
 	else if (my_strcmp(comm, "WALL") == 0)
-		p_wall(from, ArgList);
+		p_wall(comm, from, ArgList);
 	else if (my_strcmp(comm, "WALLOPS") == 0)
 		p_wallops(from, ArgList);
 	else if (my_strcmp(comm, "LINREPLY") == 0)
-		p_linreply(ArgList);
+		p_linreply(comm, from, ArgList);
 	else if (my_strcmp(comm, "PING") == 0)
-		p_ping(ArgList);
+		p_ping(comm, from, ArgList);
 	else if (my_strcmp(comm, "TOPIC") == 0)
-		p_topic(from, ArgList);
+		p_topic(comm, from, ArgList);
 	else if (my_strcmp(comm, "PONG") == 0)
-		p_pong(from, ArgList);
+		p_pong(comm, from, ArgList);
 	else if (my_strcmp(comm, "INVITE") == 0)
 		p_invite(from, ArgList);
 	else if (my_strcmp(comm, "NICK") == 0)
-		p_nick(from, ArgList);
+		p_nick(comm, from, ArgList);
 	else if (my_strcmp(comm, "KILL") == 0)
 		p_server_kill(from, ArgList);
 	else if (my_strcmp(comm, "MODE") == 0)
-		p_mode(from, ArgList);
+		p_mode(comm, from, ArgList);
 	else if (my_strcmp(comm, "KICK") == 0)
-		p_kick(from, ArgList);
+		p_kick(comm, from, ArgList);
 	else if (my_strcmp(comm, "ERROR") == 0)
 		p_error(from, ArgList);
 	else if (my_strcmp(comm, "ERROR:") == 0) /* Server bug makes this a must */
 		p_error(from, ArgList);
 	else
-	{
-		paste_args(ArgList, 0);
-		if (from)
-			say("Odd server stuff: \"%s %s\" (%s)", comm,
-				ArgList[0], from);
-		else
-			say("Odd server stuff: \"%s %s\"", comm, ArgList[0]);
-	}
+		irc2_odd_server_stuff(comm, from, ArgList);
 out:
 	new_free(&copy);
 }
diff -Nru ircii-20190117/source/queue.c ircii-20210314/source/queue.c
--- ircii-20190117/source/queue.c	2019-01-18 11:29:41.000000000 +0100
+++ ircii-20210314/source/queue.c	2021-03-14 19:32:27.000000000 +0100
@@ -8,7 +8,7 @@
  * Written by Jeremy Nelson
  *
  * Copyright (c) 1993 Jeremy Nelson.
- * Copyright (c) 1993-2016 Matthew R. Green.
+ * Copyright (c) 1993-2021 Matthew R. Green.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -36,7 +36,7 @@
  */
 
 #include "irc.h"
-IRCII_RCSID("@(#)$eterna: queue.c,v 1.31 2016/12/04 21:40:49 gkm Exp $");
+IRCII_RCSID("@(#)$eterna: queue.c,v 1.34 2021/02/27 08:02:14 mrg Exp $");
 
 #include "alias.h"
 #include "ircaux.h"
@@ -155,7 +155,7 @@
 	}
 	if (remove_by_number == 1)
 	{
-		if (delete_commands_from_queue(tmp->next,number))
+		if (delete_commands_from_queue(tmp->next, number))
 			tmp->next = remove_a_queue(tmp->next);
 	}
 	if (list == 1)
@@ -275,28 +275,48 @@
 }
 
 
-/* remove the Xth command from the queue */
+/*
+ * remove the Xth command from the queue.  if 'which' is zero, then
+ * the whole queue is cleared.
+ */
 static	int
 delete_commands_from_queue(Queue *queue, int which)
 {
 	CmdList *ctmp = queue->first;
-	CmdList *blah;
+	CmdList *next;
 	int x;
 
+	if (which == 0)
+	{
+		for (; ctmp; ctmp = next)
+		{
+			new_free(&ctmp->what);
+			next = ctmp->next;
+			new_free(&ctmp);
+		}
+		queue->first = NULL;
+		return 0;
+	}
 	if (which == 1)
 		queue->first = ctmp->next;
 	else
 	{
-		for (x=1;x<which-1;x++)
+		for (x = 1; x < which - 1; x++)
 		{
 			if (ctmp->next) 
 				ctmp = ctmp->next;
 			else 
 				return 0;
 		}
-		blah = ctmp->next;
+		if (ctmp->next == NULL)
+		{
+			say ("Could not find entry %d in %s queue", which,
+			     queue->name);
+			return 0;
+		}
+		next = ctmp->next;
 		ctmp->next = ctmp->next->next;
-		ctmp = blah;
+		ctmp = next;
 	}
 	new_free(&ctmp->what);
 	new_free(&ctmp);
diff -Nru ircii-20190117/source/server.c ircii-20210314/source/server.c
--- ircii-20190117/source/server.c	2019-01-18 11:29:41.000000000 +0100
+++ ircii-20210314/source/server.c	2021-03-14 19:32:27.000000000 +0100
@@ -33,7 +33,7 @@
  */
 
 #include "irc.h"
-IRCII_RCSID("@(#)$eterna: server.c,v 1.244 2018/06/04 19:54:57 mrg Exp $");
+IRCII_RCSID("@(#)$eterna: server.c,v 1.249 2021/03/14 18:22:31 mrg Exp $");
 
 #ifdef HAVE_SYS_UN_H
 # include <sys/un.h>
@@ -121,7 +121,7 @@
 }	Server;
 
 /* default SSL for IRC connections */
-server_ssl_level irc_ssl_level = SSL_OFF;	
+static	server_ssl_level irc_ssl_level = SSL_OFF;	
 
 /* SGroup: a structure for server groups. */
 typedef struct ser_group_list SGroup;
@@ -152,7 +152,7 @@
 /* server_group_list:  list of server groups */
 static	SGroup	*server_group_list = NULL;
 
-	int	primary_server = -1;
+static	int	primary_server = -1;
 
 /*
  * from_server: server we're currently interested in; set for window
@@ -1107,12 +1107,13 @@
 		if (server_index >= 0 &&
 		    server_list[server_index].res &&
 		    server_list[server_index].res0)
+		{
 			new_des = connect_by_number(connect_port, connect_name,
 					1, &server_list[server_index].res,
 					&server_list[server_index].res0);
+		}
 		else
 		{
-
 			new_des = connect_by_number(connect_port, connect_name,
 					1, &r, &r0);
 		}
@@ -1200,6 +1201,8 @@
 		server_list[from_server].res = r;
 		server_list[from_server].res0 = r0;
 	}
+	else if (r0)
+		freeaddrinfo(r0);
 
 	server_list[from_server].operator = 0;
 	return (0);
@@ -1424,8 +1427,6 @@
 	return 0;
 }
 
-static void login_to_server_nonblocking(int);
-
 static void
 login_to_server_nonblocking(int server)
 {
@@ -1796,17 +1797,19 @@
 {
 	FILE *fp;
 	u_char format[11];
-	u_char *file_path = NULL;
+	u_char *file_path;
+	u_char *free_path = NULL;
 	u_char	buffer[FS_BUFFER_SIZE];
 
 	if ((file_path = my_getenv("IRCSERVERSFILE")) == NULL)
 	{
-		malloc_strcpy(&file_path, my_irc_lib());
-		malloc_strcat(&file_path, UP(SERVERS_FILE));
+		malloc_strcpy(&free_path, my_irc_lib());
+		malloc_strcat(&free_path, UP(SERVERS_FILE));
+		file_path = free_path;
 	}
 	snprintf(CP(format), sizeof format, "%%%ds", (int)sizeof buffer);
 	fp = fopen(CP(file_path), "r");
-	new_free(&file_path);
+	new_free(&free_path);
 	if (NULL != fp)
 	{
 		while (fscanf(fp, CP(format), buffer) != EOF)
@@ -1852,9 +1855,23 @@
 			u_char	*icb_msg;
 			u_char	*group_msg = NULL;
 			u_char	*pname = NULL;
+			const u_char	*ssl_val;
 			int	pport = 0;
 
-			icb_msg = server_list[i].version == ServerICB ? (u_char *) " (ICB connection)" : empty_string();
+			switch (server_list[i].ssl_level) {
+			case SSL_ON:
+				ssl_val = UP(" (with unchecked TLS)");
+				break;
+			case SSL_VERIFY:
+				ssl_val = UP(" (with TLS)");
+				break;
+			default:
+				ssl_val = empty_string();
+				break;
+			}
+
+			icb_msg = server_list[i].version == ServerICB ?
+				    (u_char *) " (ICB connection)" : empty_string();
 			if (server_list[i].server_group)
 				malloc_snprintf(&group_msg, " [group: %s]",
 				    find_server_group_name(server_list[i].server_group));
@@ -1873,24 +1890,28 @@
 
 			if (!server_list[i].nickname)
 			{
-				say("\t%d) %s %d%s%s%s%s", i,
+				say("\t%d) %s %d%s%s%s%s%s", i,
 					server_list[i].name,
 					server_list[i].port,
-					server_list[i].read == -1 ? UP(" (not connected)") : empty_string(),
+					server_list[i].read == -1 ?
+					    UP(" (not connected)") : empty_string(),
 					group_msg,
 					icb_msg,
-					proxy_msg);
+					proxy_msg,
+					ssl_val);
 			}
 			else
 			{
-				say("\t%d) %s %d (%s%s)%s%s%s", i,
+				say("\t%d) %s %d (%s%s)%s%s%s%s", i,
 					server_list[i].name,
 					server_list[i].port,
-					(server_list[i].read == -1) ? UP("was ") : empty_string(),
+					(server_list[i].read == -1) ?
+					    UP("was ") : empty_string(),
 					server_list[i].nickname,
 					group_msg,
 					icb_msg,
-					proxy_msg);
+					proxy_msg,
+					ssl_val);
 			}
 			new_free(&proxy_msg);
 			new_free(&group_msg);
@@ -2665,7 +2686,10 @@
 	sock = socket(AF_UNIX, SOCK_STREAM, 0);
 
 	un.sun_family = AF_UNIX;
-	snprintf(un.sun_path, sizeof un.sun_path, "%-.100s/%-.6d", path, port);
+	if (snprintf(un.sun_path, sizeof un.sun_path, "%-.100s/%-.6d", path, port) != sizeof un.sun_path)
+	{
+		yell("--- sun_path truncated: wanted '%-.100s/%-.6d'", path, port);
+	}
 
 	if (connect(sock, (struct sockaddr *)&un, (int)my_strlen(path)+2) == -1)
 	{
diff -Nru ircii-20190117/source/signals.c ircii-20210314/source/signals.c
--- ircii-20190117/source/signals.c	2019-01-18 11:29:41.000000000 +0100
+++ ircii-20210314/source/signals.c	2021-03-14 19:32:27.000000000 +0100
@@ -1,7 +1,7 @@
-/* This file is generated from: eterna: mksignals.pl,v 1.2 2019/01/15 11:18:48 mrg Exp  */
+/* This file is generated from: eterna: mksignals.pl,v 1.3 2019/01/16 06:26:12 mrg Exp  */
 
 /*
- * Copyright (c) 2003-2019 Matthew R. Green
+ * Copyright (c) 2003-2020 Matthew R. Green
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -29,9 +29,10 @@
  */
 
 #include "irc.h"
-IRCII_RCSID("@(#)$eterna: signals.c,v 1.3 2019/01/16 06:27:37 mrg Exp $");
+IRCII_RCSID("@(#)$eterna: signals.c,v 1.4 2020/11/17 08:11:57 mrg Exp $");
 
 #include "irc_std.h"
+#include "ircaux.h"
 #include "signals.h"
 
 /*
@@ -39,7 +40,7 @@
  * second and later instances from the file.
  */
 
-const u_char * signals[] = {
+static const u_char * signals[] = {
 
 #if defined(SIGABRT)
 		[SIGABRT] = UP("ABRT"),
@@ -263,4 +264,21 @@
 
 };
 
-const int max_signo = ARRAY_SIZE(signals);
+static const int max_signo = ARRAY_SIZE(signals);
+
+const u_char *
+get_signal(int signo, int nullok)
+{
+	if (signo >= 0 && signo <= max_signo) {
+		if (signals[signo] == NULL) {
+			u_char *newsig = NULL;
+
+			malloc_snprintf(&newsig, "SIG%d", signo);
+			signals[signo] = newsig;
+		}
+		return signals[signo];
+	}
+	if (nullok)
+		return NULL;
+	return UP("(NOSIG)");
+}
diff -Nru ircii-20190117/source/snprintf.c ircii-20210314/source/snprintf.c
--- ircii-20190117/source/snprintf.c	2019-01-18 11:29:41.000000000 +0100
+++ ircii-20210314/source/snprintf.c	1970-01-01 01:00:00.000000000 +0100
@@ -1,798 +0,0 @@
-/*
- * Copyright Patrick Powell 1995
- * This code is based on code written by Patrick Powell (papowell@astart.com)
- * It may be used for any purpose as long as this notice remains intact
- * on all source code distributions
- */
-
-/**************************************************************
- * Original:
- * Patrick Powell Tue Apr 11 09:48:21 PDT 1995
- * A bombproof version of doprnt (dopr) included.
- * Sigh.  This sort of thing is always nasty do deal with.  Note that
- * the version here does not include floating point...
- *
- * snprintf() is used instead of sprintf() as it does limit checks
- * for string length.  This covers a nasty loophole.
- *
- * The other functions are there to prevent NULL pointers from
- * causing nast effects.
- *
- * More Recently:
- *  Brandon Long <blong@fiction.net> 9/15/96 for mutt 0.43
- *  This was ugly.  It is still ugly.  I opted out of floating point
- *  numbers, but the formatter understands just about everything
- *  from the normal C string format, at least as far as I can tell from
- *  the Solaris 2.5 printf(3S) man page.
- *
- *  Brandon Long <blong@fiction.net> 10/22/97 for mutt 0.87.1
- *    Ok, added some minimal floating point support, which means this
- *    probably requires libm on most operating systems.  Don't yet
- *    support the exponent (e,E) and sigfig (g,G).  Also, fmtint()
- *    was pretty badly broken, it just wasn't being exercised in ways
- *    which showed it, so that's been fixed.  Also, formated the code
- *    to mutt conventions, and removed dead code left over from the
- *    original.  Also, there is now a builtin-test, just compile with:
- *           gcc -DTEST_SNPRINTF -o snprintf snprintf.c -lm
- *    and run snprintf for results.
- *
- *  Thomas Roessler <roessler@guug.de> 01/27/98 for mutt 0.89i
- *    The PGP code was using unsigned hexadecimal formats.
- *    Unfortunately, unsigned formats simply didn't work.
- *
- *  Michael Elkins <me@cs.hmc.edu> 03/05/98 for mutt 0.90.8
- *    The original code assumed that both snprintf() and vsnprintf() were
- *    missing.  Some systems only have snprintf() but not vsnprintf(), so
- *    the code is now broken down under HAVE_SNPRINTF and HAVE_VSNPRINTF.
- *
- *  Andrew Tridgell (tridge@samba.org) Oct 1998
- *    fixed handling of %.0f
- *    added test for HAVE_LONG_DOUBLE
- *
- *  Luke Mewburn <lukem@netbsd.org>, Thu Sep 30 23:28:21 EST 1999
- *	cleaned up formatting, autoconf tests
- *	added long long support
- *
- **************************************************************/
-
-#include "irc.h"
-IRCII_RCSID("@(#)$eterna: snprintf.c,v 1.6 2016/12/04 21:40:49 gkm Exp $");
-
-#if !defined(HAVE_SNPRINTF) || ! defined(HAVE_VSNPRINTF)
-
-#if HAVE_LONG_DOUBLE
-#define LDOUBLE long double
-#else
-#define LDOUBLE double
-#endif
-
-#if HAVE_LONG_LONG
-#define LLONG long long
-#else
-#define LLONG long
-#endif
-
-static void dopr(char *buffer, size_t maxlen, size_t *retlen,
-		    const char *format, va_list args);
-static void fmtstr(char *buffer, size_t * currlen, size_t maxlen,
-		    char *value, int min, int max, int flags);
-static void fmtint(char *buffer, size_t * currlen, size_t maxlen,
-		    LLONG value, int base, int min, int max, int flags);
-static void fmtfp(char *buffer, size_t * currlen, size_t maxlen,
-		    LDOUBLE fvalue, int min, int max, int flags);
-static void dopr_outch(char *buffer, size_t * currlen, size_t maxlen, int c);
-
-/*
- * dopr(): poor man's version of doprintf
- */
-
-/* format read states */
-#define DP_S_DEFAULT	0
-#define DP_S_FLAGS	1
-#define DP_S_MIN	2
-#define DP_S_DOT	3
-#define DP_S_MAX	4
-#define DP_S_MOD	5
-#define DP_S_CONV	6
-#define DP_S_DONE	7
-
-/* format flags - Bits */
-#define DP_F_MINUS	(1 << 0)
-#define DP_F_PLUS	(1 << 1)
-#define DP_F_SPACE	(1 << 2)
-#define DP_F_NUM	(1 << 3)
-#define DP_F_ZERO	(1 << 4)
-#define DP_F_UP		(1 << 5)
-#define DP_F_UNSIGNED	(1 << 6)
-
-/* Conversion Flags */
-#define DP_C_SHORT	1
-#define DP_C_LONG	2
-#define DP_C_LDOUBLE	3
-#define DP_C_LLONG	4
-
-#define char_to_int(p) (p - '0')
-
-static void
-dopr(char *buffer, size_t maxlen, size_t *retlen, const char *format,
-	va_list args)
-{
-	char	 ch;
-	LLONG	 value;
-	LDOUBLE	 fvalue;
-	char	*strvalue;
-	int	 min;
-	int	 max;
-	int	 state;
-	int	 flags;
-	int	 cflags;
-	size_t	 currlen;
-
-	state = DP_S_DEFAULT;
-	flags = currlen = cflags = min = 0;
-	max = -1;
-	ch = *format++;
-
-	while (state != DP_S_DONE) {
-		if ((ch == '\0') || (currlen >= maxlen))
-			state = DP_S_DONE;
-
-		switch (state) {
-		case DP_S_DEFAULT:
-			if (ch == '%')
-				state = DP_S_FLAGS;
-			else
-				dopr_outch(buffer, &currlen, maxlen, ch);
-			ch = *format++;
-			break;
-		case DP_S_FLAGS:
-			switch (ch) {
-			case '-':
-				flags |= DP_F_MINUS;
-				ch = *format++;
-				break;
-			case '+':
-				flags |= DP_F_PLUS;
-				ch = *format++;
-				break;
-			case ' ':
-				flags |= DP_F_SPACE;
-				ch = *format++;
-				break;
-			case '#':
-				flags |= DP_F_NUM;
-				ch = *format++;
-				break;
-			case '0':
-				flags |= DP_F_ZERO;
-				ch = *format++;
-				break;
-			default:
-				state = DP_S_MIN;
-				break;
-			}
-			break;
-		case DP_S_MIN:
-			if (isdigit((unsigned char) ch)) {
-				min = 10 * min + char_to_int(ch);
-				ch = *format++;
-			} else if (ch == '*') {
-				min = va_arg(args, int);
-				ch = *format++;
-				state = DP_S_DOT;
-			} else
-				state = DP_S_DOT;
-			break;
-		case DP_S_DOT:
-			if (ch == '.') {
-				state = DP_S_MAX;
-				ch = *format++;
-			} else
-				state = DP_S_MOD;
-			break;
-		case DP_S_MAX:
-			if (isdigit((unsigned char) ch)) {
-				if (max < 0)
-					max = 0;
-				max = 10 * max + char_to_int(ch);
-				ch = *format++;
-			} else if (ch == '*') {
-				max = va_arg(args, int);
-				ch = *format++;
-				state = DP_S_MOD;
-			} else
-				state = DP_S_MOD;
-			break;
-		case DP_S_MOD:
-			switch (ch) {
-			case 'h':
-				cflags = DP_C_SHORT;
-				ch = *format++;
-				break;
-			case 'l':
-				if (*format == 'l') {
-					cflags = DP_C_LLONG;
-					format++;
-				} else
-					cflags = DP_C_LONG;
-				ch = *format++;
-				break;
-			case 'q':
-				cflags = DP_C_LLONG;
-				ch = *format++;
-				break;
-			case 'L':
-				cflags = DP_C_LDOUBLE;
-				ch = *format++;
-				break;
-			default:
-				break;
-			}
-			state = DP_S_CONV;
-			break;
-		case DP_S_CONV:
-			switch (ch) {
-			case 'd':
-			case 'i':
-				switch (cflags) {
-#if 0
-				case DP_C_SHORT:
-					value = va_arg(args, short int);
-					break;
-#endif
-				case DP_C_LONG:
-					value = va_arg(args, long int);
-					break;
-				case DP_C_LLONG:
-					value = va_arg(args, LLONG);
-					break;
-				default:
-					value = va_arg(args, int);
-					break;
-				}
-				fmtint(buffer, &currlen, maxlen, value, 10,
-				    min, max, flags);
-				break;
-			case 'X':
-				flags |= DP_F_UP;
-				/* FALLTHROUGH */
-			case 'x':
-			case 'o':
-			case 'u':
-				flags |= DP_F_UNSIGNED;
-				switch (cflags) {
-#if 0
-				case DP_C_SHORT:
-					value = va_arg(args,
-					    unsigned short int);
-					break;
-#endif
-				case DP_C_LONG:
-					value = (LLONG) va_arg(args,
-					    unsigned long int);
-					break;
-				case DP_C_LLONG:
-					value = va_arg(args, unsigned LLONG);
-					break;
-				default:
-					value = (LLONG) va_arg(args,
-					    unsigned int);
-					break;
-				}
-				fmtint(buffer, &currlen, maxlen, value,
-				    ch == 'o' ? 8 : (ch == 'u' ? 10 : 16),
-				    min, max, flags);
-				break;
-			case 'f':
-				if (cflags == DP_C_LDOUBLE)
-					fvalue = va_arg(args, LDOUBLE);
-				else
-					fvalue = va_arg(args, double);
-				/* um, floating point? */
-				fmtfp(buffer, &currlen, maxlen, fvalue, min,
-				    max, flags);
-				break;
-			case 'E':
-				flags |= DP_F_UP;
-			case 'e':
-				if (cflags == DP_C_LDOUBLE)
-					fvalue = va_arg(args, LDOUBLE);
-				else
-					fvalue = va_arg(args, double);
-				break;
-			case 'G':
-				flags |= DP_F_UP;
-			case 'g':
-				if (cflags == DP_C_LDOUBLE)
-					fvalue = va_arg(args, LDOUBLE);
-				else
-					fvalue = va_arg(args, double);
-				break;
-			case 'c':
-				dopr_outch(buffer, &currlen, maxlen,
-				    va_arg(args, int));
-				break;
-			case 's':
-				strvalue = va_arg(args, char *);
-				if (max < 0)
-					max = maxlen;	/* ie, no max */
-				fmtstr(buffer, &currlen, maxlen, strvalue,
-				    min, max, flags);
-				break;
-			case 'p':
-				value = (long)va_arg(args, void *);
-				fmtint(buffer, &currlen, maxlen,
-				    value, 16, min, max, flags);
-				break;
-			case 'n':
-/* XXX */
-				if (cflags == DP_C_SHORT) {
-					short int *num;
-					num = va_arg(args, short int *);
-					*num = currlen;
-				} else if (cflags == DP_C_LONG) { /* XXX */
-					long int *num;
-					num = va_arg(args, long int *);
-					*num = (long int) currlen;
-				} else if (cflags == DP_C_LLONG) { /* XXX */
-					LLONG *num;
-					num = va_arg(args, LLONG *);
-					*num = (LLONG) currlen;
-				} else {
-					int    *num;
-					num = va_arg(args, int *);
-					*num = currlen;
-				}
-				break;
-			case '%':
-				dopr_outch(buffer, &currlen, maxlen, ch);
-				break;
-			case 'w':
-				/* not supported yet, treat as next char */
-				ch = *format++;
-				break;
-			default:
-				/* Unknown, skip */
-				break;
-			}
-			ch = *format++;
-			state = DP_S_DEFAULT;
-			flags = cflags = min = 0;
-			max = -1;
-			break;
-		case DP_S_DONE:
-			break;
-		default:
-			/* hmm? */
-			break;	/* some picky compilers need this */
-		}
-	}
-	if (currlen >= maxlen - 1)
-		currlen = maxlen - 1;
-	buffer[currlen] = '\0';
-	*retlen = currlen;
-}
-
-static void
-fmtstr(char *buffer, size_t *currlen, size_t maxlen, char *value,
-	int min, int max, int flags)
-{
-	int	padlen, strln;	/* amount to pad */
-	int	cnt = 0;
-
-	if (value == 0) {
-		value = "<NULL>";
-	}
-	for (strln = 0; value[strln]; ++strln)
-		;	/* strlen */
-	padlen = min - strln;
-	if (padlen < 0)
-		padlen = 0;
-	if (flags & DP_F_MINUS)
-		padlen = -padlen;	/* Left Justify */
-
-	while ((padlen > 0) && (cnt < max)) {
-		dopr_outch(buffer, currlen, maxlen, ' ');
-		--padlen;
-		++cnt;
-	}
-	while (*value && (cnt < max)) {
-		dopr_outch(buffer, currlen, maxlen, *value++);
-		++cnt;
-	}
-	while ((padlen < 0) && (cnt < max)) {
-		dopr_outch(buffer, currlen, maxlen, ' ');
-		++padlen;
-		++cnt;
-	}
-}
-/* Have to handle DP_F_NUM (ie 0x and 0 alternates) */
-
-static void
-fmtint(char *buffer, size_t *currlen, size_t maxlen, LLONG value, int base,
-	int min, int max, int flags)
-{
-	int		signvalue = 0;
-	unsigned LLONG	uvalue;
-	char		convert[20];
-	int		place = 0;
-	int		spadlen = 0;	/* amount to space pad */
-	int		zpadlen = 0;	/* amount to zero pad */
-	int		caps = 0;
-
-	if (max < 0)
-		max = 0;
-
-	uvalue = value;
-
-	if (!(flags & DP_F_UNSIGNED)) {
-		if (value < 0) {
-			signvalue = '-';
-			uvalue = -value;
-		} else if (flags & DP_F_PLUS)	/* Do a sign (+/i) */
-			signvalue = '+';
-		else if (flags & DP_F_SPACE)
-			signvalue = ' ';
-	}
-	if (flags & DP_F_UP)
-		caps = 1;	/* Should characters be upper case? */
-
-	do {
-		convert[place++] =
-		    (caps ? "0123456789ABCDEF" : "0123456789abcdef")
-		    [uvalue % (unsigned) base];
-		uvalue = (uvalue / (unsigned) base);
-	} while (uvalue && (place < 20));
-	if (place == 20)
-		place--;
-	convert[place] = 0;
-
-	zpadlen = max - place;
-	spadlen = min - MAX(max, place) - (signvalue ? 1 : 0);
-	if (zpadlen < 0)
-		zpadlen = 0;
-	if (spadlen < 0)
-		spadlen = 0;
-	if (flags & DP_F_ZERO) {
-		zpadlen = MAX(zpadlen, spadlen);
-		spadlen = 0;
-	}
-	if (flags & DP_F_MINUS)
-		spadlen = -spadlen;	/* Left Justifty */
-
-#ifdef DEBUG_SNPRINTF
-	printf("zpad: %d, spad: %d, min: %d, max: %d, place: %d\n",
-	    zpadlen, spadlen, min, max, place);
-#endif
-
-	/* Spaces */
-	while (spadlen > 0) {
-		dopr_outch(buffer, currlen, maxlen, ' ');
-		--spadlen;
-	}
-
-	/* Sign */
-	if (signvalue)
-		dopr_outch(buffer, currlen, maxlen, signvalue);
-
-	/* Zeros */
-	if (zpadlen > 0) {
-		while (zpadlen > 0) {
-			dopr_outch(buffer, currlen, maxlen, '0');
-			--zpadlen;
-		}
-	}
-	/* Digits */
-	while (place > 0)
-		dopr_outch(buffer, currlen, maxlen, convert[--place]);
-
-	/* Left Justified spaces */
-	while (spadlen < 0) {
-		dopr_outch(buffer, currlen, maxlen, ' ');
-		++spadlen;
-	}
-}
-
-static LDOUBLE
-abs_val(LDOUBLE value)
-{
-	LDOUBLE	result = value;
-
-	if (value < 0)
-		result = -value;
-
-	return result;
-}
-
-static LDOUBLE
-pow10(int exp)
-{
-	LDOUBLE	result = 1;
-
-	while (exp) {
-		result *= 10;
-		exp--;
-	}
-
-	return result;
-}
-
-static long
-round(LDOUBLE value)
-{
-	long	intpart;
-
-	intpart = (long) value;
-	value = value - intpart;
-	if (value >= 0.5)
-		intpart++;
-
-	return intpart;
-}
-
-static void
-fmtfp(char *buffer, size_t *currlen, size_t maxlen, LDOUBLE fvalue,
-	int min, int max, int flags)
-{
-	int	signvalue = 0;
-	LDOUBLE	ufvalue;
-	char	iconvert[20];
-	char	fconvert[20];
-	int	iplace = 0;
-	int	fplace = 0;
-	int	padlen = 0;	/* amount to pad */
-	int	zpadlen = 0;
-	int	caps = 0;
-	long	intpart;
-	long	fracpart;
-
-	/* AIX manpage says the default is 0, but Solaris says the default is
-	 * 6, and sprintf on AIX defaults to 6 */
-	if (max < 0)
-		max = 6;
-
-	ufvalue = abs_val(fvalue);
-
-	if (fvalue < 0)
-		signvalue = '-';
-	else if (flags & DP_F_PLUS)	/* Do a sign (+/i) */
-		signvalue = '+';
-	else if (flags & DP_F_SPACE)
-		signvalue = ' ';
-
-#if 0
-	if (flags & DP_F_UP)
-		caps = 1;	/* Should characters be upper case? */
-#endif
-
-	intpart = (long) ufvalue;
-
-	/* Sorry, we only support 9 digits past the decimal because of our
-	 * conversion method */
-	if (max > 9)
-		max = 9;
-
-	/* We "cheat" by converting the fractional part to integer by
-	 * multiplying by a factor of 10 */
-	fracpart = round((pow10(max)) * (ufvalue - intpart));
-
-	if (fracpart >= pow10(max)) {
-		intpart++;
-		fracpart -= pow10(max);
-	}
-#ifdef DEBUG_SNPRINTF
-	printf("fmtfp: %g %d.%d min=%d max=%d\n",
-	    (double) fvalue, intpart, fracpart, min, max);
-#endif
-
-	/* Convert integer part */
-	do {
-		iconvert[iplace++] =
-		    (caps ? "0123456789ABCDEF"
-			  : "0123456789abcdef")[intpart % 10];
-		intpart = (intpart / 10);
-	} while (intpart && (iplace < 20));
-	if (iplace == 20)
-		iplace--;
-	iconvert[iplace] = 0;
-
-	/* Convert fractional part */
-	do {
-		fconvert[fplace++] =
-		    (caps ? "0123456789ABCDEF"
-			  : "0123456789abcdef")[fracpart % 10];
-		fracpart = (fracpart / 10);
-	} while (fracpart && (fplace < 20));
-	if (fplace == 20)
-		fplace--;
-	fconvert[fplace] = 0;
-
-	/* -1 for decimal point, another -1 if we are printing a sign */
-	padlen = min - iplace - max - 1 - ((signvalue) ? 1 : 0);
-	zpadlen = max - fplace;
-	if (zpadlen < 0)
-		zpadlen = 0;
-	if (padlen < 0)
-		padlen = 0;
-	if (flags & DP_F_MINUS)
-		padlen = -padlen;	/* Left Justifty */
-
-	if ((flags & DP_F_ZERO) && (padlen > 0)) {
-		if (signvalue) {
-			dopr_outch(buffer, currlen, maxlen, signvalue);
-			--padlen;
-			signvalue = 0;
-		}
-		while (padlen > 0) {
-			dopr_outch(buffer, currlen, maxlen, '0');
-			--padlen;
-		}
-	}
-	while (padlen > 0) {
-		dopr_outch(buffer, currlen, maxlen, ' ');
-		--padlen;
-	}
-	if (signvalue)
-		dopr_outch(buffer, currlen, maxlen, signvalue);
-
-	while (iplace > 0)
-		dopr_outch(buffer, currlen, maxlen, iconvert[--iplace]);
-
-
-#ifdef DEBUG_SNPRINTF
-	printf("fmtfp: fplace=%d zpadlen=%d\n", fplace, zpadlen);
-#endif
-
-	/*
-	 * Decimal point.  This should probably use locale to find the correct
-	 * char to print out.
-	 */
-	if (max > 0) {
-		dopr_outch(buffer, currlen, maxlen, '.');
-
-		while (fplace > 0)
-			dopr_outch(buffer, currlen, maxlen, fconvert[--fplace]);
-	}
-	while (zpadlen > 0) {
-		dopr_outch(buffer, currlen, maxlen, '0');
-		--zpadlen;
-	}
-
-	while (padlen < 0) {
-		dopr_outch(buffer, currlen, maxlen, ' ');
-		++padlen;
-	}
-}
-
-static void
-dopr_outch(char *buffer, size_t *currlen, size_t maxlen, int c)
-{
-	if (*currlen < maxlen)
-		buffer[(*currlen)++] = (char)c;
-}
-
-#ifndef HAVE_VSNPRINTF
-int
-vsnprintf(char *str, size_t count, const char *fmt, va_list args)
-{
-	size_t retlen;
-
-	str[0] = 0;
-	dopr(str, count, &retlen, fmt, args);
-	return (retlen);
-}
-#endif /* HAVE_VSNPRINTF */
-
-#ifndef HAVE_SNPRINTF
-int
-snprintf(char *str, size_t count, const char *fmt, ...)
-{
-	va_list	 ap;
-	int	 rv;
-
-	va_start(ap, fmt);
-	rv = vsnprintf(str, count, fmt, ap);
-	va_end(ap);
-	return (rv);
-}
-#endif /* HAVE_SNPRINTF */
-
-#endif /* HAVE_SNPRINTF || HAVE_VSNPRINTF */
-
-
-#ifdef TEST_SNPRINTF
-#ifndef LONG_STRING
-#define LONG_STRING 1024
-#endif
-
-int
-main(int argc, char *argv[])
-{
-	char	 buf1[LONG_STRING];
-	char	 buf2[LONG_STRING];
-	char	*fp_fmt[] = {
-			"%-1.5f",
-			"%1.5f",
-			"%123.9f",
-			"%10.5f",
-			"% 10.5f",
-			"%+22.9f",
-			"%+4.9f",
-			"%01.3f",
-			"%4f",
-			"%3.1f",
-			"%3.2f",
-			"%.0f",
-			"%.1f",
-			NULL
-		 };
-	double	 fp_nums[] = {
-			-1.5, 134.21, 91340.2, 341.1234, 0203.9,
-			0.96, 0.996, 0.9996, 1.996, 4.136,
-			0
-		 };
-	char	*int_fmt[] = {
-			"%-1.5d",
-			"%1.5d",
-			"%123.9d",
-			"%5.5d",
-			"%10.5d",
-			"% 10.5d",
-			"%+22.33d",
-			"%01.3d",
-			"%4d",
-#if HAVE_LONG_LONG
-			"%12lld",
-#endif
-			NULL
-		 };
-	LLONG	 int_nums[] = {
-			-1, 134, 91340, 341, 0203,
-			4294967290,
-			4294967297,
-			0
-		 };
-	int	 x, y;
-	int	 fail = 0;
-	int	 num = 0;
-	int	 len;
-
-	printf("Testing snprintf format codes against system sprintf...\n");
-
-	for (x = 0; fp_fmt[x] != NULL; x++) {
-		printf("testing %s\n", fp_fmt[x]);
-		for (y = 0; fp_nums[y] != 0; y++) {
-			snprintf(buf1, sizeof(buf1), fp_fmt[x], fp_nums[y]);
-			sprintf(buf2, fp_fmt[x], fp_nums[y]);
-			if (strcmp(buf1, buf2)) {
-				printf("snprintf doesn't match Format: %s\n",
-				    fp_fmt[x]);
-				printf("\tsnprintf = %s\n\tsprintf  = %s\n",
-				    buf1, buf2);
-				fail++;
-			}
-			num++;
-		}
-	}
-
-	for (x = 0; int_fmt[x] != NULL; x++) {
-		printf("testing %s\n", int_fmt[x]);
-		for (y = 0; int_nums[y] != 0; y++) {
-			len = snprintf(buf1, sizeof(buf1), int_fmt[x], int_nums[y]);
-printf("got %d >%s< (%d)\n", len, buf1, (int)strlen(buf1));
-			sprintf(buf2, int_fmt[x], int_nums[y]);
-			if (strcmp(buf1, buf2)) {
-				printf("snprintf doesn't match Format: %s\n",
-				    int_fmt[x]);
-				printf("\tsnprintf = %s\n\tsprintf  = %s\n",
-				    buf1, buf2);
-				fail++;
-			}
-			num++;
-		}
-	}
-
-	printf("%d tests failed out of %d.\n", fail, num);
-	exit(0);
-}
-#endif /* TEST_SNPRINTF */
diff -Nru ircii-20190117/source/status.c ircii-20210314/source/status.c
--- ircii-20190117/source/status.c	2019-01-18 11:29:41.000000000 +0100
+++ ircii-20210314/source/status.c	2021-03-14 19:32:27.000000000 +0100
@@ -5,7 +5,7 @@
  *
  * Copyright (c) 1990 Michael Sandrof.
  * Copyright (c) 1991, 1992 Troy Rollo.
- * Copyright (c) 1992-2018 Matthew R. Green.
+ * Copyright (c) 1992-2020 Matthew R. Green.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -38,7 +38,7 @@
  */
 
 #include "irc.h"
-IRCII_RCSID("@(#)$eterna: status.c,v 1.130 2018/06/04 19:54:57 mrg Exp $");
+IRCII_RCSID("@(#)$eterna: status.c,v 1.132 2020/11/17 08:12:34 mrg Exp $");
 
 #include "ircterm.h"
 #include "status.h"
@@ -231,7 +231,11 @@
 	}
 	
 	h = my_atoi(hours);
+	if (h < 0)
+		h = 0;
 	m = my_atoi(minutes);
+	if (m < 0)
+		m = 0;
 	if (h >= min_hours && h <= max_hours && isdigit(hours[0]) &&
 		(isdigit(hours[1]) || hours[1] == '\0'))
 	{
diff -Nru ircii-20190117/source/term.c ircii-20210314/source/term.c
--- ircii-20190117/source/term.c	2019-01-18 11:29:41.000000000 +0100
+++ ircii-20210314/source/term.c	2021-03-14 19:32:27.000000000 +0100
@@ -37,7 +37,7 @@
  */
 
 #include "irc.h"
-IRCII_RCSID("@(#)$eterna: term.c,v 1.117 2015/09/05 07:37:40 mrg Exp $");
+IRCII_RCSID("@(#)$eterna: term.c,v 1.118 2020/11/17 08:11:57 mrg Exp $");
 
 #ifdef HAVE_SYS_IOCTL_H
 # include <sys/ioctl.h>
@@ -130,7 +130,7 @@
  * term_reset_flag: set to true whenever the terminal is reset, thus letting
  * the calling program work out what to do
  */
-int	term_reset_flag = 0;
+static	int	term_reset_flag = 0;
 
 static	FILE	*term_fp = 0;
 static	int	li, co;
diff -Nru ircii-20190117/source/translat.c ircii-20210314/source/translat.c
--- ircii-20190117/source/translat.c	2019-01-18 11:29:41.000000000 +0100
+++ ircii-20210314/source/translat.c	2021-03-14 19:32:27.000000000 +0100
@@ -9,7 +9,7 @@
  */
 
 #include "irc.h"
-IRCII_RCSID("@(#)$eterna: translat.c,v 1.48 2018/06/04 19:25:02 mrg Exp $");
+IRCII_RCSID("@(#)$eterna: translat.c,v 1.49 2020/11/17 08:11:57 mrg Exp $");
 
 #ifdef HAVE_ICONV_H
 #include <iconv.h>
@@ -58,7 +58,7 @@
  * The higher of the pair goes in DiHi, and the digraph itself in DiDi.
  */
 
-u_char	dig_table_lo[DIG_TABLE_SIZE] =
+static	u_char	dig_table_lo[DIG_TABLE_SIZE] =
 {
 #include "digraph.inc"
 	0
@@ -72,7 +72,7 @@
 #define	DiHi(x)	x,
 #define	DiDi(x)
 
-u_char	dig_table_hi[DIG_TABLE_SIZE] =
+static	u_char	dig_table_hi[DIG_TABLE_SIZE] =
 {
 #include "digraph.inc"
 	0
@@ -86,7 +86,7 @@
 #define	DiHi(x)
 #define	DiDi(x)	x,
 
-u_char	dig_table_di[DIG_TABLE_SIZE] =
+static	u_char	dig_table_di[DIG_TABLE_SIZE] =
 {
 #include "digraph.inc"
 	0
diff -Nru ircii-20190117/source/whois.c ircii-20210314/source/whois.c
--- ircii-20190117/source/whois.c	2019-01-18 11:29:41.000000000 +0100
+++ ircii-20210314/source/whois.c	2021-03-14 19:32:27.000000000 +0100
@@ -6,7 +6,7 @@
  *
  * Copyright (c) 1990 Michael Sandrof.
  * Copyright (c) 1991, 1992 Troy Rollo.
- * Copyright (c) 1992-2017 Matthew R. Green.
+ * Copyright (c) 1992-2021 Matthew R. Green.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -36,7 +36,7 @@
 #undef MONITOR_Q /* this one is for monitoring of the 'whois queue' (debug) */
 
 #include "irc.h"
-IRCII_RCSID("@(#)$eterna: whois.c,v 1.86 2018/06/10 00:21:02 mrg Exp $");
+IRCII_RCSID("@(#)$eterna: whois.c,v 1.88 2021/02/24 10:38:03 mrg Exp $");
 
 #include "whois.h"
 #include "hook.h"
@@ -189,13 +189,13 @@
 	if (whois_type_head(parsing_server()) == WHOIS_ISON)
 	{
 		thing = remove_from_whois_queue(parsing_server());
-		thing->func(NULL, thing->nick, ArgList[0]? ArgList[0] : empty_string());
+		thing->func(NULL, thing->nick, ArgList[0]);
 		new_free(&thing->nick);
 		new_free(&thing->text);
 		new_free(&thing);
 	}
 	else
-		ison_now(NULL, ArgList[0] ? ArgList[0] : empty_string(), NULL);
+		ison_now(NULL, ArgList[0], NULL);
 }
 
 /* userhost_returned: this is called when numeric 302 is received in
@@ -240,8 +240,6 @@
 		parsed;
 	u_char	*queue_nicks;
 
-	if (!ArgList[0])
-		return;
 	if (whois_type_head(parsing_server()) == WHOIS_USERHOST)
 	{
 		isuser = (whois_func_head(parsing_server()) == USERHOST_USERHOST);
@@ -354,7 +352,7 @@
  * channel() in edit.c 
  */
 void
-whois_name(u_char *from, u_char **ArgList)
+whois_name(u_char *comm, u_char *from, u_char **ArgList)
 {
 	u_char	*nick,
 		*user,
@@ -364,14 +362,17 @@
 		*name;
 	WhoisStuff *whois_stuff;
 
+	if (check_params(comm, from, 0, ArgList, 5))
+		return;
+
 	paste_args(ArgList, 4);
+
 	nick = ArgList[0];
 	user = ArgList[1];
 	host = ArgList[2];
 	channel = ArgList[3];
 	name = ArgList[4];
-	if (!nick || !user || !host || !channel || !name)
-		return;
+
 	whois_stuff = server_get_whois_stuff(parsing_server());
 	if ((ptr = whois_queue_head(parsing_server())) &&
 	    (whois_type_head(parsing_server()) &
@@ -407,7 +408,7 @@
  * and has set the AUTO_WHOWAS variable.
  */
 void
-whowas_name(u_char *from, u_char **ArgList)
+whowas_name(u_char *comm, u_char *from, u_char **ArgList)
 {
 	u_char	*nick,
 		*user,
@@ -418,14 +419,16 @@
 	WhoisStuff *whois_stuff;
 	int	lastlog_level;
 
+	if (check_params(comm, from, 0, ArgList, 5))
+		return;
+
 	paste_args(ArgList, 4);
+
 	nick = ArgList[0];
 	user = ArgList[1];
 	host = ArgList[2];
 	channel = ArgList[3];
 	name = ArgList[4];
-	if (!nick || !user || !host || !channel || !name)
-		return;
 
 	lastlog_level = set_lastlog_msg_level(LOG_CRAP);
 	whois_stuff = server_get_whois_stuff(parsing_server());
@@ -458,12 +461,18 @@
 }
 
 void
-whois_channels(u_char *from, u_char **ArgList)
+whois_channels(u_char *comm, u_char *from, u_char **ArgList)
 {
 	u_char	*ptr;
 	u_char	*line;
 	WhoisStuff *whois_stuff;
 
+	if (ArgList[1] == NULL)
+	{
+		irc2_odd_server_stuff(comm, from, ArgList);
+		return;
+	}
+
 	paste_args(ArgList, 1);
 	line = ArgList[1];
 	whois_stuff = server_get_whois_stuff(parsing_server());
@@ -503,7 +512,7 @@
 	WhoisStuff *whois_stuff;
 
 	show_away_flag = 1;
-	if (!ArgList[0] || !ArgList[1])
+	if (ArgList[0] == NULL || ArgList[1] == NULL)
 		return;
 	if (ArgList[2])
 	{
@@ -542,39 +551,48 @@
 whois_oper(u_char *from, u_char **ArgList)
 {
 	WhoisStuff *whois_stuff;
+	u_char *arg;
 
 	whois_stuff = server_get_whois_stuff(parsing_server());
 	paste_args(ArgList, 1);
+	arg = ArgList[1] ? ArgList[1] : empty_string();
+
 	if (ignore_whois_crap)
 		whois_stuff->oper = 1;
 	else
 	{
-		u_char	*nick;
+		u_char	*nick = ArgList[0];
 
-		if ((nick = ArgList[0]) != NULL)
-		{
-			if (do_hook(current_numeric(), "%s %s %s", from, nick,
-					ArgList[1]))
-				put_it("%s %s %s%s", numeric_banner(), nick,
-					ArgList[1], (server_get_version(parsing_server()) >
-					Server2_7) ? empty_string()
-						   : (u_char *) " (is an IRC operator)");
-		}
+		if (do_hook(current_numeric(), "%s %s %s", from, nick, arg))
+			put_it("%s %s %s%s", numeric_banner(), nick,
+				arg, (server_get_version(parsing_server()) >
+				Server2_7) ? empty_string()
+					   : (u_char *) " (is an IRC operator)");
 	}
 }
 
 void
-whois_lastcom(u_char *from, u_char **ArgList)
+whois_lastcom(u_char *comm, u_char *from, u_char **ArgList)
 {
 	if (!ignore_whois_crap)
 	{
-		u_char	flag, *nick, *idle_str;
+		u_char	flag, *nick, *idle_str, *rest;
 		int	idle;
 
+		if (ArgList[1] == NULL || ArgList[2] == NULL)
+		{
+			irc2_odd_server_stuff(comm, from, ArgList);
+			return;
+		}
+
 		paste_args(ArgList, 2);
-		if ((nick = ArgList[0]) && (idle_str = ArgList[1]) &&
-				do_hook(current_numeric(), "%s %s %s %s", from,
-					nick, idle_str, ArgList[2]))
+		nick = ArgList[0];
+		idle_str = ArgList[1];
+		rest = ArgList[2];
+
+		if (nick != NULL && idle_str != NULL &&
+		    do_hook(current_numeric(), "%s %s %s %s",
+			    from, nick, idle_str, rest))
 		{
 			if ((idle = my_atoi(idle_str)) > 59)
 			{
@@ -600,22 +618,20 @@
 	WhoisStuff *whois_stuff;
 
 	whois_stuff = server_get_whois_stuff(parsing_server());
-	paste_args(ArgList, 1);
 	if (ignore_whois_crap)
 		whois_stuff->chop = 1;
 	else
 	{
-		u_char	*nick;
+		u_char	*nick = ArgList[0];
+		u_char *arg1;
 
-		if ((nick = ArgList[0]) != NULL)
-		{
-			u_char *arg1 = ArgList[1] ? ArgList[1] : empty_string();
+		paste_args(ArgList, 1);
+		arg1 = ArgList[1] ? ArgList[1] : empty_string();
 
-			if (do_hook(current_numeric(), "%s %s %s", from,
-				    nick, arg1))
-				put_it("%s %s (is a channel operator): %s",
-					numeric_banner(), nick, arg1);
-		}
+		if (do_hook(current_numeric(), "%s %s %s", from,
+			    nick, arg1))
+			put_it("%s %s (is a channel operator): %s",
+				numeric_banner(), nick, arg1);
 	}
 }
 
@@ -630,31 +646,28 @@
 
 	show_away_flag = 0;
 	server_set_whois(parsing_server(), 1);
-	if ((nick = ArgList[0]) != NULL)
+
+	nick = ArgList[0];
+	ptr = whois_queue_head(parsing_server());
+	if (ptr && my_stricmp(ptr, nick) == 0 &&
+	    (whois_type_head(parsing_server()) & (WHOIS_WHOIS|WHOIS_ISON2)))
 	{
-		ptr = whois_queue_head(parsing_server());
-		if (ptr &&
-		    (whois_type_head(parsing_server()) &
-		     (WHOIS_WHOIS|WHOIS_ISON2)) &&
-		    my_stricmp(ptr, nick) == 0)
-		{
-			WhoisQueue *thing;
+		WhoisQueue *thing;
 
-			thing = remove_from_whois_queue(parsing_server());
-			whois_stuff->not_on = 0;
-			thing->func(whois_stuff, thing->nick, thing->text);
-			new_free(&whois_stuff->channels);
-			new_free(&thing->nick);
-			new_free(&thing->text);
-			new_free(&thing);
-			ignore_whois_crap = 0;
-			return;
-		}
-		paste_args(ArgList, 0);
-		if (do_hook(current_numeric(), "%s %s", from, ArgList[0]))
-			if (get_int_var(SHOW_END_OF_MSGS_VAR))
-				display_msg(from, ArgList);
+		thing = remove_from_whois_queue(parsing_server());
+		whois_stuff->not_on = 0;
+		thing->func(whois_stuff, thing->nick, thing->text);
+		new_free(&whois_stuff->channels);
+		new_free(&thing->nick);
+		new_free(&thing->text);
+		new_free(&thing);
+		ignore_whois_crap = 0;
+		return;
 	}
+	paste_args(ArgList, 0);
+	if (do_hook(current_numeric(), "%s %s", from, ArgList[0]))
+		if (get_int_var(SHOW_END_OF_MSGS_VAR))
+			display_msg(from, ArgList);
 }
 
 /*
@@ -669,12 +682,18 @@
  * used to use it, now use no such command.  -phone, april 1993.
  */
 void
-no_such_nickname(u_char *from, u_char **ArgList)
+no_such_nickname(u_char *comm, u_char *from, u_char **ArgList)
 {
 	u_char	*nick;
 	u_char		*ptr;
 	WhoisStuff	*whois_stuff;
 
+	if (ArgList[1] == NULL)
+	{
+		irc2_odd_server_stuff(comm, from, ArgList);
+		return;
+	}
+
 	whois_stuff = server_get_whois_stuff(parsing_server());
 	ptr = whois_queue_head(parsing_server());
 	paste_args(ArgList, 1);
@@ -730,7 +749,7 @@
  * by this routine if the ignore_whois_crap flag is set 
  */
 void
-user_is_away(u_char *from, u_char **ArgList)
+user_is_away(u_char *comm, u_char *from, u_char **ArgList)
 {
 	static	u_char	*last_away_msg = NULL,
 			*last_away_nick = NULL;
@@ -738,36 +757,38 @@
 		*who;
 	WhoisStuff *whois_stuff;
 
-	if (!from)
+	if (ArgList[1] == NULL)
+	{
+		irc2_odd_server_stuff(comm, from, ArgList);
 		return;
+	}
 
 	paste_args(ArgList, 1);
+	who = ArgList[0];
+	message = ArgList[1];
 	whois_stuff = server_get_whois_stuff(parsing_server());
 
-	if ((who = ArgList[0]) && (message = ArgList[1]))
+	if (whois_stuff->nick && (!my_strcmp(who, whois_stuff->nick)) &&
+			eat_away)
+		malloc_strcpy(&whois_stuff->away, message);
+	else
 	{
-		if (whois_stuff->nick && (!my_strcmp(who, whois_stuff->nick)) &&
-				eat_away)
-			malloc_strcpy(&whois_stuff->away, message);
-		else
+		if (!show_away_flag && get_int_var(SHOW_AWAY_ONCE_VAR))
 		{
-			if (!show_away_flag && get_int_var(SHOW_AWAY_ONCE_VAR))
+			if (!last_away_msg ||
+			    my_strcmp(last_away_nick, from) ||
+			    my_strcmp(last_away_msg, message))
 			{
-				if (!last_away_msg ||
-				    my_strcmp(last_away_nick, from) ||
-				    my_strcmp(last_away_msg, message))
-				{
-					malloc_strcpy(&last_away_nick, from);
-					malloc_strcpy(&last_away_msg, message);
-				}
-				else return;
+				malloc_strcpy(&last_away_nick, from);
+				malloc_strcpy(&last_away_msg, message);
 			}
-			if (do_hook(current_numeric(), "%s %s", who, message))
-				put_it("%s %s is away: %s",numeric_banner(),
-					who, message);
+			else return;
 		}
-		eat_away = 0;
+		if (do_hook(current_numeric(), "%s %s", who, message))
+			put_it("%s %s is away: %s",numeric_banner(),
+				who, message);
 	}
+	eat_away = 0;
 }
 
 /*
diff -Nru ircii-20190117/source/window.c ircii-20210314/source/window.c
--- ircii-20190117/source/window.c	2019-01-18 11:29:41.000000000 +0100
+++ ircii-20210314/source/window.c	2021-03-14 19:32:27.000000000 +0100
@@ -6,7 +6,7 @@
  *
  * Copyright (c) 1990 Michael Sandrof.
  * Copyright (c) 1991, 1992 Troy Rollo.
- * Copyright (c) 1992-2019 Matthew R. Green.
+ * Copyright (c) 1992-2021 Matthew R. Green.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -34,7 +34,7 @@
  */
 
 #include "irc.h"
-IRCII_RCSID("@(#)$eterna: window.c,v 1.234 2019/01/16 06:41:50 mrg Exp $");
+IRCII_RCSID("@(#)$eterna: window.c,v 1.237 2021/02/27 08:02:14 mrg Exp $");
 
 #include "screen.h"
 #include "menu.h"
@@ -1066,9 +1066,9 @@
 			if (!(cont_ptr = get_string_var(CONTINUED_LINE_VAR)))
 				cont_ptr = empty_string();
 
-			if (get_int_var(INDENT_VAR) && (indent < get_co() / 3))
+			if (!cont) /* Build it only the first time */
 			{
-				if (!cont) /* Build it only the first time */
+				if (get_int_var(INDENT_VAR) && (indent < get_co() / 3))
 				{
 					/* Visual length */
 					int vlen = my_strlen_c(cont_ptr);
@@ -1090,15 +1090,15 @@
 					}
 					cont[clen] = '\0';
 				}
-			}
-			else
-			{
-				/* Converted length */
-				int clen = my_strlen_ci(cont_ptr);
-				
-				/* No indent, just prefix only */				
-				cont = new_malloc(clen + 1);
-				my_strcpy_ci(cont, clen + 1, cont_ptr);
+				else
+				{
+					/* Converted length */
+					int clen = my_strlen_ci(cont_ptr);
+					
+					/* No indent, just prefix only */				
+					cont = new_malloc(clen + 1);
+					my_strcpy_ci(cont, clen + 1, cont_ptr);
+				}
 			}
 			
 			/* cont contains internal codes, so use my_strlen_i */
@@ -1151,8 +1151,7 @@
 		}
 	}
 
-	if (mystr)
-		new_free(&mystr);
+	new_free(&mystr);
 	new_free(&cont);
 	new_free(&temp);
 	return output;
@@ -1457,7 +1456,7 @@
 /*
  * the message_from stack structure.
  */
-struct mfstack
+static	struct mfstack
 {
 	u_char	*who_from;	/* saved from */
 	int	who_level;	/* saved level */

Reply to: