1#!/bin/sh 2# 3# Interface to a glimpse search of the man pages. 4# Michael Hamilton <michael@actrix.gen.nz> 5# Small changes - aeb, 980109 6# 7 8# Do we need lynxcgi URLs? For the moment our criterion is 9# 1) HTTP_USER_AGENT=Lynx* and 2) HTTP_HOST is unset. 10AGENT="${HTTP_USER_AGENT-unknown}" 11 12case "$AGENT" in 13 Lynx*|lynx*) 14 HH="${HTTP_HOST-nohh}" 15 SED="s/%lynx //" 16 ;; 17 *) 18 HH=nolynx 19 SED="/%lynx/d" 20 ;; 21esac 22 23SERVER="${SERVER_NAME-localhost}" 24case "$HH" in 25 nohh) 26 CG="lynxcgi:/home/httpd/cgi-bin/man" 27 ;; 28 *) 29 CG="http://$SERVER/cgi-bin/man" 30 ;; 31esac 32QUOTE="'" 33export CG QUOTE SED 34 35exec awk ' 36function removeopts(string) { 37 gsub(/^[ \t]/, "", string); # Remove leading spaces 38 gsub(/[ \t]$/, "", string); # Remove trailing spaces 39 gsub(/[ \t\\];/, ";", string); # Remove spaces before ; 40 gsub(/[ \t];/, ",", string); # Remove spaces before , 41 while (match(string, /^-[FLBwk1-8]/)) { 42 if (match(string, /^-[FL]( |.)[^ \t]+[ \t]+/)) { # Option with arg 43 options = options " " substr(string, RSTART, RLENGTH); 44 string = substr(string, RSTART + RLENGTH); 45 } 46 else if (match(string, /^-[Bwk1-8][ \t]+/)) { # Option without arg 47 options = options " " substr(string, RSTART, RLENGTH); 48 string = substr(string, RSTART + RLENGTH); 49 } 50 else if (match(string, /^-[^ \t]/)) { # Remove it 51 string = substr(string, RSTART + RLENGTH); 52 } 53 } 54 return string; 55} 56 57BEGIN { 58 59 searchdocument = "/home/httpd/cgi-aux/man/mansearch.aux"; 60 quote = ENVIRON["QUOTE"]; 61 cgipath = ENVIRON["CG"]; 62 sedcmd = ENVIRON["SED"]; 63 truncate_at = 11; # Single page display match limit. 64 65 glimpse_cmd = "glimpse -z -H /var/man2html -y -W -i " 66 67 for (i = 1; i < ARGC; i++) { 68 string = string " " ARGV[i]; 69 } 70 # Have to be careful to single quote this 71 # string later. 72 gsub(/[^a-zA-Z0-9-_+ \t\/@%:;,$*|]/, " ", string); 73 74 string = removeopts(string); 75 76 gsub(/[^a-zA-Z0-9-_+ \t\/@%:,]/, " ", options); 77 78 if (!string) { 79 if (system("test -r " searchdocument ) != 0) { 80 print "Content-type: text/html\n\n"; 81 print "<head>"; 82 print "<title>mansearch - file not found</title>"; 83 print "</head>\n<body>"; 84 print "Sorry - cannot read " searchdocument "."; 85 print "</body>"; 86 exit; 87 } 88 system("sed " quote "s#%cg#" cgipath "#g;" sedcmd quote " " searchdocument ); 89 exit; 90 } 91 92 print "Content-type: text/html"; 93 print ""; 94 print "<HTML>"; 95 print "<HEAD>"; 96 print "<TITLE>Manual Pages - Search Results: " string "</TITLE>"; 97 print "</HEAD>"; 98 print "<BODY>"; 99 100 print "<H1>Manual Pages - Search Results</H1>"; 101 print "<H2>Target text: " options " " string "</H2>"; 102 103 print "<A HREF=\"" cgipath "/mansearch\">"; 104 print "Perform another search"; 105 print "</A><BR>"; 106 print "<A HREF=\"" cgipath "/man2html\">"; 107 print "Return to Main Contents"; 108 print "</A>"; 109 110 print "<HR>"; 111 112 print "<DL>"; 113 # Unless you like being hacked, the single 114 # forward quotes are most important. 115 cmd = glimpse_cmd " " options " " quote string quote " 2>/dev/null" ; 116 117 while ((cmd | getline matchline) > 0) { 118 if (split(matchline, part, ": ") == 1) { 119 continue; 120 } 121 else { 122 fullname = part[1]; 123 } 124 125 if (fullname == "glimpse") { 126 print "<DT><B>"fullname"</B>:"; 127 } 128 else if (fullname != last_fullname) { 129 mcount++; 130 tcount = 0; 131 last_fullname = fullname ; 132 last_text = ""; 133 134 if (match(fullname, ".*/")) { 135 dirname = substr(fullname, 1, RLENGTH); 136 filename = substr(fullname, RLENGTH + 1); 137 if (dirname != last_dirname) { 138 last_dirname = dirname; 139 print "</DL>"; 140 print "<H3>Location: " dirname "</H3>"; 141 print "<DL>"; 142 } 143 } 144 else { 145 filename = fullname; 146 } 147 148 if (match(filename, /\.[^.]+$/)) { 149 ref = substr(filename, 1, RSTART - 1) "+" substr(filename, RSTART + 1); 150 } 151 else { 152 ref = filename; 153 } 154 print "<DT> <a href=\"" cgipath "/man2html?" fullname "\">"; 155 textname = filename; 156 sub(/\.(gz)|Z|z$/, "", textname); 157 sub(/\./, "(", textname); 158 textname = textname ")"; 159 print textname; 160 print "</A>"; 161 } 162 163 text = substr(matchline, length(fullname) + 2); 164 tcount++; 165 if (tcount < truncate_at) { 166 sub(/^ *.[^ ]+ /, "", text); 167 sub(/ +$/, "", text); 168 gsub(/\\f./, "", text); 169 gsub(/\\&/, "", text); 170 gsub(/\\/, "", text); 171 print "<DD>" text; 172 } 173 else if (tcount == truncate_at) { 174 print "<DD> <I>...additional matches not shown.</I>"; 175 } 176 } 177 178 print "</DL>"; 179 if (mcount == 0) { 180 print "No matches found."; 181 } 182 else if (mcount == 1) { 183 print "<HR>\n<P>1 match found." 184 } 185 else { 186 print "<HR>\n<P>" mcount " matches found." 187 } 188 print "</BODY>"; 189 print "</HTML>"; 190 exit; 191}' "$@" 192 193