diff --git a/Config.h b/Config.h
index 0c90c2d..ad81a77 100644
--- a/Config.h
+++ b/Config.h
@@ -57,7 +57,7 @@
 #define MAJOR 1
 #define MINOR 1
 #define SUFFIX "a"
-#define PATCHLEVEL 111
+#define PATCHLEVEL 113
 #define MYVER_S(s) _MYVER_S(s)
 #define _MYVER_S(s) #s
 #define MYVER MYVER_S(MAJOR) "." MYVER_S(MINOR) SUFFIX "-" MYVER_S(PATCHLEVEL)
diff --git a/HISTORY b/HISTORY
index 27819e8..c0a0ebb 100644
--- a/HISTORY
+++ b/HISTORY
@@ -1,3 +1,31 @@
+2022/02/11 21:27:12 git
+nodelist.pl,1.4,1.5
+Fix some warnings in misc/nodelist.pl
+
+2021/11/14 11:17:45 1.1a-113 git
+protocol.c,2.238,2.239
+Fix format in log and M_ERR messages
+
+2021/07/08 10:01:11 git
+Makefile.in,2.25,2.26 binkd.spec,1.214,1.215
+fix binkd.spec and add a doc package with config and FAQ
+
+2021/01/19 11:07:20 1.1a-112 git
+breaksig.c,2.26,2.27
+Graceful exit when idle for Windows builds, for Nick Andre.
+Set the binkd_exit flag to TRUE when signaled to exit and return TRUE
+(indicating that the signal was handled by the process) thus mimicking the
+behavior of the *nix builds' handling of termination signals.
+
+2021/01/19 11:07:11 git
+Makefile,2.55,2.56
+Define HAS_SNPRINTF for modern MSVC build compatibility (e.g. MSVC2019)
+Fix build error using "nmake MSVC_VER=10" and MSVC2019:
+
+Linking binkd.exe...
+snprintf.obj : error LNK2005: _snprintf already defined in readcfg.obj
+bin\msvc10-binkd\binkd.exe : fatal error LNK1169: one or more multiply defined symbols found
+
 2020/05/26 20:48:08 1.1a-111 git
 binkd.c,2.127,2.128
 Print "Facilities" without space at the end of line. Make sense for further "binkd.exe -vv>file_id.diz" processing. (#21)
diff --git a/misc/nodelist.pl b/misc/nodelist.pl
index a98fcac..091e005 100644
--- a/misc/nodelist.pl
+++ b/misc/nodelist.pl
@@ -40,7 +40,7 @@ sub find_nodelist
 	my (@listdir);
 
 	if (!defined($glob)) {
-		$diehandler = $SIG{"__DIE__"};
+		my $diehandler = $SIG{"__DIE__"};
 		$SIG{"__DIE__"} = sub {};
 		eval "use File::Glob;";
 		$SIG{"__DIE__"} = $diehandler;
@@ -91,7 +91,6 @@ sub config_loaded
 {
 	my ($nlist) = find_nodelist();
 	my ($magichost) = magichost();
-	my ($subst);
 
 	if ($nlist ne $curnodelist || !%nodelist) {
 		compile_nodelist($curnodelist = $nlist);
@@ -105,7 +104,7 @@ sub config_loaded
 
 sub on_call
 {
-	my ($subst);
+	my $subst;
 	$hosts = $subst if defined($subst = subst($addr, $hosts));
 	return 1;
 }
@@ -138,7 +137,7 @@ sub subst
 sub compile_nodelist
 {
 	my ($nlist) = @_;
-	my ($zone, $net, $node, $dom, $ird, $domain, $start);
+	my ($zone, $region, $net, $node, $dom, $ird, $domain, $start);
 	my ($line, $keyword, $name, $phone, $flags, $port, $lport, $nodes);
 	my (%flags, $uflag, %addr, @addr, $domzone, $domreg, $domnet);
 
@@ -161,11 +160,13 @@ sub compile_nodelist
 		$line =~ s/\r?\n$//s;
 		next unless $line =~ /^([a-z]*),(\d+),([^,]*),[^,]*,[^,]*,([^,]*),\d+(?:,(.*))?\s*$/i;
 		($keyword, $node, $name, $phone, $flags) = ($1, $2, $3, $4, $5);
+		next if $keyword eq "Down";
+		next if $keyword eq "Hold";
 		$uflag = "";
 		%flags = ();
 		%addr = ();
 		@addr = ();
-		foreach (split(/,/, $flags)) {
+		foreach (split(/,/, $flags // "")) {
 			if (/^U/) {
 				$uflag = "U";
 				next if /^U$/;
@@ -180,13 +181,11 @@ sub compile_nodelist
 				$flags{$_} .= "";
 			}
 		}
-		next if $keyword eq "Down";
-		next if $keyword eq "Hold";
 		if ($keyword eq "Zone") {
 			$zone = $region = $net = $node;
 			$node = 0;
 			$domzone = $domreg = $domnet = "";
-			foreach $i (qw(M 1 2 3 4)) {
+			foreach my $i (qw(M 1 2 3 4)) {
 				$domzone = $domreg = $domnet = "DO$i:" . $flags{"UDO$i"} if $flags{"UDO$i"};
 			}
 			$ird = $flags{"IRD"};
@@ -194,7 +193,7 @@ sub compile_nodelist
 			$region = $net = $node;
 			$node = 0;
 			$domreg = $domnet = "";
-			foreach $i (qw(M 1 2 3 4)) {
+			foreach my $i (qw(M 1 2 3 4)) {
 				$domreg = $domnet = "DO$i:" . $flags{"UDO$i"} if $flags{"UDO$i"};
 			}
 			$ird = $flags{"IRD"};
@@ -202,22 +201,22 @@ sub compile_nodelist
 			$net = $node;
 			$node = 0;
 			$domnet = "";
-			foreach $i (qw(M 1 2 3 4)) {
+			foreach my $i (qw(M 1 2 3 4)) {
 				$domnet = "DO$i:" . $flags{"UDO$i"} if $flags{"UDO$i"};
 			}
 			$ird = $flags{"IRD"};
 		}
 		next unless defined($flags{"IBN"});
-		%port = ();
+		my %port = ();
 		foreach (split(/,/, $flags{"IBN"})) {
 			if (/^\d*$/) {
 				$port{/\d/ ? ":$_" : ""} = 1;
 				next;
 			}
-			$lport = "";
+			my $lport = "";
 			($_, $lport) = ($`, ":$'") if /:/;
 			$_ .= "." unless /^\d+\.\d+\.\d+\.\d+$|\.$/;
-			%lport = ($lport ? ( ":$lport" => 1 ) : %port);
+			my %lport = ($lport ? ( ":$lport" => 1 ) : %port);
 			$lport{""} = 1 unless %lport;
 			foreach $lport (keys %lport) {
 				next if $addr{"$_$lport"};
@@ -235,7 +234,7 @@ sub compile_nodelist
 		if ($_ = $flags{"INA"}) {
 			foreach (split(/,/, $flags{"INA"})) {
 				$_ .= "." unless /^\d+\.\d+\.\d+\.\d+$|\.$/;
-				foreach $port (keys %port) {
+				foreach my $port (keys %port) {
 					next if $addr{"$_$port"};
 					$addr{"$_$port"} = 1;
 					push(@addr, "$_$port");
@@ -260,12 +259,12 @@ sub compile_nodelist
 			}
 		}
 		unless (@addr) {
-			$domflag = ($domnet || $domreg || $domzone);
-			foreach $i (qw(M 1 2 3 4)) {
+			my $domflag = ($domnet || $domreg || $domzone);
+			foreach my $i (qw(M 1 2 3 4)) {
 				$domflag = "DO$i:" . $flags{"UDO$i"} if $flags{"UDO$i"};
 			}
 			if ($domflag =~ /^DO(.):/) {
-				($i, $dom) = ($1, $');
+				my ($i, $dom) = ($1, $');
 				if ($i eq 'M') {
 					$_ = "f$node.n$net.z$zone.$domain.$dom.";
 				} elsif ($i eq '4') {
@@ -294,8 +293,8 @@ sub compile_nodelist
 		}
 		next unless @addr;
 		%addr = ();
-		foreach $addr (@addr) {
-			foreach $port (keys %port) {
+		foreach my $addr (@addr) {
+			foreach my $port (keys %port) {
 				$addr{"$addr$port"} = 1;
 			}
 		}
diff --git a/mkfls/nt95-msvc/Makefile b/mkfls/nt95-msvc/Makefile
index 37a8cc6..62d5258 100644
--- a/mkfls/nt95-msvc/Makefile
+++ b/mkfls/nt95-msvc/Makefile
@@ -3,9 +3,10 @@
 #
 # Usage: nmake [DEBUG=1] [STATIC=1] [BINKD9X=1] [PERL=1] [PERLDL=1]
 #              [ZLIB=1] [BZLIB2=1] [ZLIBDL=1] [DEBUGCHILD=1] [BW_LIM=1]
-#              [MSVC_VER=10] [IPV6=1] [FTS5004=1] [X64=1] [AF_FORCE=1]
+#              [MSVC_VER=10|19] [IPV6=1] [FTS5004=1] [X64=1] [AF_FORCE=1]
 #
 # Use MSVC_VER=10 to build with Visual Studio 2008 or 2010
+# Use MSVC_VER=19 to build with Visual Studio 2015 or 2019
 #
 
 #PERLV=510
@@ -44,18 +45,24 @@ CDEFS=   $(CDEFS) -DWIN64
 MACHINETYPE=I386
 !endif
 
-!if "$(MSVC_VER)" == "10"
-CFLAGS=  $(CFLAGS) -nologo -M$(RTLTYPE) -W3 -EHsc -c -J \
-         -Fp"$(OBJDIR)\$(BINKDNAME).pch" -Fd"$(OBJDIR)\$(BINKDNAME)"
-CDEFS=   $(CDEFS) -DWIN32 -DHAVE_THREADS -DHAVE_IO_H -DHAVE_DOS_H \
-         -DHAVE_STDARG_H -DVISUALCPP -DHTTPS -DAMIGADOS_4D_OUTBOUND -DNTLM \
-         -DHAVE_VSNPRINTF -D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_DEPRECATE
-OUTDIR=$(OUTDIR)10
-!else
-CFLAGS=  $(CFLAGS) -nologo -M$(RTLTYPE) -W3 -GX -c -YX -J \
+CFLAGS=  $(CFLAGS) -nologo -M$(RTLTYPE) -W3 -c -J \
          -Fp"$(OBJDIR)\$(BINKDNAME).pch" -Fd"$(OBJDIR)\$(BINKDNAME)"
+
 CDEFS=   $(CDEFS) -DWIN32 -DHAVE_THREADS -DHAVE_IO_H -DHAVE_DOS_H \
          -DHAVE_STDARG_H -DVISUALCPP -DHTTPS -DAMIGADOS_4D_OUTBOUND -DNTLM
+
+!if "$(MSVC_VER)" == "10"
+CFLAGS=  $(CFLAGS) -EHsc
+CDEFS=   $(CDEFS) -D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_DEPRECATE \
+         -DHAVE_VSNPRINTF
+OUTDIR=  $(OUTDIR)10
+!elseif "$(MSVC_VER)" == "19"
+CFLAGS=  $(CFLAGS) -EHsc
+CDEFS=   $(CDEFS) -D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_DEPRECATE \
+         -DHAVE_VSNPRINTF -DHAVE_SNPRINTF
+OUTDIR=  $(OUTDIR)19
+!else
+CFLAGS=  $(CFLAGS) -GX -YX
 !endif
 
 LFLAGS=  /nologo /machine:$(MACHINETYPE) /subsystem:$(SUBSYSTEM) \
diff --git a/mkfls/unix/Makefile.in b/mkfls/unix/Makefile.in
index af1b450..a37338b 100644
--- a/mkfls/unix/Makefile.in
+++ b/mkfls/unix/Makefile.in
@@ -8,8 +8,9 @@ INSTALL=@INSTALL@
 # prepend prefix to installed program names
 prefix=@prefix@
 CONFDIR=@sysconfdir@
-MANDIR=@mandir@
-DATADIR=@datarootdir@
+DATADIR=@prefix@/share
+MANDIR=$(DATADIR)/man
+DOCDIR=$(DATADIR)/doc/$(APPL)
 
 SRCS=md5b.c binkd.c readcfg.c tools.c ftnaddr.c ftnq.c client.c server.c protocol.c bsy.c inbound.c breaksig.c branch.c unix/rename.c unix/getfree.c ftndom.c ftnnode.c srif.c pmatch.c readflo.c prothlp.c iptools.c rfc2553.c run.c binlog.c exitproc.c getw.c xalloc.c crypt.c unix/setpttl.c unix/daemonize.c @OPT_SRC@
 OBJS=${SRCS:.c=.o}
@@ -59,6 +60,8 @@ install: compile .version
 	$(INSTALL) -m 644 $(APPL).8 $(DESTDIR)$(MANDIR)/man8/$(APPL).8
 	./mkinstalldirs $(DESTDIR)$(CONFDIR)
 	$(INSTALL) -m 644 $(APPL).conf $(DESTDIR)$(CONFDIR)/$(APPL).conf-dist
+	./mkinstalldirs $(DESTDIR)$(DOCDIR)
+	$(INSTALL) -m 644 binkdfaq-??.txt $(DESTDIR)$(DOCDIR)
 
 clean:
 	rm -f *.[bo] unix/*.[bo] ntlm/*.[bo] *.BAK *.core *.obj *.err
diff --git a/mkfls/unix/binkd.spec b/mkfls/unix/binkd.spec
index 449e705..ce74f45 100644
--- a/mkfls/unix/binkd.spec
+++ b/mkfls/unix/binkd.spec
@@ -1,42 +1,68 @@
-Summary: Binkd - the binkp daemon
+%global binkd_relnum 3
+
+# for generic build; it will be overriden for some distributions
+%global vendor_prefix %nil
+%global vendor_suffix %nil
+
+# for CentOS, Fedora and RHEL
+%if "%_vendor" == "redhat"
+    %global vendor_suffix %dist
+%endif
+
+# for ALT Linux
+%if "%_vendor" == "alt"
+    %global vendor_prefix %_vendor
+%endif
+
+Summary: Binkd - a binkp daemon
 Name: binkd
-Version: 1.1a.111
-Release: 1
+Version: 1.1a.113
+Release: %{vendor_prefix}%binkd_relnum%{vendor_suffix}
 License: GPL
-Source: %{name}.tar.gz
+Source: %name.tar.gz
 URL: ftp://happy.kiev.ua/pub/fidosoft/mailer/binkd/
 Provides: binkd
-Requires: perl >= 5.8.3, zlib >= 1.2.3, bzip2 >= 1.0.3
-BuildRoot: %{_tmppath}/%{name}-%{version}-root
-Group: Applications/Internet
+BuildRequires: perl-devel >= 5.8.3
+%if "%_vendor" == "redhat"
+BuildRequires: perl(ExtUtils::Embed)
+%endif
+BuildRequires: zlib-devel >= 1.2.3
+BuildRequires: bzip2-devel >= 1.0.3
+%if "%_vendor" == "alt"
+Group: Networking/FTN
+%endif
 
 %description
-Binkd is the daemon for FTN communications over reliable links.
+Binkd is a daemon for FTN communications over reliable links.
+
+%package doc
+BuildArch: noarch
+Summary: Sample config and FAQ for %name
+
+%description doc
+%summary
 
 %prep
-%setup -q -n %{name}
+%setup -q -n %name
 cp -p mkfls/unix/{Makefile*,configure*,install-sh,mkinstalldirs} .
 
 %build
 %configure \
-        --prefix=%{_prefix} \
-        --sysconfdir=%{_sysconfdir} \
-        --localstatedir=%{_localstatedir} \
+        --prefix=%_prefix \
+        --sysconfdir=%_datarootdir/doc/%name \
         --with-proxy --with-ntlm --with-bwlim \
         --with-perl --with-zlib --with-bzip2
-make
+%make_build
 
 %install
-rm -rf %{buildroot}
-make DESTDIR=%{buildroot} install
-rm -rf %{buildroot}%{_sysconfdir}
-
-%clean
-rm -rf %{buildroot}
+%make_install
 
 %files
 %defattr(-,root,root)
-%{_sbindir}/*
-%{_mandir}/man8/*
-
+%_sbindir/*
+%_mandir/man8/*
 
+%files doc
+%defattr(-,root,root)
+%doc %_docdir/%name/%name.conf-dist
+%doc %_docdir/%name/*.txt
diff --git a/nt/breaksig.c b/nt/breaksig.c
index 2e851f8..1b547e9 100644
--- a/nt/breaksig.c
+++ b/nt/breaksig.c
@@ -71,7 +71,8 @@ SigHandler (DWORD SigType)
       break;
     case CTRL_CLOSE_EVENT:
       Log (1, "Interrupted by Close");
-      break;
+      binkd_exit = TRUE;
+      return TRUE;
     case CTRL_LOGOFF_EVENT:
 #ifndef BINKD9X
       if (isService ())
diff --git a/protocol.c b/protocol.c
index 6bdf2e2..677cb44 100644
--- a/protocol.c
+++ b/protocol.c
@@ -2262,9 +2262,9 @@ static int GET (STATE *state, char *args, int sz, BINKD_CONFIG *config)
       }
       else if ((offset = (boff_t)strtoumax (argv[3], NULL, 10)) > state->out.size)
       {
-        Log (1, "GET: remote requests seeking %s to %" PRIuMAX ", file size " PRIuMAX,
+        Log (1, "GET: remote requests seeking %s to %" PRIuMAX ", file size %" PRIuMAX,
              argv[0], (uintmax_t) offset, (uintmax_t) state->out.size);
-        msg_sendf(state, M_ERR, "Invalid M_GET violates binkp: offset " PRIuMAX " after end of file, file %s size " PRIuMAX,
+        msg_sendf(state, M_ERR, "Invalid M_GET violates binkp: offset %" PRIuMAX " after end of file, file %s size %" PRIuMAX,
                   (uintmax_t)offset, argv[0], (uintmax_t)state->out.size);
         /* touch the file and drop session */
         fclose(state->out.f);
@@ -2276,7 +2276,7 @@ static int GET (STATE *state, char *args, int sz, BINKD_CONFIG *config)
       {
         Log (1, "GET: error seeking %s to %" PRIuMAX ": %s",
              argv[0], (uintmax_t) offset, strerror (errno));
-        msg_sendf(state, M_ERR, "Error seeking: %s size " PRIuMAX " to offset " PRIuMAX,
+        msg_sendf(state, M_ERR, "Error seeking: %s size %" PRIuMAX " to offset %" PRIuMAX,
                   argv[0], (uintmax_t)state->out.size, (uintmax_t)offset);
         fclose(state->out.f);
         state->out.f=NULL;