xref: /freebsd/usr.bin/man/man.sh (revision 3d9127f1bc014bf3dd3d02a0bb297efa84564887)
1c535eb59SGordon Tetlow#! /bin/sh
2c535eb59SGordon Tetlow#
3c535eb59SGordon Tetlow#  Copyright (c) 2010 Gordon Tetlow
4c535eb59SGordon Tetlow#  All rights reserved.
5c535eb59SGordon Tetlow#
6c535eb59SGordon Tetlow#  Redistribution and use in source and binary forms, with or without
7c535eb59SGordon Tetlow#  modification, are permitted provided that the following conditions
8c535eb59SGordon Tetlow#  are met:
9c535eb59SGordon Tetlow#  1. Redistributions of source code must retain the above copyright
10c535eb59SGordon Tetlow#     notice, this list of conditions and the following disclaimer.
11c535eb59SGordon Tetlow#  2. Redistributions in binary form must reproduce the above copyright
12c535eb59SGordon Tetlow#     notice, this list of conditions and the following disclaimer in the
13c535eb59SGordon Tetlow#     documentation and/or other materials provided with the distribution.
14c535eb59SGordon Tetlow#
15c535eb59SGordon Tetlow#  THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16c535eb59SGordon Tetlow#  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17c535eb59SGordon Tetlow#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18c535eb59SGordon Tetlow#  ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19c535eb59SGordon Tetlow#  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20c535eb59SGordon Tetlow#  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21c535eb59SGordon Tetlow#  OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22c535eb59SGordon Tetlow#  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23c535eb59SGordon Tetlow#  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24c535eb59SGordon Tetlow#  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25c535eb59SGordon Tetlow#  SUCH DAMAGE.
26c535eb59SGordon Tetlow#
27c535eb59SGordon Tetlow# $FreeBSD$
28c535eb59SGordon Tetlow
29c535eb59SGordon Tetlow# Usage: add_to_manpath path
30c535eb59SGordon Tetlow# Adds a variable to manpath while ensuring we don't have duplicates.
31c535eb59SGordon Tetlow# Returns true if we were able to add something. False otherwise.
32c535eb59SGordon Tetlowadd_to_manpath() {
33c535eb59SGordon Tetlow	case "$manpath" in
34c535eb59SGordon Tetlow	*:$1)	decho "  Skipping duplicate manpath entry $1" 2 ;;
35c535eb59SGordon Tetlow	$1:*)	decho "  Skipping duplicate manpath entry $1" 2 ;;
36c535eb59SGordon Tetlow	*:$1:*)	decho "  Skipping duplicate manpath entry $1" 2 ;;
37c535eb59SGordon Tetlow	*)	if [ -d "$1" ]; then
38c535eb59SGordon Tetlow			decho "  Adding $1 to manpath"
39c535eb59SGordon Tetlow			manpath="$manpath:$1"
40c535eb59SGordon Tetlow			return 0
41c535eb59SGordon Tetlow		fi
42c535eb59SGordon Tetlow		;;
43c535eb59SGordon Tetlow	esac
44c535eb59SGordon Tetlow
45c535eb59SGordon Tetlow	return 1
46c535eb59SGordon Tetlow}
47c535eb59SGordon Tetlow
48c535eb59SGordon Tetlow# Usage: build_manlocales
49c535eb59SGordon Tetlow# Builds a correct MANLOCALES variable.
50c535eb59SGordon Tetlowbuild_manlocales() {
51c535eb59SGordon Tetlow	# If the user has set manlocales, who are we to argue.
52c535eb59SGordon Tetlow	if [ -n "$MANLOCALES" ]; then
53c535eb59SGordon Tetlow		return
54c535eb59SGordon Tetlow	fi
55c535eb59SGordon Tetlow
56c535eb59SGordon Tetlow	parse_configs
57c535eb59SGordon Tetlow
58c535eb59SGordon Tetlow	# Trim leading colon
59c535eb59SGordon Tetlow	MANLOCALES=${manlocales#:}
60c535eb59SGordon Tetlow
61c535eb59SGordon Tetlow	decho "Available manual locales: $MANLOCALES"
62c535eb59SGordon Tetlow}
63c535eb59SGordon Tetlow
64c535eb59SGordon Tetlow# Usage: build_manpath
65c535eb59SGordon Tetlow# Builds a correct MANPATH variable.
66c535eb59SGordon Tetlowbuild_manpath() {
67c535eb59SGordon Tetlow	local IFS
68c535eb59SGordon Tetlow
69c535eb59SGordon Tetlow	# If the user has set a manpath, who are we to argue.
70c535eb59SGordon Tetlow	if [ -n "$MANPATH" ]; then
71c535eb59SGordon Tetlow		return
72c535eb59SGordon Tetlow	fi
73c535eb59SGordon Tetlow
74c535eb59SGordon Tetlow	search_path
75c535eb59SGordon Tetlow
76c535eb59SGordon Tetlow	decho "Adding default manpath entries"
77c535eb59SGordon Tetlow	IFS=:
78c535eb59SGordon Tetlow	for path in $man_default_path; do
79c535eb59SGordon Tetlow		add_to_manpath "$path"
80c535eb59SGordon Tetlow	done
81c535eb59SGordon Tetlow	unset IFS
82c535eb59SGordon Tetlow
83c535eb59SGordon Tetlow	parse_configs
84c535eb59SGordon Tetlow
85c535eb59SGordon Tetlow	# Trim leading colon
86c535eb59SGordon Tetlow	MANPATH=${manpath#:}
87c535eb59SGordon Tetlow
88c535eb59SGordon Tetlow	decho "Using manual path: $MANPATH"
89c535eb59SGordon Tetlow}
90c535eb59SGordon Tetlow
91c535eb59SGordon Tetlow# Usage: check_cat catglob
92c535eb59SGordon Tetlow# Checks to see if a cat glob is available.
93c535eb59SGordon Tetlowcheck_cat() {
94c535eb59SGordon Tetlow	if exists "$1"; then
95c535eb59SGordon Tetlow		use_cat=yes
96c535eb59SGordon Tetlow		catpage=$found
97c535eb59SGordon Tetlow		decho "    Found catpage $catpage"
98c535eb59SGordon Tetlow		return 0
99c535eb59SGordon Tetlow	else
100c535eb59SGordon Tetlow		return 1
101c535eb59SGordon Tetlow	fi
102c535eb59SGordon Tetlow}
103c535eb59SGordon Tetlow
104c535eb59SGordon Tetlow# Usage: check_man manglob catglob
105c535eb59SGordon Tetlow# Given 2 globs, figures out if the manglob is available, if so, check to
106c535eb59SGordon Tetlow# see if the catglob is also available and up to date.
107c535eb59SGordon Tetlowcheck_man() {
108c535eb59SGordon Tetlow	if exists "$1"; then
109c535eb59SGordon Tetlow		# We have a match, check for a cat page
110c535eb59SGordon Tetlow		manpage=$found
111c535eb59SGordon Tetlow		decho "    Found manpage $manpage"
112c535eb59SGordon Tetlow
113c535eb59SGordon Tetlow		if exists "$2" && is_newer $found $manpage; then
114c535eb59SGordon Tetlow			# cat page found and is newer, use that
115c535eb59SGordon Tetlow			use_cat=yes
116c535eb59SGordon Tetlow			catpage=$found
117c535eb59SGordon Tetlow			decho "    Using catpage $catpage"
118c535eb59SGordon Tetlow		else
119c535eb59SGordon Tetlow			# no cat page or is older
120c535eb59SGordon Tetlow			unset use_cat
121c535eb59SGordon Tetlow			decho "    Skipping catpage: not found or old"
122c535eb59SGordon Tetlow		fi
123c535eb59SGordon Tetlow		return 0
124c535eb59SGordon Tetlow	fi
125c535eb59SGordon Tetlow
126c535eb59SGordon Tetlow	return 1
127c535eb59SGordon Tetlow}
128c535eb59SGordon Tetlow
129c535eb59SGordon Tetlow# Usage: decho "string" [debuglevel]
130c535eb59SGordon Tetlow# Echoes to stderr string prefaced with -- if high enough debuglevel.
131c535eb59SGordon Tetlowdecho() {
132c535eb59SGordon Tetlow	if [ $debug -ge ${2:-1} ]; then
133c535eb59SGordon Tetlow		echo "-- $1" >&2
134c535eb59SGordon Tetlow	fi
135c535eb59SGordon Tetlow}
136c535eb59SGordon Tetlow
137c535eb59SGordon Tetlow# Usage: exists glob
138c535eb59SGordon Tetlow# Returns true if glob resolves to a real file.
139c535eb59SGordon Tetlowexists() {
140c535eb59SGordon Tetlow	local IFS
141c535eb59SGordon Tetlow
142c535eb59SGordon Tetlow	# Don't accidentally inherit callers IFS (breaks perl manpages)
143c535eb59SGordon Tetlow	unset IFS
144c535eb59SGordon Tetlow
145c535eb59SGordon Tetlow	# Use some globbing tricks in the shell to determine if a file
146c535eb59SGordon Tetlow	# exists or not.
147c535eb59SGordon Tetlow	set +f
148c535eb59SGordon Tetlow	set -- "$1" $1
149c535eb59SGordon Tetlow	set -f
150c535eb59SGordon Tetlow
151c535eb59SGordon Tetlow	if [ "$1" != "$2" -a -r "$2" ]; then
152c535eb59SGordon Tetlow		found="$2"
153c535eb59SGordon Tetlow		return 0
154c535eb59SGordon Tetlow	fi
155c535eb59SGordon Tetlow
156c535eb59SGordon Tetlow	return 1
157c535eb59SGordon Tetlow}
158c535eb59SGordon Tetlow
159c535eb59SGordon Tetlow# Usage: find_file path section subdir pagename
160c535eb59SGordon Tetlow# Returns: true if something is matched and found.
161c535eb59SGordon Tetlow# Search the given path/section combo for a given page.
162c535eb59SGordon Tetlowfind_file() {
163c535eb59SGordon Tetlow	local manroot catroot mann man0 catn cat0
164c535eb59SGordon Tetlow
165c535eb59SGordon Tetlow	manroot="$1/man$2"
166c535eb59SGordon Tetlow	catroot="$1/cat$2"
167c535eb59SGordon Tetlow	if [ -n "$3" ]; then
168c535eb59SGordon Tetlow		manroot="$manroot/$3"
169c535eb59SGordon Tetlow		catroot="$catroot/$3"
170c535eb59SGordon Tetlow	fi
171c535eb59SGordon Tetlow
172c535eb59SGordon Tetlow	if [ ! -d "$manroot" ]; then
173c535eb59SGordon Tetlow		return 1
174c535eb59SGordon Tetlow	fi
175c535eb59SGordon Tetlow	decho "  Searching directory $manroot" 2
176c535eb59SGordon Tetlow
177c535eb59SGordon Tetlow	mann="$manroot/$4.$2*"
178c535eb59SGordon Tetlow	man0="$manroot/$4.0*"
179c535eb59SGordon Tetlow	catn="$catroot/$4.$2*"
180c535eb59SGordon Tetlow	cat0="$catroot/$4.0*"
181c535eb59SGordon Tetlow
182c535eb59SGordon Tetlow	# This is the behavior as seen by the original man utility.
183c535eb59SGordon Tetlow	# Let's not change that which doesn't seem broken.
184c535eb59SGordon Tetlow	if check_man "$mann" "$catn"; then
185c535eb59SGordon Tetlow		return 0
186c535eb59SGordon Tetlow	elif check_man "$man0" "$cat0"; then
187c535eb59SGordon Tetlow		return 0
188c535eb59SGordon Tetlow	elif check_cat "$catn"; then
189c535eb59SGordon Tetlow		return 0
190c535eb59SGordon Tetlow	elif check_cat "$cat0"; then
191c535eb59SGordon Tetlow		return 0
192c535eb59SGordon Tetlow	fi
193c535eb59SGordon Tetlow
194c535eb59SGordon Tetlow	return 1
195c535eb59SGordon Tetlow}
196c535eb59SGordon Tetlow
197c535eb59SGordon Tetlow# Usage: is_newer file1 file2
198c535eb59SGordon Tetlow# Returns true if file1 is newer than file2 as calculated by mtime.
199c535eb59SGordon Tetlowis_newer() {
200c535eb59SGordon Tetlow	if [ $(stat -f %m $1) -gt $(stat -f %m $2) ]; then
201c535eb59SGordon Tetlow		decho "    mtime: $1 newer than $2" 3
202c535eb59SGordon Tetlow		return 0
203c535eb59SGordon Tetlow	else
204c535eb59SGordon Tetlow		decho "    mtime: $1 older than $2" 3
205c535eb59SGordon Tetlow		return 1
206c535eb59SGordon Tetlow	fi
207c535eb59SGordon Tetlow}
208c535eb59SGordon Tetlow
209c535eb59SGordon Tetlow# Usage: manpath_parse_args "$@"
210c535eb59SGordon Tetlow# Parses commandline options for manpath.
211c535eb59SGordon Tetlowmanpath_parse_args() {
212c535eb59SGordon Tetlow	local cmd_arg
213c535eb59SGordon Tetlow
214c535eb59SGordon Tetlow	while getopts 'Ldq' cmd_arg; do
215c535eb59SGordon Tetlow		case "${cmd_arg}" in
216c535eb59SGordon Tetlow		L)	Lflag=Lflag ;;
217c535eb59SGordon Tetlow		d)	debug=$(( $debug + 1 )) ;;
218c535eb59SGordon Tetlow		q)	qflag=qflag ;;
219c535eb59SGordon Tetlow		*)	manpath_usage ;;
220c535eb59SGordon Tetlow		esac
221c535eb59SGordon Tetlow	done >&2
222c535eb59SGordon Tetlow}
223c535eb59SGordon Tetlow
224c535eb59SGordon Tetlow# Usage: manpath_usage
225c535eb59SGordon Tetlow# Display usage for the manpath(1) utility.
226c535eb59SGordon Tetlowmanpath_usage() {
227c535eb59SGordon Tetlow	echo 'usage: manpath [-Ldq]' >&2
228c535eb59SGordon Tetlow	exit 1
229c535eb59SGordon Tetlow}
230c535eb59SGordon Tetlow
231c535eb59SGordon Tetlow# Usage: manpath_warnings
232c535eb59SGordon Tetlow# Display some warnings to stderr.
233c535eb59SGordon Tetlowmanpath_warnings() {
234c535eb59SGordon Tetlow	if [ -z "$Lflag" -a -n "$MANPATH" ]; then
235c535eb59SGordon Tetlow		echo "(Warning: MANPATH environment variable set)" >&2
236c535eb59SGordon Tetlow	fi
237c535eb59SGordon Tetlow
238c535eb59SGordon Tetlow	if [ -n "$Lflag" -a -n "$MANLOCALES" ]; then
239c535eb59SGordon Tetlow		echo "(Warning: MANLOCALES environment variable set)" >&2
240c535eb59SGordon Tetlow	fi
241c535eb59SGordon Tetlow}
242c535eb59SGordon Tetlow
243c535eb59SGordon Tetlow# Usage: man_display_page
244c535eb59SGordon Tetlow# Display either the manpage or catpage depending on the use_cat variable
245c535eb59SGordon Tetlowman_display_page() {
246c535eb59SGordon Tetlow	local EQN COL NROFF PIC TBL TROFF REFER VGRIND
247c535eb59SGordon Tetlow	local IFS l nroff_dev pipeline preproc_arg tool
248c535eb59SGordon Tetlow
249c535eb59SGordon Tetlow	# We are called with IFS set to colon. This causes really weird
250c535eb59SGordon Tetlow	# things to happen for the variables that have spaces in them.
251c535eb59SGordon Tetlow	unset IFS
252c535eb59SGordon Tetlow
253c535eb59SGordon Tetlow	# If we are supposed to use a catpage and we aren't using troff(1)
254c535eb59SGordon Tetlow	# just zcat the catpage and we are done.
255c535eb59SGordon Tetlow	if [ -z "$tflag" -a -n "$use_cat" ]; then
256c535eb59SGordon Tetlow		if [ -n "$wflag" ]; then
257c535eb59SGordon Tetlow			echo "$catpage (source: $manpage)"
258c535eb59SGordon Tetlow			ret=0
259c535eb59SGordon Tetlow		else
260c535eb59SGordon Tetlow			if [ $debug -gt 0 ]; then
261c535eb59SGordon Tetlow				decho "Command: $ZCAT $catpage | $PAGER"
262c535eb59SGordon Tetlow				ret=0
263c535eb59SGordon Tetlow			else
264c535eb59SGordon Tetlow				eval "$ZCAT $catpage | $PAGER"
265c535eb59SGordon Tetlow				ret=$?
266c535eb59SGordon Tetlow			fi
267c535eb59SGordon Tetlow		fi
268c535eb59SGordon Tetlow		return
269c535eb59SGordon Tetlow	fi
270c535eb59SGordon Tetlow
271c535eb59SGordon Tetlow	# Okay, we are using the manpage, do we just need to output the
272c535eb59SGordon Tetlow	# name of the manpage?
273c535eb59SGordon Tetlow	if [ -n "$wflag" ]; then
274c535eb59SGordon Tetlow		echo "$manpage"
275c535eb59SGordon Tetlow		ret=0
276c535eb59SGordon Tetlow		return
277c535eb59SGordon Tetlow	fi
278c535eb59SGordon Tetlow
279c535eb59SGordon Tetlow	# So, we really do need to parse the manpage. First, figure out the
280c535eb59SGordon Tetlow	# device flag (-T) we have to pass to eqn(1) and groff(1). Then,
281c535eb59SGordon Tetlow	# setup the pipeline of commands based on the user's request.
282c535eb59SGordon Tetlow
283c535eb59SGordon Tetlow	# Apparently the locale flags are switched on where the manpage is
284c535eb59SGordon Tetlow	# found not just the locale env variables.
285c535eb59SGordon Tetlow	nroff_dev="ascii"
286c535eb59SGordon Tetlow	case "X${use_locale}X${manpage}" in
287c535eb59SGordon Tetlow	XyesX*/${man_lang}*${man_charset}/*)
288c535eb59SGordon Tetlow		# I don't pretend to know this; I'm just copying from the
289c535eb59SGordon Tetlow		# previous version of man(1).
290c535eb59SGordon Tetlow		case "$man_charset" in
291c535eb59SGordon Tetlow		KOI8-R)		nroff_dev="koi8-r" ;;
292c535eb59SGordon Tetlow		ISO8859-1)	nroff_dev="latin1" ;;
293c535eb59SGordon Tetlow		ISO8859-15)	nroff_dev="latin1" ;;
294c535eb59SGordon Tetlow		UTF-8)		nroff_dev="utf8" ;;
295c535eb59SGordon Tetlow		*)		nroff_dev="ascii" ;;
296c535eb59SGordon Tetlow		esac
297c535eb59SGordon Tetlow
298c535eb59SGordon Tetlow		NROFF="$NROFF -T$nroff_dev -dlocale=$man_lang.$man_charset"
299c535eb59SGordon Tetlow		EQN="$EQN -T$nroff_dev"
300c535eb59SGordon Tetlow
301c535eb59SGordon Tetlow		# Allow language specific calls to override the default
302c535eb59SGordon Tetlow		# set of utilities.
303c535eb59SGordon Tetlow		l=$(echo $man_lang | tr [:lower:] [:upper:])
304c535eb59SGordon Tetlow		for tool in EQN COL NROFF PIC TBL TROFF REFER VGRIND; do
305c535eb59SGordon Tetlow			eval "$tool=\${${tool}_$l:-\$$tool}"
306c535eb59SGordon Tetlow		done
307c535eb59SGordon Tetlow		;;
308c535eb59SGordon Tetlow	*)	NROFF="$NROFF -Tascii"
309c535eb59SGordon Tetlow		EQN="$EQN -Tascii"
310c535eb59SGordon Tetlow		;;
311c535eb59SGordon Tetlow	esac
312c535eb59SGordon Tetlow
313c535eb59SGordon Tetlow	if [ -n "$MANROFFSEQ" ]; then
314c535eb59SGordon Tetlow		set -- -$MANROFFSEQ
315c535eb59SGordon Tetlow		while getopts 'egprtv' preproc_arg; do
316c535eb59SGordon Tetlow			case "${preproc_arg}" in
317c535eb59SGordon Tetlow			e)	pipeline="$pipeline | $EQN" ;;
318c535eb59SGordon Tetlow			g)	;; # Ignore for compatability.
319c535eb59SGordon Tetlow			p)	pipeline="$pipeline | $PIC" ;;
320c535eb59SGordon Tetlow			r)	pipeline="$pipeline | $REFER" ;;
321c535eb59SGordon Tetlow			t)	pipeline="$pipeline | $TBL"; use_col=yes ;;
322c535eb59SGordon Tetlow			v)	pipeline="$pipeline | $VGRIND" ;;
323c535eb59SGordon Tetlow			*)	usage ;;
324c535eb59SGordon Tetlow			esac
325c535eb59SGordon Tetlow		done
326c535eb59SGordon Tetlow		# Strip the leading " | " from the resulting pipeline.
327c535eb59SGordon Tetlow		pipeline="${pipeline#" | "}"
328c535eb59SGordon Tetlow	else
329c535eb59SGordon Tetlow		pipeline="$TBL"
330c535eb59SGordon Tetlow		use_col=yes
331c535eb59SGordon Tetlow	fi
332c535eb59SGordon Tetlow
333c535eb59SGordon Tetlow	if [ -n "$tflag" ]; then
334c535eb59SGordon Tetlow		pipeline="$pipeline | $TROFF"
335c535eb59SGordon Tetlow	else
336c535eb59SGordon Tetlow		pipeline="$pipeline | $NROFF"
337c535eb59SGordon Tetlow
338c535eb59SGordon Tetlow		if [ -n "$use_col" ]; then
339c535eb59SGordon Tetlow			pipeline="$pipeline | $COL"
340c535eb59SGordon Tetlow		fi
341c535eb59SGordon Tetlow
342c535eb59SGordon Tetlow		pipeline="$pipeline | $PAGER"
343c535eb59SGordon Tetlow	fi
344c535eb59SGordon Tetlow
345c535eb59SGordon Tetlow	if [ $debug -gt 0 ]; then
346c535eb59SGordon Tetlow		decho "Command: $ZCAT $manpage | $pipeline"
347c535eb59SGordon Tetlow		ret=0
348c535eb59SGordon Tetlow	else
349c535eb59SGordon Tetlow		eval "$ZCAT $manpage | $pipeline"
350c535eb59SGordon Tetlow		ret=$?
351c535eb59SGordon Tetlow	fi
352c535eb59SGordon Tetlow}
353c535eb59SGordon Tetlow
354c535eb59SGordon Tetlow# Usage: man_find_and_display page
355c535eb59SGordon Tetlow# Search through the manpaths looking for the given page.
356c535eb59SGordon Tetlowman_find_and_display() {
357c535eb59SGordon Tetlow	local found_page locpath p path sect
358c535eb59SGordon Tetlow
359*3d9127f1SGordon Tetlow	# Check to see if it's a file. But only if it has a '/' in
360*3d9127f1SGordon Tetlow	# the filename.
361*3d9127f1SGordon Tetlow	case "$1" in
362*3d9127f1SGordon Tetlow	*/*)	if [ -f "$1" -a -r "$1" ]; then
363*3d9127f1SGordon Tetlow			decho "Found a usable page, displaying that"
364*3d9127f1SGordon Tetlow			found_page=yes
365*3d9127f1SGordon Tetlow			unset use_cat
366*3d9127f1SGordon Tetlow			manpage="$1"
367*3d9127f1SGordon Tetlow			man_display_page
368*3d9127f1SGordon Tetlow			return
369*3d9127f1SGordon Tetlow		fi
370*3d9127f1SGordon Tetlow		;;
371*3d9127f1SGordon Tetlow	esac
372*3d9127f1SGordon Tetlow
373c535eb59SGordon Tetlow	IFS=:
374c535eb59SGordon Tetlow	for sect in $MANSECT; do
375c535eb59SGordon Tetlow		decho "Searching section $sect" 2
376c535eb59SGordon Tetlow		for path in $MANPATH; do
377c535eb59SGordon Tetlow			for locpath in $locpaths; do
378c535eb59SGordon Tetlow				p=$path/$locpath
379c535eb59SGordon Tetlow				p=${p%/.} # Rid ourselves of the trailing /.
380c535eb59SGordon Tetlow
381c535eb59SGordon Tetlow				# Check if there is a MACHINE specific manpath.
382c535eb59SGordon Tetlow				if find_file $p $sect $MACHINE "$1"; then
383c535eb59SGordon Tetlow					found_page=yes
384c535eb59SGordon Tetlow					man_display_page
3851d7c660aSGordon Tetlow					if [ -n "$aflag" ]; then
3861d7c660aSGordon Tetlow						continue 2
3871d7c660aSGordon Tetlow					else
388c535eb59SGordon Tetlow						return
389c535eb59SGordon Tetlow					fi
390c535eb59SGordon Tetlow				fi
391c535eb59SGordon Tetlow
392c535eb59SGordon Tetlow				# Check if there is a MACHINE_ARCH
393c535eb59SGordon Tetlow				# specific manpath.
394c535eb59SGordon Tetlow				if find_file $p $sect $MACHINE_ARCH "$1"; then
395c535eb59SGordon Tetlow					found_page=yes
396c535eb59SGordon Tetlow					man_display_page
3971d7c660aSGordon Tetlow					if [ -n "$aflag" ]; then
3981d7c660aSGordon Tetlow						continue 2
3991d7c660aSGordon Tetlow					else
400c535eb59SGordon Tetlow						return
401c535eb59SGordon Tetlow					fi
402c535eb59SGordon Tetlow				fi
403c535eb59SGordon Tetlow
404c535eb59SGordon Tetlow				# Check plain old manpath.
405c535eb59SGordon Tetlow				if find_file $p $sect '' "$1"; then
406c535eb59SGordon Tetlow					found_page=yes
407c535eb59SGordon Tetlow					man_display_page
4081d7c660aSGordon Tetlow					if [ -n "$aflag" ]; then
4091d7c660aSGordon Tetlow						continue 2
4101d7c660aSGordon Tetlow					else
411c535eb59SGordon Tetlow						return
412c535eb59SGordon Tetlow					fi
413c535eb59SGordon Tetlow				fi
414c535eb59SGordon Tetlow			done
415c535eb59SGordon Tetlow		done
416c535eb59SGordon Tetlow	done
417c535eb59SGordon Tetlow	unset IFS
418c535eb59SGordon Tetlow
419c535eb59SGordon Tetlow	# Nothing? Well, we are done then.
420c535eb59SGordon Tetlow	if [ -z "$found_page" ]; then
421c535eb59SGordon Tetlow		echo "No manual entry for $1" >&2
422c535eb59SGordon Tetlow		ret=1
423c535eb59SGordon Tetlow		return
424c535eb59SGordon Tetlow	fi
425c535eb59SGordon Tetlow}
426c535eb59SGordon Tetlow
427c535eb59SGordon Tetlow# Usage: man_parse_args "$@"
428c535eb59SGordon Tetlow# Parses commandline options for man.
429c535eb59SGordon Tetlowman_parse_args() {
430c535eb59SGordon Tetlow	local IFS cmd_arg
431c535eb59SGordon Tetlow
432c535eb59SGordon Tetlow	while getopts 'M:P:S:adfhkm:op:tw' cmd_arg; do
433c535eb59SGordon Tetlow		case "${cmd_arg}" in
434c535eb59SGordon Tetlow		M)	MANPATH=$OPTARG ;;
435c535eb59SGordon Tetlow		P)	PAGER=$OPTARG ;;
436c535eb59SGordon Tetlow		S)	MANSECT=$OPTARG ;;
437c535eb59SGordon Tetlow		a)	aflag=aflag ;;
438c535eb59SGordon Tetlow		d)	debug=$(( $debug + 1 )) ;;
439c535eb59SGordon Tetlow		f)	fflag=fflag ;;
440c535eb59SGordon Tetlow		h)	man_usage 0 ;;
441c535eb59SGordon Tetlow		k)	kflag=kflag ;;
442c535eb59SGordon Tetlow		m)	mflag=$OPTARG ;;
443c535eb59SGordon Tetlow		o)	oflag=oflag ;;
444c535eb59SGordon Tetlow		p)	MANROFFSEQ=$OPTARG ;;
445c535eb59SGordon Tetlow		t)	tflag=tflag ;;
446c535eb59SGordon Tetlow		w)	wflag=wflag ;;
447c535eb59SGordon Tetlow		*)	man_usage ;;
448c535eb59SGordon Tetlow		esac
449c535eb59SGordon Tetlow	done >&2
450c535eb59SGordon Tetlow
451c535eb59SGordon Tetlow	shift $(( $OPTIND - 1 ))
452c535eb59SGordon Tetlow
453c535eb59SGordon Tetlow	# Check the args for incompatible options.
454c535eb59SGordon Tetlow	case "${fflag}${kflag}${tflag}${wflag}" in
455c535eb59SGordon Tetlow	fflagkflag*)	echo "Incompatible options: -f and -k"; man_usage ;;
456c535eb59SGordon Tetlow	fflag*tflag*)	echo "Incompatible options: -f and -t"; man_usage ;;
457c535eb59SGordon Tetlow	fflag*wflag)	echo "Incompatible options: -f and -w"; man_usage ;;
458c535eb59SGordon Tetlow	*kflagtflag*)	echo "Incompatible options: -k and -t"; man_usage ;;
459c535eb59SGordon Tetlow	*kflag*wflag)	echo "Incompatible options: -k and -w"; man_usage ;;
460c535eb59SGordon Tetlow	*tflagwflag)	echo "Incompatible options: -t and -w"; man_usage ;;
461c535eb59SGordon Tetlow	esac
462c535eb59SGordon Tetlow
463c535eb59SGordon Tetlow	# Short circuit for whatis(1) and apropos(1)
464c535eb59SGordon Tetlow	if [ -n "$fflag" ]; then
465c535eb59SGordon Tetlow		do_whatis "$@"
466c535eb59SGordon Tetlow		exit
467c535eb59SGordon Tetlow	fi
468c535eb59SGordon Tetlow
469c535eb59SGordon Tetlow	if [ -n "$kflag" ]; then
470c535eb59SGordon Tetlow		do_apropos "$@"
471c535eb59SGordon Tetlow		exit
472c535eb59SGordon Tetlow	fi
473c535eb59SGordon Tetlow
474c535eb59SGordon Tetlow	IFS=:
475c535eb59SGordon Tetlow	for sect in $man_default_sections; do
476c535eb59SGordon Tetlow		if [ "$sect" = "$1" ]; then
477c535eb59SGordon Tetlow			decho "Detected manual section as first arg: $1"
478c535eb59SGordon Tetlow			MANSECT="$1"
479c535eb59SGordon Tetlow			shift
480c535eb59SGordon Tetlow			break
481c535eb59SGordon Tetlow		fi
482c535eb59SGordon Tetlow	done
483c535eb59SGordon Tetlow	unset IFS
484c535eb59SGordon Tetlow
485c535eb59SGordon Tetlow	pages="$*"
486c535eb59SGordon Tetlow}
487c535eb59SGordon Tetlow
488c535eb59SGordon Tetlow# Usage: man_setup
489c535eb59SGordon Tetlow# Setup various trivial but essential variables.
490c535eb59SGordon Tetlowman_setup() {
491c535eb59SGordon Tetlow	# Setup machine and architecture variables.
492c535eb59SGordon Tetlow	if [ -n "$mflag" ]; then
493c535eb59SGordon Tetlow		MACHINE_ARCH=${mflag%%:*}
494c535eb59SGordon Tetlow		MACHINE=${mflag##*:}
495c535eb59SGordon Tetlow	fi
496c535eb59SGordon Tetlow	if [ -z "$MACHINE_ARCH" ]; then
497c535eb59SGordon Tetlow		MACHINE_ARCH=$(sysctl -n hw.machine_arch)
498c535eb59SGordon Tetlow	fi
499c535eb59SGordon Tetlow	if [ -z "$MACHINE" ]; then
500c535eb59SGordon Tetlow		MACHINE=$(sysctl -n hw.machine)
501c535eb59SGordon Tetlow	fi
502c535eb59SGordon Tetlow	decho "Using architecture: $MACHINE_ARCH:$MACHINE"
503c535eb59SGordon Tetlow
504c535eb59SGordon Tetlow	setup_pager
505c535eb59SGordon Tetlow
506c535eb59SGordon Tetlow	# Setup manual sections to search.
507c535eb59SGordon Tetlow	if [ -z "$MANSECT" ]; then
508c535eb59SGordon Tetlow		MANSECT=$man_default_sections
509c535eb59SGordon Tetlow	fi
510c535eb59SGordon Tetlow	decho "Using manual sections: $MANSECT"
511c535eb59SGordon Tetlow
512c535eb59SGordon Tetlow	build_manpath
513c535eb59SGordon Tetlow	man_setup_locale
514c535eb59SGordon Tetlow}
515c535eb59SGordon Tetlow
516c535eb59SGordon Tetlow# Usage: man_setup_locale
517c535eb59SGordon Tetlow# Setup necessary locale variables.
518c535eb59SGordon Tetlowman_setup_locale() {
519c535eb59SGordon Tetlow	# Setup locale information.
520c535eb59SGordon Tetlow	if [ -n "$oflag" ]; then
521c535eb59SGordon Tetlow		decho "Using non-localized manpages"
522c535eb59SGordon Tetlow		unset use_locale
523c535eb59SGordon Tetlow	elif [ -n "$LC_ALL" ]; then
524c535eb59SGordon Tetlow		parse_locale "$LC_ALL"
525c535eb59SGordon Tetlow	elif [ -n "$LC_CTYPE" ]; then
526c535eb59SGordon Tetlow		parse_locale "$LC_CTYPE"
527c535eb59SGordon Tetlow	elif [ -n "$LANG" ]; then
528c535eb59SGordon Tetlow		parse_locale "$LANG"
529c535eb59SGordon Tetlow	fi
530c535eb59SGordon Tetlow
531c535eb59SGordon Tetlow	if [ -n "$use_locale" ]; then
532c535eb59SGordon Tetlow		locpaths="${man_lang}_${man_country}.${man_charset}"
533c535eb59SGordon Tetlow		locpaths="$locpaths:$man_lang.$man_charset"
534c535eb59SGordon Tetlow		if [ "$man_lang" != "en" ]; then
535c535eb59SGordon Tetlow			locpaths="$locpaths:en.$man_charset"
536c535eb59SGordon Tetlow		fi
537c535eb59SGordon Tetlow		locpaths="$locpaths:."
538c535eb59SGordon Tetlow	else
539c535eb59SGordon Tetlow		locpaths="."
540c535eb59SGordon Tetlow	fi
541c535eb59SGordon Tetlow	decho "Using locale paths: $locpaths"
542c535eb59SGordon Tetlow}
543c535eb59SGordon Tetlow
544c535eb59SGordon Tetlow# Usage: man_usage [exitcode]
545c535eb59SGordon Tetlow# Display usage for the man utility.
546c535eb59SGordon Tetlowman_usage() {
547c535eb59SGordon Tetlow	echo 'Usage:'
548c535eb59SGordon Tetlow	echo ' man [-adho] [-t | -w] [-M manpath] [-P pager] [-S mansect]'
549c535eb59SGordon Tetlow	echo '     [-m arch[:machine]] [-p [eprtv]] [mansect] page [...]'
550c535eb59SGordon Tetlow	echo ' man -f page [...] -- Emulates whatis(1)'
551c535eb59SGordon Tetlow	echo ' man -k page [...] -- Emulates apropos(1)'
552c535eb59SGordon Tetlow
553c535eb59SGordon Tetlow	# When exit'ing with -h, it's not an error.
554c535eb59SGordon Tetlow	exit ${1:-1}
555c535eb59SGordon Tetlow}
556c535eb59SGordon Tetlow
557c535eb59SGordon Tetlow# Usage: parse_configs
558c535eb59SGordon Tetlow# Reads the end-user adjustable config files.
559c535eb59SGordon Tetlowparse_configs() {
560c535eb59SGordon Tetlow	local IFS file files
561c535eb59SGordon Tetlow
562c535eb59SGordon Tetlow	if [ -n "$parsed_configs" ]; then
563c535eb59SGordon Tetlow		return
564c535eb59SGordon Tetlow	fi
565c535eb59SGordon Tetlow
566c535eb59SGordon Tetlow	unset IFS
567c535eb59SGordon Tetlow
568c535eb59SGordon Tetlow	# Read the global config first in case the user wants
569c535eb59SGordon Tetlow	# to override config_local.
570c535eb59SGordon Tetlow	if [ -r "$config_global" ]; then
571c535eb59SGordon Tetlow		parse_file "$config_global"
572c535eb59SGordon Tetlow	fi
573c535eb59SGordon Tetlow
574c535eb59SGordon Tetlow	# Glob the list of files to parse.
575c535eb59SGordon Tetlow	set +f
576c535eb59SGordon Tetlow	files=$(echo $config_local)
577c535eb59SGordon Tetlow	set -f
578c535eb59SGordon Tetlow
579c535eb59SGordon Tetlow	for file in $files; do
580c535eb59SGordon Tetlow		if [ -r "$file" ]; then
581c535eb59SGordon Tetlow			parse_file "$file"
582c535eb59SGordon Tetlow		fi
583c535eb59SGordon Tetlow	done
584c535eb59SGordon Tetlow
585c535eb59SGordon Tetlow	parsed_configs='yes'
586c535eb59SGordon Tetlow}
587c535eb59SGordon Tetlow
588c535eb59SGordon Tetlow# Usage: parse_file file
589c535eb59SGordon Tetlow# Reads the specified config files.
590c535eb59SGordon Tetlowparse_file() {
591c535eb59SGordon Tetlow	local file line tstr var
592c535eb59SGordon Tetlow
593c535eb59SGordon Tetlow	file="$1"
594c535eb59SGordon Tetlow	decho "Parsing config file: $file"
595c535eb59SGordon Tetlow	while read line; do
596c535eb59SGordon Tetlow		decho "  $line" 2
597c535eb59SGordon Tetlow		case "$line" in
598c535eb59SGordon Tetlow		\#*)		decho "    Comment" 3
599c535eb59SGordon Tetlow				;;
600c535eb59SGordon Tetlow		MANPATH*)	decho "    MANPATH" 3
601c535eb59SGordon Tetlow				trim "${line#MANPATH}"
602c535eb59SGordon Tetlow				add_to_manpath "$tstr"
603c535eb59SGordon Tetlow				;;
604c535eb59SGordon Tetlow		MANLOCALE*)	decho "    MANLOCALE" 3
605c535eb59SGordon Tetlow				trim "${line#MANLOCALE}"
606c535eb59SGordon Tetlow				manlocales="$manlocales:$tstr"
607c535eb59SGordon Tetlow				;;
608c535eb59SGordon Tetlow		MANCONFIG*)	decho "    MANCONFIG" 3
609c535eb59SGordon Tetlow				trim "${line#MANCONF}"
610c535eb59SGordon Tetlow				config_local="$tstr"
611c535eb59SGordon Tetlow				;;
612c535eb59SGordon Tetlow		# Set variables in the form of FOO_BAR
613c535eb59SGordon Tetlow		*_*[\ \	]*)	var="${line%%[\ \	]*}"
614c535eb59SGordon Tetlow				trim "${line#$var}"
615c535eb59SGordon Tetlow				eval "$var=\"$tstr\""
616c535eb59SGordon Tetlow				decho "    Parsed $var" 3
617c535eb59SGordon Tetlow				;;
618c535eb59SGordon Tetlow		esac
619c535eb59SGordon Tetlow	done < "$file"
620c535eb59SGordon Tetlow}
621c535eb59SGordon Tetlow
622c535eb59SGordon Tetlow# Usage: parse_locale localestring
623c535eb59SGordon Tetlow# Setup locale variables for proper parsing.
624c535eb59SGordon Tetlowparse_locale() {
625c535eb59SGordon Tetlow	local lang_cc
626c535eb59SGordon Tetlow
627c535eb59SGordon Tetlow	case "$1" in
628c535eb59SGordon Tetlow	C)				;;
629c535eb59SGordon Tetlow	POSIX)				;;
630c535eb59SGordon Tetlow	[a-z][a-z]_[A-Z][A-Z]\.*)	lang_cc="${1%.*}"
631c535eb59SGordon Tetlow					man_lang="${1%_*}"
632c535eb59SGordon Tetlow					man_country="${lang_cc#*_}"
633c535eb59SGordon Tetlow					man_charset="${1#*.}"
634c535eb59SGordon Tetlow					use_locale=yes
635c535eb59SGordon Tetlow					return 0
636c535eb59SGordon Tetlow					;;
637c535eb59SGordon Tetlow	*)				echo 'Unknown locale, assuming C' >&2
638c535eb59SGordon Tetlow					;;
639c535eb59SGordon Tetlow	esac
640c535eb59SGordon Tetlow
641c535eb59SGordon Tetlow	unset use_locale
642c535eb59SGordon Tetlow}
643c535eb59SGordon Tetlow
644c535eb59SGordon Tetlow# Usage: search_path
645c535eb59SGordon Tetlow# Traverse $PATH looking for manpaths.
646c535eb59SGordon Tetlowsearch_path() {
647c535eb59SGordon Tetlow	local IFS p path
648c535eb59SGordon Tetlow
649c535eb59SGordon Tetlow	decho "Searching PATH for man directories"
650c535eb59SGordon Tetlow
651c535eb59SGordon Tetlow	IFS=:
652c535eb59SGordon Tetlow	for path in $PATH; do
653c535eb59SGordon Tetlow		# Do a little special casing since the base manpages
654c535eb59SGordon Tetlow		# are in /usr/share/man instead of /usr/man or /man.
655c535eb59SGordon Tetlow		case "$path" in
656c535eb59SGordon Tetlow		/bin|/usr/bin)	add_to_manpath "/usr/share/man" ;;
657c535eb59SGordon Tetlow		*)	if add_to_manpath "$path/man"; then
658c535eb59SGordon Tetlow				:
659c535eb59SGordon Tetlow			elif add_to_manpath "$path/MAN"; then
660c535eb59SGordon Tetlow				:
661c535eb59SGordon Tetlow			else
662c535eb59SGordon Tetlow				case "$path" in
663c535eb59SGordon Tetlow				*/bin)	p="${path%/bin}/man"
664c535eb59SGordon Tetlow					add_to_manpath "$p"
665c535eb59SGordon Tetlow					;;
666c535eb59SGordon Tetlow				*)	;;
667c535eb59SGordon Tetlow				esac
668c535eb59SGordon Tetlow			fi
669c535eb59SGordon Tetlow			;;
670c535eb59SGordon Tetlow		esac
671c535eb59SGordon Tetlow	done
672c535eb59SGordon Tetlow	unset IFS
673c535eb59SGordon Tetlow
674c535eb59SGordon Tetlow	if [ -z "$manpath" ]; then
675c535eb59SGordon Tetlow		decho '  Unable to find any manpaths, using default'
676c535eb59SGordon Tetlow		manpath=$man_default_path
677c535eb59SGordon Tetlow	fi
678c535eb59SGordon Tetlow}
679c535eb59SGordon Tetlow
680c535eb59SGordon Tetlow# Usage: search_whatis cmd [arglist]
681c535eb59SGordon Tetlow# Do the heavy lifting for apropos/whatis
682c535eb59SGordon Tetlowsearch_whatis() {
683c535eb59SGordon Tetlow	local IFS bad cmd f good key keywords loc opt out path rval wlist
684c535eb59SGordon Tetlow
685c535eb59SGordon Tetlow	cmd="$1"
686c535eb59SGordon Tetlow	shift
687c535eb59SGordon Tetlow
688c535eb59SGordon Tetlow	whatis_parse_args "$@"
689c535eb59SGordon Tetlow
690c535eb59SGordon Tetlow	build_manpath
691c535eb59SGordon Tetlow	build_manlocales
692c535eb59SGordon Tetlow	setup_pager
693c535eb59SGordon Tetlow
694c535eb59SGordon Tetlow	if [ "$cmd" = "whatis" ]; then
695c535eb59SGordon Tetlow		opt="-w"
696c535eb59SGordon Tetlow	fi
697c535eb59SGordon Tetlow
698c535eb59SGordon Tetlow	f='whatis'
699c535eb59SGordon Tetlow
700c535eb59SGordon Tetlow	IFS=:
701c535eb59SGordon Tetlow	for path in $MANPATH; do
702c535eb59SGordon Tetlow		if [ \! -d "$path" ]; then
703c535eb59SGordon Tetlow			decho "Skipping non-existent path: $path" 2
704c535eb59SGordon Tetlow			continue
705c535eb59SGordon Tetlow		fi
706c535eb59SGordon Tetlow
707c535eb59SGordon Tetlow		if [ -f "$path/$f" -a -r "$path/$f" ]; then
708c535eb59SGordon Tetlow			decho "Found whatis: $path/$f"
709c535eb59SGordon Tetlow			wlist="$wlist $path/$f"
710c535eb59SGordon Tetlow		fi
711c535eb59SGordon Tetlow
712c535eb59SGordon Tetlow		for loc in $MANLOCALES; do
713c535eb59SGordon Tetlow			if [ -f "$path/$loc/$f" -a -r "$path/$loc/$f" ]; then
714c535eb59SGordon Tetlow				decho "Found whatis: $path/$loc/$f"
715c535eb59SGordon Tetlow				wlist="$wlist $path/$loc/$f"
716c535eb59SGordon Tetlow			fi
717c535eb59SGordon Tetlow		done
718c535eb59SGordon Tetlow	done
719c535eb59SGordon Tetlow	unset IFS
720c535eb59SGordon Tetlow
721c535eb59SGordon Tetlow	if [ -z "$wlist" ]; then
722c535eb59SGordon Tetlow		echo "$cmd: no whatis databases in $MANPATH" >&2
723c535eb59SGordon Tetlow		exit 1
724c535eb59SGordon Tetlow	fi
725c535eb59SGordon Tetlow
726c535eb59SGordon Tetlow	rval=0
727c535eb59SGordon Tetlow	for key in $keywords; do
728c535eb59SGordon Tetlow		out=$(grep -Ehi $opt -- "$key" $wlist)
729c535eb59SGordon Tetlow		if [ -n "$out" ]; then
730c535eb59SGordon Tetlow			good="$good\\n$out"
731c535eb59SGordon Tetlow		else
732c535eb59SGordon Tetlow			bad="$bad\\n$key: nothing appropriate"
733c535eb59SGordon Tetlow			rval=1
734c535eb59SGordon Tetlow		fi
735c535eb59SGordon Tetlow	done
736c535eb59SGordon Tetlow
737c535eb59SGordon Tetlow	# Strip leading carriage return.
738c535eb59SGordon Tetlow	good=${good#\\n}
739c535eb59SGordon Tetlow	bad=${bad#\\n}
740c535eb59SGordon Tetlow
741c535eb59SGordon Tetlow	if [ -n "$good" ]; then
74200e05e69SGordon Tetlow		echo -e "$good" | $PAGER
743c535eb59SGordon Tetlow	fi
744c535eb59SGordon Tetlow
745c535eb59SGordon Tetlow	if [ -n "$bad" ]; then
74600e05e69SGordon Tetlow		echo -e "$bad" >&2
747c535eb59SGordon Tetlow	fi
748c535eb59SGordon Tetlow
749c535eb59SGordon Tetlow	exit $rval
750c535eb59SGordon Tetlow}
751c535eb59SGordon Tetlow
752c535eb59SGordon Tetlow# Usage: setup_pager
753c535eb59SGordon Tetlow# Correctly sets $PAGER
754c535eb59SGordon Tetlowsetup_pager() {
755c535eb59SGordon Tetlow	# Setup pager.
756c535eb59SGordon Tetlow	if [ -z "$PAGER" ]; then
757c535eb59SGordon Tetlow		PAGER="more -s"
758c535eb59SGordon Tetlow	fi
759c535eb59SGordon Tetlow	decho "Using pager: $PAGER"
760c535eb59SGordon Tetlow}
761c535eb59SGordon Tetlow
762c535eb59SGordon Tetlow# Usage: trim string
763c535eb59SGordon Tetlow# Trims whitespace from beginning and end of a variable
764c535eb59SGordon Tetlowtrim() {
765c535eb59SGordon Tetlow	tstr=$1
766c535eb59SGordon Tetlow	while true; do
767c535eb59SGordon Tetlow		case "$tstr" in
768c535eb59SGordon Tetlow		[\ \	]*)	tstr="${tstr##[\ \	]}" ;;
769c535eb59SGordon Tetlow		*[\ \	])	tstr="${tstr%%[\ \	]}" ;;
770c535eb59SGordon Tetlow		*)		break ;;
771c535eb59SGordon Tetlow		esac
772c535eb59SGordon Tetlow	done
773c535eb59SGordon Tetlow}
774c535eb59SGordon Tetlow
775c535eb59SGordon Tetlow# Usage: whatis_parse_args "$@"
776c535eb59SGordon Tetlow# Parse commandline args for whatis and apropos.
777c535eb59SGordon Tetlowwhatis_parse_args() {
778c535eb59SGordon Tetlow	local cmd_arg
779c535eb59SGordon Tetlow	while getopts 'd' cmd_arg; do
780c535eb59SGordon Tetlow		case "${cmd_arg}" in
781c535eb59SGordon Tetlow		d)	debug=$(( $debug + 1 )) ;;
782c535eb59SGordon Tetlow		*)	whatis_usage ;;
783c535eb59SGordon Tetlow		esac
784c535eb59SGordon Tetlow	done >&2
785c535eb59SGordon Tetlow
786c535eb59SGordon Tetlow	shift $(( $OPTIND - 1 ))
787c535eb59SGordon Tetlow
788c535eb59SGordon Tetlow	keywords="$*"
789c535eb59SGordon Tetlow}
790c535eb59SGordon Tetlow
791c535eb59SGordon Tetlow# Usage: whatis_usage
792c535eb59SGordon Tetlow# Display usage for the whatis/apropos utility.
793c535eb59SGordon Tetlowwhatis_usage() {
794c535eb59SGordon Tetlow	echo "usage: $cmd [-d] keyword [...]"
795c535eb59SGordon Tetlow	exit 1
796c535eb59SGordon Tetlow}
797c535eb59SGordon Tetlow
798c535eb59SGordon Tetlow
799c535eb59SGordon Tetlow
800c535eb59SGordon Tetlow# Supported commands
801c535eb59SGordon Tetlowdo_apropos() {
802c535eb59SGordon Tetlow	search_whatis apropos "$@"
803c535eb59SGordon Tetlow}
804c535eb59SGordon Tetlow
805c535eb59SGordon Tetlowdo_man() {
806c535eb59SGordon Tetlow	man_parse_args "$@"
807c535eb59SGordon Tetlow	if [ -z "$pages" ]; then
808c535eb59SGordon Tetlow		echo 'What manual page do you want?' >&2
809c535eb59SGordon Tetlow		exit 1
810c535eb59SGordon Tetlow	fi
811c535eb59SGordon Tetlow	man_setup
812c535eb59SGordon Tetlow
813c535eb59SGordon Tetlow	for page in $pages; do
814c535eb59SGordon Tetlow		decho "Searching for $page"
815c535eb59SGordon Tetlow		man_find_and_display "$page"
816c535eb59SGordon Tetlow	done
817c535eb59SGordon Tetlow
818c535eb59SGordon Tetlow	exit ${ret:-0}
819c535eb59SGordon Tetlow}
820c535eb59SGordon Tetlow
821c535eb59SGordon Tetlowdo_manpath() {
822c535eb59SGordon Tetlow	manpath_parse_args "$@"
823c535eb59SGordon Tetlow	if [ -z "$qflag" ]; then
824c535eb59SGordon Tetlow		manpath_warnings
825c535eb59SGordon Tetlow	fi
826c535eb59SGordon Tetlow	if [ -n "$Lflag" ]; then
827c535eb59SGordon Tetlow		build_manlocales
828c535eb59SGordon Tetlow		echo $MANLOCALES
829c535eb59SGordon Tetlow	else
830c535eb59SGordon Tetlow		build_manpath
831c535eb59SGordon Tetlow		echo $MANPATH
832c535eb59SGordon Tetlow	fi
833c535eb59SGordon Tetlow	exit 0
834c535eb59SGordon Tetlow}
835c535eb59SGordon Tetlow
836c535eb59SGordon Tetlowdo_whatis() {
837c535eb59SGordon Tetlow	search_whatis whatis "$@"
838c535eb59SGordon Tetlow}
839c535eb59SGordon Tetlow
840c535eb59SGordon TetlowEQN=/usr/bin/eqn
841c535eb59SGordon TetlowCOL=/usr/bin/col
842c535eb59SGordon TetlowNROFF='/usr/bin/groff -S -Wall -mtty-char -man'
843c535eb59SGordon TetlowPIC=/usr/bin/pic
844c535eb59SGordon TetlowTBL=/usr/bin/tbl
845c535eb59SGordon TetlowTROFF='/usr/bin/groff -S -man'
846c535eb59SGordon TetlowREFER=/usr/bin/refer
847c535eb59SGordon TetlowVGRIND=/usr/bin/vgrind
848c535eb59SGordon TetlowZCAT='/usr/bin/zcat -f'
849c535eb59SGordon Tetlow
850c535eb59SGordon Tetlowdebug=0
851c535eb59SGordon Tetlowman_default_sections='1:1aout:8:2:3:n:4:5:6:7:9:l'
852c535eb59SGordon Tetlowman_default_path='/usr/share/man:/usr/share/openssl/man:/usr/local/man'
853c535eb59SGordon Tetlow
854c535eb59SGordon Tetlowconfig_global='/etc/man.conf'
855c535eb59SGordon Tetlow
856c535eb59SGordon Tetlow# This can be overridden via a setting in /etc/man.conf.
857c535eb59SGordon Tetlowconfig_local='/usr/local/etc/man.d/*.conf'
858c535eb59SGordon Tetlow
859c535eb59SGordon Tetlow# Set noglobbing for now. I don't want spurious globbing.
860c535eb59SGordon Tetlowset -f
861c535eb59SGordon Tetlow
862c535eb59SGordon Tetlowcase "$0" in
863c535eb59SGordon Tetlow*apropos)	do_apropos "$@" ;;
864c535eb59SGordon Tetlow*manpath)	do_manpath "$@" ;;
865c535eb59SGordon Tetlow*whatis)	do_whatis "$@" ;;
866c535eb59SGordon Tetlow*)		do_man "$@" ;;
867c535eb59SGordon Tetlowesac
868