man.sh revision 213349
1251875Speter#! /bin/sh 2251875Speter# 3251875Speter# Copyright (c) 2010 Gordon Tetlow 4251875Speter# All rights reserved. 5251875Speter# 6251875Speter# Redistribution and use in source and binary forms, with or without 7251875Speter# modification, are permitted provided that the following conditions 8251875Speter# are met: 9251875Speter# 1. Redistributions of source code must retain the above copyright 10251875Speter# notice, this list of conditions and the following disclaimer. 11251875Speter# 2. Redistributions in binary form must reproduce the above copyright 12251875Speter# notice, this list of conditions and the following disclaimer in the 13251875Speter# documentation and/or other materials provided with the distribution. 14251875Speter# 15251875Speter# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16251875Speter# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17251875Speter# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18251875Speter# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19251875Speter# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20251875Speter# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21251875Speter# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22251875Speter# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23251875Speter# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24251875Speter# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25251875Speter# SUCH DAMAGE. 26251875Speter# 27251875Speter# $FreeBSD: head/usr.bin/man/man.sh 213349 2010-10-02 06:55:04Z gordon $ 28251875Speter 29251875Speter# Usage: add_to_manpath path 30251875Speter# Adds a variable to manpath while ensuring we don't have duplicates. 31251875Speter# Returns true if we were able to add something. False otherwise. 32251875Speteradd_to_manpath() { 33251875Speter case "$manpath" in 34251875Speter *:$1) decho " Skipping duplicate manpath entry $1" 2 ;; 35251875Speter $1:*) decho " Skipping duplicate manpath entry $1" 2 ;; 36251875Speter *:$1:*) decho " Skipping duplicate manpath entry $1" 2 ;; 37251875Speter *) if [ -d "$1" ]; then 38251875Speter decho " Adding $1 to manpath" 39251875Speter manpath="$manpath:$1" 40251875Speter return 0 41251875Speter fi 42251875Speter ;; 43251875Speter esac 44251875Speter 45251875Speter return 1 46251875Speter} 47251875Speter 48251875Speter# Usage: build_manlocales 49251875Speter# Builds a correct MANLOCALES variable. 50251875Speterbuild_manlocales() { 51251875Speter # If the user has set manlocales, who are we to argue. 52251875Speter if [ -n "$MANLOCALES" ]; then 53251875Speter return 54251875Speter fi 55251875Speter 56251875Speter parse_configs 57251875Speter 58251875Speter # Trim leading colon 59251875Speter MANLOCALES=${manlocales#:} 60251875Speter 61251875Speter decho "Available manual locales: $MANLOCALES" 62251875Speter} 63251875Speter 64251875Speter# Usage: build_manpath 65251875Speter# Builds a correct MANPATH variable. 66251875Speterbuild_manpath() { 67251875Speter local IFS 68251875Speter 69251875Speter # If the user has set a manpath, who are we to argue. 70251875Speter if [ -n "$MANPATH" ]; then 71251875Speter return 72251875Speter fi 73251875Speter 74251875Speter search_path 75251875Speter 76251875Speter decho "Adding default manpath entries" 77251875Speter IFS=: 78251875Speter for path in $man_default_path; do 79251875Speter add_to_manpath "$path" 80251875Speter done 81251875Speter unset IFS 82251875Speter 83251875Speter parse_configs 84251875Speter 85251875Speter # Trim leading colon 86251875Speter MANPATH=${manpath#:} 87251875Speter 88251875Speter decho "Using manual path: $MANPATH" 89251875Speter} 90251875Speter 91251875Speter# Usage: check_cat catglob 92251875Speter# Checks to see if a cat glob is available. 93251875Spetercheck_cat() { 94251875Speter if exists "$1"; then 95251875Speter use_cat=yes 96251875Speter catpage=$found 97251875Speter decho " Found catpage $catpage" 98251875Speter return 0 99251875Speter else 100251875Speter return 1 101251875Speter fi 102251875Speter} 103251875Speter 104251875Speter# Usage: check_man manglob catglob 105251875Speter# Given 2 globs, figures out if the manglob is available, if so, check to 106251875Speter# see if the catglob is also available and up to date. 107251875Spetercheck_man() { 108251875Speter if exists "$1"; then 109251875Speter # We have a match, check for a cat page 110251875Speter manpage=$found 111251875Speter decho " Found manpage $manpage" 112251875Speter 113251875Speter if exists "$2" && is_newer $found $manpage; then 114251875Speter # cat page found and is newer, use that 115251875Speter use_cat=yes 116251875Speter catpage=$found 117251875Speter decho " Using catpage $catpage" 118251875Speter else 119251875Speter # no cat page or is older 120251875Speter unset use_cat 121251875Speter decho " Skipping catpage: not found or old" 122251875Speter fi 123251875Speter return 0 124251875Speter fi 125251875Speter 126251875Speter return 1 127251875Speter} 128251875Speter 129251875Speter# Usage: decho "string" [debuglevel] 130# Echoes to stderr string prefaced with -- if high enough debuglevel. 131decho() { 132 if [ $debug -ge ${2:-1} ]; then 133 echo "-- $1" >&2 134 fi 135} 136 137# Usage: exists glob 138# Returns true if glob resolves to a real file. 139exists() { 140 local IFS 141 142 # Don't accidentally inherit callers IFS (breaks perl manpages) 143 unset IFS 144 145 # Use some globbing tricks in the shell to determine if a file 146 # exists or not. 147 set +f 148 set -- "$1" $1 149 set -f 150 151 if [ "$1" != "$2" -a -r "$2" ]; then 152 found="$2" 153 return 0 154 fi 155 156 return 1 157} 158 159# Usage: find_file path section subdir pagename 160# Returns: true if something is matched and found. 161# Search the given path/section combo for a given page. 162find_file() { 163 local manroot catroot mann man0 catn cat0 164 165 manroot="$1/man$2" 166 catroot="$1/cat$2" 167 if [ -n "$3" ]; then 168 manroot="$manroot/$3" 169 catroot="$catroot/$3" 170 fi 171 172 if [ ! -d "$manroot" ]; then 173 return 1 174 fi 175 decho " Searching directory $manroot" 2 176 177 mann="$manroot/$4.$2*" 178 man0="$manroot/$4.0*" 179 catn="$catroot/$4.$2*" 180 cat0="$catroot/$4.0*" 181 182 # This is the behavior as seen by the original man utility. 183 # Let's not change that which doesn't seem broken. 184 if check_man "$mann" "$catn"; then 185 return 0 186 elif check_man "$man0" "$cat0"; then 187 return 0 188 elif check_cat "$catn"; then 189 return 0 190 elif check_cat "$cat0"; then 191 return 0 192 fi 193 194 return 1 195} 196 197# Usage: is_newer file1 file2 198# Returns true if file1 is newer than file2 as calculated by mtime. 199is_newer() { 200 if [ $(stat -f %m $1) -gt $(stat -f %m $2) ]; then 201 decho " mtime: $1 newer than $2" 3 202 return 0 203 else 204 decho " mtime: $1 older than $2" 3 205 return 1 206 fi 207} 208 209# Usage: manpath_parse_args "$@" 210# Parses commandline options for manpath. 211manpath_parse_args() { 212 local cmd_arg 213 214 while getopts 'Ldq' cmd_arg; do 215 case "${cmd_arg}" in 216 L) Lflag=Lflag ;; 217 d) debug=$(( $debug + 1 )) ;; 218 q) qflag=qflag ;; 219 *) manpath_usage ;; 220 esac 221 done >&2 222} 223 224# Usage: manpath_usage 225# Display usage for the manpath(1) utility. 226manpath_usage() { 227 echo 'usage: manpath [-Ldq]' >&2 228 exit 1 229} 230 231# Usage: manpath_warnings 232# Display some warnings to stderr. 233manpath_warnings() { 234 if [ -z "$Lflag" -a -n "$MANPATH" ]; then 235 echo "(Warning: MANPATH environment variable set)" >&2 236 fi 237 238 if [ -n "$Lflag" -a -n "$MANLOCALES" ]; then 239 echo "(Warning: MANLOCALES environment variable set)" >&2 240 fi 241} 242 243# Usage: man_display_page 244# Display either the manpage or catpage depending on the use_cat variable 245man_display_page() { 246 local EQN COL NROFF PIC TBL TROFF REFER VGRIND 247 local IFS l nroff_dev pipeline preproc_arg tool 248 249 # We are called with IFS set to colon. This causes really weird 250 # things to happen for the variables that have spaces in them. 251 unset IFS 252 253 # If we are supposed to use a catpage and we aren't using troff(1) 254 # just zcat the catpage and we are done. 255 if [ -z "$tflag" -a -n "$use_cat" ]; then 256 if [ -n "$wflag" ]; then 257 echo "$catpage (source: $manpage)" 258 ret=0 259 else 260 if [ $debug -gt 0 ]; then 261 decho "Command: $ZCAT $catpage | $PAGER" 262 ret=0 263 else 264 eval "$ZCAT $catpage | $PAGER" 265 ret=$? 266 fi 267 fi 268 return 269 fi 270 271 # Okay, we are using the manpage, do we just need to output the 272 # name of the manpage? 273 if [ -n "$wflag" ]; then 274 echo "$manpage" 275 ret=0 276 return 277 fi 278 279 # So, we really do need to parse the manpage. First, figure out the 280 # device flag (-T) we have to pass to eqn(1) and groff(1). Then, 281 # setup the pipeline of commands based on the user's request. 282 283 # Apparently the locale flags are switched on where the manpage is 284 # found not just the locale env variables. 285 nroff_dev="ascii" 286 case "X${use_locale}X${manpage}" in 287 XyesX*/${man_lang}*${man_charset}/*) 288 # I don't pretend to know this; I'm just copying from the 289 # previous version of man(1). 290 case "$man_charset" in 291 KOI8-R) nroff_dev="koi8-r" ;; 292 ISO8859-1) nroff_dev="latin1" ;; 293 ISO8859-15) nroff_dev="latin1" ;; 294 UTF-8) nroff_dev="utf8" ;; 295 *) nroff_dev="ascii" ;; 296 esac 297 298 NROFF="$NROFF -T$nroff_dev -dlocale=$man_lang.$man_charset" 299 EQN="$EQN -T$nroff_dev" 300 301 # Allow language specific calls to override the default 302 # set of utilities. 303 l=$(echo $man_lang | tr [:lower:] [:upper:]) 304 for tool in EQN COL NROFF PIC TBL TROFF REFER VGRIND; do 305 eval "$tool=\${${tool}_$l:-\$$tool}" 306 done 307 ;; 308 *) NROFF="$NROFF -Tascii" 309 EQN="$EQN -Tascii" 310 ;; 311 esac 312 313 if [ -n "$MANROFFSEQ" ]; then 314 set -- -$MANROFFSEQ 315 while getopts 'egprtv' preproc_arg; do 316 case "${preproc_arg}" in 317 e) pipeline="$pipeline | $EQN" ;; 318 g) ;; # Ignore for compatability. 319 p) pipeline="$pipeline | $PIC" ;; 320 r) pipeline="$pipeline | $REFER" ;; 321 t) pipeline="$pipeline | $TBL"; use_col=yes ;; 322 v) pipeline="$pipeline | $VGRIND" ;; 323 *) usage ;; 324 esac 325 done 326 # Strip the leading " | " from the resulting pipeline. 327 pipeline="${pipeline#" | "}" 328 else 329 pipeline="$TBL" 330 use_col=yes 331 fi 332 333 if [ -n "$tflag" ]; then 334 pipeline="$pipeline | $TROFF" 335 else 336 pipeline="$pipeline | $NROFF" 337 338 if [ -n "$use_col" ]; then 339 pipeline="$pipeline | $COL" 340 fi 341 342 pipeline="$pipeline | $PAGER" 343 fi 344 345 if [ $debug -gt 0 ]; then 346 decho "Command: $ZCAT $manpage | $pipeline" 347 ret=0 348 else 349 eval "$ZCAT $manpage | $pipeline" 350 ret=$? 351 fi 352} 353 354# Usage: man_find_and_display page 355# Search through the manpaths looking for the given page. 356man_find_and_display() { 357 local found_page locpath p path sect 358 359 IFS=: 360 for sect in $MANSECT; do 361 decho "Searching section $sect" 2 362 for path in $MANPATH; do 363 for locpath in $locpaths; do 364 p=$path/$locpath 365 p=${p%/.} # Rid ourselves of the trailing /. 366 367 # Check if there is a MACHINE specific manpath. 368 if find_file $p $sect $MACHINE "$1"; then 369 found_page=yes 370 man_display_page 371 if [ -z "$aflag" ]; then 372 return 373 fi 374 fi 375 376 # Check if there is a MACHINE_ARCH 377 # specific manpath. 378 if find_file $p $sect $MACHINE_ARCH "$1"; then 379 found_page=yes 380 man_display_page 381 if [ -z "$aflag" ]; then 382 return 383 fi 384 fi 385 386 # Check plain old manpath. 387 if find_file $p $sect '' "$1"; then 388 found_page=yes 389 man_display_page 390 if [ -z "$aflag" ]; then 391 return 392 fi 393 fi 394 done 395 done 396 done 397 unset IFS 398 399 # Nothing? Well, we are done then. 400 if [ -z "$found_page" ]; then 401 echo "No manual entry for $1" >&2 402 ret=1 403 return 404 fi 405} 406 407# Usage: man_parse_args "$@" 408# Parses commandline options for man. 409man_parse_args() { 410 local IFS cmd_arg 411 412 while getopts 'M:P:S:adfhkm:op:tw' cmd_arg; do 413 case "${cmd_arg}" in 414 M) MANPATH=$OPTARG ;; 415 P) PAGER=$OPTARG ;; 416 S) MANSECT=$OPTARG ;; 417 a) aflag=aflag ;; 418 d) debug=$(( $debug + 1 )) ;; 419 f) fflag=fflag ;; 420 h) man_usage 0 ;; 421 k) kflag=kflag ;; 422 m) mflag=$OPTARG ;; 423 o) oflag=oflag ;; 424 p) MANROFFSEQ=$OPTARG ;; 425 t) tflag=tflag ;; 426 w) wflag=wflag ;; 427 *) man_usage ;; 428 esac 429 done >&2 430 431 shift $(( $OPTIND - 1 )) 432 433 # Check the args for incompatible options. 434 case "${fflag}${kflag}${tflag}${wflag}" in 435 fflagkflag*) echo "Incompatible options: -f and -k"; man_usage ;; 436 fflag*tflag*) echo "Incompatible options: -f and -t"; man_usage ;; 437 fflag*wflag) echo "Incompatible options: -f and -w"; man_usage ;; 438 *kflagtflag*) echo "Incompatible options: -k and -t"; man_usage ;; 439 *kflag*wflag) echo "Incompatible options: -k and -w"; man_usage ;; 440 *tflagwflag) echo "Incompatible options: -t and -w"; man_usage ;; 441 esac 442 443 # Short circuit for whatis(1) and apropos(1) 444 if [ -n "$fflag" ]; then 445 do_whatis "$@" 446 exit 447 fi 448 449 if [ -n "$kflag" ]; then 450 do_apropos "$@" 451 exit 452 fi 453 454 IFS=: 455 for sect in $man_default_sections; do 456 if [ "$sect" = "$1" ]; then 457 decho "Detected manual section as first arg: $1" 458 MANSECT="$1" 459 shift 460 break 461 fi 462 done 463 unset IFS 464 465 pages="$*" 466} 467 468# Usage: man_setup 469# Setup various trivial but essential variables. 470man_setup() { 471 # Setup machine and architecture variables. 472 if [ -n "$mflag" ]; then 473 MACHINE_ARCH=${mflag%%:*} 474 MACHINE=${mflag##*:} 475 fi 476 if [ -z "$MACHINE_ARCH" ]; then 477 MACHINE_ARCH=$(sysctl -n hw.machine_arch) 478 fi 479 if [ -z "$MACHINE" ]; then 480 MACHINE=$(sysctl -n hw.machine) 481 fi 482 decho "Using architecture: $MACHINE_ARCH:$MACHINE" 483 484 setup_pager 485 486 # Setup manual sections to search. 487 if [ -z "$MANSECT" ]; then 488 MANSECT=$man_default_sections 489 fi 490 decho "Using manual sections: $MANSECT" 491 492 build_manpath 493 man_setup_locale 494} 495 496# Usage: man_setup_locale 497# Setup necessary locale variables. 498man_setup_locale() { 499 # Setup locale information. 500 if [ -n "$oflag" ]; then 501 decho "Using non-localized manpages" 502 unset use_locale 503 elif [ -n "$LC_ALL" ]; then 504 parse_locale "$LC_ALL" 505 elif [ -n "$LC_CTYPE" ]; then 506 parse_locale "$LC_CTYPE" 507 elif [ -n "$LANG" ]; then 508 parse_locale "$LANG" 509 fi 510 511 if [ -n "$use_locale" ]; then 512 locpaths="${man_lang}_${man_country}.${man_charset}" 513 locpaths="$locpaths:$man_lang.$man_charset" 514 if [ "$man_lang" != "en" ]; then 515 locpaths="$locpaths:en.$man_charset" 516 fi 517 locpaths="$locpaths:." 518 else 519 locpaths="." 520 fi 521 decho "Using locale paths: $locpaths" 522} 523 524# Usage: man_usage [exitcode] 525# Display usage for the man utility. 526man_usage() { 527 echo 'Usage:' 528 echo ' man [-adho] [-t | -w] [-M manpath] [-P pager] [-S mansect]' 529 echo ' [-m arch[:machine]] [-p [eprtv]] [mansect] page [...]' 530 echo ' man -f page [...] -- Emulates whatis(1)' 531 echo ' man -k page [...] -- Emulates apropos(1)' 532 533 # When exit'ing with -h, it's not an error. 534 exit ${1:-1} 535} 536 537# Usage: parse_configs 538# Reads the end-user adjustable config files. 539parse_configs() { 540 local IFS file files 541 542 if [ -n "$parsed_configs" ]; then 543 return 544 fi 545 546 unset IFS 547 548 # Read the global config first in case the user wants 549 # to override config_local. 550 if [ -r "$config_global" ]; then 551 parse_file "$config_global" 552 fi 553 554 # Glob the list of files to parse. 555 set +f 556 files=$(echo $config_local) 557 set -f 558 559 for file in $files; do 560 if [ -r "$file" ]; then 561 parse_file "$file" 562 fi 563 done 564 565 parsed_configs='yes' 566} 567 568# Usage: parse_file file 569# Reads the specified config files. 570parse_file() { 571 local file line tstr var 572 573 file="$1" 574 decho "Parsing config file: $file" 575 while read line; do 576 decho " $line" 2 577 case "$line" in 578 \#*) decho " Comment" 3 579 ;; 580 MANPATH*) decho " MANPATH" 3 581 trim "${line#MANPATH}" 582 add_to_manpath "$tstr" 583 ;; 584 MANLOCALE*) decho " MANLOCALE" 3 585 trim "${line#MANLOCALE}" 586 manlocales="$manlocales:$tstr" 587 ;; 588 MANCONFIG*) decho " MANCONFIG" 3 589 trim "${line#MANCONF}" 590 config_local="$tstr" 591 ;; 592 # Set variables in the form of FOO_BAR 593 *_*[\ \ ]*) var="${line%%[\ \ ]*}" 594 trim "${line#$var}" 595 eval "$var=\"$tstr\"" 596 decho " Parsed $var" 3 597 ;; 598 esac 599 done < "$file" 600} 601 602# Usage: parse_locale localestring 603# Setup locale variables for proper parsing. 604parse_locale() { 605 local lang_cc 606 607 case "$1" in 608 C) ;; 609 POSIX) ;; 610 [a-z][a-z]_[A-Z][A-Z]\.*) lang_cc="${1%.*}" 611 man_lang="${1%_*}" 612 man_country="${lang_cc#*_}" 613 man_charset="${1#*.}" 614 use_locale=yes 615 return 0 616 ;; 617 *) echo 'Unknown locale, assuming C' >&2 618 ;; 619 esac 620 621 unset use_locale 622} 623 624# Usage: search_path 625# Traverse $PATH looking for manpaths. 626search_path() { 627 local IFS p path 628 629 decho "Searching PATH for man directories" 630 631 IFS=: 632 for path in $PATH; do 633 # Do a little special casing since the base manpages 634 # are in /usr/share/man instead of /usr/man or /man. 635 case "$path" in 636 /bin|/usr/bin) add_to_manpath "/usr/share/man" ;; 637 *) if add_to_manpath "$path/man"; then 638 : 639 elif add_to_manpath "$path/MAN"; then 640 : 641 else 642 case "$path" in 643 */bin) p="${path%/bin}/man" 644 add_to_manpath "$p" 645 ;; 646 *) ;; 647 esac 648 fi 649 ;; 650 esac 651 done 652 unset IFS 653 654 if [ -z "$manpath" ]; then 655 decho ' Unable to find any manpaths, using default' 656 manpath=$man_default_path 657 fi 658} 659 660# Usage: search_whatis cmd [arglist] 661# Do the heavy lifting for apropos/whatis 662search_whatis() { 663 local IFS bad cmd f good key keywords loc opt out path rval wlist 664 665 cmd="$1" 666 shift 667 668 whatis_parse_args "$@" 669 670 build_manpath 671 build_manlocales 672 setup_pager 673 674 if [ "$cmd" = "whatis" ]; then 675 opt="-w" 676 fi 677 678 f='whatis' 679 680 IFS=: 681 for path in $MANPATH; do 682 if [ \! -d "$path" ]; then 683 decho "Skipping non-existent path: $path" 2 684 continue 685 fi 686 687 if [ -f "$path/$f" -a -r "$path/$f" ]; then 688 decho "Found whatis: $path/$f" 689 wlist="$wlist $path/$f" 690 fi 691 692 for loc in $MANLOCALES; do 693 if [ -f "$path/$loc/$f" -a -r "$path/$loc/$f" ]; then 694 decho "Found whatis: $path/$loc/$f" 695 wlist="$wlist $path/$loc/$f" 696 fi 697 done 698 done 699 unset IFS 700 701 if [ -z "$wlist" ]; then 702 echo "$cmd: no whatis databases in $MANPATH" >&2 703 exit 1 704 fi 705 706 rval=0 707 for key in $keywords; do 708 out=$(grep -Ehi $opt -- "$key" $wlist) 709 if [ -n "$out" ]; then 710 good="$good\\n$out" 711 else 712 bad="$bad\\n$key: nothing appropriate" 713 rval=1 714 fi 715 done 716 717 # Strip leading carriage return. 718 good=${good#\\n} 719 bad=${bad#\\n} 720 721 if [ -n "$good" ]; then 722 echo -e "$good" | $PAGER 723 fi 724 725 if [ -n "$bad" ]; then 726 echo -e "$bad" >&2 727 fi 728 729 exit $rval 730} 731 732# Usage: setup_pager 733# Correctly sets $PAGER 734setup_pager() { 735 # Setup pager. 736 if [ -z "$PAGER" ]; then 737 PAGER="more -s" 738 fi 739 decho "Using pager: $PAGER" 740} 741 742# Usage: trim string 743# Trims whitespace from beginning and end of a variable 744trim() { 745 tstr=$1 746 while true; do 747 case "$tstr" in 748 [\ \ ]*) tstr="${tstr##[\ \ ]}" ;; 749 *[\ \ ]) tstr="${tstr%%[\ \ ]}" ;; 750 *) break ;; 751 esac 752 done 753} 754 755# Usage: whatis_parse_args "$@" 756# Parse commandline args for whatis and apropos. 757whatis_parse_args() { 758 local cmd_arg 759 while getopts 'd' cmd_arg; do 760 case "${cmd_arg}" in 761 d) debug=$(( $debug + 1 )) ;; 762 *) whatis_usage ;; 763 esac 764 done >&2 765 766 shift $(( $OPTIND - 1 )) 767 768 keywords="$*" 769} 770 771# Usage: whatis_usage 772# Display usage for the whatis/apropos utility. 773whatis_usage() { 774 echo "usage: $cmd [-d] keyword [...]" 775 exit 1 776} 777 778 779 780# Supported commands 781do_apropos() { 782 search_whatis apropos "$@" 783} 784 785do_man() { 786 man_parse_args "$@" 787 if [ -z "$pages" ]; then 788 echo 'What manual page do you want?' >&2 789 exit 1 790 fi 791 man_setup 792 793 for page in $pages; do 794 decho "Searching for $page" 795 man_find_and_display "$page" 796 done 797 798 exit ${ret:-0} 799} 800 801do_manpath() { 802 manpath_parse_args "$@" 803 if [ -z "$qflag" ]; then 804 manpath_warnings 805 fi 806 if [ -n "$Lflag" ]; then 807 build_manlocales 808 echo $MANLOCALES 809 else 810 build_manpath 811 echo $MANPATH 812 fi 813 exit 0 814} 815 816do_whatis() { 817 search_whatis whatis "$@" 818} 819 820EQN=/usr/bin/eqn 821COL=/usr/bin/col 822NROFF='/usr/bin/groff -S -Wall -mtty-char -man' 823PIC=/usr/bin/pic 824TBL=/usr/bin/tbl 825TROFF='/usr/bin/groff -S -man' 826REFER=/usr/bin/refer 827VGRIND=/usr/bin/vgrind 828ZCAT='/usr/bin/zcat -f' 829 830debug=0 831man_default_sections='1:1aout:8:2:3:n:4:5:6:7:9:l' 832man_default_path='/usr/share/man:/usr/share/openssl/man:/usr/local/man' 833 834config_global='/etc/man.conf' 835 836# This can be overridden via a setting in /etc/man.conf. 837config_local='/usr/local/etc/man.d/*.conf' 838 839# Set noglobbing for now. I don't want spurious globbing. 840set -f 841 842case "$0" in 843*apropos) do_apropos "$@" ;; 844*manpath) do_manpath "$@" ;; 845*whatis) do_whatis "$@" ;; 846*) do_man "$@" ;; 847esac 848