2014-01-05

Remote notifications

This post explains how to get notifications (libnotify) from a remote system. Typically this is useful with an IRC client accessible through SSH.

Prerequisites:
  • A notification daemon! (dunst, xfce4-notifyd, etc.)
  • socat
  • notify-send
apt-get install socat libnotify-bin

On the client, modify the SSH configuration to introduce two elements:
  • forward a TCP port,
  • execute a local command.

Example entry for ~/.ssh/config:
Host remote-host
    Hostname remote-host.gandi.net
    RemoteForward 12000 localhost:12000
    PermitLocalCommand yes
    LocalCommand socat -u tcp4-listen:12000,reuseaddr,fork,bind=127.0.0.1 exec:$HOME/.local/bin/notify-remote.sh 2>/dev/null &
The fowarded TCP port will be used to netcat notification messages to the local system.

socat is used to bind a port on the local system, it will take the notifcation messages, and write them to the executed shell script notify-remote.sh.

The shell script will then simply call notify-send to display a notification with the default notification daemon.

notify-remote.sh:
#!/bin/sh
delay="5000"

read line
summary="$line"
read line
msg="$line"
read line

if [ "$line" = "" ] && [ "$summary" != "" ]; then
  [ -x "$(which notify-send)" ] && notify-send -u critical -t "$delay" -- "$summary" "$msg"
fi

Now it is possible to connect to the remote host and "write" notifications:
local$ ssh remote-host
remote-host$ echo -e 'Summary\nBody\n\n' | nc 127.0.0.1 12000

Integrate into irssi


Copy the irssi script available bellow to get notifications from hilights, and private messages.

Once the script is copied, execute /script load rnotify.pl inside irssi.

~/.irssi/scripts/autorun/rnotify.pl:
# shamelessly copied from http://git.esaurito.net/?p=godog/bin.git;a=blob;f=rnotify.pl
use strict;
use Irssi;
use HTML::Entities;
use vars qw($VERSION %IRSSI);

$VERSION = "0.01";

%IRSSI = (
    authors     => 'Luke Macken, Paul W. Frields',
    contact     => 'lewk@csh.rit.edu, stickster@gmail.com',
    name        => 'rnotify',
    description => 'Use libnotify to alert user to hilighted messages',
    license     => 'GNU General Public License',
    url         => 'http://lewk.org/log/code/irssi-notify',
);

Irssi::settings_add_str('misc', $IRSSI{'name'} . '_port', '12000');
Irssi::settings_add_bool('misc', $IRSSI{'name'} . '_if_away', 0);

sub is_port_owner {
    my ($port, $uid) = @_;
    my $wanted = sprintf("0100007F:%04X", $port);

    # XXX linux-specific
    open HANDLE, "< /proc/net/tcp" || return 0;
    while(<HANDLE>){
        #   sl  local_address rem_address   st tx_queue rx_queue tr tm->when retrnsmt   uid  timeout inode
        my @splitted = split /\s+/;
        my $local = $splitted[2];
        my $remote = $splitted[3];
        my $uid = $splitted[8];

        return 1 if $local eq $wanted and $uid == $<;
    }
    close HANDLE;
    return 0;
}

sub notify {
    my ($server, $summary, $message) = @_;

    $message = HTML::Entities::encode($message);
    $summary = HTML::Entities::encode($summary);

    # echo \ escaping
    $message =~ s/\\/\\\\/g;
    $summary =~ s/\\/\\\\/g;

    my $port = Irssi::settings_get_str($IRSSI{'name'} . '_port');

    return if ! is_port_owner($port, $<);

    # check for being away in every server?
    return if $server->{usermode_away} &&
              (Irssi::settings_get_bool($IRSSI{'name'} . '_if_away') == 0);

    # XXX test for other means of doing TCP
    #print("echo '$summary\n$message\n\n' | /bin/nc 127.0.0.1 $port");
    system("echo '$summary\n$message\n\n' | /bin/nc 127.0.0.1 $port &");

    #my $pid = open(FH, "|-");
    #if( $pid ){
    #    print FH "$summary\n$message\n\n";
    #    close(FH) || warn "exited $?";
    #}else{
    #    exec("/bin/nc 127.0.0.1 $port") || warn "can't exec $!";
    #}
}

sub print_text_notify {
    my ($dest, $text, $stripped) = @_;
    my $server = $dest->{server};

    return if (!$server || !($dest->{level} & MSGLEVEL_HILIGHT));
    my $sender = $stripped;
    $sender =~ s/^\<.([^\>]+)\>.+/\1/ ;
    $stripped =~ s/^\<.[^\>]+\>.// ;
    my $summary = "Message on $dest->{target}";
    notify($server, $summary, $stripped);
}

sub message_private_notify {
    my ($server, $msg, $nick, $address) = @_;

    return if (!$server);
    notify($server, "Private message from ".$nick, $msg);
}

sub dcc_request_notify {
    my ($dcc, $sendaddr) = @_;
    my $server = $dcc->{server};

    return if (!$dcc);
    notify($server, "DCC ".$dcc->{type}." request", $dcc->{nick});
}

Irssi::signal_add('print text', 'print_text_notify');
Irssi::signal_add('message private', 'message_private_notify');
Irssi::signal_add('dcc request', 'dcc_request_notify');

# vim: et

3 comments:

  1. We are the real hot female escorts provider in Delhi for VIP peoples.

    ReplyDelete
  2. Contact us for real hot female escorts in town.

    ReplyDelete
  3. Delhi Escorts Service Delhi Escort Agency gives young Sweta Shetty delhi independent escort girl

    ReplyDelete