1 | #!/bin/env perl |
---|
2 | |
---|
3 | use strict; |
---|
4 | use warnings; |
---|
5 | use Linux::Inotify2; |
---|
6 | use POSIX ":sys_wait_h"; |
---|
7 | use Getopt::Long; |
---|
8 | use Sophie::Client; |
---|
9 | use Config::General; |
---|
10 | |
---|
11 | $ENV{LC_ALL} = 'C'; |
---|
12 | |
---|
13 | GetOptions( |
---|
14 | 'c=s' => \my $configfile, |
---|
15 | 'bdelay=i' => \my $updated_inotify, |
---|
16 | 'd|daemon' => \my $daemon, |
---|
17 | 'u|url=s' => \my $server, |
---|
18 | 'l=s' => \my $login, |
---|
19 | 'p=s' => \my $pass, |
---|
20 | 'proxy=s' => \my $proxy, |
---|
21 | ) or die "Wrong options"; |
---|
22 | |
---|
23 | $configfile ||= '/etc/sophie/sophie-notify.conf'; |
---|
24 | |
---|
25 | if (-f $configfile && (my $conf = Config::General->new($configfile))) { |
---|
26 | my %config = $conf->getall; |
---|
27 | $server ||= $config{url}; |
---|
28 | $login ||= $config{login}; |
---|
29 | $pass ||= $config{pass}; |
---|
30 | $proxy ||= $config{proxy}; |
---|
31 | } |
---|
32 | |
---|
33 | $updated_inotify ||= 500; |
---|
34 | |
---|
35 | if ($daemon) { |
---|
36 | if (fork()) { |
---|
37 | exit(0); |
---|
38 | } |
---|
39 | } |
---|
40 | |
---|
41 | my $sc = Sophie::Client->new( |
---|
42 | server => $server, |
---|
43 | login => $login, |
---|
44 | password => $pass, |
---|
45 | proxy => $proxy, |
---|
46 | ); |
---|
47 | |
---|
48 | my $update = 1; |
---|
49 | my %modified_paths; |
---|
50 | my @paths; |
---|
51 | alarm($updated_inotify); |
---|
52 | |
---|
53 | list_paths(); |
---|
54 | |
---|
55 | while (1) { |
---|
56 | local $SIG{ALRM} = sub { |
---|
57 | alarm($updated_inotify); |
---|
58 | $update = 1; |
---|
59 | }; |
---|
60 | |
---|
61 | my $inotify = inotify_path(); |
---|
62 | |
---|
63 | if ($update) { |
---|
64 | list_paths(); |
---|
65 | $update = 0; |
---|
66 | } |
---|
67 | if ($inotify) { |
---|
68 | $inotify->poll; |
---|
69 | } else { |
---|
70 | sleep(300); |
---|
71 | } |
---|
72 | notify_base(); |
---|
73 | } |
---|
74 | |
---|
75 | sub notify_base { |
---|
76 | keys %modified_paths or return; |
---|
77 | $sc->login; |
---|
78 | my $res = $sc->send_request( |
---|
79 | 'admin.update.set_path_needupdate', |
---|
80 | keys %modified_paths, |
---|
81 | ); |
---|
82 | if (ref $res && !$res->is_fault) { |
---|
83 | %modified_paths = (); |
---|
84 | } else { |
---|
85 | #warn "XML RPC error"; |
---|
86 | } |
---|
87 | } |
---|
88 | |
---|
89 | sub list_paths { |
---|
90 | $sc->login; |
---|
91 | my $res = $sc->send_request('admin.update.paths'); |
---|
92 | if (ref $res && !$res->is_fault) { |
---|
93 | @paths = grep { -d $_ } map { $_->{path} } @{ $res->value }; |
---|
94 | } else { |
---|
95 | #warn "XML RPC error"; |
---|
96 | } |
---|
97 | } |
---|
98 | |
---|
99 | |
---|
100 | sub inotify_path { |
---|
101 | my $i = Linux::Inotify2->new; |
---|
102 | my $sub = sub { |
---|
103 | my $e = shift; |
---|
104 | $modified_paths{$e->w->name} = 1; |
---|
105 | notify_base(); |
---|
106 | 1; |
---|
107 | }; |
---|
108 | |
---|
109 | foreach (@paths) { |
---|
110 | -d $_ or next; |
---|
111 | $i->watch( |
---|
112 | $_, |
---|
113 | IN_DELETE | IN_MODIFY | IN_CREATE, |
---|
114 | $sub, |
---|
115 | ); |
---|
116 | } |
---|
117 | |
---|
118 | $i; |
---|
119 | } |
---|
120 | |
---|
121 | |
---|