contrib: Move scripts content to scripts/Makefile
authorng0 <ng0@n0.is>
Tue, 19 Mar 2019 16:42:33 +0000 (16:42 +0000)
committerng0 <ng0@n0.is>
Tue, 19 Mar 2019 17:07:20 +0000 (17:07 +0000)
Actually build the contrib perl script.
Add an m4 script for perl.

configure.ac
contrib/Makefile.am
contrib/scripts/Makefile.am [new file with mode: 0644]
contrib/scripts/documentation/gnunet-doc.scm [deleted file]
contrib/scripts/gnunet-logread/Makefile.am [new file with mode: 0644]
contrib/scripts/gnunet-logread/gnunet-logread [deleted file]
contrib/scripts/gnunet-logread/gnunet-logread-ipc-sdedit [deleted file]
contrib/scripts/gnunet-logread/gnunet-logread-ipc-sdedit.in [new file with mode: 0755]
contrib/scripts/gnunet-logread/gnunet-logread.in [new file with mode: 0755]
m4/perl.m4 [new file with mode: 0644]

index d69683ff831d27605b65d28a467cccaf88060b22..a8c80eb7db97e6b282c18c0b2c54df1f15c3bde1 100644 (file)
@@ -214,6 +214,11 @@ AM_PATH_PYTHON([3.7],, [:])
 AC_SUBST([PYTHON])
 AM_CONDITIONAL([HAVE_PYTHON], [test "$PYTHON" != :])
 
+# perl
+AC_PATH_PROG( PERL, perl, ,
+              $PATH:/usr/local/bin/perl:/usr/bin/:/usr/local/bin )
+AC_SUBST([PERL])
+
 # iptables is a soft requirement to run tests
 AC_PATH_TARGET_TOOL(VAR_IPTABLES_BINARY, iptables, false)
 
