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 9757cd9717SGordon Tetlow setup_cattool $catpage 98c535eb59SGordon Tetlow decho " Found catpage $catpage" 99c535eb59SGordon Tetlow return 0 100c535eb59SGordon Tetlow else 101c535eb59SGordon Tetlow return 1 102c535eb59SGordon Tetlow fi 103c535eb59SGordon Tetlow} 104c535eb59SGordon Tetlow 105c535eb59SGordon Tetlow# Usage: check_man manglob catglob 106c535eb59SGordon Tetlow# Given 2 globs, figures out if the manglob is available, if so, check to 107c535eb59SGordon Tetlow# see if the catglob is also available and up to date. 108c535eb59SGordon Tetlowcheck_man() { 109c535eb59SGordon Tetlow if exists "$1"; then 110c535eb59SGordon Tetlow # We have a match, check for a cat page 111c535eb59SGordon Tetlow manpage=$found 11257cd9717SGordon Tetlow setup_cattool $manpage 113c535eb59SGordon Tetlow decho " Found manpage $manpage" 114c535eb59SGordon Tetlow 115c535eb59SGordon Tetlow if exists "$2" && is_newer $found $manpage; then 116c535eb59SGordon Tetlow # cat page found and is newer, use that 117c535eb59SGordon Tetlow use_cat=yes 118c535eb59SGordon Tetlow catpage=$found 11957cd9717SGordon Tetlow setup_cattool $catpage 120c535eb59SGordon Tetlow decho " Using catpage $catpage" 121c535eb59SGordon Tetlow else 122c535eb59SGordon Tetlow # no cat page or is older 123c535eb59SGordon Tetlow unset use_cat 124c535eb59SGordon Tetlow decho " Skipping catpage: not found or old" 125c535eb59SGordon Tetlow fi 126c535eb59SGordon Tetlow return 0 127c535eb59SGordon Tetlow fi 128c535eb59SGordon Tetlow 129c535eb59SGordon Tetlow return 1 130c535eb59SGordon Tetlow} 131c535eb59SGordon Tetlow 132c535eb59SGordon Tetlow# Usage: decho "string" [debuglevel] 133c535eb59SGordon Tetlow# Echoes to stderr string prefaced with -- if high enough debuglevel. 134c535eb59SGordon Tetlowdecho() { 135c535eb59SGordon Tetlow if [ $debug -ge ${2:-1} ]; then 136c535eb59SGordon Tetlow echo "-- $1" >&2 137c535eb59SGordon Tetlow fi 138c535eb59SGordon Tetlow} 139c535eb59SGordon Tetlow 140c535eb59SGordon Tetlow# Usage: exists glob 141c535eb59SGordon Tetlow# Returns true if glob resolves to a real file. 142c535eb59SGordon Tetlowexists() { 143c535eb59SGordon Tetlow local IFS 144c535eb59SGordon Tetlow 145c535eb59SGordon Tetlow # Don't accidentally inherit callers IFS (breaks perl manpages) 146c535eb59SGordon Tetlow unset IFS 147c535eb59SGordon Tetlow 148c535eb59SGordon Tetlow # Use some globbing tricks in the shell to determine if a file 149c535eb59SGordon Tetlow # exists or not. 150c535eb59SGordon Tetlow set +f 151c535eb59SGordon Tetlow set -- "$1" $1 152c535eb59SGordon Tetlow set -f 153c535eb59SGordon Tetlow 154c535eb59SGordon Tetlow if [ "$1" != "$2" -a -r "$2" ]; then 155c535eb59SGordon Tetlow found="$2" 156c535eb59SGordon Tetlow return 0 157c535eb59SGordon Tetlow fi 158c535eb59SGordon Tetlow 159c535eb59SGordon Tetlow return 1 160c535eb59SGordon Tetlow} 161c535eb59SGordon Tetlow 162c535eb59SGordon Tetlow# Usage: find_file path section subdir pagename 163c535eb59SGordon Tetlow# Returns: true if something is matched and found. 164c535eb59SGordon Tetlow# Search the given path/section combo for a given page. 165c535eb59SGordon Tetlowfind_file() { 166c535eb59SGordon Tetlow local manroot catroot mann man0 catn cat0 167c535eb59SGordon Tetlow 168c535eb59SGordon Tetlow manroot="$1/man$2" 169c535eb59SGordon Tetlow catroot="$1/cat$2" 170c535eb59SGordon Tetlow if [ -n "$3" ]; then 171c535eb59SGordon Tetlow manroot="$manroot/$3" 172c535eb59SGordon Tetlow catroot="$catroot/$3" 173c535eb59SGordon Tetlow fi 174c535eb59SGordon Tetlow 175c535eb59SGordon Tetlow if [ ! -d "$manroot" ]; then 176c535eb59SGordon Tetlow return 1 177c535eb59SGordon Tetlow fi 178c535eb59SGordon Tetlow decho " Searching directory $manroot" 2 179c535eb59SGordon Tetlow 180c535eb59SGordon Tetlow mann="$manroot/$4.$2*" 181c535eb59SGordon Tetlow man0="$manroot/$4.0*" 182c535eb59SGordon Tetlow catn="$catroot/$4.$2*" 183c535eb59SGordon Tetlow cat0="$catroot/$4.0*" 184c535eb59SGordon Tetlow 185c535eb59SGordon Tetlow # This is the behavior as seen by the original man utility. 186c535eb59SGordon Tetlow # Let's not change that which doesn't seem broken. 187c535eb59SGordon Tetlow if check_man "$mann" "$catn"; then 188c535eb59SGordon Tetlow return 0 189c535eb59SGordon Tetlow elif check_man "$man0" "$cat0"; then 190c535eb59SGordon Tetlow return 0 191c535eb59SGordon Tetlow elif check_cat "$catn"; then 192c535eb59SGordon Tetlow return 0 193c535eb59SGordon Tetlow elif check_cat "$cat0"; then 194c535eb59SGordon Tetlow return 0 195c535eb59SGordon Tetlow fi 196c535eb59SGordon Tetlow 197c535eb59SGordon Tetlow return 1 198c535eb59SGordon Tetlow} 199c535eb59SGordon Tetlow 200c535eb59SGordon Tetlow# Usage: is_newer file1 file2 201c535eb59SGordon Tetlow# Returns true if file1 is newer than file2 as calculated by mtime. 202c535eb59SGordon Tetlowis_newer() { 203c535eb59SGordon Tetlow if [ $(stat -f %m $1) -gt $(stat -f %m $2) ]; then 204c535eb59SGordon Tetlow decho " mtime: $1 newer than $2" 3 205c535eb59SGordon Tetlow return 0 206c535eb59SGordon Tetlow else 207c535eb59SGordon Tetlow decho " mtime: $1 older than $2" 3 208c535eb59SGordon Tetlow return 1 209c535eb59SGordon Tetlow fi 210c535eb59SGordon Tetlow} 211c535eb59SGordon Tetlow 212c535eb59SGordon Tetlow# Usage: manpath_parse_args "$@" 213c535eb59SGordon Tetlow# Parses commandline options for manpath. 214c535eb59SGordon Tetlowmanpath_parse_args() { 215c535eb59SGordon Tetlow local cmd_arg 216c535eb59SGordon Tetlow 217c535eb59SGordon Tetlow while getopts 'Ldq' cmd_arg; do 218c535eb59SGordon Tetlow case "${cmd_arg}" in 219c535eb59SGordon Tetlow L) Lflag=Lflag ;; 220c535eb59SGordon Tetlow d) debug=$(( $debug + 1 )) ;; 221c535eb59SGordon Tetlow q) qflag=qflag ;; 222c535eb59SGordon Tetlow *) manpath_usage ;; 223c535eb59SGordon Tetlow esac 224c535eb59SGordon Tetlow done >&2 225c535eb59SGordon Tetlow} 226c535eb59SGordon Tetlow 227c535eb59SGordon Tetlow# Usage: manpath_usage 228c535eb59SGordon Tetlow# Display usage for the manpath(1) utility. 229c535eb59SGordon Tetlowmanpath_usage() { 230c535eb59SGordon Tetlow echo 'usage: manpath [-Ldq]' >&2 231c535eb59SGordon Tetlow exit 1 232c535eb59SGordon Tetlow} 233c535eb59SGordon Tetlow 234c535eb59SGordon Tetlow# Usage: manpath_warnings 235c535eb59SGordon Tetlow# Display some warnings to stderr. 236c535eb59SGordon Tetlowmanpath_warnings() { 237c535eb59SGordon Tetlow if [ -z "$Lflag" -a -n "$MANPATH" ]; then 238c535eb59SGordon Tetlow echo "(Warning: MANPATH environment variable set)" >&2 239c535eb59SGordon Tetlow fi 240c535eb59SGordon Tetlow 241c535eb59SGordon Tetlow if [ -n "$Lflag" -a -n "$MANLOCALES" ]; then 242c535eb59SGordon Tetlow echo "(Warning: MANLOCALES environment variable set)" >&2 243c535eb59SGordon Tetlow fi 244c535eb59SGordon Tetlow} 245c535eb59SGordon Tetlow 24657cd9717SGordon Tetlow# Usage: man_check_for_so page path 24757cd9717SGordon Tetlow# Returns: True if able to resolve the file, false if it ended in tears. 24857cd9717SGordon Tetlow# Detects the presence of the .so directive and causes the file to be 24957cd9717SGordon Tetlow# redirected to another source file. 25057cd9717SGordon Tetlowman_check_for_so() { 25157cd9717SGordon Tetlow local IFS line tstr 25257cd9717SGordon Tetlow 25357cd9717SGordon Tetlow unset IFS 25457cd9717SGordon Tetlow 25557cd9717SGordon Tetlow # We need to loop to accommodate multiple .so directives. 25657cd9717SGordon Tetlow while true 25757cd9717SGordon Tetlow do 25857cd9717SGordon Tetlow line=$($cattool $manpage | head -1) 25957cd9717SGordon Tetlow case "$line" in 26057cd9717SGordon Tetlow .so*) trim "${line#.so}" 26157cd9717SGordon Tetlow decho "$manpage includes $tstr" 26257cd9717SGordon Tetlow # Glob and check for the file. 26357cd9717SGordon Tetlow if ! check_man "$path/$tstr*" ""; then 26457cd9717SGordon Tetlow decho " Unable to find $tstr" 26557cd9717SGordon Tetlow return 1 26657cd9717SGordon Tetlow fi 26757cd9717SGordon Tetlow ;; 26857cd9717SGordon Tetlow *) break ;; 26957cd9717SGordon Tetlow esac 27057cd9717SGordon Tetlow done 27157cd9717SGordon Tetlow 27257cd9717SGordon Tetlow return 0 27357cd9717SGordon Tetlow} 27457cd9717SGordon Tetlow 275c535eb59SGordon Tetlow# Usage: man_display_page 276c535eb59SGordon Tetlow# Display either the manpage or catpage depending on the use_cat variable 277c535eb59SGordon Tetlowman_display_page() { 278c535eb59SGordon Tetlow local EQN COL NROFF PIC TBL TROFF REFER VGRIND 279c535eb59SGordon Tetlow local IFS l nroff_dev pipeline preproc_arg tool 280c535eb59SGordon Tetlow 281c535eb59SGordon Tetlow # We are called with IFS set to colon. This causes really weird 282c535eb59SGordon Tetlow # things to happen for the variables that have spaces in them. 283c535eb59SGordon Tetlow unset IFS 284c535eb59SGordon Tetlow 285c535eb59SGordon Tetlow # If we are supposed to use a catpage and we aren't using troff(1) 286c535eb59SGordon Tetlow # just zcat the catpage and we are done. 287c535eb59SGordon Tetlow if [ -z "$tflag" -a -n "$use_cat" ]; then 288c535eb59SGordon Tetlow if [ -n "$wflag" ]; then 289c535eb59SGordon Tetlow echo "$catpage (source: $manpage)" 290c535eb59SGordon Tetlow ret=0 291c535eb59SGordon Tetlow else 292c535eb59SGordon Tetlow if [ $debug -gt 0 ]; then 29357cd9717SGordon Tetlow decho "Command: $cattool $catpage | $PAGER" 294c535eb59SGordon Tetlow ret=0 295c535eb59SGordon Tetlow else 29657cd9717SGordon Tetlow eval "$cattool $catpage | $PAGER" 297c535eb59SGordon Tetlow ret=$? 298c535eb59SGordon Tetlow fi 299c535eb59SGordon Tetlow fi 300c535eb59SGordon Tetlow return 301c535eb59SGordon Tetlow fi 302c535eb59SGordon Tetlow 303c535eb59SGordon Tetlow # Okay, we are using the manpage, do we just need to output the 304c535eb59SGordon Tetlow # name of the manpage? 305c535eb59SGordon Tetlow if [ -n "$wflag" ]; then 306c535eb59SGordon Tetlow echo "$manpage" 307c535eb59SGordon Tetlow ret=0 308c535eb59SGordon Tetlow return 309c535eb59SGordon Tetlow fi 310c535eb59SGordon Tetlow 311c535eb59SGordon Tetlow # So, we really do need to parse the manpage. First, figure out the 312c535eb59SGordon Tetlow # device flag (-T) we have to pass to eqn(1) and groff(1). Then, 313c535eb59SGordon Tetlow # setup the pipeline of commands based on the user's request. 314c535eb59SGordon Tetlow 315c535eb59SGordon Tetlow # Apparently the locale flags are switched on where the manpage is 316c535eb59SGordon Tetlow # found not just the locale env variables. 317c535eb59SGordon Tetlow nroff_dev="ascii" 318c535eb59SGordon Tetlow case "X${use_locale}X${manpage}" in 319c535eb59SGordon Tetlow XyesX*/${man_lang}*${man_charset}/*) 320c535eb59SGordon Tetlow # I don't pretend to know this; I'm just copying from the 321c535eb59SGordon Tetlow # previous version of man(1). 322c535eb59SGordon Tetlow case "$man_charset" in 323c535eb59SGordon Tetlow KOI8-R) nroff_dev="koi8-r" ;; 324c535eb59SGordon Tetlow ISO8859-1) nroff_dev="latin1" ;; 325c535eb59SGordon Tetlow ISO8859-15) nroff_dev="latin1" ;; 326c535eb59SGordon Tetlow UTF-8) nroff_dev="utf8" ;; 327c535eb59SGordon Tetlow *) nroff_dev="ascii" ;; 328c535eb59SGordon Tetlow esac 329c535eb59SGordon Tetlow 330c535eb59SGordon Tetlow NROFF="$NROFF -T$nroff_dev -dlocale=$man_lang.$man_charset" 331c535eb59SGordon Tetlow EQN="$EQN -T$nroff_dev" 332c535eb59SGordon Tetlow 333c535eb59SGordon Tetlow # Allow language specific calls to override the default 334c535eb59SGordon Tetlow # set of utilities. 335c535eb59SGordon Tetlow l=$(echo $man_lang | tr [:lower:] [:upper:]) 336c535eb59SGordon Tetlow for tool in EQN COL NROFF PIC TBL TROFF REFER VGRIND; do 337c535eb59SGordon Tetlow eval "$tool=\${${tool}_$l:-\$$tool}" 338c535eb59SGordon Tetlow done 339c535eb59SGordon Tetlow ;; 340c535eb59SGordon Tetlow *) NROFF="$NROFF -Tascii" 341c535eb59SGordon Tetlow EQN="$EQN -Tascii" 342c535eb59SGordon Tetlow ;; 343c535eb59SGordon Tetlow esac 344c535eb59SGordon Tetlow 345c535eb59SGordon Tetlow if [ -n "$MANROFFSEQ" ]; then 346c535eb59SGordon Tetlow set -- -$MANROFFSEQ 347c535eb59SGordon Tetlow while getopts 'egprtv' preproc_arg; do 348c535eb59SGordon Tetlow case "${preproc_arg}" in 349c535eb59SGordon Tetlow e) pipeline="$pipeline | $EQN" ;; 350c535eb59SGordon Tetlow g) ;; # Ignore for compatability. 351c535eb59SGordon Tetlow p) pipeline="$pipeline | $PIC" ;; 352c535eb59SGordon Tetlow r) pipeline="$pipeline | $REFER" ;; 353c535eb59SGordon Tetlow t) pipeline="$pipeline | $TBL"; use_col=yes ;; 354c535eb59SGordon Tetlow v) pipeline="$pipeline | $VGRIND" ;; 355c535eb59SGordon Tetlow *) usage ;; 356c535eb59SGordon Tetlow esac 357c535eb59SGordon Tetlow done 358c535eb59SGordon Tetlow # Strip the leading " | " from the resulting pipeline. 359c535eb59SGordon Tetlow pipeline="${pipeline#" | "}" 360c535eb59SGordon Tetlow else 361c535eb59SGordon Tetlow pipeline="$TBL" 362c535eb59SGordon Tetlow use_col=yes 363c535eb59SGordon Tetlow fi 364c535eb59SGordon Tetlow 365c535eb59SGordon Tetlow if [ -n "$tflag" ]; then 366c535eb59SGordon Tetlow pipeline="$pipeline | $TROFF" 367c535eb59SGordon Tetlow else 368c535eb59SGordon Tetlow pipeline="$pipeline | $NROFF" 369c535eb59SGordon Tetlow 370c535eb59SGordon Tetlow if [ -n "$use_col" ]; then 371c535eb59SGordon Tetlow pipeline="$pipeline | $COL" 372c535eb59SGordon Tetlow fi 373c535eb59SGordon Tetlow 374c535eb59SGordon Tetlow pipeline="$pipeline | $PAGER" 375c535eb59SGordon Tetlow fi 376c535eb59SGordon Tetlow 377c535eb59SGordon Tetlow if [ $debug -gt 0 ]; then 37857cd9717SGordon Tetlow decho "Command: $cattool $manpage | $pipeline" 379c535eb59SGordon Tetlow ret=0 380c535eb59SGordon Tetlow else 38157cd9717SGordon Tetlow eval "$cattool $manpage | $pipeline" 382c535eb59SGordon Tetlow ret=$? 383c535eb59SGordon Tetlow fi 384c535eb59SGordon Tetlow} 385c535eb59SGordon Tetlow 386c535eb59SGordon Tetlow# Usage: man_find_and_display page 387c535eb59SGordon Tetlow# Search through the manpaths looking for the given page. 388c535eb59SGordon Tetlowman_find_and_display() { 389c535eb59SGordon Tetlow local found_page locpath p path sect 390c535eb59SGordon Tetlow 3913d9127f1SGordon Tetlow # Check to see if it's a file. But only if it has a '/' in 3923d9127f1SGordon Tetlow # the filename. 3933d9127f1SGordon Tetlow case "$1" in 3943d9127f1SGordon Tetlow */*) if [ -f "$1" -a -r "$1" ]; then 3953d9127f1SGordon Tetlow decho "Found a usable page, displaying that" 3963d9127f1SGordon Tetlow unset use_cat 3973d9127f1SGordon Tetlow manpage="$1" 39857cd9717SGordon Tetlow setup_cattool $manpage 39957cd9717SGordon Tetlow if man_check_for_so $manpage $(dirname $manpage); then 40057cd9717SGordon Tetlow found_page=yes 4013d9127f1SGordon Tetlow man_display_page 40257cd9717SGordon Tetlow fi 4033d9127f1SGordon Tetlow return 4043d9127f1SGordon Tetlow fi 4053d9127f1SGordon Tetlow ;; 4063d9127f1SGordon Tetlow esac 4073d9127f1SGordon Tetlow 408c535eb59SGordon Tetlow IFS=: 409c535eb59SGordon Tetlow for sect in $MANSECT; do 410c535eb59SGordon Tetlow decho "Searching section $sect" 2 411c535eb59SGordon Tetlow for path in $MANPATH; do 412c535eb59SGordon Tetlow for locpath in $locpaths; do 413c535eb59SGordon Tetlow p=$path/$locpath 414c535eb59SGordon Tetlow p=${p%/.} # Rid ourselves of the trailing /. 415c535eb59SGordon Tetlow 416c535eb59SGordon Tetlow # Check if there is a MACHINE specific manpath. 417c535eb59SGordon Tetlow if find_file $p $sect $MACHINE "$1"; then 41857cd9717SGordon Tetlow if man_check_for_so $manpage $p; then 419c535eb59SGordon Tetlow found_page=yes 420c535eb59SGordon Tetlow man_display_page 4211d7c660aSGordon Tetlow if [ -n "$aflag" ]; then 4221d7c660aSGordon Tetlow continue 2 4231d7c660aSGordon Tetlow else 424c535eb59SGordon Tetlow return 425c535eb59SGordon Tetlow fi 426c535eb59SGordon Tetlow fi 42757cd9717SGordon Tetlow fi 428c535eb59SGordon Tetlow 429c535eb59SGordon Tetlow # Check if there is a MACHINE_ARCH 430c535eb59SGordon Tetlow # specific manpath. 431c535eb59SGordon Tetlow if find_file $p $sect $MACHINE_ARCH "$1"; then 43257cd9717SGordon Tetlow if man_check_for_so $manpage $p; then 433c535eb59SGordon Tetlow found_page=yes 434c535eb59SGordon Tetlow man_display_page 4351d7c660aSGordon Tetlow if [ -n "$aflag" ]; then 4361d7c660aSGordon Tetlow continue 2 4371d7c660aSGordon Tetlow else 438c535eb59SGordon Tetlow return 439c535eb59SGordon Tetlow fi 440c535eb59SGordon Tetlow fi 44157cd9717SGordon Tetlow fi 442c535eb59SGordon Tetlow 443c535eb59SGordon Tetlow # Check plain old manpath. 444c535eb59SGordon Tetlow if find_file $p $sect '' "$1"; then 44557cd9717SGordon Tetlow if man_check_for_so $manpage $p; then 446c535eb59SGordon Tetlow found_page=yes 447c535eb59SGordon Tetlow man_display_page 4481d7c660aSGordon Tetlow if [ -n "$aflag" ]; then 4491d7c660aSGordon Tetlow continue 2 4501d7c660aSGordon Tetlow else 451c535eb59SGordon Tetlow return 452c535eb59SGordon Tetlow fi 453c535eb59SGordon Tetlow fi 45457cd9717SGordon Tetlow fi 455c535eb59SGordon Tetlow done 456c535eb59SGordon Tetlow done 457c535eb59SGordon Tetlow done 458c535eb59SGordon Tetlow unset IFS 459c535eb59SGordon Tetlow 460c535eb59SGordon Tetlow # Nothing? Well, we are done then. 461c535eb59SGordon Tetlow if [ -z "$found_page" ]; then 462c535eb59SGordon Tetlow echo "No manual entry for $1" >&2 463c535eb59SGordon Tetlow ret=1 464c535eb59SGordon Tetlow return 465c535eb59SGordon Tetlow fi 466c535eb59SGordon Tetlow} 467c535eb59SGordon Tetlow 468c535eb59SGordon Tetlow# Usage: man_parse_args "$@" 469c535eb59SGordon Tetlow# Parses commandline options for man. 470c535eb59SGordon Tetlowman_parse_args() { 471c535eb59SGordon Tetlow local IFS cmd_arg 472c535eb59SGordon Tetlow 473c535eb59SGordon Tetlow while getopts 'M:P:S:adfhkm:op:tw' cmd_arg; do 474c535eb59SGordon Tetlow case "${cmd_arg}" in 475c535eb59SGordon Tetlow M) MANPATH=$OPTARG ;; 476c535eb59SGordon Tetlow P) PAGER=$OPTARG ;; 477c535eb59SGordon Tetlow S) MANSECT=$OPTARG ;; 478c535eb59SGordon Tetlow a) aflag=aflag ;; 479c535eb59SGordon Tetlow d) debug=$(( $debug + 1 )) ;; 480c535eb59SGordon Tetlow f) fflag=fflag ;; 481c535eb59SGordon Tetlow h) man_usage 0 ;; 482c535eb59SGordon Tetlow k) kflag=kflag ;; 483c535eb59SGordon Tetlow m) mflag=$OPTARG ;; 484c535eb59SGordon Tetlow o) oflag=oflag ;; 485c535eb59SGordon Tetlow p) MANROFFSEQ=$OPTARG ;; 486c535eb59SGordon Tetlow t) tflag=tflag ;; 487c535eb59SGordon Tetlow w) wflag=wflag ;; 488c535eb59SGordon Tetlow *) man_usage ;; 489c535eb59SGordon Tetlow esac 490c535eb59SGordon Tetlow done >&2 491c535eb59SGordon Tetlow 492c535eb59SGordon Tetlow shift $(( $OPTIND - 1 )) 493c535eb59SGordon Tetlow 494c535eb59SGordon Tetlow # Check the args for incompatible options. 495c535eb59SGordon Tetlow case "${fflag}${kflag}${tflag}${wflag}" in 496c535eb59SGordon Tetlow fflagkflag*) echo "Incompatible options: -f and -k"; man_usage ;; 497c535eb59SGordon Tetlow fflag*tflag*) echo "Incompatible options: -f and -t"; man_usage ;; 498c535eb59SGordon Tetlow fflag*wflag) echo "Incompatible options: -f and -w"; man_usage ;; 499c535eb59SGordon Tetlow *kflagtflag*) echo "Incompatible options: -k and -t"; man_usage ;; 500c535eb59SGordon Tetlow *kflag*wflag) echo "Incompatible options: -k and -w"; man_usage ;; 501c535eb59SGordon Tetlow *tflagwflag) echo "Incompatible options: -t and -w"; man_usage ;; 502c535eb59SGordon Tetlow esac 503c535eb59SGordon Tetlow 504c535eb59SGordon Tetlow # Short circuit for whatis(1) and apropos(1) 505c535eb59SGordon Tetlow if [ -n "$fflag" ]; then 506c535eb59SGordon Tetlow do_whatis "$@" 507c535eb59SGordon Tetlow exit 508c535eb59SGordon Tetlow fi 509c535eb59SGordon Tetlow 510c535eb59SGordon Tetlow if [ -n "$kflag" ]; then 511c535eb59SGordon Tetlow do_apropos "$@" 512c535eb59SGordon Tetlow exit 513c535eb59SGordon Tetlow fi 514c535eb59SGordon Tetlow 515c535eb59SGordon Tetlow IFS=: 516c535eb59SGordon Tetlow for sect in $man_default_sections; do 517c535eb59SGordon Tetlow if [ "$sect" = "$1" ]; then 518c535eb59SGordon Tetlow decho "Detected manual section as first arg: $1" 519c535eb59SGordon Tetlow MANSECT="$1" 520c535eb59SGordon Tetlow shift 521c535eb59SGordon Tetlow break 522c535eb59SGordon Tetlow fi 523c535eb59SGordon Tetlow done 524c535eb59SGordon Tetlow unset IFS 525c535eb59SGordon Tetlow 526c535eb59SGordon Tetlow pages="$*" 527c535eb59SGordon Tetlow} 528c535eb59SGordon Tetlow 529c535eb59SGordon Tetlow# Usage: man_setup 530c535eb59SGordon Tetlow# Setup various trivial but essential variables. 531c535eb59SGordon Tetlowman_setup() { 532c535eb59SGordon Tetlow # Setup machine and architecture variables. 533c535eb59SGordon Tetlow if [ -n "$mflag" ]; then 534c535eb59SGordon Tetlow MACHINE_ARCH=${mflag%%:*} 535c535eb59SGordon Tetlow MACHINE=${mflag##*:} 536c535eb59SGordon Tetlow fi 537c535eb59SGordon Tetlow if [ -z "$MACHINE_ARCH" ]; then 538*82db8a5eSGordon Tetlow MACHINE_ARCH=$($SYSCTL -n hw.machine_arch) 539c535eb59SGordon Tetlow fi 540c535eb59SGordon Tetlow if [ -z "$MACHINE" ]; then 541*82db8a5eSGordon Tetlow MACHINE=$($SYSCTL -n hw.machine) 542c535eb59SGordon Tetlow fi 543c535eb59SGordon Tetlow decho "Using architecture: $MACHINE_ARCH:$MACHINE" 544c535eb59SGordon Tetlow 545c535eb59SGordon Tetlow setup_pager 546c535eb59SGordon Tetlow 547c535eb59SGordon Tetlow # Setup manual sections to search. 548c535eb59SGordon Tetlow if [ -z "$MANSECT" ]; then 549c535eb59SGordon Tetlow MANSECT=$man_default_sections 550c535eb59SGordon Tetlow fi 551c535eb59SGordon Tetlow decho "Using manual sections: $MANSECT" 552c535eb59SGordon Tetlow 553c535eb59SGordon Tetlow build_manpath 554c535eb59SGordon Tetlow man_setup_locale 555c535eb59SGordon Tetlow} 556c535eb59SGordon Tetlow 557c535eb59SGordon Tetlow# Usage: man_setup_locale 558c535eb59SGordon Tetlow# Setup necessary locale variables. 559c535eb59SGordon Tetlowman_setup_locale() { 560c535eb59SGordon Tetlow # Setup locale information. 561c535eb59SGordon Tetlow if [ -n "$oflag" ]; then 562c535eb59SGordon Tetlow decho "Using non-localized manpages" 563c535eb59SGordon Tetlow unset use_locale 564c535eb59SGordon Tetlow elif [ -n "$LC_ALL" ]; then 565c535eb59SGordon Tetlow parse_locale "$LC_ALL" 566c535eb59SGordon Tetlow elif [ -n "$LC_CTYPE" ]; then 567c535eb59SGordon Tetlow parse_locale "$LC_CTYPE" 568c535eb59SGordon Tetlow elif [ -n "$LANG" ]; then 569c535eb59SGordon Tetlow parse_locale "$LANG" 570c535eb59SGordon Tetlow fi 571c535eb59SGordon Tetlow 572c535eb59SGordon Tetlow if [ -n "$use_locale" ]; then 573c535eb59SGordon Tetlow locpaths="${man_lang}_${man_country}.${man_charset}" 574c535eb59SGordon Tetlow locpaths="$locpaths:$man_lang.$man_charset" 575c535eb59SGordon Tetlow if [ "$man_lang" != "en" ]; then 576c535eb59SGordon Tetlow locpaths="$locpaths:en.$man_charset" 577c535eb59SGordon Tetlow fi 578c535eb59SGordon Tetlow locpaths="$locpaths:." 579c535eb59SGordon Tetlow else 580c535eb59SGordon Tetlow locpaths="." 581c535eb59SGordon Tetlow fi 582c535eb59SGordon Tetlow decho "Using locale paths: $locpaths" 583c535eb59SGordon Tetlow} 584c535eb59SGordon Tetlow 585c535eb59SGordon Tetlow# Usage: man_usage [exitcode] 586c535eb59SGordon Tetlow# Display usage for the man utility. 587c535eb59SGordon Tetlowman_usage() { 588c535eb59SGordon Tetlow echo 'Usage:' 589c535eb59SGordon Tetlow echo ' man [-adho] [-t | -w] [-M manpath] [-P pager] [-S mansect]' 590c535eb59SGordon Tetlow echo ' [-m arch[:machine]] [-p [eprtv]] [mansect] page [...]' 591c535eb59SGordon Tetlow echo ' man -f page [...] -- Emulates whatis(1)' 592c535eb59SGordon Tetlow echo ' man -k page [...] -- Emulates apropos(1)' 593c535eb59SGordon Tetlow 594c535eb59SGordon Tetlow # When exit'ing with -h, it's not an error. 595c535eb59SGordon Tetlow exit ${1:-1} 596c535eb59SGordon Tetlow} 597c535eb59SGordon Tetlow 598c535eb59SGordon Tetlow# Usage: parse_configs 599c535eb59SGordon Tetlow# Reads the end-user adjustable config files. 600c535eb59SGordon Tetlowparse_configs() { 601c535eb59SGordon Tetlow local IFS file files 602c535eb59SGordon Tetlow 603c535eb59SGordon Tetlow if [ -n "$parsed_configs" ]; then 604c535eb59SGordon Tetlow return 605c535eb59SGordon Tetlow fi 606c535eb59SGordon Tetlow 607c535eb59SGordon Tetlow unset IFS 608c535eb59SGordon Tetlow 609c535eb59SGordon Tetlow # Read the global config first in case the user wants 610c535eb59SGordon Tetlow # to override config_local. 611c535eb59SGordon Tetlow if [ -r "$config_global" ]; then 612c535eb59SGordon Tetlow parse_file "$config_global" 613c535eb59SGordon Tetlow fi 614c535eb59SGordon Tetlow 615c535eb59SGordon Tetlow # Glob the list of files to parse. 616c535eb59SGordon Tetlow set +f 617c535eb59SGordon Tetlow files=$(echo $config_local) 618c535eb59SGordon Tetlow set -f 619c535eb59SGordon Tetlow 620c535eb59SGordon Tetlow for file in $files; do 621c535eb59SGordon Tetlow if [ -r "$file" ]; then 622c535eb59SGordon Tetlow parse_file "$file" 623c535eb59SGordon Tetlow fi 624c535eb59SGordon Tetlow done 625c535eb59SGordon Tetlow 626c535eb59SGordon Tetlow parsed_configs='yes' 627c535eb59SGordon Tetlow} 628c535eb59SGordon Tetlow 629c535eb59SGordon Tetlow# Usage: parse_file file 630c535eb59SGordon Tetlow# Reads the specified config files. 631c535eb59SGordon Tetlowparse_file() { 632c535eb59SGordon Tetlow local file line tstr var 633c535eb59SGordon Tetlow 634c535eb59SGordon Tetlow file="$1" 635c535eb59SGordon Tetlow decho "Parsing config file: $file" 636c535eb59SGordon Tetlow while read line; do 637c535eb59SGordon Tetlow decho " $line" 2 638c535eb59SGordon Tetlow case "$line" in 639c535eb59SGordon Tetlow \#*) decho " Comment" 3 640c535eb59SGordon Tetlow ;; 641c535eb59SGordon Tetlow MANPATH*) decho " MANPATH" 3 642c535eb59SGordon Tetlow trim "${line#MANPATH}" 643c535eb59SGordon Tetlow add_to_manpath "$tstr" 644c535eb59SGordon Tetlow ;; 645c535eb59SGordon Tetlow MANLOCALE*) decho " MANLOCALE" 3 646c535eb59SGordon Tetlow trim "${line#MANLOCALE}" 647c535eb59SGordon Tetlow manlocales="$manlocales:$tstr" 648c535eb59SGordon Tetlow ;; 649c535eb59SGordon Tetlow MANCONFIG*) decho " MANCONFIG" 3 650c535eb59SGordon Tetlow trim "${line#MANCONF}" 651c535eb59SGordon Tetlow config_local="$tstr" 652c535eb59SGordon Tetlow ;; 653c535eb59SGordon Tetlow # Set variables in the form of FOO_BAR 654c535eb59SGordon Tetlow *_*[\ \ ]*) var="${line%%[\ \ ]*}" 655c535eb59SGordon Tetlow trim "${line#$var}" 656c535eb59SGordon Tetlow eval "$var=\"$tstr\"" 657c535eb59SGordon Tetlow decho " Parsed $var" 3 658c535eb59SGordon Tetlow ;; 659c535eb59SGordon Tetlow esac 660c535eb59SGordon Tetlow done < "$file" 661c535eb59SGordon Tetlow} 662c535eb59SGordon Tetlow 663c535eb59SGordon Tetlow# Usage: parse_locale localestring 664c535eb59SGordon Tetlow# Setup locale variables for proper parsing. 665c535eb59SGordon Tetlowparse_locale() { 666c535eb59SGordon Tetlow local lang_cc 667c535eb59SGordon Tetlow 668c535eb59SGordon Tetlow case "$1" in 669c535eb59SGordon Tetlow C) ;; 670c535eb59SGordon Tetlow POSIX) ;; 671c535eb59SGordon Tetlow [a-z][a-z]_[A-Z][A-Z]\.*) lang_cc="${1%.*}" 672c535eb59SGordon Tetlow man_lang="${1%_*}" 673c535eb59SGordon Tetlow man_country="${lang_cc#*_}" 674c535eb59SGordon Tetlow man_charset="${1#*.}" 675c535eb59SGordon Tetlow use_locale=yes 676c535eb59SGordon Tetlow return 0 677c535eb59SGordon Tetlow ;; 678c535eb59SGordon Tetlow *) echo 'Unknown locale, assuming C' >&2 679c535eb59SGordon Tetlow ;; 680c535eb59SGordon Tetlow esac 681c535eb59SGordon Tetlow 682c535eb59SGordon Tetlow unset use_locale 683c535eb59SGordon Tetlow} 684c535eb59SGordon Tetlow 685c535eb59SGordon Tetlow# Usage: search_path 686c535eb59SGordon Tetlow# Traverse $PATH looking for manpaths. 687c535eb59SGordon Tetlowsearch_path() { 688c535eb59SGordon Tetlow local IFS p path 689c535eb59SGordon Tetlow 690c535eb59SGordon Tetlow decho "Searching PATH for man directories" 691c535eb59SGordon Tetlow 692c535eb59SGordon Tetlow IFS=: 693c535eb59SGordon Tetlow for path in $PATH; do 694c535eb59SGordon Tetlow # Do a little special casing since the base manpages 695c535eb59SGordon Tetlow # are in /usr/share/man instead of /usr/man or /man. 696c535eb59SGordon Tetlow case "$path" in 697c535eb59SGordon Tetlow /bin|/usr/bin) add_to_manpath "/usr/share/man" ;; 698c535eb59SGordon Tetlow *) if add_to_manpath "$path/man"; then 699c535eb59SGordon Tetlow : 700c535eb59SGordon Tetlow elif add_to_manpath "$path/MAN"; then 701c535eb59SGordon Tetlow : 702c535eb59SGordon Tetlow else 703c535eb59SGordon Tetlow case "$path" in 704c535eb59SGordon Tetlow */bin) p="${path%/bin}/man" 705c535eb59SGordon Tetlow add_to_manpath "$p" 706c535eb59SGordon Tetlow ;; 707c535eb59SGordon Tetlow *) ;; 708c535eb59SGordon Tetlow esac 709c535eb59SGordon Tetlow fi 710c535eb59SGordon Tetlow ;; 711c535eb59SGordon Tetlow esac 712c535eb59SGordon Tetlow done 713c535eb59SGordon Tetlow unset IFS 714c535eb59SGordon Tetlow 715c535eb59SGordon Tetlow if [ -z "$manpath" ]; then 716c535eb59SGordon Tetlow decho ' Unable to find any manpaths, using default' 717c535eb59SGordon Tetlow manpath=$man_default_path 718c535eb59SGordon Tetlow fi 719c535eb59SGordon Tetlow} 720c535eb59SGordon Tetlow 721c535eb59SGordon Tetlow# Usage: search_whatis cmd [arglist] 722c535eb59SGordon Tetlow# Do the heavy lifting for apropos/whatis 723c535eb59SGordon Tetlowsearch_whatis() { 724c535eb59SGordon Tetlow local IFS bad cmd f good key keywords loc opt out path rval wlist 725c535eb59SGordon Tetlow 726c535eb59SGordon Tetlow cmd="$1" 727c535eb59SGordon Tetlow shift 728c535eb59SGordon Tetlow 729c535eb59SGordon Tetlow whatis_parse_args "$@" 730c535eb59SGordon Tetlow 731c535eb59SGordon Tetlow build_manpath 732c535eb59SGordon Tetlow build_manlocales 733c535eb59SGordon Tetlow setup_pager 734c535eb59SGordon Tetlow 735c535eb59SGordon Tetlow if [ "$cmd" = "whatis" ]; then 736c535eb59SGordon Tetlow opt="-w" 737c535eb59SGordon Tetlow fi 738c535eb59SGordon Tetlow 739c535eb59SGordon Tetlow f='whatis' 740c535eb59SGordon Tetlow 741c535eb59SGordon Tetlow IFS=: 742c535eb59SGordon Tetlow for path in $MANPATH; do 743c535eb59SGordon Tetlow if [ \! -d "$path" ]; then 744c535eb59SGordon Tetlow decho "Skipping non-existent path: $path" 2 745c535eb59SGordon Tetlow continue 746c535eb59SGordon Tetlow fi 747c535eb59SGordon Tetlow 748c535eb59SGordon Tetlow if [ -f "$path/$f" -a -r "$path/$f" ]; then 749c535eb59SGordon Tetlow decho "Found whatis: $path/$f" 750c535eb59SGordon Tetlow wlist="$wlist $path/$f" 751c535eb59SGordon Tetlow fi 752c535eb59SGordon Tetlow 753c535eb59SGordon Tetlow for loc in $MANLOCALES; do 754c535eb59SGordon Tetlow if [ -f "$path/$loc/$f" -a -r "$path/$loc/$f" ]; then 755c535eb59SGordon Tetlow decho "Found whatis: $path/$loc/$f" 756c535eb59SGordon Tetlow wlist="$wlist $path/$loc/$f" 757c535eb59SGordon Tetlow fi 758c535eb59SGordon Tetlow done 759c535eb59SGordon Tetlow done 760c535eb59SGordon Tetlow unset IFS 761c535eb59SGordon Tetlow 762c535eb59SGordon Tetlow if [ -z "$wlist" ]; then 763c535eb59SGordon Tetlow echo "$cmd: no whatis databases in $MANPATH" >&2 764c535eb59SGordon Tetlow exit 1 765c535eb59SGordon Tetlow fi 766c535eb59SGordon Tetlow 767c535eb59SGordon Tetlow rval=0 768c535eb59SGordon Tetlow for key in $keywords; do 769c535eb59SGordon Tetlow out=$(grep -Ehi $opt -- "$key" $wlist) 770c535eb59SGordon Tetlow if [ -n "$out" ]; then 771c535eb59SGordon Tetlow good="$good\\n$out" 772c535eb59SGordon Tetlow else 773c535eb59SGordon Tetlow bad="$bad\\n$key: nothing appropriate" 774c535eb59SGordon Tetlow rval=1 775c535eb59SGordon Tetlow fi 776c535eb59SGordon Tetlow done 777c535eb59SGordon Tetlow 778c535eb59SGordon Tetlow # Strip leading carriage return. 779c535eb59SGordon Tetlow good=${good#\\n} 780c535eb59SGordon Tetlow bad=${bad#\\n} 781c535eb59SGordon Tetlow 782c535eb59SGordon Tetlow if [ -n "$good" ]; then 78300e05e69SGordon Tetlow echo -e "$good" | $PAGER 784c535eb59SGordon Tetlow fi 785c535eb59SGordon Tetlow 786c535eb59SGordon Tetlow if [ -n "$bad" ]; then 78700e05e69SGordon Tetlow echo -e "$bad" >&2 788c535eb59SGordon Tetlow fi 789c535eb59SGordon Tetlow 790c535eb59SGordon Tetlow exit $rval 791c535eb59SGordon Tetlow} 792c535eb59SGordon Tetlow 79357cd9717SGordon Tetlow# Usage: setup_cattool page 79457cd9717SGordon Tetlow# Finds an appropriate decompressor based on extension 79557cd9717SGordon Tetlowsetup_cattool() { 79657cd9717SGordon Tetlow case "$1" in 79757cd9717SGordon Tetlow *.bz) cattool='/usr/bin/bzcat' ;; 79857cd9717SGordon Tetlow *.bz2) cattool='/usr/bin/bzcat' ;; 79957cd9717SGordon Tetlow *.gz) cattool='/usr/bin/zcat' ;; 80057cd9717SGordon Tetlow *.lzma) cattool='/usr/bin/lzcat' ;; 80157cd9717SGordon Tetlow *.xz) cattool='/usr/bin/xzcat' ;; 80257cd9717SGordon Tetlow *) cattool='/usr/bin/zcat -f' ;; 80357cd9717SGordon Tetlow esac 80457cd9717SGordon Tetlow} 80557cd9717SGordon Tetlow 806c535eb59SGordon Tetlow# Usage: setup_pager 807c535eb59SGordon Tetlow# Correctly sets $PAGER 808c535eb59SGordon Tetlowsetup_pager() { 809c535eb59SGordon Tetlow # Setup pager. 810c535eb59SGordon Tetlow if [ -z "$PAGER" ]; then 811c535eb59SGordon Tetlow PAGER="more -s" 812c535eb59SGordon Tetlow fi 813c535eb59SGordon Tetlow decho "Using pager: $PAGER" 814c535eb59SGordon Tetlow} 815c535eb59SGordon Tetlow 816c535eb59SGordon Tetlow# Usage: trim string 817c535eb59SGordon Tetlow# Trims whitespace from beginning and end of a variable 818c535eb59SGordon Tetlowtrim() { 819c535eb59SGordon Tetlow tstr=$1 820c535eb59SGordon Tetlow while true; do 821c535eb59SGordon Tetlow case "$tstr" in 822c535eb59SGordon Tetlow [\ \ ]*) tstr="${tstr##[\ \ ]}" ;; 823c535eb59SGordon Tetlow *[\ \ ]) tstr="${tstr%%[\ \ ]}" ;; 824c535eb59SGordon Tetlow *) break ;; 825c535eb59SGordon Tetlow esac 826c535eb59SGordon Tetlow done 827c535eb59SGordon Tetlow} 828c535eb59SGordon Tetlow 829c535eb59SGordon Tetlow# Usage: whatis_parse_args "$@" 830c535eb59SGordon Tetlow# Parse commandline args for whatis and apropos. 831c535eb59SGordon Tetlowwhatis_parse_args() { 832c535eb59SGordon Tetlow local cmd_arg 833c535eb59SGordon Tetlow while getopts 'd' cmd_arg; do 834c535eb59SGordon Tetlow case "${cmd_arg}" in 835c535eb59SGordon Tetlow d) debug=$(( $debug + 1 )) ;; 836c535eb59SGordon Tetlow *) whatis_usage ;; 837c535eb59SGordon Tetlow esac 838c535eb59SGordon Tetlow done >&2 839c535eb59SGordon Tetlow 840c535eb59SGordon Tetlow shift $(( $OPTIND - 1 )) 841c535eb59SGordon Tetlow 842c535eb59SGordon Tetlow keywords="$*" 843c535eb59SGordon Tetlow} 844c535eb59SGordon Tetlow 845c535eb59SGordon Tetlow# Usage: whatis_usage 846c535eb59SGordon Tetlow# Display usage for the whatis/apropos utility. 847c535eb59SGordon Tetlowwhatis_usage() { 848c535eb59SGordon Tetlow echo "usage: $cmd [-d] keyword [...]" 849c535eb59SGordon Tetlow exit 1 850c535eb59SGordon Tetlow} 851c535eb59SGordon Tetlow 852c535eb59SGordon Tetlow 853c535eb59SGordon Tetlow 854c535eb59SGordon Tetlow# Supported commands 855c535eb59SGordon Tetlowdo_apropos() { 856c535eb59SGordon Tetlow search_whatis apropos "$@" 857c535eb59SGordon Tetlow} 858c535eb59SGordon Tetlow 859c535eb59SGordon Tetlowdo_man() { 860c535eb59SGordon Tetlow man_parse_args "$@" 861c535eb59SGordon Tetlow if [ -z "$pages" ]; then 862c535eb59SGordon Tetlow echo 'What manual page do you want?' >&2 863c535eb59SGordon Tetlow exit 1 864c535eb59SGordon Tetlow fi 865c535eb59SGordon Tetlow man_setup 866c535eb59SGordon Tetlow 867c535eb59SGordon Tetlow for page in $pages; do 868c535eb59SGordon Tetlow decho "Searching for $page" 869c535eb59SGordon Tetlow man_find_and_display "$page" 870c535eb59SGordon Tetlow done 871c535eb59SGordon Tetlow 872c535eb59SGordon Tetlow exit ${ret:-0} 873c535eb59SGordon Tetlow} 874c535eb59SGordon Tetlow 875c535eb59SGordon Tetlowdo_manpath() { 876c535eb59SGordon Tetlow manpath_parse_args "$@" 877c535eb59SGordon Tetlow if [ -z "$qflag" ]; then 878c535eb59SGordon Tetlow manpath_warnings 879c535eb59SGordon Tetlow fi 880c535eb59SGordon Tetlow if [ -n "$Lflag" ]; then 881c535eb59SGordon Tetlow build_manlocales 882c535eb59SGordon Tetlow echo $MANLOCALES 883c535eb59SGordon Tetlow else 884c535eb59SGordon Tetlow build_manpath 885c535eb59SGordon Tetlow echo $MANPATH 886c535eb59SGordon Tetlow fi 887c535eb59SGordon Tetlow exit 0 888c535eb59SGordon Tetlow} 889c535eb59SGordon Tetlow 890c535eb59SGordon Tetlowdo_whatis() { 891c535eb59SGordon Tetlow search_whatis whatis "$@" 892c535eb59SGordon Tetlow} 893c535eb59SGordon Tetlow 894c535eb59SGordon TetlowEQN=/usr/bin/eqn 895c535eb59SGordon TetlowCOL=/usr/bin/col 896c535eb59SGordon TetlowNROFF='/usr/bin/groff -S -Wall -mtty-char -man' 897c535eb59SGordon TetlowPIC=/usr/bin/pic 898*82db8a5eSGordon TetlowSYSCTL=/sbin/sysctl 899c535eb59SGordon TetlowTBL=/usr/bin/tbl 900c535eb59SGordon TetlowTROFF='/usr/bin/groff -S -man' 901c535eb59SGordon TetlowREFER=/usr/bin/refer 902c535eb59SGordon TetlowVGRIND=/usr/bin/vgrind 903c535eb59SGordon Tetlow 904c535eb59SGordon Tetlowdebug=0 905c535eb59SGordon Tetlowman_default_sections='1:1aout:8:2:3:n:4:5:6:7:9:l' 906c535eb59SGordon Tetlowman_default_path='/usr/share/man:/usr/share/openssl/man:/usr/local/man' 90757cd9717SGordon Tetlowcattool='/usr/bin/zcat -f' 908c535eb59SGordon Tetlow 909c535eb59SGordon Tetlowconfig_global='/etc/man.conf' 910c535eb59SGordon Tetlow 911c535eb59SGordon Tetlow# This can be overridden via a setting in /etc/man.conf. 912c535eb59SGordon Tetlowconfig_local='/usr/local/etc/man.d/*.conf' 913c535eb59SGordon Tetlow 914c535eb59SGordon Tetlow# Set noglobbing for now. I don't want spurious globbing. 915c535eb59SGordon Tetlowset -f 916c535eb59SGordon Tetlow 917c535eb59SGordon Tetlowcase "$0" in 918c535eb59SGordon Tetlow*apropos) do_apropos "$@" ;; 919c535eb59SGordon Tetlow*manpath) do_manpath "$@" ;; 920c535eb59SGordon Tetlow*whatis) do_whatis "$@" ;; 921c535eb59SGordon Tetlow*) do_man "$@" ;; 922c535eb59SGordon Tetlowesac 923