Skip to content

Commit

Permalink
Added wman.
Browse files Browse the repository at this point in the history
  • Loading branch information
jgm committed Nov 3, 2010
1 parent 066ee52 commit dce34de
Show file tree
Hide file tree
Showing 2 changed files with 373 additions and 0 deletions.
3 changes: 3 additions & 0 deletions README
Expand Up @@ -9,6 +9,9 @@ tunnel
wiki wiki
start vim with local wiki start vim with local wiki


wman
fetch man pages for different OSs

word2pdf word2pdf
convert Word files to PDF from the command line, using OpenOffice convert Word files to PDF from the command line, using OpenOffice


Expand Down
370 changes: 370 additions & 0 deletions wman
@@ -0,0 +1,370 @@
#!/bin/sh
#
# Fetch man pages for selected OS from a man page mirror.
# Copyright © 2004 Emre Sevinc <fz@ileriseviye.org>
# Tweaked by KIVILCIM "Sundance" Hindistan <sundance@fazlamesai.net>
# Lots of changes by Recai Oktaþ <roktas@debian.org>
#
# Licensed under the GNU General Public License, version 2.
# See the file `http://www.gnu.org/copyleft/gpl.txt'.


# ------------------------------------------------------------------------------
# Script constants
# ------------------------------------------------------------------------------

NAME=wman
THIS=${0##*/}

SYSTEM_CONF=/etc/${NAME}rc
USER_CONF=$HOME/.${NAME}rc


# ------------------------------------------------------------------------------
# Default setting for target OSes
# ------------------------------------------------------------------------------
DEFAULT_OPENBSD='
OSNAME=OpenBSD
HOST=http://www.openbsd.org
CGI=cgi-bin/man.cgi?query=$page&sektion=$sect&format=troff
FORMAT=raw
FAILURE=[Nn]o [Mm]anual [Ee]ntry
'

DEFAULT_FREEBSD='
OSNAME=FreeBSD
HOST=http://www.freebsd.org
CGI=cgi/man.cgi?query=$page&sektion=$sect&format=troff
FORMAT=html
FAILURE=^[Ss]orry
'

DEFAULT_NETBSD='
OSNAME=NetBSD
HOST=http://netbsd.gw.com
CGI=cgi-bin/man-cgi?$page+$sect
FORMAT=html
FILTER=DEFAULT_NETBSD_FILTER
FAILURE=[Mm]anual [Pp]age was not found
'
DEFAULT_NETBSD_FILTER () {
sed '/^-----/,$d'
}

DEFAULT_DRAGONFLY='
OSNAME=Dragonfly BSD
HOST=http://leaf.dragonflybsd.org
CGI=cgi/web-man?command=$page&section=$sect
FORMAT=html
FAILURE=[Mm]anual [Pp]age could not be found
'

DEFAULT_LINUX='
OSNAME=GNU/Linux
HOST=http://www.freebsd.org
CGI=cgi/man.cgi?query=$page&sektion=$sect&manpath=Red+Hat+Linux%2Fi386+9&format=troff
FORMAT=html
FAILURE=^[Ss]orry
'

# ------------------------------------------------------------------------------
# Helpers
# ------------------------------------------------------------------------------

# Portable which(1).
pathfind () {
ifs_save="$IFS"
IFS=:
for _p in $PATH; do
if [ -x "$_p/$*" ] && [ -f "$_p/$*" ]; then
IFS="$OLDIFS"
return 0
fi
done
IFS="$ifs_save"
return 1
}

dumper_raw () {
for p in wget lynx w3m curl links w3c; do
if pathfind $p; then
dumper=$p
break
fi
done
# Setup proper options.
case "$dumper" in
wget) opt="-O-" ;;
lynx) opt="-source" ;;
w3m) opt="-dump_source" ;;
curl) opt="" ;;
links) opt="-source" ;;
w3c) opt="-n -get" ;;
"") printf "Couldn't locate a program to fetch files from net " >&2
printf "(e.g. wget, w3m, lynx, w3c, or curl).\n" >&2
exit 1 ;;
esac
$dumper $opt "$@"
}

dumper_html () {
# TODO w3c
for p in w3m links elinks lynx; do
if pathfind $p; then
dumper=$p
break
fi
done
# Setup proper options.
case "$dumper" in
w3m) opt="-dump" ;;
links) opt="-dump" ;;
elinks) opt="-dump" ;;
lynx) opt="-dump" ;;
"") printf "Couldn't locate a program to fetch files from net " >&2
printf "(e.g. lynx, w3m, lynx or w3c).\n" >&2
exit 1 ;;
esac
$dumper $opt "$@"
}

is_cache_valid () {
cache="$1"
failstamp="$2"
if [ $(sed '/^[[:blank:]]*$/d' $cache | wc -l) -lt 20 ]; then
[ -z "$DEBUG" ] || echo >&2 "Fetched file is too small!"
return 1
fi
if sed '/^[[:blank:]]*$/d;{3q}' $cache | grep -q "$failstamp"; then
[ -z "$DEBUG" ] || echo >&2 "Failure stamp '$failstamp' seen!"
return 1
fi
return 0
}


# ------------------------------------------------------------------------------
# Init
# ------------------------------------------------------------------------------

LC_ALL=C
export LC_ALL

for conf in $SYSTEM_CONF $USER_CONF; do
# Read user conf file.
if [ -r $conf ]; then
case $- in
*e*) ;;
*) set -e; noexitonerr=yes ;;
esac
trap "Error in configuration file $conf; aborting." QUIT INT
. $conf
trap - QUIT INT
if [ -n "$noexitonerr" ]; then
set +e
fi
fi
done

