| 1 |
#!/usr/bin/perl -T |
| 2 |
# |
| 3 |
# Copyright (c) 1996-2017 Wolfram Schneider <wosch@FreeBSD.ORG> |
| 4 |
# All rights reserved. |
| 5 |
# |
| 6 |
# Redistribution and use in source and binary forms, with or without |
| 7 |
# modification, are permitted provided that the following conditions |
| 8 |
# are met: |
| 9 |
# 1. Redistributions of source code must retain the above copyright |
| 10 |
# notice, this list of conditions and the following disclaimer. |
| 11 |
# 2. Redistributions in binary form must reproduce the above copyright |
| 12 |
# notice, this list of conditions and the following disclaimer in the |
| 13 |
# documentation and/or other materials provided with the distribution. |
| 14 |
# |
| 15 |
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND |
| 16 |
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| 17 |
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| 18 |
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE |
| 19 |
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
| 20 |
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
| 21 |
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
| 22 |
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
| 23 |
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
| 24 |
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 25 |
# SUCH DAMAGE. |
| 26 |
# |
| 27 |
# $FreeBSD$ |
| 28 |
# |
| 29 |
# ports.cgi - search engine for FreeBSD ports |
| 30 |
# o search for a port by name or description |
| 31 |
|
| 32 |
use POSIX qw(strftime); |
| 33 |
use Time::Local; |
| 34 |
|
| 35 |
require "./cgi-style.pl"; |
| 36 |
$t_style = qq`<style type="text/css"> |
| 37 |
h3 { font-size: 1.2em; border-bottom: thin solid black; } |
| 38 |
</style> |
| 39 |
<link rel="search" type="application/opensearchdescription+xml" href="https://www.freebsd.org/search/opensearch/ports.xml" title="FreeBSD Ports" /> |
| 40 |
`; |
| 41 |
|
| 42 |
sub init_variables { |
| 43 |
$localPrefix = '/usr/ports'; # ports prefix |
| 44 |
|
| 45 |
# Directory of the up-to-date INDEX* |
| 46 |
$portsDatabaseHeadDir = "/usr/local/www/ports"; |
| 47 |
|
| 48 |
# Ports database file to use |
| 49 |
if ( -f "$portsDatabaseHeadDir/INDEX-12" ) { |
| 50 |
$ports_database = 'INDEX-12'; |
| 51 |
} |
| 52 |
elsif ( -f "$portsDatabaseHeadDir/INDEX-11" ) { |
| 53 |
$ports_database = 'INDEX-11'; |
| 54 |
} |
| 55 |
else { |
| 56 |
$ports_database = 'INDEX'; |
| 57 |
} |
| 58 |
|
| 59 |
# URL of ports tree for browsing |
| 60 |
$remotePrefixFtp = 'ports'; |
| 61 |
|
| 62 |
# 'ftp://ftp.FreeBSD.org/pub/FreeBSD/branches/-current/ports'; |
| 63 |
|
| 64 |
# where to get -current packages |
| 65 |
local ($p) = 'ftp://ftp.FreeBSD.org/pub/FreeBSD/ports/i386'; |
| 66 |
local ($palpha) = 'ftp://ftp.FreeBSD.org/pub/FreeBSD/ports/alpha'; |
| 67 |
local ($pamd64) = 'ftp://ftp.FreeBSD.org/pub/FreeBSD/ports/amd64'; |
| 68 |
local ($pia64) = 'ftp://ftp.FreeBSD.org/pub/FreeBSD/ports/ia64'; |
| 69 |
local ($psparc64) = 'ftp://ftp.FreeBSD.org/pub/FreeBSD/ports/sparc64'; |
| 70 |
|
| 71 |
$remotePrefixFtpPackagesDefault = '6-STABLE/i386'; |
| 72 |
|
| 73 |
# This is currently unused |
| 74 |
%remotePrefixFtpPackages = ( |
| 75 |
'7-CURRENT/i386', "$p/packages-7-current/All", |
| 76 |
'6-STABLE/i386', " $p/packages-6-stable/All", |
| 77 |
'5-STABLE/i386', " $p/packages-5-stable/All", |
| 78 |
'4-STABLE/i386', " $p/packages-4-stable/All", |
| 79 |
|
| 80 |
'6.0-RELEASE/i386', "$p/packages-6.0-release/All", |
| 81 |
'5.4-RELEASE/i386', "$p/packages-5.4-release/All", |
| 82 |
'4.11-RELEASE/i386', "$p/packages-4.11-release/All", |
| 83 |
|
| 84 |
'4-STABLE/alpha', "$palpha/packages-4-stable/All", |
| 85 |
|
| 86 |
'5.4-RELEASE/alpha', "$palpha/packages-5.4-release/All", |
| 87 |
'4.11-RELEASE/alpha', "$palpha/packages-4.11-release/All", |
| 88 |
|
| 89 |
'7-CURRENT/amd64', "$pamd64/packages-7-current/All", |
| 90 |
'6-STABLE/amd64', "$pamd64/packages-6-stable/All", |
| 91 |
'5-STABLE/amd64', "$pamd64/packages-5-stable/All", |
| 92 |
|
| 93 |
'6.0-RELEASE/amd64', "$pamd64/packages-6.0-release/All", |
| 94 |
'5.4-RELEASE/amd64', "$pamd64/packages-5.4-release/All", |
| 95 |
|
| 96 |
'7-CURRENT/ia64', "$pia64/packages-7-current/All", |
| 97 |
'6-STABLE/ia64', "$pia64/packages-6-stable/All", |
| 98 |
|
| 99 |
'6.0-RELEASE/ia64', "$pia64/packages-6.0-release/All", |
| 100 |
'5.4-RELEASE/ia64', "$pia64/packages-5.4-release/All", |
| 101 |
|
| 102 |
'7-CURRENT/sparc64', "$psparc64/packages-7-current/All", |
| 103 |
'6-STABLE/sparc64', "$psparc64/packages-6-stable/All", |
| 104 |
'5-STABLE/sparc64', "$psparc64/packages-5-stable/All", |
| 105 |
|
| 106 |
'6.0-RELEASE/sparc64', "$psparc64/packages-6.0-release/All", |
| 107 |
'5.4-RELEASE/sparc64', "$psparc64/packages-5.4-release/All", |
| 108 |
); |
| 109 |
|
| 110 |
$remotePrefixHtml = "$hsty_base/ports"; |
| 111 |
|
| 112 |
# Web interface for the Ports tree |
| 113 |
$remotePrefixRepo = 'https://svnweb.FreeBSD.org/ports/head'; |
| 114 |
|
| 115 |
# Ports documentation |
| 116 |
$portsDesc = "$hsty_base/ports/"; |
| 117 |
|
| 118 |
# location of the tiny BSD daemon |
| 119 |
$daemonGif = |
| 120 |
"<img src='$hsty_base/gifs/littlelogo.gif' alt='Really small BSD Daemon'>"; |
| 121 |
|
| 122 |
# visible E-Mail address, plain text |
| 123 |
$mailto = 'www@FreeBSD.org'; |
| 124 |
|
| 125 |
# Mailinglist for FreeBSD Ports |
| 126 |
$mailtoList = 'ports@FreeBSD.org'; |
| 127 |
|
| 128 |
# use mailto:email?subject |
| 129 |
$mailtoAdvanced = 'yes'; |
| 130 |
|
| 131 |
# the URL if you click at the E-Mail address (see below) |
| 132 |
$mailtoURL = "mailto:$mailto" if !$mailtoURL; |
| 133 |
|
| 134 |
# security |
| 135 |
$ENV{'PATH'} = '/bin:/usr/bin'; |
| 136 |
|
| 137 |
# extension type for packages |
| 138 |
$packageExt = 'tbz'; |
| 139 |
|
| 140 |
local ($packageDB) = '../ports/packages.exists'; |
| 141 |
&packages_exist( $packageDB, *packages ) if -f $packageDB; |
| 142 |
|
| 143 |
} |
| 144 |
|
| 145 |
sub packages_exist { |
| 146 |
local ( $file, *p ) = @_; |
| 147 |
|
| 148 |
open( P, $file ) || do { |
| 149 |
warn "open $file: $!\n"; |
| 150 |
warn "Cannot create packages links\n"; |
| 151 |
return 1; |
| 152 |
}; |
| 153 |
|
| 154 |
while (<p>) { |
| 155 |
chop; |
| 156 |
$p{$_} = 1; |
| 157 |
} |
| 158 |
close P; |
| 159 |
return 0; |
| 160 |
} |
| 161 |
|
| 162 |
# return the date of the last ports database update |
| 163 |
sub last_update { |
| 164 |
local ($file) = "$portsDatabaseHeadDir/$ports_database"; |
| 165 |
local ( $modtime, $modtimestr ); |
| 166 |
|
| 167 |
$modtime = ( stat($file) )[9]; |
| 168 |
if ( defined($modtime) && $modtime > 0 ) { |
| 169 |
$modtimestr = strftime( "%Y-%m-%d %H:%M:%S UTC", gmtime($modtime) ); |
| 170 |
} |
| 171 |
else { |
| 172 |
$modtimestr = "Unknown"; |
| 173 |
} |
| 174 |
|
| 175 |
return $modtimestr; |
| 176 |
} |
| 177 |
|
| 178 |
sub last_update_message { |
| 179 |
return "<p>Last database update: " . &last_update . "</p>\n"; |
| 180 |
} |
| 181 |
|
| 182 |
sub dec { |
| 183 |
local ($_) = @_; |
| 184 |
|
| 185 |
s/\+/ /g; # '+' -> space |
| 186 |
s/%(..)/pack("c",hex($1))/ge; # '%ab' -> char ab |
| 187 |
|
| 188 |
return ($_); |
| 189 |
} |
| 190 |
|
| 191 |
# $indent is a bit of optional data processing I put in for |
| 192 |
# formatting the data nicely when you are emailing it. |
| 193 |
# This is derived from code by Denis Howe <dbh@doc.ic.ac.uk> |
| 194 |
# and Thomas A Fine <fine@cis.ohio-state.edu> |
| 195 |
sub decode_form { |
| 196 |
local ( $form, *data, $indent, $key, $_ ) = @_; |
| 197 |
foreach $_ ( split( /&/, $form ) ) { |
| 198 |
( $key, $_ ) = split( /=/, $_, 2 ); |
| 199 |
$_ =~ s/\+/ /g; # + -> space |
| 200 |
$key =~ s/\+/ /g; # + -> space |
| 201 |
$_ =~ s/%([\da-f]{1,2})/pack(C,hex($1))/eig; # undo % escapes |
| 202 |
$key =~ s/%([\da-f]{1,2})/pack(C,hex($1))/eig; # undo % escapes |
| 203 |
$_ =~ s/[\r\n]+/\n\t/g if defined($indent); # indent data after \n |
| 204 |
$data{$key} = $_; |
| 205 |
} |
| 206 |
} |
| 207 |
|
| 208 |
sub escapeHTML { |
| 209 |
my $toencode = shift; |
| 210 |
return "" unless defined($toencode); |
| 211 |
|
| 212 |
$toencode =~ s{&}{&}gso; |
| 213 |
$toencode =~ s{<}{<}gso; |
| 214 |
$toencode =~ s{>}{>}gso; |
| 215 |
$toencode =~ s{"}{"}gso; |
| 216 |
return $toencode; |
| 217 |
} |
| 218 |
|
| 219 |
# encode unknown data for use in a URL <a href="..."> |
| 220 |
sub encode_url { |
| 221 |
local ($_) = @_; |
| 222 |
s/([\000-\032\;\/\?\:\@\&\=\%\'\"\`\<\>\177-\377 ])/sprintf('%%%02x',ord($1))/eg; |
| 223 |
|
| 224 |
# s/%20/+/g; |
| 225 |
$_; |
| 226 |
} |
| 227 |
|
| 228 |
sub warn { print "$_[0]" } |
| 229 |
sub env { defined( $ENV{ $_[0] } ) ? $ENV{ $_[0] } : undef; } |
| 230 |
sub exit { exit 0 } |
| 231 |
|
| 232 |
sub readindex { |
| 233 |
local ( *var, *msec ) = @_; |
| 234 |
local ($localportsdb) = "$portsDatabaseHeadDir/$ports_database"; |
| 235 |
local ( @tmp, @s ); |
| 236 |
|
| 237 |
open( C, $localportsdb ) || do { |
| 238 |
warn "Cannot open ports database $localportsdb: $!\n"; |
| 239 |
&exit; |
| 240 |
}; |
| 241 |
|
| 242 |
while (<C>) { |
| 243 |
next if $query && !/$query/oi; |
| 244 |
chop; |
| 245 |
|
| 246 |
@tmp = split(/\|/); |
| 247 |
$var{"$tmp[1]"} = $_; |
| 248 |
@s = split( /\s+/, $tmp[6] ); |
| 249 |
foreach (@s) { |
| 250 |
$msec{"$tmp[1],$_"} = 1; |
| 251 |
} |
| 252 |
} |
| 253 |
close C; |
| 254 |
} |
| 255 |
|
| 256 |
# extract sub collections |
| 257 |
sub readcoll { |
| 258 |
|
| 259 |
local ( @a, @b, %key ); |
| 260 |
local ($file) = '../ports/categories'; |
| 261 |
local ($localportsdb) = "$portsDatabaseHeadDir/$ports_database"; |
| 262 |
|
| 263 |
if ( -r $file && open( C, $file ) ) { |
| 264 |
while (<C>) { |
| 265 |
chop; |
| 266 |
|
| 267 |
if (/^\s*([^,]+),\s*"([^"]+)",\s*([A-Z]+)/) { |
| 268 |
@b = split( /\s+/, $1 ); |
| 269 |
foreach (@b) { |
| 270 |
if ( !defined( $key{$_} ) ) { |
| 271 |
$key{$_} = 1; |
| 272 |
} |
| 273 |
} |
| 274 |
} |
| 275 |
} |
| 276 |
} |
| 277 |
else { |
| 278 |
if ( -r $localportsdb ) { |
| 279 |
open( C, $localportsdb ) || do { |
| 280 |
warn "Cannot open ports database $localportsdb: $!\n"; |
| 281 |
&exit; |
| 282 |
} |
| 283 |
} |
| 284 |
|
| 285 |
while (<C>) { |
| 286 |
chop; |
| 287 |
|
| 288 |
@a = split('\|'); |
| 289 |
@b = split( /\s+/, $a[6] ); |
| 290 |
|
| 291 |
foreach (@b) { |
| 292 |
if ( !defined( $key{$_} ) ) { |
| 293 |
$key{$_} = 1; |
| 294 |
} |
| 295 |
} |
| 296 |
} |
| 297 |
} |
| 298 |
close C; |
| 299 |
|
| 300 |
@a = (); |
| 301 |
foreach ( sort keys %key ) { |
| 302 |
push( @a, $_ ); |
| 303 |
} |
| 304 |
|
| 305 |
return @a; |
| 306 |
} |
| 307 |
|
| 308 |
# basic function for HTML output |
| 309 |
sub out { |
| 310 |
local ($line) = @_; |
| 311 |
local ( |
| 312 |
$version, $path, $local, $comment, $descfile, |
| 313 |
$email, $sections, $bdepends, $rdepends, @rest |
| 314 |
) = split( /\|/, $line ); |
| 315 |
|
| 316 |
if ( $path =~ m%^$localPrefix/([^/]+)%o ) { |
| 317 |
if ( !$out_sec || $1 ne $out_sec ) { |
| 318 |
print "</dl>\n" if $counter > 0; |
| 319 |
print qq{\n<h3>} |
| 320 |
. qq{<a href="$remotePrefixHtml/$1.html">Category $1</a>} |
| 321 |
. "</h3>\n<dl>\n"; |
| 322 |
$out_sec = $1; |
| 323 |
} |
| 324 |
} |
| 325 |
|
| 326 |
$counter++; |
| 327 |
$pathDownload = $path; |
| 328 |
$pathB = $path; |
| 329 |
$pathB =~ s/^$localPrefix/ports/o; |
| 330 |
|
| 331 |
$path =~ s/^$localPrefix/$remotePrefixFtp/o; |
| 332 |
$descfile =~ s/^$localPrefix/$remotePrefixFtp/o; |
| 333 |
$version = &encode_url($version); |
| 334 |
|
| 335 |
#$version =~ s/[\+,]/X/g; |
| 336 |
|
| 337 |
local ($l) = $path; |
| 338 |
$l =~ s%^$remotePrefixFtp%$remotePrefixRepo%o; |
| 339 |
$descfile =~ s%^$remotePrefixFtp%$remotePrefixRepo%o; |
| 340 |
|
| 341 |
print |
| 342 |
qq{<dt><b><a name="$version"></a><a href="$l">$version</a></b></dt>\n}; |
| 343 |
print qq{<dd>}, &escapeHTML($comment), qq{<br />\n}; |
| 344 |
|
| 345 |
print qq[<a href="$descfile?revision=HEAD">Description</a> <b>:</b>\n]; |
| 346 |
|
| 347 |
# Link package in "default" arch/release. Verify it's existence on ftp-master. |
| 348 |
if ( $packages{"$version.$packageExt"} ) { |
| 349 |
print |
| 350 |
qq[<a href="$remotePrefixFtpPackages{$remotePrefixFtpPackagesDefault}/$version.$packageExt">Package</a> <b>:</b>\n]; |
| 351 |
} |
| 352 |
|
| 353 |
print qq[<a href="$l/?view=log">Changes</a> <br />\n]; |
| 354 |
|
| 355 |
print qq{<i>Maintained by:</i> <a href="mailto:$email} |
| 356 |
. ( |
| 357 |
$mailtoAdvanced |
| 358 |
? qq{?cc=$mailtoList&subject=FreeBSD%20Port:%20} |
| 359 |
. &encode_url($version) |
| 360 |
: '' |
| 361 |
) . qq{">$email</a><br />\n}; |
| 362 |
|
| 363 |
local (@s) = split( /\s+/, $sections ); |
| 364 |
if ( $#s > 0 ) { |
| 365 |
print qq{<i>Also listed in:</i> }; |
| 366 |
foreach (@s) { |
| 367 |
print qq{<a href="$remotePrefixHtml/$_.html">$_</a> } |
| 368 |
if $_ ne $out_sec; |
| 369 |
} |
| 370 |
print "<br />\n"; |
| 371 |
} |
| 372 |
|
| 373 |
if ( $bdepends || $rdepends ) { |
| 374 |
local ($flag) = 0; |
| 375 |
local ($last) = ''; |
| 376 |
print qq{<i>Requires:</i> }; |
| 377 |
foreach ( sort split( /\s+/, "$bdepends $rdepends" ) ) { |
| 378 |
|
| 379 |
# delete double entries |
| 380 |
next if $_ eq $last; |
| 381 |
$last = $_; |
| 382 |
|
| 383 |
print ", " if $flag; |
| 384 |
$flag++; |
| 385 |
print qq{<a href="$script_name?query=^$_&stype=name">$_</a>}; |
| 386 |
} |
| 387 |
print "<br />\n"; |
| 388 |
} |
| 389 |
|
| 390 |
print qq[</dd>]; |
| 391 |
|
| 392 |
# XXX: should be done in a CSS |
| 393 |
print qq[<dd> </dd>]; |
| 394 |
print qq[\n\n]; |
| 395 |
|
| 396 |
} |
| 397 |
|
| 398 |
# search and output |
| 399 |
sub search_ports { |
| 400 |
local (@a) = (); |
| 401 |
local ( $key, $name, $text ); |
| 402 |
|
| 403 |
foreach $key ( sort keys %today ) { |
| 404 |
next if $today{$key} !~ /$query/oi; |
| 405 |
|
| 406 |
@a = split( /\|/, $today{$key} ); |
| 407 |
$name = $a[0]; #$name =~ s/(\W)/\\$1/g; |
| 408 |
$text = $a[3]; #$text =~ s/(\W)/\\$1/g; |
| 409 |
|
| 410 |
if ( $section ne "all" ) { |
| 411 |
next if $a[6] !~ /^$section(\s|$)/; |
| 412 |
} |
| 413 |
|
| 414 |
#warn "$stype:$query: $name $text\n"; |
| 415 |
if ( $stype eq "name" && $name =~ /$query/o ) { |
| 416 |
&out( $today{$key} ); |
| 417 |
} |
| 418 |
elsif ( $stype eq "text" && $text =~ /$query/oi ) { |
| 419 |
&out( $today{$key} ); |
| 420 |
} |
| 421 |
elsif ( $stype eq "all" |
| 422 |
&& ( $text =~ /$query/oi || $name =~ /$query/io ) ) |
| 423 |
{ |
| 424 |
&out( $today{$key} ); |
| 425 |
} |
| 426 |
elsif ( $stype eq 'maintainer' && $a[5] =~ /$query/io ) { |
| 427 |
&out( $today{$key} ); |
| 428 |
} |
| 429 |
elsif ( $stype eq 'requires' |
| 430 |
&& ( $a[7] =~ /$query/io || $a[8] =~ /$query/io ) ) |
| 431 |
{ |
| 432 |
&out( $today{$key} ); |
| 433 |
} |
| 434 |
|
| 435 |
} |
| 436 |
} |
| 437 |
|
| 438 |
sub forms { |
| 439 |
print qq{<p> |
| 440 |
FreeBSD Ports [short description <a href="$portsDesc">followed</a> ...] |
| 441 |
<a href="$script_name?stype=faq">FAQ</a> |
| 442 |
</p> |
| 443 |
}; |
| 444 |
|
| 445 |
print qq{<p> |
| 446 |
"Package Name" searches for the name of a port or distribution. |
| 447 |
"Description" searches case-insensitive in a short comment about the port. |
| 448 |
"All" searches case-insensitive for the package name and in the |
| 449 |
description about the port. |
| 450 |
</p> |
| 451 |
|
| 452 |
<form method="get" action="$script_name"> |
| 453 |
Search for: |
| 454 |
<input name="query" value="$query" type="text" autocapitalize="none" /> |
| 455 |
<select name="stype"> |
| 456 |
}; |
| 457 |
|
| 458 |
local (%d); |
| 459 |
%d = ( |
| 460 |
'name', 'Package Name', 'all', 'All', |
| 461 |
'maintainer', 'Maintainer', 'text', 'Description', |
| 462 |
'requires', 'Requires', |
| 463 |
); |
| 464 |
|
| 465 |
foreach ( 'all', 'name', 'text', 'maintainer', 'requires' ) { |
| 466 |
print "<option" |
| 467 |
. ( ( $_ eq $stype ) ? ' selected="selected" ' : ' ' ) |
| 468 |
. qq{value="$_">} |
| 469 |
. ( $d{$_} ? $d{$_} : $_ ) |
| 470 |
. qq{</option>\n}; |
| 471 |
} |
| 472 |
|
| 473 |
print qq{</select> |
| 474 |
|
| 475 |
<select name="sektion"> |
| 476 |
<option value="all">All Sections</option> |
| 477 |
}; |
| 478 |
|
| 479 |
foreach (@sec) { |
| 480 |
print "<option" |
| 481 |
. ( ( $_ eq $section ) ? ' selected="selected" ' : ' ' ) |
| 482 |
. qq{value="$_">$_</option>\n}; |
| 483 |
} |
| 484 |
|
| 485 |
print q{</select> |
| 486 |
<input type="submit" value="Submit" /> |
| 487 |
</form> |
| 488 |
<hr noshade="noshade" /> |
| 489 |
}; |
| 490 |
|
| 491 |
} |
| 492 |
|
| 493 |
sub footer { |
| 494 |
|
| 495 |
print qq{ |
| 496 |
<img align="right" src="$hsty_base/gifs/powerlogo.gif" alt="Powered by FreeBSD" /> |
| 497 |
© 1996-2017 by Wolfram Schneider. All rights reserved.<br /> |
| 498 |
}; |
| 499 |
|
| 500 |
#print q{$FreeBSD$} . "<br />\n"; |
| 501 |
print qq{General questions about FreeBSD ports should be sent to } |
| 502 |
. qq{<a href="mailto:$mailtoList">} |
| 503 |
. qq{<i>$mailtoList</i></a><br />\n}; |
| 504 |
print &last_update_message; |
| 505 |
print qq{<hr noshade="noshade" />\n<p />\n}; |
| 506 |
} |
| 507 |
|
| 508 |
sub check_input { |
| 509 |
if ($query) { |
| 510 |
$stype = "all" if !$stype; |
| 511 |
if ( |
| 512 |
!( |
| 513 |
$stype eq "name" |
| 514 |
|| $stype eq "text" |
| 515 |
|| $stype eq "maintainer" |
| 516 |
|| $stype eq "requires" |
| 517 |
|| $stype eq "all" |
| 518 |
) |
| 519 |
) |
| 520 |
{ |
| 521 |
&warn( |
| 522 |
"unknown search type ``$type'', use `all', `text', `name', 'requires', or `maintainer'\n" |
| 523 |
); |
| 524 |
&exit(0); |
| 525 |
} |
| 526 |
else { |
| 527 |
return; |
| 528 |
} |
| 529 |
} |
| 530 |
} |
| 531 |
|
| 532 |
sub faq { |
| 533 |
print qq{<H1>FreeBSD Ports Search FAQ</h1> |
| 534 |
|
| 535 |
<h2>Keywords</h2> |
| 536 |
<dl> |
| 537 |
<dt><b>Description</b><dd>A more detailed description. |
| 538 |
<dt><b>Changes</b><dd>Read the latest changes. |
| 539 |
</dl> |
| 540 |
|
| 541 |
<h2>Misc</h2> |
| 542 |
|
| 543 |
<p> |
| 544 |
The script ports.cgi use the file |
| 545 |
<a href="$hsty_base/ports/$ports_database.bz2">$ports_database</a> |
| 546 |
as database for it's operations. $ports_database is updated automatically every |
| 547 |
two hours.</p> |
| 548 |
|
| 549 |
<p> |
| 550 |
You may also search the |
| 551 |
<a href="https://www.FreeBSD.org/cgi/man.cgi?manpath=FreeBSD+Ports">ports manual pages</a>.</p> |
| 552 |
|
| 553 |
<p> |
| 554 |
<a href="$script_name">Back to the search engine</a></p> |
| 555 |
<hr noshade="noshade" /> |
| 556 |
}; |
| 557 |
} |
| 558 |
|
| 559 |
# |
| 560 |
# Main |
| 561 |
# |
| 562 |
|
| 563 |
&init_variables; |
| 564 |
$query_string = &env('QUERY_STRING'); |
| 565 |
$path_info = &env('PATH_INFO'); |
| 566 |
&decode_form( $query_string, *form ); |
| 567 |
|
| 568 |
$section = $form{'sektion'}; |
| 569 |
$section = 'all' if ( !$section ); |
| 570 |
$query = $form{'query'}; |
| 571 |
$stype = $form{'stype'}; |
| 572 |
$script_name = &env('SCRIPT_NAME'); |
| 573 |
|
| 574 |
if ( $path_info eq "/source" ) { |
| 575 |
|
| 576 |
# XXX |
| 577 |
print "Content-type: text/plain\n\n"; |
| 578 |
open( R, $0 ) || do { print "ick!\n"; &exit; }; |
| 579 |
while (<R>) { print } |
| 580 |
close R; |
| 581 |
&exit; |
| 582 |
} |
| 583 |
|
| 584 |
if ( $stype eq "faq" ) { |
| 585 |
print &short_html_header( "FreeBSD Ports Search FAQ", 1 ); |
| 586 |
&faq; |
| 587 |
&footer; |
| 588 |
print &html_footer; |
| 589 |
&exit(0); |
| 590 |
} |
| 591 |
|
| 592 |
print &html_header( "FreeBSD Ports Search", 1 ); |
| 593 |
|
| 594 |
# allow `/ports.cgi?netscape' where 'netscape' is the query port to search |
| 595 |
# this make links to this script shorter |
| 596 |
if ( !$query && $query_string =~ /^([^=&]+)$/ ) { |
| 597 |
$query = $1; |
| 598 |
} |
| 599 |
|
| 600 |
# automatically read collections, need only 0.2 sec on a pentium |
| 601 |
@sec = &readcoll; |
| 602 |
|
| 603 |
$query =~ s/"/ /g; |
| 604 |
$query =~ s/^\s+//; |
| 605 |
$query =~ s/\s+$//; |
| 606 |
&forms; |
| 607 |
|
| 608 |
if ( $query_string eq "" || !$query ) { |
| 609 |
&footer; |
| 610 |
print &html_footer; |
| 611 |
&exit(0); |
| 612 |
} |
| 613 |
|
| 614 |
&check_input; |
| 615 |
$counter = 0; |
| 616 |
|
| 617 |
# search |
| 618 |
if ($query) { |
| 619 |
&readindex( *today, *msec ); |
| 620 |
$query =~ s/([^\w\^])/\\$1/g; |
| 621 |
&search_ports; |
| 622 |
} |
| 623 |
|
| 624 |
if ( !$counter ) { |
| 625 |
print "Sorry, nothing found.\n"; |
| 626 |
print qq{You may look for other } |
| 627 |
. qq{<a href="/search/search.html">FreeBSD Search Services</a>.\n}; |
| 628 |
} |
| 629 |
else { |
| 630 |
print "</dl>\n"; |
| 631 |
} |
| 632 |
|
| 633 |
print qq{<hr noshade="noshade" />\n}; |
| 634 |
&footer; |
| 635 |
print &html_footer; |