Dear all,

tisdag den  9 november 2010 klockan 18:26 skrev Alfred M. Szmidt detta:
>    diff --git a/tests/addrpeek.c b/tests/addrpeek.c
>    new file mode 100644
>    index 0000000..d68545a
>    --- /dev/null
>    +++ b/tests/addrpeek.c
>    @@ -0,0 +1,112 @@
>    +/*
> 
> We have been bad at this, but a single line at the top to describe the
> intent of the file would be grand
> 
>    +int
>    +main (int argc, char *argv[], char *envp[])
>                                   ^^^^^^^^^^^^
> 
> Not portable, C only guarantees either void or "int, char **" (or
> similar) as prototype.

I ask for permission to push a revised edition of "tests/addrpeek.c".
Both points above have been addressed, and Simon's suggestion to
include "config.h" works well. The code now builds and executes
correctly for GNU/Linux, GNU/kFreeBSD, OpenBSD, and FreeBSD.

There is one issue with HAVE_DECL_ENVIRON, since it is set only
for GNU/Linux and GNU/kFreeBSD, neither for OpenBSD nor FreeBSD.
Yet all four have a functional

   extern char **environ;

This is due to the declaration in <unistd.h> for glibc, but which
is lacking for *BSD. I did spend substantial time to develop something
similar to

   #if HAVE_DECL_ENVIRON || GNULIB_ENVIRON
   extern char **environ;
   #endif

but I never was able to detect GNULIB_ENVIRON in the C code itself.
Therefore I removed all tests in the end. They will have to be inserted
later on again.

It it my hope that this will not prevent me from getting a permission
to push this contribution.


Best regards,

Mats  
From 8ef5cf47d8f47c819b911ada94763367b8c5869d Mon Sep 17 00:00:00 2001
From: Mats Erik Andersson <[email protected]>
Date: Tue, 23 Nov 2010 00:22:41 +0100
Subject: [PATCH 2/2] addrpeek: New test service for Inetd.

---
 ChangeLog         |    6 ++
 tests/Makefile.am |    4 ++
 tests/addrpeek.c  |  135 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 145 insertions(+), 0 deletions(-)
 create mode 100644 tests/addrpeek.c

diff --git a/ChangeLog b/ChangeLog
index 9829038..aec9d50 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,11 @@
 2010-11-22  Mats Erik Andersson <[email protected]>
 
+	* tests/addrpeek.c: New file.
+	* tests/Makefile.am: Register `addrpeek' using
+	`check_PROGRAMS', but conditioned on `ENABLE_inetd'.
+
+2010-11-22  Mats Erik Andersson <[email protected]>
+
 	* src/inetd.c (prepenv): New prototype:
 	`prepenv(int, struct sockaddr *, socklen_t)'.
 	(prepenv): Change type of IP to `char []' of fixed length.
diff --git a/tests/Makefile.am b/tests/Makefile.am
index cce19ee..1327c5e 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -21,6 +21,10 @@ AM_CPPFLAGS = -I$(top_srcdir)/libinetutils -I$(top_srcdir)/lib
 LDADD = -L../libinetutils -linetutils  ../lib/libgnu.a
 
 check_PROGRAMS = localhost
+if ENABLE_inetd
+check_PROGRAMS += addrpeek
+endif
+
 dist_check_SCRIPTS =
 if ENABLE_ping
 dist_check_SCRIPTS += ping-localhost.sh
diff --git a/tests/addrpeek.c b/tests/addrpeek.c
new file mode 100644
index 0000000..5eae6d1
--- /dev/null
+++ b/tests/addrpeek.c
@@ -0,0 +1,135 @@
+/* addrpeek - testing service for Inetd: remote address, environment vars
+  Copyright (C) 2010 Free Software Foundation, Inc.
+
+  This file is part of GNU Inetutils.
+
+  GNU Inetutils 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 3 of the License, or (at
+  your option) any later version.
+
+  GNU Inetutils 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
+  General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see `http://www.gnu.org/licenses/'. */
+
+/* Written by Mats Erik Andersson.  */
+
+/* Addrpeek is a test client for examining Inetd, primarily TCP traffic.
+ * The client executes all those tasks that were listed as server
+ * arguments in the configuration file for Inetd:
+ *
+ *    addr : Reply with "Your address is $IP."
+ *    env  : Reply with all known environment variables and their values.
+ *
+ * Reasonable entries in `inetf.conf' could be
+ *
+ *    # Return numerical address of the calling client.
+ *    #
+ *    7890 stream tcp nowait nobody /tmp/addrpeek addrpeek addr
+ *    7890 stream tcp6 nowait nobody /tmp/addrpeek addrpeek addr
+ *    #
+ *    # Display all environment variables in use, and append
+ *    # the client's address at the end.
+ *    #
+ *    tcpmux stream tcp nowait nobody internal
+ *    tcpmux stream tcp6 nowait nobody internal
+ *    tcpmux/env stream tcp nowait nobody /tmp/addrpeek addrkeep env addr
+ */
+
+#include "config.h"
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+
+#ifndef SEPARATOR
+# define SEPARATOR "\n"
+#endif
+
+/* TODO Develop some reliable test for the existence of ENVIRON.
+ * It is detectable using HAVE_DECL_ENVIRON for GNU/Linux and
+ * GNU/kFreeBSD. It is present, but not detectable for OpenBSD
+ * and FreeBSD.
+ */ 
+extern char **environ;
+
+static void
+write_address (int fd)
+{
+  int type;
+  size_t len;
+  socklen_t sslen;
+  char addr[INET6_ADDRSTRLEN], answer[128];
+  struct sockaddr_storage ss;
+
+  sslen = sizeof (type);
+  getsockopt (fd, SOL_SOCKET, SO_TYPE, &type, &sslen);
+
+  if (type == SOCK_STREAM)
+    {
+      sslen = sizeof (ss);
+      getpeername (fd, (struct sockaddr *) &ss, &sslen);
+    }
+  else if (type == SOCK_DGRAM)
+    {
+      sslen = sizeof (ss);
+      recvfrom (fd, answer, sizeof (answer), 0,
+                  (struct sockaddr *) &ss, &sslen);
+      shutdown (fd, SHUT_RD);
+    }
+  else
+      return;
+
+  getnameinfo ((struct sockaddr *) &ss, sslen, addr, sizeof (addr),
+                NULL, 0, NI_NUMERICHOST);
+
+  len = snprintf (answer, sizeof (answer),
+                  "Your address is %s." SEPARATOR, addr);
+
+  sendto (fd, answer, len, 0, (struct sockaddr *) &ss, sslen);
+}
+
+void
+write_environment (int fd, char *envp[])
+{
+  for ( ; *envp; ++envp)
+    {
+      write (fd, *envp, strlen (*envp));
+      write (fd, SEPARATOR, strlen (SEPARATOR));
+    }
+}
+
+int
+main (int argc, char *argv[])
+{
+  int j;
+
+  for (j = 1; j < argc; ++j)
+    {
+      if (strncmp (argv[j], "addr", strlen ("addr")) == 0)
+        {
+          write_address (STDOUT_FILENO);
+          continue;
+        }
+
+      if (strncmp (argv[j], "env", strlen ("env")) == 0)
+        {
+          write_environment (STDOUT_FILENO, environ);
+          continue;
+        }
+    }
+
+  close (STDIN_FILENO);
+  close (STDOUT_FILENO);
+  close (STDERR_FILENO);
+
+  return EXIT_SUCCESS;
+}
-- 
1.7.2.3

Attachment: signature.asc
Description: Digital signature

Reply via email to