Date: Tue, 25 Oct 2005 10:39:00 -0700 From: Jerry.Nairn@microchip.com To: charles.buysschaert@advalvas.be, freebsd-cvsweb@freebsd.org Subject: Re: Search function on CVSWEB. Message-ID: <OF9CD50ACC.B83B10D1-ON072570A5.00592A9C-072570A5.0060F53F@microchip.com>
next in thread | raw e-mail | index | archive | help
[-- Attachment #1 --]
I wrote this script to search for files with names matching a pattern, and
incorporated links to the script into cvsweb. I've been meaning to do
something similar to search file text and log messages, but those are not
so simple.
Jerry Nairn
Microchip Technology
Language Tools
480-792-7197
Hello all,
We would like to be able to use a search function on our cvsweb server in
order to find easily files based on files' name or even some log messages.
[-- Attachment #2 --]
#!/usr/bin/perl -T
#
# this is a CGI to search for file names in the cvs repository matching a given pattern
#
use CGI qw(a b br center img p title ul table TR td hr font u h2 h3);
my $query = new CGI;
# get the parameters passed from the form (if any)
for $key ( $query->param() ) {
$input{$key} = $query->param($key);
$qstr .= '&'.$key.'='.$input{$key};
}
my $dir = $input{'d'}; # repository directory
my $searchstr = $input{'s'}; # s = search string: can be a literal or a regular expression
my $matchtype = $input{'m'}; # m = match type: is, starts, ends, or contains: i, s, e, or c
my $caseaware = $input{'c'}; # c = case awarenes: sense case or ignore: on or not set
my $pattype = $input{'p'}; # p = pattern type: literal or reg. exp.: on or not set
my $filetype = $input{'f'}; # f = file type: directory, file, or any: d, f, or a
my $topdir = "/cvs";
if ( ( ! $dir ) && ( $input{'path'} ) ) {
$dir = $input{'path'};
}
$dir =~ s@//@/@g;
$dir =~ s/\.\.*/./g;
# Clean up PATH to avoid tainting problems
$ENV{'PATH'}='/bin:/usr/bin:/usr/sbin';
delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};
my $titlestr = "Language Tools Development";
my $pathstr = $titlestr;
my $logo = '<script language=javascript src="/inc/logo.js"></script><script language=javascript>document.write(logo);</script>';
my $true = ( 1 == 1 );
my $false = ( 0 == 1 );
my $nonefound = $true;
my $JSCRIPT =<<EOJS
function resetForm() {
searchform.reset();
searchform.m[0].checked = true;
searchform.f[2].checked = true;
searchform.c.checked = false;
searchform.p.checked = false;
}
EOJS
;
$matching = "containing";
if ( $matchtype eq "i" ) {
$matching = "matching";
} elsif ( $matchtype eq "s" ) {
$matching = "starting with";
} elsif ( $matchtype eq "e" ) {
$matching = "ending with";
}
sub untaint_me{
my $in = shift;
$in =~ tr/\"\;\'\&\|/./;
$in =~ /(.*)/;
return $1;
}
$dir = untaint_me($dir);
$searchstr = untaint_me($searchstr);
sub matchfile {
my $thefile = shift;
$thefile =~ s/,v$//;
if ( $matchtype eq "i" ) {
# file name is
if ( $pattype eq "on" ) {
if ( $caseaware eq "on" ) {
if ( $searchstr eq $thefile ) {
return $true;
} else {
return $false;
}
} else {
if ( uc($searchstr) eq uc($thefile) ) {
return $true;
} else {
return $false;
}
}
} elsif ( $caseaware eq "on" ) {
if ( $thefile =~ /^${searchstr}$/ ) {
return $true;
} else {
return $false;
}
} else {
if ( $thefile =~ /^${searchstr}$/i ) {
return $true;
} else {
return $false;
}
}
} elsif ( $matchtype eq "s" ) {
# file name starts with
if ( $caseaware eq "on" ) {
if ( $thefile =~ /^${searchstr}.*$/ ) {
return $true;
} else {
return $false;
}
} else {
if ( $thefile =~ /^${searchstr}.*$/i ) {
return $true;
} else {
return $false;
}
}
} elsif ( $matchtype eq "e" ) {
# file name ends with
if ( $caseaware eq "on" ) {
if ( $thefile =~ /^.*${searchstr}$/ ) {
return $true;
} else {
return $false;
}
} else {
if ( $thefile =~ /^.*${searchstr}$/i ) {
return $true;
} else {
return $false;
}
}
} else {
# file name contains
$matching = "containing";
if ( $caseaware eq "on" ) {
if ( $thefile =~ /.*${searchstr}.*/ ) {
return true;
} else {
return 0;
}
} else {
if ( $thefile =~ /.*${searchstr}.*/i ) {
return true;
} else {
return 0;
}
}
}
}
sub isbinary {
my $fn = shift;
$fn = untaint_me($fn);
open CVSHEADER, "-|", "rlog -N -h \"${topdir}/".$fn."\"";
while ( my $line = readline(CVSHEADER) ) {
chomp $line;
if ( $line =~ s/^keyword substitution:\s*(.*)$/$1/ ) {
close CVSHEADER;
return ( "$1" eq "b" );
last;
}
}
close CVSHEADER;
return $false;
}
sub searchdir {
# see if any of the files or directories match the search string
my $thedir = shift;
my $absolutedir = "${topdir}/${thedir}";
$absolutedir =~ s#//#/#g;
my @subdirs;
opendir REPODIR, "${absolutedir}";
while ($file = readdir REPODIR)
{
chomp $file;
my $absolutefile = "${absolutedir}/${file}";
$absolutefile =~ s#//#/#g;
my $relativefile = "${thedir}/${file}";
$relativefile =~ s#//#/#g;
$outputline = "";
if ( ($file ne ".") && ($file ne "..") ) {
if ( -d "${absolutefile}" ) {
# generate a list of subdirectories
push @subdirs, "${relativefile}";
if ( ( $filetype eq "d" ) || ( $filetype eq "a" ) ) {
if ( matchfile($file) ) {
$outputline = "<a href=\"/cgi-bin/cvsweb.cgi/${relativefile}\"><img src=\"/cvsweb/icons/dir.gif\" border=0> ${relativefile}</a>\n"
}
}
} elsif ( ( $filetype eq "f" ) || ( $filetype eq "a" ) ) {
if ( $relativefile =~ s/,v$// ) {
if ( matchfile($file) ) {
if ( isbinary("${relativefile}") ) {
$icon = "binary";
} else {
$icon = "text";
}
$outputline = "<a href=\"/cgi-bin/cvsweb.cgi/${relativefile}\"><img src=\"/cvsweb/icons/${icon}.gif\" border=0> ${relativefile}</a>\n"
}
}
}
}
if ( $outputline ) {
print TR(td({class=>"${class}"},$outputline))."\n";
$nonefound = $false;
}
}
closedir REPODIR;
while ( $thedir = shift @subdirs ) {
searchdir($thedir);
}
}
sub searchform {
print <<EOHTML
<center>
<form id="searchform" name="searchform" method="get">
<table border="1" cellpadding="3">
<tr>
<td align="right">Search module/path: </td>
<td><input type="text" name="d" id="d" size="34"
EOHTML
;
if ( $dir ) {
print " value=\"${dir}\"";
}
print <<EOHTML
/></td></tr>
<tr>
<td align="right">For: </td>
<td><input type="radio" name="f" id="f" value="f"
EOHTML
;
if ( $filetype eq "f" ) {
print " CHECKED ";
}
print ">\ filenames<br />\n";
print "<input type=\"radio\" name=\"f\" id=\"f\" value=\"d\"";
if ( $filetype eq "d" ) {
print " CHECKED ";
}
print ">\ directory names<br />\n";
print "<input type=\"radio\" name=\"f\" id=\"f\" value=\"a\"";
if ( ( ! $filetype ) || ( $filetype eq "a" ) ) {
print " CHECKED ";
}
print <<EOHTML
> anything<br />
</td></tr>
<tr>
<td align="right"><input type="radio" name="m" id="m" value="c"
EOHTML
;
if ( ( ! $matchtype ) || ( $matchtype eq "c" ) ) {
print " CHECKED ";
}
print ">\ containing:<br />\n";
print "<input type=\"radio\" name=\"m\" id=\"m\" value=\"s\"";
if ( $matchtype eq "s" ) {
print " CHECKED ";
}
print ">\ starting with:<br />\n";
print "<input type=\"radio\" name=\"m\" id=\"m\" value=\"e\"";
if ( $matchtype eq "e" ) {
print " CHECKED ";
}
print ">\ ending with:<br />\n";
print "<input type=\"radio\" name=\"m\" id=\"m\" value=\"i\"";
if ( $matchtype eq "i" ) {
print " CHECKED ";
}
print <<EOHTML
> matching:</td>
<td valign="middle"><input type="text" name="s" id="s" size="34"
EOHTML
;
if ( $searchstr ) {
print " value=\"${searchstr}\" ";
}
print <<EOHTML
/>
</td>
</tr>
<tr>
<td colspan="2" align="center">Case sensitive: <input type="checkbox" name="c" id="c"
EOHTML
;
if ( $caseaware eq "on" ) {
print " CHECKED ";
}
print <<EOHTML
/>
Literal: <input type="checkbox" name="p" id="p"
EOHTML
;
if ( $pattype eq "on" ) {
print " CHECKED ";
}
print <<EOHTML
/></td></tr>
<tr><td colspan="2" align="center"><input type="submit" value="Submit" /> <input type="button" value="Reset" onClick="resetForm();" /></td></tr>
</table>
</form>
</center>
EOHTML
;
}
print $query->header(-expires=>"-1d",-type=>"text/html");
print $query->start_html(-title=>'Find File - '.$searchstr,-script=>${JSCRIPT});
print $logo;
print p(h2({align=>"center"},"Find In Cvs"));
searchform;
if ( $searchstr ) {
print center(h3("Searching \"$dir\" for names ${matching} \"${searchstr}\""))."\n";
print "<center><table>\n";
searchdir($dir);
if ( $nonefound ) {
print TR(td(h3("nothing found")));
}
print "</table></center>\n";
}
print $query->end_html;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?OF9CD50ACC.B83B10D1-ON072570A5.00592A9C-072570A5.0060F53F>
