#!/usr/bin/env perl
=begin About
This is a perlized "Update Server" script which should run out of the box
on most machines. If not you need to install HTTP::Tiny
sudo cpan
>install HTTP::Tiny

by virii

= end

=cut

use HTTP::Tiny;
use IO::Socket;
######## [defaults] ########
@configs = @ARGV if @ARGV;                           # perl updater_server.pl torrc torrc0 torrc1
@configs = qw(torrc torrc2) unless @ARGV;            # OR hardcode every config file! like: torrc torrc0 torrc1 
$data_dir = '/var/lib/tor';                          # default data dir
$pidfile  = '/var/run/tor/tor.pid';                  # default pid file
$API_url = 'http://enn.lu';                          # will be ignored if /etc/ennstatus_updater.conf is present
######## [ennstatus URL - config file] ######
if (-e '/etc/ennstatus_updater.conf') {
    open ennstatus, "<", "/etc/ennstatus_updater.conf" || die "Cannot open 'ennstatus_updater.conf'!\n";
            while (<ennstatus>) {
                $ennstatus_url = $1 if /^ennstatus_url = (.+)/i;
            }
    close ennstatus;
} else {
    $ennstatus_url = $API_url;
}
######## [loop through configs] ########
for (1..scalar @configs) {
    open config, "<", "/etc/tor/" . $configs[$_ -1] || die "Cannot open $configs[$_ -1]\n";
        while (<config>) {
            $server_name = $1       if /^Nickname (\w+)/i;
            $server_type = 'Exit'   if /^ExitPolicy accept \*:\*/i;
            $server_type = 'Relay'  if /^ExitPolicy reject \*:\*/i and $server_type ne 'Bridge';
            $server_type = 'Bridge' if /^BridgeRelay 1/i;
            $data_dir    = $1       if /^DataDirectory (.*)/i;
            $pidfile     = $1       if /^PidFile (.*)/i;
            $obfs        = 'True'   if /^ServerTransportPlugin (obfs\d+|scramblesuit)/i;
	    $fteproxy    = 'True'   if /^ServerTransportPlugin fte/i;
            $ip          = $1       if /^OutboundBindAddress (\d+\.\d+\.\d+\.\d+)/i;
        }
    close config;
######## [obfs check] ########  
    $obfs = 'False' if $obfs ne 'True' and $server_type eq 'Bridge';
print $obfs . "\n";
######## [fte check] ########
$fteproxy = 'False' if $fteproxy ne 'True' and $server_type eq 'Bridge';
print $fteproxy . "\n";
######## [ip check] ########    
    if ($ip == "") {
        $socket = new IO::Socket::INET ( PeerAddr => "enn.lu",
                                         PeerPort => 80,
                                         Proto => 'tcp');
        $ip = $socket->sockhost;
        close $socket;
    }
######## [fingerprint] ######## 
    open fingerprint, "<", $data_dir . '/fingerprint';
        $read_in = <fingerprint>;
        $fingerprint = $1 if $read_in =~ /^\w+ (\w{40})/i;
    close fingerprint;
######## [pid check] ########   
    open pidfile, "<", $pidfile;
        $pid = <pidfile>;
    close pidfile;
    $psaux = kill 0, $pid;
    if ($psaux) {
        $tor_status = 'Online';
    } else {
        $tor_status = 'Offline';
    }
######## [create json string] ########    
if ($server_type eq "Bridge") {
$json_string = '{"fingerprint": "' . $fingerprint .
                '", "ip": "' . $ip .
                '", "server_name": "' . $server_name .
                '", "server_type": "' . $server_type .
                '", "obfs": "' . $obfs .
		'", "fteproxy": "' . $fteproxy .
                '", "tor_status": "' . $tor_status .
                '"}';
} else {
$json_string = '{"fingerprint": "' . $fingerprint .
                '", "ip": "' . $ip .
                '", "server_name": "' . $server_name .
                '", "server_type": "' . $server_type . 
                '", "tor_status": "' . $tor_status .
                '"}';
}
######## [Send to server] ########
$request = HTTP::Tiny->new->request('POST', $ennstatus_url . '/api/update',
                    {
                      content => $json_string,
                      headers => { 'content-type' => 'application/json' }
                    }
                                    );

print $request->{content};
######## [end of loop] ########
}