OS=
DEBUG=${DEBUG-}
CACHE_RENEW=
while getopts o:dhn opt; do
case $opt in
o) OS="$OPTARG" ;;
d) DEBUG=yes ;;
r) CACHE_RENEW=yes ;;
h) cat >&2 <<- EOF
Usage: $THIS [options] [section] page
Options:
-o os_name operating system (e.g. openbsd, netbsd)
-d print debug info
-n renew cache
-h this screen
EOF
exit 2 ;;
esac
done
shift $(($OPTIND - 1))

if [ -z "$OS" ] && ! [ "$THIS" = "$NAME" ]; then
OS=$(echo "$THIS" | sed 's/^man[-_+]//')
else
DEFAULT_OS=${DEFAULT_OS:-$(uname)}
OS=${OS:-$DEFAULT_OS}
fi

if [ -z "$OS" ]; then
echo "Couldn't determine OS; aborting"
exit 1
fi

OS=$(echo $OS | tr 'a-z' 'A-Z')

# Defaults for some global settings.
PAGER=${PAGER-less}
DEBUG=${DEBUG:-}
CACHEROOT=${CACHEROOT-$HOME/.$THIS}

if [ $# -eq 0 ]; then
echo >&2 "What manual page do you want?"
exit 1
fi

sect=
case "$1" in
[1-9])
sect=$1
shift

if [ -z "$1" ]; then
echo >&2 "What manual page do you want from section ${sect}?"
exit 1
fi
;;
esac

page="$1"

NEWLINE='
'
OLDIFS="$IFS"
_expand_variable () {
condensed=${1:?'variable empty!'}

eval "this=\$$condensed"

# Expand page and sect.
eval "this=\"$this\""

IFS="$NEWLINE"
for line in $this; do
IFS="$OLDIFS"

var="${line%%=*}"
val="${line#[!=]*=}"
case "$var" in
'OSNAME'|'HOST'|'CGI'|'FORMAT'|'FILTER'|'FAILURE')
var="man_$(echo $var | tr 'A-Z' 'a-z')"
eval "$var=\${$var:-$val}" ;;
*)
continue ;;
esac
done
}

# User settings.
_expand_variable "$OS"

# Builtin default settings.
_expand_variable "DEFAULT_$OS"

man_url="$man_host/$man_cgi"
man_dumper="dumper_$man_format"
man_osname="${man_osname:-$(echo $OS | tr 'A-Z' 'a-z')}"

[ -z "$DEBUG" ] || cat >&2 <<- EOF
Fetch parameters:
OS: $man_osname
Page: $page
Section: $sect
Host: $man_host
CGI: $man_cgi
Format: $man_format
Dumper: $man_dumper
Filter: $man_filter
Failure: '$man_failure'
Resulting url: $man_url
EOF

( eval $man_dumper </dev/null >/dev/null 2>&1 )
if [ $? -eq 127 ]; then
echo >&2 "No such '$man_format' dumper for '$OS'; aborting"
exit 1
fi

if [ -n "$man_filter" ]; then
( eval $man_filter </dev/null >/dev/null 2>&1 )
if [ $? -eq 127 ]; then
echo >&2 "No such '$man_filter' for '$OS'; aborting"
exit 1
fi
else
man_filter=cat
fi

# ... now cache variables
cachedir=$CACHEROOT/$(echo $OS | tr 'A-Z' 'a-z')
man_cache=$cachedir/$page.${sect:-0} # use 0 to catch the default man page


# ------------------------------------------------------------------------------
# Main
# ------------------------------------------------------------------------------

if [ -n "$CACHE_RENEW" ] || {
[ -f $man_cache ] && ! is_cache_valid $man_cache "$man_failure"
}; then
rm -f $man_cache
fi

what="$man_osname manual entry for $page"
if [ -n "$sect" ]; then
what="$what in section $sect"
fi

if ! [ -f $man_cache ]; then
# Initiate cache if it doesn't exist.
(umask 0077 && mkdir -p $cachedir)

tmpfile="$(mktemp $cachedir/$THIS.XXXXXXXX)" || exit 1
# Remove partial files.
trap 'exitcode=$?
[ -z "$tmpfile" ] || rm -rf "$tmpfile"
exit $exitcode' 0 1 2 3 13 15

printf "Querying $what... " >&2
if $man_dumper "$man_url" 2>/dev/null | sed '/./,$!d' >$tmpfile; then
if is_cache_valid $tmpfile "$man_failure"; then
echo "success."
mv -f $tmpfile $man_cache && tmpfile=
else
echo "failed."
fi >&2
else
echo >&2 "fetch failed."
fi
fi

if ! [ -f $man_cache ]; then
echo >&2 "No $what."
exit 1
fi

# Attempt to reduce cache space whenever a section is explicitly given.
# Note that we avoid to extract the section info from cache file, since
# this might be unreliable for some formats and also it would increase
# the code complexity.
if [ "$sect" != "0" ]; then
man_fallback=$cachedir/$page.0
if [ -f $man_fallback ] && ! [ -L $man_fallback ]; then
(
cd $cachedir
# Search for an idantic file.
found=
for f in $page.[1-9]; do
if cmp -s $f $man_fallback; then
found=$f
break
fi
done
# If found, symlink it to sectioned file to reduce space.
[ -z "$found" ] || ln -sf $found $man_fallback
)
fi
fi

$man_filter <$man_cache | $PAGER

0 comments on commit dce34de

Please sign in to comment.