xref: /freebsd/usr.sbin/manctl/manctl.sh (revision a466cc55373fc3cf86837f09da729535b57e69a1)
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# $FreeBSD$
36#
37# manctl:
38#	a utility for manipulating manual pages
39# functions:
40#	compress uncompressed man pages (elliminating .so's)
41#		this is now two-pass.  If possible, .so's
42#		are replaced with hard links
43#	uncompress compressed man pages
44# Things to watch out for:
45#	Hard links - careful with g(un)zipping!
46#	.so's - throw everything through soelim before gzip!
47#	symlinks - ignore these - eg: expn is its own man page:
48#			don't want to compress this!
49#
50PATH=/bin:/sbin:/usr/bin:/usr/sbin; export PATH
51
52#
53# Uncompress one page
54#
55uncompress_page()
56{
57	local	pname
58	local	fname
59	local	sect
60	local	ext
61
62	# break up file name
63	pname=$1
64	IFS='.' ; set $pname
65	# less than 3 fields - don't know what to do with this
66	if [ $# -lt 3 ] ; then
67		IFS=" 	" ; echo ignoring $pname 1>&2 ; return 0 ;
68	fi
69	# construct name and section
70	fname=$1 ; shift
71	while [ $# -gt 2 ] ; do
72		fname=$fname.$1
73		shift
74	done
75	sect=$1
76	ext=$2
77
78	IFS=" 	"
79	case "$ext" in
80	gz|Z) 	{
81		IFS=" 	" ; set `file $pname`
82		if [ $2 != "gzip" ] ; then
83			echo moving hard link $pname 1>&2
84			mv $pname $fname.$ext	# link
85		else
86			if [ $2 != "symbolic" ] ; then
87				echo gunzipping page $pname 1>&2
88				temp=`mktemp -t manager` || exit 1
89				gunzip -c $pname > $temp
90				chmod u+w $pname
91				cp $temp $pname
92				chmod 444 $pname
93				mv $pname $fname.$sect
94				rm -f $temp
95			else
96				# skip symlinks - this can be
97				# a program like expn, which is
98				# its own man page !
99				echo skipping symlink $pname 1>&2
100			fi
101		fi };;
102	*)	{
103		IFS=" 	"
104		echo skipping file $pname 1>&2
105		} ;;
106	esac
107	# reset IFS - this is important!
108	IFS=" 	"
109}
110
111
112#
113# Uncompress manpages in paths
114#
115do_uncompress()
116{
117	local	i
118	local	dir
119	local	workdir
120
121	workdir=`pwd`
122	while [ $# != 0 ] ; do
123		if [ -d $1 ] ; then
124			dir=$1
125			cd $dir
126			for i in * ; do
127				case $i in
128				*cat?)	;; # ignore cat directories
129				*)	{
130					if [ -d $i ] ; then
131						do_uncompress $i
132					else
133						if [ -e $i ] ; then
134							uncompress_page $i
135						fi
136					fi } ;;
137				esac
138			done
139			cd $workdir
140		else
141			echo "directory $1 not found" 1>&2
142		fi
143		shift
144	done
145}
146
147#
148# Remove .so's from one file
149#
150so_purge_page()
151{
152 	local	so_entries
153	local	lines
154	local	fname
155
156	so_entries=`grep "^\.so" $1 | wc -l`
157	if [ $so_entries -eq 0 ] ; then return 0 ; fi
158
159	# we have a page with a .so in it
160	echo $1 contains a .so entry 2>&1
161
162	# now check how many lines in the file
163	lines=`wc -l < $1`
164
165	# if the file is only one line long, we can replace it
166	# with a hard link!
167	if [ $lines -eq 1 ] ; then
168		fname=$1;
169		echo replacing $fname with a hard link
170		set `cat $fname`;
171		rm -f $fname
172		ln ../$2 $fname
173	else
174		echo inlining page $fname 1>&2
175		temp=`mktemp -t manager` || exit 1
176		cat $fname | \
177		(cd .. ; soelim ) > $temp
178		chmod u+w $fname
179		cp $temp $fname
180		chmod 444 $fname
181		rm -f $temp
182	fi
183}
184
185#
186# Remove .so entries from man pages
187#	If a page consists of just one line with a .so,
188#	replace it with a hard link
189#
190remove_so()
191{
192	local	pname
193	local	fname
194	local	sect
195
196	# break up file name
197	pname=$1
198	IFS='.' ; set $pname
199	if [ $# -lt 2 ] ; then
200		IFS=" 	" ; echo ignoring $pname 1>&2 ; return 0 ;
201	fi
202	# construct name and section
203	fname=$1 ; shift
204	while [ $# -gt 1 ] ; do
205		fname=$fname.$1
206		shift
207	done
208	sect=$1
209
210	IFS=" 	"
211	case "$sect" in
212	gz) 	{ echo file $pname already gzipped 1>&2 ; } ;;
213	Z)	{ echo file $pname already compressed 1>&2 ; } ;;
214	[12345678ln]*){
215		IFS=" 	" ; set `file $pname`
216		if [ $2 = "gzip" ] ; then
217			echo moving hard link $pname 1>&2
218			mv $pname $pname.gz	# link
219		else
220			if [ $2 != "symbolic" ] ; then
221				echo "removing .so's in  page $pname" 1>&2
222				so_purge_page $pname
223			else
224				# skip symlink - this can be
225				# a program like expn, which is
226				# its own man page !
227				echo skipping symlink $pname 1>&2
228			fi
229		fi };;
230	*)	{
231		IFS=" 	"
232		echo skipping file $pname 1>&2
233		} ;;
234	esac
235	# reset IFS - this is important!
236	IFS=" 	"
237}
238
239
240#
241# compress one page
242#	We need to watch out for hard links here.
243#
244compress_page()
245{
246	local	pname
247	local	fname
248	local	sect
249
250	# break up file name
251	pname=$1
252	IFS='.' ; set $pname
253	if [ $# -lt 2 ] ; then
254		IFS=" 	" ; echo ignoring $pname 1>&2 ; return 0 ;
255	fi
256	# construct name and section
257	fname=$1 ; shift
258	while [ $# -gt 1 ] ; do
259		fname=$fname.$1
260		shift
261	done
262	sect=$1
263
264	IFS=" 	"
265	case "$sect" in
266	gz) 	{ echo file $pname already gzipped 1>&2 ; } ;;
267	Z)	{ echo file $pname already compressed 1>&2 ; } ;;
268	[12345678ln]*){
269		IFS=" 	" ; set `file $pname`
270		if [ $2 = "gzip" ] ; then
271			echo moving hard link $pname 1>&2
272			mv $pname $pname.gz	# link
273		else
274			if [ $2 != "symbolic" ] ; then
275				echo gzipping page $pname 1>&2
276				temp=`mktemp -t manager` || exit 1
277				cat $pname | \
278				(cd .. ; soelim )| gzip -c -- > $temp
279				chmod u+w $pname
280				cp $temp $pname
281				chmod 444 $pname
282				mv $pname $pname.gz
283				rm -f $temp
284			else
285				# skip symlink - this can be
286				# a program like expn, which is
287				# its own man page !
288				echo skipping symlink $pname 1>&2
289			fi
290		fi };;
291	*)	{
292		IFS=" 	"
293		echo skipping file $pname 1>&2
294		} ;;
295	esac
296	# reset IFS - this is important!
297	IFS=" 	"
298}
299
300#
301# Compress man pages in paths
302#
303do_compress_so()
304{
305	local	i
306	local	dir
307	local	workdir
308	local	what
309
310	what=$1
311	shift
312	workdir=`pwd`
313	while [ $# != 0 ] ; do
314		if [ -d $1 ] ; then
315			dir=$1
316			cd $dir
317			for i in * ; do
318				case $i in
319				*cat?)	;; # ignore cat directories
320				*)	{
321					if [ -d $i ] ; then
322						do_compress_so $what $i
323					else
324						if [ -e $i ] ; then
325							$what $i
326						fi
327					fi } ;;
328				esac
329			done
330			cd $workdir
331		else
332			echo "directory $1 not found" 1>&2
333		fi
334		shift
335	done
336}
337
338#
339# Display a usage message
340#
341ctl_usage()
342{
343	echo "usage: $1 -compress <path> ... " 1>&2
344	echo "       $1 -uncompress <path> ... " 1>&2
345	exit 1
346}
347
348#
349# remove .so's and do compress
350#
351do_compress()
352{
353	# First remove all so's from the pages to be compressed
354	do_compress_so remove_so "$@"
355	# now do ahead and compress the pages
356	do_compress_so compress_page "$@"
357}
358
359#
360# dispatch options
361#
362if [ $# -lt 2 ] ; then ctl_usage $0 ; fi ;
363
364case "$1" in
365	-compress)	shift ; do_compress "$@" ;;
366	-uncompress)	shift ; do_uncompress "$@" ;;
367	*)		ctl_usage $0 ;;
368esac
369