Skip site navigation (1)Skip section navigation (2)
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>&nbsp;${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>&nbsp;${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:&nbsp;</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:&nbsp;</td>
			<td><input type="radio" name="f" id="f" value="f"
EOHTML
;
	if ( $filetype eq "f" ) {
		print " CHECKED ";
	}
	print ">\&nbsp;filenames<br />\n";
	print "<input type=\"radio\" name=\"f\" id=\"f\" value=\"d\"";
	if ( $filetype eq "d" ) {
		print " CHECKED ";
	}
	print ">\&nbsp;directory names<br />\n";
	print "<input type=\"radio\" name=\"f\" id=\"f\" value=\"a\"";
	if ( ( ! $filetype ) || ( $filetype eq "a" ) ) {
		print " CHECKED ";
	}
	print <<EOHTML
>&nbsp;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 ">\&nbsp;containing:<br />\n";
	print "<input type=\"radio\" name=\"m\" id=\"m\" value=\"s\"";
	if ( $matchtype eq "s" ) {
		print " CHECKED ";
	}
	print ">\&nbsp;starting with:<br />\n";
	print "<input type=\"radio\" name=\"m\" id=\"m\" value=\"e\"";
	if ( $matchtype eq "e" ) {
		print " CHECKED ";
	}
	print ">\&nbsp;ending with:<br />\n";
	print "<input type=\"radio\" name=\"m\" id=\"m\" value=\"i\"";
	if ( $matchtype eq "i" ) {
		print " CHECKED ";
	}
	print <<EOHTML
>&nbsp;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:&nbsp;<input type="checkbox" name="c" id="c" 
EOHTML
;
	if ( $caseaware eq "on" ) {
		print " CHECKED ";
	}
	print <<EOHTML
 />
			&nbsp;&nbsp;Literal:&nbsp;<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" />&nbsp;&nbsp;<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>