#!/bin/sh argv0="$0" die() { printf "$*" >/dev/stderr && exit 1; } # A lot of these break convention when recording errors because this tries to # imitate other implementations. [ -n "$1" ] || die "What manual page do you want?\nFor example, try 'man man'.\n" [ -n "$LANG" ] || LANG="C" [ -n "$MANPATH" ] || MANPATH="/usr/share/man" [ -d "$MANPATH" ] || die "$0: \$MANPATH: $MANPATH: Does not exist\n" [ -n "$MANSECTIONS" ] \ && default_mansections="$MANSECTIONS" \ || default_mansections="1nl830254967" [ -d "$MANPATH"/"$LANG" ] \ && MANDIR="$MANPATH/$LANG" \ || MANDIR="$MANPATH" if [ -z "$PAGER" ]; then for prog in $(printf " less more cat dd "); do if which "$prog" >/dev/null 2>&1; then PAGER="$prog" break fi done fi man() { eq $# 2 || die "$argv0: man() called with $# arguments. Expected 2. This is a programmer error\n" MANSECTIONS="$1" NAME="$2" # the way manpages are laid out SUCKS # so, yeah, each man section is one character. which means it's totally # bueno to just iterate over the string like this. but $MANDIR/man1 can # have both man.1.gz AND man.1p.gz. ARGH!!!! for SECTION in $(printf "$MANSECTIONS" | sed 's/\(.\)/\1\n/g'); do PAGE="$(find "$MANDIR/man$SECTION" -type f 2>/dev/null | grep "\/$NAME\.\|\/$NAME$" | sed q)" [ -z "$PAGE" ] || break done ! [ -n "$PAGE" ] \ && printf "No manual entry for $NAME\n" \ && return 1 case "$(file -bir --no-buffer "$PAGE")" in ("text/"*) COMMAND="cat" ;; ("application/gzip"*) COMMAND="zcat" ;; (*) die "$argv0: $PAGE: Unknown file type.\n" ;; esac $COMMAND "$PAGE" | nroff -man | $PAGER } # this seems to be what the popular man does # so like `man foo -k bar` will show the manpages for foo, -k, and bar # expected behavior imo would be manpage for foo, then gist for bar # but let's not break things if streq "$1" "-k"; then # -k printf "Not yet implemented\n" && exit 1 else # not -k while gt $# 0; do if eq $(fdivide $# 2) 0 && gt 1 $# || ! stris int "$1"; then MANSECTIONS="$default_mansections" NAME="$1" SHIFTING=1 elif gt 1 $(fdivide $# 2); then MANSECTIONS="$1" NAME="$2" SHIFTING=2 else exit 0 # no more args fi man "$MANSECTIONS" "$NAME" shift $SHIFTING done fi