1###############################################################################
2# Find script that searches your local files and sends them to users
3# Copyright (C) 2003  Thomas Karlsson
4#
5# Findbot script, which responds to @find commands in irc channels
6#
7# This program is free software; you can redistribute it and/or modify
8# it under the terms of the GNU General Public License as published by
9# the Free Software Foundation; either version 2 of the License, or
10# (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15# GNU General Public License for more details.
16#
17# You should have received a copy of the GNU General Public License
18# along with this program; if not, write to the Free Software
19# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20#
21# Thomas Karlsson (findbot@planet.eu.org)
22#
23###############################################################################
24# Description:
25#
26# This script loads into an Irssi client and then monitors selected channels
27# and replies to public channel commands.
28# The commands are:
29# @find :	searches the summaryfile after file "@find birthday" looks for
30#		a file containing birthday.
31# @<botnick>-stats : Replies with the users queue.
32# @<botnick>-remove : Will remove the users whole queue
33# @<botnick>-remove 2 : Will remove queue position 2 from the queue
34# @<botnick>-help : Will message the help to the user.
35# !<botnick> <filename> :Will queue the file. For eg."!santa_claus jingle.bells.mp3"
36#
37###############################################################################
38# Installation:
39#
40# AT THE END OF THIS FILE IS ALL INSTALLATION INSTRUCTIONS!!
41#
42# Variables:
43# findbot_channels - Space separated channels (#mp3 #othermp3)
44# findbot_summaryfile - Full path to the "mymp3s.txt" file (/misc/mp3/mymp3s.txt)
45# findbot_sendlist - Full path and filename to the list that is sent to clients
46# findbot_maxresults - Max findresults returned to the requesting client
47# findbot_maxqueue - Max files allowed in the queue
48# findbot_maxsends - Max simultanous sends allowed
49# findbot_maxuserqueue - Max queued files per Nick
50# findbot_maxusersends - Max simultanous sends per Nick
51# findbot_showbanner - Present a banner in every "findbot_channels" channel
52# findbot_bannertime - How many seconds between each banner
53# findbot_minspeed - Minimum CPS for a send, 10000 means 10kb/s, 0 means disabled
54# findbot_mustbeinchannel - If ON, the user is required to be in the channel during download
55# findbot_debuglevel - Debuglevel, Higher value equals more debugoutput
56# findbot_enabled - Set ON or OFF
57# findbot_timeslots - When the server should be enabled (sat=10:00-18:00sun=00:00-23:59)
58#		      If a day can't be found the bot will be ON by default
59# findbot_voicegetpriority - If ON then voiceuserusers and ops will get priority in the queue.
60#			Ops get 20 in priority and voice gets 10. I.e ops are more prioritized than voice
61#
62# Admincommands:
63# /findbotqueue  - Shows you the whole queue in the findbot window
64# /findbotremove - Admin removes queueitems
65# /findbotreset  - If you like you can specify how many sends the script thinks it have. This was just added
66#                  if you wanted to send somefiles your self without the script sending files.
67# /findbotreload - Reloads the summaryfile if you have added files
68# /findbotactivesends - Show which users are currently having a download
69#
70###############################################################################
71# TODO or maybe features
72#
73# * When requesting it SHOULD be case sensitive
74# * Support CTCP SLOTS and CTCP MP3, seems unnecessary to help windows-mirc users :)
75#   Slots Free Next Queues Max Sendspeed Files
76#   4     4    NOW  0      999 0         120575 36856591362 0 1073595728 1
77# * Make an ignore and ban function
78# * Should the users see the whole que or just their own files?
79# * If there is a netsplit all downloads will be cancelled if an active user disappered
80# * If one send is below like 4kb/s then change findbot_maxsends to one more, so we use the bandwidth
81# * DONE Servers (i.e +v) should get priority, but how? First in queue?
82# * DONE Fix admin_showqueue to really show VIP instead of 1
83###############################################################################
84# CHANGES
85#
86# 1.58  * requesting in a private message is allowed when user is in a monitored channel
87# 	* filelist creation script at the bottom of this script has been changed to support utf8, multiple folders, with or without file and          7z compression of the command list
88# 1.57	* Added a VIP function which allows +v users to be first in line to get a file
89# 	* Remove a users queue if they get kicked (only if findbot_mustbeinchannel is ON)
90#	* Fixed a bug when a user with a download changed nick.
91# 1.56  * The findbot_maxqueue now works
92#	* Sending files with spaces in them, now works
93# 1.55	* Minor changes
94# 1.54	* Added support to update the mp3list without restarting the bot (/findbotreload)
95# 1.53	* Fixed some debug output
96# 1.52	* Fixed some typos
97#	* Now people can't look for * . etc. Now a searchpattern MUST contain atleast 1 normal character
98#	* Fixed so you can change banner time without restarting the bot
99# 1.50	* Added a timeslot function
100#	* Added logging support. Now logging to file. Must specify filename and path INSIDE this script
101# 1.06	* "Optimized" search. Instead of opening and read the whole summaryfile everytime
102#	  someone searched the script reads the file once at startup.
103#	* Fixed more regular expressions
104#	* Added multiserver support, i.e you can have the bot on two nets and two different channels
105# 1.05	* Added a new perlscript at the end of this file.
106#	  It searches your mp3s and makes the 2 necessary files.
107#	  The script is made by Henrik Andreasson (findbot@han.pp.se)
108# 1.04	* Changed so the files contains full path to mp3s
109#	* findbot_maxsends was ignored under some circumstanses
110#	* Added so debugoutput shows which file are sent
111#	* Sending to client "Now sending you file...." only if they accually are in the channel
112# 1.03	* Changed a "for-loop" one bit
113#	* If findbot_minimumspeed was disabled, then the user could leave channel
114#	  and still get files even if findbot_mustbeinchannel was enabled
115#	* Forgot to write to debugwindow if someone downloaded the whole list
116#	* Corrected some bad english :)
117#	* Fixed more regular expressions
118#	* The user will be told the queueposition when requesting a file
119#	* Fixed some queueproblems
120#	* Added some errormessages if someone types !nickname in a private message
121# 1.01	* Do not reply with "no match" if no match was found to avoid unnecessary spam
122#	* Removed alot of commented code
123#	* Changed the description of the script
124#	* Changed the "results found" string a bit.
125#	* Added a new value findbot_sendlist and separated the filelist and the one which accually is sent to the users
126#	* Fixed some regular expressions to fit the new searchfiles
127#	* Bug fix. If someone resumed a file, they always will be under findbot_minspeed in the start
128#	* Didn't search if someone typed @FIND (in uppercase)
129#	* Ops the url wasn't right. There is no ~ in the address :)
130# 1.0	Release
131###############################################################################
132use Irssi;
133use Irssi::Irc;
134use strict;
135use vars qw($VERSION %IRSSI);
136
137$VERSION = "1.58";
138
139%IRSSI = (
140    authors     =>  "Thomas Karlsson",
141    contact     =>  "findbot\@planet.eu.org",
142    name        =>  "Findbot",
143    description =>  "Public command \@find script",
144    license     =>  "GPL",
145    url         =>  "http://hem.passagen.se/thka2315/",
146);
147
148my %nickqueue = ();	# Queuenumber + nickname
149my %filequeue = ();	# Queuenumber + filename
150my %servertagqueue = (); # Queuenumber + array with servertag,voiceprio,extrafield
151my %activesends = ();	# nickname + 1 The user is here if he has an active send
152my $lastqueuenumber = 0;	# Holds the last queueitem
153my %scriptdetect = ();
154my $timeout_tag;
155my $banner_timeout;
156my $currentsends = 0;
157my $servertag;
158my $globalstart = 0;
159my $globalvippos = 0;
160my $debuglevel;
161my %bannedpeople = ();	# This will contain banned people and time of ban
162my @bigarray;		# In here the whole filelist will reside
163my @daynames = qw(Sun Mon Tue Wed Thu Fri Sat);
164my $logfile = "findbot.log";
165my $scriptdetecttime = "3"; # Three seconds must pass before a new filerequest is issued, after a DCC CLOSE
166my $showscriptdetect = 1;
167my $lastbannerprint = time();	# The last time the banner was printed into monitored channels
168
169sub timeslotenabled {
170	my $weekday = shift;		# Save weekday
171	my $slothour = shift;		# Save hours
172	my $slotminute = shift;		# Save minutes
173
174	$weekday = $daynames[$weekday];
175	my $timeslotstring = Irssi::settings_get_str('findbot_timeslots');
176	if ( $timeslotstring =~ /$weekday/i ) {
177		if ( $timeslotstring =~ m/.*$weekday=(.?.):(.?.)(a\.?m\.?|p\.?m\.?)?-(.?.):(.?.)(a\.?m\.?|p\.?m\.?)?.*/i ) {
178			my $fromhour = $1;
179			my $frommin = $2;
180			my $fromampm = $3;
181			my $tohour = $4;
182			my $tomin = $5;
183			my $toampm = $6;
184			if ( $fromampm =~ /p/i ) { $fromhour += 12; }		# If it is a pm time add 12 to get 24h format
185			if ( $toampm =~ /p/i ) { $tohour += 12; }		# If it is a pm time add 12 to get 24h format
186			my $midnightfrom = ( $fromhour * 60 ) + $frommin;		# Get minutes from midnight
187			my $midnightto = ( $tohour * 60 ) + $tomin;		# Get minutes from midnight
188			my $inputtime = ( $slothour * 60 ) + $slotminute;		# Get minutes from midnight
189			debugprint(20,"inputtime:$inputtime midfrom:$midnightfrom midto:$midnightto");
190			if ( $inputtime <= $midnightto && $inputtime >= $midnightfrom ) {
191				return 1;					# The time is between the timeenabled slot
192			} else {
193				return 0;					# Time was outside. Bot should be off.
194			}
195		} else {
196			return 0;	# Hmm didnt get the times in that day, maybe wrong input from user
197		}
198	} else {
199		return 1;	# If the current day wasn't found in findbot_timeslots then return true, i.e bot is default ON.
200	}
201	return 0;		# Return false i.e
202}
203
204sub private_get {
205	(my $server, my $message, my $nick, my $address) = @_;
206	if ( $message =~ /^!$server->{nick}\ .*/i ) {
207		$server->command("/MSG " . $nick . " Please request files in the channel, not personally to me. Type \@$server->{nick}-help in channel for help");
208	} elsif ( $message =~ /^\@$server->{nick}.*/i ) {
209		$server->command("/MSG " . $nick . " Please request my filelist in the channel, not personally to me. Type \@$server->{nick}-help in channel for help");
210	} elsif ( $message =~ /^\@find.*/i ) {
211		$server->command("/MSG " . $nick . " Please search files in the channel, not personally to me. Type \@$server->{nick}-help in channel for help");
212	}
213}
214
215sub check_user_queued_items {
216	my $user = shift;					# Get the nickname to check
217	my $localsrvtag = shift;
218	my $counter = 0;					# Reset the counter
219	for ( my $i=1; $i <= $lastqueuenumber; $i++ ) { # Loop through entire queue
220		if ( $nickqueue{$i} eq $user && $localsrvtag eq $servertagqueue{$i}[0] ) {
221			$counter++;
222		}
223	}
224	return $counter;
225}
226
227sub already_queued_file {
228	my $checknick = shift;
229	my $checkfile = shift;
230	my $srvtag = shift;
231	my $alreadyqueued = 0;
232	for ( my $i=1; $i <= $lastqueuenumber; $i++ ) {	# Loop through entire queue
233		if ( $nickqueue{$i} eq $checknick && $filequeue{$i} eq $checkfile && $servertagqueue{$i}[0] eq $srvtag) { # Check if its queued
234			$alreadyqueued = 1;		# Yep it was
235		}
236	}
237	if ( $alreadyqueued ) { return 1; } else { return 0; } # Return true if queued else false
238}
239
240sub add_file_to_queue {
241	(my $addnick, my $addfile, my $srvtag, my $priority) = @_;			# Split nickname and filename into two variables
242	$lastqueuenumber++;
243	$nickqueue{$lastqueuenumber} = $addnick;	# for eg. $nickqueue{1} = 'El_Tomten'
244	$filequeue{$lastqueuenumber} = $addfile;	# for eg. $filequeue{1} = '/misc/legal-mp3s/happy.birthday.mp3'
245	if ( ! Irssi::settings_get_bool('findbot_voicegetpriority') ) { $priority = 0; }
246	my @field = ($srvtag,$priority,"To be used later, maybe");
247	$servertagqueue{$lastqueuenumber} = \@field;	# for eg. $servertagqueue{1} = 'stockholm'
248	if ( $priority > 1 ) {		# Did a priority user queued the file
249		fix_vip_position($priority);	# Move vip position up to number one, or just after the last already existing vip position
250	}
251}
252
253sub fix_vip_position {
254	my $priority = shift;		# Get priority from input
255	my ($tnickqueue,$tfilequeue,$tservertagqueue);
256	if ( $lastqueuenumber eq 1 ) { return; }	# If the queue only have one entry, why try to make it a priority?
257	for ( my $i = $lastqueuenumber; $i > 1; $i--) {
258		if ( $servertagqueue{$i-1}[1] >= $priority ) { $globalvippos = $i; last; } # Is the queue entry before a vip entry? Lets quit the prioritymove
259		$tnickqueue = $nickqueue{$i-1};			# Backup entry
260		$tfilequeue = $filequeue{$i-1};
261		$tservertagqueue = $servertagqueue{$i-1};
262
263		$nickqueue{$i-1} = $nickqueue{$i};		# Move entry up
264		$filequeue{$i-1} = $filequeue{$i};
265		$servertagqueue{$i-1} = $servertagqueue{$i};
266
267		$nickqueue{$i} = $tnickqueue;			# Restore entry ( the two entris have now changed place )
268		$filequeue{$i} = $tfilequeue;
269		$servertagqueue{$i} = $tservertagqueue;
270	}
271}
272
273sub remove_queueitem {
274	my $queueitem = shift;
275	if (defined($nickqueue{$queueitem}) && defined($filequeue{$queueitem} && defined($servertagqueue{$queueitem})) ) { # Is there really a queueitem here?
276		for ( my $i = $queueitem; $i <= Irssi::settings_get_int('findbot_maxqueue'); $i++) {
277			if ( defined($nickqueue{$i+1}) && defined($filequeue{$i+1}) && defined($servertagqueue{$i+1}) ) { # Move up in queue if there is one
278				$nickqueue{$i} = $nickqueue{$i+1};			# Move up in queue
279				$filequeue{$i} = $filequeue{$i+1};			# Move up in queue
280				$servertagqueue{$i} = $servertagqueue{$i+1};		# Move up in queue
281			}
282
283		}
284		delete $nickqueue{$lastqueuenumber};		# Delete the last entry. It has been moved up one slot
285		delete $filequeue{$lastqueuenumber};		# Delete the last entry. It has been moved up one slot
286		delete $servertagqueue{$lastqueuenumber};	# Delete the last entry. It has been moved up one slot
287		$lastqueuenumber--;				# Since we removed a queue item the lastqueuenumber decreases
288	} else { debugprint(10,"debug: No remove $queueitem"); }
289}
290
291sub user_have_max_active_sends {
292	my $nickname = shift;					# Save the nick
293	my $localserver = shift;				# Save current servertag
294	if ( $activesends{$nickname} < Irssi::settings_get_int('findbot_maxusersends') ) {
295		return 0;					# The user didn't have enough sends
296	} else {
297		return 1;					# The user have NOT an active send
298	}
299}
300
301sub user_is_in_active_channel {
302	my $nickname = shift;
303	my $srvtag = shift;
304	my $find_channels = Irssi::settings_get_str('findbot_channels'); # What channels to monitor
305        my @checkchannels = split (/ /, $find_channels); # Split into an array
306
307	foreach my $localserver ( Irssi::servers() ) {		# Loop through all connected servers
308		foreach my $singlechan ( @checkchannels ) {	# Loop through all monitored channels
309			my $channel = $localserver->channel_find($singlechan);	# Get a channelobject
310			if ( defined($channel) && defined($channel->nick_find($nickname)) ) {	# Is the nick there?
311				return 1;	# User are in monitored channels # Yep is was
312			}
313        	}
314	}
315		return 0;	# User have left monitored channels
316
317}
318
319sub nicefilename {
320        my $filename = shift;
321
322        if ( $filename =~ /.*\/(.*)\ *:.*/g ) { # If filelist is made by "file"
323		debugprint(15,"Summary file is made by the program file");
324                return $1;
325        } elsif ( $filename =~ /.*\/(.*)$/g ) { # If filelist is Not made by file
326		debugprint(15,"Summary file is NOT made by the program file");
327                return $1;
328        }
329}
330
331sub strippath {
332	my $filename = shift;			# Get parameter into $filename
333
334	$filename =~ s/.*\/(.*)/$1/g;		# Remove everything until the last /
335	return $filename;			# Return the stripped line
336}
337
338sub debugprint {
339	(my $dbglvl,my $debugmessage) = @_;	# Save input to variables
340	$debuglevel = Irssi::settings_get_int('findbot_debuglevel');
341	my $win;
342	if ( ! ($win = Irssi::window_find_name($IRSSI{name})) ) { # If the windows doesn't exist
343		$win = Irssi::Windowitem::window_create($IRSSI{name},1);
344	}
345	if ( $dbglvl <= $debuglevel ) {
346		$win->set_name($IRSSI{name});	# Select the window
347		$win->print($debugmessage,MSGLEVEL_CLIENTCRAP);
348		my $debugtid = localtime(time);
349		open (LOGFILE,">>", $logfile);
350		print LOGFILE "$debugtid: $debugmessage\n";
351		close (LOGFILE);
352	}
353}
354
355sub process_queue {
356	if (Irssi::settings_get_bool('findbot_enabled') ) { # Is the findbot enabled?
357		my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); # Get current time
358		if ( ! timeslotenabled($wday,$hour,$min) ) {		# If NOT true the bot is offline
359			debugprint(15,"The bot is Offline due to timerestrictions in findbot_timeslots");
360			return 0;
361		}
362		print_banner();
363		if ( $currentsends < Irssi::settings_get_int('findbot_maxsends') ) {    # Check if we'll send another file simultanously
364			my $i = 1;
365			while ( $i <= $lastqueuenumber ) {
366				if ( ! user_have_max_active_sends($nickqueue{$i},$servertagqueue{$i}[0]) ) { # If NOT user have max active sends
367					my $nicefile = nicefilename($filequeue{$i});
368					if ( user_is_in_active_channel($nickqueue{$i},$servertagqueue{$i}[0]) ) { # Are the user in a monitored channel?
369						debugprint(10,"[ADMIN] $nickqueue{$i} is in monitored channels, sending $nicefile");
370						my $localserver = Irssi::server_find_tag($servertagqueue{$i}[0]);
371						$localserver->command("/QUOTE NOTICE " . $nickqueue{$i} . " :Sending you the requested file: $nicefile");
372						$localserver->command("/DCC SEND $nickqueue{$i} \"$filequeue{$i}\"" );
373						remove_queueitem($i);
374						last;	# Exit the loop
375					} else {
376						debugprint(10,"[ADMIN] $nickqueue{$i} is NOT in monitored channels. Removing queueentry $filequeue{$i}");
377						remove_queueitem($i);
378					 } # Remove the queued item if the user have parted the channel
379				} else { # A user had too many sends, increase $i by one to check next queue pos.
380					$i++;	# Increase by one so we can loop through whole queue
381				}
382			} # End while or for
383		}
384	}
385	check_dcc_speed_and_in_channel();			# Check minimumspeed
386}
387
388sub dcc_created {
389	(my $dcc) = @_;	# Put active dcc in variable
390
391	debugprint(15,"dcc_created was called");
392	if ( $dcc->{type} eq "SEND" ) {				# Is it a SEND?
393		if ( defined( $activesends{$dcc->{nick}} ) ) {
394			$activesends{$dcc->{nick}} = $activesends{$dcc->{nick}} + 1;
395		} else {
396			$activesends{$dcc->{nick}} = 1;
397		}
398		$currentsends++;
399	}
400}
401
402sub dcc_closed {
403	(my $dcc) = @_; # Put active dcc in variable
404
405	debugprint(15,"dcc_closed was called");
406	if ( $dcc->{type} eq "SEND" && defined ($activesends{$dcc->{nick}}) ) {	# Is it a SEND and a findbot SEND?
407		my $tiden = time();
408		$tiden = $tiden - $dcc->{starttime};
409		if ( $tiden > 0 ) {
410			my $kbsec = $dcc->{transfd} / $tiden;
411		} else {
412			$tiden = 1;
413			my $kbsec = $dcc->{transfd} / $tiden;
414		}
415		if ( $dcc->{transfd} == 0 ) {		# If transfered byts are zero, then it was probably aborted
416			debugprint(10,"[ADMIN] SEND aborted Nick: $dcc->{nick} File: $dcc->{arg}");
417		} else {
418			debugprint(10,"[ADMIN] SEND done Nick: $dcc->{nick} File: $dcc->{arg} Bytes: $dcc->{transfd} Time(sec): $tiden Speed: " . calc_kb_sec($tiden,$dcc->{transfd}) . " KB/s");
419		}
420		if ($activesends{$dcc->{nick}} == 1) {
421			delete $activesends{$dcc->{nick}};
422		} else {
423			 $activesends{$dcc->{nick}} = $activesends{$dcc->{nick}} - 1;
424		}
425		$currentsends--;
426		$scriptdetect{$dcc->{nick}} = time();		# Record the time when dcc was closed
427	}
428}
429
430sub calc_kb_sec {
431	my $seco = shift;
432	my $bytest = shift;
433
434my 	$kbsec = $bytest / $seco / 1000;
435	$kbsec =~ s/(.*\..?.?).*/$1/;
436
437	return $kbsec;
438}
439
440sub dcc_destroyed {
441        (my $dcc) = @_; # Put active dcc in variable
442
443	debugprint(15,"dcc_destroyed was called");
444}
445
446sub check_dcc_speed_and_in_channel {
447#	my $localserver = Irssi::server_find_tag($servertag); # Get serverobject
448	my $minimumspeed = Irssi::settings_get_int('findbot_minspeed');
449	my $channelcheck = Irssi::settings_get_bool('findbot_mustbeinchannel');
450	foreach my $dccconnection (Irssi::Irc::dccs()) {
451		if ( $dccconnection->{type} eq "SEND" &&  defined($activesends{$dccconnection->{nick}}) && ($dccconnection->{transfd} - $dccconnection->{skipped}) > 50000) { # Check if its a findbot send.
452			my $bytetransferred = $dccconnection->{transfd} - $dccconnection->{skipped};
453			my $timedownloaded = time() - $dccconnection->{starttime};
454			if ( $timedownloaded == 0 ) { $timedownloaded++; } # Fix for Illegal division by zero
455			my $currentcps = sprintf("%02d",($bytetransferred / $timedownloaded)); # Get current CPS
456			if ( $currentcps < $minimumspeed && $minimumspeed > 0 ) {	# Check if below minimumspeed
457				my $localserver = Irssi::server_find_tag($dccconnection->{servertag});
458				$localserver->command("/QUOTE NOTICE $dccconnection->{nick} :Minimum CPS is $minimumspeed and you only have $currentcps. Closing your connection");
459				$localserver->command("/DCC CLOSE SEND $dccconnection->{nick}");
460				debugprint(10,"[ADMIN] $dccconnection->{nick} ($currentcps) is below minimumspeed($minimumspeed). Closing...");
461			} elsif ( $channelcheck ) {
462				if ( ! user_is_in_active_channel($dccconnection->{nick},$dccconnection->{servertag}) ) {
463					debugprint(10,"[ADMIN] $dccconnection->{nick} has LEFT monitored channels, closing SEND");
464					my $localserver = Irssi::server_find_tag($dccconnection->{servertag});
465					$localserver->command("/DCC CLOSE SEND $dccconnection->{nick}");
466					# Just close without warning, why bother to tell him if he's left.
467				}
468			}
469		}
470	}
471}
472
473sub nickname_changed {
474	my ($chan, $newnick, $oldnick) = @_;
475
476	foreach my $queuepos (keys(%nickqueue)) {	# Go through all nicks in my queuelist to see if we're affected
477		if ( $nickqueue{$queuepos} eq $oldnick ) {	# Check the nick
478			$nickqueue{$queuepos} = $newnick->{nick};	# Insert the new nick in that position
479			debugprint(10,"[ADMIN] Nickchange $nickqueue{$queuepos} -> $newnick->{nick}");
480		}
481	}
482	if ( defined($activesends{$oldnick}) ) {		# He has an active send
483		$activesends{$newnick->{nick}} = $activesends{$oldnick}; # Make a new entry so he can't evade the dcc speed check
484		delete $activesends{$oldnick};
485	}
486}
487
488sub user_got_kicked {
489	my ($kchannel,$knick,$kkicker,$kaddress,$kreason) = @_;
490	my $mustbeinchannel = Irssi::settings_get_bool('findbot_mustbeinchannel');
491
492	if ( $mustbeinchannel ) {				# Are we to punish this kicked user?
493		foreach my $queuepos (keys(%nickqueue)) {	# Go through all nicks in my queuelist to see if we're affected
494			if ( $nickqueue{$queuepos} eq $knick ) {	# Check the nick if the kicked user has a queue.
495				debugprint(10,"[ADMIN] $knick was KICKED. Removing queueposition $queuepos $filequeue{$queuepos}");
496				remove_queueitem($queuepos);	# Removes the users queue
497			}
498		}
499	}
500}
501
502sub print_banner {
503	my $timenow = time();
504	my $timecalc = Irssi::settings_get_str('findbot_bannertime') + $lastbannerprint;
505#	debugprint(10,"print_banner function... now: $timenow last: $lastbannerprint timecalc: $timecalc");
506	if ( $timenow > $timecalc ) {
507		$lastbannerprint = time();		# Reset timer
508		my $find_channels = Irssi::settings_get_str('findbot_channels'); # What channels to monitor
509		my @checkchannels = split (/ /, $find_channels); # Split into an array
510		if ( Irssi::settings_get_bool('findbot_showbanner') ) { # Check if I will print the banner
511			debugprint(10,"[ADMIN] Sending banner to monitored channels");
512			my $showvoiceprio = "OFF";
513			if (Irssi::settings_get_bool('findbot_voicegetpriority') ) {
514				$showvoiceprio = "ON";
515			}
516			foreach my $localserver ( Irssi::servers() ) {
517				my $bannerad = "For my list of $#bigarray files type: \@" . $localserver->{nick} . ", Sends: $currentsends/" . Irssi::settings_get_int('findbot_maxsends') . " , Queue: $lastqueuenumber/" . Irssi::settings_get_int('findbot_maxqueue') . ", Voicepriority: $showvoiceprio, For help: \@" . $localserver->{nick} . "-help";
518				foreach my $singlechan ( @checkchannels ) {	# Loop through all monitored channels
519					my $channel = $localserver->channel_find($singlechan);	# Get the channelobject
520					if ( defined($channel) ) { # Am I in the specific channel, if so its defined
521						$channel->command("/MSG $singlechan $bannerad" . " Using: Irssi " . $IRSSI{name} . " v$VERSION"); # Print banner
522					} # End if
523				} # End foreach channel
524			} # End foreach server
525		} # End if
526	} # End check if I'll print the banner
527}
528
529sub admin_showqueue {
530	debugprint(10,"[ADMIN] Show queue");
531	debugprint(10,"[ADMIN] Current sends are: $currentsends");
532	for ( my $i = 1; $i <= $lastqueuenumber; $i++ ) { # Loop through the queue
533		debugprint(10,"[ADMIN] ($i) $nickqueue{$i}:$filequeue{$i}:$servertagqueue{$i}[0]:Prio $servertagqueue{$i}[1]");
534#		if ( $servertagqueue{$i}[1] > 0 ) {	# Is this a VIP entry?
535#			debugprint(10,"[ADMIN] ($i) $nickqueue{$i}:$filequeue{$i}:$servertagqueue{$i}[0]:VIP queued($servertagqueue{$i}[1])");
536#		} else {
537#			debugprint(10,"[ADMIN] ($i) $nickqueue{$i}:$filequeue{$i}:$servertagqueue{$i}[0]:Normal queued");
538#		}
539	}
540	debugprint(10,"[ADMIN] End of list");
541}
542
543sub admin_reset {
544	my $howmany = shift;
545	if ( $howmany =~ /\d+/ ) {
546		$currentsends = $howmany;	# Reset current sends
547		debugprint(10,"[ADMIN] Current sends are now set to $currentsends");
548	} else {
549		debugprint(10,"[ADMIN] Specify how many sends there are now");
550	}
551}
552
553#sub start_findbot {
554#	my($data,$localserver,$witem) = @_;
555
556#	if ( $localserver != 0 ) {
557#		$servertag = $localserver->{tag};		# Remeber on which server the findbot is on
558#		$globalstart = 1;
559#		debugprint(10,"Findserver is started");
560#	} else {
561#		debugprint(10,"Please start the server in a window where I can get hold of a servertag");
562#3	}
563#}
564
565sub admin_removequeue {
566	my $queueposition = shift;
567	if ( $queueposition =~ /\d+/ ) {
568		remove_queueitem($queueposition);
569		debugprint(10,"[ADMIN] Removed position $queueposition");
570	} else {
571		debugprint(10,"[ADMIN] Specify which queueitem should be removed");
572	}
573}
574
575sub admin_activesends {
576		debugprint(10,"[ADMIN] Listing active dccsends");
577	foreach my $send (keys(%activesends)) {
578		debugprint(10,"[ADMIN] $send ($activesends{$send})");
579	}
580		debugprint(10,"[ADMIN] End of list");
581}
582
583sub admin_reload {
584	if ( -r Irssi::settings_get_str('findbot_summaryfile') ) {
585	        open (FINDFILE, "<", Irssi::settings_get_str('findbot_summaryfile')); # Open the file
586	        @bigarray = <FINDFILE>;                         # Load it whole into memory :)
587	        close (FINDFILE);
588		debugprint(10,"[ADMIN] Summary file has been reloaded into memory.");
589	} else {
590	        debugprint(10,"[ADMIN] The Summaryfile cannot be read. Please check if the path is correct and the file is accually there.");
591	}
592}
593
594sub send_ctcp_slots {
595# Not implemented yet
596}
597
598sub sanitize_input {
599	my $tainted_input = shift;
600	$tainted_input =~ s/[\^\\\[\]\$\(\)\?\+\/\|\'\}\{]+/\./g; # Translate ^\[]$()?+ to .
601	return $tainted_input;		# Return regularexpression sanitized input
602}
603
604sub find_public {
605	my ($server, $msg, $nick, $address, $targetchan) = @_;		# Save all input to variables
606	my $find_channels = Irssi::settings_get_str('findbot_channels');# What channels to monitor
607	my $find_file = Irssi::settings_get_str('findbot_summaryfile');	# Filename which holds all the files
608	my $mp3list = Irssi::settings_get_str('findbot_sendlist');	# The nice list which is sent to users
609	my $max_results = Irssi::settings_get_int('findbot_maxresults');# Get max results retured to client
610	my $userqueuelimit = Irssi::settings_get_int('findbot_maxuserqueue'); # Get userqueue limit
611	my $serverqueuelimit = Irssi::settings_get_int('findbot_maxqueue'); # Get server maxqueue
612	my @checkchannels = split (/ /, $find_channels);		# Split into an array
613
614	my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); # Get current time
615
616	my $validchan = 0;
617	foreach my $singlechan ( @checkchannels ) {
618		if ( $singlechan eq $targetchan ) {
619			$validchan = 1;
620		}
621	}
622	# allows requesting and searching files in private messages because $targetchan has the own nickname in it when it is a private message, if not it's the channel where it was said
623	if ( $targetchan == "$server->{nick}" && user_is_in_active_channel($nick) ) {
624		$validchan = 1;
625	}
626
627	if ( $validchan && Irssi::settings_get_bool('findbot_enabled') && timeslotenabled($wday,$hour,$min) ) {	# Did the user say something in one of our channels?
628		my $mynick = $server->{nick};
629		if ( $msg =~ /^\ *\@find\ +.+/i ) { 			# Was it a @find command?
630			$msg =~ s/^\ *\@find\ (.*)/$1/i;		# Remove @find space spaces infront of it
631			$msg =~ tr/*/\ /;				# Translate * to spaces
632			$msg =~ s/[\ \+]+/\.\*/g;			# Translate ALL spaces to .*
633			$msg = sanitize_input($msg);
634			debugprint(10,"$nick is searching for $msg");
635			my @matched;
636#			if ( length($msg) > 2  && $msg =~ m/[a-z]+/i) { # MUST be over 2 chars and contain atleast 1 or more normal characters
637				@matched = grep (/$msg/i,@bigarray);		# Search for the matches
638#			} else {
639#				debugprint(10,"[ADMIN] $nick tried to search with too wide searchpattern ($msg)");
640#				return;
641#			}
642			my $matchcount = 0;				# Reset a counter
643			my $found_results = $#matched;			# Return how many hits
644			$found_results++;				# If nomatch then it is -1
645			if ( $found_results > 0 ) {	# Print number of results to the user
646				debugprint(10,"Found $found_results matches");
647				$server->command("/QUOTE PRIVMSG " . $nick . " :Found $found_results matching files. Using: $IRSSI{name} v$VERSION for Irssi");
648			}
649			foreach my $match (@matched) {			# Loop through each file match
650				$match = strippath($match);		# Remove the path and keep filename and mp3info
651				$match =~ s/:/\ \ \ :\ \ /;		# Replace the ":" with "   :  "
652				if ( $matchcount < $max_results ) { 	# Is the matchlimit reached and is it a mp3 file?
653					$matchcount++;			# Increase by one
654					$server->command("/QUOTE PRIVMSG " . $nick . " :!$mynick $match");
655				} else {				# Limit reached!
656					$server->command("/QUOTE PRIVMSG " . $nick . " :Resultlimit by " . $max_results . " reached. Download my list for more, by typing \@$server->{nick}");
657					close (FINDFILE);
658					return;
659				}
660			}
661#			if ( $matchcount == 0 ) {
662#				$server->command("/QUOTE NOTICE " . $nick . " :No match found.");
663#			}
664		} elsif ( $msg =~ /^\ *!$server->{nick}.*/i ) {		# Send file trigger
665			my $localsrvtag = $server->{tag};		# Get current servertag
666			debugprint(20,"$nick tries to queue $msg");	# Just debugoutput
667			$msg =~ s/\ *!$server->{nick}\ *(.*)/$1/;	# Remove the trigger
668			$msg =~ tr/\(\)/\.\./;				# Translate all () to . (any char)
669			$msg = sanitize_input($msg);
670			my @matched = grep (/$msg/i,@bigarray);		# Get the real path from the file
671			if ( $matched[0] eq "" ) {
672				$server->command("/QUOTE NOTICE " . $nick . " :That file does not exist");
673				return;
674			}
675			my $realfile = $matched[0]; 			# Append the real path to the relative path
676			$realfile =~ s/(.*)\ +:.*/$1/;			# Remove : and beyoned
677
678			my $scriptrequest = time() - $scriptdetect{$nick};
679			if ( $scriptrequest <= $scriptdetecttime && $showscriptdetect ) {
680				debugprint(10,"[ADMIN] Requestscript detected on $nick");
681				# return;	#
682			}
683			chomp ($realfile);
684			if ( check_user_queued_items($nick,$localsrvtag) < $userqueuelimit ) { # Is it below allowed user queue limit
685				if ( already_queued_file($nick,$realfile,$localsrvtag) ) {
686					$server->command("/QUOTE PRIVMSG " . $nick . " :You have already queued that file!");
687				} else {
688					my $priority = 1;			# Default prio
689					if ( $lastqueuenumber < $serverqueuelimit ) {
690						foreach my $vchannel ($server->channels()) {	# Loop through all joined channels
691							if ( $vchannel->{name} eq $targetchan ) {	# Did he say it in a monitored channel
692								my $nickrec = $vchannel->nick_find($nick);
693								if ( $nickrec->{voice} ) {
694									$priority = 10;	# A voiced user get 10 prioritypoints
695								} # Voiced user?
696								if ( $nickrec->{op} ) {
697									$priority = 20; # An op get 20 prioritypoints
698								}
699								last;		# Skip rest of loop
700							}
701						}
702						add_file_to_queue($nick,$realfile,$localsrvtag,$priority);	# Add file to queue
703						if ( Irssi::settings_get_bool('findbot_voicegetpriority') && $priority > 1 ) {
704							$server->command("/QUOTE PRIVMSG " . $nick . " :Added file to VIP queueposition $globalvippos.");
705							debugprint(10,"[ADMIN] $nick VIP queued: $realfile");
706						} else {
707							$server->command("/QUOTE PRIVMSG " . $nick . " :Added file to queueposition $lastqueuenumber.");
708							debugprint(10,"[ADMIN] $nick queued: $realfile");
709						}
710					} else {
711						$server->command("/QUOTE PRIVMSG " . $nick . " :The serverqueue is full. Please try again in a few minutes.");
712						debugprint(10,"[ADMIN] Queue is FULL.");
713					}
714				}
715			} else {						# Tell the user the user queue limit is reached
716				$server->command("/QUOTE PRIVMSG " . $nick . " :You have reached the " . $userqueuelimit . " files queue limit.");
717				debugprint(10,"[ADMIN] $nick has reached his queuelimit");
718			}
719		} elsif ( ($msg =~ /^\ *\@$server->{nick}-stats.*/i) || ($msg =~ /^\ *\@$server->{nick}-que.*/i) ) {
720			debugprint(10,"[ADMIN] $nick checked queuepositions");
721			$server->command("/QUOTE PRIVMSG " . $nick . " :Sending you, your queuepositions");
722			for ( my $i = 1; $i <= $lastqueuenumber; $i++ ) { # Loop through the queue
723				if ( $nickqueue{$i} eq $nick ) {
724					my $nicefile = nicefilename($filequeue{$i});
725					$server->command("/QUOTE PRIVMSG " . $nick . " :Pos $i, $nicefile");
726				}
727			}
728		} elsif ( $msg =~ /^\ *\@$server->{nick}-remove.*/i ) {
729			if ( $msg =~ /\ *\@$server->{nick}-remove\ *([\d]+)/ ) { # We have a number
730				my $qitem = $1;
731				debugprint(10,"[ADMIN] $nick is trying to remove queueposition $qitem");
732				if ( $nickqueue{$qitem} eq $nick ) {	# Check if the item is owned by the user
733					remove_queueitem($qitem);	# Remove the requested queueitem
734					$server->command("/QUOTE NOTICE " . $nick . " :Item $qitem has");
735				} else {	# Unauthorized removal
736					debugprint(10,"[ADMIN] $nick tried to remove other peoples files from queue");
737					$server->command("/QUOTE NOTICE " . $nick . " :You can't remove other peoples queueitems");
738				}
739			} else {			# We dont have a number, ie remove the whole user queue
740				debugprint(10,"[ADMIN] $nick has removed all own queueitems");
741				for ( my $i = 1; $i <= $lastqueuenumber; $i++ ) { # Loop through the queue
742					if ( $nickqueue{$i} eq $nick ) {
743						remove_queueitem($i);
744					}
745				}
746				$server->command("/QUOTE NOTICE " . $nick . " :Your whole queue have been deleted");
747			}
748		} elsif ( $msg =~ /^\ *\@$server->{nick}$/i ) {
749			if ( -r $mp3list ) {				# Check if the file is still there
750				debugprint(10,"[ADMIN] $nick requested my list: $mp3list");
751				$server->command("/QUOTE NOTICE " . $nick . " :Sending you my full list...");
752				$server->command("/DCC SEND $nick $mp3list" );
753			} else {
754				debugprint(5,"[WARNING] the $mp3list doesn't exist!");
755				$server->command("/QUOTE NOTICE " . $nick . " :Something wicked happened. My list has disappeared and i have notified the bot owner.");
756			}
757		} elsif ( ($msg =~ /^\ *\@$server->{nick}\ *help\ *$/i) || ($msg =~ /^\ *\@$server->{nick}-help\ *$/i) ) {
758			debugprint(10,"[ADMIN] $nick requested HELP");
759			$server->command("/QUOTE PRIVMSG " . $nick . " :Public channel commands:");
760			$server->command("/QUOTE PRIVMSG " . $nick . " :\@find [searchpattern] : Searches my database for that file");
761			$server->command("/QUOTE PRIVMSG " . $nick . " :!$server->{nick} [file] : Queues that file and it will be sent to you when its your turn");
762			$server->command("/QUOTE PRIVMSG " . $nick . " :\@$server->{nick}-stats : Shows you your queuepositions");
763			$server->command("/QUOTE PRIVMSG " . $nick . " :\@$server->{nick}-que : Shows you your queuepositions");
764			$server->command("/QUOTE PRIVMSG " . $nick . " :\@$server->{nick}-remove : Clears all your queued files");
765			$server->command("/QUOTE PRIVMSG " . $nick . " :\@$server->{nick}-remove 2 : Clear your queueposition 2");
766			$server->command("/QUOTE PRIVMSG " . $nick . " :$IRSSI{name} v$VERSION $IRSSI{url}");
767		} else {
768			return; # Just ordinary chatter
769		}
770	}
771	return;	# Just in case
772}
773
774sub check_vital_configuration {
775	my $configerror = 0;
776	if ( Irssi::settings_get_str('findbot_channels') eq "" ) {
777		$configerror = 1;
778		Irssi::print("The setting findbot_channels is empty.");
779	} elsif (  Irssi::settings_get_str('findbot_summaryfile') eq "" ) {
780		$configerror = 1;
781                Irssi::print("The setting findbot_summaryfile is empty.");
782	} elsif (  Irssi::settings_get_str('findbot_sendlist') eq "" ) {
783		$configerror = 1;
784                Irssi::print("The setting findbot_sendlist is empty.");
785	} elsif (  Irssi::settings_get_int('findbot_maxresults') == 0 ) {
786                $configerror = 1;
787                Irssi::print("The setting findbot_maxresults is empty.");
788        } elsif (  Irssi::settings_get_int('findbot_maxqueue') == 0 ) {
789                $configerror = 1;
790                Irssi::print("The setting findbot_maxqueue is empty.");
791        } elsif (  Irssi::settings_get_int('findbot_maxsends') == 0 ) {
792                $configerror = 1;
793                Irssi::print("The setting findbot_maxsends is empty.");
794        } elsif (  Irssi::settings_get_int('findbot_maxuserqueue') == 0 ) {
795                $configerror = 1;
796                Irssi::print("The setting findbot_maxuserqueue is empty.");
797        } elsif (  Irssi::settings_get_int('findbot_maxusersends') == 0 ) {
798                $configerror = 1;
799                Irssi::print("The setting findbot_maxusersends is empty.");
800        } elsif (  Irssi::settings_get_int('findbot_bannertime') == 0 ) {
801                $configerror = 1;
802                Irssi::print("The setting findbot_bannertime is empty.");
803        }
804	if ($configerror) {
805		Irssi::print("Please correct the settings first. The server will be disabled");
806		Irssi::print("You have to reload the script when the settings are correct");
807		Irssi::timeout_remove($timeout_tag);
808		Irssi::timeout_remove($banner_timeout);
809	}
810}
811
812########
813# Main #
814########
815
816Irssi::settings_add_str("misc", "findbot_channels", "");	# Add a variable inside of irssi
817Irssi::settings_add_str("misc", "findbot_summaryfile", "");	# Add a variable inside of irssi
818Irssi::settings_add_int("misc", "findbot_maxresults", "");	# Add a variable inside of irssi
819Irssi::settings_add_str("misc", "findbot_sendlist", "");	# Add a variable inside of irssi
820Irssi::settings_add_int("misc", "findbot_maxqueue", "");	# Add a variable inside of irssi
821Irssi::settings_add_int("misc", "findbot_maxsends", "");	# Add a variable inside of irssi
822Irssi::settings_add_int("misc", "findbot_maxuserqueue", "");	# Add a variable inside of irssi
823Irssi::settings_add_int("misc", "findbot_maxusersends", "");	# Add a variable inside of irssi
824Irssi::settings_add_bool("misc", "findbot_showbanner", "");	# Add a variable inside of irssi
825Irssi::settings_add_int("misc", "findbot_bannertime", "");	# Add a variable inside of irssi
826Irssi::settings_add_bool("misc", "findbot_enabled", "");	# Add a variable inside of irssi
827Irssi::settings_add_bool("misc", "findbot_voicegetpriority", "");	# Add a variable inside of irssi
828Irssi::settings_add_int("misc", "findbot_minspeed", "");	# Add a variable inside of irssi
829Irssi::settings_add_int("misc", "findbot_debuglevel", 10);	# Add a variable inside of irssi
830Irssi::settings_add_bool("misc", "findbot_mustbeinchannel", "");
831Irssi::settings_add_str("misc", "findbot_timeslots", "");	# Add a variable inside of irssi
832Irssi::signal_add_last('message public', 'find_public');	# Hook up a function to public chatter
833Irssi::signal_add_last('message private', 'find_public');	# Hook up a function to public chatter
834Irssi::signal_add_last('dcc created', 'dcc_created');		# Hook when a dcc is created
835Irssi::signal_add_last('dcc closed', 'dcc_closed');		# Hook when a dcc is closed
836Irssi::signal_add_last('dcc destroyed', 'dcc_destroyed');
837Irssi::signal_add('nicklist changed', 'nickname_changed');
838Irssi::signal_add('message kick', 'user_got_kicked');
839Irssi::command_bind('findbotqueue', 'admin_showqueue');
840Irssi::command_bind('findbotremove', 'admin_removequeue');
841Irssi::command_bind('findbotreset', 'admin_reset');
842Irssi::command_bind('findbotreload', 'admin_reload');
843Irssi::command_bind('findbotactivesends', 'admin_activesends');
844
845check_vital_configuration();	# Run a subroutine to check all variables before starting
846if ( -r Irssi::settings_get_str('findbot_summaryfile') ) {
847	open (FINDFILE, "<", Irssi::settings_get_str('findbot_summaryfile'));	# Open the file
848	@bigarray = <FINDFILE>; 			# Load it whole into memory :)
849	close (FINDFILE);
850} else {
851	debugprint(10,"The Summaryfile cannot be read. Please check if the path is correct and the file is accually there.");
852}
853# my $slots_timeout = Irssi::timeout_add(600000, "send_ctcp_slots", ""); # Not implemented yet
854$timeout_tag = Irssi::timeout_add(5000, "process_queue", "");	# Add a timeout value the process the queue
855#my $bannertime = Irssi::settings_get_int('findbot_bannertime');
856#$banner_timeout = Irssi::timeout_add($bannertime * 1000, "print_banner", ""); # Set timeout for banner
857Irssi::print("Findbot script v$VERSION by $IRSSI{'authors'} loaded!"); # Show version and stuff when it has been loaded
858
859if ( Irssi::settings_get_bool('findbot_enabled') ) {
860	Irssi::print("Findserver is Online");
861} else {
862	Irssi::print("Findserver is Offline");
863}
864debugprint (5,"[ADMIN] Findbot fileserver has been loaded!");
865
866
867#############################
868# INSTALLATION INSTRUCTIONS
869#############################
870# - Making of the "findbot_summaryfile" and "findbot_sendlist"
871# 	Run the perlscript below to create the summaryfile and sendlist
872#
873# - Install it in Irssi
874# 	Put the script in your Irssi scripts directory (~.irssi/scripts)
875# 	Start Irssi and load it. (/run findbot.pl)
876# 	Now start setting all vital variables by using the command /set
877#	set the "findbot_summaryfile" and "findbot_sendlist" to the files you just have created with
878#	the perlscript below.
879#	Dont forget to set all the other variables
880
881
882####### Here is the script #########
883
884# #!/usr/bin/perl
885#use open ":encoding(UTF-8)";
886# if not supplied on cmd line this is the values
887#@PATH = ("/mnt/folder1","/mnt/folder2"); # if only one folder should be used let it be @PATH = ("/mnt/folder1");
888#@INPUT = "";
889#$NICK    = "nickname";
890#($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
891#
892#$year    = sprintf("%04d",$year+1900);
893#$mon     = sprintf("%02d",$mon + 1);
894#$mday    = sprintf("%02d",$mday);
895#$DATE    = "$year-$mon-$mday";
896#$LIST    = $NICK . "_books_list.txt";
897#$CMD     = $NICK . "_books_cmd.txt";
898#$CMD_7z  = $NICK . "_books_cmd";
899#$padding = 50; # How many pad-characters should it be
900#$use_file = 0; # each file is analysed by the program file if this is set to 0, this takes ages when with lots of files
901#$use_compressed_cmdfile = 1; # if 1 then use 7z for compressing the command filelist that is being sent to the users
902#
903#if( "x" ne  "x$ARGV[0]" ){ $NICK    = $ARGV[0]; }
904#if( "x" ne  "x$ARGV[1]" ){ $PATH    = $ARGV[1]; }
905#if( "x" ne  "x$ARGV[2]" ){ $LIST    = $ARGV[2]; }
906#if( "x" ne  "x$ARGV[3]" ){ $CMD     = $ARGV[3]; }
907#
908#print "Using nick: $NICK\n";
909#foreach (@PATH){
910#	print "Finding under supplied path $_\n";
911#	push(@INPUT,`find "$_" -follow -type f`);
912#}
913#print "Find done\n";
914#print "Summaryfile: $LIST\n";
915#print "Sendlist:    $CMD\n";
916#
917#print "Generating lists done/total files\n";
918#open(LIST,">$LIST");
919#open(CMD,">$CMD");
920#
921#print LIST "### List generated: $DATE I have a total of $#INPUT files ###\n";
922#print CMD  "### List generated: $DATE I have a total of $#INPUT files ###\r\n";
923#print CMD  "### This list was created by Findbot for Irssi\r\n";
924#print CMD  "### http://irssi.org/scripts\r\n";
925#
926#$CHECKDIR="";
927#$CNT=0;
928#
929## arrays start 0 and If I have 10 mp3 without +1 it would stat you have 9 ...
930#$TOTAL = $#INPUT + 1;
931#
932#sub padline {
933#       $filename = shift;
934#       $filelength = length($filename);
935#       $paddchar = "=";
936#       if ( $filelength <= $padding ) {
937#               for ( $counter = $filelength; $counter < $padding; $counter++ ) {
938#                       $paddchar .= "=";
939#               }
940#       }
941#       return $paddchar;
942#}
943#
944#foreach( @INPUT ){
945#        $CNT++;
946#        print "\r$CNT/" . $TOTAL;
947#        chomp $_;
948#
949#       $FILE=$_;
950#       $DIR=$_;
951#       $FILEwPATH=$_;
952#
953#       $FILE =~ s/.*\/(.*)/$1/g; # only the file
954#       $DIR =~ s/(.*)\/.*/$1/g; # only the dir
955#
956#       if ( $use_file ) {
957#               $STAT_OF_FILE = `file -b "$FILEwPATH"`; # the info about the file
958#               $STAT_OF_FILE =~ s#/##gio; # remove /
959#               chomp $STAT_OF_FILE;
960#               print LIST "$FILEwPATH : $STAT_OF_FILE\n"; # output to the LIST-file
961#       } else {
962#                print LIST "$FILEwPATH\n"; # output to the LIST-file
963#       }
964#       if( "$DIR" ne "$CHECKDIR" ){
965#               # output to the CMD-file
966#               print CMD "\r\n=================================================\r\n";
967#               $CHECKDIR = $DIR; print CMD "Files in $DIR\r\n";
968#               print CMD "=================================================\r\n\r\n";
969#       }
970#       if ( $use_file ) {
971#               print CMD "!$NICK $FILE " . padline($FILE) . " $STAT_OF_FILE\r\n"; # output to the CMD-file
972#       } else {
973#               print CMD "!$NICK $FILE\r\n"; # output to the CMD-file
974#       }
975#}
976#print CMD "EOF\r\n";
977#print LIST "EOF\r\n";
978#close LIST;
979#close CMD;
980#if ( $use_compressed_cmdfile ) {
981#        print "\ncompressing filelist...\n";
982#        system "7z a -t7z -mx9 $CMD_7z.7z $CMD";
983#}
984#print "\nList generation done\n";
985