#!/bin/bash
# script: debmany
# author: Michael Arlt
# description: select the manpages of any [not] installed debian package
# comment: debmany is based on the work of debman and debget
# uses: whiptail (preferred) or dialog as well as curl
# This is free software. You may redistribute copies of it under the terms of
# the GNU General Public License <http://www.gnu.org/licenses/gpl.html>.
# There is NO WARRANTY, to the extent permitted by law.
LC_ALL=C
# choose the manpageviewer
mancmdline="man %s" # default manpageviewer
curdir=`pwd`
error()
{
# show errorcode and quit
echo "ERROR: $*" >&2
exit 1
}
usage()
{
echo "debmany 1.2 Mon Aug 27 19:06:55 CEST 2007
Description: Display a manpage from a Debian package.
The list of manpages is displayed in a dialog.
Supported locations for debian packages are: Local .deb-file,
a package in the repository or an installed package.
Syntax1 : debmany [-?|-h|--help]
Syntax2 : debmany [-m viewer|-k|-g|-x] [-L limit] [-l lang1[,...]] package[.deb]
Examples: debmany foo.deb show manpages from a local package file foo.deb
debmany foo show manpages from a package, if the package is
not installed it is retrieved from the
configured repositories.
debmany -k foo show manpages using your preferred man-viewer (KDE)
debmany -g foo show manpages using your preferred man-viewer (GNOME)
debmany -x foo show manpages using your preferred man-viewer
using xdg-open from xdg-utils package (Xfce users)
debmany -m 'konqueror man:%s' -l de,fr -L 5M foo
show english, german and french manpages using
konqueror as man-viewer and ask if download size
exceeds 5M
alias debmany='debmany -l de -L 5M -k'; debmany -m man -l '*' foo
set an alias with your preferred options and
overwrite them if needed"
if [ $# -eq 0 ]
then
exit 0
else
error "$*"
fi
}
while [ $# -gt 0 ]
do
case $1 in
"-?"|-h|--help) usage ;;
-m) # override default manpageviewer or environment variable DEBMANY_MAN_VIEWER
shift
mancmd=($1) # get first word from manpageviewer
if which $mancmd >/dev/null 2>&1 # is the manpageviewer executeable?
then
echo $1 | grep -q "%s" && mancmdline="$1" || mancmdline="$1 %s"
else
usage "Manpageviewer '$mancmd' is not available or executable"
fi
;;
-k) mancmdline='kfmclient exec man:%s';; # set kde viewer
-g) mancmdline='gnome-open man:%s';; # set gnome viewer
-x) mancmdline='xdg-open man:%s';; # set independant viewer
-l) shift; lang=$1;; # remember language
-L) shift; asksize=$1;; # remember asksize
-*) usage "Unknown option '$1'.";;
*) package="$1";;
esac
shift
done
test -z "$package" && usage "You must specify one package or a Debian package file."
# determine the size of your terminal
declare -i size=(`stty size`)
declare -i x=${size[1]}
declare -i y=${size[0]}
# if it is impossible to determine the size
if [ $x -eq 0 ]
then
x=80
y=25
echo "Unable to determine the size of your terminal - using Console default: $x*$y" >&2
sleep 3
fi
# test upon minimum resolution
if [ $x -lt 40 -o $y -lt 9 ]
then
error "Resolution too small ($x*$y). I need a minimum of 40*9 - recommended is more..."
fi
# set the size of the dialog window and menu
x=x-1 # width of the dialog
y=y-1 # height of the dialog
declare -i h=y-7 # height of the menu
if [ "${package##*.}" = "deb" ]
then
# mode1: you want to see manpages from a .deb-file
if [ -r "$package" ]
then
file=`readlink -f "$package"`
status=file
else
error "The file $package cannot be read."
fi
else
# mode 2: test if you have the package already installed
if dpkg -l "$package" 2>/dev/null | grep -q ^i
then
status=installed
set -f
# modify lang for grep regular expressions: fr -> fr\.* (-> fr+fr.ISO8859-1+"fr."...)
langgrep=`echo $lang|sed -e s/*/.*/g -e 's/\([a-zA-Z_][a-zA-Z_]*\)/\1,\1\\\\\\.*/'`
# create the list of all mandirs (with -e for grep) (X11R6 is only for sarge - didn't find it in etch anymore)
mandirs="`eval echo \\"-e \\"/usr/\{share,X11R6\}/man/man.*/ \\"-e \\"/usr/\{share,X11R6\}/man/\{$langgrep,XYZZXY\}/`"
for man in `dpkg -L "$package" 2>/dev/null|grep $mandirs|sort`
do
# mode 2: add the manpages to the list
test -f $man && manpages="$manpages $man ${man##*/}"
done
set +f
fi
fi
# choose whiptail or dialog
whiptail=/usr/bin/whiptail
dialog=/usr/bin/dialog
test -x $whiptail && cmd=$whiptail || cmd=$dialog
if [ "$status" = "installed" ]
then
# mode 2
cd /
else
# mode 1 and 3
trap 'test -n "$temp" && rm -rf $temp; exit' 0 2 15 # cleanup
tmp=/dev/shm # set default tempdir
test -d $tmp || tmp=/tmp # if not available use /tmp
# make a temporary folder for the manpages - $TMPDIR overrides the path of -p
temp=`mktemp -d -p $tmp debmany.XXXXXXXXXX` || error "Unable to create a temporary folder."
if [ -z "$file" ]
then
# mode 3: find the package.deb
aptdata=`apt-get -q2 --print-uris --reinstall install "$package" 2>/dev/null | tail -1`
if [ -z "$aptdata" ]
then
error "There is no package called '$package'."
exit 1
fi
url=`echo "$aptdata" | sed -e "s/^'\([^']*\)'.*$/\1/"`
test -z "$url" && error "Could not obtain an URL for '$pkgspec'."
if [ "${url%%:*}" = "file" ]
then
# mode 3: access the local file
file="${url#*:}"
if [ ! -r "$file" ]
then
error "Could not access '$file' from the repository."
fi
status=repos-file
else
# mode 3: download the local file
file="$temp/tmp.deb"
# if i should ask at a specific size
if [ "$asksize" != "" ]
then
# determine the size of the file to download (*10 for 10,5M)
declare -i size=`apt-cache show "$package"|grep ^"Size: "|cut -f2 -d" "|head -1`*10
# determine the value of ask_size
templimit=`echo ${asksize//[^0-9]/}`
test "$templimit" = "" && error "Parameter -L needs an argument - e.g. '10M'."
declare -i limit=`echo ${asksize//[^0-9]/}`*10
# determine the unit of ask_size
unit=`echo ${asksize//[0-9]/}`
# calculate the limit according to unit from DEBMANY_ASK_SIZE
case $unit in
B|"") ;;
K) limit=limit*1024;;
M) limit=limit*1024*1024;;
G) limit=limit*1024*1024*1024;;
T) limit=limit*1024*1024*1024*1024;;
*) error "Invalid unit '$unit' in variable DEBMANY_ASK_SIZE."
esac
# calculate the human readable size and ask for download if size exceeds limit
if [ $size -ge $limit ]
then
unit=B
# reduce the size and correct the unit until it is human readable
while [ $size -gt 1024 ]
do
size=size/1024
case $unit in
G) unit=T;;
M) unit=G;;
K) unit=M;;
B) unit=K;;
esac
done
# set the comma (so if the file has a size of 50M we change 500 to 50,0M
commasize=`echo $size|sed "s/\([0-9]*\)\([0-9]\)/\1,\2/"`$unit
# ask if the download may start - otherwise debmany exits
if ! $cmd --yesno "Would you like to download the package with a size of $commasize?" 9 40
then
echo "Download undesired - $commasize is too big."
exit
fi
fi
fi
curl "$url" >"$file" || error "Could not download '$file' from the repository."
status=repos-curl
fi
fi
cd $temp
# extract the manpages
set -f
# modify lang for pathname expansion: fr -> fr.* (-> fr+fr.ISO8859-1+"fr."...)
lang=`echo $lang|sed -e 's/\([a-zA-Z_][a-zA-Z_]*\)/\1,\1*/'`
# create the list of all mandirs (X11R6 is only for sarge - didn't find it in etch anymore)
mandirs="`eval echo \{./,\}usr/\{share,X11R6\}/man/man*/ \{./,\}usr/\{share,X11R6\}/man/\{$lang,XYZZXY\}/`"
dpkg --fsys-tarfile "$file" | tar --wildcards -xf - $mandirs 2>/dev/null
set +f
manpages=`find usr -type f|sort|sed -e 's§\([^/]*\)$§\1 \1§'`
fi
while true
do
# test if manpages where found
test -z "$manpages" && error "No manpage exists for package '$package'."
# select your manpages using dialog
exec 3>&1
return=`$cmd --title "Select a manpage ($status:$package)" --menu '' $y $x $h $manpages 2>&1 1>&3`
exec 3>&-
if [ -n "$return" ]
then
# show the manpage
`printf "$mancmdline" "$PWD/$return"`
else
cd $curdir
exit
fi
done
# This should not be reached
cd $curdir
exit 0