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