]>
Commit | Line | Data |
---|---|---|
ccc6cda3 JA |
1 | #! /bin/bash |
2 | # | |
3 | # original from: | |
4 | # fman: new man program | |
5 | # @(#) fman.ksh 1.5 94/04/16 | |
6 | # 91/07/03 john h. dubois iii (john@armory.com) | |
7 | # 91/07/11 made it unpack man pages if neccessary | |
8 | # 91/07/16 fixed test for whether man file pattern was expanded | |
9 | # 92/01/21 made it read /etc/default/man to get section order, | |
10 | # and only display the first section found. | |
11 | # 92/02/06 changed name to fman | |
12 | # 92/02/07 fixed bug in notfound | |
13 | # 92/02/13 incorporated changes from DOS version | |
14 | # 92/03/11 changed to use MANPATH from environment if set, | |
15 | # and search all directories given in MANPATH | |
16 | # 92/03/15 exec pager or man w/o forking | |
17 | # 92/05/31 try using index if one exists | |
18 | # 92/10/01 Added "See also <other sections>" | |
19 | # 92/10/18 If PAGER is less, search for name of man page to make it easier | |
20 | # to find information in man pages for multiple items | |
21 | # 92/11/11 Make it work for compressed files not listed in index; | |
22 | # deal with man pages listed in index that don't exist. | |
23 | # 93/03/30 Fixed bug in MANPATH processing | |
24 | # 93/06/17 Include paths in "See also:" message if they would be needed | |
25 | # to get to a man page. Allow MANPATH spec on command line. | |
26 | # 93/07/09 Added -h and -e options. | |
27 | # 94/04/16 Added x option. | |
28 | # | |
29 | # conversion to bash v2 syntax done by Chet Ramey | |
30 | ||
31 | istrue() | |
32 | { | |
33 | test 0 -ne "$1" | |
34 | } | |
35 | ||
36 | isfalse() | |
37 | { | |
38 | test 0 -eq "$1" | |
39 | } | |
40 | ||
41 | # Finds all sections that man page $1 is in and puts them in the the | |
42 | # global array Sections[]. | |
43 | # The filename of each page is put in FileNames[] with the same index. | |
44 | # Global vars used: | |
45 | # patharr[] MANPATH directories. | |
46 | ||
47 | FindSectionsInIndex () | |
48 | { | |
49 | typeset index indexes section mpath page=$1 | |
50 | typeset -i i=0 NIndex=0 | |
51 | ||
52 | for mpath in "${patharr[@]}"; do | |
53 | if [ -r $mpath/index ]; then | |
54 | indexes="$indexes $mpath/index" | |
55 | let NIndex+=1 | |
56 | fi | |
57 | done | |
58 | [ -z "$indexes" ] && return | |
b80f6443 | 59 | # Make grep give filename |
ccc6cda3 JA |
60 | [ NIndex -lt 2 ] && indexes="$indexes /dev/null" |
61 | # set positional parameters to | |
62 | # indexfile:searchname pagename section ... | |
63 | # e.g. | |
64 | # /usr/man/index:FP_OFF Routines DOS | |
b80f6443 | 65 | set -- `grep "^$page[ ]" $indexes` |
ccc6cda3 JA |
66 | while [ $# -gt 2 ]; do |
67 | FileNames[i]=${1%%index*}cat$3/$2.$3 | |
68 | Sections[i]=$3 | |
69 | shift 3 | |
70 | let i+=1 | |
71 | done | |
72 | } | |
73 | ||
74 | # Finds all sections that man page $1 is in by searching each man directory | |
75 | # in the order given in patharr[], | |
76 | # and puts them in the the global array Sections[]. | |
77 | # The filename of each page is put in FileNames[] with the same index. | |
78 | # Global vars used: | |
79 | # patharr[] MANPATH directories. | |
80 | FindSectionsInDirs () | |
81 | { | |
82 | local page=$1 mpath AllPaths Path | |
83 | typeset -i i | |
84 | ||
85 | for mpath in "${patharr[@]}"; do | |
86 | AllPaths="$AllPaths $mpath/cat[0-9]*/$page.* $mpath/man[0-9]*/$page.*" | |
87 | done | |
88 | ||
89 | i=0 | |
90 | for Path in $AllPaths; do | |
91 | istrue $debug && echo Path = $Path | |
92 | case "$Path" in | |
93 | *\*) ;; | |
94 | *) | |
95 | # Remove compressed-file suffix to make FileNames be the same | |
96 | # as it is when built by FindSectionsInIndex() | |
97 | FileNames[i]=${Path%.[zZ]} | |
98 | Path=${Path%/*} | |
99 | Sections[i]=${Path##*/*.} | |
100 | let i+=1 ;; | |
101 | esac | |
102 | done | |
103 | } | |
104 | ||
105 | # FindSection: display man page. | |
106 | # Uses ordarr[] (built from $ORDER) to display the version of the man | |
107 | # page that occurs first in $ORDER. | |
108 | # Sections[] gives the sections that a man page was found in. | |
109 | # If the global variable "exist" is set to 1, nothing is displayed; | |
110 | # the function instead returns zero if a page is found, nonzero if not. | |
111 | # The filename of each page is in FileNames[] with the same index. | |
112 | # Global vars used: | |
113 | # Sections[], FileNames[], ordarr[] | |
114 | FindSection () | |
115 | { | |
116 | typeset -i NumPages i foundsec | |
117 | local section OtherSec filename NPAGER=$PAGER POpt page=$1 Pat | |
118 | local PageFile | |
119 | ||
120 | NumPages=${#Sections[*]} # Number of versions of man page found. | |
121 | isfalse $NumPages && return 1 | |
122 | case "$PAGER" in | |
123 | *less) Popt="-p$page" ;; | |
124 | esac | |
125 | ||
126 | # For each section in ORDER, determine if any man page was found in | |
127 | # that section | |
128 | for section in "${ordarr[@]}"; do | |
129 | i=0 | |
130 | foundsec=0 | |
131 | while [ $i -lt $NumPages ]; do | |
132 | if [ "${Sections[i]}" = $section ]; then | |
133 | # Found a man page from this section of ORDER | |
134 | filename=${FileNames[i]} | |
135 | if [ -z "$PageFile" ]; then | |
136 | PageFile=$filename | |
137 | else | |
138 | if istrue $foundsec; then | |
139 | OtherSec="$OtherSec$page(${filename%/*/*} $section) " | |
140 | else | |
141 | OtherSec="$OtherSec$page($section) " | |
142 | fi | |
143 | fi | |
144 | foundsec=1 | |
145 | istrue $exist && return | |
146 | fi | |
147 | let i+=1 | |
148 | done | |
149 | done | |
150 | # No pages with the specified section found. | |
151 | [ -z "$PageFile" ] && return 1 | |
152 | # Return if all we want to know is whether the man page exists. | |
153 | [ "$exist" = 1 ] && return 0 | |
154 | if [ -z "$OtherSec" ]; then | |
155 | NPAGER="exec $PAGER" | |
156 | fi | |
157 | if [ -r $PageFile ]; then | |
158 | $NPAGER $POpt $PageFile | |
159 | elif [ -r $PageFile.z ]; then | |
160 | pcat $PageFile.z | $NPAGER $POpt | |
161 | elif [ -r $PageFile.Z ]; then | |
162 | zcat $PageFile.Z | $NPAGER $POpt | |
163 | elif [ -f $PageFile.gz ]; then | |
164 | gzip -dc $PageFile.gz | $NPAGER $POpt | |
165 | else | |
166 | echo "$PageFile: cannot open." 1>&2 | |
167 | OtherSec= | |
168 | unset Sections[i] | |
169 | let i+=1 | |
170 | continue | |
171 | fi | |
172 | echo "See also $OtherSec" | |
173 | exit 0 | |
174 | } | |
175 | ||
176 | phelp() | |
177 | { | |
178 | echo "$name: print man pages. | |
179 | $name locates and prints the specified manual pages from the online UNIX | |
180 | documentation. | |
181 | $Usage | |
182 | Options: | |
183 | -e: Determine whether the specified man page exists. Nothing is printed; | |
184 | $0 exits with a zero status if the page exists and a nonzero status if | |
185 | it does not. | |
186 | -h: Print this help." | |
187 | } | |
188 | ||
189 | # main program | |
190 | ||
191 | typeset -i exist=0 debug=0 | |
192 | ||
193 | name=${0##*/} | |
194 | Usage="Usage: $name [-eh] [[manpath] section] command-name" | |
195 | ||
196 | while getopts :hex opt; do | |
197 | case $opt in | |
198 | h) phelp; exit 0;; | |
199 | e) exist=1 ;; | |
200 | x) debug=1 ;; | |
201 | +?) echo "$name: options should not be preceded by a '+'." 1>&2; exit 2;; | |
202 | ?) | |
203 | echo "$name: $OPTARG: bad option. Use -h for help." 1>&2 ; exit 2 ;; | |
204 | esac | |
205 | done | |
206 | ||
207 | # remove args that were options | |
208 | shift $((OPTIND-1)) | |
209 | ||
210 | if [ $# -lt 1 ]; then | |
211 | echo -e "$Usage\nUse -h for help." 1>&2 | |
212 | exit | |
213 | fi | |
214 | ||
215 | P=$PAGER | |
216 | O=1:n:l:6:8:2:3:4:5:7:p:o | |
217 | T=$TERM | |
218 | M=${MANPATH:-/usr/local/man:/usr/man} | |
219 | [ -f /etc/default/man ] && . /etc/default/man | |
220 | [ -n "$P" ] && PAGER=$P | |
221 | [ -n "$O" ] && ORDER=$O | |
222 | [ -n "$T" ] && TERM=$T | |
223 | [ -n "$M" ] && MANPATH=$M | |
224 | ||
225 | case $# in | |
226 | 0) echo "No man page specified." ; exit 1;; | |
227 | 1) page=$1;; | |
228 | 2) ORDER=$(echo $1 | tr a-z A-Z) ; page=$2;; | |
229 | 3) MANPATH=$1 | |
230 | [ -n "$2" ] && ORDER=$(echo $2 | tr a-z A-Z) | |
231 | page=$3;; | |
232 | *) echo "Too many arguments."; exit 1;; | |
233 | esac | |
234 | ||
235 | aargs=("$@") | |
236 | [ ! -t 0 ] && PAGER=cat | |
237 | ||
238 | OIFS=$IFS | |
239 | IFS=: | |
240 | patharr=($MANPATH) | |
241 | i=0 | |
242 | for d in $MANPATH; do | |
243 | for sec in $ORDER; do | |
244 | ordarr[i]=$d/cat${sec} | |
245 | let i+=1 | |
246 | ordarr[i]=$d/man${sec} | |
247 | let i+=1 | |
248 | done | |
249 | done | |
250 | IFS=$OIFS | |
251 | ||
252 | istrue $debug && echo patharr = "${patharr[@]}" | |
253 | ||
254 | # if less or more is being used, remove multiple blank lines | |
255 | export LESS="-s $LESS" | |
256 | export MORE="-s $MORE" | |
257 | ||
258 | # Try using index | |
259 | FindSectionsInIndex "$page" | |
260 | # Exit 0 if a page was found and we're just testing for existence. | |
261 | FindSection "$page" && exit 0 | |
262 | ||
263 | # Try searching directories | |
264 | unset Sections[*] | |
265 | FindSectionsInDirs "$page" | |
266 | FindSection "$page" && exit 0 | |
267 | ||
268 | istrue $exist && exit 1 | |
269 | ||
270 | # Try using man | |
271 | # If using more or less, make man run faster by letting more or less compress | |
272 | # multiple blank lines instead of rmb | |
273 | #case "$PAGER" in | |
274 | #*more|*less) manopt=-b;; | |
275 | #esac | |
276 | ||
277 | #cmd=(man $manopt -p$PAGER "${aargs[@]}") | |
278 | export PAGER | |
279 | cmd=(man $manopt "${aargs[@]}") | |
280 | istrue $debug && echo "$name: running ${cmd[*]}" 1>&2 | |
281 | exec "${cmd[@]}" |