88 lines
2.2 KiB
Bash
Executable File
88 lines
2.2 KiB
Bash
Executable File
#!/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
|