xref: /freebsd/usr.sbin/manctl/manctl.sh (revision a9fcb51fbb8d2c5b47a35bcae5b4d5fb771c5985)
1#!/bin/sh
2#
3# Copyright (c) 1994 Geoffrey M. Rehmet, Rhodes University
4# All rights reserved.
5#
6# Redistribution and use in source and binary forms, with or without
7# modification, are permitted provided that the following conditions
8# are met:
9# 1. Redistributions of source code must retain the above copyright
10#    notice, this list of conditions and the following disclaimer.
11# 2. Redistributions in binary form must reproduce the above copyright
12#    notice, this list of conditions and the following disclaimer in the
13#    documentation and/or other materials provided with the distribution.
14# 3. All advertising materials mentioning features or use of this software
15#    must display the following acknowledgement:
16#	This product includes software developed by Geoffrey M. Rehmet
17# 4. Neither the name of Geoffrey M. Rehmet nor that of Rhodes University
18#    may be used to endorse or promote products derived from this software
19#    without specific prior written permission.
20#
21# THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
22# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
23# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24# IN NO EVENT SHALL GEOFFREY M. REHMET OR RHODES UNIVERSITY BE LIABLE
25# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31# SUCH DAMAGE.
32#
33# $FreeBSD$
34#
35# manctl:
36#	a utility for manipulating manual pages
37# functions:
38#	compress uncompressed man pages (elliminating .so's)
39#		this is now two-pass.  If possible, .so's
40#		are replaced with hard links
41#	uncompress compressed man pages
42#	purge old formatted man pages (not implemented yet)
43# Things to watch out for:
44#	Hard links - careful with g(un)zipping!
45#	.so's - throw everything through soelim before gzip!
46#	symlinks - ignore these - eg: expn is its own man page:
47#			don't want to compress this!
48#
49PATH=/bin:/sbin:/usr/bin:/usr/sbin; export PATH
50
51#
52# purge cat? directories
53#
54do_purge()
55{
56	echo "purge $@" 2>&1
57	echo "not implemented yet\n" 2>&1
58}
59
60
61#
62# Uncompress one page
63#
64uncompress_page()
65{
66	local	pname
67	local	fname
68	local	sect
69	local	ext
70
71	# break up file name
72	pname=$1
73	IFS='.' ; set $pname
74	# less than 3 fields - don't know what to do with this
75	if [ $# -lt 3 ] ; then
76		IFS=" 	" ; echo ignoring $pname 1>&2 ; return 0 ;
77	fi
78	# construct name and section
79	fname=$1 ; shift
80	while [ $# -gt 2 ] ; do
81		fname=$fname.$1
82		shift
83	done
84	sect=$1
85	ext=$2
86
87	IFS=" 	"
88	case "$ext" in
89	gz|Z) 	{
90		IFS=" 	" ; set `file $pname`
91		if [ $2 != "gzip" ] ; then
92			echo moving hard link $pname 1>&2
93			mv $pname $fname.$ext	# link
94		else
95			if [ $2 != "symbolic" ] ; then
96				echo gunzipping page $pname 1>&2
97				temp=`mktemp -t manager` || exit 1
98				gunzip -c $pname > $temp
99				chmod u+w $pname
100				cp $temp $pname
101				chmod 444 $pname
102				mv $pname $fname.$sect
103				rm -f $temp
104			else
105				# skip symlinks - this can be
106				# a program like expn, which is
107				# its own man page !
108				echo skipping symlink $pname 1>&2
109			fi
110		fi };;
111	*)	{
112		IFS=" 	"
113		echo skipping file $pname 1>&2
114		} ;;
115	esac
116	# reset IFS - this is important!
117	IFS=" 	"
118}
119
120
121#
122# Uncompress manpages in paths
123#
124do_uncompress()
125{
126	local	i
127	local	dir
128	local	workdir
129
130	workdir=`pwd`
131	while [ $# != 0 ] ; do
132		if [ -d $1 ] ; then
133			dir=$1
134			cd $dir
135			for i in * ; do
136				case $i in
137				*cat?)	;; # ignore cat directories
138				*)	{
139					if [ -d $i ] ; then
140						do_uncompress $i
141					else
142						if [ -e $i ] ; then
143							uncompress_page $i
144						fi
145					fi } ;;
146				esac
147			done
148			cd $workdir
149		else
150			echo "directory $1 not found" 1>&2
151		fi
152		shift
153	done
154}
155
156#
157# Remove .so's from one file
158#
159so_purge_page()
160{
161 	local	so_entries
162	local	lines
163	local	fname
164
165	so_entries=`grep "^\.so" $1 | wc -l`
166	if [ $so_entries -eq 0 ] ; then return 0 ; fi
167
168	# we have a page with a .so in it
169	echo $1 contains a .so entry 2>&1
170
171	# now check how many lines in the file
172	lines=`wc -l < $1`
173
174	# if the file is only one line long, we can replace it
175	# with a hard link!
176	if [ $lines -eq 1 ] ; then
177		fname=$1;
178		echo replacing $fname with a hard link
179		set `cat $fname`;
180		rm -f $fname
181		ln ../$2 $fname
182	else
183		echo inlining page $fname 1>&2
184		temp=`mktemp -t manager` || exit 1
185		cat $fname | \
186		(cd .. ; soelim ) > $temp
187		chmod u+w $fname
188		cp $temp $fname
189		chmod 444 $fname
190		rm -f $temp
191	fi
192}
193
194#
195# Remove .so entries from man pages
196#	If a page consists of just one line with a .so,
197#	replace it with a hard link
198#
199remove_so()
200{
201	local	pname
202	local	fname
203	local	sect
204
205	# break up file name
206	pname=$1
207	IFS='.' ; set $pname
208	if [ $# -lt 2 ] ; then
209		IFS=" 	" ; echo ignoring $pname 1>&2 ; return 0 ;
210	fi
211	# construct name and section
212	fname=$1 ; shift
213	while [ $# -gt 1 ] ; do
214		fname=$fname.$1
215		shift
216	done
217	sect=$1
218
219	IFS=" 	"
220	case "$sect" in
221	gz) 	{ echo file $pname already gzipped 1>&2 ; } ;;
222	Z)	{ echo file $pname already compressed 1>&2 ; } ;;
223	[12345678ln]*){
224		IFS=" 	" ; set `file $pname`
225		if [ $2 = "gzip" ] ; then
226			echo moving hard link $pname 1>&2
227			mv $pname $pname.gz	# link
228		else
229			if [ $2 != "symbolic" ] ; then
230				echo "removing .so's in  page $pname" 1>&2
231				so_purge_page $pname
232			else
233				# skip symlink - this can be
234				# a program like expn, which is
235				# its own man page !
236				echo skipping symlink $pname 1>&2
237			fi
238		fi };;
239	*)	{
240		IFS=" 	"
241		echo skipping file $pname 1>&2
242		} ;;
243	esac
244	# reset IFS - this is important!
245	IFS=" 	"
246}
247
248
249#
250# compress one page
251#	We need to watch out for hard links here.
252#
253compress_page()
254{
255	local	pname
256	local	fname
257	local	sect
258
259	# break up file name
260	pname=$1
261	IFS='.' ; set $pname
262	if [ $# -lt 2 ] ; then
263		IFS=" 	" ; echo ignoring $pname 1>&2 ; return 0 ;
264	fi
265	# construct name and section
266	fname=$1 ; shift
267	while [ $# -gt 1 ] ; do
268		fname=$fname.$1
269		shift
270	done
271	sect=$1
272
273	IFS=" 	"
274	case "$sect" in
275	gz) 	{ echo file $pname already gzipped 1>&2 ; } ;;
276	Z)	{ echo file $pname already compressed 1>&2 ; } ;;
277	[12345678ln]*){
278		IFS=" 	" ; set `file $pname`
279		if [ $2 = "gzip" ] ; then
280			echo moving hard link $pname 1>&2
281			mv $pname $pname.gz	# link
282		else
283			if [ $2 != "symbolic" ] ; then
284				echo gzipping page $pname 1>&2
285				temp=`mktemp -t manager` || exit 1
286				cat $pname | \
287				(cd .. ; soelim )| gzip -c -- > $temp
288				chmod u+w $pname
289				cp $temp $pname
290				chmod 444 $pname
291				mv $pname $pname.gz
292				rm -f $temp
293			else
294				# skip symlink - this can be
295				# a program like expn, which is
296				# its own man page !
297				echo skipping symlink $pname 1>&2
298			fi
299		fi };;
300	*)	{
301		IFS=" 	"
302		echo skipping file $pname 1>&2
303		} ;;
304	esac
305	# reset IFS - this is important!
306	IFS=" 	"
307}
308
309#
310# Compress man pages in paths
311#
312do_compress_so()
313{
314	local	i
315	local	dir
316	local	workdir
317	local	what
318
319	what=$1
320	shift
321	workdir=`pwd`
322	while [ $# != 0 ] ; do
323		if [ -d $1 ] ; then
324			dir=$1
325			cd $dir
326			for i in * ; do
327				case $i in
328				*cat?)	;; # ignore cat directories
329				*)	{
330					if [ -d $i ] ; then
331						do_compress_so $what $i
332					else
333						if [ -e $i ] ; then
334							$what $i
335						fi
336					fi } ;;
337				esac
338			done
339			cd $workdir
340		else
341			echo "directory $1 not found" 1>&2
342		fi
343		shift
344	done
345}
346
347#
348# Display a usage message
349#
350ctl_usage()
351{
352	echo "usage: $1 -compress <path> ... " 1>&2
353	echo "       $1 -uncompress <path> ... " 1>&2
354	echo "       $1 -purge <days> <path> ... " 1>&2
355	echo "       $1 -purge expire <path> ... " 1>&2
356	exit 1
357}
358
359#
360# remove .so's and do compress
361#
362do_compress()
363{
364	# First remove all so's from the pages to be compressed
365	do_compress_so remove_so "$@"
366	# now do ahead and compress the pages
367	do_compress_so compress_page "$@"
368}
369
370#
371# dispatch options
372#
373if [ $# -lt 2 ] ; then ctl_usage $0 ; fi ;
374
375case "$1" in
376	-compress)	shift ; do_compress "$@" ;;
377	-uncompress)	shift ; do_uncompress "$@" ;;
378	-purge)		shift ; do_purge "$@" ;;
379	*)		ctl_usage $0 ;;
380esac
381