1#!/usr/bin/perl
2# ircstats2.pl v1.3 06 Apr 2001 Lucas Nussbaum <lucas@schickler.net>
3# More info can be found on http://www.schickler.net/lucas/ircstats2.php
4# based on ircstats from Matt Ramsey (MR227) mjr@geeks.org, mjr@nin.com
5# Used to generate stats on the Kewl.Org IRC Network
6# If you see something that should be changed, please notify me !
7
8use Socket;
9
10# pseudo-client parameters
11$nick = "StatsMaker234";
12$ident = "Stats";
13$realname = "http://www.schickler.net/lucas/";
14
15# server and port to connect to
16$ircserver = "127.0.0.1";
17$ircport = "6667";
18
19# Where to store the output data (directory MUST exist)
20# The number of users on each server will be in a file named like the server.
21# An additionnal file named 'global' will be created, containing the sum of
22# all servers' users.
23# An example configuration file is included.
24$datapath = "/home/lucas/ircstats2/temp";
25
26# Where to put the PID file
27$pidfile = "/home/lucas/ircstats2/ircstats2.pid";
28
29# NOTE: Set those variables to 0 to enable, put a # in front of the
30# lines to disable.
31# Count the global number of users in "globalusersmrtg" file (MRTG format)
32$globalusersmrtg=0;
33# Count the channels in "channelsmrtg" file (MRTG format)
34$channelsmrtg=0;
35# Count the global number of ircops in "ircopsmrtg" file (MRTG format)
36$ircopsmrtg=0;
37# Count the number of servers in "serversmrtg" file (MRTG format)
38$serversmrtg=0;
39# Count the global number of users in "globalusersplain" file
40# (Plain text, to be used with others scripts)
41$globalusersplain=0;
42# Count the channels in "channelsplain" file (Plain text,
43# to be used with others scripts)
44$channelsplain=0;
45# Count the global number of ircops in "ircopsplain" file
46# (Plain text, to be used with others scripts)
47$ircopsplain=0;
48# Count the number of servers in "serversmrtg file (MRTG format)
49$serversplain=0;
50# ircops number offset (not to count services, for example)
51$ircopsoffset=0;
52# servers number offset (not to count services, for example)
53$serversoffset=0;
54
55# Servers to poll
56$server{"cybernet.langochat.net"}=0;
57$server{"sicfa.langochat.net"}=0;
58$server{"free.langochat.net"}=0;
59$server{"jeuxgroup.langochat.net"}=0;
60$server{"diligo.langochat.net"}=0;
61
62##############################################
63### DO NOT MODIFY ANYTHING BELOW THIS LINE ###
64##############################################
65
66print "Now daemonizing ...\n";
67&daemonize;
68
69if (!(($globalusersmrtg eq "")&&($globalusersplain eq "")&&($channelsmrtg eq "")&&($channelsplain eq "")&&($ircopsmrtg eq "")&&($ircopsplain eq "")&&($serversplain eq "")&&($serversmrtg eq ""))) {
70	$needlusers=1;
71}
72($g, $g, $proto) = getprotobyname("tcp");
73while (true) {
74	($g, $g, $g, $g, $rawserver) = gethostbyname($ircserver);
75	if ($rawserver) {
76		$serveraddr = pack("Sna4x8", 2, $ircport, $rawserver);
77		socket(SOCKET, AF_INET, SOCK_STREAM, $proto) || die "No socket: $!";
78		if (connect(SOCKET, $serveraddr)){
79			select(SOCKET); $| = 1;
80			select(STDOUT); $| = 1;
81			print SOCKET "USER $ident a b :$realname\n";
82			print SOCKET "NICK $nick\n";
83			while (<SOCKET>){
84				@i = split(" ",$_);
85				if ($i[1] eq "433") {print SOCKET "NICK ".$nick.time()."\n";}
86				elsif ($i[1] eq "437") {print SOCKET "NICK ".$nick.time()."\n";}
87				elsif ($i[1] eq "376") {&getinfo;}
88				elsif ($i[1] eq "402") {$server{lc($i[3])}=0;}
89				elsif ($i[1] eq "265") {
90					$i[0]=~s/\://;
91					$server{lc($i[0])}=$i[6];
92				}
93				elsif ($i[1] eq "266") {
94					if ($globalusersmrtg ne "") {
95						$globalusersmrtg=$i[6];
96					}
97					if ($globalusersplain ne "") {
98						$globalusersplain=$i[6];
99					}
100				}
101				elsif ($i[1] eq "254") {
102					if ($channelsmrtg ne "") {
103						$channelsmrtg=$i[3];
104					}
105					if ($channelsplain ne "") {
106						$channelsplain=$i[3];
107					}
108				}
109				elsif ($i[1] eq "251") {
110					if ($serversmrtg ne "") {
111						$serversmrtg=$i[11]-$serversoffset;
112					}
113					if ($serversplain ne "") {
114						$serversplain=$i[11]-$serversoffset;
115					}
116				}
117				elsif ($i[1] eq "252") {
118					if ($ircopsmrtg ne "") {
119						$ircopsmrtg=$i[3]-$ircopsoffset;
120					}
121					if ($ircopsplain ne "") {
122						$ircopsplain=$i[3]-$ircopsoffset;
123					}
124				}
125				elsif ($i[0] eq "PING") {
126					&saveinfo;
127					print SOCKET "PONG $i[1]\n";
128					&getinfo;
129				}
130			}
131		}
132		close(SOCKET);
133	}
134	sleep(120);
135}
136
137sub saveinfo {
138	foreach $s (keys %server){
139		open(OUTPUT,">$datapath/$s");
140		print OUTPUT "$server{$s}\n$server{$s}\n$time\n";
141		close(OUTPUT);
142	}
143	if ($globalusersmrtg ne "") {
144		open(OUTPUT, ">$datapath/globalusersmrtg");
145		print OUTPUT "$globalusersmrtg\n$globalusersmrtg\n$time\n";
146		close(OUTPUT);
147	}
148	if ($channelsmrtg ne "") {
149		open(OUTPUT, ">$datapath/channelsmrtg");
150		print OUTPUT "$channelsmrtg\n$channelsmrtg\n$time\n";
151		close(OUTPUT);
152	}
153	if ($serversmrtg ne "") {
154		open(OUTPUT, ">$datapath/serversmrtg");
155		print OUTPUT "$serversmrtg\n$serversmrtg\n$time\n";
156		close(OUTPUT);
157	}
158	if ($ircopsmrtg ne "") {
159		open(OUTPUT, ">$datapath/ircopsmrtg");
160		print OUTPUT "$ircopsmrtg\n$ircopsmrtg\n$time\n";
161		close(OUTPUT);
162		$ircopsmrtg=0; # raw 252 pas disp si pas opers
163
164	}
165	if ($globalusersplain ne "") {
166		open(OUTPUT,">$datapath/globalusersplain");
167		print OUTPUT "$globalusersplain";
168		close(OUTPUT);
169	}
170	if ($channelsplain ne "") {
171		open(OUTPUT, ">$datapath/channelsplain");
172		print OUTPUT "$channelsplain";
173		close(OUTPUT);
174	}
175	if ($serversplain ne "") {
176		open(OUTPUT, ">$datapath/serversplain");
177		print OUTPUT "$serversplain";
178		close(OUTPUT);
179	}
180	if ($ircopsplain ne "") {
181		open(OUTPUT, ">$datapath/ircopsplain");
182		print OUTPUT "$ircopsplain";
183		close(OUTPUT);
184		$ircopsplain=0; # raw 252 pas disp si pas opers
185	}
186}
187
188sub getinfo {
189	foreach $s (keys %server) {
190		print SOCKET "lusers * $s\n";
191	}
192	$time=time();
193	if ($needlusers==1) {
194		print SOCKET "lusers\n";
195	}
196}
197
198sub daemonize () {
199	chdir "/" or die "Can't chdir to /: $!";
200	open STDIN, "/dev/null" or die "Can't read /dev/null: $!";
201	open STDOUT, ">/dev/null" or die "Can't write to /dev/null: $!";
202	defined (my $pid = fork) or die "Can't fork: $!";
203	if ($pid) {
204		if ($pidfile) {
205			open(PIDFILE,">$pidfile");
206			print PIDFILE "$pid\n";
207			close(PIDFILE);
208		}
209		exit;
210	}
211	setsid or die "Can't start a new session: $!";
212	open STDERR, ">&STDOUT" or die "Can't dup stdout: $!";
213}
214