aboutsummaryrefslogtreecommitdiff
path: root/website/content/en/cgi
diff options
context:
space:
mode:
Diffstat (limited to 'website/content/en/cgi')
-rw-r--r--website/content/en/cgi/MyCgiSimple.pm433
-rw-r--r--website/content/en/cgi/cgi-lib.pl2
-rw-r--r--website/content/en/cgi/cgi-style.pl21
-rwxr-xr-xwebsite/content/en/cgi/fingerprints.cgi58
-rwxr-xr-xwebsite/content/en/cgi/getmsg.cgi245
-rwxr-xr-xwebsite/content/en/cgi/mailindex.cgi111
-rwxr-xr-xwebsite/content/en/cgi/man-autocomplete.cgi209
-rwxr-xr-xwebsite/content/en/cgi/man.cgi526
-rwxr-xr-xwebsite/content/en/cgi/mid.cgi161
-rwxr-xr-xwebsite/content/en/cgi/mirror.cgi32
-rwxr-xr-xwebsite/content/en/cgi/ports-autocomplete.cgi219
-rwxr-xr-xwebsite/content/en/cgi/ports.cgi245
12 files changed, 1367 insertions, 895 deletions
diff --git a/website/content/en/cgi/MyCgiSimple.pm b/website/content/en/cgi/MyCgiSimple.pm
new file mode 100644
index 0000000000..d31623ba75
--- /dev/null
+++ b/website/content/en/cgi/MyCgiSimple.pm
@@ -0,0 +1,433 @@
+# This module is free software; you can redistribute it and/or modify it under the
+# same terms as Perl itself. See https://metacpan.org/pod/perlartistic
+#
+# MyCgiSimple.pm - striped down version of CGI::Simple;
+
+package MyCgiSimple;
+
+sub charset {
+ return 'utf-8';
+}
+
+sub param {
+ my ( $self, $param, @p ) = @_;
+ unless ( defined $param ) { # return list of all params
+ my @params = $self->{'.parameters'} ? @{ $self->{'.parameters'} } : ();
+ return @params;
+ }
+ unless (@p) { # return values for $param
+ return () unless exists $self->{$param};
+ return wantarray ? @{ $self->{$param} } : $self->{$param}->[0];
+ }
+ if ( $param =~ m/^-name$/i and @p == 1 ) {
+ return () unless exists $self->{ $p[0] };
+ return wantarray ? @{ $self->{ $p[0] } } : $self->{ $p[0] }->[0];
+ }
+
+ # set values using -name=>'foo',-value=>'bar' syntax.
+ # also allows for $q->param( 'foo', 'some', 'new', 'values' ) syntax
+ ( $param, undef, @p ) = @p
+ if $param =~ m/^-name$/i; # undef represents -value token
+ $self->_add_param( $param, ( ref $p[0] eq 'ARRAY' ? $p[0] : [@p] ),
+ 'overwrite' );
+ return wantarray ? @{ $self->{$param} } : $self->{$param}->[0];
+}
+
+sub new {
+ my ( $class, $init ) = @_;
+ $class = ref($class) || $class;
+ my $self = {};
+ bless $self, $class;
+
+ $self->_initialize_globals;
+ $self->_store_globals;
+ $self->_initialize($init);
+
+ return $self;
+}
+
+sub path_info {
+ my ( $self, $info ) = @_;
+ if ( defined $info ) {
+ $info = "/$info" if $info !~ m|^/|;
+ $self->{'.path_info'} = $info;
+ }
+ elsif ( !defined( $self->{'.path_info'} ) ) {
+ $self->{'.path_info'} =
+ defined( $ENV{'PATH_INFO'} ) ? $ENV{'PATH_INFO'} : '';
+
+ # hack to fix broken path info in IIS source CGI.pm
+ $self->{'.path_info'} =~ s/^\Q$ENV{'SCRIPT_NAME'}\E//
+ if defined( $ENV{'SERVER_SOFTWARE'} )
+ && $ENV{'SERVER_SOFTWARE'} =~ /IIS/;
+ }
+ return $self->{'.path_info'};
+}
+
+sub _initialize {
+ my ( $self, $init ) = @_;
+
+ if ( !defined $init ) {
+
+ # initialize from QUERY_STRING, STDIN or @ARGV
+ $self->_read_parse();
+ }
+ elsif ( ( ref $init ) =~ m/HASH/i ) {
+
+ # initialize from param hash
+ for my $param ( keys %{$init} ) {
+ $self->_add_param( $param, $init->{$param} );
+ }
+ }
+
+ # chromatic's blessed GLOB patch
+ # elsif ( (ref $init) =~ m/GLOB/i ) { # initialize from a file
+ elsif ( UNIVERSAL::isa( $init, 'GLOB' ) ) { # initialize from a file
+ $self->_init_from_file($init);
+ }
+ elsif ( ( ref $init ) eq 'CGI::Simple' ) {
+
+ # initialize from a CGI::Simple object
+ require Data::Dumper;
+
+ # avoid problems with strict when Data::Dumper returns $VAR1
+ my $VAR1;
+ my $clone = eval( Data::Dumper::Dumper($init) );
+ if ($@) {
+ $self->cgi_error("Can't clone CGI::Simple object: $@");
+ }
+ else {
+ $_[0] = $clone;
+ }
+ }
+ else {
+ $self->_parse_params($init); # initialize from a query string
+ }
+}
+
+sub _initialize_globals {
+
+ # set this to 1 to use CGI.pm default global settings
+ $USE_CGI_PM_DEFAULTS = 0
+ unless defined $USE_CGI_PM_DEFAULTS;
+
+ # see if user wants old CGI.pm defaults
+ if ($USE_CGI_PM_DEFAULTS) {
+ _use_cgi_pm_global_settings();
+ return;
+ }
+
+ # no file uploads by default, set to 0 to enable uploads
+ $DISABLE_UPLOADS = 1
+ unless defined $DISABLE_UPLOADS;
+
+ # use a post max of 100K, set to -1 for no limits
+ $POST_MAX = 102_400
+ unless defined $POST_MAX;
+
+ # set to 1 to not include undefined params parsed from query string
+ $NO_UNDEF_PARAMS = 0
+ unless defined $NO_UNDEF_PARAMS;
+
+ # separate the name=value pairs with ; rather than &
+ $USE_PARAM_SEMICOLONS = 0
+ unless defined $USE_PARAM_SEMICOLONS;
+
+ # return everything as utf-8
+ $PARAM_UTF8 ||= 0;
+ $PARAM_UTF8 and require Encode;
+
+ # only print headers once
+ $HEADERS_ONCE = 0
+ unless defined $HEADERS_ONCE;
+
+ # Set this to 1 to enable NPH scripts
+ $NPH = 0
+ unless defined $NPH;
+
+ # 0 => no debug, 1 => from @ARGV, 2 => from STDIN
+ $DEBUG = 0
+ unless defined $DEBUG;
+
+ # filter out null bytes in param - value pairs
+ $NO_NULL = 1
+ unless defined $NO_NULL;
+
+ # set behavior when cgi_err() called -1 => silent, 0 => carp, 1 => croak
+ $FATAL = -1
+ unless defined $FATAL;
+}
+
+# this is called by new, we will never directly reference the globals again
+sub _store_globals {
+ my $self = shift;
+
+ $self->{'.globals'}->{'DISABLE_UPLOADS'} = $DISABLE_UPLOADS;
+ $self->{'.globals'}->{'POST_MAX'} = $POST_MAX;
+ $self->{'.globals'}->{'NO_UNDEF_PARAMS'} = $NO_UNDEF_PARAMS;
+ $self->{'.globals'}->{'USE_PARAM_SEMICOLONS'} = $USE_PARAM_SEMICOLONS;
+ $self->{'.globals'}->{'HEADERS_ONCE'} = $HEADERS_ONCE;
+ $self->{'.globals'}->{'NPH'} = $NPH;
+ $self->{'.globals'}->{'DEBUG'} = $DEBUG;
+ $self->{'.globals'}->{'NO_NULL'} = $NO_NULL;
+ $self->{'.globals'}->{'FATAL'} = $FATAL;
+ $self->{'.globals'}->{'USE_CGI_PM_DEFAULTS'} = $USE_CGI_PM_DEFAULTS;
+ $self->{'.globals'}->{'PARAM_UTF8'} = $PARAM_UTF8;
+}
+
+sub _read_parse {
+ my $self = shift;
+ my $data = '';
+ my $type = $ENV{'CONTENT_TYPE'} || 'No CONTENT_TYPE received';
+ my $length = $ENV{'CONTENT_LENGTH'} || 0;
+ my $method = $ENV{'REQUEST_METHOD'} || 'No REQUEST_METHOD received';
+
+ # first check POST_MAX Steve Purkis pointed out the previous bug
+ if ( ( $method eq 'POST' or $method eq "PUT" )
+ and $self->{'.globals'}->{'POST_MAX'} != -1
+ and $length > $self->{'.globals'}->{'POST_MAX'} )
+ {
+ $self->cgi_error(
+"413 Request entity too large: $length bytes on STDIN exceeds \$POST_MAX!"
+ );
+
+ # silently discard data ??? better to just close the socket ???
+ while ( $length > 0 ) {
+ last unless _internal_read( $self, my $buffer );
+ $length -= length($buffer);
+ }
+
+ return;
+ }
+
+ if ( $length and $type =~ m|^multipart/form-data|i ) {
+ my $got_length = $self->_parse_multipart;
+ if ( $length != $got_length ) {
+ $self->cgi_error(
+"500 Bad read on multipart/form-data! wanted $length, got $got_length"
+ );
+ }
+
+ return;
+ }
+ elsif ( $method eq 'POST' or $method eq 'PUT' ) {
+ if ($length) {
+
+ # we may not get all the data we want with a single read on large
+ # POSTs as it may not be here yet! Credit Jason Luther for patch
+ # CGI.pm < 2.99 suffers from same bug
+ _internal_read( $self, $data, $length );
+ while ( length($data) < $length ) {
+ last unless _internal_read( $self, my $buffer );
+ $data .= $buffer;
+ }
+
+ unless ( $length == length $data ) {
+ $self->cgi_error( "500 Bad read on POST! wanted $length, got "
+ . length($data) );
+ return;
+ }
+
+ if ( $type !~ m|^application/x-www-form-urlencoded| ) {
+ $self->_add_param( $method . "DATA", $data );
+ }
+ else {
+ $self->_parse_params($data);
+ }
+ }
+ }
+ elsif ( $method eq 'GET' or $method eq 'HEAD' ) {
+ $data =
+ $self->{'.mod_perl'}
+ ? $self->_mod_perl_request()->args()
+ : $ENV{'QUERY_STRING'}
+ || $ENV{'REDIRECT_QUERY_STRING'}
+ || '';
+ $self->_parse_params($data);
+ }
+ else {
+ unless ($self->{'.globals'}->{'DEBUG'}
+ and $data = $self->read_from_cmdline() )
+ {
+ $self->cgi_error("400 Unknown method $method");
+ return;
+ }
+
+ unless ($data) {
+
+ # I liked this reporting but CGI.pm does not behave like this so
+ # out it goes......
+ # $self->cgi_error("400 No data received via method: $method, type: $type");
+ return;
+ }
+
+ $self->_parse_params($data);
+ }
+}
+
+sub cgi_error {
+ my ( $self, $err ) = @_;
+ if ($err) {
+ require Carp;
+ $self->{'.cgi_error'} = $err;
+ $self->{'.globals'}->{'FATAL'} == 1 ? croak $err
+ : $self->{'.globals'}->{'FATAL'} == 0 ? carp $err
+ : return $err;
+ }
+ return $self->{'.cgi_error'};
+}
+
+# This internal routine creates date strings suitable for use in
+# cookies and HTTP headers. (They differ, unfortunately.)
+# Thanks to Mark Fisher for this.
+sub expires {
+ my ( $time, $format ) = @_;
+ $format ||= 'http';
+
+ my (@MON) = qw/Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec/;
+ my (@WDAY) = qw/Sun Mon Tue Wed Thu Fri Sat/;
+
+ # pass through preformatted dates for the sake of expire_calc()
+ $time = expire_calc($time);
+ return $time unless $time =~ /^\d+$/;
+
+ # make HTTP/cookie date string from GMT'ed time
+ # (cookies use '-' as date separator, HTTP uses ' ')
+ my ($sc) = ' ';
+ $sc = '-' if $format eq "cookie";
+ my ( $sec, $min, $hour, $mday, $mon, $year, $wday ) = gmtime($time);
+ $year += 1900;
+ return sprintf( "%s, %02d$sc%s$sc%04d %02d:%02d:%02d GMT",
+ $WDAY[$wday], $mday, $MON[$mon], $year, $hour, $min, $sec );
+}
+
+# This internal routine creates an expires time exactly some number of
+# hours from the current time. It incorporates modifications from
+# Mark Fisher.
+sub expire_calc {
+ my ($time) = @_;
+ my (%mult) = (
+ 's' => 1,
+ 'm' => 60,
+ 'h' => 60 * 60,
+ 'd' => 60 * 60 * 24,
+ 'M' => 60 * 60 * 24 * 30,
+ 'y' => 60 * 60 * 24 * 365
+ );
+
+ # format for time can be in any of the forms...
+ # "now" -- expire immediately
+ # "+180s" -- in 180 seconds
+ # "+2m" -- in 2 minutes
+ # "+12h" -- in 12 hours
+ # "+1d" -- in 1 day
+ # "+3M" -- in 3 months
+ # "+2y" -- in 2 years
+ # "-3m" -- 3 minutes ago(!)
+ # If you don't supply one of these forms, we assume you are
+ # specifying the date yourself
+ my ($offset);
+ if ( !$time || ( lc($time) eq 'now' ) ) {
+ $offset = 0;
+ }
+ elsif ( $time =~ /^\d+/ ) {
+ return $time;
+ }
+ elsif ( $time =~ /^([+-]?(?:\d+|\d*\.\d*))([mhdMy]?)/ ) {
+ $offset = ( $mult{$2} || 1 ) * $1;
+ }
+ else {
+ return $time;
+ }
+ return ( time + $offset );
+}
+
+sub header {
+ my $self = shift;
+ my %args = @_;
+
+ my $type = $args{-type};
+ my $charset = $args{-charset};
+ my $expires = $args{-expires};
+
+ push( @header, "Expires: " . expires( $expires, 'http' ) )
+ if $expires;
+ push( @header, "Date: " . expires( 0, 'http' ) ) if $expires;
+
+ if ( $type && $charset ) {
+ $type .= '; charset=' . $charset;
+ }
+ push @header, "Content-Type: $type" if $type;
+
+ return join( "\n", @header ), "\n\n";
+}
+
+sub _parse_params {
+ my ( $self, $data ) = @_;
+ return () unless defined $data;
+ unless ( $data =~ /[&=;]/ ) {
+
+ #$self->{'keywords'} = [ $self->_parse_keywordlist( $data ) ];
+ $self->{'keywords'} = [];
+ return;
+ }
+ my @pairs = split /[&;]/, $data;
+ for my $pair (@pairs) {
+ my ( $param, $value ) = split /=/, $pair, 2;
+ next unless defined $param;
+ $value = '' unless defined $value;
+ $self->_add_param( $self->url_decode($param),
+ $self->url_decode($value) );
+ }
+}
+
+# use correct encoding conversion to handle non ASCII char sets.
+# we import and install the complex routines only if we have to.
+BEGIN {
+
+ sub url_decode {
+ my ( $self, $decode ) = @_;
+ return () unless defined $decode;
+ $decode =~ tr/+/ /;
+ $decode =~ s/%([a-fA-F0-9]{2})/ pack "C", hex $1 /eg;
+ return $decode;
+ }
+
+ sub url_encode {
+ my ( $self, $encode ) = @_;
+ return () unless defined $encode;
+ $encode =~ s/([^A-Za-z0-9\-_.!~*'() ])/ uc sprintf "%%%02x",ord $1 /eg;
+ $encode =~ tr/ /+/;
+ return $encode;
+ }
+
+}
+
+sub _add_param {
+ my ( $self, $param, $value, $overwrite ) = @_;
+ return () unless defined $param and defined $value;
+ $param =~ tr/\000//d if $self->{'.globals'}->{'NO_NULL'};
+ @{ $self->{$param} } = () if $overwrite;
+ @{ $self->{$param} } = () unless exists $self->{$param};
+ my @values = ref $value ? @{$value} : ($value);
+ for my $value (@values) {
+ next
+ if $value eq ''
+ and $self->{'.globals'}->{'NO_UNDEF_PARAMS'};
+ $value =~ tr/\000//d if $self->{'.globals'}->{'NO_NULL'};
+ $value = Encode::decode( utf8 => $value )
+ if $self->{'.globals'}->{PARAM_UTF8};
+ push @{ $self->{$param} }, $value;
+ unless ( $self->{'.fieldnames'}->{$param} ) {
+ push @{ $self->{'.parameters'} }, $param;
+ $self->{'.fieldnames'}->{$param}++;
+ }
+ }
+ return scalar @values; # for compatibility with CGI.pm request.t
+}
+
+# from CGI::Simple 1.115
+sub script_name { $ENV{'SCRIPT_NAME'} || $0 || '' }
+sub server_name { $ENV{'SERVER_NAME'} || 'localhost' }
+
+1;
diff --git a/website/content/en/cgi/cgi-lib.pl b/website/content/en/cgi/cgi-lib.pl
index 3af18c1a0c..38f849a866 100644
--- a/website/content/en/cgi/cgi-lib.pl
+++ b/website/content/en/cgi/cgi-lib.pl
@@ -35,8 +35,6 @@
# If a variable-glob parameter (e.g., *cgi_input) is passed to ReadParse,
# information is stored there, rather than in $in, @in, and %in.
#
-# $FreeBSD$
-#
sub ReadParse {
local (*in) = @_ if @_;
diff --git a/website/content/en/cgi/cgi-style.pl b/website/content/en/cgi/cgi-style.pl
index d82497f052..06932fa80f 100644
--- a/website/content/en/cgi/cgi-style.pl
+++ b/website/content/en/cgi/cgi-style.pl
@@ -1,4 +1,3 @@
-# $FreeBSD$
#
# Perl routines to encapsulate various elements of HTML page style.
@@ -12,11 +11,11 @@ if (!defined($hsty_base)) {
# $hsty_base should be relative if possible, so that mirrors
# serve their local copy instead of going to the main site.
# However, if we aren't running as a cgi, or if we're
- # running on cgi, hub, docs or people, use the absolute home path.
+ # running on one of the subdomains listed below, use the absolute home path.
if (!defined($ENV{'HTTP_HOST'}) ||
- $ENV{'HTTP_HOST'} =~ /(cgi|hub|docs|people|mailarchive.ysv).freebsd.org/i) {
+ $ENV{'HTTP_HOST'} =~ /(docs|docs-archive|mail-archive|man|man-dev|people|ports).freebsd.org/i) {
- $hsty_base = '//www.FreeBSD.org'
+ $hsty_base = 'https://www.FreeBSD.org'
} else {
$hsty_base = '..';
}
@@ -25,7 +24,7 @@ if (!defined($hsty_email)) {
$hsty_email = 'Contact';
}
if (!defined($hsty_author)) {
- $hsty_author = "<a href='$hsty_base/mailto.html'>$hsty_email</a>";
+ $hsty_author = "<a href='$hsty_base/mailto/'>$hsty_email</a>";
}
if (!defined($hsty_date)) {
@@ -151,7 +150,7 @@ $i_topbar = qq`
<li><a href="$hsty_base/projects/index.html">Developers</a>
<ul>
<li><a href="$hsty_base/projects/ideas/ideas.html">Project Ideas</a></li>
- <li><a href="//cgit.FreeBSD.org">GIT Repository</a></li>
+ <li><a href="https://cgit.FreeBSD.org">GIT Repository</a></li>
</ul>
</li>
</ul>
@@ -159,16 +158,16 @@ $i_topbar = qq`
<li><a href="$hsty_base/support.html">Support</a>
<ul>
<li><a href="$hsty_base/commercial/commercial.html">Vendors</a></li>
- <li><a href="//security.FreeBSD.org/">Security Information</a></li>
+ <li><a href="https://security.FreeBSD.org/">Security Information</a></li>
<li><a href="https://bugs.freebsd.org/search/">Bug Reports</a></li>
<li><a href="$hsty_base/support.html">Submit Bug-report</a></li>
</ul>
</li>
</ul>
<ul>
- <li><a href="//www.freebsdfoundation.org/">Foundation</a>
+ <li><a href="https://www.freebsdfoundation.org/">Foundation</a>
<ul>
- <li><a href="//www.freebsdfoundation.org/donate/">Donate</a></li>
+ <li><a href="https://www.freebsdfoundation.org/donate/">Donate</a></li>
</ul>
</li>
</ul>
@@ -187,7 +186,7 @@ if (!defined($hsty_home)) {
sub html_header {
local ($title, $xhtml) = @_;
- return short_html_header($title, $xhtml) . "<h1>$title</h1>\n";
+ return short_html_header($title, $xhtml) . "<br/>\n<h1>$title</h1>\n";
}
sub short_html_header {
@@ -236,7 +235,7 @@ sub html_footer {
return qq`
</div>
<div id="footer">
- <a href="$hsty_base/copyright/">Legal Notices</a> | &copy; 1995-2022
+ <a href="$hsty_base/copyright/">Legal Notices</a> | &copy; 1995-2024
The FreeBSD Project. All rights reserved.<br />
<address>$hsty_author<br />$hsty_date</address>
</div>
diff --git a/website/content/en/cgi/fingerprints.cgi b/website/content/en/cgi/fingerprints.cgi
deleted file mode 100755
index bc99be8985..0000000000
--- a/website/content/en/cgi/fingerprints.cgi
+++ /dev/null
@@ -1,58 +0,0 @@
-#!/usr/bin/perl -T
-#
-# Display current HTTPS/SSL/TLS certificate fingerprints.
-# Should be replaced with something better.
-#
-# $FreeBSD$
-
-require "./cgi-lib.pl";
-require "./cgi-style.pl";
-$ENV{PATH} = '/bin:/usr/bin';
-
-# There is an internal post-renew propagation window of about 5-10 minutes.
-# However, the script is expensive so we leverage the cache. The problem
-# is that people could come here immediately after a fingerprint mismatch
-# so we have to be quick to update.
-print "Cache-control: public; max-age=120\n"; # 2 minutes
-print &short_html_header("FreeBSD HTTPS/SSL/TLS Server Certificate Fingerprints");
-
-print qq{<h1>FreeBSD HTTPS/SSL/TLS Server Certificate Fingerprints</h1>\n};
-print qq{<p>The FreeBSD Project makes use of <a href="https://letsencrypt.org">Let's Encrypt</a> certificates for many of its HTTPS/SSL/TLS services. These certificates are automatically updated every 60 days. The current certificate fingerprints of significant services are listed below.</p>\n};
-
-# Note: These are all case sensitive. Use lower case to match the file names.
-&Fingerprint('git.freebsd.org');
-&Fingerprint('svn.freebsd.org');
-&Fingerprint('download.freebsd.org');
-&Fingerprint('pkg.freebsd.org');
-
-print qq{<p>These fingerprints may be helpful in situations where automatic verification is not available.</p>\n};
-print &html_footer;
-exit 0;
-
-sub Fingerprint
-{
- my ($domain) = @_;
-
- my $message;
- my $sha1, $sha256;
- if ( -e "/etc/clusteradm/acme-certs/$domain.crt" ) {
- $sha1 = `/usr/bin/openssl x509 -fingerprint -noout -sha1 -in /etc/clusteradm/acme-certs/$domain.crt`;
- $sha256 = `/usr/bin/openssl x509 -fingerprint -noout -sha256 -in /etc/clusteradm/acme-certs/$domain.crt`;
- chomp($sha1);
- chomp($sha256);
- $sha1 =~ s/^.*=//;
- $sha256 =~ s/^.*=//;
- } else {
- $sha1 = 'Error';
- $sha256 = 'Error';
- }
-
- $message = qq{<p>The fingerprints of the current <b>$domain</b> certificate are:</p>\n};
- $message .= qq{<div class="informaltable"><table border="1"><colgroup><col /><col /></colgroup>};
- $message .= qq{<thead><tr><th>Hash</th><th>Fingerprint</th></tr></thead><tbody>};
- $message .= qq{<tr><td>SHA1</td><td><code class="literal">$sha1</code></td></tr>};
- $message .= qq{<tr><td>SHA256</td><td><code class="literal">$sha256</code></td></tr>};
- $message .= qq{</tbody></table></div>\n};
-
- print $message;
-}
diff --git a/website/content/en/cgi/getmsg.cgi b/website/content/en/cgi/getmsg.cgi
deleted file mode 100755
index ba486e4c99..0000000000
--- a/website/content/en/cgi/getmsg.cgi
+++ /dev/null
@@ -1,245 +0,0 @@
-#!/usr/bin/perl -T
-#
-# Given a filename, start offset and end offset of a mail message,
-# read the message and format it nicely using HTML.
-#
-# by John Fieber
-# February 26, 1998
-#
-# $FreeBSD$
-#
-
-require "./cgi-lib.pl";
-require "./cgi-style.pl";
-use POSIX qw(strftime);
-#
-# Site design includes setting a:visited to the same as a:link,
-# which isn't good in archived messages, e.g., you want to follow
-# links in commit messages and know which links you've visited.
-# Override it inside the <pre> that is the message.
-$t_style = qq`<style type="text/css">
-pre a:visited { color: #220000; }
-</style>
-`;
-
-
-#
-# Files MUST be fully qualified and MUST start with this path.
-#
-$messagepath = "/usr/local/www/mailindex/archive/";
-$messagepathcurrent = "/usr/local/www/mid/archive/";
-$ftparchive = 'ftp://ftp.FreeBSD.org/pub/FreeBSD/doc/mailing-lists/archive';
-
-&ReadParse(*formdata);
-&Fetch($formdata{'fetch'});
-exit 0;
-
-sub Fetch
-{
- my ($docid) = @_;
- my ($start, $end, $file, $type) = split(/ /, $docid);
- my ($message, @finfo);
-
- #
- # Check to ensure that (a) the specified file starts
- # with an approved pathname and (b) that it contains no
- # relative components (eg ..). This is so that arbitrary
- # files cannot be accessed.
- #
-
- $file =~ s/\.\.//g;
- $file =~ s|/+|/|;
- $file =~ s|^archive/|$messagepath/|;
-
- # read the full archive
- if ($type eq 'archive') {
- # from the FreeBSD ftp server
- if ($file =~ s%^$messagepath%%o) {
- print "Location: $ftparchive/$file.gz\n";
- print "Content-type: text/plain\n\n";
- exit(0);
- }
-
- # from the local mail archive for current mails
- elsif ($file =~ m%^current/(cvs|svn|freebsd|p4|trustedbsd)-[a-z0-9-]+$% &&
- open(DATA, "$messagepathcurrent$file")) {
- print "Content-type: text/plain\n\n";
- while(<DATA>) {
- print;
- }
- close(DATA);
- exit(0);
- }
- }
-
- if (($file =~ /^$messagepath/ && -f $file && open(DATA, $file)) ||
- ($file =~ m%^current/(cvs|svn|freebsd|p4|trustedbsd)-[a-z0-9-]+$% &&
- open(DATA, "$messagepathcurrent$file")))
- {
- @finfo = stat DATA;
- seek DATA, $start, 0;
- if ($end > $start && $start >= 0) {
- read DATA, $message, $end - $start;
- } else {
- # Unknown length, guess the end of the E-Mail
- my($newline) = 0;
- while(<DATA>) {
- last if ($newline && /^From .* \d{4}/);
- if (/^$/) { $newline = 1 } else { $newline = 0; }
- $message .= $_;
- }
- }
- close(DATA);
- print "last-modified: " .
- POSIX::strftime("%a, %d %b %Y %T GMT", gmtime($finfo[9])) . "\n";
-
- # print E-Mail as plain ascii text
- if ($type eq 'raw') {
- print "Content-type: text/plain\n\n";
- print $message;
- return;
- }
- $message = &MessageToHTML($message, $file);
- }
- else
- {
- $message = "<p>The specified message cannot be accessed.</p>\n";
- }
-
- print &short_html_header("FreeBSD Mail Archives");
- print $message;
- print &html_footer;
-}
-
-sub EscapeHTML
-{
- my ($text) = @_;
- $text =~ s/&/&amp;/g;
- $text =~ s/</&lt;/g;
- $text =~ s/>/&gt;/g;
- return $text;
-}
-
-sub MessageToHTML
-{
- my ($doc, $file) = @_;
- my ($header, $body) = split(/\n\n/, $doc, 2);
- my ($i, %hdr, $field, $data, $message);
- my ($mid) = 'mid.cgi';
- my ($mid_full_url) = 'https://docs.FreeBSD.org/cgi/mid.cgi';
- my ($tmid,$tirt,$tref);
-
- $body = &AddAnchors(&EscapeHTML($body));
-
- $header = &EscapeHTML($header);
- $header =~ s/\n[ \t]+/ /g;
-
- foreach $i (split(/\n/, $header)) {
- ($field, $data) = split(/ /, $i, 2);
- $field =~ y/A-Z/a-z/;
- $hdr{$field} = $data;
- }
-
- $message = "<pre>\n";
- if (length($hdr{'date:'}) > 0) {
- $message .= "<strong>Date: </strong> $hdr{'date:'}\n";
- }
- if (length($hdr{'from:'}) > 0) {
- $message .= "<strong>From: </strong> $hdr{'from:'}\n";
- }
- if (length($hdr{'to:'}) > 0) {
- $message .= "<strong>To: </strong> $hdr{'to:'}\n";
- }
- if (length($hdr{'cc:'}) > 0) {
- $message .= "<strong>Cc: </strong> $hdr{'cc:'}\n";
- }
-# if (length($hdr{'sender:'}) > 0) {
-# $message .= "<strong>Sender: </strong> $hdr{'sender:'}\n";
-# }
- if (length($hdr{'subject:'}) > 0) {
- $message .= "<strong>Subject: </strong> $hdr{'subject:'}\n";
- }
-
- if ($hdr{'message-id:'}) {
- $tmid = $hdr{'message-id:'};
- $hdr{'message-id:'} =~
- s%;([^&]+)&%;<a href="$mid?db=irt&amp;id=$1">$1</a>&%oi;
- $message .= "<strong>Message-ID: </strong> $hdr{'message-id:'}\n";
- }
-
- if ($hdr{'resent-message-id:'}) {
- $hdr{'resent-message-id:'} =~
- s%;([^&]+)&%;<a href="$mid?db=irt&amp;id=$1">$1</a>&%oi;
- $message .= "<strong>Resent-Message-ID: </strong>$hdr{'resent-message-id:'}\n";
- }
-
- if ($hdr{'in-reply-to:'}) {
- $tirt = $hdr{'in-reply-to:'};
- $hdr{'in-reply-to:'} =~
- s%;([^&]+)&%;<a href="$mid?db=mid&amp;id=$1">$1</a>&%oi;
- $message .= "<strong>In-Reply-To: </strong>$hdr{'in-reply-to:'}\n";
- }
-
- if ($hdr{'references:'}) {
- $tref = $hdr{'references:'};
- $hdr{'references:'} =~
- s%;([^&\s]+)&%;<a href="$mid?db=mid&amp;id=$1">$1</a>&%goi;
- $message .= "<strong>References: </strong> $hdr{'references:'}\n";
- }
-
-
- $message .= "</pre>\n";
- $message .= "<hr noshade=\"noshade\"/>\n";
-
- if ($tmid =~ m%;([^&]+)&%) {
- $message .= qq{<a href="$mid?db=irt&amp;id=$1">Next in thread</a>\n};
- }
-
- if ($tirt =~ m%;([^&]+)&% ||
- $tref =~ m%;([^&]+)&%) {
- $message .= qq{| <a href="$mid?db=mid&amp;id=$1">Previous in thread</a>\n};
- }
- $message .= qq{| <a href="$ENV{'REQUEST_URI'}+raw">Raw E-Mail</a>\n};
- my $file2 = $file;
- if ($file2 =~ s%^$messagepath%archive/%oi ||
- $file2 =~ /^current/) {
- $message .= qq{| <a href="/mail/$file2.html">Index</a>\n};
- }
- $message .= qq{| <a href="$ENV{'REQUEST_URI'}+archive">Archive</a>\n};
- $message .= qq{| <a href="../search/searchhints.html">Help</a>\n};
-
- my $tid = $tmid;
- $tid =~ s/^&lt;//;
- $tid =~ s/\@.*//;
-
- $message .= "<hr noshade=\"noshade\"/>\n";
- #$message .= qq{<div onclick="document.location='$mid_full_url?db=irt&amp;id=$tid'">\n};
- $message .= "<pre>\n$body\n</pre>\n";
- #$message .= qq{</div>\n};
-
- $message .= qq{<hr/>\n<p>Want to link to this message? Use this URL: &lt;};
- $message .= qq{<a href="} . $mid_full_url . '?' . $tid;
- $message .= qq{">$mid_full_url} . '?' . $tid . qq{</a>&gt;</p>};
-
- return $message;
-}
-
-sub strip_url
-{
- my $url = shift;
-
- # strip trailing characters
- $url =~ s/&gt;?$//;
- $url =~ s/[.,;>\s\)]*$//;
-
- return $url;
-}
-
-sub AddAnchors
-{
- my ($text) = @_;
-
- $text =~ s/(http|https|ftp)(:[\S]*?\/?)(\W?\s)/sprintf("<a href=\"%s\">%s<\/a>$3", &strip_url("$1$2"), "$1$2", $3)/egoi;
-
- return $text;
-}
diff --git a/website/content/en/cgi/mailindex.cgi b/website/content/en/cgi/mailindex.cgi
deleted file mode 100755
index 249da5f041..0000000000
--- a/website/content/en/cgi/mailindex.cgi
+++ /dev/null
@@ -1,111 +0,0 @@
-#!/usr/bin/perl -T
-#
-# Copyright (c) Jan 1999-2011 Wolfram Schneider <wosch@FreeBSD.org>
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions
-# are met:
-# 1. Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# 2. Redistributions in binary form must reproduce the above copyright
-# notice, this list of conditions and the following disclaimer in the
-# documentation and/or other materials provided with the distribution.
-#
-# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
-# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-# SUCH DAMAGE.
-#
-# $FreeBSD$
-
-
-use CGI;
-use CGI::Carp;
-
-require "./cgi-lib.pl";
-require "./cgi-style.pl";
-
-$ENV{PATH} = "/bin:/usr/bin:/usr/local/bin";
-
-# no sort
-my $sortopt = '';
-my $up = 0;
-
-$| = 1;
-
-# mail archive location
-$maildir = '/home/mail/archive';
-
-# mailindex program
-$mailindex = '/usr/local/www/mailindex/bin/mailindex';
-
-
-$query = new CGI();
-
-print "Content-type: text/html\n\n";
-
-my $reverse;
-$sortopt = '--sort-by-subject' if ($query->param('sort') eq 'subject');
-$sortopt = '--sort-by-author' if ($query->param('sort') eq 'author');
-$sortopt = '' if ($query->param('sort') eq 'date');
-
-$reverse = '--reverse' if ($query->param('reverse'));
-
-my $file = $query->param('file');
-if (!$file) {
- print "No file name given\n";
- exit;
-}
-
-# forbid link to parent directories
-$file =~ s%\.\./%%g;
-if ($file =~ m,^([0-9a-z/-]+|[0-9a-z/-]+\.[0-9a-z-]+)$,) {
- $file = $1;
-} else {
- print "Unknown file name given\n";
- exit;
-}
-
-
-sub file_not_exists {
- my $file = shift;
- print "File does not exist: $file\n";
- exit;
-}
-
-if ($file =~ s%^archive/%%) {
- $maildir = '/usr/local/www/mailindex/archive';
- &file_not_exists("$maildir/$file") if (! -f "$maildir/$file");
-} elsif ($file =~ s%^current/%% && $file =~ /^(freebsd|cvs|svn|ctm|trustedbsd)-/) {
- &file_not_exists("$file") if (! -f "$maildir/$file");
- $up = 0;
-} else {
- &file_not_exists("$file");
-}
-
-chdir($maildir) or die "chdir $maildir: $!\n";
-
-my @options;
-push(@options, ("--up=$up", '--outdir=stdout', '--cgilink=1'));
-push(@options, $sortopt) if $sortopt;
-push(@options, $reverse) if $reverse;
-
-open(M, "-|") || exec "$mailindex", @options, $file || do {
- print "Cannot open $mailindex: $!\n";
- exit;
-};
-
-#print "cd $maildir; $mailindex @options $file\n";
-while(<M>) {
- print;
-}
-
-exit;
diff --git a/website/content/en/cgi/man-autocomplete.cgi b/website/content/en/cgi/man-autocomplete.cgi
new file mode 100755
index 0000000000..d05f1b0b23
--- /dev/null
+++ b/website/content/en/cgi/man-autocomplete.cgi
@@ -0,0 +1,209 @@
+#!/usr/local/bin/perl -T
+# Copyright (c) 2009-2023 Wolfram Schneider, https://wolfram.schneider.org
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+# man-autocomplete.cgi - autocomplete/suggestion service for FreeBSD manpages
+#
+# expected run time on a modern CPU:
+# FreeBSD Release: 12ms for perl cgi script and 5ms for GNU grep => 17ms
+# FreeBSD Release + Ports: 15ms for perl cgi script and 10ms for GNU grep => 25ms
+#
+
+use lib qw(. ../../lib);
+use MyCgiSimple;
+
+use strict;
+use warnings; # 3% slower
+
+$ENV{PATH} = "/usr/local/bin:/bin:/usr/bin";
+$ENV{'LANG'} = 'C';
+
+my $debug = 2;
+binmode( \*STDIN, ":bytes" );
+binmode( \*STDOUT, ":bytes" );
+binmode( \*STDERR, ":bytes" );
+
+sub suggestion {
+ my %args = @_;
+
+ my $database = $args{'database'};
+ my $icase = $args{'icase'};
+ my $manpath = $args{'manpath'};
+ my $query = $args{'query'};
+ my $limit = $args{'limit'};
+
+ if ( !-e $database ) {
+ warn "$!: $database\n";
+ return;
+ }
+
+ # GNU grep, ripgrep, agrep, BSD grep etc.
+ my @command = ('grep');
+
+ # read more data for prefix match <=> sub-string match
+ my $limit_factor = 8;
+
+ push @command, ( '-m', $limit * $limit_factor );
+ push @command, '-i' if $icase == 1;
+ push @command, ( '--', $query, $database );
+
+ warn join( " ", @command ), "\n" if $debug >= 2;
+ if ( !open( IN, '-|' ) ) {
+ exec @command;
+ die "@command: $! :: $?\n";
+ }
+ binmode( \*IN, ":bytes" );
+
+ my @data = ();
+ while (<IN>) {
+ chomp;
+ s,["\s/],,g;
+
+ # XXX: workaround for Firefox which ignores entries with "::" or "." inside a string
+ # Note: we have to undo this in man.cgi
+ s/::/: :/g;
+ s/\./ \./g;
+ push @data, $_;
+
+ last if scalar(@data) >= $limit * $limit_factor;
+ }
+
+ close IN;
+
+ # a sorted list, but prefix matches first
+ # e.g. 'sort(1)' is before 'alphasort(3) if you searched for 'sor'
+ my $lc_query = $icase ? lc($query) : $query;
+ my @prefix = grep { index( lc($_), $lc_query ) == 0 } @data;
+ my @non_prefix = grep { index( lc($_), $lc_query ) != 0 } @data;
+
+ # prefix first & real limit
+ @data = ( @prefix, @non_prefix );
+ @data = splice( @data, 0, $limit );
+
+ warn "data: ", join( " ", @data ), "\n" if $debug >= 2;
+ return @data;
+}
+
+sub escapeQuote {
+ my $string = shift;
+
+ $string =~ s/"/\\"/g;
+
+ return $string;
+}
+
+# create devbridge autocomplete response JSON object
+sub devbridge_autocomplete {
+ my $query = shift;
+ my $suggestion = shift;
+
+ my @suggestion = @$suggestion;
+
+ print qq/{ query:"/, escapeQuote($query), qq/", suggestions:[/;
+ print '"', join( '","', map { escapeQuote($_) } @suggestion ), '"'
+ if scalar(@suggestion) > 0;
+ print "] }\n";
+
+ warn "query '$query', suggestions: ", join ", ", @suggestion, "\n"
+ if $debug >= 1;
+}
+
+# create opensearch autocomplete response JSON object
+sub opensearch_autocomplete {
+ my $query = shift;
+ my $suggestion = shift;
+
+ my @suggestion = @$suggestion;
+
+ print '["', escapeQuote($query), '", [';
+
+ print qq{"}, join( '","', map { escapeQuote($_) } @suggestion ), qq{"}
+ if scalar(@suggestion) > 0;
+ print "]]\n";
+
+ warn "query '$query', suggestions: ", join ", ", @suggestion, "\n"
+ if $debug >= 1;
+}
+
+######################################################################
+# param alias: query, q: search query
+# manpath, m: release or release + ports
+# icase,i : case sensitive
+# debug, d: debug level
+
+my $max_suggestions = 24;
+my $database_freebsd_release =
+ '/usr/local/www/bsddoc/man/etc/autocomplete/freebsd-release.txt';
+my $database_freebsd_release_ports =
+ '/usr/local/www/bsddoc/man/etc/autocomplete/freebsd-release-ports.txt';
+
+my $q = new MyCgiSimple;
+
+my $test_street = "kurz";
+
+my $query = $q->param('query') // $q->param('q') // $test_street;
+my $manpath = $q->param('manpath') // $q->param('m') // "";
+my $d = $q->param('debug') // $q->param('d') // $debug;
+
+# we always use case insensive search for autocomplete
+my $icase = $q->param('icase') // $q->param('i') // 1;
+
+$query = ( $query =~ /^(.+)$/ ? $1 : "" );
+$manpath = ( $manpath =~ /^([a-z\-]+)$/ ? $1 : "" );
+$icase = ( $icase =~ /^([01])$/ ? $1 : 0 );
+$debug = ( $d =~ /^([0-3])$/ ? $1 : $debug );
+
+# not part of a filename
+$query =~ s,["\s'/]+,,;
+
+my $database =
+ $manpath eq 'freebsd-release-ports'
+ ? $database_freebsd_release_ports
+ : $database_freebsd_release;
+
+my $expire = $debug >= 2 ? '+1s' : '+1h';
+print $q->header(
+ -type => 'text/javascript',
+ -charset => 'utf-8',
+ -expires => $expire,
+);
+
+my @suggestion = ();
+if ( length($query) >= 2 ) {
+ @suggestion = &suggestion(
+ 'database' => $database,
+ 'limit' => $max_suggestions,
+ 'query' => $query,
+ 'icase' => $icase,
+ 'manpath' => $manpath,
+ );
+}
+
+# ns=devbridge, for jQuery devbridge plugin
+# &devbridge_autocomplete( $query, \@suggestion );
+
+# ns=opensearch (Firefox etc.)
+&opensearch_autocomplete( $query, \@suggestion );
+
+#EOF
diff --git a/website/content/en/cgi/man.cgi b/website/content/en/cgi/man.cgi
index 60c9fe795e..24c11be53b 100755
--- a/website/content/en/cgi/man.cgi
+++ b/website/content/en/cgi/man.cgi
@@ -1,6 +1,6 @@
#!/usr/local/bin/perl -T
#
-# Copyright (c) 1996-2022 Wolfram Schneider <wosch@FreeBSD.org>
+# Copyright (c) 1996-2024 Wolfram Schneider <wosch@FreeBSD.org>
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@@ -33,7 +33,6 @@
# BSDI Id: bsdi-man,v 1.2 1995/01/11 02:30:01 polk Exp
# Dual CGI/Plexus mode and new interface by sanders@bsdi.com 9/22/1995
#
-# $FreeBSD$
############################################################################
# !!! man.cgi is stale perl4 code !!!
@@ -51,14 +50,26 @@ package main;
$debug = 2;
$www{'title'} = 'FreeBSD Manual Pages';
$www{'home'} = 'https://www.FreeBSD.org';
+$www{'home_man'} = 'https://man.FreeBSD.org';
+$www{'cgi_man'} = '/cgi/man.cgi';
$www{'head'} = $www{'title'};
# set to zero if your front-end cache has low memory
my $download_streaming_caching = 0;
+# enable to download the manual pages as a tarball
+my $enable_download = 1;
+
#$command{'man'} = '/usr/bin/man'; # 8Bit clean man
$command{'man'} = '/usr/local/www/bin/man.wrapper'; # set CPU limits
+# First look in the FreeBSD base manual pages (aka /usr/share/man) and then
+# in FreeBSD ports (aka /usr/local/man). This avoids confusion when manual pages have
+# have the same name, but are in different sections. In this case, a ports manual
+# pages would win because of the higher section priority. Now, searching for "socket"
+# will always show socket(2) from the base system and not socket(1) from ports
+my $freebsd_base_manpages_first = 1;
+
# Config Options
# map sections to their man command argument(s)
%sections = (
@@ -173,9 +184,15 @@ $sectionpath = {
'OpenBSD 6.8' => { 'path' => '1:2:3:3p:4:5:6:7:8:9', },
'OpenBSD 6.9' => { 'path' => '1:2:3:3p:4:5:6:7:8:9', },
'OpenBSD 7.0' => { 'path' => '1:2:3:3p:4:5:6:7:8:9', },
+ 'OpenBSD 7.1' => { 'path' => '1:2:3:3p:4:5:6:7:8:9', },
+ 'OpenBSD 7.2' => { 'path' => '1:2:3:3p:4:5:6:7:8:9', },
+ 'OpenBSD 7.3' => { 'path' => '1:2:3:3p:4:5:6:7:8:9', },
+ 'OpenBSD 7.4' => { 'path' => '1:2:3:3p:4:5:6:7:8:9', },
+ 'OpenBSD 7.5' => { 'path' => '1:2:3:3p:4:5:6:7:8:9', },
'CentOS 3.9' => { 'path' => '1:2:3:3p:4:5:6:7:8:9:n', },
'CentOS 4.8' => { 'path' => '1:1p:2:3:3p:4:5:6:7:8:9:n:0p', },
+
'CentOS 5.3' => { 'path' => '0p:1:1p:1x:2:2x:3:3p:3x:4:4x:5:5x:6:6x:7:7x:8:8x:9:9x:l:n' },
'CentOS 5.4' => { 'path' => '0p:1:1p:1x:2:2x:3:3p:3x:4:4x:5:5x:6:6x:7:7x:8:8x:9:9x:l:n' },
'CentOS 5.5' => { 'path' => '0p:1:1p:1x:2:2x:3:3p:3x:4:4x:5:5x:6:6x:7:7x:8:8x:9:9x:l:n' },
@@ -185,6 +202,7 @@ $sectionpath = {
'CentOS 5.9' => { 'path' => '0p:1:1p:1x:2:2x:3:3p:3x:4:4x:5:5x:6:6x:7:7x:8:8x:9:9x:l:n' },
'CentOS 5.10' => { 'path' => '0p:1:1p:1x:2:2x:3:3p:3x:4:4x:5:5x:6:6x:7:7x:8:8x:9:9x:l:n' },
'CentOS 5.11' => { 'path' => '0p:1:1p:1x:2:2x:3:3p:3x:4:4x:5:5x:6:6x:7:7x:8:8x:9:9x:l:n' },
+
'CentOS 6.0' => { 'path' => '0p:1:1p:1x:2:2x:3:3p:3x:4:4x:5:5x:6:6x:7:7x:8:8x:9:9x:l:n' },
'CentOS 6.1' => { 'path' => '0p:1:1p:1x:2:2x:3:3p:3x:4:4x:5:5x:6:6x:7:7x:8:8x:9:9x:l:n' },
'CentOS 6.2' => { 'path' => '0p:1:1p:1x:2:2x:3:3p:3x:4:4x:5:5x:6:6x:7:7x:8:8x:9:9x:l:n' },
@@ -192,8 +210,33 @@ $sectionpath = {
'CentOS 6.4' => { 'path' => '0p:1:1p:1x:2:2x:3:3p:3x:4:4x:5:5x:6:6x:7:7x:8:8x:9:9x:l:n' },
'CentOS 6.5' => { 'path' => '0p:1:1p:1x:2:2x:3:3p:3x:4:4x:5:5x:6:6x:7:7x:8:8x:9:9x:l:n' },
'CentOS 6.6' => { 'path' => '0p:1:1p:1x:2:2x:3:3p:3x:4:4x:5:5x:6:6x:7:7x:8:8x:9:9x:l:n' },
+ 'CentOS 6.7' => { 'path' => '0p:1:1p:2:3:3p:3t:4:5:6:7:8:9:n' },
+ 'CentOS 6.8' => { 'path' => '0p:1:1p:2:3:3p:3t:4:5:6:7:8:9:n' },
+ 'CentOS 6.9' => { 'path' => '0p:1:1p:2:3:3p:3t:4:5:6:7:8:9:n' },
+ 'CentOS 6.10' => { 'path' => '0p:1:1p:2:3:3p:3t:4:5:6:7:8:9:n' },
+
'CentOS 7.0' => { 'path' => '0p:1:1p:1x:2:2x:3:3p:3t:3x:4:4x:5:5x:6:6x:7:7x:8:8x:9:9x:n' },
'CentOS 7.1' => { 'path' => '0p:1:1p:2:3:3p:3t:4:5:6:7:8:9:n' },
+ 'CentOS 7.2' => { 'path' => '0p:1:1p:2:3:3p:3t:4:5:6:7:8:9:n' },
+ 'CentOS 7.3' => { 'path' => '0p:1:1p:2:3:3p:3t:4:5:6:7:8:9:n' },
+ 'CentOS 7.4' => { 'path' => '0p:1:1p:2:3:3p:3t:4:5:6:7:8:9:n' },
+ 'CentOS 7.5' => { 'path' => '0p:1:1p:2:3:3p:3t:4:5:6:7:8:9:n' },
+ 'CentOS 7.6' => { 'path' => '0p:1:1p:2:3:3p:3t:4:5:6:7:8:9:n' },
+ 'CentOS 7.7' => { 'path' => '0p:1:1p:2:3:3p:3t:4:5:6:7:8:9:n' },
+ 'CentOS 7.8' => { 'path' => '0p:1:1p:2:3:3p:3t:4:5:6:7:8:9:n' },
+ 'CentOS 7.9' => { 'path' => '0p:1:1p:2:3:3p:3t:4:5:6:7:8:9:n' },
+
+ 'Rocky 9.3' => { 'path' => '0p:1:1p:2:3:3p:4:5:6:7:8:9:n', },
+ 'Rocky 9.2' => { 'path' => '0p:1:1p:2:3:3p:4:5:6:7:8:9:n', },
+ 'Rocky 9.1' => { 'path' => '0p:1:1p:2:3:3p:4:5:6:7:8:9:n', },
+ 'Rocky 9.0' => { 'path' => '0p:1:1p:2:3:3p:4:5:6:7:8:9:n', },
+ 'Rocky 8.9' => { 'path' => '0p:1:1p:2:3:3p:4:5:6:7:8:9:n', },
+ 'Rocky 8.8' => { 'path' => '0p:1:1p:2:3:3p:4:5:6:7:8:9:n', },
+ 'Rocky 8.7' => { 'path' => '0p:1:1p:2:3:3p:4:5:6:7:8:9:n', },
+ 'Rocky 8.6' => { 'path' => '0p:1:1p:2:3:3p:4:5:6:7:8:9:n', },
+ 'Rocky 8.5' => { 'path' => '0p:1:1p:2:3:3p:4:5:6:7:8:9:n', },
+ 'Rocky 8.4' => { 'path' => '0p:1:1p:2:3:3p:4:5:6:7:8:9:n', },
+ 'Rocky 8.3' => { 'path' => '0p:1:1p:2:3:3p:4:5:6:7:8:9:n', },
'SuSE 4.3' => { 'path' => '0p:1:1p:2:3:3p:4:5:6:7:8:9:n:s', },
'SuSE 5.0' => { 'path' => '0p:1:1p:2:3:3p:4:5:6:7:8:9:n:s', },
@@ -241,14 +284,24 @@ foreach my $os ( keys %$sectionpath ) {
$manLocalDir = '/usr/local/www/bsddoc/man';
# this should be the latest "release and ports"
-$manPathDefault = 'FreeBSD 13.1-RELEASE and Ports';
+$manPathDefault = 'FreeBSD 14.0-RELEASE and Ports';
%manPath = (
- # supported releases / stable / current
+ # supported RELEASES / STABLE / CURRENT
+ 'FreeBSD 14.0-RELEASE and Ports',
+"$manLocalDir/FreeBSD-14.0-RELEASE/man:$manLocalDir/FreeBSD-14.0-RELEASE/openssl/man:$manLocalDir/FreeBSD-ports-14.0-RELEASE/man:$manLocalDir/FreeBSD-ports-14.0-RELEASE/misc",
+
+ 'FreeBSD 13.3-RELEASE and Ports',
+"$manLocalDir/FreeBSD-13.3-RELEASE/man:$manLocalDir/FreeBSD-13.3-RELEASE/openssl/man:$manLocalDir/FreeBSD-ports-13.3-RELEASE/man:$manLocalDir/FreeBSD-ports-13.3-RELEASE/misc",
+ 'FreeBSD 13.2-RELEASE and Ports',
+"$manLocalDir/FreeBSD-13.2-RELEASE/man:$manLocalDir/FreeBSD-13.2-RELEASE/openssl/man:$manLocalDir/FreeBSD-ports-13.2-RELEASE/man:$manLocalDir/FreeBSD-ports-13.2-RELEASE/misc",
'FreeBSD 13.1-RELEASE and Ports',
"$manLocalDir/FreeBSD-13.1-RELEASE/man:$manLocalDir/FreeBSD-13.1-RELEASE/openssl/man:$manLocalDir/FreeBSD-ports-13.1-RELEASE/man:$manLocalDir/FreeBSD-ports-13.1-RELEASE/misc",
'FreeBSD 13.0-RELEASE and Ports',
"$manLocalDir/FreeBSD-13.0-RELEASE/man:$manLocalDir/FreeBSD-13.0-RELEASE/openssl/man:$manLocalDir/FreeBSD-ports-13.0-RELEASE/man:$manLocalDir/FreeBSD-ports-13.0-RELEASE/misc",
+
+ 'FreeBSD 12.4-RELEASE and Ports',
+"$manLocalDir/FreeBSD-12.4-RELEASE/man:$manLocalDir/FreeBSD-12.4-RELEASE/openssl/man:$manLocalDir/FreeBSD-ports-12.4-RELEASE/man:$manLocalDir/FreeBSD-ports-12.4-RELEASE/misc",
'FreeBSD 12.3-RELEASE and Ports',
"$manLocalDir/FreeBSD-12.3-RELEASE/man:$manLocalDir/FreeBSD-12.3-RELEASE/openssl/man:$manLocalDir/FreeBSD-ports-12.3-RELEASE/man:$manLocalDir/FreeBSD-ports-12.3-RELEASE/misc",
'FreeBSD 12.2-RELEASE and Ports',
@@ -256,6 +309,7 @@ $manPathDefault = 'FreeBSD 13.1-RELEASE and Ports';
'FreeBSD 12.1-RELEASE and Ports',
"$manLocalDir/FreeBSD-12.1-RELEASE/man:$manLocalDir/FreeBSD-12.1-RELEASE/openssl/man:$manLocalDir/FreeBSD-ports-12.1-RELEASE/man:$manLocalDir/FreeBSD-ports-12.1-RELEASE/misc",
'FreeBSD 12.0-RELEASE and Ports',
+
"$manLocalDir/FreeBSD-12.0-RELEASE/man:$manLocalDir/FreeBSD-12.0-RELEASE/openssl/man:$manLocalDir/FreeBSD-ports-12.0-RELEASE/man:$manLocalDir/FreeBSD-ports-12.0-RELEASE/misc",
'FreeBSD 11.4-RELEASE and Ports',
"$manLocalDir/FreeBSD-11.4-RELEASE/man:$manLocalDir/FreeBSD-11.4-RELEASE/openssl/man:$manLocalDir/FreeBSD-ports-11.4-RELEASE/man:$manLocalDir/FreeBSD-ports-11.4-RELEASE/misc",
@@ -301,18 +355,27 @@ $manPathDefault = 'FreeBSD 13.1-RELEASE and Ports';
'FreeBSD 6.4-RELEASE and Ports',
"$manLocalDir/FreeBSD-6.4-RELEASE/man:$manLocalDir/FreeBSD-6.4-RELEASE/openssl/man:$manLocalDir/FreeBSD-ports-6.2-RELEASE",
- 'FreeBSD 14.0-current',
-"$manLocalDir/FreeBSD-14.0-current/man:$manLocalDir/FreeBSD-14.0-current/openssl/man",
+ 'FreeBSD 15.0-CURRENT',
+"$manLocalDir/FreeBSD-15.0-CURRENT/man:$manLocalDir/FreeBSD-15.0-CURRENT/openssl/man",
+
+ 'FreeBSD 14.0-STABLE',
+"$manLocalDir/FreeBSD-14.0-STABLE/man:$manLocalDir/FreeBSD-14.0-STABLE/openssl/man",
+ 'FreeBSD 14.0-RELEASE',
+"$manLocalDir/FreeBSD-14.0-RELEASE/man:$manLocalDir/FreeBSD-14.0-RELEASE/openssl/man",
- 'FreeBSD 13.1-stable',
-"$manLocalDir/FreeBSD-13.1-stable/man:$manLocalDir/FreeBSD-13.1-stable/openssl/man",
+ 'FreeBSD 13.3-STABLE',
+"$manLocalDir/FreeBSD-13.3-STABLE/man:$manLocalDir/FreeBSD-13.3-STABLE/openssl/man",
+ 'FreeBSD 13.3-RELEASE',
+"$manLocalDir/FreeBSD-13.3-RELEASE/man:$manLocalDir/FreeBSD-13.3-RELEASE/openssl/man",
+ 'FreeBSD 13.2-RELEASE',
+"$manLocalDir/FreeBSD-13.2-RELEASE/man:$manLocalDir/FreeBSD-13.2-RELEASE/openssl/man",
'FreeBSD 13.1-RELEASE',
"$manLocalDir/FreeBSD-13.1-RELEASE/man:$manLocalDir/FreeBSD-13.1-RELEASE/openssl/man",
'FreeBSD 13.0-RELEASE',
"$manLocalDir/FreeBSD-13.0-RELEASE/man:$manLocalDir/FreeBSD-13.0-RELEASE/openssl/man",
- 'FreeBSD 12.3-stable',
-"$manLocalDir/FreeBSD-12.3-stable/man:$manLocalDir/FreeBSD-12.3-stable/openssl/man",
+ 'FreeBSD 12.4-RELEASE',
+"$manLocalDir/FreeBSD-12.4-RELEASE/man:$manLocalDir/FreeBSD-12.4-RELEASE/openssl/man",
'FreeBSD 12.3-RELEASE',
"$manLocalDir/FreeBSD-12.3-RELEASE/man:$manLocalDir/FreeBSD-12.3-RELEASE/openssl/man",
'FreeBSD 12.2-RELEASE',
@@ -322,8 +385,6 @@ $manPathDefault = 'FreeBSD 13.1-RELEASE and Ports';
'FreeBSD 12.0-RELEASE',
"$manLocalDir/FreeBSD-12.0-RELEASE/man:$manLocalDir/FreeBSD-12.0-RELEASE/openssl/man",
- 'FreeBSD 11.4-stable',
-"$manLocalDir/FreeBSD-11.4-stable/man:$manLocalDir/FreeBSD-11.4-stable/openssl/man",
'FreeBSD 11.4-RELEASE',
"$manLocalDir/FreeBSD-11.4-RELEASE/man:$manLocalDir/FreeBSD-11.4-RELEASE/openssl/man",
'FreeBSD 11.3-RELEASE',
@@ -334,9 +395,6 @@ $manPathDefault = 'FreeBSD 13.1-RELEASE and Ports';
"$manLocalDir/FreeBSD-11.1-RELEASE/man:$manLocalDir/FreeBSD-11.1-RELEASE/openssl/man",
'FreeBSD 11.0-RELEASE',
"$manLocalDir/FreeBSD-11.0-RELEASE/man:$manLocalDir/FreeBSD-11.0-RELEASE/openssl/man",
-
- 'FreeBSD 10.4-stable',
-"$manLocalDir/FreeBSD-10.4-stable/man:$manLocalDir/FreeBSD-10.4-stable/openssl/man",
'FreeBSD 10.4-RELEASE',
"$manLocalDir/FreeBSD-10.4-RELEASE/man:$manLocalDir/FreeBSD-10.4-RELEASE/openssl/man",
'FreeBSD 10.3-RELEASE',
@@ -424,8 +482,12 @@ $manPathDefault = 'FreeBSD 13.1-RELEASE and Ports';
'FreeBSD Ports 12.1', "$manLocalDir/FreeBSD-ports-12.1-RELEASE/man:$manLocalDir/FreeBSD-ports-12.1-RELEASE/misc",
'FreeBSD Ports 12.2', "$manLocalDir/FreeBSD-ports-12.2-RELEASE/man:$manLocalDir/FreeBSD-ports-12.2-RELEASE/misc",
'FreeBSD Ports 12.3', "$manLocalDir/FreeBSD-ports-12.3-RELEASE/man:$manLocalDir/FreeBSD-ports-12.3-RELEASE/misc",
+ 'FreeBSD Ports 12.4', "$manLocalDir/FreeBSD-ports-12.4-RELEASE/man:$manLocalDir/FreeBSD-ports-12.4-RELEASE/misc",
'FreeBSD Ports 13.0', "$manLocalDir/FreeBSD-ports-13.0-RELEASE/man:$manLocalDir/FreeBSD-ports-13.0-RELEASE/misc",
'FreeBSD Ports 13.1', "$manLocalDir/FreeBSD-ports-13.1-RELEASE/man:$manLocalDir/FreeBSD-ports-13.1-RELEASE/misc",
+ 'FreeBSD Ports 13.2', "$manLocalDir/FreeBSD-ports-13.2-RELEASE/man:$manLocalDir/FreeBSD-ports-13.2-RELEASE/misc",
+ 'FreeBSD Ports 13.3', "$manLocalDir/FreeBSD-ports-13.3-RELEASE/man:$manLocalDir/FreeBSD-ports-13.3-RELEASE/misc",
+ 'FreeBSD Ports 14.0', "$manLocalDir/FreeBSD-ports-14.0-RELEASE/man:$manLocalDir/FreeBSD-ports-14.0-RELEASE/misc",
# FreeBSD Releases + Ports
@@ -458,9 +520,6 @@ $manPathDefault = 'FreeBSD 13.1-RELEASE and Ports';
'FreeBSD 8.3-RELEASE and Ports', "$manLocalDir/FreeBSD-8.3-RELEASE/man:$manLocalDir/FreeBSD-8.3-RELEASE/openssl/man:$manLocalDir/FreeBSD-ports-8.3-RELEASE/man:$manLocalDir/FreeBSD-ports-8.3-RELEASE/misc",
'FreeBSD 9.1-RELEASE and Ports', "$manLocalDir/FreeBSD-9.1-RELEASE/man:$manLocalDir/FreeBSD-9.1-RELEASE/openssl/man:$manLocalDir/FreeBSD-ports-9.1-RELEASE/man:$manLocalDir/FreeBSD-ports-9.1-RELEASE/misc",
-
- 'FreeBSD 7.4-stable',
-"$manLocalDir/FreeBSD-7.4-RELEASE/man:$manLocalDir/FreeBSD-7.4-RELEASE/openssl/man",
'FreeBSD 7.4-RELEASE',
"$manLocalDir/FreeBSD-7.4-RELEASE/man:$manLocalDir/FreeBSD-7.4-RELEASE/openssl/man",
@@ -597,6 +656,11 @@ $manPathDefault = 'FreeBSD 13.1-RELEASE and Ports';
'OpenBSD 6.8', "$manLocalDir/OpenBSD-6.8",
'OpenBSD 6.9', "$manLocalDir/OpenBSD-6.9",
'OpenBSD 7.0', "$manLocalDir/OpenBSD-7.0",
+ 'OpenBSD 7.1', "$manLocalDir/OpenBSD-7.1",
+ 'OpenBSD 7.2', "$manLocalDir/OpenBSD-7.2",
+ 'OpenBSD 7.3', "$manLocalDir/OpenBSD-7.3",
+ 'OpenBSD 7.4', "$manLocalDir/OpenBSD-7.4",
+ 'OpenBSD 7.5', "$manLocalDir/OpenBSD-7.5",
#'NetBSD 0.9', "$manLocalDir/NetBSD-0.9",
'NetBSD 1.0', "$manLocalDir/NetBSD-1.0",
@@ -637,6 +701,8 @@ $manPathDefault = 'FreeBSD 13.1-RELEASE and Ports';
'NetBSD 9.0', "$manLocalDir/NetBSD-9.0",
'NetBSD 9.1', "$manLocalDir/NetBSD-9.1",
'NetBSD 9.2', "$manLocalDir/NetBSD-9.2",
+ 'NetBSD 9.3', "$manLocalDir/NetBSD-9.3",
+ 'NetBSD 10.0', "$manLocalDir/NetBSD-10.0",
'2.8 BSD', "$manLocalDir/2.8BSD",
'2.9.1 BSD', "$manLocalDir/2.9.1BSD",
@@ -663,6 +729,7 @@ $manPathDefault = 'FreeBSD 13.1-RELEASE and Ports';
'CentOS 3.9', "$manLocalDir/CentOS-3.9",
'CentOS 4.8', "$manLocalDir/CentOS-4.8",
+
'CentOS 5.4', "$manLocalDir/CentOS-5.4",
'CentOS 5.5', "$manLocalDir/CentOS-5.5",
'CentOS 5.6', "$manLocalDir/CentOS-5.6",
@@ -671,6 +738,7 @@ $manPathDefault = 'FreeBSD 13.1-RELEASE and Ports';
'CentOS 5.9', "$manLocalDir/CentOS-5.9",
'CentOS 5.10', "$manLocalDir/CentOS-5.10",
'CentOS 5.11', "$manLocalDir/CentOS-5.11",
+
'CentOS 6.0', "$manLocalDir/CentOS-6.0",
'CentOS 6.1', "$manLocalDir/CentOS-6.1",
'CentOS 6.2', "$manLocalDir/CentOS-6.2",
@@ -678,8 +746,33 @@ $manPathDefault = 'FreeBSD 13.1-RELEASE and Ports';
'CentOS 6.4', "$manLocalDir/CentOS-6.4",
'CentOS 6.5', "$manLocalDir/CentOS-6.5",
'CentOS 6.6', "$manLocalDir/CentOS-6.6",
+ 'CentOS 6.7', "$manLocalDir/CentOS-6.7",
+ 'CentOS 6.8', "$manLocalDir/CentOS-6.8",
+ 'CentOS 6.9', "$manLocalDir/CentOS-6.9",
+ 'CentOS 6.10', "$manLocalDir/CentOS-6.10",
+
'CentOS 7.0', "$manLocalDir/CentOS-7.0",
'CentOS 7.1', "$manLocalDir/CentOS-7.1",
+ 'CentOS 7.2', "$manLocalDir/CentOS-7.2",
+ 'CentOS 7.3', "$manLocalDir/CentOS-7.3",
+ 'CentOS 7.4', "$manLocalDir/CentOS-7.4",
+ 'CentOS 7.5', "$manLocalDir/CentOS-7.5",
+ 'CentOS 7.6', "$manLocalDir/CentOS-7.6",
+ 'CentOS 7.7', "$manLocalDir/CentOS-7.7",
+ 'CentOS 7.8', "$manLocalDir/CentOS-7.8",
+ 'CentOS 7.9', "$manLocalDir/CentOS-7.9",
+
+ 'Rocky 9.3', "$manLocalDir/Rocky-9.3",
+ 'Rocky 9.2', "$manLocalDir/Rocky-9.2",
+ 'Rocky 9.1', "$manLocalDir/Rocky-9.1",
+ 'Rocky 9.0', "$manLocalDir/Rocky-9.0",
+ 'Rocky 8.9', "$manLocalDir/Rocky-8.9",
+ 'Rocky 8.8', "$manLocalDir/Rocky-8.8",
+ 'Rocky 8.7', "$manLocalDir/Rocky-8.7",
+ 'Rocky 8.6', "$manLocalDir/Rocky-8.6",
+ 'Rocky 8.5', "$manLocalDir/Rocky-8.5",
+ 'Rocky 8.4', "$manLocalDir/Rocky-8.4",
+ 'Rocky 8.3', "$manLocalDir/Rocky-8.3",
'SuSE 4.3', "$manLocalDir/SuSE-4.3-i386",
'SuSE 5.0', "$manLocalDir/SuSE-5.0-i386",
@@ -709,13 +802,36 @@ $manPathDefault = 'FreeBSD 13.1-RELEASE and Ports';
'SuSE ES 10 SP1', "$manLocalDir/SLES-10-SP1-i386",
+ 'Debian 2.0.0', "$manLocalDir/Debian-2.0r0/man:$manLocalDir/Debian-2.0r0/misc",
'Debian 2.2.7', "$manLocalDir/Debian-2.2r7/man:$manLocalDir/Debian-2.2r7/misc",
'Debian 3.1.8', "$manLocalDir/Debian-31r8/man:$manLocalDir/Debian-31r8/misc",
'Debian 4.0.9', "$manLocalDir/Debian-40r9/man:$manLocalDir/Debian-40r9/misc",
- 'Debian 5.0.10', "$manLocalDir/Debian-5.0.10/man:$manLocalDir/Debian-5.0.10/misc",
+ 'Debian 5.0.10', "$manLocalDir/Debian-5010/man:$manLocalDir/Debian-5010/misc",
'Debian 6.0.10', "$manLocalDir/Debian-6.0.10/man:$manLocalDir/Debian-6.0.10/misc",
- 'Debian 7.8.0', "$manLocalDir/Debian-7.8.0/man:$manLocalDir/Debian-7.8.0/misc",
- 'Debian 8.1.0', "$manLocalDir/Debian-8.1.0/man:$manLocalDir/Debian-8.1.0/misc",
+ 'Debian 7.11.0', "$manLocalDir/Debian-7.11.0/man:$manLocalDir/Debian-7.11.0/misc",
+ 'Debian 8.11.1', "$manLocalDir/Debian-8.11.1/man:$manLocalDir/Debian-8.11.1/misc",
+ 'Debian 9.13.0', "$manLocalDir/Debian-9.13.0/man:$manLocalDir/Debian-9.13.0/misc",
+ 'Debian 10.13.0', "$manLocalDir/Debian-10.13.0/man:$manLocalDir/Debian-10.13.0/misc",
+ 'Debian 11.9.0', "$manLocalDir/Debian-11.9.0/man:$manLocalDir/Debian-11.9.0/misc",
+ 'Debian 12.5.0', "$manLocalDir/Debian-12.5.0/man:$manLocalDir/Debian-12.5.0/misc",
+ 'Debian 13.0 unstable', "$manLocalDir/Debian-unstable/man:$manLocalDir/Debian-unstable/misc",
+
+ 'Ubuntu 23.10 mantic', "$manLocalDir/Ubuntu-mantic-23.10/man:$manLocalDir/Ubuntu-mantic-23.10/misc",
+
+ 'Ubuntu 24.04 noble', "$manLocalDir/Ubuntu-noble-24.04/man:$manLocalDir/Ubuntu-noble-24.04/misc",
+ 'Ubuntu 22.04 jammy', "$manLocalDir/Ubuntu-jammy-22.04/man:$manLocalDir/Ubuntu-jammy-22.04/misc",
+ 'Ubuntu 20.04 focal', "$manLocalDir/Ubuntu-focal-20.04/man:$manLocalDir/Ubuntu-focal-20.04/misc",
+ 'Ubuntu 18.04 bionic', "$manLocalDir/Ubuntu-bionic-18.04/man:$manLocalDir/Ubuntu-bionic-18.04/misc",
+ 'Ubuntu 16.04 xenial', "$manLocalDir/Ubuntu-xenial-16.04/man:$manLocalDir/Ubuntu-xenial-16.04/misc",
+ 'Ubuntu 14.04 trusty', "$manLocalDir/Ubuntu-trusty-14.04/man:$manLocalDir/Ubuntu-trusty-14.04/misc",
+
+ 'DragonFly 6.4.0', "$manLocalDir/DragonFly-6.4.0",
+ 'DragonFly 5.8.3', "$manLocalDir/DragonFly-5.8.3",
+ 'DragonFly 4.8.1', "$manLocalDir/DragonFly-4.8.1",
+ 'DragonFly 3.8.2', "$manLocalDir/DragonFly-3.8.2",
+ 'DragonFly 2.10.1', "$manLocalDir/DragonFly-2.10.1",
+ 'DragonFly 1.12.1', "$manLocalDir/DragonFly-1.12.1",
+ 'DragonFly 1.0A', "$manLocalDir/DragonFly-1.0A",
'HP-UX 11.22', "$manLocalDir/HP-UX-11.22",
'HP-UX 11.20', "$manLocalDir/HP-UX-11.20",
@@ -742,6 +858,10 @@ $manPathDefault = 'FreeBSD 13.1-RELEASE and Ports';
# alias SunOS 0.4, apparently released in April 1983 based on 4.2BSD beta
'Sun UNIX 0.4', "$manLocalDir/Sun-UNIX-0.4",
+ 'macOS 14.3.1', "$manLocalDir/macOS-14.3.1/man:$manLocalDir/macOS-14.3.1/developer-man:$manLocalDir/macOS-14.3.1/developer-platform-man:$manLocalDir/macOS-14.3.1/developer-platform-sdk-man:$manLocalDir/macOS-14.3.1/xctoolchain-man",
+ 'macOS 13.6.5', "$manLocalDir/macOS-13.6.5/man:$manLocalDir/macOS-13.6.5/developer-man:$manLocalDir/macOS-13.6.5/developer-platform-man:$manLocalDir/macOS-13.6.5/developer-platform-sdk-man:$manLocalDir/macOS-13.6.5/xctoolchain-man",
+ 'macOS 12.7.3', "$manLocalDir/macOS-12.7.3/man:$manLocalDir/macOS-12.7.3/developer-man:$manLocalDir/macOS-12.7.3/developer-platform-man:$manLocalDir/macOS-12.7.3/developer-platform-sdk-man:$manLocalDir/macOS-12.7.3/xctoolchain-man",
+ 'macOS 10.13.6', "$manLocalDir/macOS-10.13.6",
#'XFree86 3.2', "$manLocalDir/XFree86-3.2",
'XFree86 2.1', "$manLocalDir/XFree86-2.1",
@@ -775,7 +895,14 @@ $manPathDefault = 'FreeBSD 13.1-RELEASE and Ports';
'Inferno 4th Edition', "$manLocalDir/Inferno",
'Plan 9', "$manLocalDir/plan9",
- 'Minix 2.0', "$manLocalDir/Minix-2.0",
+ 'Minix 2.0.0', "$manLocalDir/Minix-2.0.0",
+ 'Minix 3.1.5', "$manLocalDir/Minix-3.1.5",
+ 'Minix 3.1.6', "$manLocalDir/Minix-3.1.6",
+ 'Minix 3.1.7', "$manLocalDir/Minix-3.1.7",
+ 'Minix 3.1.7', "$manLocalDir/Minix-3.1.8",
+ 'Minix 3.2.0', "$manLocalDir/Minix-3.2.0",
+ 'Minix 3.2.1', "$manLocalDir/Minix-3.2.1",
+ 'Minix 3.3.0', "$manLocalDir/Minix-3.3.0",
'Unix Seventh Edition', "$manLocalDir/v7man",
"Darwin 1.3.1/x86", "$manLocalDir/Darwin-1.3.1-x86",
@@ -878,6 +1005,8 @@ my %arch = (
'NetBSD 9.0' => { 'arch' => [qw/acorn26 acorn32 algor alpha amd64 amiga arc atari bebox cats cesfic cobalt dreamcast emips evbarm evbmips evbppc evbsh3 hp300 hpcarm hpcmips hpcsh hppa i386 ibmnws luna68k mac68k macppc mipsco mmeye mvme68k mvmeppc netwinder news68k newsmips next68k ofppc playstation2 pmax prep sandpoint sbmips sgimips shark sparc sparc64 sun2 sun3 vax x68k x86/] } ,
'NetBSD 9.1' => { 'arch' => [qw/acorn26 acorn32 algor alpha amd64 amiga arc atari bebox cats cesfic cobalt dreamcast emips evbarm evbmips evbppc evbsh3 hp300 hpcarm hpcmips hpcsh hppa i386 ibmnws luna68k mac68k macppc mipsco mmeye mvme68k mvmeppc netwinder news68k newsmips next68k ofppc playstation2 pmax prep sandpoint sbmips sgimips shark sparc sparc64 sun2 sun3 vax x68k x86/] } ,
'NetBSD 9.2' => { 'arch' => [qw/acorn26 acorn32 algor alpha amd64 amiga arc atari bebox cats cesfic cobalt dreamcast emips evbarm evbmips evbppc evbsh3 hp300 hpcarm hpcmips hpcsh hppa i386 ibmnws luna68k mac68k macppc mipsco mmeye mvme68k mvmeppc netwinder news68k newsmips next68k ofppc playstation2 pmax prep sandpoint sbmips sgimips shark sparc sparc64 sun2 sun3 vax x68k x86/] } ,
+'NetBSD 9.3' => { 'arch' => [qw/acorn26 acorn32 algor alpha amd64 amiga arc atari bebox cats cesfic cobalt dreamcast emips evbarm evbmips evbppc evbsh3 hp300 hpcarm hpcmips hpcsh hppa i386 ibmnws luna68k mac68k macppc mipsco mmeye mvme68k mvmeppc netwinder news68k newsmips next68k ofppc playstation2 pmax prep sandpoint sbmips sgimips shark sparc sparc64 sun2 sun3 vax x68k x86/] } ,
+'NetBSD 10.0' => { 'arch' => [qw/acorn26 acorn32 algor alpha amd64 amiga arc atari bebox cats cesfic cobalt dreamcast emips evbarm evbmips evbppc evbsh3 hp300 hpcarm hpcmips hpcsh hppa i386 ibmnws luna68k mac68k macppc mipsco mmeye mvme68k mvmeppc netwinder news68k newsmips next68k ofppc playstation2 pmax prep sandpoint sbmips sgimips shark sparc sparc64 sun2 sun3 vax x68k x86/] } ,
'OpenBSD 4.7' => { 'arch' => [qw/alpha amd64 armish aviion hp300 hppa hppa64 i386 landisk loongson luna88k mac68k macppc mvme68k mvme88k mvmeppc palm sgi socppc sparc sparc64 vax zaurus/] },
'OpenBSD 4.8' => { 'arch' => [qw/alpha amd64 armish aviion hp300 hppa hppa64 i386 landisk loongson luna88k mac68k macppc mvme68k mvme88k mvmeppc palm sgi socppc sparc sparc64 vax zaurus/] },
'OpenBSD 4.9' => { 'arch' => [qw/alpha amd64 armish aviion hp300 hppa hppa64 i386 landisk loongson luna88k mac68k macppc mvme68k mvme88k mvmeppc palm sgi socppc sparc sparc64 vax zaurus/] },
@@ -902,6 +1031,11 @@ my %arch = (
'OpenBSD 6.8' => { 'arch' => [qw/alpha amd64 arm64 armv7 hppa i386 landisk loongson luna88k macppc octeon powerpc64 sgi sparc64/] },
'OpenBSD 6.9' => { 'arch' => [qw/alpha amd64 arm64 armv7 hppa i386 landisk loongson luna88k macppc octeon powerpc64 sgi sparc64/] },
'OpenBSD 7.0' => { 'arch' => [qw/alpha amd64 arm64 armv7 hppa i386 landisk loongson luna88k macppc octeon powerpc64 riscv64 sparc64/] },
+'OpenBSD 7.1' => { 'arch' => [qw/alpha amd64 arm64 armv7 hppa i386 landisk loongson luna88k macppc octeon powerpc64 riscv64 sparc64/] },
+'OpenBSD 7.2' => { 'arch' => [qw/alpha amd64 arm64 armv7 hppa i386 landisk loongson luna88k macppc octeon powerpc64 riscv64 sparc64/] },
+'OpenBSD 7.3' => { 'arch' => [qw/alpha amd64 arm64 armv7 hppa i386 landisk loongson luna88k macppc octeon powerpc64 riscv64 sparc64/] },
+'OpenBSD 7.4' => { 'arch' => [qw/alpha amd64 arm64 armv7 hppa i386 landisk loongson luna88k macppc octeon powerpc64 riscv64 sparc64/] },
+'OpenBSD 7.5' => { 'arch' => [qw/alpha amd64 arm64 armv7 hppa i386 landisk loongson luna88k macppc octeon powerpc64 riscv64 sparc64/] },
);
# delete not existing releases
@@ -922,30 +1056,32 @@ while ( ( $key, $val ) = each %manPath ) {
# keywords must be in lower cases.
%manPathAliases = (
- 'freebsd', 'FreeBSD 13.1-RELEASE',
- 'freebsd-release', 'FreeBSD 13.1-RELEASE',
+ 'freebsd', 'FreeBSD 14.0-RELEASE',
+ 'freebsd-release', 'FreeBSD 14.0-RELEASE',
- 'freebsd-stable', 'FreeBSD 13.1-stable',
- 'freebsd-stable13', 'FreeBSD 13.1-stable',
- 'freebsd-stable12', 'FreeBSD 12.3-stable',
- 'freebsd-stable11', 'FreeBSD 11.4-stable',
+ 'freebsd-stable', 'FreeBSD 14.0-STABLE',
+ 'freebsd-stable14', 'FreeBSD 14.0-STABLE',
+ 'freebsd-stable13', 'FreeBSD 13.3-STABLE',
- 'freebsd-current', 'FreeBSD 14.0-current',
- 'freebsd-release-ports', 'FreeBSD 13.1-RELEASE and Ports',
- 'freebsd-ports', 'FreeBSD Ports 13.1',
+ 'freebsd-current', 'FreeBSD 15.0-CURRENT',
+ 'freebsd-release-ports', 'FreeBSD 14.0-RELEASE and Ports',
+ 'freebsd-ports', 'FreeBSD Ports 14.0',
'slackware', 'Linux Slackware 3.1',
'redhat', 'Red Hat 9',
'suse', 'SuSE 11.3',
- 'debian', 'Debian 7.7.0',
- 'centos', 'CentOS 7.1',
- 'linux', 'Debian 7.7.0',
+ 'debian', 'Debian 12.5.0',
+ 'ubuntu', 'Ubuntu 24.04 noble',
+ 'dragonfly', 'DragonFly 6.4.0',
+ 'centos', 'CentOS 7.9',
+ 'rocky', 'Rocky 9.3',
+ 'linux', 'Debian 12.5.0',
'darwin', 'Darwin 8.0.1/ppc',
'opendarwin', 'OpenDarwin 7.2.1',
'macosx', 'Darwin 8.0.1/ppc',
- 'netbsd', 'NetBSD 9.2',
- 'openbsd', 'OpenBSD 7.0',
+ 'netbsd', 'NetBSD 10.0',
+ 'openbsd', 'OpenBSD 7.5',
'v7', 'Unix Seventh Edition',
'v7man', 'Unix Seventh Edition',
'x11', 'X11R7.4',
@@ -957,13 +1093,39 @@ while ( ( $key, $val ) = each %manPath ) {
'sunos5', 'SunOS 5.10',
'sunos4', 'SunOS 4.1.3',
'sunos', 'SunOS 4.1.3',
- 'freebsd ports', 'FreeBSD Ports',
- 'ports', 'FreeBSD Ports',
+ 'macos', 'macOS 14.3.1',
'plan9', 'Plan 9',
'osf1', 'OSF1 V5.1/alpha',
'true64', 'OSF1 V5.1/alpha',
+ 'minix', 'Minix 3.3.0',
);
+# pre-build a hash to get relevant information for sorting
+my $sort_manpath_hash;
+sub sort_manpath {
+ my $manpath = shift;
+ my @list = keys %$manpath;
+
+ $sort_manpath_hash = {};
+ foreach my $name (@list) {
+ my $name_lc = lc($name);
+ my $os_lc;
+
+ # a release has at least 2 numbers seperated by a dot:
+ # FreeBSD 11.1-RELEASE ports
+ # X11R7.4
+ my ($os, $version, $ports) = ( $name =~ m,^(.*?)(\d+\.[\d\.]+)(.*)$, );
+ $os //= $name;
+ $os_lc = lc($os);
+ $version //= "0.0";
+ $ports //= "";
+
+ $sort_manpath_hash->{$name} = { 'os' => $os, 'os_lc' => $os_lc, 'version' => $version, 'ports' => $ports };
+ }
+
+ return sort { &sort_versions } keys %$manpath;
+}
+
#
# sort by OS release number, highest version first
#
@@ -979,24 +1141,17 @@ while ( ( $key, $val ) = each %manPath ) {
# XFree86 10.0
#
sub sort_versions {
-
- # a release has at least 2 numbers seperated by a dot:
- # FreeBSD 11.1-RELEASE ports
- # X11R7.4
- my @a = ( lc($a) =~ m,^(.*?)(\d+\.[\d\.]+)(.*)$, );
- my @b = ( lc($b) =~ m,^(.*?)(\d+\.[\d\.]+)(.*)$, );
-
- if (@a and @b) {
- return $a[0] cmp $b[0] || # FreeBDS <=> IRIX
- &version($a[1], $b[1]) || # 6.5.30 <=> 6.5.31
- $a[2] cmp $a[2] || # RELEASE <=> ports
- $a cmp $b; # rest
- } else {
- # for the rest: basic string compare
- return $a cmp $b;
- }
+ my $h = $sort_manpath_hash;
+
+ return
+ $h->{$a}->{'os_lc'} cmp $h->{$b}->{'os_lc'} || # freebsd <=> irix
+ $h->{$a}->{'os'} cmp $h->{$b}->{'os'} || # FreeBSD <=> freebsd
+ &version($h->{$a}->{'version'}, $h->{$b}->{'version'}) || # 6.5.30 <=> 6.5.31
+ $h->{$a}->{'ports'} cmp $h->{$b}->{'ports'} || # RELEASE <=> ports (release first)
+ $a cmp $b; # for the rest: basic string compare
}
+# reverse order, newest release first
sub version {
return &version_compare(@_) * -1;
}
@@ -1037,7 +1192,7 @@ sub freebsd_first {
return @data;
}
-foreach ( sort { &sort_versions } keys %manPathAliases ) {
+foreach ( &sort_manpath(\%manPathAliases) ) {
# delete non-existing aliases
if ( !defined( $manPath{ $manPathAliases{$_} } ) ) {
@@ -1062,7 +1217,7 @@ $sections = join( "|", @sections ); # sections regexp
$mailto = 'wosch@FreeBSD.org';
$mailtoURL = 'https://wolfram.schneider.org';
$mailtoURL = "mailto:$mailto" if !$mailtoURL;
-$full_url = 'https://www.freebsd.org/cgi/man.cgi';
+$full_url = 'https://man.freebsd.org/cgi/man.cgi';
$want_to_link_to_this_page = 1;
&secure_env;
@@ -1085,9 +1240,10 @@ my $enable_intro = 0;
sub html_footer {
my %args = @_;
- print
-qq{<span class="footer_links"><a href="$BASE?manpath=$m">home</a> | <a href="$BASE/help.html">help</a></span>\n}
- if !$args{'no_home_link'};
+ print qq[<span class="footer_links">\n];
+ print qq[ <a href="$www{'cgi_man'}">home</a>\n] if !$args{'no_home_link'};
+ print qq[| <a href="$www{'cgi_man'}/help.html">help</a>\n] if !$args{'no_help_link'};
+ print qq[</span>\n\n];
if (cgi_style::HAS_FREEBSD_CGI_STYLE) {
print q{<hr noshade="noshade" />};
@@ -1104,26 +1260,29 @@ sub html_header {
my $html_meta = q|
<meta name="robots" content="nofollow" />
<meta content="text/html; charset=iso-8859-1" http-equiv="Content-Type" />
-<link rel="search" type="application/opensearchdescription+xml" href="https://www.freebsd.org/opensearch/man.xml" title="FreeBSD Manual Pages" />
-<link rel="search" type="application/opensearchdescription+xml" href="https://www.freebsd.org/opensearch/man-freebsd-release-ports.xml" title="FreeBSD + Ports Manual Pages" />
+<link rel="search" type="application/opensearchdescription+xml" href="https://www.freebsd.org/opensearch/man.xml" title="FreeBSD Man" />
+<link rel="search" type="application/opensearchdescription+xml" href="https://www.freebsd.org/opensearch/man-freebsd-release-ports.xml" title="FreeBSD Man+P" />
+
<style type="text/css">
-<!--
-b { color: #996600; }
-i { color: #008000; }
--->
span.footer_links { font-size: small; }
span.space { font-size: xx-small; }
form#man > input, form#man > button { font-size: large; }
form#man > input[name='query'] { text-align: center; }
@media only screen and (max-height: 640px), (max-width: 760px) {
-div#header, div#menu { display: none !important; }
-div#content { padding-top: 4.9em; }
-form#man > input, button { font-size: 200%; }
-form#man > button { font-size: 200%; }
-form#man > input[name='query'] { width: 12em; }
-form#man > select { font-size: 140%; }
-span.spaces { display: none; }
+ /* hide logo color top */
+ body { background: #fff !important; }
+
+ /* hide menu top */
+ div#header, div#menu { display: none !important; }
+ // div#content { padding-top: 4.9em; }
+ span.spaces { display: none; }
+
+ /* larger search form */
+ form#man > input, button { font-size: 200%; }
+ form#man > button { font-size: 200%; }
+ form#man > input[name='query'] { width: 12em; }
+ form#man > select { font-size: 140%; }
}
</style>
|;
@@ -1176,6 +1335,18 @@ sub do_man {
$form{'query'} =~ s/\s+$//;
$form{'query'} =~ s/^\s+//;
+ # not supported query characters
+ $form{'query'} =~ s/"//g;
+ $form{'query'} =~ s/=//g;
+
+ # Firefox opensearch autocomplete workaround
+ if ($form{'sourceid'} eq 'opensearch') {
+ # remove space between double colon
+ $form{'query'} =~ s/: :/::/g;
+ # remove space before a dot
+ $form{'query'} =~ s/ \./\./g;
+ }
+
$name = $query = $form{'query'};
$section = $form{'sektion'};
$apropos = $form{'apropos'};
@@ -1234,7 +1405,7 @@ sub do_man {
}
else { $section = ''; }
- $apropos ? &apropos($query) : &man( $name, $section, $arch );
+ $apropos ? &apropos($query, $section) : &man( $name, $section, $arch );
}
# --------------------- support routines ------------------------
@@ -1257,9 +1428,11 @@ sub get_the_sources {
# download a manual directory as gzip'd tar archive
sub download {
+ if (!$enable_download) {
# 2019-05-31: allanjude: Disable downloading as it is being abused.
print qq{Status: 418 No Downloads For You\n\n};
exit(0);
+ }
$| = 1;
my $filename = $manpath;
@@ -1308,7 +1481,7 @@ sub http_header {
sub env { defined( $main'ENV{ $_[0] } ) ? $main'ENV{ $_[0] } : undef; }
sub apropos {
- local ($query) = @_;
+ local ($query, $sektion) = @_;
local ( $_, $title, $head, *APROPOS );
local ( $names, $section, $msg, $key );
local ($prefix);
@@ -1326,7 +1499,9 @@ sub apropos {
&http_header("text/html");
print &html_header("Apropos $title");
- print "<h1>", $www{'head'}, "</h1>\n\n";
+ print "<br/>\n<h1>$www{'head'}</h1>\n\n";
+
+ $section = $sektion;
&formquery;
local ($mpath) = $manPath{$manpath};
@@ -1351,6 +1526,8 @@ sub apropos {
print qq{<dl>\n};
while (<APROPOS>) {
next if !/$q/oi;
+ next if $sektion && !/\($sektion\)/oi;
+
$acounter++;
# matches whatis.db lines: name[, name ...] (sect) - msg
@@ -1390,6 +1567,18 @@ sub to_filename {
return $filename;
}
+# strip ports manual pages from path
+sub manpath_without_ports {
+ my $path = shift;
+
+ my @list;
+ foreach my $p (split(/:/, $path)) {
+ push @list, $p if $p !~ /-ports-/;
+ }
+
+ return join(":", @list);
+}
+
sub man {
local ( $name, $section, $arch ) = @_;
local ( $_, $title, $head, *MAN );
@@ -1418,7 +1607,7 @@ sub man {
if ( $format eq "html" ) {
&http_header("text/html");
print &html_header("$title");
- print "<h1>", $www{'head'}, "</h1>\n\n";
+ print "<br/>\n<h1>$www{'head'}</h1>\n\n";
&formquery;
print "<pre>\n";
}
@@ -1456,8 +1645,6 @@ sub man {
$html_name = &encode_data($name);
$html_section = &encode_data($section);
- #print Dumper($sectionpath);
- #print "yy $section yy $manpath\n";
if ( $name =~ /^\s*$/ ) {
print "</pre><hr/>";
print "Empty input. Please type a manual page and search again.\n";
@@ -1497,13 +1684,15 @@ sub man {
}
@manargs = split( / /, $section );
+ my $manpath_m = "";
+
if ($manpath) {
if ( $manPath{$manpath} ) {
- unshift( @manargs, ( '-M', $manPath{$manpath} ) );
+ $manpath_m = $manPath{$manpath};
&groff_path( $manPath{$manpath} );
}
elsif ( $manpath{ &dec($manpath) } ) {
- unshift( @manargs, ( '-M', $manPath{ &dec($manpath) } ) );
+ $manpath_m = $manPath{ &dec($manpath) };
&groff_path( $manPath{ &dec($manpath) } );
}
else {
@@ -1519,12 +1708,31 @@ sub man {
push( @manargs, '-t' );
}
- warn "X $command{'man'} @manargs -- x $name x\n" if $debug >= 3;
push( @manargs, ( "-m", $arch ) ) if $arch;
- &proc( *MAN, $command{'man'}, @manargs, "--", $name )
- || &mydie("$0: open of $command{'man'} command failed: $!\n");
+ # search first for base manual pages, and maybe later in ports
+ if ($freebsd_base_manpages_first && $section eq "" && $manpath =~ m/ and Ports$/) {
+ warn "search for base pages first: $name\n" if $debug >= 2;
+ my @m = ("-M", &manpath_without_ports($manpath_m));
+ warn "X $command{'man'} @m @manargs -- x $name x\n" if $debug >= 3;
+ &proc( *MAN, $command{'man'}, @m, @manargs, "--", $name )
+ || &mydie("$0: open of $command{'man'} command failed: $!\n");
+
+ if ( eof(MAN) ) {
+ warn "search for ports pages as well: $name\n" if $debug >= 2;
+ @m = ("-M", $manpath_m);
+ warn "X $command{'man'} @m @manargs -- x $name x\n" if $debug >= 3;
+ &proc( *MAN, $command{'man'}, @m, @manargs, "--", $name )
+ || &mydie("$0: open of $command{'man'} command failed: $!\n");
+ }
+ } else {
+ my @m = $manpath_m ? ("-M", $manpath_m) : ();
+ warn "X $command{'man'} @m @manargs -- x $name x\n" if $debug >= 3;
+ &proc( *MAN, $command{'man'}, @m, @manargs, "--", $name )
+ || &mydie("$0: open of $command{'man'} command failed: $!\n");
+ }
+
if ( eof(MAN) ) {
if ( $format eq "ascii" ) {
print "Sorry, no data found for '$html_name'\n";
@@ -1803,6 +2011,9 @@ sub encode_data {
s/\</\&lt\;/g;
s/\>/\&gt\;/g;
+ # bold bullet
+ s,\+\010\+\010o\010o,<b>o</b>,g;
+
# underline: _^H.^H(.)
s,((_\010[^_]\010.)+),($str = $1) =~ s/_\010..//g; "<I>$str</I>";,ge;
@@ -1820,8 +2031,9 @@ sub encode_data {
sub indexpage {
&http_header("text/html");
- print &html_header("$www{'title'}") . "<h1><br/>", $www{'head'},
- "</h1>\n\n";
+ print &html_header("$www{'title'}");
+ print "<br/>\n<h1>$www{'head'}</h1>\n\n";
+
# print &intro;
&formquery;
@@ -1867,7 +2079,7 @@ ETX
if ($enable_section_indexes || $enable_intro) {
print "<br />\n";
}
- &html_footer( 'no_home_link' => 1 );
+ &html_footer( 'no_home_link' => 1, 'no_help_link' => 1 );
}
sub formquery {
@@ -1904,7 +2116,7 @@ ETX
print qq{</select>\n<select name="manpath">\n};
local ($l) = ( $manpath ? $manpath : $manPathDefault );
- foreach ( &freebsd_first( sort { &sort_versions } keys %manPath) ) {
+ foreach ( &freebsd_first( &sort_manpath(\%manPath)) ) {
$key = $_;
print "<option"
. ( ( $key eq $l ) ? ' selected="selected" ' : ' ' )
@@ -1958,84 +2170,72 @@ ETX
</form>
<br/>
-<span class="footer_links"><a href="$BASE?manpath=$m">home</a> | <a href="$BASE/help.html">help</a></span>
+<span class="footer_links">
+ <a href="$www{'cgi_man'}">home</a> |
+ <a href="$www{'cgi_man'}/help.html">help</a>
+</span>
ETX
if ($query) {
print "<hr/>\n";
}
- 0;
}
sub faq {
local ( @list, @list2 );
local ($url);
- foreach ( &freebsd_first (sort { &sort_versions } keys %manPath )) {
+ foreach ( &freebsd_first (&sort_manpath(\%manPath) )) {
$url = &encode_url($_);
- push( @list,
- qq{<li><a href="$BASE?apropos=2&amp;manpath=$url">[download]}
- . qq{</a> "$_" -> $BASE?manpath=$url}
- . qq{</li>\n} );
+ my $download_link = $enable_download ? qq[<a href="/cgi/man.cgi?apropos=2&amp;manpath=$url">tarball</a>] : '';
+ push( @list, qq{<li>$_: <a href="$BASE?manpath=$url">permalink</a> | $download_link</li>\n} );
}
- foreach ( &freebsd_first (sort { &sort_versions } keys %manPathAliases )) {
+ foreach ( &freebsd_first (&sort_manpath(\%manPathAliases) )) {
+ next if !$manPathAliases{$_};
+
+ my $encode_url = &encode_url($_);
push( @list2,
- qq[<li>"$_" -> "$manPathAliases{$_}" -> ]
- . qq{<a href="$BASE?manpath=}
- . &encode_url($_)
- . qq{">$BASE?manpath=}
- . &encode_url($_)
- . "</a></li>\n" )
- if $manPathAliases{$_};
+ qq[<li>"$_" -> "$manPathAliases{$_}" -> ] .
+ qq[<a href="$www{'home_man'}/cgi/man.cgi?manpath=$encode_url">$www{'home_man'}/cgi/man.cgi?manpath=$encode_url</a></li>\n] )
}
return qq{\
+<h2>Copyright</h2>
<pre>
-Copyright (c) 1996-2022 <a href="$mailtoURL">Wolfram Schneider</a>
+Copyright (c) 1996-2024 <a href="$mailtoURL">Wolfram Schneider</a>
Copyright (c) 1993-1995 Berkeley Software Design, Inc.
+</pre>
+<p/>
-This data is part of a licensed program from BERKELEY SOFTWARE
-DESIGN, INC. Portions are copyrighted by BSDI, The Regents of
-the University of California, Massachusetts Institute of
-Technology, Free Software Foundation, The FreeBSD Project, and others.
-
-</pre>\n
-<p />
-
-Copyright (c) for man pages by OS vendors.
+Copyright (c) for manual pages by OS vendors:
<p/>
-<a href="ftp://ftp.2bsd.com">2.11 BSD</a>,
+<a href="https://en.wikipedia.org/wiki/History_of_the_Berkeley_Software_Distribution">2.11 BSD</a>,
<a href="https://www.apple.com">Apple</a>,
-<a href="https://www.hp.com">HP</a>,
+<a href="https://www.centos.org">CentOS</a>,
+<a href="https://www.debian.org">Debian</a>,
+<a href="https://www.dragonflybsd.org">DragonFly BSD</a>,
<a href="https://www.freebsd.org">FreeBSD</a>,
-<a href="http://www.minix3.org">Minix</a>,
+<a href="https://www.hp.com">HP</a>,
+<a href="https://en.wikipedia.org/wiki/IRIX">IRIX</a>,
+<a href="https://www.minix3.org">Minix</a>,
<a href="https://www.netbsd.org">NetBSD</a>,
+<a href="https://en.wikipedia.org/wiki/NeXTSTEP">NeXTSTEP</a>,
<a href="https://www.openbsd.org">OpenBSD</a>,
<a href="https://9p.io/plan9/">Plan 9</a>,
<a href="https://www.redhat.com">Red Hat</a>,
-<a href="https://www.slackware.com">Slackware Linux</a>,
-<a href="https://www.sun.com">SunOS</a>,
+<a href="https://www.slackware.com">Slackware</a>,
+<a href="https://en.wikipedia.org/wiki/OSF/1">OSF</a>,
+<a href="https://9p.io/plan9/">Plan 9</a>,
+<a href="https://en.wikipedia.org/wiki/Rhapsody_(operating_system)">Rhapsody</a>,
+<a href="https://www.oracle.com/solaris/technologies/">SunOS</a>,
+<a href="https://rockylinux.org/">Rocky</a>,
<a href="https://www.suse.com">SuSE</a>,
+<a href="https://ubuntu.com">Ubuntu</a>,
<a href="https://en.wikipedia.org/wiki/Ultrix">ULTRIX</a>,
-<a href="http://www.plan9.bell-labs.com/7thEdMan/">Unix Seventh Edition</a>,
+<a href="https://en.wikipedia.org/wiki/Version_7_Unix">Unix Seventh Edition</a>,
<a href="https://www.xfree86.org">XFree86</a>,
<a href="https://www.x.org">X11R6</a>
-<h2>FAQ</h2>
-<ul>
-<li>Get the <a href="$BASE/source">source</a> of the man.cgi script</li>
-<li>Troff macros works only if defined in FreeBSD/groff. OS specific
-macros like `appeared in NetBSD version 1.2' are not supported.</li>
-<li>Some OSs provide only formatted manual pages (catpages), e.g., NetBSD
-and OpenBSD. In this case it is not possible to create Postscript
-and troff output.</li>
-<li>The <a href="https://cgit.freebsd.org/src/tree/share/misc/bsd-family-tree">
-Unix family tree, BSD part</a>.</li>
-<li>The <a href="https://www.freebsd.org/cgi/ports.cgi">
-FreeBSD Ports Changes</a> script.</li>
-<li>Copyright (c) and download for man pages by
-OS vendors</li>
-</ul>
<h2>Shortcuts for FreeBSD manual pages</h2>
@@ -2047,30 +2247,55 @@ OS vendors</li>
<p />
<ul>
-<li>which manpage: <a href="$BASE?which">$full_url?which</a></li>
-<li>socket(2) manpage: <a href="$BASE?socket(2)">$full_url?socket(2)</a></li>
+<li>which manpage: <a href="$full_url?which">$full_url?which</a></li>
+<li>socket(2) manpage: <a href="$full_url?socket(2)">$full_url?socket(2)</a></li>
</ul>
-<h2>Releases</h2>
+<h2>Release Permalinks and tarballs</h2>
-Releases and Releases Aliases are information how
+<p>
+Releases and releases aliases permalinks are information how
to make a link to this script to the right OS version.
-<p />
-You may download the manpages as gzip'd tar archive
-for private use. A tarball is usually 5MB big.
-<p />
+</p>
+
+<p>
+You may download the manual pages as gzip'd tar archive for private or educational purposes.
+A tarball is normally 5-25 MB in size.
+</p>
+
<ul>
@list
</ul>
-<h2>Releases Aliases</h2>
+
+<h2>Releases Aliases Permalinks</h2>
+
+<p>
Release aliases are for lazy people. Plus, they have a longer
-lifetime, eg. 'openbsd' points always to the latest OpenBSD release.
+lifetime, eg. 'netbsd' points always to the latest NetBSD release.
+</p>
+
<ul>
@list2
</ul>
+
+<h2>FAQ</h2>
+
+<ul>
+<li>Get the <a href="$BASE/source">source</a> of the man.cgi script</li>
+<li>Troff macros works only if defined in FreeBSD/groff. OS specific
+macros like `appeared in NetBSD version 1.2' are not supported.</li>
+<li>Some OSs provide only formatted manual pages (catpages), e.g.,
+older NetBSD and OpenBSD releases. In this case it is not possible to create Postscript
+and troff output.</li>
+<li>The <a href="https://cgit.freebsd.org/src/tree/share/misc/bsd-family-tree">
+Unix family tree, BSD part</a>.</li>
+<li>The <a href="https://ports.freebsd.org/cgi/ports.cgi">
+FreeBSD Ports Search</a> script.</li>
+</ul>
};
+
}
sub intro {
@@ -2089,14 +2314,11 @@ sections.
}
sub faq_output {
- my $base = $BASE;
- $base =~ s,[^/]*$,,;
- $base = 'https://www.freebsd.org/cgi/'; # XXX
-
&http_header("text/html");
- print &html_header( "FreeBSD manual page help", $base ) . "<h1>",
- $www{'head'}, "</h1>\n" . &faq . qq{<br />\n};
- &html_footer;
+ print &html_header( "FreeBSD manual page help", '/cgi/' );
+ print "<br/>\n<h1>$www{'head'}</h1>\n";
+ print &faq . "<br/>\n";
+ &html_footer('no_help_link' => 1);
}
sub html_header2 {
@@ -2139,10 +2361,6 @@ sub mydie {
print &html_header("Error");
print $message;
- print qq{
-<p />
-<a href="$BASE">home</a>
-};
&html_footer;
exit(0);
}
diff --git a/website/content/en/cgi/mid.cgi b/website/content/en/cgi/mid.cgi
deleted file mode 100755
index 3971bf5b84..0000000000
--- a/website/content/en/cgi/mid.cgi
+++ /dev/null
@@ -1,161 +0,0 @@
-#!/usr/bin/perl -T
-#
-# Copyright (c) March 1998-2021 Wolfram Schneider <wosch@FreeBSD.org>. Berlin.
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions
-# are met:
-# 1. Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# 2. Redistributions in binary form must reproduce the above copyright
-# notice, this list of conditions and the following disclaimer in the
-# documentation and/or other materials provided with the distribution.
-#
-# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
-# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-# SUCH DAMAGE.
-#
-# Search a mail by Message-ID, References or In-Reply-To field
-#
-# $FreeBSD$
-
-require "./cgi-lib.pl";
-require "./cgi-style.pl";
-
-$home = '/usr/local/www/mailindex';
-$prefix= "/usr/local/www/mailindex/archive";
-$lookupdir = "$home/message-id"; # database(s) directory
-$databaseDefault = 'mid'; # default database
-$script = $ENV{'SCRIPT_NAME'};
-$shortid = 1;
-$lookCommand = "/usr/bin/look";
-$ENV{PATH} = '/bin:/usr/bin';
-
-$main::t_style .= qq{\n<link rel="search" type="application/opensearchdescription+xml" href="https://www.freebsd.org/opensearch/message-id.xml" title="FreeBSD Mail Message-ID" />\n};
-
-sub escape($) { $_ = $_[0]; s/&/&amp;/g; s/</&lt;/g; s/>/&gt;/g; $_; }
-
-sub get_id {
- local($query, $db) = @_;
-
- open(DB, "-|") ||
- exec("$lookCommand", $query, "$lookupdir/mid-current.$db") ||
- do {
- print &midheader .
- "<p>Cannot connect to Message-ID database.</p>\n" . &foot;
- exit;
- };
-
- local(@idlist);
- while(<DB>) {
- push(@idlist, $_);
- }
- close DB;
- #warn "$lookCommand $query, $lookupdir/mid.$db";
- open(DB, "-|") ||
- exec("$lookCommand", $query, "$lookupdir/mid.$db") ||
- do {
- print &midheader .
- "<p>Cannot connect to Message-ID database.</p>\n" . &foot;
- exit;
- };
-
- while(<DB>) {
- push(@idlist, $_);
- }
- close DB;
-
-
- if ($#idlist < 0) { # nothing found
- print &midheader;
- if ($db eq 'mid') {
- printf "Message-ID: \"%s\" not found\n", escape($query);
- } else {
- printf "No answers found for: \"%s\"\n", escape($query);
- }
- print &foot;
-
- } elsif ($#idlist == 0) { # one hit
- local($location) = $ENV{'SCRIPT_NAME'};
- local($id, $file, $start) = split($", $idlist[0]);
- $location =~ s%/[^/]+$%%;
- local($host) = $ENV{'HTTP_HOST'};
- $location = '//' . $host . $location;
- $start =~ s/\s+$//;
-
- print "Location: $location/getmsg.cgi?fetch=$start+0+" .
- ($file =~ /^current/ ? '' : "$prefix/") . "$file\n";
- print "Content-type: text/plain\n\n";
- exit;
-
- } else { # more than one hit
- local($id, $file, $start, $name);
- print &midheader;
- print "<ul>\n";
- foreach (@idlist) {
- ($id, $file, $start) = split;
- $name = $file;
- $name =~ s%.*/%%;
- $name =~ s%(....)(..)(..)\.%$1-$2-$3 %;
- print qq{<li><a href="getmsg.cgi?fetch=$start+0+} .
- ($file =~ /^current/ ? '' : "$prefix/") .
- qq{$file">$name $start</a></li>\n};
- }
- print "</ul>\n<p></p>\n";
- print &foot;
- }
-}
-
-sub midheader {
- return &short_html_header("FreeBSD Message-ID Mail Archives") .
- qq{<p><a href="$hsty_base/search/">Back to the search interface</a></p>\n};
-}
-
-sub foot { return &html_footer; }
-
-###
-# Main
-###
-
-&ReadParse(*input);
-$messageid = $input{'id'};
-$database = $input{'db'};
-
-
-if (!$messageid) {
- # for lazy people ;-)
- # allow the syntax mid.cgi?messageid
- if ($ENV{'QUERY_STRING'} =~ /<?[a-z0-9._>\-]+\S+$/) {
- $messageid = $ENV{'QUERY_STRING'};
- $database = $databaseDefault;
- }
-
- # no message-id given
- else {
- print &midheader;
- print "No input given\n";
- print &foot; exit;
- }
-}
-
-$messageid =~ s/^<//;
-$messageid =~ s/>$//;
-$messageid =~ s/@.*// if $shortid;
-($messageid) = $messageid =~ m|^(\S+)$|; # XXX: can be more strict...
-
-if ($database =~ m/^(mid|irt)$/) {
- $database = $1;
-} else {
- $database = $databaseDefault;
-}
-
-&get_id($messageid, $database);
diff --git a/website/content/en/cgi/mirror.cgi b/website/content/en/cgi/mirror.cgi
deleted file mode 100755
index 43bfd38ea6..0000000000
--- a/website/content/en/cgi/mirror.cgi
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/usr/bin/perl -T
-# (c) 1996-2011 Wolfram Schneider. Public domain.
-#
-# FreeBSD WWW mirror redirect
-#
-# $FreeBSD$
-
-use CGI;
-use strict;
-use warnings;
-
-my $debug = 1;
-my $master_url = 'https://www.freebsd.org/';
-
-my $q = new CGI;
-my $url = $q->param('goto') || "";
-
-if ( $url =~ m,^http://[a-z0-9\.]+\.freebsd\.org/?$,i
- || $url =~ m,^http://[a-z0-9\.]+\.freebsd\.org/www\.FreeBSD\.org/(data)?$,i
- || $url =~ m,^http://(freebsd\.unixtech\.be|www\.gufi\.org/mirrors/www.freebsd.org/data)/$,i
- )
-{
- # ok
-}
-
-else {
- warn "Ignore illegal redirect URL: $url\n" if $debug;
- $url = $master_url;
-}
-
-print $q->redirect($url);
-
diff --git a/website/content/en/cgi/ports-autocomplete.cgi b/website/content/en/cgi/ports-autocomplete.cgi
new file mode 100755
index 0000000000..438b1f3fbc
--- /dev/null
+++ b/website/content/en/cgi/ports-autocomplete.cgi
@@ -0,0 +1,219 @@
+#!/usr/local/bin/perl -T
+# Copyright (c) 2009-2023 Wolfram Schneider, https://wolfram.schneider.org
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+# ports-autocomplete.cgi - autocomplete/suggestion service for FreeBSD ports
+#
+# For the OpenSearch protocol, please read https://en.wikipedia.org/wiki/OpenSearch
+#
+# expected run time on a modern CPU: ca. 16ms (10ms for perl, 6ms for GNU grep)
+
+use lib qw(. ../../lib);
+use MyCgiSimple;
+
+use strict;
+use warnings; # 3% slower
+
+$ENV{PATH} = "/usr/local/bin:/bin:/usr/bin";
+$ENV{'LANG'} = 'C';
+
+my $debug = 0;
+binmode( \*STDIN, ":bytes" );
+binmode( \*STDOUT, ":bytes" );
+binmode( \*STDERR, ":bytes" );
+
+sub suggestion {
+ my %args = @_;
+
+ my $database = $args{'database'};
+ my $icase = $args{'icase'};
+ my $stype = $args{'stype'};
+ my $query = $args{'query'};
+ my $limit = $args{'limit'};
+
+ if ( !-e $database ) {
+ warn "$!: $database\n";
+ return;
+ }
+
+ # GNU grep, ripgrep, agrep, BSD grep etc.
+ my @command = ('grep');
+
+ # read more data for prefix match <=> sub-string match
+ my $limit_factor = 8;
+
+ push @command, ( '-m', $limit * $limit_factor );
+ push @command, '-i' if $icase == 1;
+ push @command, ( '--', $query, $database );
+
+ warn join( " ", @command ), "\n" if $debug >= 2;
+ if ( !open( IN, '-|' ) ) {
+ exec @command;
+ die "@command: $! :: $?\n";
+ }
+ binmode( \*IN, ":bytes" );
+
+ my @data = ();
+ while (<IN>) {
+ chomp;
+ s,["],,g;
+
+# XXX: workaround for Firefox which ignores entries with "::" or "." inside a string
+# Note: we have to undo this in ports.cgi
+ s/::/: :/g;
+ s/\./ \./g;
+ push @data, $_;
+
+ last if scalar(@data) >= $limit * $limit_factor;
+ }
+
+ close IN;
+
+ # a sorted list, but prefix matches first
+ # e.g. 'sort(1)' is before 'alphasort(3) if you searched for 'sor'
+ my $lc_query = $icase ? lc($query) : $query;
+ my @prefix = grep { index( lc($_), $lc_query ) == 0 } @data;
+ my @non_prefix = grep { index( lc($_), $lc_query ) != 0 } @data;
+
+ # prefix first & real limit
+ @data = ( @prefix, @non_prefix );
+ @data = splice( @data, 0, $limit );
+
+ warn "data: ", join( " ", @data ), "\n" if $debug >= 2;
+ return @data;
+}
+
+sub escapeQuote {
+ my $string = shift;
+
+ $string =~ s/"/\\"/g;
+
+ return $string;
+}
+
+# create devbridge autocomplete response JSON object
+sub devbridge_autocomplete {
+ my $query = shift;
+ my $suggestion = shift;
+
+ my @suggestion = @$suggestion;
+
+ print qq/{ query:"/, escapeQuote($query), qq/", suggestions:[/;
+ print '"', join( '","', map { escapeQuote($_) } @suggestion ), '"'
+ if scalar(@suggestion) > 0;
+ print "] }\n";
+
+ warn "query '$query', suggestions: ", join ", ", @suggestion, "\n"
+ if $debug >= 1;
+}
+
+# create opensearch autocomplete response JSON object
+sub opensearch_autocomplete {
+ my $query = shift;
+ my $suggestion = shift;
+
+ my @suggestion = @$suggestion;
+
+ print '["', escapeQuote($query), '", [';
+
+ print qq{"}, join( '","', map { escapeQuote($_) } @suggestion ), qq{"}
+ if scalar(@suggestion) > 0;
+ print "]]\n";
+
+ warn "query '$query', suggestions: ", join ", ", @suggestion, "\n"
+ if $debug >= 1;
+}
+
+sub check_query {
+ my $query = shift;
+
+ # XXX: Firefox opensearch autocomplete workarounds
+ # remove space before a dot
+ $query =~ s/ \././g;
+
+ # remove space between double colon
+ $query =~ s/: :/::/g;
+
+ return $query;
+}
+
+######################################################################
+# param alias: query, q: search query
+# stype, s: name or name + description
+# icase,i : case sensitive
+# debug, d: debug level
+
+my $max_suggestions = 24;
+my $database_name = '/usr/local/www/ports/etc/autocomplete/autocomplete-name.txt';
+my $database_description = '/usr/local/www/ports/etc/autocomplete/autocomplete-description.txt';
+
+my $q = new MyCgiSimple;
+
+my $test_query = "bbbike";
+
+my $query = $q->param('query') // $q->param('q') // $test_query;
+my $stype = $q->param('stype') // $q->param('s') // "";
+my $d = $q->param('debug') // $q->param('d') // $debug;
+
+# we always use case insensive search for autocomplete
+my $icase = $q->param('icase') // $q->param('i') // 1;
+
+$query = ( $query =~ /^(.+)$/ ? $1 : "" );
+$stype = ( $stype =~ /^([a-z\-]+)$/ ? $1 : "" );
+$icase = ( $icase =~ /^([01])$/ ? $1 : 0 );
+$debug = ( $d =~ /^([0-3])$/ ? $1 : $debug );
+
+my $database =
+ $stype eq 'name'
+ ? $database_name
+ : $database_description;
+
+my $expire = $debug >= 2 ? '+1s' : '+1h';
+print $q->header(
+ -type => 'text/javascript',
+ -charset => 'utf-8',
+ -expires => $expire,
+);
+
+my $query_original = $query;
+$query = &check_query($query);
+
+my @suggestion = ();
+if ( length($query) >= 2 ) {
+ @suggestion = &suggestion(
+ 'database' => $database,
+ 'limit' => $max_suggestions,
+ 'query' => $query,
+ 'icase' => $icase,
+ 'stype' => $stype,
+ );
+}
+
+# ns=devbridge, for jQuery devbridge plugin
+# &devbridge_autocomplete( $query, \@suggestion );
+
+# ns=opensearch (Firefox etc.)
+&opensearch_autocomplete( $query_original, \@suggestion );
+
+#EOF
diff --git a/website/content/en/cgi/ports.cgi b/website/content/en/cgi/ports.cgi
index fd5b8962c4..0b2588d24a 100755
--- a/website/content/en/cgi/ports.cgi
+++ b/website/content/en/cgi/ports.cgi
@@ -1,6 +1,6 @@
#!/usr/bin/perl -T
#
-# Copyright (c) 1996-2022 Wolfram Schneider <wosch@FreeBSD.ORG>
+# Copyright (c) 1996-2024 Wolfram Schneider <wosch@FreeBSD.ORG>
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@@ -24,21 +24,32 @@
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
-# $FreeBSD$
-#
# ports.cgi - search engine for FreeBSD ports
-# o search for a port by name or description
use POSIX qw(strftime);
use Time::Local;
require "./cgi-style.pl";
-$t_style = qq`<style type="text/css">
+$t_style = qq`
+<style type="text/css">
h3 { font-size: 1.2em; border-bottom: thin solid black; }
+span.footer_links { font-size: small; }
+
+form#ports > input[name='query'] { text-align: center; }
+form#ports > input[name='query'] { width: 14em; }
+form#ports > input, form#ports > button, form#ports > select { font-size: large; }
</style>
+
<link rel="search" type="application/opensearchdescription+xml" href="https://www.freebsd.org/opensearch/ports.xml" title="FreeBSD Ports" />
`;
+# No unlimited result set. A HTML page with 1000 results can be 10MB big.
+my $max_hits = 1000;
+my $max_hits_default = 250;
+my $max;
+
+my $debug = 1;
+
sub init_variables {
$localPrefix = '/usr/ports'; # ports prefix
@@ -46,11 +57,11 @@ sub init_variables {
$portsDatabaseHeadDir = "/usr/local/www/ports";
# Ports database file to use
- if ( -f "$portsDatabaseHeadDir/INDEX-13" ) {
- $ports_database = 'INDEX-13';
+ if ( -f "$portsDatabaseHeadDir/INDEX-14" ) {
+ $ports_database = 'INDEX-14';
}
- elsif ( -f "$portsDatabaseHeadDir/INDEX-12" ) {
- $ports_database = 'INDEX-12';
+ elsif ( -f "$portsDatabaseHeadDir/INDEX-13" ) {
+ $ports_database = 'INDEX-13';
}
else {
$ports_database = 'INDEX';
@@ -59,66 +70,9 @@ sub init_variables {
# URL of ports tree for browsing
$remotePrefixFtp = 'ports';
- # 'ftp://ftp.FreeBSD.org/pub/FreeBSD/branches/-current/ports';
-
- # where to get -current packages
- local ($p) = 'ftp://ftp.FreeBSD.org/pub/FreeBSD/ports/i386';
- local ($palpha) = 'ftp://ftp.FreeBSD.org/pub/FreeBSD/ports/alpha';
- local ($pamd64) = 'ftp://ftp.FreeBSD.org/pub/FreeBSD/ports/amd64';
- local ($pia64) = 'ftp://ftp.FreeBSD.org/pub/FreeBSD/ports/ia64';
- local ($psparc64) = 'ftp://ftp.FreeBSD.org/pub/FreeBSD/ports/sparc64';
-
- $remotePrefixFtpPackagesDefault = '6-STABLE/i386';
-
- # This is currently unused
- %remotePrefixFtpPackages = (
- '7-CURRENT/i386', "$p/packages-7-current/All",
- '6-STABLE/i386', " $p/packages-6-stable/All",
- '5-STABLE/i386', " $p/packages-5-stable/All",
- '4-STABLE/i386', " $p/packages-4-stable/All",
-
- '6.0-RELEASE/i386', "$p/packages-6.0-release/All",
- '5.4-RELEASE/i386', "$p/packages-5.4-release/All",
- '4.11-RELEASE/i386', "$p/packages-4.11-release/All",
-
- '4-STABLE/alpha', "$palpha/packages-4-stable/All",
-
- '5.4-RELEASE/alpha', "$palpha/packages-5.4-release/All",
- '4.11-RELEASE/alpha', "$palpha/packages-4.11-release/All",
-
- '7-CURRENT/amd64', "$pamd64/packages-7-current/All",
- '6-STABLE/amd64', "$pamd64/packages-6-stable/All",
- '5-STABLE/amd64', "$pamd64/packages-5-stable/All",
-
- '6.0-RELEASE/amd64', "$pamd64/packages-6.0-release/All",
- '5.4-RELEASE/amd64', "$pamd64/packages-5.4-release/All",
-
- '7-CURRENT/ia64', "$pia64/packages-7-current/All",
- '6-STABLE/ia64', "$pia64/packages-6-stable/All",
-
- '6.0-RELEASE/ia64', "$pia64/packages-6.0-release/All",
- '5.4-RELEASE/ia64', "$pia64/packages-5.4-release/All",
-
- '7-CURRENT/sparc64', "$psparc64/packages-7-current/All",
- '6-STABLE/sparc64', "$psparc64/packages-6-stable/All",
- '5-STABLE/sparc64', "$psparc64/packages-5-stable/All",
-
- '6.0-RELEASE/sparc64', "$psparc64/packages-6.0-release/All",
- '5.4-RELEASE/sparc64', "$psparc64/packages-5.4-release/All",
- );
-
- $remotePrefixHtml = "$hsty_base/ports";
-
# Web interface for the Ports tree
$remotePrefixRepo = 'https://cgit.FreeBSD.org/ports';
- # Ports documentation
- $portsDesc = "$hsty_base/ports/";
-
- # location of the tiny BSD daemon
- $daemonGif =
-"<img src='$hsty_base/gifs/littlelogo.gif' alt='Really small BSD Daemon'>";
-
# visible E-Mail address, plain text
$mailto = 'www@FreeBSD.org';
@@ -133,13 +87,6 @@ sub init_variables {
# security
$ENV{'PATH'} = '/bin:/usr/bin';
-
- # extension type for packages
- $packageExt = 'tbz';
-
- local ($packageDB) = '../ports/packages.exists';
- &packages_exist( $packageDB, *packages ) if -f $packageDB;
-
}
sub packages_exist {
@@ -176,7 +123,7 @@ sub last_update {
}
sub last_update_message {
- return "<p>Last database update: " . &last_update . "</p>\n";
+ return "<p>Last database update: @{[ &last_update ]}</p>\n";
}
sub dec {
@@ -244,7 +191,7 @@ sub readindex {
chop;
@tmp = split(/\|/);
- $var{"$tmp[1]"} = $_;
+ $var{"$tmp[0]"} = $_;
@s = split( /\s+/, $tmp[6] );
foreach (@s) {
$msec{"$tmp[1],$_"} = 1;
@@ -324,7 +271,6 @@ sub out {
}
$counter++;
- $pathDownload = $path;
$pathB = $path;
$pathB =~ s/^$localPrefix/ports/o;
@@ -346,12 +292,6 @@ sub out {
print qq[<a href="$descfile?revision=HEAD">Description</a> <b>:</b>\n];
- # Link package in "default" arch/release. Verify it's existence on ftp-master.
- if ( $packages{"$version.$packageExt"} ) {
- print
-qq[<a href="$remotePrefixFtpPackages{$remotePrefixFtpPackagesDefault}/$version.$packageExt">Package</a> <b>:</b>\n];
- }
-
print qq[<a href="$l">Changes</a> <br />\n];
print qq{<i>Maintained by:</i> <a href="mailto:$email}
@@ -404,6 +344,7 @@ sub search_ports {
foreach $key ( sort keys %today ) {
next if $today{$key} !~ /$query/oi;
+ next if $counter >= $max;
@a = split( /\|/, $today{$key} );
$name = $a[0]; #$name =~ s/(\W)/\\$1/g;
@@ -439,8 +380,7 @@ sub search_ports {
sub forms {
print qq{<p>
-FreeBSD Ports [short description <a href="$portsDesc">followed</a> ...]
-<a href="$script_name?stype=faq">FAQ</a>
+The FreeBSD Ports and Packages Collection offers a simple way for users and administrators to install applications.
</p>
};
@@ -451,9 +391,9 @@ FreeBSD Ports [short description <a href="$portsDesc">followed</a> ...]
description about the port.
</p>
-<form method="get" action="$script_name">
+<form id="ports" method="get" action="$script_name">
Search for:
-<input name="query" value="$query" type="text" autocapitalize="none" />
+<input name="query" value="$query" type="text" autocapitalize="none" autofocus />
<select name="stype">
};
@@ -484,9 +424,11 @@ Search for:
. qq{value="$_">$_</option>\n};
}
- print q{</select>
+ print qq{</select>
<input type="submit" value="Submit" />
</form>
+<br/>
+@{[ &footer_links ]}
<hr noshade="noshade" />
};
@@ -494,17 +436,38 @@ Search for:
sub footer {
- print qq{
-<img align="right" src="$hsty_base/gifs/powerlogo.gif" alt="Powered by FreeBSD" />
-&copy; 1996-2022 by Wolfram Schneider. All rights reserved.<br />
-};
+print <<EOF;
+<span class="footer_links">
+ <img align="right" src="$hsty_base/gifs/powerlogo.gif" alt="Powered by FreeBSD"/>
+ &copy; 1996-2024 by Wolfram Schneider. All rights reserved.<br/>
-#print q{$FreeBSD$} . "<br />\n";
- print qq{General questions about FreeBSD ports should be sent to }
- . qq{<a href="mailto:$mailtoList">}
- . qq{<i>$mailtoList</i></a><br />\n};
- print &last_update_message;
- print qq{<hr noshade="noshade" />\n<p />\n};
+ General questions about FreeBSD ports should be sent to
+ <a href="mailto:$mailtoList"><i>$mailtoList</i></a><br/>
+
+ @{[ &last_update_message ]}
+</span>
+<hr noshade="noshade" />
+<p/>
+
+EOF
+}
+
+sub check_query {
+ my ($query, $sourceid) = @_;
+
+ $query =~ s/"/ /g;
+ $query =~ s/^\s+//;
+ $query =~ s/\s+$//;
+
+ # XXX: Firefox opensearch autocomplete workarounds
+ if ($sourceid eq 'opensearch') {
+ # remove space before a dot
+ $query =~ s/ \././g;
+ # remove space between double colon
+ $query =~ s/: :/::/g;
+ }
+
+ return $query;
}
sub check_input {
@@ -521,41 +484,65 @@ sub check_input {
)
{
&warn(
-"unknown search type ``$type'', use `all', `text', `name', 'requires', or `maintainer'\n"
+"unknown search type ``$stype'', use `all', `text', `name', 'requires', or `maintainer'\n"
);
&exit(0);
}
- else {
- return;
- }
+ }
+
+ $max = int($max);
+ if ($max <= 0 || $max > $max_hits) {
+ warn "reset max=$max to $max_hits_default\n";
+ $max = $max_hits_default;
}
}
sub faq {
- print qq{<H1>FreeBSD Ports Search FAQ</h1>
+ print <<EOF
+<br/>
+<h1>FreeBSD Ports Search Help</h1>
<h2>Keywords</h2>
<dl>
-<dt><b>Description</b><dd>A more detailed description.
-<dt><b>Changes</b><dd>Read the latest changes.
-</dl>
+ <dt><b>Description</b></dt>
+ <dd>A more detailed description (text).</dd>
-<h2>Misc</h2>
+ <dt><b>Changes</b></dt>
+ <dd>Read the latest changes via the git repo</dd>
+</dl>
+<h2>Documentation</h2>
<p>
-The script ports.cgi use the file
-<a href="$hsty_base/ports/$ports_database.xz">$ports_database</a>
-as database for it's operations. $ports_database is updated automatically every
-two hours.</p>
+Handbook: <a href="https://docs.freebsd.org/en/books/handbook/ports/#ports-using">Using the Ports Collection</a>
+</p>
<p>
You may also search the
-<a href="https://www.FreeBSD.org/cgi/man.cgi?manpath=FreeBSD+Ports">ports manual pages</a>.</p>
+<a href="https://man.FreeBSD.org/cgi/man.cgi?manpath=freebsd-ports">ports manual pages</a>.
+</p>
+
+<h2>Updates</h2>
<p>
-<a href="$script_name">Back to the search engine</a></p>
+The script ports.cgi use the file
+<a href="https://download.FreeBSD.org/ports/index/$ports_database.xz">$ports_database</a>
+as database for its operations. $ports_database is updated automatically every
+two hours.
+</p>
+
+
+@{[ &footer_links ]}
<hr noshade="noshade" />
-};
+EOF
+}
+
+sub footer_links {
+ return <<EOF;
+<span class="footer_links">
+ <a href="$script_name">home</a>
+ @{[ $stype eq "faq" ? "" : qq, | <a href="$script_name?stype=faq">help</a>, ]}
+</span>
+EOF
}
#
@@ -571,7 +558,9 @@ $section = $form{'sektion'};
$section = 'all' if ( !$section );
$query = $form{'query'};
$stype = $form{'stype'};
+$sourceid = $form{'sourceid'} // "";
$script_name = &env('SCRIPT_NAME');
+$max = $form{'max'} // $max_hits_default;
if ( $path_info eq "/source" ) {
@@ -584,7 +573,7 @@ if ( $path_info eq "/source" ) {
}
if ( $stype eq "faq" ) {
- print &short_html_header( "FreeBSD Ports Search FAQ", 1 );
+ print &short_html_header( "FreeBSD Ports Search Help", 1 );
&faq;
&footer;
print &html_footer;
@@ -602,9 +591,7 @@ if ( !$query && $query_string =~ /^([^=&]+)$/ ) {
# automatically read collections, need only 0.2 sec on a pentium
@sec = &readcoll;
-$query =~ s/"/ /g;
-$query =~ s/^\s+//;
-$query =~ s/\s+$//;
+$query = &check_query($query, $sourceid);
&forms;
if ( $query_string eq "" || !$query ) {
@@ -616,20 +603,36 @@ if ( $query_string eq "" || !$query ) {
&check_input;
$counter = 0;
+# no prefix search for requires supported yet
+$query =~ s/^\^// if $stype eq 'requires';
+
+# quote non characters
+$query =~ s/([^\w\^])/\\$1/g;
+
# search
if ($query) {
&readindex( *today, *msec );
- $query =~ s/([^\w\^])/\\$1/g;
&search_ports;
}
if ( !$counter ) {
- print "Sorry, nothing found.\n";
- print qq{You may look for other }
- . qq{<a href="/search/">FreeBSD Search Services</a>.\n};
+ print <<EOF;
+<p>
+Sorry, nothing found.
+You may look for other <a href="https://www.freebsd.org/search/">FreeBSD Search Services</a>
+</p>
+EOF
}
+
else {
print "</dl>\n";
+ my $counter_message = $counter;
+ if ($counter >= $max) {
+ $counter_message .= " (max hit limit reached)";
+ warn "$counter_message: query=$query stype=$stype section=$section\n" if $debug >= 1;
+ }
+ print "<p>Number of hits: $counter_message\n</p>\n";
+ print &footer_links;
}
print qq{<hr noshade="noshade" />\n};