-
-
Notifications
You must be signed in to change notification settings - Fork 162
/
Copy pathstats.cgi
executable file
·110 lines (95 loc) · 3.01 KB
/
stats.cgi
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
#!/usr/local/bin/perl
#
# Authentic Theme (https://github.com/authentic-theme/authentic-theme)
# Copyright Ilia Rostovtsev <ilia@virtualmin.com>
# Licensed under MIT (https://github.com/authentic-theme/authentic-theme/blob/master/LICENSE)
#
use strict;
require($ENV{'THEME_ROOT'} . "/stats-lib.pl");
our ($config_directory, $current_theme, $root_directory, $var_directory, %text);
# Check access
init_prefail();
if (!defined(&webmin_user_is_admin) || !webmin_user_is_admin()) {
print_json({ error => $text{'index_noadmin_eaccess'}, access => 0 });
exit;
}
# Check dependencies
my @errors;
my @modnames = ("Digest::SHA", "Digest::MD5", "IO::Select",
"Time::HiRes", "Net::WebSocket::Server");
foreach my $modname (@modnames) {
eval "use ${modname};";
if ($@) {
push(@errors, $@, $modname);
push(@errors, text('index_mods_missing', $modname));
last;
}
}
if (@errors) {
print_json({ error => $errors[2],
error_module => $errors[1],
error_stack => $errors[0] });
exit;
}
# Get the log file
my $get_logfile = sub {
my ($port) = @_;
return "$var_directory/modules/$current_theme/stats-server-$port.log";
};
# Get the socket URL
my $get_socket = sub {
my ($port) = @_;
return get_miniserv_websocket_url($port, undef, $current_theme);
};
# Prevent race condition
my $tempname_dir = tempname_dir();
my $lock_file = "stats-server-locking";
my $lock_file_checked = 0;
while ($lock_file_checked < 3 && -r "$tempname_dir/$lock_file") {
$lock_file_checked++;
sleep(1);
}
my $lock = transname($lock_file);
my $lockfh;
open_tempfile($lockfh, ">$lock");
print_tempfile($lockfh, $$);
close_tempfile($lockfh);
sleep(1);
# Do we have an active socket?
my %miniserv;
get_miniserv_config(\%miniserv);
foreach my $k (keys %miniserv) {
if ($k =~ /^websockets_\/$current_theme\/ws-(\d+)$/) {
my $port = $1;
my $host = $miniserv{$k};
($host) = $host =~ /.*host=([^ ]+).*/;
next if (!$host);
# Is this socket still active?
my $err;
open_socket($host, $port, my $fh, \$err);
next if ($err);
print_json({ success => 1, port => $port, new => 0,
socket => $get_socket->($port),
errlog => $get_logfile->($port) });
exit;
}
}
# Allocate port
my $port = allocate_miniserv_websocket($current_theme);
# Launch the stats server
my $server_name = "stats.pl";
my $statsserver_cmd = "$config_directory/$current_theme/$server_name";
create_wrapper($statsserver_cmd, $current_theme, $server_name)
if (!-r $statsserver_cmd);
# Launch the server in a sub-process (no fork)
my $logfile = $get_logfile->($port);
my $rs = system_logged(
"SESSION_ID=$main::session_id ".
"$statsserver_cmd @{[quotemeta($port)]} ".
">$logfile 2>&1 </dev/null &");
# Return the result
print_json({ success => !$rs, port => $port,
socket => $get_socket->($port),
new => 1, errlog => $logfile });
# Make sure the server is up
sleep(1);