Xfce

Subdomains
 

Remote notifications

  • January 5, 2014
  • Mike Massonnet
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 'SummarynBodynn' | 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 '$summaryn$messagenn' | /bin/nc 127.0.0.1 $port");
system("echo '$summaryn$messagenn' | /bin/nc 127.0.0.1 $port &");

#my $pid = open(FH, "|-");
#if( $pid ){
# print FH "$summaryn$messagenn";
# 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

Remote notifications

  • January 5, 2014
  • Mike Massonnet
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