[balsa/wip/gtk4: 127/351] Improve low-level network library



commit 328fec4ac7a2999e51269730832a95db710d1e90
Author: Albrecht Dreß <albrecht dress arcor de>
Date:   Sat Jan 20 10:59:58 2018 -0500

    Improve low-level network library
    
    Improve low-level network library, POP3 responsiveness on error
    
        * configure.ac: add missing flags and libs for libnetclient unit tests,
        drop sed and ncat prerequisites
        * libbalsa/mailbox_pop3.c: shut down the connection on error,
        so un'refing it does not wait for the QUIT command
        * libnetclient/Makefile.am: fix log domain
        * libnetclient/README: update documentation
        * libnetclient/net-client-pop.c: execute QUIT only if the connection exists
        * libnetclient/net-client-smtp.c: fix FlexeLint warnings
        about ignored function return values,
        execute QUIT only if the connection exists
        * libnetclient/net-client.[ch]: implement new methods
        for shutting down the network connection
        and for checking the connection status
        * libnetclient/test/Makefile.am: drop sed and ncat requirements,
        fix test application build error
        * libnetclient/test/echoserver.py: (new file) trivial echo server in Python
        * libnetclient/test/start-test-env.sh.in: control the echo server for testing
        * libnetclient/test/tests.c: improve unit tests
    
    Signed-off-by: Peter Bloomfield <PeterBloomfield bellsouth net>

 ChangeLog                              |   23 +++++++++++
 configure.ac                           |    5 +-
 libbalsa/mailbox_pop3.c                |    5 ++-
 libnetclient/Makefile.am               |    1 +
 libnetclient/README                    |   18 ++++-----
 libnetclient/net-client-pop.c          |    4 +-
 libnetclient/net-client-smtp.c         |   20 +++++----
 libnetclient/net-client.c              |   66 ++++++++++++++++++++++---------
 libnetclient/net-client.h              |   18 +++++++++
 libnetclient/test/Makefile.am          |    4 +-
 libnetclient/test/echoserver.py        |   54 ++++++++++++++++++++++++++
 libnetclient/test/start-test-env.sh.in |    5 ++-
 libnetclient/test/tests.c              |   45 ++++++++++++----------
 13 files changed, 202 insertions(+), 66 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index a895aa2..ca233f6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,26 @@
+2018-01-20  Albrecht Dreß <albrecht dress arcor de>
+
+       Improve low-level network library, POP3 responsiveness on error
+
+       * configure.ac: add missing flags and libs for libnetclient unit tests,
+       drop sed and ncat prerequisites
+       * libbalsa/mailbox_pop3.c: shut down the connection on error,
+       so un'refing it does not wait for the QUIT command
+       * libnetclient/Makefile.am: fix log domain
+       * libnetclient/README: update documentation
+       * libnetclient/net-client-pop.c: execute QUIT only if the connection exists
+       * libnetclient/net-client-smtp.c: fix FlexeLint warnings
+       about ignored function return values,
+       execute QUIT only if the connection exists
+       * libnetclient/net-client.[ch]: implement new methods
+       for shutting down the network connection
+       and for checking the connection status
+       * libnetclient/test/Makefile.am: drop sed and ncat requirements,
+       fix test application build error
+       * libnetclient/test/echoserver.py: (new file) trivial echo server in Python
+       * libnetclient/test/start-test-env.sh.in: control the echo server for testing
+       * libnetclient/test/tests.c: improve unit tests
+
 2018-01-11  Albrecht Dreß <albrecht dress arcor de>
 
        Fix progress dialogue on error
diff --git a/configure.ac b/configure.ac
index 31943b1..782af48 100644
--- a/configure.ac
+++ b/configure.ac
@@ -457,6 +457,8 @@ if test "x$with_gss" != xno  ; then
       AC_DEFINE(HAVE_GSSAPI,1,[Defined when GSSAPI support is to be compiled.])
       BALSA_CFLAGS="$BALSA_CFLAGS `$KRB5_CONFIG --cflags gssapi`"
       BALSA_LIBS="$BALSA_LIBS `$KRB5_CONFIG --libs gssapi`"
