1#!/bin/sh -e
2#
3# Copyright 2005 Branden Robinson
4# Changes copyright 2007 by their respective authors
5#
6# This program is free software; you can redistribute it and/or modify
7# it under the terms of the GNU General Public License as published by
8# the Free Software Foundation; either version 2 of the License, or
9# (at your option) any later version.
10#
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14# GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License along
17# with this program; if not, write to the Free Software Foundation, Inc.,
18# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19
20usage() {
21    cat <<EOF
22Usage: manpage-alert [options] [paths]
23  Options:
24    -h, --help          This usage screen.
25    -V, --version       Display the version and copyright information.
26    -f, --file          Show filenames of missing manpages
27                        without any leading text.
28    -p, --package       Show filenames of missing manpages
29                        with their package name.
30    -n, --no-stat       Do not show statistics at the end.
31
32  This script will locate executables in the given paths with manpage
33  outputs for which no manpage is available and its statistics.
34
35  If no paths are specified on the command line, "/bin /sbin /usr/bin
36  /usr/sbin /usr/games" will be used by default.
37EOF
38}
39
40version() {
41    cat <<EOF
42This is manpage-alert, from the Debian devscripts package, version ###VERSION###.
43This code is (C) 2005 by Branden Robinson, all rights reserved.
44This program comes with ABSOLUTELY NO WARRANTY.
45You are free to redistribute this code under the terms of the
46GNU General Public License, version 2 or later.
47EOF
48}
49
50showpackage() {
51    F1="$1"
52    P1="$(LANG=C dpkg-query -S "$F1" 2> /dev/null || true )"
53    Q1=""; R1=""; Q2=""; R2=""
54    if [ -n "$P1" ]; then
55        Q1="$(echo "$P1" | grep -v "^diversion by" || true)"
56        R1="$(echo "$P1" | sed -ne 's/^diversion by \(.*\) to:.*$/\1/p'): $F1"
57    fi
58    # symlink may be created by postinst script for alternatives etc.,
59    if [ -z "$Q1" ] && [ -L "$F1" ]; then
60        F2=$(readlink -f "$F1")
61        P2="$(LANG=C dpkg-query -S "$F2" 2> /dev/null || true )"
62        if [ -n "$P2" ]; then
63            Q2="$(echo "$P2" | grep -v "^diversion by" || true)"
64            R2="$(echo "$P2" | sed -ne 's/^diversion by \(.*\) to:.*$/\1/p'): $F2"
65        fi
66    fi
67    if [ -n "$Q1" ]; then
68        echo "$Q1"
69    elif [ -n "$R1" ]; then
70        echo "$R1 (diversion)"
71    elif [ -n "$Q2" ]; then
72        echo "unknown_package: $F1 -> $Q2"
73    elif [ -n "$R2" ]; then
74        echo "unknown_package: $F1 -> $R2 (diversion)"
75    else
76        echo "unknown_package: $F1"
77    fi
78}
79
80SHOWPACKAGE=DEFAULT
81SHOWSTAT=TRUE
82
83while [ -n "$1" ]; do
84    case "$1" in
85        -h|--help) usage; exit 0;;
86        -V|--version) version; exit 0;;
87        -p|--package) SHOWPACKAGE=PACKAGE
88            shift
89            ;;
90        -f|--file) SHOWPACKAGE=FILE
91            shift
92            ;;
93        -n|--no-stat) SHOWSTAT=FALSE
94            shift
95            ;;
96        *)  break
97            ;;
98    esac
99done
100
101if [ $# -lt 1 ]; then
102    # check if we're running on a usrmerge system
103    if [ -L /bin -a -L /sbin ]; then
104        set -- /usr/bin /usr/sbin /usr/games
105     else
106        set -- /bin /sbin /usr/bin /usr/sbin /usr/games
107    fi
108fi
109
110NUM_EXECUTABLES=0
111NUM_MANPAGES_FOUND=0
112NUM_MANPAGES_MISSING=0
113
114for DIR in "$@"; do
115    for F in "$DIR"/*; do
116        # Skip as it's a symlink to /usr/bin
117        if [ "$F" = "/usr/bin/X11" ]; then continue; fi
118        NUM_EXECUTABLES=$(( NUM_EXECUTABLES + 1 ))
119
120        if OUT=$(man -w -S 1:8:6 "${F##*/}" 2>&1 >/dev/null); then
121            NUM_MANPAGES_FOUND=$(( NUM_MANPAGES_FOUND + 1 ))
122        else
123            if [ $SHOWPACKAGE = "PACKAGE" ]; then
124                # echo "<packagename>: <filename>"
125                showpackage "$F"
126            elif [ $SHOWPACKAGE = "FILE" ]; then
127                # echo "<filename>"
128                echo "$F"
129            else
130                # echo "No manual entry for <filename>"
131                echo "$OUT" | perl -ne "next if /^.*'man 7 undocumented'.*$/;" \
132                  -e "s,(\W)\Q${F##*/}\E(?:\b|$),\1$F,; s,//,/,; print;"
133            fi
134            NUM_MANPAGES_MISSING=$(( NUM_MANPAGES_MISSING + 1 ))
135        fi
136    done
137done
138
139if [ $SHOWSTAT = "TRUE" ]; then
140echo
141printf "Of %d commands, found manpages for %d (%d missing).\n" \
142    $NUM_EXECUTABLES \
143    $NUM_MANPAGES_FOUND \
144    $NUM_MANPAGES_MISSING
145fi
146
147# vim:set ai et sw=4 ts=4 tw=80:
148