#!/bin/env perl use strict; use warnings; use Linux::Inotify2; use POSIX ":sys_wait_h"; use Getopt::Long; use Sophie::Client; use Config::General; $ENV{LC_ALL} = 'C'; GetOptions( 'c=s' => \my $configfile, 'bdelay=i' => \my $updated_inotify, 'd|daemon' => \my $daemon, 'u|url=s' => \my $server, 'l=s' => \my $login, 'p=s' => \my $pass, 'proxy=s' => \my $proxy, ) or die "Wrong options"; $configfile ||= '/etc/sophie/sophie-notify.conf'; if (-f $configfile && (my $conf = Config::General->new($configfile))) { my %config = $conf->getall; $server ||= $config{url}; $login ||= $config{login}; $pass ||= $config{pass}; $proxy ||= $config{proxy}; } $updated_inotify ||= 500; if ($daemon) { if (fork()) { exit(0); } } my $sc = Sophie::Client->new( server => $server, login => $login, password => $pass, proxy => $proxy, ); my $update = 1; my %modified_paths; my @paths; alarm($updated_inotify); list_paths(); while (1) { local $SIG{ALRM} = sub { alarm($updated_inotify); $update = 1; }; my $inotify = inotify_path(); if ($update) { list_paths(); $update = 0; } if ($inotify) { $inotify->poll; } else { sleep(300); } notify_base(); } sub notify_base { keys %modified_paths or return; $sc->login; my $res = $sc->send_request( 'admin.update.set_path_needupdate', keys %modified_paths, ); if (ref $res && !$res->is_fault) { %modified_paths = (); } else { #warn "XML RPC error"; } } sub list_paths { $sc->login; my $res = $sc->send_request('admin.update.paths'); if (ref $res && !$res->is_fault) { @paths = grep { -d $_ } map { $_->{path} } @{ $res->value }; } else { #warn "XML RPC error"; } } sub inotify_path { my $i = Linux::Inotify2->new; my $sub = sub { my $e = shift; $modified_paths{$e->w->name} = 1; notify_base(); 1; }; foreach (@paths) { -d $_ or next; $i->watch( $_, IN_DELETE | IN_MODIFY | IN_CREATE, $sub, ); } $i; }