+      LIBNETCLIENT_CFLAGS="$LIBNETCLIENT_CFLAGS `$KRB5_CONFIG --cflags gssapi`"
+      LIBNETCLIENT_LIBS="$LIBNETCLIENT_LIBS `$KRB5_CONFIG --libs gssapi`"
       SAVE_CFLAGS="$CFLAGS"; CFLAGS="$BALSA_CFLAGS"
       AC_CHECK_HEADER([gssapi.h],
                       [AC_DEFINE([HAVE_HEIMDAL],1,[Defined for Heimdal.])],
@@ -698,8 +700,6 @@ fi
 
 if test x$with_libncdtest != xno; then
        AC_CHECK_HEADER([sput.h],[have_sput_h=yes],[have_sput_h=no])
-       AC_PROG_SED
-       AC_PATH_PROGS(NCAT, ncat, no)
        AC_PATH_PROGS(VALGRIND, valgrind, no)
        AC_PATH_PROGS(LCOV, lcov, no)
        AC_PATH_PROGS(GENHTML, genhtml, no)
@@ -708,7 +708,6 @@ if test x$with_libncdtest != xno; then
        AC_PATH_PROGS(SUDO, sudo, no)
        AC_PATH_PROGS(INETSIM, inetsim, no)
        if test "x$have_sput_h" = "xno" || \
-          test "x$NCAT" = "xno" || \
           test "x$VALGRIND" = "xno" || \
           test "x$LCOV" = "xno" || \
           test "x$GENHTML" = "xno" || \
diff --git a/libbalsa/mailbox_pop3.c b/libbalsa/mailbox_pop3.c
index 59871b5..6459404 100644
--- a/libbalsa/mailbox_pop3.c
+++ b/libbalsa/mailbox_pop3.c
@@ -509,6 +509,7 @@ libbalsa_mailbox_pop3_startup(LibBalsaServer            *server,
                libbalsa_information(LIBBALSA_INFORMATION_ERROR, _("POP3 mailbox %s: cannot connect %s: %s"), 
name, server->host,
                        error->message);
                g_error_free(error);
+               net_client_shutdown(NET_CLIENT(pop));
                g_object_unref(G_OBJECT(pop));
                return NULL;
        }
@@ -518,6 +519,7 @@ libbalsa_mailbox_pop3_startup(LibBalsaServer            *server,
        if (!net_client_pop_list(pop, msg_list, !mbox->delete_from_server, &error)) {
                libbalsa_information(LIBBALSA_INFORMATION_ERROR, _("POP3 mailbox %s error: %s"), name, 
error->message);
                g_error_free(error);
+               net_client_shutdown(NET_CLIENT(pop));
                g_object_unref(G_OBJECT(pop));
                pop = NULL;
        }
@@ -682,10 +684,11 @@ libbalsa_mailbox_pop3_check(LibBalsaMailbox * mailbox)
                }
 
                if (!result) {
+                       net_client_shutdown(NET_CLIENT(pop));
                        libbalsa_information(LIBBALSA_INFORMATION_ERROR, _("POP3 error: %s"),
                                              err != NULL ? err->message : "?");
                        if (err != NULL)
-                            g_error_free(err);
+                               g_error_free(err);
                }
 
                /* done - clean up */
diff --git a/libnetclient/Makefile.am b/libnetclient/Makefile.am
index 89da9de..926f816 100644
--- a/libnetclient/Makefile.am
+++ b/libnetclient/Makefile.am
@@ -13,6 +13,7 @@ libnetclient_a_SOURCES =      \
 CLEANFILES = doxygen.log
 SUBDIRS = test
 AM_CFLAGS = $(LIBNETCLIENT_CFLAGS)
+AM_CPPFLAGS = -DG_LOG_DOMAIN=\"libnetclient\"
 
 clean-local:
        -rm -rf html
diff --git a/libnetclient/README b/libnetclient/README
index 72e04c4..b48ecbb 100644
--- a/libnetclient/README
+++ b/libnetclient/README
@@ -62,7 +62,7 @@ are required for running them:
 
 - the Sput Unit Testing Framework for C/C++, available from
   <http://www.use-strict.de/sput-unit-testing/>
-- ncat, available from <https://nmap.org/ncat/>
+- python2
 - screen, available from <https://www.gnu.org/software/screen/>
 - sudo, available from <https://www.sudo.ws/>
 - Valgrind, avilable from <http://valgrind.org/>
@@ -76,9 +76,9 @@ are required for running them:
 Note that most of these requirements are typically available pre-packaged
 for your favorite distribution.
 
-Unfortunately, INetSim 1.2.6 has two little bugs in POP3 handling and does
-not offer pipelining.  The file test/inetsim-1.2.6-POP3.diff contains a
-patch which fixes these issues.
+Unfortunately, INetSim 1.2.6 and 1.2.7 have two little bugs in POP3 handling
+and do not offer pipelining.  The file test/inetsim-1.2.6-POP3.diff contains
+a patch which fixes these issues.
 
 For running the tests, open two terminal windows, and cd to the test folder
 of this package.
@@ -94,9 +94,7 @@ Then, in the second terminal, call
 
        make tests
 
-to build the test application, and run it in Valgrind.  Note that the test
-application will report many CRITICAL glib errors.  This is normal, as the
-behaviour of the library's parameter checks is verified.
+to build the test application, and run it in Valgrind.
 
 The test produces the following output:
 - stdout/stderr: unit test results, which shall report zero failed
@@ -104,9 +102,9 @@ The test produces the following output:
 - gcov/index.html: results of the coverage analysis
 
 Finally, just terminate the test servers in the first window.  Note that
-INetSim will dump further information in its output files (typically in
-/var/log/inetsim).  You should verify that INetSim recorded the requested
-operations properly.
+INetSim will dump further information in its output files in the test
+folder.  You should verify that INetSim recorded the requested operations
+properly.
 
 Note that no unit tests are available for the GSSAPI authentication methods
 as they are not supported by INetSim.
diff --git a/libnetclient/net-client-pop.c b/libnetclient/net-client-pop.c
index 8741d8d..3837427 100644
--- a/libnetclient/net-client-pop.c
+++ b/libnetclient/net-client-pop.c
@@ -396,7 +396,9 @@ net_client_pop_dispose(GObject *object)
        const GObjectClass *parent_class = G_OBJECT_CLASS(net_client_pop_parent_class);
 
        /* send the 'QUIT' command - no need to evaluate the reply or check for errors */
-       (void) net_client_execute(NET_CLIENT(client), NULL, "QUIT", NULL);
+       if (net_client_is_connected(NET_CLIENT(client))) {
+               (void) net_client_execute(NET_CLIENT(client), NULL, "QUIT", NULL);
+       }
 
        (*parent_class->dispose)(object);
 }
