summaryrefslogtreecommitdiff
path: root/deprecated-ngircd/src
diff options
context:
space:
mode:
Diffstat (limited to 'deprecated-ngircd/src')
-rw-r--r--deprecated-ngircd/src/Makefile.am19
-rw-r--r--deprecated-ngircd/src/ipaddr/Makefile.ng21
-rw-r--r--deprecated-ngircd/src/ipaddr/ng_ipaddr.c179
-rw-r--r--deprecated-ngircd/src/ipaddr/ng_ipaddr.h134
-rw-r--r--deprecated-ngircd/src/portab/Makefile.ng41
-rw-r--r--deprecated-ngircd/src/portab/portab.h184
-rw-r--r--deprecated-ngircd/src/portab/portabtest.c206
-rw-r--r--deprecated-ngircd/src/portab/strdup.c34
-rw-r--r--deprecated-ngircd/src/portab/strlcpy.c72
-rw-r--r--deprecated-ngircd/src/portab/strndup.c34
-rw-r--r--deprecated-ngircd/src/portab/strtok_r.c36
-rw-r--r--deprecated-ngircd/src/portab/vsnprintf.c799
-rw-r--r--deprecated-ngircd/src/portab/waitpid.c30
-rw-r--r--deprecated-ngircd/src/testsuite/Makefile.ng143
-rw-r--r--deprecated-ngircd/src/testsuite/README100
-rw-r--r--deprecated-ngircd/src/testsuite/channel-test.e107
-rw-r--r--deprecated-ngircd/src/testsuite/check-idle.e31
-rwxr-xr-xdeprecated-ngircd/src/testsuite/cleanup-server32
-rw-r--r--deprecated-ngircd/src/testsuite/connect-ssl-cert1-test.e21
-rw-r--r--deprecated-ngircd/src/testsuite/connect-ssl-cert2-test.e21
-rw-r--r--deprecated-ngircd/src/testsuite/connect-test.e20
-rw-r--r--deprecated-ngircd/src/testsuite/functions.inc28
-rwxr-xr-xdeprecated-ngircd/src/testsuite/getpid.sh67
-rw-r--r--deprecated-ngircd/src/testsuite/invite-test.e114
-rw-r--r--deprecated-ngircd/src/testsuite/join-test.e112
-rw-r--r--deprecated-ngircd/src/testsuite/kick-test.e113
-rw-r--r--deprecated-ngircd/src/testsuite/message-test.e152
-rw-r--r--deprecated-ngircd/src/testsuite/misc-test.e164
-rw-r--r--deprecated-ngircd/src/testsuite/mode-test.e175
-rw-r--r--deprecated-ngircd/src/testsuite/ngircd-test1.conf72
-rw-r--r--deprecated-ngircd/src/testsuite/ngircd-test2.conf35
-rw-r--r--deprecated-ngircd/src/testsuite/ngircd-test3.conf31
-rw-r--r--deprecated-ngircd/src/testsuite/opless-channel-test.e33
-rwxr-xr-xdeprecated-ngircd/src/testsuite/prep-server37
-rwxr-xr-xdeprecated-ngircd/src/testsuite/reload-server.sh31
-rwxr-xr-xdeprecated-ngircd/src/testsuite/reload-server37
-rw-r--r--deprecated-ngircd/src/testsuite/server-link-test.e50
-rw-r--r--deprecated-ngircd/src/testsuite/server-login-test.e94
-rw-r--r--deprecated-ngircd/src/testsuite/ssl/cert-my-first-domain-tld.pem24
-rw-r--r--deprecated-ngircd/src/testsuite/ssl/cert-my-second-domain-tld.pem24
-rw-r--r--deprecated-ngircd/src/testsuite/ssl/dhparams-my-first-domain-tld.pem77
-rw-r--r--deprecated-ngircd/src/testsuite/ssl/dhparams-my-second-domain-tld.pem77
-rw-r--r--deprecated-ngircd/src/testsuite/ssl/key-my-first-domain-tld.pem182
-rw-r--r--deprecated-ngircd/src/testsuite/ssl/key-my-second-domain-tld.pem182
-rwxr-xr-xdeprecated-ngircd/src/testsuite/start-server.sh53
-rwxr-xr-xdeprecated-ngircd/src/testsuite/start-server16
-rwxr-xr-xdeprecated-ngircd/src/testsuite/start-server26
-rwxr-xr-xdeprecated-ngircd/src/testsuite/start-server36
-rwxr-xr-xdeprecated-ngircd/src/testsuite/stop-server.sh36
-rwxr-xr-xdeprecated-ngircd/src/testsuite/stop-server16
-rwxr-xr-xdeprecated-ngircd/src/testsuite/stop-server26
-rwxr-xr-xdeprecated-ngircd/src/testsuite/stop-server36
-rw-r--r--deprecated-ngircd/src/testsuite/stress-A.e10
-rw-r--r--deprecated-ngircd/src/testsuite/stress-B.e76
-rwxr-xr-xdeprecated-ngircd/src/testsuite/stress-server.sh88
-rwxr-xr-xdeprecated-ngircd/src/testsuite/switch-server34
-rwxr-xr-xdeprecated-ngircd/src/testsuite/test-loop.sh34
-rwxr-xr-xdeprecated-ngircd/src/testsuite/tests.sh69
-rwxr-xr-xdeprecated-ngircd/src/testsuite/wait-tests.sh44
-rw-r--r--deprecated-ngircd/src/testsuite/who-test.e203
-rw-r--r--deprecated-ngircd/src/testsuite/whois-test.e77
-rw-r--r--deprecated-ngircd/src/tool/Makefile.ng27
-rw-r--r--deprecated-ngircd/src/tool/tool.c249
-rw-r--r--deprecated-ngircd/src/tool/tool.h38
64 files changed, 5129 insertions, 0 deletions
diff --git a/deprecated-ngircd/src/Makefile.am b/deprecated-ngircd/src/Makefile.am
new file mode 100644
index 0000000..e04ebe1
--- /dev/null
+++ b/deprecated-ngircd/src/Makefile.am
@@ -0,0 +1,19 @@
+#
+# ngIRCd -- The Next Generation IRC Daemon
+# Copyright (c)2001,2002 by Alexander Barton (alex@barton.de)
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+# Please read the file COPYING, README and AUTHORS for more information.
+#
+# $Id: Makefile.am,v 1.8 2008/02/26 22:04:15 fw Exp $
+#
+
+SUBDIRS = portab tool ipaddr ngircd testsuite
+
+maintainer-clean-local:
+ rm -f Makefile Makefile.in config.h config.h.in stamp-h.in
+
+# -eof-
diff --git a/deprecated-ngircd/src/ipaddr/Makefile.ng b/deprecated-ngircd/src/ipaddr/Makefile.ng
new file mode 100644
index 0000000..ecfce29
--- /dev/null
+++ b/deprecated-ngircd/src/ipaddr/Makefile.ng
@@ -0,0 +1,21 @@
+#
+# ipaddr/Makefile.am
+# (c) 2008 Florian Westphal <fw@strlen.de>, public domain.
+#
+
+__ng_Makefile_am_template__
+
+EXTRA_DIST = Makefile.ng
+
+AM_CPPFLAGS = -I$(srcdir)/../portab
+
+noinst_LIBRARIES = libngipaddr.a
+
+libngipaddr_a_SOURCES = ng_ipaddr.c
+
+noinst_HEADERS = ng_ipaddr.h
+
+maintainer-clean-local:
+ rm -f Makefile Makefile.in Makefile.am
+
+# -eof-
diff --git a/deprecated-ngircd/src/ipaddr/ng_ipaddr.c b/deprecated-ngircd/src/ipaddr/ng_ipaddr.c
new file mode 100644
index 0000000..37f75b6
--- /dev/null
+++ b/deprecated-ngircd/src/ipaddr/ng_ipaddr.c
@@ -0,0 +1,179 @@
+/*
+ * (c) 2008 Florian Westphal <fw@strlen.de>, public domain.
+ */
+
+#include "portab.h"
+
+/**
+ * @file
+ * Functions for AF_ agnostic ipv4/ipv6 handling.
+ */
+
+#include <assert.h>
+#include <stdio.h>
+#include <string.h>
+
+#ifdef HAVE_GETADDRINFO
+#include <netdb.h>
+#include <sys/types.h>
+#endif
+
+#include "ng_ipaddr.h"
+
+GLOBAL bool
+ng_ipaddr_init(ng_ipaddr_t *addr, const char *ip_str, UINT16 port)
+{
+#ifdef HAVE_WORKING_GETADDRINFO
+ int ret;
+ char portstr[64];
+ struct addrinfo *res0;
+ struct addrinfo hints;
+
+ assert(ip_str);
+
+ memset(&hints, 0, sizeof(hints));
+#ifdef AI_NUMERICHOST
+ hints.ai_flags = AI_NUMERICHOST;
+#endif
+#ifndef WANT_IPV6 /* do not convert ipv6 addresses */
+ hints.ai_family = AF_INET;
+#endif
+
+ /* some getaddrinfo implementations require that ai_socktype is set. */
+ hints.ai_socktype = SOCK_STREAM;
+
+ /* silly, but ngircd stores UINT16 in server config, not string */
+ snprintf(portstr, sizeof(portstr), "%u", (unsigned int) port);
+
+ ret = getaddrinfo(ip_str, portstr, &hints, &res0);
+ if (ret != 0)
+ return false;
+
+ assert(sizeof(*addr) >= (size_t)res0->ai_addrlen);
+ if (sizeof(*addr) >= (size_t)res0->ai_addrlen)
+ memcpy(addr, res0->ai_addr, res0->ai_addrlen);
+ else
+ ret = -1;
+ freeaddrinfo(res0);
+ return ret == 0;
+#else /* HAVE_GETADDRINFO */
+ assert(ip_str);
+ memset(addr, 0, sizeof *addr);
+#ifdef HAVE_sockaddr_in_len
+ addr->sin4.sin_len = sizeof(addr->sin4);
+#endif
+ addr->sin4.sin_family = AF_INET;
+# ifdef HAVE_INET_ATON
+ if (inet_aton(ip_str, &addr->sin4.sin_addr) == 0)
+ return false;
+# else
+ addr->sin4.sin_addr.s_addr = inet_addr(ip_str);
+ if (addr->sin4.sin_addr.s_addr == (unsigned) -1)
+ return false;
+# endif
+ ng_ipaddr_setport(addr, port);
+ return true;
+#endif /* HAVE_GETADDRINFO */
+}
+
+
+GLOBAL void
+ng_ipaddr_setport(ng_ipaddr_t *a, UINT16 port)
+{
+#ifdef WANT_IPV6
+ int af;
+
+ assert(a != NULL);
+
+ af = a->sa.sa_family;
+
+ assert(af == AF_INET || af == AF_INET6);
+
+ switch (af) {
+ case AF_INET:
+ a->sin4.sin_port = htons(port);
+ break;
+ case AF_INET6:
+ a->sin6.sin6_port = htons(port);
+ break;
+ }
+#else /* WANT_IPV6 */
+ assert(a != NULL);
+ assert(a->sin4.sin_family == AF_INET);
+ a->sin4.sin_port = htons(port);
+#endif /* WANT_IPV6 */
+}
+
+
+
+GLOBAL bool
+ng_ipaddr_ipequal(const ng_ipaddr_t *a, const ng_ipaddr_t *b)
+{
+ assert(a != NULL);
+ assert(b != NULL);
+#ifdef WANT_IPV6
+ if (a->sa.sa_family != b->sa.sa_family)
+ return false;
+ assert(ng_ipaddr_salen(a) == ng_ipaddr_salen(b));
+ switch (a->sa.sa_family) {
+ case AF_INET6:
+ return IN6_ARE_ADDR_EQUAL(&a->sin6.sin6_addr, &b->sin6.sin6_addr);
+ case AF_INET:
+ return memcmp(&a->sin4.sin_addr, &b->sin4.sin_addr, sizeof(a->sin4.sin_addr)) == 0;
+ }
+ return false;
+#else
+ assert(a->sin4.sin_family == AF_INET);
+ assert(b->sin4.sin_family == AF_INET);
+ return memcmp(&a->sin4.sin_addr, &b->sin4.sin_addr, sizeof(a->sin4.sin_addr)) == 0;
+#endif
+}
+
+
+#ifdef WANT_IPV6
+GLOBAL const char *
+ng_ipaddr_tostr(const ng_ipaddr_t *addr)
+{
+ static char strbuf[NG_INET_ADDRSTRLEN];
+
+ strbuf[0] = 0;
+
+ ng_ipaddr_tostr_r(addr, strbuf);
+ return strbuf;
+}
+
+
+/* str must be at least NG_INET_ADDRSTRLEN bytes long */
+GLOBAL bool
+ng_ipaddr_tostr_r(const ng_ipaddr_t *addr, char *str)
+{
+#ifdef HAVE_GETNAMEINFO
+ const struct sockaddr *sa = (const struct sockaddr *) addr;
+ int ret;
+
+ *str = 0;
+
+ ret = getnameinfo(sa, ng_ipaddr_salen(addr),
+ str, NG_INET_ADDRSTRLEN, NULL, 0, NI_NUMERICHOST);
+ /*
+ * avoid leading ':'.
+ * causes mis-interpretation of client host in e.g. /WHOIS
+ */
+ if (*str == ':') {
+ char tmp[NG_INET_ADDRSTRLEN] = "0";
+ ret = getnameinfo(sa, ng_ipaddr_salen(addr),
+ tmp + 1, (socklen_t)sizeof(tmp) - 1,
+ NULL, 0, NI_NUMERICHOST);
+ if (ret == 0)
+ strlcpy(str, tmp, NG_INET_ADDRSTRLEN);
+ }
+ assert (ret == 0);
+ return ret == 0;
+#else
+ abort(); /* WANT_IPV6 depends on HAVE_GETNAMEINFO */
+#endif
+}
+
+#endif /* WANT_IPV6 */
+
+/* -eof- */
diff --git a/deprecated-ngircd/src/ipaddr/ng_ipaddr.h b/deprecated-ngircd/src/ipaddr/ng_ipaddr.h
new file mode 100644
index 0000000..f8409de
--- /dev/null
+++ b/deprecated-ngircd/src/ipaddr/ng_ipaddr.h
@@ -0,0 +1,134 @@
+/*
+ * (c) 2008 Florian Westphal <fw@strlen.de>, public domain.
+ */
+
+#ifndef NG_IPADDR_HDR
+#define NG_IPADDR_HDR
+
+#include "portab.h"
+
+/**
+ * @file
+ * Functions for AF_ agnostic ipv4/ipv6 handling (header).
+ */
+
+#include <assert.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+
+#ifdef HAVE_ARPA_INET_H
+# include <arpa/inet.h>
+#else
+# define PF_INET AF_INET
+#endif
+
+
+#ifdef WANT_IPV6
+#define NG_INET_ADDRSTRLEN INET6_ADDRSTRLEN
+#else
+#define NG_INET_ADDRSTRLEN 16
+#endif
+
+
+#ifdef WANT_IPV6
+typedef union {
+ struct sockaddr sa;
+ struct sockaddr_in sin4;
+ struct sockaddr_in6 sin6;
+} ng_ipaddr_t;
+#else
+/* assume compiler can't deal with typedef struct {... */
+struct NG_IP_ADDR_DONTUSE {
+ struct sockaddr_in sin4;
+};
+typedef struct NG_IP_ADDR_DONTUSE ng_ipaddr_t;
+#endif
+
+
+static inline int
+ng_ipaddr_af(const ng_ipaddr_t *a)
+{
+ assert(a != NULL);
+#ifdef WANT_IPV6
+ return a->sa.sa_family;
+#else
+ assert(a->sin4.sin_family == 0 || a->sin4.sin_family == AF_INET);
+ return a->sin4.sin_family;
+#endif
+}
+
+
+static inline socklen_t
+ng_ipaddr_salen(const ng_ipaddr_t *a)
+{
+ assert(a != NULL);
+#ifdef WANT_IPV6
+ assert(a->sa.sa_family == AF_INET || a->sa.sa_family == AF_INET6);
+ if (a->sa.sa_family == AF_INET6)
+ return (socklen_t)sizeof(a->sin6);
+#endif
+ assert(a->sin4.sin_family == AF_INET);
+ return (socklen_t)sizeof(a->sin4);
+}
+
+
+static inline UINT16
+ng_ipaddr_getport(const ng_ipaddr_t *a)
+{
+#ifdef WANT_IPV6
+ int af = a->sa.sa_family;
+
+ assert(a != NULL);
+ assert(af == AF_INET || af == AF_INET6);
+
+ if (af == AF_INET6)
+ return ntohs(a->sin6.sin6_port);
+#endif /* WANT_IPV6 */
+
+ assert(a != NULL);
+ assert(a->sin4.sin_family == AF_INET);
+ return ntohs(a->sin4.sin_port);
+}
+
+/*
+ * init a ng_ipaddr_t object.
+ * @param addr: pointer to ng_ipaddr_t to initialize.
+ * @param ip_str: ip address in dotted-decimal (ipv4) or hexadecimal (ipv6) notation
+ * @param port: transport layer port number to use.
+ */
+GLOBAL bool ng_ipaddr_init PARAMS((ng_ipaddr_t *addr, const char *ip_str, UINT16 port));
+
+/* set sin4/sin6_port, depending on a->sa_family */
+GLOBAL void ng_ipaddr_setport PARAMS((ng_ipaddr_t *a, UINT16 port));
+
+/* return true if a and b have the same IP address. If a and b have different AF, return false. */
+GLOBAL bool ng_ipaddr_ipequal PARAMS((const ng_ipaddr_t *a, const ng_ipaddr_t *b));
+
+
+#ifdef WANT_IPV6
+/* convert struct sockaddr to string, returns pointer to static buffer */
+GLOBAL const char *ng_ipaddr_tostr PARAMS((const ng_ipaddr_t *addr));
+
+/* convert struct sockaddr to string. dest must be NG_INET_ADDRSTRLEN bytes long */
+GLOBAL bool ng_ipaddr_tostr_r PARAMS((const ng_ipaddr_t *addr, char *dest));
+#else
+static inline const char*
+ng_ipaddr_tostr(const ng_ipaddr_t *addr)
+{
+ assert(addr != NULL);
+ return inet_ntoa(addr->sin4.sin_addr);
+}
+
+static inline bool
+ng_ipaddr_tostr_r(const ng_ipaddr_t *addr, char *d)
+{
+ assert(addr != NULL);
+ assert(d != NULL);
+ strlcpy(d, inet_ntoa(addr->sin4.sin_addr), NG_INET_ADDRSTRLEN);
+ return true;
+}
+#endif
+#endif
+
+/* -eof- */
diff --git a/deprecated-ngircd/src/portab/Makefile.ng b/deprecated-ngircd/src/portab/Makefile.ng
new file mode 100644
index 0000000..9be5f56
--- /dev/null
+++ b/deprecated-ngircd/src/portab/Makefile.ng
@@ -0,0 +1,41 @@
+#
+# ngIRCd -- The Next Generation IRC Daemon
+# Copyright (c)2001-2024 Alexander Barton (alex@barton.de) and Contributors
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+# Please read the file COPYING, README and AUTHORS for more information.
+#
+
+__ng_Makefile_am_template__
+
+EXTRA_DIST = Makefile.ng
+
+noinst_LIBRARIES = libngportab.a
+
+libngportab_a_SOURCES = \
+ strdup.c \
+ strlcpy.c \
+ strndup.c \
+ strtok_r.c \
+ vsnprintf.c \
+ waitpid.c
+
+check_PROGRAMS = portabtest
+
+portabtest_SOURCES = portabtest.c
+
+portabtest_LDFLAGS = -L.
+
+portabtest_LDADD = -lngportab
+
+noinst_HEADERS = portab.h
+
+maintainer-clean-local:
+ rm -f Makefile Makefile.in Makefile.am
+
+TESTS = portabtest
+
+# -eof-
diff --git a/deprecated-ngircd/src/portab/portab.h b/deprecated-ngircd/src/portab/portab.h
new file mode 100644
index 0000000..e0ec3e1
--- /dev/null
+++ b/deprecated-ngircd/src/portab/portab.h
@@ -0,0 +1,184 @@
+/*
+ * ngIRCd -- The Next Generation IRC Daemon
+ * Copyright (c)2001-2014 Alexander Barton (alex@barton.de) and Contributors.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * Please read the file COPYING, README and AUTHORS for more information.
+ */
+
+#ifndef __PORTAB__
+#define __PORTAB__
+
+/**
+ * @file
+ * Portability functions and declarations (header)
+ */
+
+#include "config.h"
+
+/* remove assert() macro at compile time if DEBUG is not set. */
+
+#ifndef DEBUG
+# define NDEBUG
+#endif
+
+/* compiler features */
+
+#if (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 7))
+# define PUNUSED(x) __attribute__ ((unused)) x
+# define UNUSED __attribute__ ((unused))
+#else
+# define PUNUSED(x) x
+# define UNUSED
+#endif
+
+#ifndef PARAMS
+# if PROTOTYPES
+# define PARAMS(args) args
+# else
+# define PARAMS(args) ()
+# endif
+#endif
+
+/* datatypes */
+
+#include <sys/types.h>
+
+#ifdef HAVE_STDDEF_H
+# include <stddef.h>
+#endif
+
+#ifdef HAVE_INTTYPES_H
+# include <inttypes.h>
+# define NGIRC_GOT_INTTYPES
+#else
+# ifdef HAVE_STDINT_H
+# include <stdint.h>
+# define NGIRC_GOT_INTTYPES
+# endif
+#endif
+
+#ifndef PROTOTYPES
+# ifndef signed
+# define signed
+# endif
+#endif
+
+typedef void POINTER;
+
+#ifdef NGIRC_GOT_INTTYPES
+typedef uint8_t UINT8;
+typedef uint16_t UINT16;
+typedef uint32_t UINT32;
+#else
+typedef unsigned char UINT8;
+typedef unsigned short UINT16;
+typedef unsigned int UINT32;
+#endif
+
+#ifdef HAVE_STDBOOL_H
+# include <stdbool.h>
+#else
+typedef unsigned char bool;
+# define true (bool)1
+# define false (bool)0
+#endif
+
+#ifndef NULL
+# ifdef PROTOTYPES
+# define NULL (void *)0
+# else
+# define NULL 0L
+# endif
+#endif
+
+#ifdef NeXT
+# define S_IRUSR 0000400 /* read permission, owner */
+# define S_IWUSR 0000200 /* write permission, owner */
+# define S_IRGRP 0000040 /* read permission, group */
+# define S_IROTH 0000004 /* read permission, other */
+# define ssize_t int
+#endif
+
+#undef GLOBAL
+#ifdef GLOBAL_INIT
+#define GLOBAL
+#else
+#define GLOBAL extern
+#endif
+
+/* target constants */
+
+#ifndef HOST_OS
+# define HOST_OS "unknown"
+#endif
+
+#ifndef HOST_CPU
+# define HOST_CPU "unknown"
+#endif
+
+#ifndef HOST_VENDOR
+# define HOST_VENDOR "unknown"
+#endif
+
+#ifdef __HAIKU__
+# define SINGLE_USER_OS
+#endif
+
+/* configure options */
+
+#ifndef HAVE_socklen_t
+typedef int socklen_t; /* for Mac OS X, amongst others */
+#endif
+
+#ifndef HAVE_SNPRINTF
+extern int snprintf PARAMS(( char *str, size_t count, const char *fmt, ... ));
+#endif
+
+#ifndef HAVE_STRLCAT
+extern size_t strlcat PARAMS(( char *dst, const char *src, size_t size ));
+#endif
+
+#ifndef HAVE_STRLCPY
+extern size_t strlcpy PARAMS(( char *dst, const char *src, size_t size ));
+#endif
+
+#ifndef HAVE_STRDUP
+extern char * strdup PARAMS(( const char *s ));
+#endif
+
+#ifndef HAVE_STRNDUP
+extern char * strndup PARAMS((const char *s, size_t maxlen));
+#endif
+
+#ifndef HAVE_STRTOK_R
+extern char * strtok_r PARAMS((char *str, const char *delim, char **saveptr));
+#endif
+
+#ifndef HAVE_VSNPRINTF
+#include <stdarg.h>
+extern int vsnprintf PARAMS(( char *str, size_t count, const char *fmt, va_list args ));
+#endif
+
+#ifndef HAVE_GAI_STRERROR
+# define gai_strerror(r) "unknown error"
+#endif
+
+#ifndef PACKAGE_NAME
+# define PACKAGE_NAME PACKAGE
+#endif
+
+#ifndef PACKAGE_VERSION
+# define PACKAGE_VERSION VERSION
+#endif
+
+#ifndef SYSCONFDIR
+# define SYSCONFDIR "/etc"
+#endif
+
+#endif
+
+/* -eof- */
diff --git a/deprecated-ngircd/src/portab/portabtest.c b/deprecated-ngircd/src/portab/portabtest.c
new file mode 100644
index 0000000..5ad37b9
--- /dev/null
+++ b/deprecated-ngircd/src/portab/portabtest.c
@@ -0,0 +1,206 @@
+/*
+ * ngIRCd -- The Next Generation IRC Daemon
+ * Copyright (c)2001-2014 Alexander Barton (alex@barton.de) and Contributors.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * Please read the file COPYING, README and AUTHORS for more information.
+ */
+
+#include "portab.h"
+
+/**
+ * @file
+ * Test program for portab.h and friends ;-)
+ */
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+int allow_severity = 0, deny_severity = 0;
+
+static void
+Panic(char *Reason)
+{
+ /* Oops, something failed!? */
+ fprintf(stderr, "Oops, test for %s failed!?\n", Reason);
+ exit(1);
+} /* Panic */
+
+static void
+Check_snprintf(void)
+{
+ char str[5];
+
+ snprintf(str, sizeof(str), "%s", "1234567890");
+ if (str[4] != '\0')
+ Panic("snprintf NULL byte");
+ if (strlen(str) != 4)
+ Panic("snprintf string length");
+}
+
+static void
+Check_strdup(void)
+{
+ char *ptr;
+
+ ptr = strdup("1234567890");
+ if (!ptr)
+ Panic("strdup");
+ if (ptr[10] != '\0')
+ Panic("strdup NULL byte");
+ if (strlen(ptr) != 10)
+ Panic("strdup string length");
+ free(ptr);
+}
+
+static void
+Check_strndup(void)
+{
+ char *ptr;
+
+ ptr = strndup("1234567890", 5);
+ if (!ptr)
+ Panic("strndup");
+ if (ptr[5] != '\0')
+ Panic("strndup NULL byte");
+ if (strlen(ptr) != 5)
+ Panic("strndup string length");
+ free(ptr);
+}
+
+static void
+Check_strlcpy(void)
+{
+ char str[5];
+
+ if (strlcpy(str, "1234567890", sizeof(str)) != 10)
+ Panic("strlcpy return code");
+ if (str[4] != '\0')
+ Panic("strlcpy NULL byte");
+ if (strlen(str) != 4)
+ Panic("strlcpy string length");
+}
+
+static void
+Check_strlcat(void)
+{
+ char str[5];
+
+ if (strlcpy(str, "12", sizeof(str)) != 2)
+ Panic("strlcpy for strlcat");
+ if (strlcat(str, "1234567890", sizeof(str)) != 12)
+ Panic("strlcat return code");
+ if (str[4] != '\0')
+ Panic("strlcat NULL byte");
+ if (strlen(str) != 4)
+ Panic("strlcat string length");
+}
+
+static void
+Check_strtok_r(void)
+{
+ char *str, *ptr, *last;
+
+ ptr = strdup("12,abc");
+ str = ptr;
+
+ ptr = strtok_r(ptr, ",", &last);
+ if (!ptr)
+ Panic("strtok_r result #1");
+ if (strcmp(ptr, "12") != 0)
+ Panic("strtok_r token #1");
+
+ ptr = strtok_r(NULL, ",", &last);
+ if (!ptr)
+ Panic("strtok_r result #2");
+ if (strcmp(ptr, "abc") != 0)
+ Panic("strtok_r token #2");
+
+ ptr = strtok_r(NULL, ",", &last);
+ if (ptr)
+ Panic("strtok_r result #3");
+
+ free(str);
+}
+
+#ifdef PROTOTYPES
+static void
+Check_vsnprintf(const int Len, const char *Format, ...)
+#else
+static void
+Check_vsnprintf(Len, Format, va_alist)
+const int Len;
+const char *Format;
+va_dcl
+#endif
+{
+ char str[5];
+ va_list ap;
+ int r;
+
+#ifdef PROTOTYPES
+ va_start(ap, Format);
+#else
+ va_start(ap);
+#endif
+ r = vsnprintf(str, sizeof(str), Format, ap);
+ va_end(ap);
+ if (r != Len) {
+ /* C99 states that vsnprintf() "returns the number of
+ * characters that would have been printed if the n were
+ * unlimited", but according to the Linux manual page "glibc
+ * until 2.0.6 would return -1 when the output was truncated",
+ * and other implementations (libUTIL on A/UX) even return the
+ * number of characters processed ... so we only test our own
+ * implementation and warn on errors otherwise :-/ */
+#ifdef HAVE_VSNPRINTF
+ fprintf(stderr,
+ "\n ** WARNING: The vsnprintf() function of this system isn't standard\n");
+ fprintf(stderr,
+ " ** conformant and returns a WRONG result: %d (should be %d)! The test\n",
+ r, Len);
+ fprintf(stderr,
+ " ** result has been ignored but may lead to errors during execution!\n\n");
+#else
+ Panic("vsnprintf return code");
+#endif
+ }
+ if (str[4] != '\0')
+ Panic("vsnprintf NULL byte");
+ if (strlen(str) != 4)
+ Panic("vsnprintf string length");
+}
+
+GLOBAL int
+main(void)
+{
+ /* validate datatypes */
+ if (false != 0)
+ Panic("false");
+ if (true != 1)
+ Panic("true");
+ if (sizeof(UINT8) != 1)
+ Panic("UINT8");
+ if (sizeof(UINT16) != 2)
+ Panic("UINT16");
+ if (sizeof(UINT32) != 4)
+ Panic("UINT32");
+
+ /* check functions */
+ Check_snprintf();
+ Check_strdup();
+ Check_strndup();
+ Check_strlcpy();
+ Check_strlcat();
+ Check_strtok_r();
+ Check_vsnprintf(2+10, "%s%s", "ab", "1234567890");
+
+ return 0;
+}
+
+/* -eof- */
diff --git a/deprecated-ngircd/src/portab/strdup.c b/deprecated-ngircd/src/portab/strdup.c
new file mode 100644
index 0000000..adb19e7
--- /dev/null
+++ b/deprecated-ngircd/src/portab/strdup.c
@@ -0,0 +1,34 @@
+/*
+ * ngIRCd -- The Next Generation IRC Daemon
+ */
+
+#include "portab.h"
+
+/**
+ * @file
+ * strdup() implementation. Public domain.
+ */
+
+#ifndef HAVE_STRDUP
+
+#include <string.h>
+#include <stdlib.h>
+#include <sys/types.h>
+
+GLOBAL char *
+strdup(const char *s)
+{
+ char *dup;
+ size_t len = strlen(s);
+ size_t alloc = len + 1;
+
+ if (len >= alloc)
+ return NULL;
+ dup = malloc(alloc);
+ if (dup)
+ strlcpy(dup, s, alloc );
+
+ return dup;
+}
+
+#endif
diff --git a/deprecated-ngircd/src/portab/strlcpy.c b/deprecated-ngircd/src/portab/strlcpy.c
new file mode 100644
index 0000000..1f86a93
--- /dev/null
+++ b/deprecated-ngircd/src/portab/strlcpy.c
@@ -0,0 +1,72 @@
+/*
+ * ngIRCd -- The Next Generation IRC Daemon
+ * Copyright (c)2001-2014 Alexander Barton (alex@barton.de) and Contributors.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * Please read the file COPYING, README and AUTHORS for more information.
+ */
+
+#include "portab.h"
+
+/**
+ * @file
+ * strlcpy() and strlcat() replacement functions.
+ *
+ * See <http://www.openbsd.org/papers/strlcpy-paper.ps> for details.
+ *
+ * Code partially borrowed from compat.c of rsync, written by Andrew
+ * Tridgell (1998) and Martin Pool (2002):
+ * <http://cvs.samba.org/cgi-bin/cvsweb/rsync/lib/compat.c>
+ */
+
+#include <string.h>
+#include <sys/types.h>
+
+#ifndef HAVE_STRLCAT
+
+GLOBAL size_t
+strlcat( char *dst, const char *src, size_t size )
+{
+ /* Like strncat() but does not 0 fill the buffer and
+ * always null terminates. */
+
+ size_t len1 = strlen( dst );
+ size_t len2 = strlen( src );
+ size_t ret = len1 + len2;
+
+ if( size && ( len1 < size - 1 )) {
+ if( len2 >= size - len1 )
+ len2 = size - len1 - 1;
+ memcpy( dst + len1, src, len2 );
+ dst[len1 + len2] = 0;
+ }
+ return ret;
+} /* strlcat */
+
+#endif
+
+#ifndef HAVE_STRLCPY
+
+GLOBAL size_t
+strlcpy( char *dst, const char *src, size_t size )
+{
+ /* Like strncpy but does not 0 fill the buffer and
+ * always null terminates. */
+
+ size_t len = strlen( src );
+ size_t ret = len;
+
+ if( size > 0 ) {
+ if( len >= size ) len = size - 1;
+ memcpy( dst, src, len );
+ dst[len] = 0;
+ }
+ return ret;
+} /* strlcpy */
+
+#endif
+
+/* -eof- */
diff --git a/deprecated-ngircd/src/portab/strndup.c b/deprecated-ngircd/src/portab/strndup.c
new file mode 100644
index 0000000..d63b972
--- /dev/null
+++ b/deprecated-ngircd/src/portab/strndup.c
@@ -0,0 +1,34 @@
+/*
+ * ngIRCd -- The Next Generation IRC Daemon
+ */
+
+#include "portab.h"
+
+/**
+ * @file
+ * strndup() implementation. Public domain.
+ */
+
+#ifndef HAVE_STRNDUP
+
+#include <string.h>
+#include <stdlib.h>
+#include <sys/types.h>
+
+GLOBAL char *
+strndup(const char *s, size_t maxlen)
+{
+ char *dup;
+ size_t len = strlen(s);
+
+ if (len > maxlen)
+ len = maxlen;
+ len++;
+ dup = malloc(len);
+ if (dup)
+ strlcpy(dup, s, len);
+
+ return dup;
+}
+
+#endif
diff --git a/deprecated-ngircd/src/portab/strtok_r.c b/deprecated-ngircd/src/portab/strtok_r.c
new file mode 100644
index 0000000..4d00772
--- /dev/null
+++ b/deprecated-ngircd/src/portab/strtok_r.c
@@ -0,0 +1,36 @@
+/*
+ * ngIRCd -- The Next Generation IRC Daemon
+ */
+
+#include "portab.h"
+
+/**
+ * @file
+ * Implementation of strtok_r()
+ */
+
+#ifndef HAVE_STRTOK_R
+
+#include <string.h>
+
+char *
+strtok_r(char *str, const char *delim, char **saveptr)
+{
+ char *tmp;
+
+ if (!str)
+ str = *saveptr;
+ str += strspn(str, delim);
+ if (*str == 0)
+ return NULL;
+
+ tmp = str + strcspn(str, delim); /* get end of token */
+ if (*tmp) { /* another delimiter */
+ *tmp = 0;
+ tmp++;
+ }
+ *saveptr = tmp;
+ return str;
+}
+
+#endif
diff --git a/deprecated-ngircd/src/portab/vsnprintf.c b/deprecated-ngircd/src/portab/vsnprintf.c
new file mode 100644
index 0000000..d3b2a88
--- /dev/null
+++ b/deprecated-ngircd/src/portab/vsnprintf.c
@@ -0,0 +1,799 @@
+/*
+ * ngIRCd -- The Next Generation IRC Daemon
+ * Copyright (c)2001,2002 by Alexander Barton (alex@barton.de)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * Please read the file COPYING, README and AUTHORS for more information.
+ */
+
+#include "portab.h"
+
+/**
+ * @file
+ * snprintf() and vsnprintf() replacement functions
+ */
+
+/*
+ * snprintf.c: 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, formatted 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>, October 1998
+ * fixed handling of %.0f
+ * added test for HAVE_LONG_DOUBLE
+ *
+ * tridge@samba.org, idra@samba.org, April 2001
+ * got rid of fcvt code (twas buggy and made testing harder)
+ * added C99 semantics
+ *
+ * Alexander Barton, <alex@barton.de>, 2002-05-19
+ * removed [v]asprintf() and C99 tests: not needed by ngIRCd.
+ */
+
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif
+#ifdef HAVE_CTYPE_H
+#include <ctype.h>
+#endif
+#include <sys/types.h>
+#include <stdarg.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+
+#if defined(HAVE_SNPRINTF) && defined(HAVE_VSNPRINTF)
+/* only include stdio.h if we are not re-defining snprintf or vsnprintf */
+#include <stdio.h>
+/* make the compiler happy with an empty file */
+void dummy_snprintf PARAMS(( void ));
+void dummy_snprintf PARAMS(( void )) { }
+#else
+
+#ifdef HAVE_LONG_DOUBLE
+#define LDOUBLE long double
+#else
+#define LDOUBLE double
+#endif
+
+#ifdef HAVE_LONG_LONG
+#define LLONG long long
+#else
+#define LLONG long
+#endif
+
+static size_t dopr PARAMS((char *buffer, size_t maxlen, const char *format,
+ va_list args));
+static void fmtstr PARAMS((char *buffer, size_t *currlen, size_t maxlen,
+ char *value, int flags, int min, int max));
+static void fmtint PARAMS((char *buffer, size_t *currlen, size_t maxlen,
+ long value, int base, int min, int max, int flags));
+static void fmtfp PARAMS((char *buffer, size_t *currlen, size_t maxlen,
+ LDOUBLE fvalue, int min, int max, int flags));
+static void dopr_outch PARAMS((char *buffer, size_t *currlen, size_t maxlen,
+ char 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')
+#ifndef MAX
+#define MAX(p,q) (((p) >= (q)) ? (p) : (q))
+#endif
+
+static size_t
+dopr(char *buffer, size_t maxlen, 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;
+ currlen = flags = cflags = min = 0;
+ max = -1;
+ ch = *format++;
+
+ while (state != DP_S_DONE) {
+ if (ch == '\0')
+ 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':
+ cflags = DP_C_LONG;
+ ch = *format++;
+ if (ch == 'l') { /* It's a long long */
+ 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':
+ if (cflags == DP_C_SHORT)
+ value = va_arg (args, int);
+ else if (cflags == DP_C_LONG)
+ value = va_arg (args, long int);
+ else if (cflags == DP_C_LLONG)
+ value = va_arg (args, LLONG);
+ else
+ value = va_arg (args, int);
+ fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags);
+ break;
+ case 'o':
+ flags |= DP_F_UNSIGNED;
+ if (cflags == DP_C_SHORT)
+ value = va_arg (args, unsigned int);
+ else if (cflags == DP_C_LONG)
+ value = (long)va_arg (args, unsigned long int);
+ else if (cflags == DP_C_LLONG)
+ value = (long)va_arg (args, unsigned LLONG);
+ else
+ value = (long)va_arg (args, unsigned int);
+ fmtint (buffer, &currlen, maxlen, value, 8, min, max, flags);
+ break;
+ case 'u':
+ flags |= DP_F_UNSIGNED;
+ if (cflags == DP_C_SHORT)
+ value = va_arg (args, unsigned int);
+ else if (cflags == DP_C_LONG)
+ value = (long)va_arg (args, unsigned long int);
+ else if (cflags == DP_C_LLONG)
+ value = (LLONG)va_arg (args, unsigned LLONG);
+ else
+ value = (long)va_arg (args, unsigned int);
+ fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags);
+ break;
+ case 'X':
+ flags |= DP_F_UP;
+ case 'x':
+ flags |= DP_F_UNSIGNED;
+ if (cflags == DP_C_SHORT)
+ value = va_arg (args, unsigned int);
+ else if (cflags == DP_C_LONG)
+ value = (long)va_arg (args, unsigned long int);
+ else if (cflags == DP_C_LLONG)
+ value = (LLONG)va_arg (args, unsigned LLONG);
+ else
+ value = (long)va_arg (args, unsigned int);
+ fmtint (buffer, &currlen, maxlen, value, 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 == -1) {
+ max = strlen(strvalue);
+ }
+ if (min > 0 && max >= 0 && min > max) max = min;
+ fmtstr (buffer, &currlen, maxlen, strvalue, flags, min, max);
+ break;
+ case 'p':
+ strvalue = va_arg (args, void *);
+ fmtint (buffer, &currlen, maxlen, (long) strvalue, 16, min, max, flags);
+ break;
+ case 'n':
+ if (cflags == DP_C_SHORT) {
+ short int *num;
+ num = va_arg (args, short int *);
+ *num = currlen;
+ } else if (cflags == DP_C_LONG) {
+ long int *num;
+ num = va_arg (args, long int *);
+ *num = (long int)currlen;
+ } else if (cflags == DP_C_LLONG) {
+ 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 (maxlen != 0) {
+ if (currlen < maxlen - 1)
+ buffer[currlen] = '\0';
+ else if (maxlen > 0)
+ buffer[maxlen - 1] = '\0';
+ }
+
+ return currlen;
+}
+
+static void
+fmtstr(char *buffer, size_t *currlen, size_t maxlen, char *value, int flags,
+ int min, int max)
+{
+ int padlen, strln; /* amount to pad */
+ int cnt = 0;
+
+#ifdef DEBUG_SNPRINTF
+ printf("fmtstr min=%d max=%d s=[%s]\n", min, max, value);
+#endif
+ 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, long value, int base,
+ int min, int max, int flags)
+{
+ int signvalue = 0;
+ unsigned long 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 LLONG
+ROUND(LDOUBLE value)
+{
+ LLONG intpart;
+
+ intpart = (LLONG)value;
+ value = value - intpart;
+ if (value >= 0.5) intpart++;
+
+ return intpart;
+}
+
+/* a replacement for modf that doesn't need the math library. Should
+ be portable, but slow */
+static double
+my_modf(double x0, double *iptr)
+{
+ int i;
+ long l;
+ double x = x0;
+ double f = 1.0;
+
+ for (i=0;i<100;i++) {
+ l = (long)x;
+ if (l <= (x+1) && l >= (x-1)) break;
+ x *= 0.1;
+ f *= 10.0;
+ }
+
+ if (i == 100) {
+ /* yikes! the number is beyond what we can handle. What do we do? */
+ (*iptr) = 0;
+ return 0;
+ }
+
+ if (i != 0) {
+ double i2;
+ double ret;
+
+ ret = my_modf(x0-l*f, &i2);
+ (*iptr) = l*f + i2;
+ return ret;
+ }
+
+ (*iptr) = l;
+ return x - (*iptr);
+}
+
+
+static void
+fmtfp (char *buffer, size_t *currlen, size_t maxlen, LDOUBLE fvalue,
+ int min, int max, int flags)
+{
+ int signvalue = 0;
+ double ufvalue;
+ char iconvert[311];
+ char fconvert[311];
+ int iplace = 0;
+ int fplace = 0;
+ int padlen = 0; /* amount to pad */
+ int zpadlen = 0;
+ int caps = 0;
+ int index;
+ double intpart;
+ double fracpart;
+ double temp;
+
+ /*
+ * 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 = ' ';
+ }
+ }
+
+ /*
+ * Sorry, we only support 16 digits past the decimal because of our
+ * conversion method
+ */
+ if (max > 16)
+ max = 16;
+
+ /* We "cheat" by converting the fractional part to integer by
+ * multiplying by a factor of 10
+ */
+
+ temp = ufvalue;
+ my_modf(temp, &intpart);
+
+ fracpart = ROUND((POW10(max)) * (ufvalue - intpart));
+
+ if (fracpart >= POW10(max)) {
+ intpart++;
+ fracpart -= POW10(max);
+ }
+
+
+ /* Convert integer part */
+ do {
+ temp = intpart;
+ my_modf(intpart*0.1, &intpart);
+ temp = temp*0.1;
+ index = (int) ((temp -intpart +0.05)* 10.0);
+ /* index = (int) (((double)(temp*0.1) -intpart +0.05) *10.0); */
+ /* printf ("%llf, %f, %x\n", temp, intpart, index); */
+ iconvert[iplace++] =
+ (caps? "0123456789ABCDEF":"0123456789abcdef")[index];
+ } while (intpart && (iplace < 311));
+ if (iplace == 311) iplace--;
+ iconvert[iplace] = 0;
+
+ /* Convert fractional part */
+ if (fracpart)
+ {
+ do {
+ temp = fracpart;
+ my_modf(fracpart*0.1, &fracpart);
+ temp = temp*0.1;
+ index = (int) ((temp -fracpart +0.05)* 10.0);
+ /* index = (int) ((((temp/10) -fracpart) +0.05) *10); */
+ /* printf ("%lf, %lf, %ld\n", temp, fracpart, index); */
+ fconvert[fplace++] =
+ (caps? "0123456789ABCDEF":"0123456789abcdef")[index];
+ } while(fracpart && (fplace < 311));
+ if (fplace == 311) 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, char c)
+{
+ if (*currlen < maxlen) {
+ buffer[(*currlen)] = c;
+ }
+ (*currlen)++;
+}
+
+#if !defined(HAVE_VSNPRINTF)
+int
+vsnprintf (char *str, size_t count, const char *fmt, va_list args)
+{
+ return dopr(str, count, fmt, args);
+}
+#endif
+
+#if !defined(HAVE_SNPRINTF)
+#ifdef PROTOTYPES
+int
+snprintf(char *str, size_t count, const char *fmt, ...)
+#else
+int
+snprintf(str, count, fmt, va_alist)
+char *str;
+size_t count;
+const char *fmt;
+va_dcl
+#endif
+{
+ size_t ret;
+ va_list ap;
+
+ va_start(ap, fmt);
+ ret = vsnprintf(str, count, fmt, ap);
+ va_end(ap);
+ return ret;
+}
+#endif
+
+#endif
+
+/* -eof- */
diff --git a/deprecated-ngircd/src/portab/waitpid.c b/deprecated-ngircd/src/portab/waitpid.c
new file mode 100644
index 0000000..921dd3d
--- /dev/null
+++ b/deprecated-ngircd/src/portab/waitpid.c
@@ -0,0 +1,30 @@
+/*
+ * ngIRCd -- The Next Generation IRC Daemon
+ */
+
+#include "portab.h"
+
+/**
+ * @file
+ * waitpid() implementation. Public domain.
+ * Written by Steven D. Blackford for the NeXT system.
+ */
+
+#ifndef HAVE_WAITPID
+
+#include <string.h>
+#include <stdlib.h>
+#include <sys/types.h>
+
+GLOBAL int
+waitpid(pid, stat_loc, options)
+int pid, *stat_loc, options;
+{
+ for (;;) {
+ int wpid = wait(stat_loc);
+ if (wpid == pid || wpid == -1)
+ return wpid;
+ }
+}
+
+#endif
diff --git a/deprecated-ngircd/src/testsuite/Makefile.ng b/deprecated-ngircd/src/testsuite/Makefile.ng
new file mode 100644
index 0000000..f866e60
--- /dev/null
+++ b/deprecated-ngircd/src/testsuite/Makefile.ng
@@ -0,0 +1,143 @@
+#
+# ngIRCd -- The Next Generation IRC Daemon
+# Copyright (c)2001-2014 Alexander Barton (alex@barton.de) and Contributors
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+# Please read the file COPYING, README and AUTHORS for more information.
+#
+
+__ng_Makefile_am_template__
+
+AM_CPPFLAGS = -I$(srcdir)/../portab
+
+EXTRA_DIST = \
+ Makefile.ng README functions.inc getpid.sh \
+ start-server.sh stop-server.sh tests.sh stress-server.sh \
+ test-loop.sh wait-tests.sh \
+ channel-test.e connect-test.e check-idle.e invite-test.e \
+ join-test.e kick-test.e message-test.e misc-test.e mode-test.e \
+ opless-channel-test.e server-link-test.e who-test.e whois-test.e \
+ stress-A.e stress-B.e \
+ server-login-test.e \
+ start-server1 stop-server1 ngircd-test1.conf \
+ start-server2 stop-server2 ngircd-test2.conf \
+ start-server3 stop-server3 ngircd-test3.conf \
+ reload-server3 reload-server.sh prep-server3 cleanup-server3 switch-server3 \
+ connect-ssl-cert1-test.e connect-ssl-cert2-test.e \
+ ssl/cert-my-first-domain-tld.pem ssl/cert-my-second-domain-tld.pem \
+ ssl/dhparams-my-first-domain-tld.pem ssl/dhparams-my-second-domain-tld.pem \
+ ssl/key-my-first-domain-tld.pem ssl/key-my-second-domain-tld.pem
+
+all:
+
+clean-local:
+ rm -rf logs tests *-test ngircd-test*.log procs.tmp tests-skipped.lst \
+ T-ngircd1 ngircd-test1.motd T-ngircd2 ngircd-test2.motd T-ngircd3 ngircd-test3.motd
+
+maintainer-clean-local:
+ rm -f Makefile Makefile.in Makefile.am
+
+check_SCRIPTS = ngircd-TEST-Binary tests.sh
+
+ngircd-TEST-Binary:
+ cp ../ngircd/ngircd T-ngircd1
+ cp ../ngircd/ngircd T-ngircd2
+ cp ../ngircd/ngircd T-ngircd3
+ [ -f getpid.sh ] || ln -s $(srcdir)/getpid.sh .
+ rm -f tests-skipped.lst
+
+connect-test: tests.sh
+ rm -f connect-test
+ ln -s $(srcdir)/tests.sh connect-test
+
+connect-ssl-cert1-test: tests.sh
+ rm -f connect-ssl-cert1-test
+ ln -s $(srcdir)/tests.sh connect-ssl-cert1-test
+
+connect-ssl-cert2-test: tests.sh
+ rm -f connect-ssl-cert2-test
+ ln -s $(srcdir)/tests.sh connect-ssl-cert2-test
+
+channel-test: tests.sh
+ rm -f channel-test
+ ln -s $(srcdir)/tests.sh channel-test
+
+invite-test: tests.sh
+ rm -f invite-test
+ ln -s $(srcdir)/tests.sh invite-test
+
+join-test: tests.sh
+ rm -f join-test
+ ln -s $(srcdir)/tests.sh join-test
+
+kick-test: tests.sh
+ rm -f kick-test
+ ln -s $(srcdir)/tests.sh kick-test
+
+message-test: tests.sh
+ rm -f message-test
+ ln -s $(srcdir)/tests.sh message-test
+
+misc-test: tests.sh
+ rm -f misc-test
+ ln -s $(srcdir)/tests.sh misc-test
+
+mode-test: tests.sh
+ rm -f mode-test
+ ln -s $(srcdir)/tests.sh mode-test
+
+opless-channel-test: tests.sh
+ rm -f opless-channel-test
+ ln -s $(srcdir)/tests.sh opless-channel-test
+
+server-link-test: tests.sh
+ rm -f server-link-test
+ ln -s $(srcdir)/tests.sh server-link-test
+
+server-login-test: tests.sh
+ rm -f server-login-test
+ ln -s $(srcdir)/tests.sh server-login-test
+
+who-test: tests.sh
+ rm -f who-test
+ ln -s $(srcdir)/tests.sh who-test
+
+whois-test: tests.sh
+ rm -f whois-test
+ ln -s $(srcdir)/tests.sh whois-test
+
+TESTS = start-server1 \
+ connect-test \
+ start-server2 \
+ channel-test \
+ invite-test \
+ join-test \
+ kick-test \
+ message-test \
+ misc-test \
+ mode-test \
+ opless-channel-test \
+ who-test \
+ whois-test \
+ server-link-test \
+ server-login-test \
+ stop-server2 \
+ stress-server.sh \
+ stop-server1
+
+if HAVE_SSL
+TESTS += \
+ prep-server3 \
+ start-server3 \
+ connect-ssl-cert1-test \
+ switch-server3 \
+ reload-server3 \
+ connect-ssl-cert2-test \
+ cleanup-server3 \
+ stop-server3
+endif
+
+# -eof-
diff --git a/deprecated-ngircd/src/testsuite/README b/deprecated-ngircd/src/testsuite/README
new file mode 100644
index 0000000..33855fb
--- /dev/null
+++ b/deprecated-ngircd/src/testsuite/README
@@ -0,0 +1,100 @@
+
+ ngIRCd - Next Generation IRC Server
+
+ (c)2001-2008 Alexander Barton,
+ alex@barton.de, http://www.barton.de/
+
+ ngIRCd is free software and published under the
+ terms of the GNU General Public License.
+
+ -- README for the Test Suite --
+
+
+I. Overview
+~~~~~~~~~~~
+
+The purpose of the "test suite" contained in this directory is to detect
+bugs and incompatibilities in ngIRCd introduced during coding and after
+building ngIRCd on a specific platform.
+
+To run the "standard" tests call "make check" (which runs "make check" in
+all the source directories, testing the "portab" library as well for example)
+or "make testsuite" (which only runs the tests in this directory). Both will
+build ngIRCd (if required) and run some tests on it. These tests should be
+portable and run on all supported platforms without errors.
+
+NOTE #1: most tests of this suite depend on the external tools expect(1)
+and telnet(1), so make sure you have them installed. If not, the tests will
+not fail but simply be skipped.
+
+NOTE #2: the two test servers started by this test suite are configured to
+run on port 6789 and 6790; so it will fail if one or both of these ports
+are already used by some other daemons!
+
+
+II. Shell Scripts
+~~~~~~~~~~~~~~~~
+
+getpid.sh <name>
+
+ This script is used to detect the PID of the running process with
+ the given name in a portable manner. The result is echoed on the
+ console. It is a helper script for some other scripts of this suite.
+
+start-server.sh [<id>]
+
+ start-server.sh starts up the test binary, "T-ngircd<id>" (the default
+ for <id> is 1) with configuration file "ngircd-test<id>.conf" and the
+ console output redirected to "ngircd-test<id>.log".
+ The script first makes sure that getpid.sh is available and working,
+ and that no other instance of the test binary is already running.
+ The exit code is 0 if the test binary could be started.
+
+stop-server.sh [<id>]
+
+ This script uses getpid.sh to detect a running test binary
+ "T-ngircd<id>" and then shuts it down using the TERM signal.
+ The exit code is 0 if the test binary could be stopped.
+
+stress-server.sh [<clientCount> [<maxConcurrent>]]
+
+ stress-server.sh starts <clientCount> clients that "stress" the
+ running test server (id 1); but no more than <maxConcurrent> clients
+ are started at the same moment.
+
+tests.sh
+
+ Most of the tests scripts are symlinked to tests.sh, which in turn
+ uses expect(1) to run the respective script <name>.e and checks
+ its exit code.
+
+test-loop.sh [<loops> [<wait>]]
+
+ This script runs all the tests <loops> times (default: 5) and pauses
+ <wait> seconds (default: 5) between runs.
+ It isn't used by "make check" or "make testsuite".
+
+wait-tests.sh [<max>]
+
+ stress-server.sh uses this script to ensure that no more than <max>
+ clients are connected to the test server (id 1).
+
+
+III. Scripts for expect(1)
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+channel-test.e
+check-idle.e
+connect-test.e
+invite-test.e
+join-test.e
+kick-test.e
+message-test.e
+misc-test.e
+mode-test.e
+opless-channel-test.e
+server-link-test.e
+stress-A.e
+stress-B.e
+who-test.e
+whois-test.e
diff --git a/deprecated-ngircd/src/testsuite/channel-test.e b/deprecated-ngircd/src/testsuite/channel-test.e
new file mode 100644
index 0000000..5e0afab
--- /dev/null
+++ b/deprecated-ngircd/src/testsuite/channel-test.e
@@ -0,0 +1,107 @@
+# ngIRCd test suite
+# Channel test
+
+spawn telnet 127.0.0.1 6789
+expect {
+ timeout { exit 1 }
+ "Connected"
+}
+
+send "nick nick\r"
+send "user user . . :User\r"
+expect {
+ timeout { exit 1 }
+ "376"
+}
+
+send "join #channel\r"
+expect {
+ timeout { exit 1 }
+ "@* JOIN :#channel"
+}
+expect {
+ timeout { exit 1 }
+ "366"
+}
+
+send "topic #channel :Test-Topic\r"
+expect {
+ timeout { exit 1 }
+ "@* TOPIC #channel :Test-Topic"
+}
+
+send "who #channel\r"
+expect {
+ timeout { exit 1 }
+ "352 nick #channel"
+}
+expect {
+ timeout { exit 1 }
+ "* nick H@ :0 User"
+}
+expect {
+ timeout { exit 1 }
+ "315 nick #channel"
+}
+
+send "names #channel\r"
+expect {
+ timeout { exit 1 }
+ "353 nick = #channel :@nick"
+}
+expect {
+ timeout { exit 1 }
+ "366 nick #channel"
+}
+
+send "list\r"
+expect {
+ timeout { exit 1 }
+ "322 nick #channel 1 :Test-Topic"
+}
+expect {
+ timeout { exit 1 }
+ "323 nick :End of LIST"
+}
+
+send "part #channel :bye bye\r"
+expect {
+ timeout { exit 1 }
+ "@* PART #channel :bye bye"
+}
+
+send "join #channel\r"
+expect {
+ timeout { exit 1 }
+ "@* JOIN :#channel"
+}
+expect {
+ timeout { exit 1 }
+ "366"
+}
+
+send "join #channel2\r"
+expect {
+ timeout { exit 1 }
+ "@* JOIN :#channel2"
+}
+expect {
+ timeout { exit 1 }
+ "366"
+}
+
+send "join 0\r"
+expect {
+ timeout { exit 1 }
+ "@* PART #channel2 :"
+}
+expect {
+ timeout { exit 1 }
+ "@* PART #channel :"
+}
+
+send "quit\r"
+expect {
+ timeout { exit 1 }
+ "ERROR :Closing connection"
+}
diff --git a/deprecated-ngircd/src/testsuite/check-idle.e b/deprecated-ngircd/src/testsuite/check-idle.e
new file mode 100644
index 0000000..3c37e80
--- /dev/null
+++ b/deprecated-ngircd/src/testsuite/check-idle.e
@@ -0,0 +1,31 @@
+# ngIRCd test suite
+# Idle test
+
+spawn telnet 127.0.0.1 6789
+expect {
+ timeout { exit 1 }
+ "Connected"
+}
+
+send "nick IdleTest\r"
+send "user idle . . :Idle-Test\r"
+expect {
+ timeout { exit 1 }
+ "433 * IdleTest :Nickname already in use" { exit 99 }
+ "376"
+}
+
+send "lusers\r"
+expect {
+ timeout { exit 1 }
+ "251 IdleTest :There are 1 users and 0 services on 1 servers" { set r 0 }
+ "251 IdleTest :There are" { set r 99 }
+}
+
+send "quit\r"
+expect {
+ timeout { exit 1 }
+ "ERROR :Closing connection"
+}
+
+exit $r
diff --git a/deprecated-ngircd/src/testsuite/cleanup-server3 b/deprecated-ngircd/src/testsuite/cleanup-server3
new file mode 100755
index 0000000..a80fe73
--- /dev/null
+++ b/deprecated-ngircd/src/testsuite/cleanup-server3
@@ -0,0 +1,2 @@
+#!/bin/sh
+rm ssl/cert.pem ssl/key.pem ssl/dhparams.pem
diff --git a/deprecated-ngircd/src/testsuite/connect-ssl-cert1-test.e b/deprecated-ngircd/src/testsuite/connect-ssl-cert1-test.e
new file mode 100644
index 0000000..37abb76
--- /dev/null
+++ b/deprecated-ngircd/src/testsuite/connect-ssl-cert1-test.e
@@ -0,0 +1,21 @@
+# ngIRCd test suite
+# Server connect test
+
+spawn openssl s_client -quiet -connect 127.0.0.1:6790
+expect {
+ timeout { exit 1 }
+ "*CN*=*my.first.domain.tld"
+}
+
+sleep 2
+send "oper\r"
+expect {
+ timeout { exit 1 }
+ "451"
+}
+
+send "quit\r"
+expect {
+ timeout { exit 1 }
+ "ERROR :Closing connection"
+}
diff --git a/deprecated-ngircd/src/testsuite/connect-ssl-cert2-test.e b/deprecated-ngircd/src/testsuite/connect-ssl-cert2-test.e
new file mode 100644
index 0000000..0e67d75
--- /dev/null
+++ b/deprecated-ngircd/src/testsuite/connect-ssl-cert2-test.e
@@ -0,0 +1,21 @@
+# ngIRCd test suite
+# Server connect test
+
+spawn openssl s_client -quiet -connect 127.0.0.1:6790
+expect {
+ timeout { exit 1 }
+ "*CN*=*my.second.domain.tld"
+}
+
+sleep 2
+send "oper\r"
+expect {
+ timeout { exit 1 }
+ "451"
+}
+
+send "quit\r"
+expect {
+ timeout { exit 1 }
+ "ERROR :Closing connection"
+}
diff --git a/deprecated-ngircd/src/testsuite/connect-test.e b/deprecated-ngircd/src/testsuite/connect-test.e
new file mode 100644
index 0000000..f3015d8
--- /dev/null
+++ b/deprecated-ngircd/src/testsuite/connect-test.e
@@ -0,0 +1,20 @@
+# ngIRCd test suite
+# Server connect test
+
+spawn telnet 127.0.0.1 6789
+expect {
+ timeout { exit 1 }
+ "Connected"
+}
+
+send "oper\r"
+expect {
+ timeout { exit 1 }
+ "451"
+}
+
+send "quit\r"
+expect {
+ timeout { exit 1 }
+ "ERROR :Closing connection"
+}
diff --git a/deprecated-ngircd/src/testsuite/functions.inc b/deprecated-ngircd/src/testsuite/functions.inc
new file mode 100644
index 0000000..e03499e
--- /dev/null
+++ b/deprecated-ngircd/src/testsuite/functions.inc
@@ -0,0 +1,28 @@
+#!/bin/sh
+#
+# ngIRCd Test Suite
+# Copyright (c)2002-2004 by Alexander Barton (alex@barton.de)
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+# Please read the file COPYING, README and AUTHORS for more information.
+#
+# $Id: functions.inc,v 1.1 2004/09/06 22:04:06 alex Exp $
+#
+
+# test how to call echo to get output without newline
+echo -n | grep -- -n >/dev/null 2>&1
+if [ $? -eq 0 ]; then
+ ECHO_N=""; ECHO_C="\c"
+else
+ ECHO_N="-n"; ECHO_C=""
+fi
+
+echo_n()
+{
+ echo $ECHO_N "$*$ECHO_C"
+}
+
+# -eof-
diff --git a/deprecated-ngircd/src/testsuite/getpid.sh b/deprecated-ngircd/src/testsuite/getpid.sh
new file mode 100755
index 0000000..7a3dbe3
--- /dev/null
+++ b/deprecated-ngircd/src/testsuite/getpid.sh
@@ -0,0 +1,67 @@
+#!/bin/sh
+# ngIRCd Test Suite
+#
+# Try to detect the PID of a running process of the current user.
+#
+
+set -u
+
+# did we get a name?
+if [ $# -ne 1 ]; then
+ echo "Usage: $0 <name>" >&2
+ exit 1
+fi
+
+UNAME=`uname`
+
+# Use pgrep(1) whenever possible
+if [ -x /usr/bin/pgrep ]; then
+ case "$UNAME" in
+ "FreeBSD")
+ PGREP_FLAGS="-a"
+ ;;
+ *)
+ PGREP_FLAGS=""
+ esac
+ if [ -n "${LOGNAME:-}" ] || [ -n "${USER:-}" ]; then
+ # Try to narrow the search down to the current user ...
+ exec /usr/bin/pgrep $PGREP_FLAGS -n -u "${LOGNAME:-$USER}" "$1"
+ else
+ # ... but neither LOGNAME nor USER were set!
+ exec /usr/bin/pgrep $PGREP_FLAGS -n "$1"
+ fi
+fi
+
+# pidof(1) could be a good alternative on elder Linux systems
+if [ -x /bin/pidof ]; then
+ exec /bin/pidof -s "$1"
+fi
+
+# fall back to ps(1) and parse its output:
+# detect flags for "ps" and "head"
+PS_PIDCOL=1
+case "$UNAME" in
+ "A/UX"|"GNU"|"SunOS")
+ PS_FLAGS="-a"; PS_PIDCOL=2
+ ;;
+ "Haiku")
+ PS_FLAGS="-o Id -o Team"
+ ;;
+ *)
+ # Linux (GNU coreutils), Free/Net/OpenBSD, ...
+ PS_FLAGS="-o pid,comm"
+esac
+
+# search PID
+ps $PS_FLAGS >procs.tmp
+grep -v "$$" procs.tmp | grep "$1" | \
+ awk "{print \$$PS_PIDCOL}" | \
+ sort -nr >pids.tmp
+pid=`head -1 pids.tmp`
+rm -rf procs.tmp pids.tmp
+
+# validate PID
+[ "$pid" -gt 1 ] >/dev/null 2>&1 || exit 1
+
+echo $pid
+exit 0
diff --git a/deprecated-ngircd/src/testsuite/invite-test.e b/deprecated-ngircd/src/testsuite/invite-test.e
new file mode 100644
index 0000000..f3115a3
--- /dev/null
+++ b/deprecated-ngircd/src/testsuite/invite-test.e
@@ -0,0 +1,114 @@
+# ngIRCd test suite
+# INVITE test
+
+spawn telnet 127.0.0.1 6789
+expect {
+ timeout { exit 1 }
+ "Connected"
+}
+
+send "nick nick\r"
+send "user user . . :User\r"
+expect {
+ timeout { exit 1 }
+ "376"
+}
+
+send "invite\r"
+expect {
+ timeout { exit 1 }
+ "461"
+}
+
+send "invite nick\r"
+expect {
+ timeout { exit 1 }
+ "461"
+}
+
+send "invite nick #channel\r"
+expect {
+ timeout { exit 1 }
+ -re "INVITE nick :?#channel"
+}
+expect {
+ timeout { exit 1 }
+ -re "341 nick nick :?#channel"
+}
+
+send "invite nosuchnic #TopicChannel\r"
+expect {
+ timeout { exit 1 }
+ "401 nick nosuchnic :No such nick or channel name"
+}
+
+send "invite nick #TopicChannel\r"
+expect {
+ timeout { exit 1 }
+ "442 nick #TopicChannel :You are not on that channel"
+}
+
+send "join #channel\r"
+expect {
+ timeout { exit 1 }
+ -re "JOIN :?#channel"
+}
+
+send "invite nick #channel\r"
+expect {
+ timeout { exit 1 }
+ "443 nick nick #channel :is already on channel"
+}
+
+send "mode #channel +i\r"
+expect {
+ timeout { exit 1 }
+ "MODE #channel +i"
+}
+
+send "mode #channel -o nick\r"
+expect {
+ timeout { exit 1 }
+ "MODE #channel -o nick"
+}
+
+send "invite nick #channel\r"
+expect {
+ timeout { exit 1 }
+ "482 nick #channel :You are not channel operator"
+ #it would be reasonable to expect 443 here instead
+}
+
+send "part #channel\r"
+expect {
+ timeout { exit 1}
+ "@* PART #channel :"
+}
+
+send "invite nick :parameter with spaces\r"
+expect {
+ timeout { exit 1 }
+ "INVITE nick :parameter with spaces"
+}
+expect {
+ timeout { exit 1 }
+ "341 nick nick :parameter with spaces"
+}
+
+send "away message\r"
+expect {
+ timeout { exit 1 }
+ "306 nick :You have been marked as being away"
+}
+
+send "INVITE nick #channel\r"
+expect {
+ timeout { exit 1 }
+ -re "301 nick nick :?message"
+}
+
+send "quit\r"
+expect {
+ timeout { exit 1 }
+ "ERROR :Closing connection"
+}
diff --git a/deprecated-ngircd/src/testsuite/join-test.e b/deprecated-ngircd/src/testsuite/join-test.e
new file mode 100644
index 0000000..7e6a29a
--- /dev/null
+++ b/deprecated-ngircd/src/testsuite/join-test.e
@@ -0,0 +1,112 @@
+# ngIRCd test suite
+# JOIN test
+
+spawn telnet 127.0.0.1 6789
+expect {
+ timeout { exit 1 }
+ "Connected"
+}
+
+send "nick nick\r"
+send "user user . . :User\r"
+expect {
+ timeout { exit 1 }
+ "376"
+}
+
+send "JOIN\r"
+expect {
+ timeout { exit 1}
+ "461"
+}
+
+send "JOIN #InviteChannel\r"
+expect {
+ timeout { exit 1 }
+ "473"
+}
+
+send "JOIN #FullKeyed\r"
+expect {
+ timeout { exit 1 }
+ "475"
+}
+
+send "JOIN #FullKeyed WrongKey\r"
+expect {
+ timeout { exit 1 }
+ "475"
+}
+
+send "JOIN #FullKeyed Secret\r"
+expect {
+ timeout { exit 1 }
+ "471"
+}
+
+send "JOIN #TopicChannel\r"
+expect {
+ timeout { exit 1 }
+ "@* JOIN :#TopicChannel"
+}
+expect {
+ timeout { exit 1 }
+ "332"
+}
+
+send "JOIN 0\r"
+send "JOIN #1,#2,#3,#4\r"
+send "JOIN #5\r"
+expect {
+ timeout { exit 1 }
+ "405"
+}
+send "JOIN 0\r"
+
+send "JoIn #MultiMode\r"
+expect {
+ timeout { exit 1 }
+ "474 nick #MultiMode"
+}
+
+send "OPer TestOp 123\r"
+expect {
+ timeout { exit 1 }
+ "381"
+}
+
+send "Mode #MultiMode -b nick!~user\r"
+expect {
+ timeout { exit 1 }
+ "MODE #MultiMode -b nick!~user@*"
+}
+
+send "jOiN #MULTIMODE\r"
+expect {
+ timeout { exit 1 }
+ "@* JOIN :#MULTIMODE"
+}
+expect {
+ timeout { exit 1 }
+ "366"
+}
+send "ModE #MULTImode\r"
+expect {
+ timeout { exit 1 }
+ "324 nick #MultiMode +Pnt"
+}
+send "mODe #multimode +b\r"
+expect {
+ timeout { exit 1 }
+ "367 nick #MultiMode banned!~ghost@example.com ngircd.test.server"
+}
+expect {
+ timeout { exit 1 }
+ "368 nick #MultiMode"
+}
+
+send "quit\r"
+expect {
+ timeout { exit 1 }
+ "ERROR :Closing connection"
+}
diff --git a/deprecated-ngircd/src/testsuite/kick-test.e b/deprecated-ngircd/src/testsuite/kick-test.e
new file mode 100644
index 0000000..a803879
--- /dev/null
+++ b/deprecated-ngircd/src/testsuite/kick-test.e
@@ -0,0 +1,113 @@
+# ngIRCd test suite
+# KICK test
+
+spawn telnet 127.0.0.1 6789
+expect {
+ timeout { exit 1 }
+ "Connected"
+}
+
+send "nick nick\r"
+send "user user . . :User\r"
+expect {
+ timeout { exit 1 }
+ "376"
+}
+
+send "kick #Channel nick\r"
+expect {
+ timeout { exit 1 }
+ "403"
+}
+
+send "join #Channel\r"
+
+send "kick #Channel nick\r"
+expect {
+ timeout { exit 1 }
+ "@* KICK #Channel nick :nick"
+}
+
+send "join #Channel\r"
+
+send "kick #Channel nick :reason\r"
+expect {
+ timeout { exit 1 }
+ "@* KICK #Channel nick :reason"
+}
+
+send "join #Channel,#Channel2\r"
+
+send "kick #Channel,#Channel2 nick\r"
+expect {
+ timeout { exit 1 }
+ "461"
+}
+
+send "kick #Channel,#Channel2,#NoExists,#NoExists nick1,nick,nick3,nick :reason\r"
+expect {
+ timeout { exit 1 }
+ "401"
+}
+expect {
+ timeout { exit 1 }
+ "@* KICK #Channel2 nick :reason"
+}
+expect {
+ timeout { exit 1 }
+ "401"
+}
+expect {
+ timeout { exit 1 }
+ "403"
+}
+
+send "kick #Channel nick2,nick,nick3\r"
+expect {
+ timeout { exit 1 }
+ "401"
+}
+expect {
+ timeout { exit 1 }
+ "@* KICK #Channel nick :nick"
+}
+expect {
+ timeout { exit 1 }
+ "401"
+}
+
+send "kick #Channel ,,\r"
+expect {
+ timeout { exit 1 }
+ "401"
+}
+expect {
+ timeout { exit 1 }
+ "401"
+}
+
+send "kick ,, ,,,\r"
+expect {
+ timeout { exit 1 }
+ "461"
+}
+
+send "kick ,, ,,\r"
+expect {
+ timeout { exit 1 }
+ "401"
+}
+expect {
+ timeout { exit 1 }
+ "401"
+}
+expect {
+ timeout { exit 1 }
+ "401"
+}
+
+send "quit\r"
+expect {
+ timeout { exit 1 }
+ "ERROR :Closing connection"
+}
diff --git a/deprecated-ngircd/src/testsuite/message-test.e b/deprecated-ngircd/src/testsuite/message-test.e
new file mode 100644
index 0000000..28d4a93
--- /dev/null
+++ b/deprecated-ngircd/src/testsuite/message-test.e
@@ -0,0 +1,152 @@
+# ngIRCd test suite
+# PRIVMSG and NOTICE test
+
+spawn telnet 127.0.0.1 6789
+expect {
+ timeout { exit 1 }
+ "Connected"
+}
+
+send "nick nick\r"
+send "user user . . :User\r"
+expect {
+ timeout { exit 1 }
+ "376"
+}
+
+send "privmsg nick :test\r"
+expect {
+ timeout { exit 1 }
+ "@* PRIVMSG nick :test"
+}
+
+send "privmsg nick\r"
+expect {
+ timeout { exit 1 }
+ "412"
+}
+
+send "privmsg\r"
+expect {
+ timeout { exit 1 }
+ "411"
+}
+
+send "privmsg nick,nick :test\r"
+expect {
+ timeout { exit 1 }
+ "@* PRIVMSG nick :test"
+}
+
+send "privmsg ,,,, :dummy\r"
+send "privmsg ,,,nick,,&server,,, :test\r"
+expect {
+ timeout { exit 1 }
+ "@* PRIVMSG nick :test"
+}
+expect {
+ timeout { exit 1 }
+ "404"
+}
+
+send "privmsg Nick,#testChannel,nick :test\r"
+expect {
+ timeout { exit 1 }
+ "@* PRIVMSG nick :test\r*401"
+}
+
+send "privmsg doesnotexist :test\r"
+expect {
+ timeout { exit 1 }
+ "401"
+}
+
+send "privmsg ~UsEr@ngIRCd.Test.Server :test\r"
+expect {
+ timeout { exit 1 }
+ "@* PRIVMSG nick :test"
+}
+
+send "mode nick +b\r"
+expect {
+ timeout { exit 1 }
+ "MODE nick :+b"
+}
+send "privmsg nick :test\r"
+expect {
+ timeout { exit 1 }
+ "486"
+}
+send "mode nick -b\r"
+expect {
+ timeout { exit 1 }
+ "MODE nick :-b"
+}
+
+send "privmsg ~user\%127.0.0.1 :test\r"
+expect {
+ timeout { exit 1 }
+ "@* PRIVMSG nick :test"
+}
+
+send "privmsg Nick!~User@127.0.0.1 :test\r"
+expect {
+ timeout { exit 1 }
+ "@* PRIVMSG nick :test"
+}
+
+send "away :away\r"
+expect {
+ timeout { exit 1 }
+ "306"
+}
+
+send "privmsg nick :test\r"
+expect {
+ timeout { exit 1 }
+ "301"
+}
+
+send "away\r"
+expect {
+ timeout { exit 1 }
+ "305"
+}
+
+send "privmsg \$ngircd.test.server :test\r"
+expect {
+ timeout { exit 1 }
+ "481"
+}
+
+send "privmsg #*.de :test\r"
+expect {
+ timeout { exit 1 }
+ "481"
+}
+
+send "oper TestOp 123\r"
+
+send "privmsg \$ngircd.test.server :test\r"
+expect {
+ timeout { exit 1 }
+ "@* PRIVMSG nick :test"
+}
+
+send "privmsg \$*.test*.server :test\r"
+expect {
+ timeout { exit 1 }
+ "@* PRIVMSG nick :test"
+}
+
+send "privmsg \$noDotServer :test\r"
+expect {
+ timeout { exit 1 }
+ "401"
+}
+
+send "quit\r"
+expect {
+ timeout { exit 1 }
+ "ERROR :Closing connection"
+}
diff --git a/deprecated-ngircd/src/testsuite/misc-test.e b/deprecated-ngircd/src/testsuite/misc-test.e
new file mode 100644
index 0000000..8896624
--- /dev/null
+++ b/deprecated-ngircd/src/testsuite/misc-test.e
@@ -0,0 +1,164 @@
+# ngIRCd test suite
+# Misc test
+
+spawn telnet 127.0.0.1 6789
+expect {
+ timeout { exit 1 }
+ "Connected"
+}
+
+send "nick nick\r"
+send "user user . . :User\r"
+expect {
+ timeout { exit 1 }
+ "376"
+}
+
+# RFC 2812 Section 3.4.1
+
+send "motd\r"
+expect {
+ timeout { exit 1 }
+ "375"
+}
+expect {
+ timeout { exit 1 }
+ "372"
+}
+expect {
+ timeout { exit 1 }
+ "376"
+}
+
+send "motd ngircd.test.server\r"
+expect {
+ timeout { exit 1 }
+ "375"
+}
+expect {
+ timeout { exit 1 }
+ "372"
+}
+expect {
+ timeout { exit 1 }
+ "376"
+}
+
+send "motd doesnotexist\r"
+expect {
+ timeout { exit 1 }
+ "402"
+# note this is not specified in RFC 2812, but probably should be
+}
+
+# RFC 2812 Section 3.4.3
+
+send "version\r"
+expect {
+ timeout { exit 1 }
+ "351"
+}
+
+send "version ngircd.test.server\r"
+expect {
+ timeout { exit 1 }
+ "351"
+}
+
+send "version doesnotexist\r"
+expect {
+ timeout { exit 1 }
+ "402"
+}
+
+# RFC 2812 Section 3.4.6
+
+send "time\r"
+expect {
+ timeout { exit 1 }
+ "391"
+}
+
+send "time ngircd.test.server\r"
+expect {
+ timeout { exit 1 }
+ "391"
+}
+
+send "time doesnotexist\r"
+expect {
+ timeout { exit 1 }
+ "402"
+}
+
+# RFC 2812 Section 3.4.10
+
+send "info\r"
+expect {
+ timeout { exit 1 }
+ "371"
+}
+expect {
+ timeout { exit 1 }
+ "374"
+}
+
+# RFC 2812 Section 4.5
+
+send "summon\r"
+expect {
+ timeout { exit 1 }
+ "445"
+}
+
+# RFC 2812 Section 4.6
+
+send "users\r"
+expect {
+ timeout { exit 1 }
+ "446"
+}
+
+# RFC 2812 Section 4.8
+
+send "userhost\r"
+expect {
+ timeout { exit 1 }
+ "461"
+}
+
+send "userhost nick\r"
+expect {
+ timeout { exit 1 }
+ -re ":ngircd.test.server 302 nick :?nick=+.*@127.0.0.1"
+}
+
+send "userhost doesnotexist\r"
+expect {
+ timeout { exit 1 }
+ ":ngircd.test.server 302 nick :\r"
+}
+
+send "userhost nick doesnotexist nick doesnotexist\r"
+expect {
+ timeout { exit 1 }
+ -re ":ngircd.test.server 302 nick :nick=+.*@127.0.0.1 nick=+.*@127.0.0.1"
+}
+
+send "away :testing\r"
+expect {
+ timeout { exit 1 }
+ "306 nick"
+}
+
+send "userhost nick nick nick nick nick nick\r"
+expect {
+ timeout { exit 1 }
+ -re ":ngircd.test.server 302 nick :nick=-.*@127.0.0.1 nick=-.*@127.0.0.1 nick=-.*@127.0.0.1 nick=-.*@127.0.0.1 nick=-.*@127.0.0.1\r"
+}
+
+send "quit\r"
+expect {
+ timeout { exit 1 }
+ "ERROR :Closing connection"
+}
diff --git a/deprecated-ngircd/src/testsuite/mode-test.e b/deprecated-ngircd/src/testsuite/mode-test.e
new file mode 100644
index 0000000..668e57c
--- /dev/null
+++ b/deprecated-ngircd/src/testsuite/mode-test.e
@@ -0,0 +1,175 @@
+# ngIRCd test suite
+# MODE test
+
+spawn telnet 127.0.0.1 6789
+expect {
+ timeout { exit 1 }
+ "Connected"
+}
+
+send "nick nick\r"
+send "user user . . :User\r"
+expect {
+ timeout { exit 1 }
+ "376"
+}
+
+send "mode nick +i\r"
+expect {
+ timeout { exit 1 }
+ "@* MODE nick :+i"
+}
+
+send "mode nick\r"
+expect {
+ timeout { exit 1 }
+ "221 nick +i"
+}
+
+send "mode nick -i\r"
+expect {
+ timeout { exit 1 }
+ "@* MODE nick :-i"
+}
+
+send "join #usermode\r"
+expect {
+ timeout { exit 1 }
+ "@* JOIN :#usermode"
+}
+expect {
+ timeout { exit 1 }
+ "366"
+}
+
+send "mode #usermode +v nick\r"
+expect {
+ timeout { exit 1 }
+ "@* MODE #usermode +v nick\r"
+}
+
+send "mode #usermode +h nick\r"
+expect {
+ timeout { exit 1 }
+ "@* MODE #usermode +h nick\r"
+}
+
+send "mode #usermode +a nick\r"
+expect {
+ timeout { exit 1 }
+ "482 nick"
+}
+
+send "mode #usermode +q nick\r"
+expect {
+ timeout { exit 1 }
+ "482 nick"
+}
+
+send "mode #usermode -vho nick nick nick\r"
+expect {
+ timeout { exit 1 }
+ "@* MODE #usermode -vho nick nick nick"
+}
+
+send "oper TestOp 123\r"
+expect {
+ timeout { exit 1 }
+ "MODE nick :+o"
+}
+expect {
+ timeout { exit 1 }
+ "381 nick"
+}
+
+send "mode nick\r"
+expect {
+ timeout { exit 1 }
+ "221 nick +o"
+}
+
+send "mode #usermode +a nick\r"
+expect {
+ timeout { exit 1 }
+ "@* MODE #usermode +a nick"
+}
+
+send "mode #usermode +q nick\r"
+expect {
+ timeout { exit 1 }
+ "@* MODE #usermode +q nick"
+}
+
+send "names #usermode\r"
+expect {
+ timeout { exit 1 }
+ "353 nick = #usermode :~nick"
+}
+expect {
+ timeout { exit 1 }
+ "366 nick #usermode"
+}
+
+send "part #usermode\r"
+expect {
+ timeout { exit 1 }
+ "@* PART #usermode"
+}
+
+send "join #channel\r"
+expect {
+ timeout { exit 1 }
+ "@* JOIN :#channel"
+}
+expect {
+ timeout { exit 1 }
+ "366"
+}
+
+send "mode #channel +tn\r"
+expect {
+ timeout { exit 1 }
+ "@* MODE #channel +tn"
+}
+
+send "mode #channel\r"
+expect {
+ timeout { exit 1 }
+ "324 nick #channel +tn"
+}
+
+send "mode #channel +v nick\r"
+expect {
+ timeout { exit 1 }
+ "@* MODE #channel +v nick\r"
+}
+
+send "mode #channel +I nick1\r"
+expect {
+ timeout { exit 1 }
+ "@* MODE #channel +I nick1!*@*"
+}
+
+send "mode #channel +b nick2@domain\r"
+expect {
+ timeout { exit 1 }
+ "@* MODE #channel +b nick2!*@domain"
+}
+
+send "mode #channel +I nick3!user\r"
+expect {
+ timeout { exit 1 }
+ "@* MODE #channel +I nick3!user@*"
+}
+
+send "mode #channel -vo nick nick\r"
+expect {
+ timeout { exit 1 }
+ "@* MODE #channel -vo nick nick\r"
+}
+
+send "quit\r"
+expect {
+ timeout { exit 1 }
+ "ERROR :Closing connection"
+}
diff --git a/deprecated-ngircd/src/testsuite/ngircd-test1.conf b/deprecated-ngircd/src/testsuite/ngircd-test1.conf
new file mode 100644
index 0000000..233238a
--- /dev/null
+++ b/deprecated-ngircd/src/testsuite/ngircd-test1.conf
@@ -0,0 +1,72 @@
+# ngIRCd test suite
+# configuration file for test server #1
+
+[Global]
+ Name = ngircd.test.server
+ Info = ngIRCd Test-Server 1
+ Listen = 127.0.0.1
+ Ports = 6789
+ MotdFile = ngircd-test1.motd
+ AdminEMail = admin@irc.server
+
+[Limits]
+ MaxConnectionsIP = 0
+ MaxJoins = 4
+ MaxPenaltyTime = 1
+
+[Options]
+ OperCanUseMode = yes
+ Ident = no
+ IncludeDir = /var/empty
+ DNS = no
+ PAM = no
+
+[Operator]
+ Name = TestOp
+ Password = 123
+
+[Server]
+ Name = ngircd.test.server2
+ MyPassword = pwd1
+ PeerPassword = pwd2
+
+[Server]
+ Name = ngircd.test.server3
+ MyPassword = pwd1
+ PeerPassword = pwd3
+
+[Channel]
+ Name = InviteChannel
+ Modes = i
+
+[Channel]
+ Name = #FullKeyed
+ Modes = lk
+ MaxUsers = 0
+ Key = Secret
+
+[Channel]
+ Name = #TopicChannel
+ Modes = t
+ Topic = the topic
+
+[Channel]
+ Name = #SecretChannel
+ Modes = s
+ Topic = A secret Channel
+
+[Channel]
+ Name = &LocalChannel
+ Topic = A local Channel
+
+[Channel]
+ Name = +ModelessChannel
+ Topic = A modeless Channel
+
+[Channel]
+ Name = MultiMode
+ Modes = +n +b nick!~user
+ Modes = +t
+ Modes = +b banned!~ghost@example.com
+
+# -eof-
diff --git a/deprecated-ngircd/src/testsuite/ngircd-test2.conf b/deprecated-ngircd/src/testsuite/ngircd-test2.conf
new file mode 100644
index 0000000..40d881d
--- /dev/null
+++ b/deprecated-ngircd/src/testsuite/ngircd-test2.conf
@@ -0,0 +1,35 @@
+# ngIRCd test suite
+# configuration file for test server #2
+
+[Global]
+ Name = ngircd.test.server2
+ Info = ngIRCd Test-Server 2
+ Listen = 127.0.0.1
+ Ports = 6790
+ MotdFile = ngircd-test2.motd
+ AdminEMail = admin@irc.server2
+
+[Limits]
+ MaxConnectionsIP = 0
+ MaxJoins = 4
+ MaxPenaltyTime = 1
+
+[Options]
+ OperCanUseMode = yes
+ Ident = no
+ IncludeDir = /var/empty
+ DNS = no
+ PAM = no
+
+[Operator]
+ Name = TestOp
+ Password = 123
+
+[Server]
+ Name = ngircd.test.server
+ Host = 127.0.0.1
+ Port = 6789
+ MyPassword = pwd2
+ PeerPassword = pwd1
+
+# -eof-
diff --git a/deprecated-ngircd/src/testsuite/ngircd-test3.conf b/deprecated-ngircd/src/testsuite/ngircd-test3.conf
new file mode 100644
index 0000000..1117e37
--- /dev/null
+++ b/deprecated-ngircd/src/testsuite/ngircd-test3.conf
@@ -0,0 +1,31 @@
+# ngIRCd test suite
+# configuration file for test server #1
+
+[Global]
+ Name = ngircd.test.server
+ Info = ngIRCd Test-Server 3
+ Listen = 127.0.0.1
+ Ports = 6789
+ MotdFile = ngircd-test3.motd
+ AdminEMail = admin@irc.server
+
+[SSL]
+ CertFile = ssl/cert.pem
+ KeyFile = ssl/key.pem
+ DHFile = ssl/dhparams.pem
+ Ports = 6790
+
+
+[Limits]
+ MaxConnectionsIP = 0
+ MaxJoins = 4
+ MaxPenaltyTime = 1
+
+[Options]
+ OperCanUseMode = yes
+ Ident = no
+ IncludeDir = /var/empty
+ DNS = no
+ PAM = no
+
+# -eof-
diff --git a/deprecated-ngircd/src/testsuite/opless-channel-test.e b/deprecated-ngircd/src/testsuite/opless-channel-test.e
new file mode 100644
index 0000000..cd4f9a0
--- /dev/null
+++ b/deprecated-ngircd/src/testsuite/opless-channel-test.e
@@ -0,0 +1,33 @@
+# ngIRCd test suite
+# Op-less channel test
+
+spawn telnet 127.0.0.1 6789
+expect {
+ timeout { exit 1 }
+ "Connected"
+}
+
+send "nick nick\r"
+send "user user . . :User\r"
+expect {
+ timeout { exit 1 }
+ "376"
+}
+
+send "JOIN +Channel\r"
+expect {
+ timeout { exit 1 }
+ "@* JOIN :+Channel"
+}
+
+send "mode +Channel +t\r"
+expect {
+ timeout { exit 1 }
+ "477"
+}
+
+send "quit\r"
+expect {
+ timeout { exit 1 }
+ "ERROR :Closing connection"
+}
diff --git a/deprecated-ngircd/src/testsuite/prep-server3 b/deprecated-ngircd/src/testsuite/prep-server3
new file mode 100755
index 0000000..c76b250
--- /dev/null
+++ b/deprecated-ngircd/src/testsuite/prep-server3
@@ -0,0 +1,7 @@
+#!/bin/sh -e
+[ -z "$srcdir" ] && srcdir=`dirname "$0"`
+set -eu
+mkdir -p ssl
+cp "${srcdir}"/ssl/cert-my-first-domain-tld.pem ssl/cert.pem
+cp "${srcdir}"/ssl/key-my-first-domain-tld.pem ssl/key.pem
+cp "${srcdir}"/ssl/dhparams-my-first-domain-tld.pem ssl/dhparams.pem
diff --git a/deprecated-ngircd/src/testsuite/reload-server.sh b/deprecated-ngircd/src/testsuite/reload-server.sh
new file mode 100755
index 0000000..8d6fd2b
--- /dev/null
+++ b/deprecated-ngircd/src/testsuite/reload-server.sh
@@ -0,0 +1,31 @@
+#!/bin/sh
+# ngIRCd Test Suite
+
+[ -z "$srcdir" ] && srcdir=`dirname "$0"`
+set -u
+
+# read in functions
+. "${srcdir}/functions.inc"
+
+if [ -n "$1" ]; then
+ id="$1"; shift
+else
+ id="1"
+fi
+
+echo_n "reloading server ${id} ..."
+
+# reload (sighup) test-server ...
+pid=`./getpid.sh T-ngircd${id}`
+if [ -z "$pid" ]; then
+ echo " failure: no running server found!?"
+ exit 1
+fi
+kill -HUP $pid >/dev/null 2>&1; r=$?
+if [ $r -eq 0 ]; then
+ sleep 2
+ echo " ok".
+ kill -0 $pid && exit 0
+fi
+echo " failure: server ${id} could not be reloaded!"
+exit 1
diff --git a/deprecated-ngircd/src/testsuite/reload-server3 b/deprecated-ngircd/src/testsuite/reload-server3
new file mode 100755
index 0000000..da7b37e
--- /dev/null
+++ b/deprecated-ngircd/src/testsuite/reload-server3
@@ -0,0 +1,7 @@
+#!/bin/sh
+# ngIRCd Test Suite
+
+[ -z "$srcdir" ] && srcdir=`dirname $0`
+${srcdir}/reload-server.sh 3
+
+# -eof-
diff --git a/deprecated-ngircd/src/testsuite/server-link-test.e b/deprecated-ngircd/src/testsuite/server-link-test.e
new file mode 100644
index 0000000..48230af
--- /dev/null
+++ b/deprecated-ngircd/src/testsuite/server-link-test.e
@@ -0,0 +1,50 @@
+# ngIRCd test suite
+# server-server link test
+
+spawn telnet 127.0.0.1 6790
+expect {
+ timeout { exit 1 }
+ "Connected"
+}
+
+send "nick nick\r"
+send "user user . . :User\r"
+expect {
+ timeout { exit 1 }
+ "376"
+}
+
+send "version ngircd.test.server2\r"
+expect {
+ timeout { exit 1 }
+ ":ngircd.test.server2 351"
+}
+send "version ngircd.test.server\r"
+expect {
+ timeout { exit 1 }
+ ":ngircd.test.server 351"
+}
+
+send "whois ngircd.test.server nick\r"
+expect {
+ timeout { exit 1 }
+ ":ngircd.test.server 318"
+}
+
+send "admin ngircd.test.server\r"
+expect {
+ timeout { exit 1 }
+ ":ngircd.test.server 259 nick :admin@irc.server"
+}
+
+send "links\r"
+expect {
+ timeout { exit 1 }
+ "364 nick ngircd.test.server ngircd.test.server2 :1"
+}
+
+send "quit\r"
+expect {
+ timeout { exit 1 }
+ "ERROR :Closing connection"
+}
diff --git a/deprecated-ngircd/src/testsuite/server-login-test.e b/deprecated-ngircd/src/testsuite/server-login-test.e
new file mode 100644
index 0000000..bdf95e0
--- /dev/null
+++ b/deprecated-ngircd/src/testsuite/server-login-test.e
@@ -0,0 +1,94 @@
+# ngIRCd test suite
+# server-server login test
+
+spawn telnet 127.0.0.1 6789
+expect {
+ timeout { exit 1 }
+ "Connected"
+}
+
+# Register server
+send "PASS pwd1 0210-IRC+ ngIRCd|testsuite0:CHLMSX P\r"
+send "SERVER ngircd.test.server3 :Testsuite Server Emulation\r"
+expect {
+ timeout { exit 1 }
+ ":ngircd.test.server PASS pwd3 0210-IRC+ ngIRCd|"
+}
+expect {
+ timeout { exit 1 }
+ ":ngircd.test.server SERVER ngircd.test.server 1 :"
+}
+expect {
+ timeout { exit 1 }
+ ":ngircd.test.server 005 "
+}
+expect {
+ timeout { exit 1 }
+ ":ngircd.test.server 376 "
+}
+
+# End of handshake
+send ":ngircd.test.server3 376 ngircd.test.server :End of MOTD command\r"
+
+# Receive existing channels
+expect {
+ timeout { exit 1 }
+ ":ngircd.test.server CHANINFO +ModelessChannel +P :A modeless Channel"
+}
+expect {
+ timeout { exit 1 }
+ ":ngircd.test.server CHANINFO #SecretChannel +Ps :A secret Channel"
+}
+expect {
+ timeout { exit 1 }
+ ":ngircd.test.server CHANINFO #TopicChannel +Pt :the topic"
+}
+expect {
+ timeout { exit 1 }
+ ":ngircd.test.server CHANINFO #FullKeyed +Pkl Secret 0 :"
+}
+expect {
+ timeout { exit 1 }
+ ":ngircd.test.server CHANINFO #InviteChannel +Pi"
+}
+expect {
+ timeout { exit 1 }
+ ":ngircd.test.server PING :ngircd.test.server"
+}
+
+# Emulate network burst
+send ":ngircd.test.server3 NICK NickName 1 ~User localhost 1 + :Real Name\r"
+send ":ngircd.test.server3 NJOIN #Channel :@NickName\r"
+
+# End of burst
+send ":ngircd.test.server3 PONG :ngircd.test.server\r"
+
+# Test server-server link ...
+send ":ngircd.test.server3 VERSION\r"
+expect {
+ timeout { exit 1 }
+ ":ngircd.test.server 351 ngircd.test.server3 "
+}
+
+# Make sure our test client is still known in the network
+send ":ngircd.test.server3 WHOIS NickName\r"
+expect {
+ timeout { exit 1 }
+ ":ngircd.test.server 311 ngircd.test.server3 NickName ~User localhost * :Real Name"
+}
+expect {
+ timeout { exit 1 }
+ ":ngircd.test.server 319 ngircd.test.server3 NickName :@#Channel"
+}
+
+expect {
+ timeout { exit 1 }
+ ":ngircd.test.server 318 ngircd.test.server3 NickName :"
+}
+
+# Logout
+send ":ngircd.test.server3 QUIT\r"
+expect {
+ timeout { exit 1 }
+ "ERROR :Closing connection"
+}
diff --git a/deprecated-ngircd/src/testsuite/ssl/cert-my-first-domain-tld.pem b/deprecated-ngircd/src/testsuite/ssl/cert-my-first-domain-tld.pem
new file mode 100644
index 0000000..1b3961d
--- /dev/null
+++ b/deprecated-ngircd/src/testsuite/ssl/cert-my-first-domain-tld.pem
@@ -0,0 +1,24 @@
+-----BEGIN CERTIFICATE-----
+MIIEDDCCAnSgAwIBAgIBATANBgkqhkiG9w0BAQsFADAeMRwwGgYDVQQDExNteS5m
+aXJzdC5kb21haW4udGxkMB4XDTIwMDQyNDA4MjQyNVoXDTQ3MDkxMDA4MjQyNVow
+HjEcMBoGA1UEAxMTbXkuZmlyc3QuZG9tYWluLnRsZDCCAaIwDQYJKoZIhvcNAQEB
+BQADggGPADCCAYoCggGBAJ3HvAIDQxL/o7yoemMH5OZEXyFTQ/Q838UY0lXbWBb0
+Lsz9ft0UFtu/SSabHLLJHQME99IyleYiMwi0Y3oqDCVZp6eqeKS7MTRIot2D1m4T
+QsK13dAvZOaEYPsltdsFDCP75s07tDp9aYYsHDsNhHu8LxUachmb3747/v1E1TGZ
+T5BSnzGxEsQo1vzKKMpMbjct1d3zdQRB1o/r6BlaPykTAaB1DkM7GOOdtprhO/Sh
+PbfXL+BHgldPbxboul7NTt1r2CfqFmz4Pi4PbCruv0HVG8N8egN6Jb80UuwOiCcM
+BxY9uhCh6ZPoZ9ufmGALhkgD0rlt/sQfKQ0EImzx8cC/6zvSfJQ0WazLp/wCImkP
+QZwKm/U6RMHWtthHg4pJRsYF5rL2+YMqebTcG655+fgQm9EI+ZcAqWIbnogGA046
+oS1X7805ogBo7OPMlJ19NjxOc3yS9dXlk6hEe0AKSCCusy4lI4gcGd2gwmAtXp3i
+ZVkFBsUsmBe3x5sEAEVVyQIDAQABo1UwUzAMBgNVHRMBAf8EAjAAMBMGA1UdJQQM
+MAoGCCsGAQUFBwMBMA8GA1UdDwEB/wQFAwMHoAAwHQYDVR0OBBYEFFst+QAEUdCP
+V80/hmOEBKtjOMRLMA0GCSqGSIb3DQEBCwUAA4IBgQCOEIJgi0H1lc33dU8Na4//
+CI3rOOYwFnSiiUe8A5n38LsU2ZrwwJmn60JgNdAmrNkXTI8qNTuTU6XIOAqq32FY
+wdNqPt7wE7UDRMQeMDlLNo+lnuI1XrBxk9mEpfmyGeGqeIDIr5vlEWs4Snr73RC0
+iQBUD6qGdhZa/ABm342psSA4OxtjCn6mBBT/gSi8yCO0Po8yFvndGMe3kNQFwir4
+supxptzqFDCDOQOYSgUy2QT7wlFAqPdZWMSepdeoaBYrqBsvf9shWC0iChKJxnCp
+SVZpoPysxuVyQMKjjzTJcNDwydMyIny4Z9rt+kkvgn/JDxIQe1+jJ8dJR+VWQeNe
+we604uEsN0hWq1FkkMO8NQdbM4xipDciEanHunWvwFkXuIuc0aEpqIchU32O2wav
+ck8ytssLLQDGaJLHx6iOB2MCi8HbS8U9xfrg8JJIFnxmnkKdI6x2akzYm+nqDxqQ
+dGeoVJgegiamYlydkGskw04oGkD16H0LQwlzsDwgvP8=
+-----END CERTIFICATE-----
diff --git a/deprecated-ngircd/src/testsuite/ssl/cert-my-second-domain-tld.pem b/deprecated-ngircd/src/testsuite/ssl/cert-my-second-domain-tld.pem
new file mode 100644
index 0000000..f8d8985
--- /dev/null
+++ b/deprecated-ngircd/src/testsuite/ssl/cert-my-second-domain-tld.pem
@@ -0,0 +1,24 @@
+-----BEGIN CERTIFICATE-----
+MIIEDjCCAnagAwIBAgIBATANBgkqhkiG9w0BAQsFADAfMR0wGwYDVQQDExRteS5z
+ZWNvbmQuZG9tYWluLnRsZDAeFw0yMDA0MjQwODIzNDBaFw00NzA5MTAwODIzNDBa
+MB8xHTAbBgNVBAMTFG15LnNlY29uZC5kb21haW4udGxkMIIBojANBgkqhkiG9w0B
+AQEFAAOCAY8AMIIBigKCAYEA4+442scsdqSf6O4UO/RskMzOX8BhDcSwrhGe97jd
+CuQKUqS6OT1UoHK0DdMkxHlOMhifPzKxoBQlI/02l14tV//xNArKj4a+BZzNS1mp
+3adjgTc3uRDQHmHVZUzH4VXhL2zZ1EXVaJULZVWJYAqMW8GOObs+Kwijo+zxBGRs
+96Re9sg3XMkCUN+ZMoCpqoU4R/QiJ5z7B4AXS9CVcvczQKiULn1otP+UQQ4ABHlN
+t8pZzR6P/WGy91PvGt5wWfpReGveP/Zl2tksVXXs0CQgteneblYVzj01MaobVW59
+/LGUpe0oQy2rtzQVX3DZkDoGwGh4lof2Af+xMjCbVL6oDbPPooXG8TJnDP3AVhMG
+KIb+EhBUIEJnd/z6ZXTWbv0KQOt4wiVBzuXVBf7xxn/aH4+3kyrnj7CsUHXM4++x
+KRZq7gaP7nRbN22rw+WCHnqvMfAGnS7/6AjKFUWxmNWxRXMX+ehsSbT/XQnQm88e
+oUBLzQc4JrNSPklVJ82Qp19tAgMBAAGjVTBTMAwGA1UdEwEB/wQCMAAwEwYDVR0l
+BAwwCgYIKwYBBQUHAwEwDwYDVR0PAQH/BAUDAwegADAdBgNVHQ4EFgQUdnjZogYk
+7JK21Fj2NfYwrtJzK1EwDQYJKoZIhvcNAQELBQADggGBABDreWdgeyLMvqv1fO1f
+zbkSxUp57XoQsX3G/1nUfjT2Zujxwvu8D9N74R3I/BsxVTiI4RL2LZj33q+eq0KX
+LG/zBH2DEBheMmQtbMS6Ah+MTSlvG8SDlRRYPEVdYYtXOwskGNyIwcqNTr0j2Mrn
+Zlre0VJQc5r94seoVCjCseio26I9qf0LW2QsGfk4vSMJlhTRkcbBjKABG8xGXv61
++Hd4OFA0e/gOzFZFwDxWEsks5d8w6kzyipdGcCezBhlDi/qNCAex1GVTdUsCbGNS
+9N2i1Cty01AJbrkfWwKCc/Xg/YV/9PVncoiwJSIILllmFvLPu0vRof8AX/4DxEkS
+YFnN2x+qyukW+DfSnC3YSqyKdKtvB0U0Xf4tcHQfX2kHS/PqOIR6F9trY45ZlXoA
+nQKf1vcsIJzHW1mi9SvyVgyp3HftPw5xIU15mHRHBfBEzkVNwZJxyCl6nd++4vMS
+DmzpJPCT/a8rl1Jj5yyQ5zJp06Z7FbPpkT9kiAB5+U/vKw==
+-----END CERTIFICATE-----
diff --git a/deprecated-ngircd/src/testsuite/ssl/dhparams-my-first-domain-tld.pem b/deprecated-ngircd/src/testsuite/ssl/dhparams-my-first-domain-tld.pem
new file mode 100644
index 0000000..011750b
--- /dev/null
+++ b/deprecated-ngircd/src/testsuite/ssl/dhparams-my-first-domain-tld.pem
@@ -0,0 +1,77 @@
+
+Recommended key length: 256 bits
+
+generator:
+ 39:76:54:fb:49:4c:58:2c:f6:62:3a:81:d1:1e:ef:55
+ 97:da:5a:9c:f8:11:e4:23:26:91:e2:d4:14:94:14:e1
+ d2:82:69:b6:f0:2e:af:08:cc:bc:21:0d:e5:a7:40:f9
+ 8d:18:a2:52:6a:41:de:57:c7:17:0d:23:b9:36:3c:33
+ ef:ff:0b:85:b1:a9:59:65:49:46:36:3b:57:e4:b7:91
+ 4b:6c:56:1a:47:44:d8:5b:8a:bd:93:93:41:81:01:9d
+ 31:8d:3d:b8:a6:6c:7e:48:aa:86:b6:68:eb:66:0b:f3
+ 42:58:c5:ef:65:75:9d:8d:0f:18:21:25:86:40:a6:fd
+ 23:15:58:82:57:df:b6:0d:e5:c9:f1:85:ef:ec:ae:4a
+ b4:1b:70:ac:f5:c8:75:57:d6:4b:17:ca:f1:a1:45:13
+ c0:e7:2b:b9:26:92:c0:a1:c4:ba:87:4e:b7:37:2f:6c
+ 02:51:86:95:2d:f3:c1:7e:c1:f7:00:52:00:0d:43:f2
+ aa:8d:af:f6:5a:4f:a8:65:a5:26:af:58:fa:5d:fb:77
+ 42:e2:1e:19:f5:0f:8a:f2:9b:6b:9a:c0:2c:60:4f:45
+ da:9c:54:97:67:6a:e3:62:b9:c1:a0:3d:bf:cb:aa:22
+ 23:3b:08:bc:29:6a:a5:91:5e:76:1b:60:1d:c2:02:85
+ 2e:c6:85:20:5a:6e:0b:84:e3:e3:88:4e:c5:48:f3:c8
+ c1:71:b0:22:22:70:00:27:99:c6:dc:50:62:2d:be:55
+ 65:af:60:d7:43:44:2f:97:72:a2:66:48:fa:ee:af:7a
+ 81:cc:77:97:95:61:74:37:44:f2:b9:8e:9a:90:e4:45
+ 89:69:66:fe:52:fe:82:d2:de:4c:11:64:a2:c3:6e:00
+ e4:a7:58:4f:e9:61:0d:d2:72:a1:fb:72:89:84:73:64
+ de:1a:2c:0f:7e:46:5f:73:f6:67:3f:14:86:1c:90:bf
+ 49:d6:d1:3c:6a:6a:8b:42:29:22:02:47:c4:b9:bb:64
+
+
+prime:
+ 90:cb:d2:ec:9f:0c:6c:69:f5:c0:46:e1:9c:fc:4d:3b
+ ff:65:40:32:66:d5:fa:e0:ee:88:7d:35:ad:5e:1a:37
+ 07:db:c0:ed:a4:b2:94:ed:41:b4:be:be:35:e3:36:ff
+ 04:c2:48:4d:f0:e9:d2:54:54:de:10:4b:1c:6b:0e:e6
+ 8f:c1:8a:9f:9d:e2:f0:9e:35:52:b7:2a:29:5e:e1:95
+ c0:e0:6e:2b:a9:eb:00:fb:fe:90:d9:aa:02:2d:52:e5
+ 09:fe:5a:e9:5e:73:e1:94:d1:a5:a1:f5:3b:97:e8:53
+ 67:ea:86:a7:f2:70:5c:31:7f:ed:23:f1:ce:01:62:e5
+ 0c:7b:7c:18:67:ec:42:35:e8:d1:3d:e1:74:f9:77:02
+ fb:8d:24:a7:bf:3a:38:36:cf:82:9e:90:b2:7c:c3:f3
+ d3:e4:f1:55:ca:4b:1e:5e:50:b9:3b:d8:6a:6c:c2:51
+ a9:a7:e2:86:02:ef:7b:c2:d1:80:e2:dd:e0:7c:e2:03
+ e5:b1:e9:5b:45:c7:56:bb:37:56:9a:4a:0e:7e:b6:f6
+ a5:95:ef:93:5f:f9:38:16:e3:73:b5:68:a7:98:15:a2
+ 6c:ff:6b:2e:89:f7:9f:f8:a9:d7:ce:a4:9a:de:cb:42
+ 90:40:7b:fe:6c:3a:e0:4c:42:fe:0c:af:4e:7f:37:be
+ fd:3b:31:17:f6:30:0d:52:a5:ca:19:c3:c6:a4:dc:48
+ ec:59:02:6e:5a:80:b8:09:7d:3d:9a:00:32:7a:d7:fe
+ 84:38:12:22:7f:c6:97:88:91:05:7f:ba:74:2b:8c:36
+ a0:e4:d7:1c:22:2f:0b:6a:cb:a8:71:40:d2:b1:ed:9f
+ 43:79:2f:a6:34:7d:c0:65:c4:04:fa:d4:5c:14:7c:4b
+ 6f:cb:b2:f8:f0:91:05:33:b7:23:58:e8:4d:ff:3f:ef
+ a4:f3:17:78:9b:5b:f6:f1:49:82:12:de:5d:f7:1d:47
+ 1e:08:7f:ee:2d:10:68:f8:a5:97:03:9d:32:d2:9c:b7
+
+
+
+-----BEGIN DH PARAMETERS-----
+MIIDDQKCAYEAkMvS7J8MbGn1wEbhnPxNO/9lQDJm1frg7oh9Na1eGjcH28DtpLKU
+7UG0vr414zb/BMJITfDp0lRU3hBLHGsO5o/Bip+d4vCeNVK3Kile4ZXA4G4rqesA
++/6Q2aoCLVLlCf5a6V5z4ZTRpaH1O5foU2fqhqfycFwxf+0j8c4BYuUMe3wYZ+xC
+NejRPeF0+XcC+40kp786ODbPgp6QsnzD89Pk8VXKSx5eULk72GpswlGpp+KGAu97
+wtGA4t3gfOID5bHpW0XHVrs3VppKDn629qWV75Nf+TgW43O1aKeYFaJs/2suifef
++KnXzqSa3stCkEB7/mw64ExC/gyvTn83vv07MRf2MA1SpcoZw8ak3EjsWQJuWoC4
+CX09mgAyetf+hDgSIn/Gl4iRBX+6dCuMNqDk1xwiLwtqy6hxQNKx7Z9DeS+mNH3A
+ZcQE+tRcFHxLb8uy+PCRBTO3I1joTf8/76TzF3ibW/bxSYIS3l33HUceCH/uLRBo
++KWXA50y0py3AoIBgDl2VPtJTFgs9mI6gdEe71WX2lqc+BHkIyaR4tQUlBTh0oJp
+tvAurwjMvCEN5adA+Y0YolJqQd5XxxcNI7k2PDPv/wuFsalZZUlGNjtX5LeRS2xW
+GkdE2FuKvZOTQYEBnTGNPbimbH5Iqoa2aOtmC/NCWMXvZXWdjQ8YISWGQKb9IxVY
+glfftg3lyfGF7+yuSrQbcKz1yHVX1ksXyvGhRRPA5yu5JpLAocS6h063Ny9sAlGG
+lS3zwX7B9wBSAA1D8qqNr/ZaT6hlpSavWPpd+3dC4h4Z9Q+K8ptrmsAsYE9F2pxU
+l2dq42K5waA9v8uqIiM7CLwpaqWRXnYbYB3CAoUuxoUgWm4LhOPjiE7FSPPIwXGw
+IiJwACeZxtxQYi2+VWWvYNdDRC+XcqJmSPrur3qBzHeXlWF0N0TyuY6akORFiWlm
+/lL+gtLeTBFkosNuAOSnWE/pYQ3ScqH7comEc2TeGiwPfkZfc/ZnPxSGHJC/SdbR
+PGpqi0IpIgJHxLm7ZAICAQA=
+-----END DH PARAMETERS-----
diff --git a/deprecated-ngircd/src/testsuite/ssl/dhparams-my-second-domain-tld.pem b/deprecated-ngircd/src/testsuite/ssl/dhparams-my-second-domain-tld.pem
new file mode 100644
index 0000000..a158861
--- /dev/null
+++ b/deprecated-ngircd/src/testsuite/ssl/dhparams-my-second-domain-tld.pem
@@ -0,0 +1,77 @@
+
+Recommended key length: 256 bits
+
+generator:
+ da:16:f5:61:0c:09:de:cd:9b:be:b8:2b:c9:96:97:1b
+ fc:29:b2:a5:1b:ee:d3:36:bd:6c:73:7e:1c:2a:35:71
+ 26:c6:54:b6:28:24:db:87:9d:fc:9e:26:28:e9:01:b8
+ 85:f2:02:9b:6a:c3:f5:3a:85:ae:1d:8c:e9:e8:c4:41
+ 3a:78:2f:9e:f0:2a:77:18:99:a6:91:2b:2b:8c:10:98
+ 89:04:d9:03:5f:4f:77:d6:27:1d:5e:ee:a2:d0:b1:c8
+ a7:64:b4:7a:67:5f:aa:3f:02:b0:d2:f7:cd:4c:7a:9d
+ 63:57:99:8c:89:17:3f:2d:2d:1d:f5:58:61:49:62:54
+ 55:17:be:ea:43:03:44:d7:02:39:67:26:b3:7a:4f:00
+ a3:a1:3b:d9:f3:aa:7a:c5:00:46:86:92:e2:2e:d8:09
+ ee:ca:97:06:c5:33:e5:99:f3:4c:46:81:50:59:6b:60
+ fb:a3:24:2a:f8:8f:e0:fb:a5:c3:9a:7d:f7:f2:d7:30
+ e5:1b:fa:15:a0:ca:6d:f5:64:4f:20:a3:fb:f4:31:55
+ b5:58:c4:6f:06:7d:5d:36:16:03:31:73:57:6b:39:c6
+ 10:21:d9:f0:eb:74:43:2e:b0:da:ee:96:86:6e:0c:b5
+ 08:78:af:3d:9b:66:71:bc:05:63:9d:aa:a6:2e:bc:c9
+ c0:e4:a4:c6:60:e8:5d:d2:96:55:a3:72:4e:7a:ec:b2
+ a8:23:b9:3f:7c:33:5d:f0:5f:29:57:cd:8e:9a:fd:7b
+ b6:83:7f:56:ba:64:bd:a8:1c:83:7f:ee:04:f1:bb:1f
+ 70:6d:08:46:a2:95:e6:6e:2a:54:44:d9:af:9d:22:a4
+ 50:6d:88:65:de:05:89:99:75:7e:0c:12:d9:25:43:f7
+ da:b6:41:f8:60:68:f7:6a:f6:a4:8d:8b:93:82:87:56
+ c1:80:4d:e6:66:37:1e:22:5c:86:90:d1:8e:02:3a:18
+ 34:84:6a:da:e5:4f:a5:4f:29:78:46:97:71:24:80:92
+
+
+prime:
+ f8:98:84:b9:b2:75:39:d5:da:14:fa:4a:03:96:57:78
+ 95:4e:8c:ba:c3:89:de:36:2c:4a:2b:0a:31:08:09:89
+ bb:f6:00:a1:0b:64:02:52:1e:3f:23:67:df:2c:97:7a
+ 7a:81:e0:b0:ae:00:bf:a6:8f:02:e1:62:d4:dc:9e:62
+ 9a:27:f2:cf:4f:88:73:96:de:8a:61:1c:ac:3f:bb:f3
+ 0d:be:5e:07:3b:6f:da:0c:10:03:b5:b2:5a:60:3e:c8
+ 6f:aa:2c:3e:92:b9:ec:ee:08:29:90:c3:5e:8e:c1:a4
+ a7:1a:ab:87:f8:70:13:e8:b1:2f:b5:79:c1:bb:8f:21
+ 76:b4:1f:ba:91:62:f9:d3:3a:d7:c8:23:00:3e:fe:a5
+ 49:51:f8:eb:9f:46:e3:7d:1a:d3:54:a1:3a:d1:4b:05
+ ec:77:6e:80:dc:1b:22:e1:36:2a:a1:75:20:8c:48:bd
+ 53:a6:24:c0:b2:47:36:51:0d:69:b3:cc:e6:fe:8c:34
+ 0e:1f:16:03:af:81:b7:62:11:a8:82:06:c2:70:00:23
+ fe:0e:e0:fa:a1:e7:3d:cc:81:ae:76:f4:3e:66:84:df
+ 3f:63:ba:4e:aa:21:1d:5c:a2:a2:55:0e:53:31:40:7d
+ 7a:99:20:77:23:82:0c:a7:b3:1b:dd:13:fc:23:5f:6d
+ 58:6c:a7:1f:f6:1a:7c:2a:57:31:c1:10:7b:f1:54:a9
+ 8c:49:7f:17:14:5f:a4:69:16:11:6c:7d:1d:eb:d4:88
+ ab:6b:f8:8d:8b:be:0d:45:c7:7b:04:4f:a3:5f:f4:4f
+ 83:12:0c:00:73:5d:57:02:0c:95:b6:ce:70:60:52:80
+ 05:79:55:ed:99:e3:0c:23:dc:23:cd:9b:d3:a5:8e:4d
+ 94:c8:61:2d:56:b1:15:19:ca:b2:2c:76:7c:89:04:44
+ 18:5c:72:1e:03:9b:e0:dd:69:44:9f:68:0d:c4:2a:34
+ 5e:bd:4f:6c:14:41:93:08:0d:4b:4d:de:97:41:9b:8d
+
+
+
+-----BEGIN DH PARAMETERS-----
+MIIDDgKCAYEA+JiEubJ1OdXaFPpKA5ZXeJVOjLrDid42LEorCjEICYm79gChC2QC
+Uh4/I2ffLJd6eoHgsK4Av6aPAuFi1NyeYpon8s9PiHOW3ophHKw/u/MNvl4HO2/a
+DBADtbJaYD7Ib6osPpK57O4IKZDDXo7BpKcaq4f4cBPosS+1ecG7jyF2tB+6kWL5
+0zrXyCMAPv6lSVH4659G430a01ShOtFLBex3boDcGyLhNiqhdSCMSL1TpiTAskc2
+UQ1ps8zm/ow0Dh8WA6+Bt2IRqIIGwnAAI/4O4Pqh5z3Mga529D5mhN8/Y7pOqiEd
+XKKiVQ5TMUB9epkgdyOCDKezG90T/CNfbVhspx/2GnwqVzHBEHvxVKmMSX8XFF+k
+aRYRbH0d69SIq2v4jYu+DUXHewRPo1/0T4MSDABzXVcCDJW2znBgUoAFeVXtmeMM
+I9wjzZvTpY5NlMhhLVaxFRnKsix2fIkERBhcch4Dm+DdaUSfaA3EKjRevU9sFEGT
+CA1LTd6XQZuNAoIBgQDaFvVhDAnezZu+uCvJlpcb/CmypRvu0za9bHN+HCo1cSbG
+VLYoJNuHnfyeJijpAbiF8gKbasP1OoWuHYzp6MRBOngvnvAqdxiZppErK4wQmIkE
+2QNfT3fWJx1e7qLQscinZLR6Z1+qPwKw0vfNTHqdY1eZjIkXPy0tHfVYYUliVFUX
+vupDA0TXAjlnJrN6TwCjoTvZ86p6xQBGhpLiLtgJ7sqXBsUz5ZnzTEaBUFlrYPuj
+JCr4j+D7pcOafffy1zDlG/oVoMpt9WRPIKP79DFVtVjEbwZ9XTYWAzFzV2s5xhAh
+2fDrdEMusNruloZuDLUIeK89m2ZxvAVjnaqmLrzJwOSkxmDoXdKWVaNyTnrssqgj
+uT98M13wXylXzY6a/Xu2g39WumS9qByDf+4E8bsfcG0IRqKV5m4qVETZr50ipFBt
+iGXeBYmZdX4MEtklQ/fatkH4YGj3avakjYuTgodWwYBN5mY3HiJchpDRjgI6GDSE
+atrlT6VPKXhGl3EkgJICAgEA
+-----END DH PARAMETERS-----
diff --git a/deprecated-ngircd/src/testsuite/ssl/key-my-first-domain-tld.pem b/deprecated-ngircd/src/testsuite/ssl/key-my-first-domain-tld.pem
new file mode 100644
index 0000000..667ffac
--- /dev/null
+++ b/deprecated-ngircd/src/testsuite/ssl/key-my-first-domain-tld.pem
@@ -0,0 +1,182 @@
+Public Key Info:
+ Public Key Algorithm: RSA
+ Key Security Level: High (3072 bits)
+
+modulus:
+ 00:9d:c7:bc:02:03:43:12:ff:a3:bc:a8:7a:63:07:e4
+ e6:44:5f:21:53:43:f4:3c:df:c5:18:d2:55:db:58:16
+ f4:2e:cc:fd:7e:dd:14:16:db:bf:49:26:9b:1c:b2:c9
+ 1d:03:04:f7:d2:32:95:e6:22:33:08:b4:63:7a:2a:0c
+ 25:59:a7:a7:aa:78:a4:bb:31:34:48:a2:dd:83:d6:6e
+ 13:42:c2:b5:dd:d0:2f:64:e6:84:60:fb:25:b5:db:05
+ 0c:23:fb:e6:cd:3b:b4:3a:7d:69:86:2c:1c:3b:0d:84
+ 7b:bc:2f:15:1a:72:19:9b:df:be:3b:fe:fd:44:d5:31
+ 99:4f:90:52:9f:31:b1:12:c4:28:d6:fc:ca:28:ca:4c
+ 6e:37:2d:d5:dd:f3:75:04:41:d6:8f:eb:e8:19:5a:3f
+ 29:13:01:a0:75:0e:43:3b:18:e3:9d:b6:9a:e1:3b:f4
+ a1:3d:b7:d7:2f:e0:47:82:57:4f:6f:16:e8:ba:5e:cd
+ 4e:dd:6b:d8:27:ea:16:6c:f8:3e:2e:0f:6c:2a:ee:bf
+ 41:d5:1b:c3:7c:7a:03:7a:25:bf:34:52:ec:0e:88:27
+ 0c:07:16:3d:ba:10:a1:e9:93:e8:67:db:9f:98:60:0b
+ 86:48:03:d2:b9:6d:fe:c4:1f:29:0d:04:22:6c:f1:f1
+ c0:bf:eb:3b:d2:7c:94:34:59:ac:cb:a7:fc:02:22:69
+ 0f:41:9c:0a:9b:f5:3a:44:c1:d6:b6:d8:47:83:8a:49
+ 46:c6:05:e6:b2:f6:f9:83:2a:79:b4:dc:1b:ae:79:f9
+ f8:10:9b:d1:08:f9:97:00:a9:62:1b:9e:88:06:03:4e
+ 3a:a1:2d:57:ef:cd:39:a2:00:68:ec:e3:cc:94:9d:7d
+ 36:3c:4e:73:7c:92:f5:d5:e5:93:a8:44:7b:40:0a:48
+ 20:ae:b3:2e:25:23:88:1c:19:dd:a0:c2:60:2d:5e:9d
+ e2:65:59:05:06:c5:2c:98:17:b7:c7:9b:04:00:45:55
+ c9:
+
+public exponent:
+ 01:00:01:
+
+private exponent:
+ 45:26:8b:e4:c9:ef:34:bd:6b:d2:bc:78:5f:3c:cf:7a
+ 88:4e:b5:39:5c:18:08:31:fe:9d:21:5a:55:b6:e6:e0
+ 80:3e:81:7f:7f:7f:55:81:5b:f5:c0:80:cc:f4:22:a6
+ 9f:73:26:f6:2e:0b:7a:80:54:a3:a5:03:d0:3f:eb:70
+ d7:39:5e:87:9d:36:7d:80:54:2c:dd:8c:7e:42:95:9d
+ c5:6d:b6:ed:8f:57:a6:3e:4d:98:7f:9a:08:79:04:5e
+ 4c:cb:13:5d:b1:a4:0c:da:78:4c:40:ba:e2:ba:ca:ec
+ bc:0e:5a:8e:6b:a1:83:aa:6d:22:b8:5f:e2:32:19:f9
+ da:60:23:85:f7:ee:66:8e:28:64:09:08:c5:15:dc:a7
+ 95:71:76:41:3f:79:72:b3:34:49:81:98:08:bc:7f:e0
+ 0d:9f:71:e6:bb:a8:85:97:23:f3:34:5b:ef:09:2a:ef
+ 1c:30:9d:94:33:14:c4:30:65:f5:07:32:5a:b4:40:00
+ 77:4e:93:b3:f4:6a:9d:9f:dc:6b:8f:0b:43:81:43:ff
+ d5:43:a9:93:68:f5:ab:2b:b9:8e:36:7b:13:0e:11:51
+ 5f:aa:46:24:a7:3b:19:4d:31:e9:2a:a2:7b:d4:a8:68
+ 38:9e:70:dd:68:9a:a0:f8:f3:27:40:b2:24:1b:80:93
+ 7e:ae:d1:25:6e:90:7d:7f:52:84:a8:46:1b:54:c9:c7
+ 9a:e5:a0:06:94:bd:d4:94:33:c7:25:f4:6c:13:e3:38
+ e0:83:97:51:aa:52:25:06:d9:64:b2:dc:79:53:e5:37
+ 0e:e4:33:e6:f4:bb:10:1a:66:11:9f:86:69:b0:2f:9c
+ b4:f8:89:e6:a4:a1:96:5e:14:3d:a4:24:51:21:98:17
+ 28:46:79:85:75:e6:f4:79:26:8a:db:18:94:35:07:ab
+ de:5f:49:e5:88:02:95:13:d6:ac:ca:e6:4d:65:be:8f
+ a5:f5:27:da:a9:72:b0:d5:6d:9a:4d:45:b6:69:a4:4d
+
+
+prime1:
+ 00:c2:19:9f:3e:b1:d3:f8:18:d0:79:56:3f:6d:d5:67
+ 6b:0b:48:bd:4a:b6:c1:c9:1d:70:b5:ff:73:cf:bc:37
+ 09:e9:b0:15:a6:6c:ff:bd:20:c9:ea:67:09:ce:f7:fe
+ d1:74:c3:d4:4b:87:38:47:9f:7b:b2:77:a3:a2:db:7d
+ 64:d2:77:dc:50:a3:56:2e:44:2a:1c:90:5d:f2:f9:e8
+ 4f:84:43:83:a6:b2:48:c4:dc:26:bd:87:d3:e3:f3:be
+ 20:cb:7e:ce:ea:b7:93:1f:b9:6b:57:ee:73:d7:d6:08
+ 35:b9:10:2f:60:03:e5:68:d5:5d:59:c7:e8:66:7a:51
+ 6a:59:75:71:4a:be:1f:83:9c:01:bc:d0:5c:e5:7b:a6
+ 5d:7f:f2:4a:e0:a2:31:58:c3:5d:c7:a5:2f:19:1e:10
+ 56:c0:fb:83:35:84:c3:d7:ca:f7:3d:9f:1d:95:5e:3f
+ 7d:d9:9d:ef:15:a2:15:c2:ae:ff:92:74:db:92:ae:21
+ 43:
+
+prime2:
+ 00:d0:18:f2:f7:da:77:4a:6f:60:a0:93:92:d6:7e:da
+ bf:86:19:df:70:f5:41:99:eb:13:49:6d:c2:79:7c:51
+ 20:4f:b0:10:01:0d:87:17:90:87:78:41:22:95:f1:72
+ 2b:78:97:c3:12:6a:ca:49:73:50:68:fa:d7:12:56:5e
+ d5:bc:3f:eb:e5:ec:55:82:1b:2d:c8:15:da:d4:63:81
+ 0e:b3:45:bb:1f:52:9b:b6:3a:96:36:87:79:43:cd:58
+ 5d:a4:11:f6:a4:77:5f:9e:df:26:b2:e1:5d:0a:8d:bf
+ 32:9d:52:1e:9b:21:66:ca:45:23:23:f4:04:71:23:9a
+ 4b:19:e3:10:ff:12:9c:90:b5:ae:80:3e:0e:a8:67:64
+ 61:ff:4e:83:db:ae:34:22:94:58:b9:e1:c3:bf:c5:39
+ d2:60:a0:b2:7e:e0:08:92:b7:f2:8c:28:69:2c:9c:97
+ 59:b6:55:d9:0a:ff:c3:d3:b4:a6:eb:5a:55:35:59:26
+ 03:
+
+coefficient:
+ 51:2c:52:fc:45:b3:05:bf:1b:ca:e3:12:a6:b1:20:8a
+ 52:98:d0:87:84:a0:a5:04:12:19:af:13:4c:8c:3c:d7
+ 91:bb:c8:0d:cc:7e:14:89:4c:bf:05:c2:fe:f2:7e:29
+ 5c:5a:3e:37:6e:9f:16:66:5f:93:83:87:c8:e9:3c:0e
+ de:00:44:18:3b:7a:76:d8:fb:32:b2:4b:db:af:c3:11
+ 45:3e:55:ae:ac:94:a5:20:ba:11:d5:4f:01:64:a4:c3
+ 70:af:4b:e9:23:a1:9e:b8:7a:3f:79:27:e1:2b:ff:a8
+ ed:1f:7e:0c:27:11:6e:4d:8c:1f:37:90:a6:98:b9:e3
+ 5a:a5:04:65:5e:36:a6:1b:2e:32:f3:14:0f:94:3b:88
+ be:94:ee:5d:b0:0b:3f:3e:8b:9b:b6:60:5c:94:5c:88
+ 01:54:90:07:8b:69:ab:fe:72:4d:6b:6a:6c:5f:c1:b9
+ 5b:52:ef:c6:38:03:06:0c:25:78:73:d1:e1:db:54:46
+
+
+exp1:
+ 33:25:37:3d:f8:f3:c6:db:1b:0b:ed:fb:16:c0:f5:d8
+ 52:07:df:c1:31:39:0c:fa:91:f9:93:0f:7c:3c:b7:30
+ 08:80:da:a3:98:f3:26:6d:de:66:c2:b1:e5:f4:99:13
+ ae:35:ef:d9:db:0e:ac:68:cc:da:71:06:10:62:cf:be
+ e2:6a:ad:06:1e:94:15:ea:e6:41:d2:94:be:f2:b5:11
+ 46:e3:d7:6b:f4:6c:92:5b:04:66:4a:c5:3d:ba:bb:6d
+ be:d1:72:4a:8d:06:da:84:2c:51:e6:46:66:28:42:cf
+ 8d:2d:43:9e:84:48:4e:00:72:f1:b6:68:79:a0:5f:95
+ ab:6e:f3:e4:63:06:c0:d2:39:ee:fb:e4:8e:9f:af:6d
+ d1:ca:11:8a:f1:92:19:36:99:9e:82:db:4f:3e:09:c6
+ 22:61:e3:e8:15:4c:d9:ae:e4:c9:3b:05:3b:97:b3:19
+ 41:5f:89:61:64:ed:60:f8:65:e5:bc:9f:23:1e:79:2b
+
+
+exp2:
+ 5f:18:97:a7:d6:49:1f:55:e8:85:59:0b:08:44:6e:38
+ 89:d2:b6:fe:4a:c5:d0:cd:d1:41:84:0c:14:32:50:6c
+ 80:9e:07:a2:43:89:51:a6:75:91:e9:ca:21:55:76:04
+ 11:96:e0:c9:40:cd:f2:64:e5:01:24:68:36:74:0b:e0
+ 86:a7:7b:68:d5:e8:79:8d:6c:0d:7c:97:44:e9:b7:e7
+ 7c:db:47:d8:d7:8a:5a:eb:49:0b:e0:3a:f5:56:18:a4
+ aa:3e:9f:44:a7:5c:a6:20:79:f1:d2:f5:0e:c6:99:f2
+ 4a:5c:65:aa:24:c8:71:74:c8:cb:3c:4e:ef:59:02:c0
+ 81:32:f7:e8:68:9b:ed:b1:68:ee:27:ed:d0:dd:76:cd
+ 25:bb:be:9c:1c:6e:ac:c2:b8:0d:31:f3:9f:66:44:b7
+ 33:fb:1b:b6:c9:30:81:c3:d7:ee:5e:e5:39:42:d2:13
+ 68:34:b0:fb:ca:c7:b5:ae:5f:7d:3c:09:a6:58:77:fb
+
+
+
+Public Key PIN:
+ pin-sha256:nCxZsiBRLBQ0Lz6/eXIc9kEBwXZg06i/XORB+NNXVrE=
+Public Key ID:
+ sha256:9c2c59b220512c14342f3ebf79721cf64101c17660d3a8bf5ce441f8d35756b1
+ sha1:5b2df9000451d08f57cd3f86638404ab6338c44b
+
+-----BEGIN RSA PRIVATE KEY-----
+MIIG4gIBAAKCAYEAnce8AgNDEv+jvKh6Ywfk5kRfIVND9DzfxRjSVdtYFvQuzP1+
+3RQW279JJpscsskdAwT30jKV5iIzCLRjeioMJVmnp6p4pLsxNEii3YPWbhNCwrXd
+0C9k5oRg+yW12wUMI/vmzTu0On1phiwcOw2Ee7wvFRpyGZvfvjv+/UTVMZlPkFKf
+MbESxCjW/MooykxuNy3V3fN1BEHWj+voGVo/KRMBoHUOQzsY4522muE79KE9t9cv
+4EeCV09vFui6Xs1O3WvYJ+oWbPg+Lg9sKu6/QdUbw3x6A3olvzRS7A6IJwwHFj26
+EKHpk+hn25+YYAuGSAPSuW3+xB8pDQQibPHxwL/rO9J8lDRZrMun/AIiaQ9BnAqb
+9TpEwda22EeDiklGxgXmsvb5gyp5tNwbrnn5+BCb0Qj5lwCpYhueiAYDTjqhLVfv
+zTmiAGjs48yUnX02PE5zfJL11eWTqER7QApIIK6zLiUjiBwZ3aDCYC1eneJlWQUG
+xSyYF7fHmwQARVXJAgMBAAECggGARSaL5MnvNL1r0rx4XzzPeohOtTlcGAgx/p0h
+WlW25uCAPoF/f39VgVv1wIDM9CKmn3Mm9i4LeoBUo6UD0D/rcNc5XoedNn2AVCzd
+jH5ClZ3Fbbbtj1emPk2Yf5oIeQReTMsTXbGkDNp4TEC64rrK7LwOWo5roYOqbSK4
+X+IyGfnaYCOF9+5mjihkCQjFFdynlXF2QT95crM0SYGYCLx/4A2fcea7qIWXI/M0
+W+8JKu8cMJ2UMxTEMGX1BzJatEAAd06Ts/RqnZ/ca48LQ4FD/9VDqZNo9asruY42
+exMOEVFfqkYkpzsZTTHpKqJ71KhoOJ5w3WiaoPjzJ0CyJBuAk36u0SVukH1/UoSo
+RhtUycea5aAGlL3UlDPHJfRsE+M44IOXUapSJQbZZLLceVPlNw7kM+b0uxAaZhGf
+hmmwL5y0+InmpKGWXhQ9pCRRIZgXKEZ5hXXm9HkmitsYlDUHq95fSeWIApUT1qzK
+5k1lvo+l9SfaqXKw1W2aTUW2aaRNAoHBAMIZnz6x0/gY0HlWP23VZ2sLSL1KtsHJ
+HXC1/3PPvDcJ6bAVpmz/vSDJ6mcJzvf+0XTD1EuHOEefe7J3o6LbfWTSd9xQo1Yu
+RCockF3y+ehPhEODprJIxNwmvYfT4/O+IMt+zuq3kx+5a1fuc9fWCDW5EC9gA+Vo
+1V1Zx+hmelFqWXVxSr4fg5wBvNBc5XumXX/ySuCiMVjDXcelLxkeEFbA+4M1hMPX
+yvc9nx2VXj992Z3vFaIVwq7/knTbkq4hQwKBwQDQGPL32ndKb2Cgk5LWftq/hhnf
+cPVBmesTSW3CeXxRIE+wEAENhxeQh3hBIpXxcit4l8MSaspJc1Bo+tcSVl7VvD/r
+5exVghstyBXa1GOBDrNFux9Sm7Y6ljaHeUPNWF2kEfakd1+e3yay4V0Kjb8ynVIe
+myFmykUjI/QEcSOaSxnjEP8SnJC1roA+DqhnZGH/ToPbrjQilFi54cO/xTnSYKCy
+fuAIkrfyjChpLJyXWbZV2Qr/w9O0putaVTVZJgMCgcAzJTc9+PPG2xsL7fsWwPXY
+UgffwTE5DPqR+ZMPfDy3MAiA2qOY8yZt3mbCseX0mROuNe/Z2w6saMzacQYQYs++
+4mqtBh6UFermQdKUvvK1EUbj12v0bJJbBGZKxT26u22+0XJKjQbahCxR5kZmKELP
+jS1DnoRITgBy8bZoeaBflatu8+RjBsDSOe775I6fr23RyhGK8ZIZNpmegttPPgnG
+ImHj6BVM2a7kyTsFO5ezGUFfiWFk7WD4ZeW8nyMeeSsCgcBfGJen1kkfVeiFWQsI
+RG44idK2/krF0M3RQYQMFDJQbICeB6JDiVGmdZHpyiFVdgQRluDJQM3yZOUBJGg2
+dAvghqd7aNXoeY1sDXyXROm353zbR9jXilrrSQvgOvVWGKSqPp9Ep1ymIHnx0vUO
+xpnySlxlqiTIcXTIyzxO71kCwIEy9+hom+2xaO4n7dDdds0lu76cHG6swrgNMfOf
+ZkS3M/sbtskwgcPX7l7lOULSE2g0sPvKx7WuX308CaZYd/sCgcBRLFL8RbMFvxvK
+4xKmsSCKUpjQh4SgpQQSGa8TTIw815G7yA3MfhSJTL8Fwv7yfilcWj43bp8WZl+T
+g4fI6TwO3gBEGDt6dtj7MrJL26/DEUU+Va6slKUguhHVTwFkpMNwr0vpI6GeuHo/
+eSfhK/+o7R9+DCcRbk2MHzeQppi541qlBGVeNqYbLjLzFA+UO4i+lO5dsAs/Poub
+tmBclFyIAVSQB4tpq/5yTWtqbF/BuVtS78Y4AwYMJXhz0eHbVEY=
+-----END RSA PRIVATE KEY-----
diff --git a/deprecated-ngircd/src/testsuite/ssl/key-my-second-domain-tld.pem b/deprecated-ngircd/src/testsuite/ssl/key-my-second-domain-tld.pem
new file mode 100644
index 0000000..8cfe8d0
--- /dev/null
+++ b/deprecated-ngircd/src/testsuite/ssl/key-my-second-domain-tld.pem
@@ -0,0 +1,182 @@
+Public Key Info:
+ Public Key Algorithm: RSA
+ Key Security Level: High (3072 bits)
+
+modulus:
+ 00:e3:ee:38:da:c7:2c:76:a4:9f:e8:ee:14:3b:f4:6c
+ 90:cc:ce:5f:c0:61:0d:c4:b0:ae:11:9e:f7:b8:dd:0a
+ e4:0a:52:a4:ba:39:3d:54:a0:72:b4:0d:d3:24:c4:79
+ 4e:32:18:9f:3f:32:b1:a0:14:25:23:fd:36:97:5e:2d
+ 57:ff:f1:34:0a:ca:8f:86:be:05:9c:cd:4b:59:a9:dd
+ a7:63:81:37:37:b9:10:d0:1e:61:d5:65:4c:c7:e1:55
+ e1:2f:6c:d9:d4:45:d5:68:95:0b:65:55:89:60:0a:8c
+ 5b:c1:8e:39:bb:3e:2b:08:a3:a3:ec:f1:04:64:6c:f7
+ a4:5e:f6:c8:37:5c:c9:02:50:df:99:32:80:a9:aa:85
+ 38:47:f4:22:27:9c:fb:07:80:17:4b:d0:95:72:f7:33
+ 40:a8:94:2e:7d:68:b4:ff:94:41:0e:00:04:79:4d:b7
+ ca:59:cd:1e:8f:fd:61:b2:f7:53:ef:1a:de:70:59:fa
+ 51:78:6b:de:3f:f6:65:da:d9:2c:55:75:ec:d0:24:20
+ b5:e9:de:6e:56:15:ce:3d:35:31:aa:1b:55:6e:7d:fc
+ b1:94:a5:ed:28:43:2d:ab:b7:34:15:5f:70:d9:90:3a
+ 06:c0:68:78:96:87:f6:01:ff:b1:32:30:9b:54:be:a8
+ 0d:b3:cf:a2:85:c6:f1:32:67:0c:fd:c0:56:13:06:28
+ 86:fe:12:10:54:20:42:67:77:fc:fa:65:74:d6:6e:fd
+ 0a:40:eb:78:c2:25:41:ce:e5:d5:05:fe:f1:c6:7f:da
+ 1f:8f:b7:93:2a:e7:8f:b0:ac:50:75:cc:e3:ef:b1:29
+ 16:6a:ee:06:8f:ee:74:5b:37:6d:ab:c3:e5:82:1e:7a
+ af:31:f0:06:9d:2e:ff:e8:08:ca:15:45:b1:98:d5:b1
+ 45:73:17:f9:e8:6c:49:b4:ff:5d:09:d0:9b:cf:1e:a1
+ 40:4b:cd:07:38:26:b3:52:3e:49:55:27:cd:90:a7:5f
+ 6d:
+
+public exponent:
+ 01:00:01:
+
+private exponent:
+ 30:61:85:91:f2:cb:1e:57:ed:55:8d:0b:a0:7a:4e:7d
+ 21:ec:00:69:1e:70:c4:ba:58:08:87:7c:bf:b1:b3:b9
+ 19:f3:d6:e1:6c:7a:f7:36:a3:82:52:98:e9:ea:06:71
+ b1:b2:86:42:ec:e8:c5:38:e1:75:55:2f:3c:4c:12:45
+ e6:9e:f5:54:01:11:1c:21:c3:a1:37:f6:71:8e:db:ec
+ c6:f3:4b:9c:39:5d:37:3f:eb:b6:57:2d:48:14:2d:9d
+ 81:ea:92:06:3b:d8:83:bd:77:50:c8:2a:43:c7:99:69
+ 74:99:52:e9:ca:d5:69:9d:0a:93:a5:c9:2f:e3:ed:60
+ e7:83:6c:96:4b:cc:a3:00:35:a6:18:11:35:72:6b:9a
+ b9:b3:39:78:bd:1a:8f:ca:01:a7:e7:1b:81:ee:b4:e3
+ 59:a5:32:85:0e:2f:b5:3c:6b:de:a3:e4:4f:37:4e:f6
+ d5:be:f3:68:ce:f8:e8:fb:14:c6:e1:26:2c:24:fd:3b
+ dd:4b:70:c1:20:aa:0b:b5:0d:16:a8:45:4c:97:e9:0b
+ 08:97:c3:e9:ae:bf:0b:f7:1c:b1:81:63:ea:f4:72:dd
+ b7:da:5d:ab:21:06:c9:e3:99:3e:6c:c7:15:ca:79:fb
+ 44:7b:77:06:69:d9:59:a2:3c:b0:96:7b:66:6f:48:0c
+ 42:87:9c:df:4b:3a:dc:15:1f:48:0a:eb:b0:b1:38:98
+ 5b:6d:7f:34:ce:43:60:25:64:7c:8d:c0:d1:69:27:b8
+ ac:33:85:be:26:65:98:9f:8a:eb:cf:9a:6b:d7:5b:a3
+ 49:60:f9:ff:fb:5f:67:d9:08:20:a1:d8:d0:20:25:d5
+ 62:f9:d6:07:82:f6:c6:a6:55:65:71:3f:b8:64:b4:bd
+ 35:a9:2d:62:6c:cb:2c:e1:96:f0:9e:40:39:03:3b:10
+ 38:72:ac:af:6e:0a:ba:ea:f5:c1:c0:c6:86:60:58:a9
+ 28:23:6c:dd:8a:f2:84:76:a5:db:ef:f9:29:b9:b4:81
+
+
+prime1:
+ 00:f5:32:7d:80:4d:14:b1:3d:a1:ef:1b:7f:22:87:9f
+ d4:3d:4d:ce:e2:11:96:29:0f:ea:0b:c4:24:9c:9a:fa
+ 8a:4c:9a:5e:cd:48:aa:ce:6d:c0:fd:d4:53:46:1f:06
+ f4:4f:da:2c:e5:f1:cb:19:19:a3:a4:37:11:47:ed:3d
+ fc:4c:b8:f1:93:b8:d8:f7:6a:dd:5c:bd:51:4d:c6:09
+ 27:bc:c9:9a:19:05:0a:e9:00:ec:72:75:7f:89:0d:63
+ 65:e2:89:ac:ce:f1:78:20:0a:b8:fd:fd:a5:88:a7:7c
+ 38:1e:55:7d:16:23:6a:4d:dc:87:56:ef:ff:02:db:bd
+ 1b:61:60:b5:8f:7a:e1:d1:26:e3:2d:d5:21:bb:03:84
+ e2:a8:34:d6:7f:16:61:3c:a2:55:e1:c4:8a:82:61:74
+ e0:63:cb:53:fd:6d:6a:0d:f5:b5:55:e0:ef:83:2a:46
+ 80:7f:85:57:60:d3:b6:c3:2b:ba:af:88:c8:b8:3c:2c
+ a1:
+
+prime2:
+ 00:ed:f8:fc:68:1c:ae:2e:6d:63:f1:8b:6f:85:5c:5b
+ ba:3e:68:f9:61:03:44:60:83:90:26:8e:4c:8b:e0:49
+ c1:5a:a1:5c:e5:f1:67:43:0b:f6:b5:29:84:40:a8:0f
+ e8:bf:bf:62:7e:33:ca:86:a2:c4:47:3b:4a:d6:9c:09
+ a0:bb:10:00:ec:e6:81:f2:bc:86:3f:58:4d:3a:a4:98
+ 94:7e:5d:43:7d:33:3f:53:76:55:d1:73:a4:1f:fb:76
+ 75:92:70:8e:82:68:d8:f4:f7:b7:36:fa:3e:cc:a7:7a
+ fc:a4:7b:8c:72:b4:83:d7:ce:d8:f8:b2:35:ce:36:59
+ 7e:95:55:b8:c4:a9:44:26:a1:fe:be:f4:b9:67:bc:12
+ c8:e7:c3:0b:8a:51:b6:5c:1b:77:58:1f:53:ac:30:41
+ 43:5f:97:a2:fd:70:ac:4a:91:e0:bc:f6:4f:b1:06:47
+ 2d:89:77:ae:59:e0:5a:e2:31:c7:d9:a6:10:b8:7e:13
+ 4d:
+
+coefficient:
+ 2a:54:f9:93:b2:32:7a:c4:b6:41:0e:1a:8a:0e:d9:db
+ 4b:02:68:8d:15:10:84:42:ba:c9:35:e5:6d:ac:8e:ca
+ 47:5d:6f:fe:e4:81:c6:ce:ab:7c:b8:5a:59:12:96:a4
+ 0b:af:fb:d0:d7:e2:92:60:1b:81:05:4f:43:4c:5c:98
+ e1:84:a8:6e:bf:ad:cc:ac:de:26:d5:a8:58:09:45:ec
+ 38:d8:5d:ec:a7:39:46:88:d1:cc:ea:b9:13:5c:9d:bb
+ db:69:d0:a7:e4:0e:33:b1:71:eb:13:14:28:72:45:b0
+ 71:05:2a:a1:45:26:6c:a1:35:bf:a8:b0:1d:01:80:d9
+ af:66:71:3a:f4:e4:3c:fe:e8:68:2b:aa:64:a7:43:f3
+ 7f:38:4b:51:a1:ed:73:69:52:30:25:b8:62:5b:c7:cd
+ 02:f5:6f:4a:21:94:cb:29:44:76:f0:f8:96:50:57:33
+ 8c:eb:7b:08:70:fc:bc:fd:69:c1:3a:3a:82:5a:4c:15
+
+
+exp1:
+ 71:83:42:5e:97:50:b1:0d:1b:5e:9a:98:2c:e0:24:ba
+ 18:f7:60:83:80:28:c8:31:b9:e4:60:95:a2:7a:8c:ea
+ 61:b4:45:97:3b:c0:f7:78:10:14:72:ab:6a:97:0a:9d
+ 28:2a:95:06:8e:fd:bb:4d:07:59:0a:b5:51:5b:1f:8b
+ 21:e9:ac:cc:fa:92:57:58:7d:ca:65:4a:b2:7a:af:da
+ 59:a7:eb:53:11:e6:8f:20:02:56:aa:d6:b4:18:22:a0
+ 14:54:30:50:4d:b1:93:03:e3:c8:92:18:84:3f:25:5e
+ c5:8c:46:30:6d:8c:d5:26:f6:f0:e4:82:66:4c:5c:2b
+ c4:d5:04:b8:bb:e6:b6:f1:0d:d3:36:0c:3b:8b:d1:85
+ 2c:e1:e9:3b:44:9d:17:78:ff:d1:59:2f:d6:54:4f:cb
+ 61:e7:cb:a6:53:74:f9:a9:7a:9d:9b:58:c6:9c:57:af
+ 3d:59:f9:ad:b5:d5:b2:5d:18:3c:13:52:f9:17:c2:81
+
+
+exp2:
+ 10:56:1e:65:bb:4a:4d:cf:9e:a3:cf:51:a9:93:0c:8c
+ fd:89:d1:4c:d2:9f:98:0c:90:11:c5:85:05:b9:30:f7
+ 00:14:c1:be:db:52:9e:6c:ac:d4:04:f4:9a:47:af:47
+ e8:19:e8:56:07:92:28:a9:f5:d5:7a:01:8a:38:0e:05
+ 25:b2:54:8d:ee:c9:0e:f3:d8:37:73:05:62:38:38:6d
+ 41:3b:7f:cd:91:7e:10:69:b8:3c:77:b6:d5:a7:3a:9b
+ 99:a0:f6:77:87:61:15:78:07:f0:d3:3f:0a:67:98:ee
+ cd:0f:da:35:69:a4:ff:64:a8:ca:71:d9:75:bd:8f:69
+ 3c:31:35:4c:f2:dd:c5:d5:2b:1a:ca:cc:0b:8e:02:b0
+ 1e:10:ea:b2:e5:27:22:ad:94:04:cd:a9:bd:d1:56:39
+ 9c:cf:59:16:12:ed:10:f5:70:bb:28:21:92:62:7e:f2
+ 66:54:7b:f8:99:89:43:ab:ed:2f:48:d2:2f:08:20:a5
+
+
+
+Public Key PIN:
+ pin-sha256:NiuGB0c98aUqMKk4SVQIIwXNglOf+6m1LuVn6aQ2A1U=
+Public Key ID:
+ sha256:362b8607473df1a52a30a9384954082305cd82539ffba9b52ee567e9a4360355
+ sha1:7678d9a20624ec92b6d458f635f630aed2732b51
+
+-----BEGIN RSA PRIVATE KEY-----
+MIIG4gIBAAKCAYEA4+442scsdqSf6O4UO/RskMzOX8BhDcSwrhGe97jdCuQKUqS6
+OT1UoHK0DdMkxHlOMhifPzKxoBQlI/02l14tV//xNArKj4a+BZzNS1mp3adjgTc3
+uRDQHmHVZUzH4VXhL2zZ1EXVaJULZVWJYAqMW8GOObs+Kwijo+zxBGRs96Re9sg3
+XMkCUN+ZMoCpqoU4R/QiJ5z7B4AXS9CVcvczQKiULn1otP+UQQ4ABHlNt8pZzR6P
+/WGy91PvGt5wWfpReGveP/Zl2tksVXXs0CQgteneblYVzj01MaobVW59/LGUpe0o
+Qy2rtzQVX3DZkDoGwGh4lof2Af+xMjCbVL6oDbPPooXG8TJnDP3AVhMGKIb+EhBU
+IEJnd/z6ZXTWbv0KQOt4wiVBzuXVBf7xxn/aH4+3kyrnj7CsUHXM4++xKRZq7gaP
+7nRbN22rw+WCHnqvMfAGnS7/6AjKFUWxmNWxRXMX+ehsSbT/XQnQm88eoUBLzQc4
+JrNSPklVJ82Qp19tAgMBAAECggGAMGGFkfLLHlftVY0LoHpOfSHsAGkecMS6WAiH
+fL+xs7kZ89bhbHr3NqOCUpjp6gZxsbKGQuzoxTjhdVUvPEwSReae9VQBERwhw6E3
+9nGO2+zG80ucOV03P+u2Vy1IFC2dgeqSBjvYg713UMgqQ8eZaXSZUunK1WmdCpOl
+yS/j7WDng2yWS8yjADWmGBE1cmuaubM5eL0aj8oBp+cbge6041mlMoUOL7U8a96j
+5E83TvbVvvNozvjo+xTG4SYsJP073UtwwSCqC7UNFqhFTJfpCwiXw+muvwv3HLGB
+Y+r0ct232l2rIQbJ45k+bMcVynn7RHt3BmnZWaI8sJZ7Zm9IDEKHnN9LOtwVH0gK
+67CxOJhbbX80zkNgJWR8jcDRaSe4rDOFviZlmJ+K68+aa9dbo0lg+f/7X2fZCCCh
+2NAgJdVi+dYHgvbGplVlcT+4ZLS9NaktYmzLLOGW8J5AOQM7EDhyrK9uCrrq9cHA
+xoZgWKkoI2zdivKEdqXb7/kpubSBAoHBAPUyfYBNFLE9oe8bfyKHn9Q9Tc7iEZYp
+D+oLxCScmvqKTJpezUiqzm3A/dRTRh8G9E/aLOXxyxkZo6Q3EUftPfxMuPGTuNj3
+at1cvVFNxgknvMmaGQUK6QDscnV/iQ1jZeKJrM7xeCAKuP39pYinfDgeVX0WI2pN
+3IdW7/8C270bYWC1j3rh0SbjLdUhuwOE4qg01n8WYTyiVeHEioJhdOBjy1P9bWoN
+9bVV4O+DKkaAf4VXYNO2wyu6r4jIuDwsoQKBwQDt+PxoHK4ubWPxi2+FXFu6Pmj5
+YQNEYIOQJo5Mi+BJwVqhXOXxZ0ML9rUphECoD+i/v2J+M8qGosRHO0rWnAmguxAA
+7OaB8ryGP1hNOqSYlH5dQ30zP1N2VdFzpB/7dnWScI6CaNj097c2+j7Mp3r8pHuM
+crSD187Y+LI1zjZZfpVVuMSpRCah/r70uWe8EsjnwwuKUbZcG3dYH1OsMEFDX5ei
+/XCsSpHgvPZPsQZHLYl3rlngWuIxx9mmELh+E00CgcBxg0Jel1CxDRtempgs4CS6
+GPdgg4AoyDG55GCVonqM6mG0RZc7wPd4EBRyq2qXCp0oKpUGjv27TQdZCrVRWx+L
+IemszPqSV1h9ymVKsnqv2lmn61MR5o8gAlaq1rQYIqAUVDBQTbGTA+PIkhiEPyVe
+xYxGMG2M1Sb28OSCZkxcK8TVBLi75rbxDdM2DDuL0YUs4ek7RJ0XeP/RWS/WVE/L
+YefLplN0+al6nZtYxpxXrz1Z+a211bJdGDwTUvkXwoECgcAQVh5lu0pNz56jz1Gp
+kwyM/YnRTNKfmAyQEcWFBbkw9wAUwb7bUp5srNQE9JpHr0foGehWB5IoqfXVegGK
+OA4FJbJUje7JDvPYN3MFYjg4bUE7f82RfhBpuDx3ttWnOpuZoPZ3h2EVeAfw0z8K
+Z5juzQ/aNWmk/2SoynHZdb2PaTwxNUzy3cXVKxrKzAuOArAeEOqy5ScirZQEzam9
+0VY5nM9ZFhLtEPVwuyghkmJ+8mZUe/iZiUOr7S9I0i8IIKUCgcAqVPmTsjJ6xLZB
+DhqKDtnbSwJojRUQhEK6yTXlbayOykddb/7kgcbOq3y4WlkSlqQLr/vQ1+KSYBuB
+BU9DTFyY4YSobr+tzKzeJtWoWAlF7DjYXeynOUaI0czquRNcnbvbadCn5A4zsXHr
+ExQockWwcQUqoUUmbKE1v6iwHQGA2a9mcTr05Dz+6GgrqmSnQ/N/OEtRoe1zaVIw
+JbhiW8fNAvVvSiGUyylEdvD4llBXM4zrewhw/Lz9acE6OoJaTBU=
+-----END RSA PRIVATE KEY-----
diff --git a/deprecated-ngircd/src/testsuite/start-server.sh b/deprecated-ngircd/src/testsuite/start-server.sh
new file mode 100755
index 0000000..bc6eb7e
--- /dev/null
+++ b/deprecated-ngircd/src/testsuite/start-server.sh
@@ -0,0 +1,53 @@
+#!/bin/sh
+# ngIRCd Test Suite
+
+[ -z "$srcdir" ] && srcdir=`dirname "$0"`
+set -u
+
+# read in functions
+. "${srcdir}/functions.inc"
+
+if [ -n "$1" ]; then
+ id="$1"; shift
+else
+ id="1"
+fi
+
+echo_n "starting server ${id} ..."
+
+# remove old logfiles, if this is the first server (ID 1)
+[ "$id" = "1" ] && rm -rf logs *.log
+
+# check weather getpid.sh returns valid PIDs. If not, don't start up the
+# test-server, because we won't be able to kill it at the end of the test.
+./getpid.sh sh >/dev/null
+if [ $? -ne 0 ]; then
+ echo " getpid.sh failed!"
+ exit 1
+fi
+
+# check if there is a test-server already running
+./getpid.sh T-ngircd${id} >/dev/null 2>&1
+if [ $? -eq 0 ]; then
+ echo " failure: test-server ${id} already running!"
+ exit 1
+fi
+
+# generate MOTD for test-server
+echo "This is an ngIRCd Test Server" >ngircd-test${id}.motd
+
+# glibc memory checking, see malloc(3)
+MALLOC_CHECK_=3
+export MALLOC_CHECK_
+
+# starting up test-server ...
+./T-ngircd${id} -n -f "${srcdir}/ngircd-test${id}.conf" "$@" \
+ >ngircd-test${id}.log 2>&1 &
+sleep 1
+
+# validate running test-server
+r=1
+pid=`./getpid.sh T-ngircd${id}`
+[ -n "$pid" ] && kill -0 $pid >/dev/null 2>&1; r=$?
+[ $r -eq 0 ] && echo " ok." || echo " failure!"
+exit $r
diff --git a/deprecated-ngircd/src/testsuite/start-server1 b/deprecated-ngircd/src/testsuite/start-server1
new file mode 100755
index 0000000..ced37c4
--- /dev/null
+++ b/deprecated-ngircd/src/testsuite/start-server1
@@ -0,0 +1,6 @@
+#!/bin/sh
+# ngIRCd Test Suite
+
+[ -z "$srcdir" ] && srcdir=`dirname "$0"`
+set -u
+"${srcdir}/start-server.sh" 1
diff --git a/deprecated-ngircd/src/testsuite/start-server2 b/deprecated-ngircd/src/testsuite/start-server2
new file mode 100755
index 0000000..ca05bcf
--- /dev/null
+++ b/deprecated-ngircd/src/testsuite/start-server2
@@ -0,0 +1,6 @@
+#!/bin/sh
+# ngIRCd Test Suite
+
+[ -z "$srcdir" ] && srcdir=`dirname "$0"`
+set -u
+"${srcdir}/start-server.sh" 2
diff --git a/deprecated-ngircd/src/testsuite/start-server3 b/deprecated-ngircd/src/testsuite/start-server3
new file mode 100755
index 0000000..167040b
--- /dev/null
+++ b/deprecated-ngircd/src/testsuite/start-server3
@@ -0,0 +1,6 @@
+#!/bin/sh
+# ngIRCd Test Suite
+
+[ -z "$srcdir" ] && srcdir=`dirname "$0"`
+set -u
+"${srcdir}/start-server.sh" 3
diff --git a/deprecated-ngircd/src/testsuite/stop-server.sh b/deprecated-ngircd/src/testsuite/stop-server.sh
new file mode 100755
index 0000000..c5a9486
--- /dev/null
+++ b/deprecated-ngircd/src/testsuite/stop-server.sh
@@ -0,0 +1,36 @@
+#!/bin/sh
+# ngIRCd Test Suite
+
+[ -z "$srcdir" ] && srcdir=`dirname "$0"`
+set -u
+
+# read in functions
+. "${srcdir}/functions.inc"
+
+if [ -n "$1" ]; then
+ id="$1"; shift
+else
+ id="1"
+fi
+
+echo_n "stopping server ${id} ..."
+
+# stop test-server ...
+pid=`./getpid.sh T-ngircd${id}`
+if [ -z "$pid" ]; then
+ echo " failure: no running server found!?"
+ exit 1
+fi
+kill $pid >/dev/null 2>&1 || exit 1
+
+# waiting ...
+for i in 1 2 3 4 5; do
+ kill -0 $pid >/dev/null 2>&1; r=$?
+ if [ $r -ne 0 ]; then
+ echo " ok".
+ exit 0
+ fi
+ sleep 1
+done
+echo " failure: server ${id} still running!?"
+exit 1
diff --git a/deprecated-ngircd/src/testsuite/stop-server1 b/deprecated-ngircd/src/testsuite/stop-server1
new file mode 100755
index 0000000..aad0c85
--- /dev/null
+++ b/deprecated-ngircd/src/testsuite/stop-server1
@@ -0,0 +1,6 @@
+#!/bin/sh
+# ngIRCd Test Suite
+
+[ -z "$srcdir" ] && srcdir=`dirname "$0"`
+set -u
+"${srcdir}/stop-server.sh" 1
diff --git a/deprecated-ngircd/src/testsuite/stop-server2 b/deprecated-ngircd/src/testsuite/stop-server2
new file mode 100755
index 0000000..104a096
--- /dev/null
+++ b/deprecated-ngircd/src/testsuite/stop-server2
@@ -0,0 +1,6 @@
+#!/bin/sh
+# ngIRCd Test Suite
+
+[ -z "$srcdir" ] && srcdir=`dirname "$0"`
+set -u
+"${srcdir}/stop-server.sh" 2
diff --git a/deprecated-ngircd/src/testsuite/stop-server3 b/deprecated-ngircd/src/testsuite/stop-server3
new file mode 100755
index 0000000..a9515ed
--- /dev/null
+++ b/deprecated-ngircd/src/testsuite/stop-server3
@@ -0,0 +1,6 @@
+#!/bin/sh
+# ngIRCd Test Suite
+
+[ -z "$srcdir" ] && srcdir=`dirname "$0"`
+set -u
+"${srcdir}/stop-server.sh" 3
diff --git a/deprecated-ngircd/src/testsuite/stress-A.e b/deprecated-ngircd/src/testsuite/stress-A.e
new file mode 100644
index 0000000..d51adaa
--- /dev/null
+++ b/deprecated-ngircd/src/testsuite/stress-A.e
@@ -0,0 +1,10 @@
+# ngIRCd test suite
+# "Stress" header
+
+set timeout 30
+
+spawn telnet 127.0.0.1 6789
+expect {
+ timeout { exit 1 }
+ "Connected"
+}
diff --git a/deprecated-ngircd/src/testsuite/stress-B.e b/deprecated-ngircd/src/testsuite/stress-B.e
new file mode 100644
index 0000000..53c75a0
--- /dev/null
+++ b/deprecated-ngircd/src/testsuite/stress-B.e
@@ -0,0 +1,76 @@
+# ngIRCd test suite
+# "Stress" body
+
+send "user user . . :User\r"
+expect {
+ timeout { exit 1 }
+ " 376"
+}
+
+sleep 2
+
+send "oper TestOp 123\r"
+expect {
+ timeout { exit 1 }
+ "MODE test* :+o"
+}
+expect {
+ timeout { exit 1 }
+ " 381 test"
+}
+
+sleep 2
+
+send "join #channel\r"
+expect {
+ timeout { exit 1 }
+ " 353 * = #channel "
+}
+expect {
+ timeout { exit 1 }
+ " 366 * #channel :"
+}
+
+send "mode #channel\r"
+expect {
+ timeout { exit 1 }
+ " 324 test* #channel"
+}
+
+send "join #channel2\r"
+expect {
+ timeout { exit 1 }
+ " 353 * = #channel2 "
+}
+expect {
+ timeout { exit 1 }
+ " 366 * #channel2 :"
+}
+
+send "names\r"
+expect {
+ timeout { exit 1 }
+ " 366 "
+}
+
+sleep 3
+
+send "part #channel2\r"
+expect {
+ timeout { exit 1 }
+ " PART #channel2 "
+}
+
+send "part #channel\r"
+expect {
+ timeout { exit 1 }
+ " PART #channel "
+}
+
+sleep 1
+
+send "quit\r"
+expect {
+ timeout { exit 1 }
+ "ERROR :Closing connection"
+}
diff --git a/deprecated-ngircd/src/testsuite/stress-server.sh b/deprecated-ngircd/src/testsuite/stress-server.sh
new file mode 100755
index 0000000..a9ef507
--- /dev/null
+++ b/deprecated-ngircd/src/testsuite/stress-server.sh
@@ -0,0 +1,88 @@
+#!/bin/sh
+#
+# ngIRCd Test Suite
+# Copyright (c)2001-2024 Alexander Barton (alex@barton.de) and Contributors.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+# Please read the file COPYING, README and AUTHORS for more information.
+#
+
+# parse command line
+[ "$1" -gt 0 ] 2>/dev/null && CLIENTS="$1" || CLIENTS=5
+[ "$2" -gt 0 ] 2>/dev/null && MAX="$2" || MAX=-1
+
+# detect source directory
+[ -z "$srcdir" ] && srcdir=`dirname "$0"`
+set -u
+
+# get our name
+name=`basename "$0"`
+
+# create directories
+[ -d logs ] || mkdir logs
+[ -d tests ] || mkdir tests
+
+# test for required external tools
+type expect >/dev/null 2>&1
+if [ $? -ne 0 ]; then
+ echo "${name}: \"expect\" not found."
+ exit 77
+fi
+type telnet >/dev/null 2>&1
+if [ $? -ne 0 ]; then
+ echo "${name}: \"telnet\" not found.";
+ exit 77
+fi
+
+# hello world! :-)
+echo "stressing server with $CLIENTS clients (be patient!):"
+
+# read in functions
+. "${srcdir}/functions.inc"
+
+# create scripts for expect(1)
+no=0
+while [ ${no} -lt $CLIENTS ]; do
+ cat "${srcdir}/stress-A.e" >tests/${no}.e
+ echo "send \"nick test${no}\\r\"" >>tests/${no}.e
+ cat "${srcdir}/stress-B.e" >>tests/${no}.e
+ no=`expr ${no} + 1`
+done
+
+# run first script and check if it succeeds
+echo_n "checking stress script ..."
+expect tests/0.e >logs/stress-0.log 2>/dev/null
+if [ $? -ne 0 ]; then
+ echo " failure!"
+ exit 1
+else
+ echo " ok."
+fi
+
+no=0
+while [ ${no} -lt $CLIENTS ]; do
+ expect tests/${no}.e >logs/stress-${no}.log 2>/dev/null &
+
+ no=`expr ${no} + 1`
+ echo "started client $no/$CLIENTS."
+
+ [ $MAX -gt 0 ] && "$srcdir/wait-tests.sh" $MAX
+done
+
+echo_n "waiting for clients to complete: ."
+touch logs/check-idle.log
+while true; do
+ expect "${srcdir}/check-idle.e" >>logs/check-idle.log; res=$?
+ echo "====================" >>logs/check-idle.log
+ [ $res -ne 99 ] && break
+
+ # there are still clients connected. Wait ...
+ sleep 3
+ echo_n "."
+done
+
+[ $res -eq 0 ] && echo " ok." || echo " failure!"
+exit $res
diff --git a/deprecated-ngircd/src/testsuite/switch-server3 b/deprecated-ngircd/src/testsuite/switch-server3
new file mode 100755
index 0000000..4087e24
--- /dev/null
+++ b/deprecated-ngircd/src/testsuite/switch-server3
@@ -0,0 +1,4 @@
+#!/bin/sh -e
+cp "${srcdir}"/ssl/cert-my-second-domain-tld.pem ssl/cert.pem
+cp "${srcdir}"/ssl/key-my-second-domain-tld.pem ssl/key.pem
+cp "${srcdir}"/ssl/dhparams-my-second-domain-tld.pem ssl/dhparams.pem
diff --git a/deprecated-ngircd/src/testsuite/test-loop.sh b/deprecated-ngircd/src/testsuite/test-loop.sh
new file mode 100755
index 0000000..18fe9a5
--- /dev/null
+++ b/deprecated-ngircd/src/testsuite/test-loop.sh
@@ -0,0 +1,34 @@
+#!/bin/sh
+#
+# ngIRCd Test Suite
+# Copyright (c)2001-2024 Alexander Barton (alex@barton.de) and Contributors.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+# Please read the file COPYING, README and AUTHORS for more information.
+#
+
+# parse command line
+[ "$1" -gt 0 ] 2>/dev/null && LOOPS="$1" || LOOPS=5
+[ "$2" -gt 0 ] 2>/dev/null && WAIT="$2" || WAIT=5
+
+# detect source directory
+[ -z "$srcdir" ] && srcdir=`dirname "$0"`
+set -u
+
+loop=0
+while [ ${loop} -lt $LOOPS ]; do
+ loop=`expr ${loop} + 1`
+ echo " loop $loop/$LOOPS starting:"
+ for s in "$srcdir"/*-test; do
+ sh "$s"; r=$?
+ [ $r -ne 0 ] && exit $r
+ sleep 1
+ done
+ if [ ${loop} -lt $LOOPS ]; then
+ echo " waiting $WAIT seconds ..."
+ sleep $WAIT
+ fi
+done
diff --git a/deprecated-ngircd/src/testsuite/tests.sh b/deprecated-ngircd/src/testsuite/tests.sh
new file mode 100755
index 0000000..3e46c18
--- /dev/null
+++ b/deprecated-ngircd/src/testsuite/tests.sh
@@ -0,0 +1,69 @@
+#!/bin/sh
+#
+# ngIRCd Test Suite
+# Copyright (c)2001-2024 Alexander Barton (alex@barton.de) and Contributors.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+# Please read the file COPYING, README and AUTHORS for more information.
+#
+
+# detect source directory
+[ -z "$srcdir" ] && srcdir=`dirname "$0"`
+set -u
+
+name=`basename "$0"`
+test=`echo ${name} | cut -d '.' -f 1`
+[ -d logs ] || mkdir logs
+
+if [ ! -r "$test" ]; then
+ echo "$test: test not found" >>tests-skipped.lst
+ echo "${name}: test \"$test\" not found!"; exit 77
+ exit 1
+fi
+
+# read in functions
+. "${srcdir}/functions.inc"
+
+type expect >/dev/null 2>&1
+if [ $? -ne 0 ]; then
+ echo "$test: \"expect\" not found" >>tests-skipped.lst
+ echo "${name}: \"expect\" not found."
+ exit 77
+fi
+type telnet >/dev/null 2>&1
+if [ $? -ne 0 ]; then
+ echo "$test: \"telnet\" not found" >>tests-skipped.lst
+ echo "${name}: \"telnet\" not found."
+ exit 77
+fi
+
+case "$test" in
+ *ssl*)
+ type openssl >/dev/null 2>&1
+ if [ $? -ne 0 ]; then
+ echo "$test: \"openssl\" not found" >>tests-skipped.lst
+ echo "${name}: \"openssl\" not found."
+ exit 77
+ fi
+ ;;
+esac
+
+# prepare expect script
+e_in="${srcdir}/${test}.e"
+e_tmp="${test}.e_"
+e_exec="$e_in"
+if test -t 1 2>/dev/null; then
+ sed -e 's|^expect |puts -nonewline stderr "."; expect |g' \
+ "$e_in" >"$e_tmp"
+ [ $? -eq 0 ] && e_exec="$e_tmp"
+fi
+
+echo_n "running ${test} ..."
+expect "$e_exec" >logs/${test}.log; r=$?
+[ $r -eq 0 ] && echo " ok." || echo " failure!"
+
+rm -f "$e_tmp"
+exit $r
diff --git a/deprecated-ngircd/src/testsuite/wait-tests.sh b/deprecated-ngircd/src/testsuite/wait-tests.sh
new file mode 100755
index 0000000..b6fa08f
--- /dev/null
+++ b/deprecated-ngircd/src/testsuite/wait-tests.sh
@@ -0,0 +1,44 @@
+#!/bin/sh
+#
+# ngIRCd Test Suite
+# Copyright (c)2001-2024 Alexander Barton (alex@barton.de) and Contributors.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+# Please read the file COPYING, README and AUTHORS for more information.
+#
+
+[ "$1" -gt 0 ] 2>/dev/null && MAX="$1" || MAX=5
+
+# detect source directory
+[ -z "$srcdir" ] && srcdir=`dirname "$0"`
+set -u
+
+PS_FLAGS="-f"
+ps $PS_FLAGS >/dev/null 2>&1
+[ $? -ne 0 ] && PS_FLAGS="a"
+
+# read in functions
+. "${srcdir}/functions.inc"
+
+msg=0
+while true; do
+ count=`ps $PS_FLAGS | grep "expect " | wc -l`
+ count=`expr $count - 1`
+
+ [ $count -le $MAX ] && break
+
+ if [ $msg -lt 1 ]; then
+ echo_n " waiting for processes to settle: "
+ msg=1
+ fi
+
+ # there are still clients connected. Wait ...
+ echo_n "$count>$MAX "
+ sleep 1
+done
+
+[ $msg -gt 0 ] && echo "done: $count"
+exit 0
diff --git a/deprecated-ngircd/src/testsuite/who-test.e b/deprecated-ngircd/src/testsuite/who-test.e
new file mode 100644
index 0000000..55c6570
--- /dev/null
+++ b/deprecated-ngircd/src/testsuite/who-test.e
@@ -0,0 +1,203 @@
+# ngIRCd test suite
+# WHO test
+
+spawn telnet 127.0.0.1 6789
+expect {
+ timeout { exit 1 }
+ "Connected"
+}
+
+send "nick nick\r"
+send "user user . . :Real Name\r"
+expect {
+ timeout { exit 1 }
+ "376"
+}
+
+send "who\r"
+expect {
+ timeout { exit 1 }
+ ":ngircd.test.server 352 nick \* * * ngircd.test.server nick H :0 Real Name"
+}
+
+send "who 0\r"
+expect {
+ timeout { exit 1 }
+ ":ngircd.test.server 352 nick \* * * ngircd.test.server nick H :0 Real Name"
+}
+
+send "away :testing\r"
+expect {
+ timeout { exit 1 }
+ "306 nick"
+}
+
+send "who *\r"
+expect {
+ timeout { exit 1 }
+ ":ngircd.test.server 352 nick \* * * ngircd.test.server nick G :0 Real Name"
+}
+
+send "join #channel\r"
+expect {
+ timeout { exit 1 }
+ "@* JOIN :#channel"
+}
+
+send "who #channel\r"
+expect {
+ timeout { exit 1 }
+ ":ngircd.test.server 352 nick #channel * * ngircd.test.server nick G@ :0 Real Name"
+}
+
+send "mode #channel +v nick\r"
+expect {
+ timeout { exit 1 }
+ "@* MODE #channel +v nick\r"
+}
+
+send "who #channel\r"
+expect {
+ timeout { exit 1 }
+ ":ngircd.test.server 352 nick #channel * * ngircd.test.server nick G@ :0 Real Name"
+}
+
+send "who 127.0.0.*\r"
+expect {
+ timeout { exit 1 }
+ ":ngircd.test.server 352 nick \* * * ngircd.test.server nick G :0 Real Name"
+}
+
+send "mode #channel -o nick\r"
+expect {
+ timeout { exit 1 }
+ "@* MODE #channel -o nick\r"
+}
+
+send "who #channel\r"
+expect {
+ timeout { exit 1 }
+ ":ngircd.test.server 352 nick #channel * * ngircd.test.server nick G+ :0 Real Name"
+}
+
+send "who ngircd.test.server\r"
+expect {
+ timeout { exit 1 }
+ ":ngircd.test.server 352 nick \* * * ngircd.test.server nick G :0 Real Name"
+}
+
+send "part #channel\r"
+expect {
+ timeout { exit 1 }
+ "@* PART #channel :"
+}
+
+send "who Real?Name\r"
+expect {
+ timeout { exit 1 }
+ ":ngircd.test.server 352 nick \* * * ngircd.test.server nick G :0 Real Name"
+}
+
+send "oper TestOp 123\r"
+expect {
+ timeout { exit 1 }
+ "MODE nick :+o"
+}
+expect {
+ timeout { exit 1 }
+ "381 nick"
+}
+
+send "who 0 o\r"
+expect {
+ timeout { exit 1 }
+ ":ngircd.test.server 352 nick \* * * ngircd.test.server nick G* :0 Real Name"
+}
+
+send "away\r"
+expect {
+ timeout { exit 1 }
+ "305 nick"
+}
+
+send "who ??7.*0*\r"
+expect {
+ timeout { exit 1 }
+ ":ngircd.test.server 352 nick \* * * ngircd.test.server nick H* :0 Real Name"
+}
+
+send "join #opers\r"
+expect {
+ timeout { exit 1 }
+ "@* JOIN :#opers"
+}
+
+send "who #opers\r"
+expect {
+ timeout { exit 1 }
+ ":ngircd.test.server 352 nick #opers * * ngircd.test.server nick H*@ :0 Real Name"
+}
+
+send "who Re*me\r"
+expect {
+ timeout { exit 1 }
+ ":ngircd.test.server 352 nick \* * * ngircd.test.server nick H* :0 Real Name"
+}
+
+send "mode #opers -o nick\r"
+expect {
+ timeout { exit 1 }
+ "@* MODE #opers -o nick\r"
+}
+
+send "who #opers\r"
+expect {
+ timeout { exit 1 }
+ ":ngircd.test.server 352 nick #opers * * ngircd.test.server nick H* :0 Real Name"
+}
+
+send "who *.server\r"
+expect {
+ timeout { exit 1 }
+ ":ngircd.test.server 352 nick \* * * ngircd.test.server nick H* :0 Real Name"
+}
+
+send "mode #opers +v nick\r"
+expect {
+ timeout { exit 1 }
+ "@* MODE #opers +v nick\r"
+}
+
+send "who #opers\r"
+expect {
+ timeout { exit 1 }
+ ":ngircd.test.server 352 nick #opers * * ngircd.test.server nick H*+ :0 Real Name"
+}
+
+send "mode #opers +s\r"
+expect {
+ timeout { exit 1 }
+ "@* MODE #opers +s\r"
+}
+
+send "who n?c?\r"
+expect {
+ timeout { exit 1 }
+ ":ngircd.test.server 352 nick \* * ngircd.test.server nick H* :0 Real Name"
+}
+expect {
+ timeout { exit 1 }
+ "315"
+}
+
+send "who #SecretChannel\r"
+expect {
+ timeout { exit 1 }
+ "315"
+}
+
+send "quit\r"
+expect {
+ timeout { exit 1 }
+ "ERROR :Closing connection"
+}
diff --git a/deprecated-ngircd/src/testsuite/whois-test.e b/deprecated-ngircd/src/testsuite/whois-test.e
new file mode 100644
index 0000000..74442ed
--- /dev/null
+++ b/deprecated-ngircd/src/testsuite/whois-test.e
@@ -0,0 +1,77 @@
+# ngIRCd test suite
+# WHOIS test
+
+spawn telnet 127.0.0.1 6789
+expect {
+ timeout { exit 1 }
+ "Connected"
+}
+
+send "nick nick\r"
+send "user user . . :Real Name\r"
+expect {
+ timeout { exit 1 }
+ "376"
+}
+
+send "whois nick\r"
+expect {
+ timeout { exit 1 }
+ "311 nick nick ~user 127.0.0.1 \* :Real Name\r"
+}
+expect {
+ timeout { exit 1 }
+ "318 nick nick :"
+}
+
+send "whois *\r"
+expect {
+ timeout { exit 1 }
+ "311 nick nick ~user 127.0.0.1* \* :Real Name\r"
+}
+
+send "whois n*\r"
+expect {
+ timeout { exit 1 }
+ "311 nick nick ~user 127.0.0.1* \* :Real Name\r"
+}
+
+send "whois ?ick\r"
+expect {
+ timeout { exit 1 }
+ "311 nick nick ~user 127.0.0.1* \* :Real Name\r"
+}
+
+send "whois ????,n?*k\r"
+expect {
+ timeout { exit 1 }
+ "311 nick nick ~user 127.0.0.1* \* :Real Name\r"
+}
+
+send "whois unknown\r"
+expect {
+ timeout { exit 1 }
+ "401 nick unknown :"
+}
+expect {
+ timeout { exit 1 }
+ "318 nick unknown :"
+}
+
+send "whois ngircd.test.server2 nick\r"
+expect {
+ timeout { exit 1 }
+ ":ngircd.test.server2 311 nick nick ~user 127.0.0.1* \* :Real Name\r"
+}
+
+send "whois nosuchserver unknown\r"
+expect {
+ timeout { exit 1 }
+ "402 nick nosuchserver :"
+}
+
+send "quit\r"
+expect {
+ timeout { exit 1 }
+ "ERROR :Closing connection"
+}
diff --git a/deprecated-ngircd/src/tool/Makefile.ng b/deprecated-ngircd/src/tool/Makefile.ng
new file mode 100644
index 0000000..d88bdc9
--- /dev/null
+++ b/deprecated-ngircd/src/tool/Makefile.ng
@@ -0,0 +1,27 @@
+#
+# ngIRCd -- The Next Generation IRC Daemon
+# Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+# Please read the file COPYING, README and AUTHORS for more information.
+#
+
+__ng_Makefile_am_template__
+
+EXTRA_DIST = Makefile.ng
+
+AM_CPPFLAGS = -I$(srcdir)/../portab
+
+noinst_LIBRARIES = libngtool.a
+
+libngtool_a_SOURCES = tool.c
+
+noinst_HEADERS = tool.h
+
+maintainer-clean-local:
+ rm -f Makefile Makefile.in Makefile.am
+
+# -eof-
diff --git a/deprecated-ngircd/src/tool/tool.c b/deprecated-ngircd/src/tool/tool.c
new file mode 100644
index 0000000..35c1ee6
--- /dev/null
+++ b/deprecated-ngircd/src/tool/tool.c
@@ -0,0 +1,249 @@
+/*
+ * ngIRCd -- The Next Generation IRC Daemon
+ * Copyright (c)2001-2018 Alexander Barton (alex@barton.de) and Contributors.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * Please read the file COPYING, README and AUTHORS for more information.
+ */
+
+#include "portab.h"
+
+/**
+ * @file
+ * Tool functions
+ */
+
+#include <assert.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/time.h>
+
+#include <netinet/in.h>
+
+#ifdef SYSLOG
+#define SYSLOG_NAMES 1
+#include <syslog.h>
+#endif
+
+#include "tool.h"
+
+
+/**
+ * Removes all leading and trailing whitespaces of a string.
+ * @param String The string to remove whitespaces from.
+ */
+GLOBAL void
+ngt_TrimStr(char *String)
+{
+ char *start, *end;
+
+ assert(String != NULL);
+
+ start = String;
+
+ /* Remove whitespaces at the beginning of the string ... */
+ while (*start == ' ' || *start == '\t' ||
+ *start == '\n' || *start == '\r')
+ start++;
+
+ if (!*start) {
+ *String = '\0';
+ return;
+ }
+
+ /* ... and at the end: */
+ end = strchr(start, '\0');
+ end--;
+ while ((*end == ' ' || *end == '\t' || *end == '\n' || *end == '\r')
+ && end >= start)
+ end--;
+
+ /* New trailing NULL byte */
+ *(++end) = '\0';
+
+ memmove(String, start, (size_t)(end - start)+1);
+} /* ngt_TrimStr */
+
+
+/**
+ * Convert a string to uppercase letters.
+ */
+GLOBAL char *
+ngt_UpperStr(char *String)
+{
+ char *ptr;
+
+ assert(String != NULL);
+
+ ptr = String;
+ while(*ptr) {
+ *ptr = (char)toupper(*ptr);
+ ptr++;
+ }
+ return String;
+} /* ngt_UpperStr */
+
+
+/**
+ * Convert a string to lowercase letters.
+ */
+GLOBAL char *
+ngt_LowerStr(char *String)
+{
+ char *ptr;
+
+ assert(String != NULL);
+
+ ptr = String;
+ while(*ptr) {
+ *ptr = (char)tolower(*ptr);
+ ptr++;
+ }
+ return String;
+} /* ngt_LowerStr */
+
+
+GLOBAL void
+ngt_TrimLastChr( char *String, const char Chr)
+{
+ /* If last character in the string matches Chr, remove it.
+ * Empty strings are handled correctly. */
+
+ size_t len;
+
+ assert(String != NULL);
+
+ len = strlen(String);
+ if(len == 0)
+ return;
+
+ len--;
+
+ if(String[len] == Chr)
+ String[len] = '\0';
+} /* ngt_TrimLastChr */
+
+
+/**
+ * Fill a String with random chars
+ */
+GLOBAL char *
+ngt_RandomStr(char *String, const size_t len)
+{
+ static const char chars[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz!\"#$&'()*+,-./:;<=>?@[\\]^_`";
+ struct timeval t;
+ size_t i;
+
+ assert(String != NULL);
+
+ gettimeofday(&t, NULL);
+#ifndef HAVE_ARC4RANDOM
+ srand((unsigned)(t.tv_usec * t.tv_sec));
+
+ for (i = 0; i < len; ++i) {
+ String[i] = chars[rand() % (sizeof(chars) - 1)];
+ }
+#else
+ for (i = 0; i < len; ++i)
+ String[i] = chars[arc4random() % (sizeof(chars) - 1)];
+#endif
+ String[len] = '\0';
+
+ return String;
+} /* ngt_RandomStr */
+
+
+#ifdef SYSLOG
+
+
+#ifndef INTERNAL_MARK
+
+#ifndef _code
+typedef struct _code {
+ char *c_name;
+ int c_val;
+} CODE;
+#endif
+
+CODE facilitynames[] = {
+#ifdef LOG_AUTH
+ { "auth", LOG_AUTH },
+#endif
+#ifdef LOG_AUTHPRIV
+ { "authpriv", LOG_AUTHPRIV },
+#endif
+#ifdef LOG_CRON
+ { "cron", LOG_CRON },
+#endif
+#ifdef LOG_DAEMON
+ { "daemon", LOG_DAEMON },
+#endif
+#ifdef LOG_FTP
+ { "ftp", LOG_FTP },
+#endif
+#ifdef LOG_LPR
+ { "lpr", LOG_LPR },
+#endif
+#ifdef LOG_MAIL
+ { "mail", LOG_MAIL },
+#endif
+#ifdef LOG_NEWS
+ { "news", LOG_NEWS },
+#endif
+#ifdef LOG_UUCP
+ { "uucp", LOG_UUCP },
+#endif
+#ifdef LOG_USER
+ { "user", LOG_USER },
+#endif
+#ifdef LOG_LOCAL7
+ { "local0", LOG_LOCAL0 },
+ { "local1", LOG_LOCAL1 },
+ { "local2", LOG_LOCAL2 },
+ { "local3", LOG_LOCAL3 },
+ { "local4", LOG_LOCAL4 },
+ { "local5", LOG_LOCAL5 },
+ { "local6", LOG_LOCAL6 },
+ { "local7", LOG_LOCAL7 },
+#endif
+ { 0, -1 }
+};
+
+#endif
+
+
+GLOBAL const char*
+ngt_SyslogFacilityName(int Facility)
+{
+ int i = 0;
+ while(facilitynames[i].c_name) {
+ if (facilitynames[i].c_val == Facility)
+ return facilitynames[i].c_name;
+ i++;
+ }
+ return "unknown";
+}
+
+
+GLOBAL int
+ngt_SyslogFacilityID(char *Name, int DefaultFacility)
+{
+ int i = 0;
+ while(facilitynames[i].c_name) {
+ if (strcasecmp(facilitynames[i].c_name, Name) == 0)
+ return facilitynames[i].c_val;
+ i++;
+ }
+ return DefaultFacility;
+}
+
+
+#endif
+
+
+/* -eof- */
diff --git a/deprecated-ngircd/src/tool/tool.h b/deprecated-ngircd/src/tool/tool.h
new file mode 100644
index 0000000..b05649a
--- /dev/null
+++ b/deprecated-ngircd/src/tool/tool.h
@@ -0,0 +1,38 @@
+/*
+ * ngIRCd -- The Next Generation IRC Daemon
+ * Copyright (c)2001-2010 Alexander Barton (alex@barton.de)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * Please read the file COPYING, README and AUTHORS for more information.
+ */
+
+#ifndef __tool_h__
+#define __tool_h__
+
+/**
+ * @file
+ * Tool functions (Header)
+ */
+
+#include "portab.h"
+
+GLOBAL void ngt_TrimLastChr PARAMS((char *String, const char Chr ));
+
+GLOBAL void ngt_TrimStr PARAMS((char *String ));
+
+GLOBAL char *ngt_UpperStr PARAMS((char *String ));
+GLOBAL char *ngt_LowerStr PARAMS((char *String ));
+
+GLOBAL char *ngt_RandomStr PARAMS((char *String, const size_t len));
+
+#ifdef SYSLOG
+GLOBAL const char *ngt_SyslogFacilityName PARAMS((int Facility));
+GLOBAL int ngt_SyslogFacilityID PARAMS((char *Name, int DefaultFacility));
+#endif
+
+#endif
+
+/* -eof- */