This file is indexed.

/usr/share/perl5/IkiWiki/Plugin/pinger.pm is in ikiwiki 3.20141016.4.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  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
#!/usr/bin/perl
package IkiWiki::Plugin::pinger;

use warnings;
use strict;
use IkiWiki 3.00;

my %pages;
my $pinged=0;

sub import {
	hook(type => "getsetup", id => "pinger", call => \&getsetup);
	hook(type => "needsbuild", id => "pinger", call => \&needsbuild);
	hook(type => "preprocess", id => "ping", call => \&preprocess);
	hook(type => "delete", id => "pinger", call => \&ping);
	hook(type => "rendered", id => "pinger", call => \&ping);
}

sub getsetup () {
	return
		plugin => {
			safe => 1,
			rebuild => 0,
		},
		pinger_timeout => {
			type => "integer",
			example => 15,
			description => "how many seconds to try pinging before timing out",
			safe => 1,
			rebuild => 0,
		},
}

sub needsbuild (@) {
	my $needsbuild=shift;
	foreach my $page (keys %pagestate) {
		if (exists $pagestate{$page}{pinger}) {
			$pages{$page}=1;
			if (exists $pagesources{$page} &&
			    grep { $_ eq $pagesources{$page} } @$needsbuild) {
				# remove state, will be re-added if
				# the ping directive is still present
				# on rebuild.
				delete $pagestate{$page}{pinger};
			}
		}
	}
	return $needsbuild;
}

sub preprocess (@) {
	my %params=@_;
	if (! exists $params{from} || ! exists $params{to}) {
		error gettext("requires 'from' and 'to' parameters");
	}
	if ($params{from} eq $config{url}) {
		$pagestate{$params{destpage}}{pinger}{$params{to}}=1;
		$pages{$params{destpage}}=1;
		return sprintf(gettext("Will ping %s"), $params{to});
	}
	else {
		return sprintf(gettext("Ignoring ping directive for wiki %s (this wiki is %s)"), $params{from}, $config{url});
	}
}

sub ping {
	if (! $pinged && %pages) {
		$pinged=1;
		
		eval q{use Net::INET6Glue::INET_is_INET6}; # may not be available
		
		my $ua;
		eval q{use LWPx::ParanoidAgent};
		if (!$@) {
			$ua=LWPx::ParanoidAgent->new(agent => $config{useragent});
		}
		else {
			eval q{use LWP};
			if ($@) {
				debug(gettext("LWP not found, not pinging"));
				return;
			}
			$ua=useragent();
		}
		$ua->timeout($config{pinger_timeout} || 15);
		
		# daemonise here so slow pings don't slow down wiki updates
		defined(my $pid = fork) or error("Can't fork: $!");
		return if $pid;
		chdir '/';
		open STDIN, '/dev/null';
		open STDOUT, '>/dev/null';
		POSIX::setsid() or error("Can't start a new session: $!");
		open STDERR, '>&STDOUT' or error("Can't dup stdout: $!");
		
		# Don't need to keep a lock on the wiki as a daemon.
		IkiWiki::unlockwiki();
		
		my %urls;
		foreach my $page (%pages) {
			if (exists $pagestate{$page}{pinger}) {
				$urls{$_}=1 foreach keys %{$pagestate{$page}{pinger}};
			}
		}
		foreach my $url (keys %urls) {
			# Try to avoid pinging ourselves. If this check
			# fails, it's not the end of the world, since we
			# only ping when a page was changed, so a ping loop
			# will still be avoided.
			next if $url=~/^\Q$config{cgiurl}\E/;
			my $local_cgiurl = IkiWiki::cgiurl();
			next if $url=~/^\Q$local_cgiurl\E/;
			
			$ua->get($url);
		}
		
		exit 0;
	}
}

1