Actually build the contrib perl script.
Add an m4 script for perl.
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)
AC_CONFIG_FILES([
Makefile
contrib/Makefile
+contrib/scripts/Makefile
+contrib/scripts/gnunet-logread/Makefile
doc/Makefile
doc/man/Makefile
doc/doxygen/Makefile
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 \
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 \
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
--- /dev/null
+# 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 $@
+++ /dev/null
-;;; 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
--- /dev/null
+# 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
+++ /dev/null
-#!@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
+++ /dev/null
-#!@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;
--- /dev/null
+#!@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;
--- /dev/null
+#!@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
--- /dev/null
+# 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.
+] )
+])