#!/bin/sh # vim:ts=4:et # # Interface to a glimpse search of the man pages. # Michael Hamilton # 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 <Swish++ not installed

Swish++ not installed

Search is only enabled if the Swish++ package is installed. You may download it from the Debian site. 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 "
"; i = first; skip = i * maxperpage; while (i <= last && i < pagescnt) { ss = "" if (i == pageno ) { ss = ss "[" (i + 1) "]" } else if (i >= 0) { ss = ss "[ 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 "]"; } print ss; i++; skip += maxperpage; } print "
"; } 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 ""; print "mansearch - file not found"; print "\n"; print "Sorry - cannot read " searchdocument "."; print ""; exit; } system("sed " quote "s#%cg#" cgipath "#g;" sedcmd quote " " searchdocument ); exit; } print "Content-type: text/html; charset=UTF-8\n"; print ""; print ""; print ""; print "Manual Pages - Search Results: " string ""; print ""; print ""; print "

Manual Pages - Search Results

"; print "

Target text: " string "

"; print ""; print "Perform another search"; print "
"; print ""; print "Return to Main Contents"; print ""; print "
"; 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 "
"; } mcount++; print "
" textname "" \ " (" part[1] "%)
"; text = part[4]; if ( text == filename ) { text = textname; } else { sub(/^ *.[^ ]+[- ]+/, "", text); sub(/ +$/, "", text); gsub(/\\f./, "", text); gsub(/\\&/, "", text); gsub(/\\/, "", text); } print "
" text "
"; print "

"; } close(cmd); print "
"; number_pages( string, skip, maxperpage, resultcnt ); if (resultcnt == 0) { print "No matches found."; } else if (resultcnt == 1) { print "
\n

1 match found." } else { print "


\n

" resultcnt " matches found." } print ""; print ""; exit; }' "$@"