diff --git a/libnetclient/net-client-smtp.c b/libnetclient/net-client-smtp.c
index 72e8090..975492a 100644
--- a/libnetclient/net-client-smtp.c
+++ b/libnetclient/net-client-smtp.c
@@ -125,7 +125,7 @@ net_client_smtp_connect(NetClientSmtp *client, gchar **greeting, GError **error)
 
        /* get the greeting */
        if (result) {
-               net_client_set_timeout(NET_CLIENT(client), 5U * 60U);   /* RFC 5321, Sect. 4.5.3.2.1.: 5 
minutes timeout */
+               (void) net_client_set_timeout(NET_CLIENT(client), 5U * 60U);    /* RFC 5321, Sect. 
4.5.3.2.1.: 5 minutes timeout */
                result = net_client_smtp_read_reply(client, 220, greeting, error);
        }
 
@@ -184,6 +184,7 @@ net_client_smtp_can_dsn(NetClientSmtp *client)
 gboolean
 net_client_smtp_send_msg(NetClientSmtp *client, const NetClientSmtpMessage *message, GError **error)
 {
+       NetClient *netclient;
        gboolean result;
        const GList *rcpt;
 
@@ -192,7 +193,8 @@ net_client_smtp_send_msg(NetClientSmtp *client, const NetClientSmtpMessage *mess
                (message->recipients != NULL) && (message->data_callback != NULL), FALSE);
 
        /* set the RFC 5321 sender and recipient(s) */
-       net_client_set_timeout(NET_CLIENT(client), 5U * 60U);   /* RFC 5321, Sect. 4.5.3.2.2., 4.5.3.2.3.: 5 
minutes timeout */
+       netclient = NET_CLIENT(client);         /* convenience pointer */
+       (void) net_client_set_timeout(netclient, 5U * 60U);     /* RFC 5321, Sect. 4.5.3.2.2., 4.5.3.2.3.: 5 
minutes timeout */
        if (client->priv->can_dsn && message->have_dsn_rcpt) {
                if (message->dsn_envid != NULL) {
                        result = net_client_smtp_execute(client, "MAIL FROM:<%s> RET=%s ENVID=%s", NULL, 
error, message->sender,
@@ -218,7 +220,7 @@ net_client_smtp_send_msg(NetClientSmtp *client, const NetClientSmtpMessage *mess
 
        /* initialise sending the message data */
        if (result) {
-               net_client_set_timeout(NET_CLIENT(client), 2U * 60U);   /* RFC 5321, Sect. 4.5.3.2.4.: 2 
minutes timeout */
+               (void) net_client_set_timeout(netclient, 2U * 60U);     /* RFC 5321, Sect. 4.5.3.2.4.: 2 
minutes timeout */
                result = net_client_smtp_execute(client, "DATA", NULL, error);
        }
 
@@ -228,28 +230,28 @@ net_client_smtp_send_msg(NetClientSmtp *client, const NetClientSmtpMessage *mess
                gssize count;
                gchar last_char = '\0';
 
-               net_client_set_timeout(NET_CLIENT(client), 3U * 60U);   /* RFC 5321, Sect. 4.5.3.2.5.: 3 
minutes timeout */
+               (void) net_client_set_timeout(netclient, 3U * 60U);     /* RFC 5321, Sect. 4.5.3.2.5.: 3 
minutes timeout */
                client->priv->data_state = TRUE;
                do {
                        count = message->data_callback(buffer, SMTP_DATA_BUF_SIZE, message->user_data, error);
                        if (count < 0) {
                                result = FALSE;
                        } else if (count > 0) {
-                               result = net_client_write_buffer(NET_CLIENT(client), buffer, (gsize) count, 
error);
+                               result = net_client_write_buffer(netclient, buffer, (gsize) count, error);
                                last_char = buffer[count - 1];
                        } else {
                                /* write termination */
                                if (last_char == '\n') {
-                                       result = net_client_write_buffer(NET_CLIENT(client), ".\r\n", 3U, 
error);
+                                       result = net_client_write_buffer(netclient, ".\r\n", 3U, error);
                                } else {
-                                       result = net_client_write_buffer(NET_CLIENT(client), "\r\n.\r\n", 5U, 
error);
+                                       result = net_client_write_buffer(netclient, "\r\n.\r\n", 5U, error);
                                }
                        }
                } while (result && (count > 0));
        }
 
        if (result) {
-               net_client_set_timeout(NET_CLIENT(client), 10U * 60U);  /* RFC 5321, Sect 4.5.3.2.6.: 10 
minutes timeout */
+               (void) net_client_set_timeout(netclient, 10U * 60U);    /* RFC 5321, Sect 4.5.3.2.6.: 10 
minutes timeout */
                result = net_client_smtp_read_reply(client, -1, NULL, error);
                client->priv->data_state = FALSE;
        }
@@ -358,7 +360,7 @@ net_client_smtp_dispose(GObject *object)
 
        /* send the 'QUIT' command unless we are in 'DATA' state where the server will probably fail to reply 
- no need to evaluate the
         * reply or check for errors */
-       if (!client->priv->data_state) {
+       if (net_client_is_connected(NET_CLIENT(client)) && !client->priv->data_state) {
                (void) net_client_execute(NET_CLIENT(client), NULL, "QUIT", NULL);
                 client->priv->data_state = TRUE;
        }
diff --git a/libnetclient/net-client.c b/libnetclient/net-client.c
index 1332c47..0eb6769 100644
--- a/libnetclient/net-client.c
+++ b/libnetclient/net-client.c
@@ -130,12 +130,48 @@ net_client_connect(NetClient *client, GError **error)
 }
 
 
+void
+net_client_shutdown(const NetClient *client)
+{
+       if (NET_IS_CLIENT(client)) {
+               /* note: we must unref the GDataInputStream, but *not* the GOutputStream! */
+               if (client->priv->istream != NULL) {
+                       g_object_unref(G_OBJECT(client->priv->istream));
+                       client->priv->istream = NULL;
+               }
+               if (client->priv->tls_conn != NULL) {
+                       g_object_unref(G_OBJECT(client->priv->tls_conn));
+                       client->priv->tls_conn = NULL;
+               }
+               if (client->priv->plain_conn != NULL) {
+                       g_object_unref(G_OBJECT(client->priv->plain_conn));
+                       client->priv->plain_conn = NULL;
+               }
+       }
+}
+
+
+gboolean
+net_client_is_connected(NetClient *client)
+{
+       gboolean result;
+
+       if (NET_IS_CLIENT(client) && (client->priv->plain_conn != NULL)) {
+               result = TRUE;
+       } else {
+               result = FALSE;
+       }
+
+       return result;
+}
+
+
 gboolean
 net_client_is_encrypted(NetClient *client)
 {
        gboolean result;
 
-       if (NET_IS_CLIENT(client) && (client->priv->plain_conn != NULL) && (client->priv->tls_conn != NULL)) {
+       if (net_client_is_connected(client) && (client->priv->tls_conn != NULL)) {
                result = TRUE;
        } else {
                result = FALSE;
@@ -425,6 +461,7 @@ net_client_start_tls(NetClient *client, GError **error)
                                client->priv->istream = 
g_data_input_stream_new(g_io_stream_get_input_stream(G_IO_STREAM(client->priv->tls_conn)));
                                g_data_input_stream_set_newline_type(client->priv->istream, 
G_DATA_STREAM_NEWLINE_TYPE_CR_LF);
                                client->priv->ostream = 
g_io_stream_get_output_stream(G_IO_STREAM(client->priv->tls_conn));
+                               g_debug("connection is encrypted");
                        } else {
                                g_object_unref(G_OBJECT(client->priv->tls_conn));
                                client->priv->tls_conn = NULL;
@@ -481,24 +518,15 @@ net_client_dispose(GObject *object)
        const NetClient *client = NET_CLIENT(object);
        const GObjectClass *parent_class = G_OBJECT_CLASS(net_client_parent_class);
 
-       /* note: we must unref the GDataInputStream, but *not* the GOutputStream! */
-        g_clear_object(&client->priv->istream);
-
-        g_clear_object(&client->priv->tls_conn);
-        g_clear_object(&client->priv->plain_conn);
-        g_clear_object(&client->priv->sock);
-        g_clear_object(&client->priv->certificate);
-
-       (*parent_class->dispose)(object);
-}
-
-
-static void
-net_client_finalise(GObject *object)
-{
-       const NetClient *client = NET_CLIENT(object);
-       const GObjectClass *parent_class = G_OBJECT_CLASS(net_client_parent_class);
-
+       net_client_shutdown(client);
+       if (client->priv->sock != NULL) {
+               g_object_unref(G_OBJECT(client->priv->sock));
+               client->priv->sock = NULL;
+       }
+       if (client->priv->certificate != NULL) {
+               g_object_unref(G_OBJECT(client->priv->certificate));
+               client->priv->certificate = NULL;
+       }
        g_debug("finalised connection to %s", client->priv->host_and_port);
        g_free(client->priv->host_and_port);
        (*parent_class->finalize)(object);
diff --git a/libnetclient/net-client.h b/libnetclient/net-client.h
index ea6e756..e92f9b8 100644
--- a/libnetclient/net-client.h
+++ b/libnetclient/net-client.h
@@ -127,11 +127,29 @@ const gchar *net_client_get_host(const NetClient *client);
 gboolean net_client_connect(NetClient *client, GError **error);
 
 
+/** @brief Shut down the connection to a network client
+ *
+ * @param client network client
+ *
+ * Shut down the connection.  Note that it is usually not necessary to call this function, as the connection 
will be shut down when
+ * the client is destroyed by calling <tt>g_object_unref()</tt>.
+ */
+void net_client_shutdown(const NetClient *client);
+
+
 /** @brief Check if a network client is connected
  *
  * @param client network client
  * @return TRUE if the passed network client is connected, FALSE if not
  */
+gboolean net_client_is_connected(NetClient *client);
+
+
+/** @brief Check if a network client is encrypted
+ *
+ * @param client network client
+ * @return TRUE if the passed network client is encrypted, FALSE if not
+ */
 gboolean net_client_is_encrypted(NetClient *client);
 
 
diff --git a/libnetclient/test/Makefile.am b/libnetclient/test/Makefile.am
index d735dc5..a04d45e 100644
--- a/libnetclient/test/Makefile.am
+++ b/libnetclient/test/Makefile.am
@@ -12,7 +12,7 @@ EXTRA_DIST =          \
        cert_u.pem              \
        valgrind.supp
 
-TESTFLAGS = -DNCAT="\"@NCAT@\"" -DSED="\"@SED@\"" -fprofile-arcs -ftest-coverage -g -Wno-error
+TESTFLAGS = -fprofile-arcs -ftest-coverage -g -Wno-error
 
 LCOVFLGS       = --rc lcov_branch_coverage=1
 GENHTMLFLGS    = --function-coverage --branch-coverage --num-spaces 4
@@ -25,7 +25,7 @@ clean-local:
        -rm -rf gcov
 
 tests: tests.c
-       $(CC) $(LIBNETCLIENT_CFLAGS) $(CPPFLAGS) $(TESTFLAGS) -I. -I.. $< $(test_src) -o $@ 
$(LIBNETCLIENT_LIBS)
+       $(CC) $(LIBNETCLIENT_CFLAGS) $(CPPFLAGS) $(TESTFLAGS) -I. -I.. -I../.. $< $(test_src) -o $@ 
$(LIBNETCLIENT_LIBS)
        $(VALGRIND) $(VALGRFLAGS) ./$@
        $(LCOV) $(LCOVFLGS) -c -b $(libsrcdir) -d $(abs_srcdir) --no-external -o $@.covi
        $(LCOV) $(LCOVFLGS) -r $@.covi $< -o $@.covi
diff --git a/libnetclient/test/echoserver.py b/libnetclient/test/echoserver.py
new file mode 100644
index 0000000..ab82730
--- /dev/null
+++ b/libnetclient/test/echoserver.py
@@ -0,0 +1,54 @@
+#!/usr/bin/env python2
+# -*- coding: utf-8 -*-
+# $Id$
+#
+# Echo server listening at port 65000, with the following non-standard
+# features:
+# - any 'x' in the received string is replaced by 'ThisIsLong'
+# - 'DISCONNECT' in the received string causes the connection to be closed
+# 
+# Copyright (C) Albrecht Dreß <mailto:albrecht dress arcor de> 2017
+#
+# This script is free software; you can redistribute it and/or modify it under
+# the terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation; either version 3 of the License, or (at your option)
+# any later version.
+#
+# This script is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+# for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this script. If not, see <http://www.gnu.org/licenses/>.
+
+import sys
+import socket
+
+sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+server_address = ('localhost', 65000)
+sock.bind(server_address)
+sock.listen(1)
+
+while True:
+    connection, client_address = sock.accept()
+    try:
+        comp = False
+        while True:
+            if comp:
+                data = zlib.decompress(connection.recv(2048))
+            else:
+                data = connection.recv(2048)
+            if data:
+                print "received: {}".format(data.strip())
+                if 'DISCONNECT' in data:
+                    break
+                data = data.replace('x', 'ThisIsLong')
+                if comp:
+                    connection.sendall(zlib.compress(data))
+                else:
+                    connection.sendall(data)
+            else:
+                break
+    finally:
+        connection.close()
diff --git a/libnetclient/test/start-test-env.sh.in b/libnetclient/test/start-test-env.sh.in
index acb8e4b..e1f10fd 100644
--- a/libnetclient/test/start-test-env.sh.in
+++ b/libnetclient/test/start-test-env.sh.in
@@ -3,6 +3,8 @@
 
 echo "starting test environment:"
 
+echo "echo server @ port 65000 as e_echo..."
+@SCREEN@ -d -m -S e_echo @abs_srcdir@/echoserver.py
 echo "GnuTLS server w/o client checking @ port 65001 as s_server1..."
 @SCREEN@ -d -m -S s_server1 \
        @GTLSSRV@ -a --x509keyfile=cert_u.pem --x509certfile=cert_u.pem --echo -p 65001
@@ -19,6 +21,7 @@ rm -f debug.log main.log service.log report.*.txt
 chmod 666 debug.log main.log service.log report.*.txt
 EOF
 
-echo "shut down GnuTLS servers..."
+echo "shut down echo and GnuTLS servers..."
+@SCREEN@ -S e_echo -X quit
 @SCREEN@ -S s_server1 -X quit
 @SCREEN@ -S s_server2 -X quit
diff --git a/libnetclient/test/tests.c b/libnetclient/test/tests.c
index 6675007..12ecbb3 100644
--- a/libnetclient/test/tests.c
+++ b/libnetclient/test/tests.c
@@ -1,8 +1,15 @@
-/*
- * tests.c
+/* NetClient - simple line-based network client library
  *
- *  Created on: 07.01.2017
- *      Author: albrecht
+ * Copyright (C) Albrecht Dreß <mailto:albrecht dress arcor de> 2017
+ *
+ * This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser 
General Public License
+ * as published by the Free Software Foundation; either version 3 of the License, or (at your option) any 
later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even 
the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more 
details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License along with this library. If not, 
see
+ * <http://www.gnu.org/licenses/>.
  */
 
 #include <sys/types.h>
@@ -22,9 +29,17 @@ static void test_pop3(void);
 static void test_utils(void);
 
 
+static void
+log_dummy(const gchar G_GNUC_UNUSED *log_domain, GLogLevelFlags G_GNUC_UNUSED log_level,
+          const gchar G_GNUC_UNUSED *message, gpointer G_GNUC_UNUSED user_data)
+{
+}
+
 int
 main(G_GNUC_UNUSED int argc, G_GNUC_UNUSED char **argv)
 {
+       g_log_set_default_handler(log_dummy, NULL);
+
        sput_start_testing();
 
        sput_enter_suite("test basic (plain)");
@@ -51,16 +66,14 @@ main(G_GNUC_UNUSED int argc, G_GNUC_UNUSED char **argv)
 static void
 test_basic(void)
 {
-       static gchar *nc_args[] = { NCAT, "-l", "65000", "--exec", SED " -u -e s/x/ThisIsLong/g", NULL };
        NetClient *basic;
-       GPid child;
        GError *error = NULL;
        gboolean op_res;
        gchar *read_res;
 
        sput_fail_unless(net_client_new(NULL, 65000, 42) == NULL, "missing host");
 
-       sput_fail_unless((basic = net_client_new("localhost", 65000, 42)) != NULL, "localhost; port 65000");
+       sput_fail_unless((basic = net_client_new("localhost", 64999, 42)) != NULL, "localhost; port 64999");
        sput_fail_unless(net_client_get_host(NULL) == NULL, "get host w/o client");
        sput_fail_unless(strcmp(net_client_get_host(basic), "localhost") == 0, "read host ok");
        sput_fail_unless(net_client_connect(basic, NULL) == FALSE, "connect failed");
@@ -81,14 +94,6 @@ test_basic(void)
        sput_fail_unless((op_res == FALSE) && (error->code == NET_CLIENT_ERROR_NOT_CONNECTED), "read line w/o 
connection");
        g_clear_error(&error);
 
-       op_res =
-               g_spawn_async(NULL, nc_args, NULL, G_SPAWN_STDOUT_TO_DEV_NULL + G_SPAWN_STDERR_TO_DEV_NULL, 
NULL, NULL, &child, &error);
-       if (!op_res) {
-               g_error("launching %s failed: %s", nc_args[0], error->message);
-               g_assert_not_reached();
-       }
-       sleep(1);
-
        sput_fail_unless(net_client_connect(basic, NULL) == TRUE, "connect succeeded");
        op_res = net_client_connect(basic, &error);
        sput_fail_unless((op_res == FALSE) && (error->code == NET_CLIENT_ERROR_CONNECTED), "cannot connect 
already connected");
@@ -132,7 +137,7 @@ test_basic(void)
        sput_fail_unless((op_res == FALSE) && (error->code == NET_CLIENT_ERROR_LINE_TOO_LONG), "read line too 
long");
        g_clear_error(&error);
 
-       kill(child, SIGTERM);
+       sput_fail_unless(net_client_write_buffer(basic, "DISCONNECT\r\n", 12U, NULL) == TRUE, "disconnect");
 
        op_res = net_client_read_line(basic, NULL, &error);
        sput_fail_unless((op_res == FALSE) && (error->code = NET_CLIENT_ERROR_CONNECTION_LOST), "read line, 
client lost");
@@ -185,9 +190,9 @@ test_basic_crypt(void)
        op_res = net_client_start_tls(basic, &error);
        sput_fail_unless((op_res == FALSE) && (error != NULL), "start tls: bad server cert");
        g_clear_error(&error);
-       g_object_unref(basic);
 
-       sput_fail_unless((basic = net_client_new("localhost", 65001, 42)) != NULL, "localhost; port 65001");
+       net_client_shutdown(basic);
+
        g_signal_connect(G_OBJECT(basic), "cert-check", G_CALLBACK(check_cert), NULL);
        sput_fail_unless(net_client_connect(basic, NULL) == TRUE, "connect ok");
        sput_fail_unless(net_client_start_tls(basic, NULL) == TRUE, "start tls: success");
@@ -329,7 +334,7 @@ test_smtp(void)
        sput_fail_unless(net_client_smtp_new("localhost", 0, 0) == NULL, "new, bad crypt mode");
        sput_fail_unless(net_client_smtp_new("localhost", 0, 42) == NULL, "new, bad crypt mode");
 
-       sput_fail_unless((smtp = net_client_smtp_new("localhost", 65000, NET_CLIENT_CRYPT_NONE)) != NULL, 
"localhost; port 65000");
+       sput_fail_unless((smtp = net_client_smtp_new("localhost", 65024, NET_CLIENT_CRYPT_NONE)) != NULL, 
"localhost; port 65024");
        sput_fail_unless(net_client_smtp_connect(smtp, NULL, NULL) == FALSE, "no server");
        g_object_unref(smtp);
 
@@ -500,7 +505,7 @@ test_pop3(void)
        net_client_pop_msg_info_free(NULL);             // just for checking
 
        // some basic stuff
-       sput_fail_unless((pop = net_client_pop_new("localhost", 65000, NET_CLIENT_CRYPT_NONE, TRUE)) != NULL, 
"localhost; port 65000");
+       sput_fail_unless((pop = net_client_pop_new("localhost", 65109, NET_CLIENT_CRYPT_NONE, TRUE)) != NULL, 
"localhost; port 65109");
        sput_fail_unless(net_client_pop_connect(pop, NULL, NULL) == FALSE, "no server");
        g_object_unref(pop);
 


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