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-hostThe fowarded TCP port will be used to netcat notification messages to the local system.
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 &
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
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-hostThe fowarded TCP port will be used to netcat notification messages to the local system.
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 &
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
rndc retransfer failed: not found
I came accross the dummy error rndc: 'retranfer' failed: not found, with many unhelpful articles. If you run a rndc retranfer command, and get this error, make sure there is an entry for the zone on the slave, it may be helpful…rndc retransfer failed: not found
I came accross the dummy error rndc: 'retranfer' failed: not found, with many unhelpful articles. If you run a rndc retranfer command, and get this error, make sure there is an entry for the zone on the slave, it may be helpful…Reorder network devices set by udev
In order to reorder network devices (e.g. swap eth1 with eth2), the persistent-net rules from udev can be edited. Usually there is a file at the following location:/etc/udev/rules.d/70-persistent-net.rulesThe file contains several rules, for example:
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="3c:ab:cd:00:ab:cd", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="eth*", NAME="eth2"By editing this file it is possible to change the NAME of each rule. After that, to reload the rules, simply issue this command:
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="3c:ab:cd:00:ab:ce", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="eth*", NAME="eth3"
udevadm control --reload-rules
Reorder network devices set by udev
In order to reorder network devices (e.g. swap eth1 with eth2), the persistent-net rules from udev can be edited. Usually there is a file at the following location:/etc/udev/rules.d/70-persistent-net.rulesThe file contains several rules, for example:
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="3c:ab:cd:00:ab:cd", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="eth*", NAME="eth2"By editing this file it is possible to change the NAME of each rule. After that, to reload the rules, simply issue this command:
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="3c:ab:cd:00:ab:ce", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="eth*", NAME="eth3"
udevadm control --reload-rulesEdit: you need to unload the modules first (modprobe -r e1000e for example), ensure the udev rules are reloaded, and load the modules back in. If the network drivers are built into the kernel, you need to reboot.
Making use of custom actions with Xfce Appfinder
One addition in the latest versions of Appfinder was the custom actions. I never used it until after I started typing several times twitter which didn't work (a habit from the web browser url bar).The custom actions can be useful for anything, and it's really quick to run it.
Examples of custom actions:
- twitter: xdg-open https://twitter.com/
- us: setxkbmap us
Making use of custom actions with Xfce Appfinder
One addition in the latest versions of Appfinder was the custom actions. I never used it until after I started typing several times twitter which didn't work (a habit from the web browser url bar).The custom actions can be useful for anything, and it's really quick to run it.
Examples of custom actions:
- twitter: xdg-open https://twitter.com/
- us: setxkbmap us
Apache restart with Vim autocmd
In order to execute a command right after saving a file in Vim, you can use the :autocmd command. Here is a quick example how it can be useful with Apache files.NB: on my system, Debian in this case, an Apache file is automatically recognized as filetype=apache.
augroup apache
autocmd BufWritePost */sites-enabled/* !/etc/init.d/apache2 restart
augroup END
Apache restart with Vim autocmd
In order to execute a command right after saving a file in Vim, you can use the :autocmd command. Here is a quick example how it can be useful with Apache files.NB: on my system, Debian in this case, an Apache file is automatically recognized as filetype=apache.
augroup apache
autocmd BufWritePost */sites-enabled/* !/etc/init.d/apache2 restart
augroup END