summaryrefslogtreecommitdiffstats
path: root/config/chroot_local-includes/usr/local/bin/tails-start-i2p
blob: 1e062dec613820d0126f97b55012fac4115f1694 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
#!/usr/bin/perl

use strict;
use warnings;

#man{{{

=head1 NAME

tails-start-i2p

=head1 VERSION

Version X.XX

=head1 AUTHOR

Tails dev team <amnesia@boum.org>
See https://tails.boum.org/.

=cut

#}}}

use Desktop::Notify;
use Locale::gettext;
use POSIX;

### initialization
setlocale(LC_MESSAGES, "");
textdomain("tails");

### helper subs

# TODO: get router port (default 7657) from /etc/i2p/clients.config
sub get_router_port {
    return 7657;
}

# TODO: more perlish way to do below?
# TODO: use netstat -p, check that a child of i2psvc runs the router console
sub router_status {
    return !system("netstat -nl -A inet,inet6 | grep -qe \"\\(127\\.0\\.0\\.1\\|::1\\):" . get_router_port() . "\"");
}

sub open_router_console {
    system("/usr/bin/iceweasel http://127.0.0.1:" . get_router_port());
}

sub start_i2psvc {
    system("/usr/bin/gksu /etc/init.d/i2p start");
}

sub stop_i2psvc {
    system("/usr/bin/gksu /etc/init.d/i2p start");
}  

### main

my $notify = Desktop::Notify->new();

my $summary = gettext("Starting I2P...");
my $body    = gettext("The I2P router console will be opened on start.");

my $notification = $notify->create(summary => $summary,
                                   body => $body,
                                   timeout => 0);

$notification->show();

my $tordate_done_file = '/var/run/tordate/done';
my $tordate_wait      = 0;

# There was a "fix" in i2p 0.8.8 for handling clock jumps and skews which seems
# to be broken -- a jump during i2p bootstrap leads to i2p starting in a non-
# working state, as does starting i2p when the clock is off too much. Hence, for
# simplicity, we make i2p dependent on tordate. The real fix will be when
# i2p gets its act together and handles these problems correctly.
until (-e $tordate_done_file) {
    if ($tordate_wait > 60) {
	$notification->close();
	$summary = gettext("I2P failed to start");
	$body    = gettext("Make sure that you have a working Internet " .
			      "connection, then try to start I2P again.");
	$notification = $notify->create(summary => $summary,
					   body => $body,
					   timeout => 60000);
	$notification->show();
	exit 1;
    }
    sleep(1);
    $tordate_wait++;
}

my $htpdate_done_file = '/var/run/htpdate/done';
my $htpdate_wait      = 0;

# We also need to wait for htpdate for same the reason as
# above. However, tordate will set the clock so that it is correct
# enough for I2P to work (it can operate with +/- 2 hours clock skew)
# so we optimistically try to start I2P even if htpdate doesn't
# finish.
until (-e $htpdate_done_file || $htpdate_wait > 120) {
    sleep(1);
    $htpdate_wait++;
}

start_i2psvc();

my $t = 0;
my $timeout = 180;
while ($t < $timeout && !router_status()) {
    $t++;
    sleep 1;
}

$notification->close();

if (router_status()) {
    open_router_console();
    exit 0;
} else {
    stop_i2psvc();
    $summary = gettext("I2P failed to start");
    $body    = gettext("Something went wrong when I2P was starting. Look in " .
		       "the logs in the following directory for " .
			  "more information:") . "\n\t/var/log/i2p/";
    $notification = $notify->create(summary => $summary,
                                    body => $body,
                                    timeout => 60000);
    $notification->show();
    exit 1;
}