Sei sulla pagina 1di 3

# Grep

# Copyright (C) perpleXa 2004-2006


# http://perplexa.ugug.co.uk / #perpleXa on QuakeNet
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
# Using pcre if play.mod is loaded, regexp otherwise.
# play.mod is available at http://perplexa.ugug.co.uk
#
# Usage: grep [-ivl num] pattern resource
# i - ignore upper/lower case distinctions during comparisons
# v - invert the sense of matching, to select non-matching lines
# l num - list max <num> amounts of lines (20 by default)
# pattern - a perl compatible regular expression (PCRE)
# ie: #channel2|user9|Cleanup or [a-z]{7}\s[0-9]{2}
# resource - an absolute or relative path
# ie: /dev/null/*

# fsck is available at http://perplexa.ugug.co.uk


package require fsck 1.10;

namespace eval grep {


variable version 2.0;
variable busy;
variable use_pcre [expr {(![string compare [info commands "pcre"]
"pcre"])?"pcre":"regexp"}];
bind msg n|- "grep" [namespace current]::msg:grep;
bind dcc n|- "grep" [namespace current]::dcc:grep;
namespace export *;
}

proc grep::msg:grep {nick host hand argv} {


grep $nick $argv "msg";
}

proc grep::dcc:grep {hand id argv} {


grep $id $argv "dcc";
}

proc grep::irc_send {nick type str} {


switch -exact -- $type {
"dcc" { putidx $nick $str; return 1; }
"msg" { puthelp "PRIVMSG $nick :$str"; return 1; }
default { Error "grep" ERROR "Unknown message type: $type"; }
}
return 0;
}

proc grep::grep {nick argv type} {


variable use_pcre;
set offset 0;
set invert 0;
set flags "--";
set option [getword $argv 0];

if {[string match "-*" $option]} {


set option [string range $option 1 end];
set offset 1;
foreach char [split $option ""] {
if {$char == "i"} {
set flags [expr {($use_pcre=="pcre") ? [list "-nocase"] : [list "-nocase"
"--"]}];
continue;
}
if {$char == "v"} {
set invert 1;
continue;
}
if {$char == "l"} {
set limit [getword $argv 1];
set offset 2;
continue;
}
irc_send $nick $type "Invalid or disallowed flag specified.";
return 0;
}
} else {
set option "";
}
if {![info exists limit] || ![string is digit -strict $limit]} {
set limit 20;
}
set pattern [getword $argv $offset];
set resource [getword $argv [expr $offset+1]-end];
if {$resource == ""} {
irc_send $nick $type "grep: Not enough parameters.";
return 0;
}
variable busy;
if {[info exists busy] && $busy} {
irc_send $nick $type "Sorry, grep is currently busy - try later.";
return 0;
}
set count 0;
if {[catch {$use_pcre -- $pattern ""} error]} {
irc_send $nick $type "$error";
return 0;
}
set busy 1;
irc_send $nick $type "Started grep for $pattern...";
set files [glob -nocomplain -- [string map [list "\\" "/"] $resource]];
set filenum 0; set filematch 0;
set lastping [clock seconds];
foreach file $files {
# Seems to be a cygwin bug, fixed just for our windows users... :P
if {![string first $::env(HOME) $file]} {
set FILE ~[string range $file [string length $::env(HOME)] end];
} else {
set FILE $file;
}
if {[file isdirectory $FILE]} continue;
if {[catch {open $FILE "r"} fp]} {
irc_send $nick $type "Unable to open file: $file";
continue;
}
incr filenum; set lnum 0; set filematched 0;
while {![eof $fp] && (($count<$limit) || !$limit)} {
set cuneti [clock seconds];
if {$lastping+60<$cuneti} {
putquick "PING :$cuneti";
set lastping $cuneti;
}
incr lnum;
set line [gets $fp];
set res [eval $use_pcre $flags [list $pattern] [list $line]];
if {($res && !$invert) || (!$res && $invert)} {
irc_send $nick $type "\[$file:$lnum\] $line";
incr count;
if {!$filematched} {
set filematched 1;
incr filematch;
}
}
}
close $fp;
if {($count == $limit) && $limit} {
irc_send $nick $type "--- More than $limit matches found, truncating list.";
break;
}
}
irc_send $nick $type "--- End of list: $count match(es) in $filematch/$filenum
files.";
set busy 0;
}

putlog "Script loaded: Grep v$grep::version by perpleXa";

Potrebbero piacerti anche