All posts by Mike Massonnet

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.

  • 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
RemoteForward 12000 localhost:12000
PermitLocalCommand yes
LocalCommand socat -u tcp4-listen:12000,reuseaddr,fork,bind= exec:$HOME/.local/bin/ 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

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

read line
read line
read line

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

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 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 inside irssi.


# shamelessly copied from;a=blob;
use strict;
use Irssi;
use HTML::Entities;
use vars qw($VERSION %IRSSI);

$VERSION = "0.01";

%IRSSI = (
authors => 'Luke Macken, Paul W. Frields',
contact => ',',
name => 'rnotify',
description => 'Use libnotify to alert user to hilighted messages',
license => 'GNU General Public License',
url => '',

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;
# 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 $port");
system("echo '$summary\n$message\n\n' | /bin/nc $port &");

#my $pid = open(FH, "|-");
#if( $pid ){
# print FH "$summary\n$message\n\n";
# close(FH) || warn "exited $?";
# exec("/bin/nc $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

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:
The 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"

SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="3c:ab:cd:00:ab:ce", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="eth*", NAME="eth3"
By editing this file it is possible to change the NAME of each rule. After that, to reload the rules, simply issue this command:
udevadm control --reload-rules

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
  • us: setxkbmap us
It can be very handy, check the online documention for a quick setup. There are also online examples, don't mind to leave a comment or to fill the bugtracker if you have clever ideas, I can add them, I just did with the setxkbmap us example ;-)

Moving from Unique to GtkApplication

A new class has been introduced in GTK+3 that is GtkApplication, and GApplication with GIO 2.28. A common use case is to have a single window present every time the same application or command line is run, that is also known as process uniqueness. This is already possible with Unique that was especially developed for single instance applications. This very basic post will show an example in C with Unique, and also how to do it with GtkApplication, where you will see that GtkApplication makes things even easier.

First of all, the documentation available from the GIO source code doesn't give a concrete example for process uniqueness with GApplication. There are mainly examples about using GApplication with GSimpleAction, that is pretty cool since it lets you easily define actions to run on the primary instance outside of the process, either with the same program or a different one.

Single window with Unique

In the following example, a UniqueApp class is instantiated, then it's checked against another running instance. If not, a window is created and a handle is connected to the UniqueApp object to react on received messages. Otherwise a message is sent, and the existing instance will execute the connected handle and put the window in front.
#include <unique/unique.h>
#include <gtk/gtk.h>

static UniqueResponse
cb_unique_app (UniqueApp *app,
gint command,
UniqueMessageData *message_data,
guint time_,
gpointer user_data)
GtkWidget *window = user_data;
if (command != UNIQUE_ACTIVATE)
gtk_window_present (GTK_WINDOW (window));

gint main (gint argc, gchar *argv[])
GtkWidget *window;
UniqueApp *app;

gtk_init (&argc, &argv);

app = unique_app_new ("info.mmassonnet.UniqueExample", NULL);
if (unique_app_is_running (app))
if (unique_app_send_message (app, UNIQUE_ACTIVATE, NULL) == UNIQUE_RESPONSE_OK)
g_object_unref (app);
return 0;

window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_widget_show (window);

gtk_main ();
return 0;

Single window with GtkApplication

In this example, a GtkApplication class is instantiated. This one is then registered, and a check is done to know if the running process is the primary one or a remote one. Just like in the previous example, either the process is the main one and a window is created and shown, otherwise a signal is sent and the connected handle will put the window in front. The handle used here is directly a GTK function that presents the window which spares the need to write a custom handler.
#include <gtk/gtk.h>

gint main (gint argc, gchar *argv[])
GtkWidget *window;
GtkApplication *app;
GError *error = NULL;

gtk_init (&argc, &argv);

app = gtk_application_new ("info.mmassonnet.GtkExample", 0);

g_application_register (G_APPLICATION (app), NULL, &error);
if (error != NULL)
g_warning ("Unable to register GApplication: %s", error->message);
g_error_free (error);
error = NULL;

if (g_application_get_is_remote (G_APPLICATION (app)))
g_application_activate (G_APPLICATION (app));
g_object_unref (app);
return 0;

window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_widget_show (window);

g_signal_connect_swapped (app, "activate", G_CALLBACK (gtk_window_present), dialog);

gtk_main ();
return 0;
In both examples there is just one difference, it is how the primary process is seen. With Unique there is a function to know if another instance is running, while with GtkApplication there is a function to know if the current process is not the primary one e.g. a remote instance. I prefer the second approach, since with Unique if there is only one instance running, the is_running property will tell you false but the primary instance is running, isn't it? But anyhow, as you can see, it is possible to implement painlessly what is done by Unique with GtkApplication.

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

Vim and Vala

I once wrote a quick note about Vala and Vim (or Vim and Vala) and the use of the Tag List plugin. Here is a clean post about these two beasts.

Vim — probably the best editor out there, at least always after trying out different editors I end up with Vim — has great plugins. However there is a lack of support for the Vala language. So here are two basic add-ins to include in the Vim editor.

Vala syntax

First there is no syntax color for this language. A quick fix is to use the C# syntax with the command :set filetype=cs. That works but is not ideal, ideal is to install a vim.syntax file, and there is one available on this GNOME Live! page.

First download the file from this page and save it under ~/.vim/syntax. Next at the following lines to your ~/.vimrc file:
" Filetypes
augroup filetypedetect
au! BufRead,BufNewFile *.vala,*.vapi setfiletype vala
augroup END

augroup vala
autocmd BufRead *.vala,*.vapi set tw=100 efm=%f:%1.%c-%[%^:]%#:\ %t%[%^:]%#:\ %m
augroup END

Tag List

Tag List is a powerful plugin that lets you explore classes or functions from a source file, also called a source code browser. The installation steps are simple, they are also available bellow, and again to get it working with Vim there is a small hack to include inside the ~/.vimrc file.

First download the latest version of taglist from this page. Than uncompress the archive with, for example, the command line:
unzip -x -d $HOME/.vim/
Than go inside ~/.vim/doc, run Vim and inside Vim execute the command :helptags .:
cd ~/.vim/doc
:helptags .
Finally add the following lines inside ~/.vimrc:
" Work-around Tag List for Vala
let tlist_vala_settings='c#;d:macro;t:typedef;n:namespace;c:class;'.
\ 'E:event;g:enum;s:struct;i:interface;'.
\ 'p:properties;m:method'

Now Vim is ready for Vala, and it's possible to browse source code by typing the command :TListToggle.

Screenshot of Vim Vala Tag List
Vim Vala Tag List


So I pimped up my .screenrc, and since it's been a long time I didn't care about my hardstatus I keep the content here just in case I need it again in a few years...

defscrollback 2048
startup_message off
caption always "%{= Wk}%-w%{= KW}%f%n %t%{-}%+w"
hardstatus off
hardstatus alwayslastline
hardstatus string "%{= ky}[ %H %l ]%=%{= kg}%{+b}[ %n %t ]%-=%{= ky}[ %D %d.%m.%Y %0c ]"

screen -t irssi 0
screen -t mutt 1
screen -t bubbie 2

Xfce 4.8 with Conky

I have been following a short discussion on the IRC channel #xfce regarding an issue with the use of Conky and transparency. I didn't use Conky for a very long time, but since I knew it was possible to have Conky perfectly running, I gave it a shot again and since I did a fresh reinitialization of Xfce on my workstation, I tweaked the configuration file to my need. Now I have it running in the background and I'll most probably keep it.

The configuration I was able to get for a good working Conky window with transparency is bellow. Of course I could tell you which combination doesn't work, with the why, but since there are so many of them I simply put a working one.
own_window yes # create a separate XWindow over the one from Xfdesktop
own_window_type desktop # the window cannot be moved or resized
own_window_hints undecorated,below,sticky,skip_taskbar,skip_pager # make it behave like it belongs to the desktop
own_window_argb_visual yes # true transparency, a compositor has to be active
own_window_argb_value 100 # make the background semi-transparent
double_buffer yes # avoid flickering

Here is a screenshot of the desktop with Conky in the bottom right corner, I made sure there is some I/O activity going on :-)

Xfce with Conky
Now if you want you can steal my .conkyrc file.

Analysing a phishing email

I've been hit by several phishing emails in a short time the last week. Having time this morning I took the initiative to look at the headers from one email and the phishing location.

The hosting server
The domains DNS zone is hosted on a particular network just like its website. Two different servers actually, but behind it seems to be a lucrative webhosting service where you can get your domain registered although it's not a registrar. All of this is hosted in Texas.

The email server
The email is originating from Italy. The FROM address is set up to show a truthful email (usually where you put the surname) with an inexistant email address behind that. The email address' domain name exists however and is hosted in France, but has no relation to the scam, at least the owner of this domain can't do anything about it.

The Return-Path shows a real email address with a different domain name but same network anyway. The domain name shows a dummy webpage "Under construction".

Who to contact?
All of them if you care, otherwise just let it go, because phishing pages are set up and down daily...

To contact the webhosting or email server, request the Whois information of the IP address and contact the abuse department, there is always an abuse section in the Whois of an IP address. You can also contact the domain name holder and/or look if the registrar or webhosting sevice has a dedicated abuse website page.

Of course it happens that an abuse email address forwards everything to the trash can. In order to have a chance to stop the scam, it is good to contact as many services as possible.