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
signature.asc
Description: Digital signature
