1 package Packages::DoSearchContents;
11 our @ISA = qw( Exporter );
12 our @EXPORT = qw( do_search_contents );
15 use Packages::Search qw( :all );
18 use Packages::Config qw( $DBDIR $SEARCH_URL $SEARCH_CGI $SEARCH_PAGE
19 @SUITES @ARCHIVES $ROOT );
21 sub do_search_contents {
22 my ($params, $opts, $html_header, $menu, $page_content) = @_;
24 if ($params->{errors}{keywords}) {
25 fatal_error( "keyword not valid or missing" );
26 } elsif (length($opts->{keywords}) < 2) {
27 fatal_error( "keyword too short (keywords need to have at least two characters)" );
32 my $keyword = $opts->{keywords};
33 my $searchon = $opts->{searchon};
34 my $exact = $opts->{exact};
36 # for URL construction
37 my $keyword_esc = uri_escape( $keyword );
38 my $suites_param = join ',', @{$params->{values}{suite}{no_replace}};
39 my $sections_param = join ',', @{$params->{values}{section}{no_replace}};
40 my $archs_param = join ',', @{$params->{values}{arch}{no_replace}};
43 my $keyword_enc = encode_entities $keyword || '';
44 my $searchon_enc = encode_entities $searchon;
45 my $suites_enc = encode_entities( join( ', ', @{$params->{values}{suite}{no_replace}} ) );
46 my $sections_enc = encode_entities( join( ', ', @{$params->{values}{section}{no_replace}} ) );
47 my $archs_enc = encode_entities( join( ', ', @{$params->{values}{arch}{no_replace}} ) );
49 my $st0 = new Benchmark;
50 my (@results, @non_results);
52 unless (@Packages::CGI::fatal_errors) {
57 # full filename search is tricky
58 my $ffn = $searchon eq 'filenames';
60 my $suite = 'stable'; #fixme
62 my $reverses = tie my %reverses, 'DB_File', "$DBDIR/contents/reverse_$suite.db",
63 O_RDONLY, 0666, $DB_BTREE
64 or die "Failed opening reverse DB: $!";
67 open FILENAMES, '-|', 'fgrep', '--', "$kw", "$DBDIR/contents/filenames_$suite.txt"
68 or die "Failed opening filename table: $!";
71 last unless &searchfile(\@results, reverse($_)."/", \$nres, $reverses);
78 # exact filename searching follows trivially:
79 $kw = "$kw/" if $exact;
81 print "ERROR: Exact and fullfilenamesearch don't go along" if $ffn and $exact;
83 &searchfile(\@results, $kw, \$nres, $reverses);
89 my $st1 = new Benchmark;
90 my $std = timediff($st1, $st0);
91 debug( "Search took ".timestr($std) );
94 my $suite_wording = $suites_enc eq "all" ? "all suites"
95 : "suite(s) <em>$suites_enc</em>";
96 my $section_wording = $sections_enc eq 'all' ? "all sections"
97 : "section(s) <em>$sections_enc</em>";
98 my $arch_wording = $archs_enc eq 'any' ? "all architectures"
99 : "architecture(s) <em>$archs_enc</em>";
100 my $wording = $opts->{exact} ? "exact filenames" : "filenames that contain";
101 $wording = "paths that end with" if $searchon eq "contents";
102 msg( "You have searched for ${wording} <em>$keyword_enc</em> in $suite_wording, $section_wording, and $arch_wording." );
104 if ($Packages::Search::too_many_hits) {
105 error( "Your search was too wide so we will only display exact matches. At least <em>$Packages::Search::too_many_hits</em> results have been omitted and will not be displayed. Please consider using a longer keyword or more keywords." );
109 if (!@Packages::CGI::fatal_errors && !@results) {
110 $$page_content .= "No results";
113 %$html_header = ( title => 'Package Contents Search Results' ,
115 title_tag => 'Debian Package Contents Search Results',
117 print_search_field => 'packages',
118 search_field_values => {
119 keywords => $keyword_enc,
120 searchon => 'contents',
122 suite => $suites_enc,
123 section => $sections_enc,
124 exact => $opts->{exact},
125 debug => $opts->{debug},
130 $$page_content .= scalar @results . " results displayed:<br>";
132 $$page_content .= "<tt>$_</tt><br>\n";
135 } # sub do_search_contents
139 my ($results, $kw, $nres, $reverses) = @_;
141 my ($key, $value) = ($kw, "");
142 for (my $status = $reverses->seq($key, $value, R_CURSOR);
144 $status = $reverses->seq( $key, $value, R_NEXT)) {
146 # FIXME: what's the most efficient "is prefix of" thingy? We only want to know
147 # whether $kw is or is not a prefix of $key
148 last unless index($key, $kw) == 0;
150 my @hits = split /\0/o, $value;
151 push @$results, reverse($key)." is found in @hits";
152 last if ($$nres)++ > 100;
155 # FIXME: use too_many_hits