301
#!/bin/sh
# vim:ts=4:et
#
# Interface to a glimpse search of the man pages.
# Michael Hamilton <michael@actrix.gen.nz>
# Small changes - aeb, 980109
#
# $Id: mansearch,v 1.19 2005-10-19 20:56:30 robert Exp $
type search++ > /dev/null 2> /dev/null || {
cat <<EOF
Content-type: text/html; charset=UTF-8
<title>Swish++ not installed</title>
<body>
<h1>Swish++ not installed</h1>
Search is only enabled if the <b>Swish++</b> package is installed.
You may <a href="https://packages.debian.org/swish++">download</a> it from
the <a href="https://www.debian.org">Debian</a> site.
</body>
EOF
exit 0
}
# Do we need lynxcgi URLs? For the moment our criterion is
# 1) HTTP_USER_AGENT=Lynx* and 2) HTTP_HOST is unset.
AGENT="${HTTP_USER_AGENT-unknown}"
case "$AGENT" in
Lynx*|lynx*)
HH="${HTTP_HOST-nohh}"
SED="s/%lynx //"
;;
*)
HH=nolynx
SED="/%lynx/d"
;;
esac
SERVER="${SERVER_NAME-localhost}"
case "$HH" in
nohh)
CG="lynxcgi:/usr/lib/cgi-bin/man"
;;
*)
CG="/cgi-bin/man"
;;
esac
QUOTE="'"
export CG QUOTE SED
exec gawk '
# Generate pages index
function number_pages( searchfor, skip, maxperpage, resultcnt ) {
if ( resultcnt < maxperpage || skip < 0 ) {
return;
}
if (skip > resultcnt) {
skip = 0;
}
max = 10; # max returned pages
searchurl= cgipath "/mansearch" urlencode(searchfor, 1);
pagescnt = int (resultcnt / maxperpage) + 1;
pageno = int (skip / maxperpage);
first = int (pageno / max) * max - 1;
last = first + max + 1;
print "<CENTER>";
i = first;
skip = i * maxperpage;
while (i <= last && i < pagescnt) {
ss = ""
if (i == pageno ) {
ss = ss "[<STRONG>" (i + 1) "</STRONG>]"
} else if (i >= 0) {
ss = ss "[<EM><A HREF=\"" searchurl;
if (skip > 0) {
ss = ss "&skip=" skip;
}
ss = ss "\">";
if (i == first) {
ss = ss "<<";
} else if (i == last) {
ss = ss ">>";
} else {
ss = ss (i + 1);
}
ss = ss "</A></EM>]";
}
print ss;
i++;
skip += maxperpage;
}
print "</CENTER>";
}
function urldecode(string) {
gsub(/\+/, " ", string);
oldIGNORECASE=IGNORECASE;
IGNORECASE=1;
while(match(string, /%[0-9a-f][0-9a-f]/)) {
a=substr(string, RSTART + 1, RLENGTH - 1);
b=sprintf("%c",strtonum("0x" a)) ;
retstr = retstr substr(string, 0, RSTART - 1) b;
string = substr(string, RSTART + RLENGTH);
}
IGNORECASE=oldIGNORECASE;
return retstr string;
}
# Encode URL; the force argument forces "query=...." format
function urlencode(string, force) {
# uses global ord table, set up in BEGIN
encoded = force;
retstr = "";
while(match(string, /[^a-zA-Z0-9_:\/\.\-]/)) {
a=substr(string, RSTART, RLENGTH);
if (a == " ") {
b = "+";
} else {
b = "%" sprintf("%02X", ord[a]);
}
retstr = retstr substr(string, 0, RSTART - 1) b;
string = substr(string, RSTART + RLENGTH);
encoded = 1;
}
if (encoded) {
return "?query=" retstr string;
} else {
return retstr string;
}
}
BEGIN {
# fill ord table, used by urlencode
for (i = 0; i < 255; i++)
ord[sprintf("%c", i)] = i
searchdocument = "/usr/share/man2html/mansearch.aux";
quote = ENVIRON["QUOTE"];
cgipath = ENVIRON["CG"];
sedcmd = ENVIRON["SED"];
maxperpage = 50; # Single page display match limit.
glimpse_cmd = "search++ --config-file=/usr/share/man2html/swish++.conf "
qry_str = ENVIRON["QUERY_STRING"];
if (match(qry_str, /skip=[0-9]+/)) {
skip = int(substr(qry_str, RSTART + 5, RLENGTH - 5) / maxperpage) * maxperpage;
} else {
skip = 0
}
if (match(qry_str, /query=[^&]+/)) {
qry_str = substr(qry_str, RSTART + 6, RLENGTH - 6);
string = urldecode(qry_str);
}
if (!string) {
for (i = 1; i < ARGC; i++) {
string = string " " ARGV[i];
}
}
# Have to be careful to single quote this
# string later.
gsub(/[^a-zA-Z0-9\-_+ \t\/@%:;,$*|=]/, " ", string);
# string = removeopts(string);
# gsub(/[^a-zA-Z0-9-_+ \t\/@%:,]/, " ", options);
if (!string) {
if (system("test -r " searchdocument ) != 0) {
print "<HTML><HEAD>";
print "<TITLE>mansearch - file not found</TITLE>";
print "</HEAD>\n<BODY>";
print "Sorry - cannot read " searchdocument ".";
print "</BODY></HTML>";
exit;
}
system("sed " quote "s#%cg#" cgipath "#g;" sedcmd quote " " searchdocument );
exit;
}
print "Content-type: text/html; charset=UTF-8\n";
print "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">";
print "<HTML>";
print "<HEAD>";
print "<TITLE>Manual Pages - Search Results: " string "</TITLE>";
print "</HEAD>";
print "<BODY>";
print "<H1>Manual Pages - Search Results</H1>";
print "<H2>Target text: " string "</H2>";
print "<A HREF=\"" cgipath "/mansearch\">";
print "Perform another search";
print "</A><BR>";
print "<A HREF=\"" cgipath "/man2html\">";
print "Return to Main Contents";
print "</A>";
print "<HR>";
if ( skip > 0) {
options = options "--skip-results=" skip;
}
if ( maxperpage > 0 ) {
options = options "-m " maxperpage;
}
# Unless you like being hacked, the single
# forward quotes are most important.
cmd = glimpse_cmd " " options " " quote string quote " 2>/dev/null" ;
while ((cmd | getline matchline) > 0) {
if (split(matchline, part, "__--__") <= 3) {
if ( match( matchline, "^# results: .*$" ) ) {
resultcnt = substr( matchline, RSTART + 11, RLENGTH - 11 ) + 0;
number_pages( string, skip, maxperpage, resultcnt );
}
continue;
}
else {
fullname = part[2];
}
if (fullname == last_fullname) {
continue;
}
last_fullname = fullname ;
last_text = "";
if (match(fullname, ".*/")) {
dirname = substr(fullname, 1, RLENGTH);
filename = substr(fullname, RLENGTH + 1);
} else {
filename = fullname;
}
if (match(filename, /\.[^.]+$/)) {
ref = substr(filename, 1, RSTART - 1) "+" substr(filename, RSTART + 1);
} else {
ref = filename;
}
textname = filename;
sub(/\.(gz|Z|z)$/, "", textname);
# replace last "." with "(". gsub is used to count number of "."
textname = gensub(/\./, "(", gsub(/\./, ".", textname), textname);
textname = textname ")";
if (mcount == 0) {
print "<DL>";
}
mcount++;
print "<DT><A HREF=\"" cgipath "/man2html" urlencode(fullname, 0) "\">" textname "</A>" \
" <EM>(" part[1] "%)</EM></DT>";
text = part[4];
if ( text == filename ) {
text = textname;
} else {
sub(/^ *.[^ ]+[- ]+/, "", text);
sub(/ +$/, "", text);
gsub(/\\f./, "", text);
gsub(/\\&/, "", text);
gsub(/\\/, "", text);
}
print "<DD>" text "</DD>";
print "<DT><BR></DT>";
}
close(cmd);
print "</DL>";
number_pages( string, skip, maxperpage, resultcnt );
if (resultcnt == 0) {
print "No matches found.";
}
else if (resultcnt == 1) {
print "<HR>\n<P>1 match found."
}
else {
print "<HR>\n<P>" resultcnt " matches found."
}
print "</BODY>";
print "</HTML>";
exit;
}' "$@"