@@ -1722,6 +1727,8 @@ AC_DEFINE_UNQUOTED(VCS_VERSION, [$vcs_version], [VCS revision/hash or tarball ve
 AC_CONFIG_FILES([
 Makefile
 contrib/Makefile
+contrib/scripts/Makefile
+contrib/scripts/gnunet-logread/Makefile
 doc/Makefile
 doc/man/Makefile
 doc/doxygen/Makefile
index 49aa36dfd4291c57087964d72b0b2df5d93af292..ff1d1fbbb6138950e5378f5f44f906f6e3fa0e41 100644 (file)
@@ -5,13 +5,7 @@ tap32dir = $(pkgdatadir)/openvpn-tap32/tapw32/
 
 tap64dir = $(pkgdatadir)/openvpn-tap32/tapw64/
 
-noinst_SCRIPTS = \
- scripts/terminate.py \
- scripts/pydiffer.py \
- scripts/removetrailingwhitespace.py \
- scripts/gnunet_pyexpect.py \
- scripts/gnunet_janitor.py \
- scripts/gnunet-chk.py
+SUBDIRS = scripts
 
 dist_pkgdata_DATA = \
  gns/gns-bcd.html \
@@ -46,14 +40,6 @@ EXTRA_DIST = \
  conf/gnunet/no_autostart_above_core.conf \
  conf/nss/nssswitch.conf \
  conf/wireshark/wireshark.lua \
- scripts/coverage.sh \
- scripts/terminate.py.in \
- scripts/gnunet_pyexpect.py.in \
- scripts/gnunet_janitor.py.in \
- scripts/gnunet-chk.py.in \
- scripts/gnunet-bugreport \
- scripts/removetrailingwhitespace.py.in \
- scripts/pydiffer.py.in \
  packages/nix/default.nix \
  packages/nix/gnunet-dev.nix \
  3rdparty/Windows/openvpn-tap32/tapw32/tap0901.sys \
@@ -67,27 +53,6 @@ EXTRA_DIST = \
  3rdparty/Windows/openvpn-tap32/tap32-source-2.1.zip \
  $(INITD_FILES)
 
-CLEANFILES = \
-  $(noinst_SCRIPTS)
-
-do_subst = $(SED) -e 's,[@]PYTHON[@],$(PYTHON),g'
-
-# Use SUFFIX Extension rules, they are more portable for every
-# implementation of 'make'.
-# You'll also run into the "'%' is a GNU make extension warning"
-# if you use this:
-#
-#%.py: %.py.in Makefile
-#      $(do_subst) < $< > $@
-#      chmod +x $@
-#
-# instead of this:
-SUFFIXES = .py.in .py
-
-.py.in.py:
-       $(do_subst) < $< > $@
-       chmod +x $@
-
 check_PROGRAMS = \
  test_gnunet_prefix
 
diff --git a/contrib/scripts/Makefile.am b/contrib/scripts/Makefile.am
new file mode 100644 (file)
index 0000000..a9eadf3
--- /dev/null
@@ -0,0 +1,43 @@
+# This Makefile.am is in the public domain
+AM_CPPFLAGS = -I$(top_srcdir)/src/include -I$(top_builddir)/src/include
+
+SUBDIRS = gnunet-logread
+
+noinst_SCRIPTS = \
+ terminate.py \
+ pydiffer.py \
+ removetrailingwhitespace.py \
+ gnunet_pyexpect.py \
+ gnunet_janitor.py \
+ gnunet-chk.py
+
+EXTRA_DIST = \
+ coverage.sh \
+ terminate.py.in \
+ gnunet_pyexpect.py.in \
+ gnunet_janitor.py.in \
+ gnunet-chk.py.in \
+ gnunet-bugreport \
+ removetrailingwhitespace.py.in \
+ pydiffer.py.in
+
+CLEANFILES = \
+  $(noinst_SCRIPTS)
+
+do_subst = $(SED) -e 's,[@]PYTHON[@],$(PYTHON),g'
+
+# Use SUFFIX Extension rules, they are more portable for every
+# implementation of 'make'.
+# You'll also run into the "'%' is a GNU make extension warning"
+# if you use this:
+#
+#%.py: %.py.in Makefile
+#      $(do_subst) < $< > $@
+#      chmod +x $@
+#
+# instead of this:
+SUFFIXES = .py.in .py
+
+.py.in.py:
+       $(do_subst) < $< > $@
+       chmod +x $@
diff --git a/contrib/scripts/documentation/gnunet-doc.scm b/contrib/scripts/documentation/gnunet-doc.scm
deleted file mode 100644 (file)
index 077efac..0000000
+++ /dev/null
@@ -1,182 +0,0 @@
-;;; This file is part of GNUnet.
-;;; Copyright (C) 2016, 2017 GNUnet e.V.
-;;;
-;;; GNUnet is free software: you can redistribute it and/or modify it
-;;; under the terms of the GNU Affero General Public License as published
-;;; by the Free Software Foundation, either version 3 of the License, or
-;;; (at your option) any later version.
-;;;
-;;; GNUnet 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
-;;; Affero General Public License for more details.
-;;;
-;;; You should have received a copy of the GNU Affero General Public License
-;;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
-;;;
-
-(use-modules
- (ice-9 popen)
- (ice-9 match)
- (ice-9 rdelim)
- (guix packages)
- (guix build-system gnu)
- (guix gexp)
- ((guix build utils) #:select (with-directory-excursion))
- (guix git-download)
- (guix utils) ; current-source-directory
- (gnu packages)
- (gnu packages aidc)
- (gnu packages autotools)
- (gnu packages backup)
- (gnu packages base)
- (gnu packages compression)
- (gnu packages curl)
- (gnu packages databases)
- (gnu packages file)
- (gnu packages gettext)
- (gnu packages glib)
- (gnu packages gnome)
- (gnu packages gnunet)
- (gnu packages gnupg)
- (gnu packages gnuzilla)
- (gnu packages groff)
- (gnu packages gstreamer)
- (gnu packages gtk)
- (gnu packages guile)
- (gnu packages graphviz)
- (gnu packages image)
- (gnu packages image-viewers)
- (gnu packages libidn)
- (gnu packages libunistring)
- (gnu packages linux)
- (gnu packages maths)
- (gnu packages multiprecision)
- (gnu packages perl)
- (gnu packages pkg-config)
- (gnu packages pulseaudio)
- (gnu packages python)
- (gnu packages tex)
- (gnu packages texinfo)
- (gnu packages tex)
- (gnu packages tls)
- (gnu packages video)
- (gnu packages web)
- (gnu packages xiph)
- ;;(gnunet packages texlive) ;GNUnet module including texlive-2012 WIP
- ((guix licenses) #:prefix license:))
-
-;;(define %source-dir (string-append (current-source-directory)
-;;                                   "/../../../"))
-(define %source-dir (dirname (current-filename)))
-
-(define gnunet-doc
-  (let* ((revision "2")
-         (select? (delay (or (git-predicate
-                              (string-append (current-source-directory)
-                                             "/../../../"))
-                             source-file?))))
-    (package
-      (name "gnunet-doc")
-      (version (string-append "0.10.1-" revision "." "dev"))
-      (source
-       (local-file ;;"../../.."
-        ;;%source-dir
-        ;;(string-append (getcwd) "/../../../")
-        (string-append (getcwd)) ;drrty hack and this assumes one static position FIXME!
-        #:recursive? #t))
-      ;;#:select? (git-predicate %source-dir)))
-      ;;#:select? (force select?)))
-      (build-system gnu-build-system)
-      (inputs
-       `(("glpk" ,glpk)
-         ("gnurl" ,gnurl)
-         ("gstreamer" ,gstreamer)
-         ("gst-plugins-base" ,gst-plugins-base)
-         ("gnutls/dane" ,gnutls/dane)
-         ("libextractor" ,libextractor)
-         ("libgcrypt" ,libgcrypt)
-         ("libidn" ,libidn)
-         ("libmicrohttpd" ,libmicrohttpd)
-         ("libltdl" ,libltdl)
-         ("libunistring" ,libunistring)
-         ("openssl" ,openssl)
-         ("opus" ,opus)
-         ("pulseaudio" ,pulseaudio)
-         ("sqlite" ,sqlite)
-         ("postgresql" ,postgresql)
-         ("mysql" ,mariadb)
-         ("zlib" ,zlib)
-         ("perl" ,perl)
-         ("python-2" ,python-2) ; tests and gnunet-qr
-         ("jansson" ,jansson)
-         ("nss" ,nss)
-         ("glib" ,glib "bin")
-         ("gmp" ,gmp)
-         ("bluez" ,bluez) ; for optional bluetooth feature
-         ("glib" ,glib)
-         ;;("texlive-minimal" ,texlive-minimal) ; optional.
-         ("texlive" ,texlive) ;TODO: Stabilize Texlive-2012 package
-         ("libogg" ,libogg)))
-      (native-inputs
-       `(("pkg-config" ,pkg-config)
-         ("autoconf" ,autoconf)
-         ("automake" ,automake)
-         ("gnu-gettext" ,gnu-gettext)
-         ("graphviz" ,graphviz) ; dot
-         ("texinfo-5" ,texinfo-5) ; Debian stable
-         ("which" ,which)
-         ("libtool" ,libtool)))
-      (arguments
-       `(#:configure-flags
-         (list "--enable-documentation")
-         #:tests? #f ;Don't run tests
-         #:phases
-         (modify-phases %standard-phases
-           (add-after 'unpack 'autoconf
-             (lambda _
-               (substitute* "bootstrap"
-                 (("contrib/pogen.sh") "sh contrib/pogen.sh"))
-               (for-each (lambda (f) (chmod f #o755))
-                         (find-files "po" ""))
-               (zero? (system* "sh" "bootstrap"))))
-           (add-after 'build 'run-gendocs
-             (lambda _
-               (chdir "doc/documentation")
-               ;;(zero? (system* "make" "dev-build"))))
-               (zero? (system* "sh" "run-gendocs.sh"))))
-           ;; (zero? (system* "make" "pdf"))
-           ;; (zero? (system* "make" "html"))
-           ;; (zero? (system* "make" "info"))))
-           ;;(zero? (system* "make" "doc-all-give-me-the-noise"))))
-           (replace 'install
-             (lambda _
-               (zero? (system* "make" "doc-gendoc-install")))))))
-      ;;(lambda* (#:key outputs #:allow-other-keys)
-      ;; (let* ((out (assoc-ref outputs "out"))
-      ;;        (doc (string-append out "/share/doc/gnunet")))
-      ;;   (mkdir-p doc)
-      ;;   (copy-recursively "images"
-      ;;                     (string-append doc
-      ;;                                    "/images"))
-      ;;   (mkdir-p (string-append doc "/gnunet"))
-      ;;   (install-file "gnunet.pdf" doc)
-      ;;   (install-file "gnunet.info" doc)
-      ;;   (install-file "gnunet.log" doc) ;TODO: Move to 'dev' output?
-      ;;   (copy-recursively "gnunet"
-      ;;                     (string-append doc
-      ;;                                    "/gnunet"))
-      ;;   (install-file "gnunet-c-tutorial.pdf" doc)
-      ;;   (install-file "gnunet-c-tutorial.info" doc)
-      ;;   (install-file "gnunet-c-tutorial.log" doc) ;TODO: Move to 'dev' output?
-      ;;   (copy-recursively "gnunet-c-tutorial"
-      ;;                     (string-append doc
-      ;;                                    "/gnunet-c-tutorial")))
-      ;; #t)))))
-      (synopsis "Documentation of GNUnet")
-      (description
-       "GNUnet documentation build")
-      (license (list license:fdl1.3+ license:gpl3+))
-      (home-page "https://gnunet.org/"))))
-
-gnunet-doc
diff --git a/contrib/scripts/gnunet-logread/Makefile.am b/contrib/scripts/gnunet-logread/Makefile.am
new file mode 100644 (file)
index 0000000..82c9949
--- /dev/null
@@ -0,0 +1,22 @@
+# This Makefile.am is in the public domain
+AM_CPPFLAGS = -I$(top_srcdir)/src/include -I$(top_builddir)/src/include
+
+do_subst = $(SED) -e 's,[@]PERL[@],$(PERL),g'
+
+SUFFIXES = .in
+
+gnunet-logread: gnunet-logread.in Makefile
+       $(do_subst) < $(srcdir)/gnunet-logread.in > gnunet-logread
+       chmod +x gnunet-logread
+
+gnunet-logread-ipc-sdedit: gnunet-logread-ipc-sdedit.in Makefile
+       $(do_subst) < $(srcdir)/gnunet-logread-ipc-sdedit.in > gnunet-logread-ipc-sdedit
+       chmod +x gnunet-logread-ipc-sdedit
+
+CLEANFILES=    \
+               gnunet-logread \
+               gnunet-logread-ipc-sdedit
+
+noinst_SCRIPTS =               \
+               $(CLEANFILES) \
+               gnunet-logread-ipc
diff --git a/contrib/scripts/gnunet-logread/gnunet-logread b/contrib/scripts/gnunet-logread/gnunet-logread
deleted file mode 100755 (executable)
index 9b1c654..0000000
+++ /dev/null
@@ -1,198 +0,0 @@
-#!@PERL@
-# helper tool to make gnunet logs more readable
-# try 'gnunet-logread -h' for usage
-
-use strict;
-use warnings;
-my $DEFAULT_SOCKET = '/tmp/gnunet-logread-ipc.sock';
-
-print STDERR <<X if -t STDIN and $#ARGV == -1;
-*** For a usage message, try '$0 -h'.
-*** For documentation, try 'perldoc $0'.
-*** Listening for GNUNET_log events on STDIN. Type CTRL-D to terminate.
-
-X
-
-use Getopt::Std;
-my (%opts, $name, $ipc, $msg_level, $msg_regex);
-getopts ('i:x:n:s:L:m:fhq', \%opts);
-
-use Pod::Usage qw( pod2usage );
-die pod2usage if $opts{h};
-
-use POSIX qw(mkfifo);
-
-use Term::ANSIColor qw(:constants :pushpop);
-$Term::ANSIColor::AUTOLOCAL = 1;
-
-my %levels = ( NONE => 0, ERROR => 1, WARNING => 2, INFO => 4, DEBUG => 8 );
-
-# Message type numbers to names
-my %msgtypes;
-my $prefix = $ENV{GNUNET_PREFIX} || '/usr';
-my $filename = "$prefix/include/gnunet/gnunet_protocols.h";
-$ipc = $opts{s} || $DEFAULT_SOCKET;
-
-if (open HEADER, $filename)
-{
-    while (<HEADER>)
-    {
-        $msgtypes{$2} = $1 if /^\s*#define\s+GNUNET_MESSAGE_TYPE_(\w+)\s+(\d+)/i;
-    }
-    close HEADER;
-} else {
-    warn <<X;
-Could not read $filename for message codes:
-       $!.
-Please provide a \$GNUNET_PREFIX environment variable to replace "/usr".
-Try also '$0 -h' for help.
-
-X
-}
-
-die "You can't read and write the socket at the same time"
-  if exists $opts{f} and exists $opts{n};
-
-if ((exists $opts{n} or exists $opts{f}) and not -r $ipc) {
-    undef $!;
-    die "Could not mkfifo $ipc: $!" unless mkfifo $ipc, 0600;
-    system('chgrp', 'gnunet', $ipc);
-    die "Could not chgrp $ipc to 'gnunet': $!" if $!;
-    chmod 0660, $ipc;
-    die "Could not chmod $ipc to allow gnunet group writes: $!" if $!;
-}
-
-if (exists $opts{n}) {
-    $name = $opts{n};
-    $msg_level = $opts{L} && exists $levels{$opts{L}} ? $levels{$opts{L}} : 0;
-    $msg_regex = $opts{m};
-    print STDERR "RE: /$msg_regex/\n" if defined $msg_regex;
-    open O, '>', $ipc or die "Cannot write to $ipc: $!";
-}
-
-if (exists $opts{f}) {
-    open(I, $ipc) or die "Cannot read from $ipc: $!";
-    &perform while <I>;
-    close I;
-} else {
-    &perform while <>;
-}
-fileno O and close O;
-exit;
-
-
-sub perform {
-    if (fileno O) {
-        my ($time, $type, $size, $from, $to, $level, $msg);
-        if (($time, $type, $size, $from, $to) =
-            /^([A-Z][a-z]{2}\ .[0-9]\ [0-9:]{8}(?:-[0-9]{6})?)\ util-client-.*\b
-             (?: Received | Transmitting )\ message \b.*?\b
-             type \s+ (\d+) \b.*?\b
-             size \s+ (\d+) \b.*?\b
-             (?: from \s+ (\S+)
-               | to   \s+ (\S+) ) /x)
-        {
-            $from ||= $name;
-            $to ||= $name;
-            my ($time, $type, $size, $from, $to) = ($1, $2, $3,
-                                                $4 || $name, $5 || $name);
-            my $msg = exists $msgtypes{$type} ? $msgtypes{$type} : $type;
-            my $ofh = select O;
-            print O "$time\t$from -> $to\t$msg ($size)\n";
-            $| = 1;
-            select $ofh;
-        }
-        if (($time, $level, $msg) =
-            /^([A-Z][a-z]{2}\ .[0-9]\ [0-9:]{8}(?:-[0-9]{6})?)
-              \s+\S+\s+(\S+)\s+(.+)/x
-            and (exists $levels{$level}
-                 && $levels{$level} <= $msg_level
-                 && (!defined $msg_regex || $msg =~ /$msg_regex/i)))
-        {
-            print O "$time\t$name\t$level: $msg\n";
-        }
-    }
-    return if $opts{x} and /$opts{x}/io;
-    return if $opts{i} and not /$opts{i}/io;
-
-    # Timestamp (e.g. Nov 01 19:36:11-384136)
-    s/^([A-Z][a-z]{2} .[0-9] [0-9:]{8}(?:-[0-9]{6})?)/YELLOW $1/e;
-
-    # Log levels
-    s/\b(ERROR  )\b/RED $1/ex;
-    s/\b(WARNING)\b/YELLOW $1/ex;
-    s/\b(INFO   )\b/GREEN $1/ex;
-    s/\b(DEBUG  )\b/BRIGHT_BLACK $1/ex;
-
-    # Service names
-    # TODO: might read the list from $GNUNET_PREFIX/libexec/gnunet/
-    s/\b(multicast|psyc|psycstore|social)\b/BLUE $1/gex;
-
-    # Add message type names
-    s/(\s+type\s+)(\d+)/
-      $1 . BRIGHT_CYAN (exists $msgtypes{$2} ? $msgtypes{$2} : 'UNKNOWN') .
-      CYAN " ($2)"/gei;
-
-    # logread-ipc output
-    s/(\s+)([A-Z_]+)( \(\d+\))$/$1 . BRIGHT_CYAN $2 . CYAN $3/e;
-
-    print;
-}
-
-__END__
-
-=pod
-
-=head1 NAME
-
-gnunet-logread - a GNUnet log analyzer, colorizer and aggregator
-
-=head1 SYNOPSIS
-
-       <gnunet-service> |& $0 [<options>]
-    or
-       $0 [<options>] [<logfile>]
-
- Options:
-    -f                         Follow input from IPC FIFO socket.
-
-   Regular screen output options:
-    -i <regex>                 Include only messages that match <regex>.
-    -x <regex>                 Exclude all messages that match <regex>.
-    -q                         Quiet: Do not show usage advice to new users.
-
-   Options to forward messages to the IPC FIFO socket:
-    -n <component_name>                Name of the component we are forwarding messages for.
-    -s </path/to/ipc.sock>     Default = $DEFAULT_SOCKET
-    -L <LOGLEVEL>              Minimum level of messages to forward:
-                                Log levels: NONE, ERROR, WARNING, INFO, DEBUG.
-    -m <regex>                 Only forward messages matching a regular expression.
-
- See 'perldoc gnunet-logread' for a longer explanation.
-
-=head1 MOTIVATION
-
-GNUnet debug logs are a tedious read, but given a complex system that we
-cannot run all parts of in a debugger all the time, some gathering and
-structuring of events and message passing is useful.
-
-At first, this tool simply makes logs easier to read. Both if viewed in
-real-time or taken from disk. Then it also allows to extract all message
-passing events from it and forward them to a special process that aggregates
-all message passing events and therefore helps you make sense of all the
-inter-process communication (IPC) happening between the various pieces of
-the GNUnet system beast.
-
-That master process is simply an extra gnunet-logread that you run in a
-separate window and adorn it with the '-f' flag. The submitting processes
-instead need to be given a '-n' flag. That is because from the GNUnet logs
-it isn't clear which process events belong to. For example you may be
-having events taking place in the 'util' subsystem of gnunet-psyc-service
-just as much as in the 'util' subsystem of gnunet-multicast-service. In
-order to make sense of them it is necessary to manually add that info. This
-could be remedied by extending the semantics of the GNUNET_log facility
-instead, but that is still subject to further consideration.
-
-=head1 AUTHORS
-
-tg & lynX
diff --git a/contrib/scripts/gnunet-logread/gnunet-logread-ipc-sdedit b/contrib/scripts/gnunet-logread/gnunet-logread-ipc-sdedit
deleted file mode 100755 (executable)
index f8b7dc7..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-#!@PERL@
-
-# 1. Start sdedit and enable 'RT diagram server' in 'Global preferences'.
-#
-# 2. Start this tool (see defaults below):
-#    gnunet-logread-ipc-sdedit -n buffer-name -i /path/to/ipc.sock -h <sdedit-host> -p <sdedit-port>
-#
-# 3. Start a gnunet-logread instance for each component with the -n <component_name> option
-
-use strict;
-use warnings;
-
-use Getopt::Std;
-use IO::Socket::INET;
-use POSIX qw(mkfifo);
-
-my %opts;
-getopts ('i:n:h:p:', \%opts);
-
-my $ipc  = $opts{i} || '/tmp/gnunet-logread-ipc.sock';
-my $name = $opts{n} || 'gnunet';
-my $host = $opts{h} || 'localhost';
-my $port = $opts{p} || 16001;
-my %svcs = map { $_ => 1 } @ARGV;
-
-my $sdedit = IO::Socket::INET->new(PeerAddr => $host,
-                                   PeerPort => $port,
-                                   Proto => 'tcp')
-    or die "Cannot connect to $host:$port: $!\n";
-
-print $sdedit "$name\n";
-print $sdedit "_t:time[e]\n";
-print $sdedit "$_:$_\[ap\] \"$_\"\n" for @ARGV;
-print $sdedit "_e:ext[e]\n";
-print $sdedit "\n";
-
-mkfifo $ipc, 0600 or die "$ipc: $!\n" unless -e $ipc;
-open IPC, '<', $ipc or die "$ipc: $!\n";
-$| = 1;
-while (<IPC>)
-{
-    print;
-    my ($time, $from, $to, $msg, $svc);
-    if (my ($time, $from, $to, $msg) =
-        /^([A-Z][a-z]{2}\ .[0-9]\ [0-9:]{8}(?:-[0-9]{6})?)\s+
-         (\S+)\s+ -> \s+(\S+)\s+ (\S+\s+ \(\d+\))/x)
-    {
-        $from = '_e' unless exists $svcs{$from};
-        $to = '_e' unless exists $svcs{$to};
-        print $sdedit "*0 _t\n$time\n*0\n", "$from:$to.$msg\n"
-    }
-    elsif (($time, $svc, $msg) =
-           /^([A-Z][a-z]{2}\ .[0-9]\ [0-9:]{8}(?:-[0-9]{6})?)\s+
-             (\S+)\s+(.+)/x)
-    {
-        print $sdedit "*0 _t\n$time\n*0\n", "*0 $svc\n$msg\n*0\n"
-    }
-}
-
-close IPC;
diff --git a/contrib/scripts/gnunet-logread/gnunet-logread-ipc-sdedit.in b/contrib/scripts/gnunet-logread/gnunet-logread-ipc-sdedit.in
new file mode 100755 (executable)
index 0000000..f8b7dc7
--- /dev/null
@@ -0,0 +1,60 @@
+#!@PERL@
+
+# 1. Start sdedit and enable 'RT diagram server' in 'Global preferences'.
+#
+# 2. Start this tool (see defaults below):
+#    gnunet-logread-ipc-sdedit -n buffer-name -i /path/to/ipc.sock -h <sdedit-host> -p <sdedit-port>
+#
+# 3. Start a gnunet-logread instance for each component with the -n <component_name> option
+
+use strict;
+use warnings;
+
+use Getopt::Std;
+use IO::Socket::INET;
+use POSIX qw(mkfifo);
+
+my %opts;
+getopts ('i:n:h:p:', \%opts);
+
+my $ipc  = $opts{i} || '/tmp/gnunet-logread-ipc.sock';
+my $name = $opts{n} || 'gnunet';
+my $host = $opts{h} || 'localhost';
+my $port = $opts{p} || 16001;
+my %svcs = map { $_ => 1 } @ARGV;
+
+my $sdedit = IO::Socket::INET->new(PeerAddr => $host,
+                                   PeerPort => $port,
+                                   Proto => 'tcp')
+    or die "Cannot connect to $host:$port: $!\n";
+
+print $sdedit "$name\n";
+print $sdedit "_t:time[e]\n";
+print $sdedit "$_:$_\[ap\] \"$_\"\n" for @ARGV;
+print $sdedit "_e:ext[e]\n";
+print $sdedit "\n";
+
+mkfifo $ipc, 0600 or die "$ipc: $!\n" unless -e $ipc;
+open IPC, '<', $ipc or die "$ipc: $!\n";
+$| = 1;
+while (<IPC>)
+{
+    print;
+    my ($time, $from, $to, $msg, $svc);
+    if (my ($time, $from, $to, $msg) =
+        /^([A-Z][a-z]{2}\ .[0-9]\ [0-9:]{8}(?:-[0-9]{6})?)\s+
+         (\S+)\s+ -> \s+(\S+)\s+ (\S+\s+ \(\d+\))/x)
+    {
+        $from = '_e' unless exists $svcs{$from};
+        $to = '_e' unless exists $svcs{$to};
+        print $sdedit "*0 _t\n$time\n*0\n", "$from:$to.$msg\n"
+    }
+    elsif (($time, $svc, $msg) =
+           /^([A-Z][a-z]{2}\ .[0-9]\ [0-9:]{8}(?:-[0-9]{6})?)\s+
+             (\S+)\s+(.+)/x)
+    {
+        print $sdedit "*0 _t\n$time\n*0\n", "*0 $svc\n$msg\n*0\n"
+    }
+}
+
+close IPC;
diff --git a/contrib/scripts/gnunet-logread/gnunet-logread.in b/contrib/scripts/gnunet-logread/gnunet-logread.in
new file mode 100755 (executable)
index 0000000..9b1c654
--- /dev/null
@@ -0,0 +1,198 @@
+#!@PERL@
+# helper tool to make gnunet logs more readable
+# try 'gnunet-logread -h' for usage
+
+use strict;
+use warnings;
+my $DEFAULT_SOCKET = '/tmp/gnunet-logread-ipc.sock';
+
+print STDERR <<X if -t STDIN and $#ARGV == -1;
+*** For a usage message, try '$0 -h'.
+*** For documentation, try 'perldoc $0'.
+*** Listening for GNUNET_log events on STDIN. Type CTRL-D to terminate.
+
+X
+
+use Getopt::Std;
+my (%opts, $name, $ipc, $msg_level, $msg_regex);
+getopts ('i:x:n:s:L:m:fhq', \%opts);
+
+use Pod::Usage qw( pod2usage );
+die pod2usage if $opts{h};
+
+use POSIX qw(mkfifo);
+
+use Term::ANSIColor qw(:constants :pushpop);
+$Term::ANSIColor::AUTOLOCAL = 1;
+
+my %levels = ( NONE => 0, ERROR => 1, WARNING => 2, INFO => 4, DEBUG => 8 );
+
+# Message type numbers to names
+my %msgtypes;
+my $prefix = $ENV{GNUNET_PREFIX} || '/usr';
+my $filename = "$prefix/include/gnunet/gnunet_protocols.h";
+$ipc = $opts{s} || $DEFAULT_SOCKET;
+
+if (open HEADER, $filename)
+{
+    while (<HEADER>)
+    {
+        $msgtypes{$2} = $1 if /^\s*#define\s+GNUNET_MESSAGE_TYPE_(\w+)\s+(\d+)/i;
+    }
+    close HEADER;
+} else {
+    warn <<X;
+Could not read $filename for message codes:
+       $!.
+Please provide a \$GNUNET_PREFIX environment variable to replace "/usr".
+Try also '$0 -h' for help.
+
+X
+}
+
+die "You can't read and write the socket at the same time"
+  if exists $opts{f} and exists $opts{n};
+
+if ((exists $opts{n} or exists $opts{f}) and not -r $ipc) {
+    undef $!;
+    die "Could not mkfifo $ipc: $!" unless mkfifo $ipc, 0600;
+    system('chgrp', 'gnunet', $ipc);
+    die "Could not chgrp $ipc to 'gnunet': $!" if $!;
+    chmod 0660, $ipc;
+    die "Could not chmod $ipc to allow gnunet group writes: $!" if $!;
+}
+
+if (exists $opts{n}) {
+    $name = $opts{n};
+    $msg_level = $opts{L} && exists $levels{$opts{L}} ? $levels{$opts{L}} : 0;
+    $msg_regex = $opts{m};
+    print STDERR "RE: /$msg_regex/\n" if defined $msg_regex;
+    open O, '>', $ipc or die "Cannot write to $ipc: $!";
+}
+
+if (exists $opts{f}) {
+    open(I, $ipc) or die "Cannot read from $ipc: $!";
+    &perform while <I>;
+    close I;
+} else {
+    &perform while <>;
+}
+fileno O and close O;
+exit;
+
+
+sub perform {
+    if (fileno O) {
+        my ($time, $type, $size, $from, $to, $level, $msg);
+        if (($time, $type, $size, $from, $to) =
+            /^([A-Z][a-z]{2}\ .[0-9]\ [0-9:]{8}(?:-[0-9]{6})?)\ util-client-.*\b
+             (?: Received | Transmitting )\ message \b.*?\b
+             type \s+ (\d+) \b.*?\b
+             size \s+ (\d+) \b.*?\b
+             (?: from \s+ (\S+)
+               | to   \s+ (\S+) ) /x)
+        {
+            $from ||= $name;
+            $to ||= $name;
+            my ($time, $type, $size, $from, $to) = ($1, $2, $3,
+                                                $4 || $name, $5 || $name);
+            my $msg = exists $msgtypes{$type} ? $msgtypes{$type} : $type;
+            my $ofh = select O;
+            print O "$time\t$from -> $to\t$msg ($size)\n";
+            $| = 1;
+            select $ofh;
+        }
+        if (($time, $level, $msg) =
+            /^([A-Z][a-z]{2}\ .[0-9]\ [0-9:]{8}(?:-[0-9]{6})?)
+              \s+\S+\s+(\S+)\s+(.+)/x
+            and (exists $levels{$level}
+                 && $levels{$level} <= $msg_level
+                 && (!defined $msg_regex || $msg =~ /$msg_regex/i)))
+        {
+            print O "$time\t$name\t$level: $msg\n";
+        }
+    }
+    return if $opts{x} and /$opts{x}/io;
+    return if $opts{i} and not /$opts{i}/io;
+
+    # Timestamp (e.g. Nov 01 19:36:11-384136)
+    s/^([A-Z][a-z]{2} .[0-9] [0-9:]{8}(?:-[0-9]{6})?)/YELLOW $1/e;
+
+    # Log levels
+    s/\b(ERROR  )\b/RED $1/ex;
+    s/\b(WARNING)\b/YELLOW $1/ex;
+    s/\b(INFO   )\b/GREEN $1/ex;
+    s/\b(DEBUG  )\b/BRIGHT_BLACK $1/ex;
+
+    # Service names
+    # TODO: might read the list from $GNUNET_PREFIX/libexec/gnunet/
+    s/\b(multicast|psyc|psycstore|social)\b/BLUE $1/gex;
+
+    # Add message type names
+    s/(\s+type\s+)(\d+)/
+      $1 . BRIGHT_CYAN (exists $msgtypes{$2} ? $msgtypes{$2} : 'UNKNOWN') .
+      CYAN " ($2)"/gei;
+
+    # logread-ipc output
+    s/(\s+)([A-Z_]+)( \(\d+\))$/$1 . BRIGHT_CYAN $2 . CYAN $3/e;
+
+    print;
+}
+
+__END__
+
+=pod
+
+=head1 NAME
+
+gnunet-logread - a GNUnet log analyzer, colorizer and aggregator
+
+=head1 SYNOPSIS
+
+       <gnunet-service> |& $0 [<options>]
+    or
+       $0 [<options>] [<logfile>]
+
+ Options:
+    -f                         Follow input from IPC FIFO socket.
+
+   Regular screen output options:
+    -i <regex>                 Include only messages that match <regex>.
+    -x <regex>                 Exclude all messages that match <regex>.
+    -q                         Quiet: Do not show usage advice to new users.
+
+   Options to forward messages to the IPC FIFO socket:
+    -n <component_name>                Name of the component we are forwarding messages for.
+    -s </path/to/ipc.sock>     Default = $DEFAULT_SOCKET
+    -L <LOGLEVEL>              Minimum level of messages to forward:
+                                Log levels: NONE, ERROR, WARNING, INFO, DEBUG.
+    -m <regex>                 Only forward messages matching a regular expression.
+
+ See 'perldoc gnunet-logread' for a longer explanation.
+
+=head1 MOTIVATION
+
+GNUnet debug logs are a tedious read, but given a complex system that we
+cannot run all parts of in a debugger all the time, some gathering and
+structuring of events and message passing is useful.
+
+At first, this tool simply makes logs easier to read. Both if viewed in
+real-time or taken from disk. Then it also allows to extract all message
+passing events from it and forward them to a special process that aggregates
+all message passing events and therefore helps you make sense of all the
+inter-process communication (IPC) happening between the various pieces of
+the GNUnet system beast.
+
+That master process is simply an extra gnunet-logread that you run in a
+separate window and adorn it with the '-f' flag. The submitting processes
+instead need to be given a '-n' flag. That is because from the GNUnet logs
+it isn't clear which process events belong to. For example you may be
+having events taking place in the 'util' subsystem of gnunet-psyc-service
+just as much as in the 'util' subsystem of gnunet-multicast-service. In
+order to make sense of them it is necessary to manually add that info. This
+could be remedied by extending the semantics of the GNUNET_log facility
+instead, but that is still subject to further consideration.
+
+=head1 AUTHORS
+
+tg & lynX
diff --git a/m4/perl.m4 b/m4/perl.m4
new file mode 100644 (file)
index 0000000..6f855c7
--- /dev/null
@@ -0,0 +1,48 @@
+# serial 9
+
+dnl From Jim Meyering.
+dnl Find a new-enough version of Perl.
+
+# Copyright (C) 1998-2001, 2003-2004, 2007, 2009-2018 Free Software Foundation,
+# Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# GNUnet e.V. comment of origin: gnulib
+
+AC_DEFUN([gl_PERL],
+[
+  dnl FIXME: don't hard-code 5.005
+  AC_MSG_CHECKING([for perl5.005 or newer])
+  if test "${PERL+set}" = set; then
+    # 'PERL' is set in the user's environment.
+    candidate_perl_names="$PERL"
+    perl_specified=yes
+  else
+    candidate_perl_names='perl perl5'
+    perl_specified=no
+  fi
+
+  found=no
+  AC_SUBST([PERL])
+  PERL="$am_missing_run perl"
+  for perl in $candidate_perl_names; do
+    # Run test in a subshell; some versions of sh will print an error if
+    # an executable is not found, even if stderr is redirected.
+    if ( $perl -e 'require 5.005; use File::Compare' ) > /dev/null 2>&1; then
+      PERL=$perl
+      found=yes
+      break
+    fi
+  done
+
+  AC_MSG_RESULT([$found])
+  test $found = no && AC_MSG_WARN([
+WARNING: You don't seem to have perl5.005 or newer installed, or you lack
+         a usable version of the Perl File::Compare module.  As a result,
+         you may be unable to run a few tests or to regenerate certain
+         files if you modify the sources from which they are derived.
+] )
+])