#!/usr/bin/perl -I/usr/depot/lib/perl5
#
# listen for PSYC packets and dump them

sub DEBUG() { 0 }

use Term::ANSIColor qw( :constants );   # optional but pervasive
use Pod::Usage qw( pod2usage );
use Net::PSYC qw( :event );

my $noargs = $#ARGV == -1;
use Getopt::Std;
getopt('b');
my $uni = $opt_b || 'psyc://localhost:2244';

my $x = undef;
if ($opt_x) {
    print STDERR <<X unless $x = &which('notify-send');
Cannot notify X11 user, notify_send not available on this system.

X
}

if ($opt_h) {
    pod2usage;
    exit;
}

bind_uniform( $uni );
register_uniform();
add(\*STDIN, 'r', \&type);
$|=1;

print STDERR <<X if $noargs and -t STDIN;
*** Try -h for help or 'perldoc psyclisten' for a manual.
X

print GREEN, "*** Listening on $uni ...\n", RESET;
start_loop();
exit;


### SUBS AND SANDWICHES FOLLOW ###

# if your system doesn't have "which" we're in trouble
sub which {
    my $cmd = shift;
    $_ = `which $cmd 2>&1`;
    print STDERR "which $cmd: $_" if DEBUG & 2;
    /^(\S+)\s*$/;
    return $1;
}

sub type {
    my $bla = <STDIN>;
    print <<X;
you typed: $bla
bye.
X
    exit;
}

sub msg {
    my ($source, $mc, $data, $vars) = @_;

    if ($opt_d and $vars) {
	    print <<X;

*** method $mc; variables:
X
	    foreach $i (keys %$vars) {
		    print "\t$i $vars->{$i}\n";
	    }
    }
    if ($data) {
	    my $l = length($data);
	    if ($l < 256) {
		    if ($opt_d) {
			    print <<X;
==============================================================================
$data
==============================================================================
X
			    return unless $opt_x;
		    }
		    if ($mc =~ /^_(message|converse)/) {
			    my $o;
			    if (exists $vars->{_nick}) {
				    $o = "<". $vars->{_nick} ."> ";
				    $_ = GREEN. $o .YELLOW. $data;
			    } else {
				    $o = "(". $source .") ";
				    $_ = BLUE. $o .YELLOW. $data;
			    }
			    system($x, $source, $o.$data) if $x;
		    } else {
			    $_ = MAGENTA. psyctext($data, $vars);
		    }
		    print RED, '{', $mc, '} ', $_, RESET, "\n" unless $opt_d;
	    } elsif (open(O, ">dump$$")) {
		    print O $data;
		    close O;
		    print <<X;
*** $l bytes of data stored in a file called 'dump$$'
X
		    system($x, $source, <<X) if $x;
Received $l bytes of data from $source in a file called 'dump$$'
X
	    } else {
		    print STDERR <<X;
*** Could not save data in a file called 'dump$$': $!
X
		    system($x, $source, <<X) if $x;
Could not store $l bytes of data from $source to disk.
X
	    }
    }
    print "\nlistening... " if DEBUG & 1;
}

__END__

=pod

=head1 NAME

psyclisten - a minimal PSYC server that receives messages

=head1 SYNOPSIS

 psyclisten [<options>]

 Options:
	-x		Use notify-send to inform an X11 user
	-n		Do not store large messages in file dumps
	-d		Debug: output a raw format
	-b <uniform>	PSYC address to bind to
	-h		Output this usage help message
	-q		Be more quiet

=head1 DESCRIPTION

This tool binds to a PSYC address, then receives messages
using the PSYC syntax. You can use tools like psycmsg to
generate such messages, or simply use /msg or /talk from
a psyced server.

=head2 Forwarding messages to the desktop

With the -x option, the notify-send command is used to forward
conversational messages to the desktop. So you can have a
psyclisten run as a daemon.

=head2 Receiving file transfers

Currently file transfers aren't implemented as such, but,
unless option -n has been provided, any data content exceeding
a certain limit is stored into a file in the current directory.
You can launch a file transfer using psyccat.

=head1 CAVEATS

As long as Net::PSYC does not provide any encryption, you
should use this within a trustworthy local network or
as a localhost service.

=head1 AUTHORS

carlo von lynX.

=head1 COPYRIGHT

This program is free software, published under the Affero GNU Public
License. A disclaimer isn't necessary in my country, nor do I need
to mention the current year to assert a copyright.

