#!/usr/bin/perl # # Copyright (c) by Kirill Miazine # # This software is distributed under an ISC-style license, please see # for details. # use strict; use vars qw(%cache); use POE; use POE::Session; use POE::Component::Client::HTTP; use IO::Socket::UNIX; use HTTP::Request::Common; use Unix::Syslog qw(:macros :subs); use constant SOCKET_PATH => '/var/imap/socket/notify'; # see your imapd.conf use constant VGS_USER => 'abc'; # vgsmail username use constant VGS_PASS => 'zyx'; # vgsmail password use constant DAILY_MAX => 50; # max messages/day openlog('notify', LOG_PID, LOG_LOCAL6); POE::Component::Client::HTTP->spawn(Alias => 'ua', MaxSize => 128); POE::Session->create( inline_states => { _start => sub { my ($kernel, $heap) = @_[KERNEL, HEAP]; my $socket_path = SOCKET_PATH; unlink $socket_path if -e $socket_path; umask 0002; my $sock = IO::Socket::UNIX->new(Local => $socket_path, Type => SOCK_DGRAM); $kernel->select_read($sock, 'recv_data'); }, _stop => sub { }, recv_data => sub { my ($kernel, $heap) = @_[KERNEL, HEAP]; my $handle = $_[ARG0]; return if !defined(recv($handle, my $data, 8192, 0)); my @args = split /\0/, $data; my %args = (method => shift @args, class => shift @args, priority => shift @args, user => shift @args, mailbox => shift @args, nopt => shift @args, message => pop @args, opts => \@args); return if $args{'nopt'} == 0; my ($user, $message) = @args{qw(user message)}; (my $target = $args{'opts'}->[0]) =~ s/[^\d]//g; return if !($target and $message); my $now = time; my ($last, $count) = ($now, 0); if (exists $cache{$user}) { ($last, $count) = @{$cache{$user}}{qw(last count)}; ($last, $count) = ($now, 0) if $last + 86400 < $now; } return syslog(LOG_ERR, "$user: max daily limit reached") if $count >= DAILY_MAX; $cache{$target} = {last => $last, count => ++$count}; my $req = POST('http://www.vgsmail.com/cgi/sendsms.cgi', [userid => VGS_USER, password => VGS_PASS, client => 'notifyd', to => $target, text => substr($message, 0, 160)]); $kernel->post('ua', 'request', 'http_response', $req); syslog(LOG_ERR, "$user: notified at $target"); }, http_response => sub { my ($kernel, $heap) = @_[KERNEL, HEAP]; my ($req, $res) = map { $_->[0] } @_[ARG0, ARG1]; syslog(LOG_ERR, $res->content); }, }, ); POE::Kernel->run(); exit;