diff --git a/gnu/usr.bin/man/catman/Makefile b/gnu/usr.bin/man/catman/Makefile index a66ae9e3fd0e..3b919e19c9dc 100644 --- a/gnu/usr.bin/man/catman/Makefile +++ b/gnu/usr.bin/man/catman/Makefile @@ -1,26 +1,7 @@ -FILES= catman -NOMAN= noman +MAN1= catman.1 -CLEANFILES+= ${FILES} - -all: ${FILES} - -# XXX null suffixes are currently broken -# .SUFFIXES: -# .SUFFIXES: .sh -# .sh: -# sed -e 's,%compress%,${compress},' \ -# -e 's,%compext%,${compext},' \ -# -e 's,%zcat%,${zcat},' \ -# ${.IMPSRC} > ${.TARGET} -catman: catman.sh - sed -e 's,%compress%,${compress},' \ - -e 's,%compext%,${compext},' \ - -e 's,%zcat%,${zcat},' \ - ${.CURDIR}/${.TARGET}.sh > ${.TARGET} - -install: - install -c -o ${BINOWN} -g ${BINGRP} -m ${BINMODE} \ - ${FILES} ${DESTDIR}${BINDIR} +beforeinstall: + ${INSTALL} -c -o ${BINOWN} -g ${BINGRP} -m ${BINMODE} \ + ${.CURDIR}/catman.perl ${DESTDIR}${BINDIR}/catman .include diff --git a/gnu/usr.bin/man/catman/catman.1 b/gnu/usr.bin/man/catman/catman.1 new file mode 100644 index 000000000000..ac1cc45c32d6 --- /dev/null +++ b/gnu/usr.bin/man/catman/catman.1 @@ -0,0 +1,146 @@ +.\" +.\" (c) Copyright 1995 Wolfram Schneider. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed by Wolfram Schneider +.\" 4. The name of the author may not be used to endorse or promote products +.\" derived from this software without specific prior written permission +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.\" /usr/bin/catman - preformat man pages +.\" +.\" E-mail: Wolfram Schneider +.\" +.\" $Id: catman.1,v 1.5 1995/03/14 18:09:55 w Exp w $ +.\" + +.Dd Mar 12, 1995 +.Dt CATMAN 1 +.Os +.Sh NAME +.Nm catman +.Nd preformat man pages + +.Sh SYNOPSIS +.Nm catman +.Op Fl h | Fl help +.Op Fl f | Fl force +.Op Fl p | Fl print +.Op Fl v | Fl verbose +.Op Fl directories... + +.Sh DESCRIPTION +.Nm Catman +format man pages to ASCII/Latin-1. It's like typing +.Sq man program +for all man pages in +.Ar directories . +.Ar Directories +is a list of man directories or subdirectories separated +by spaces or colons. +Use +.Ar /usr/share/man +if no +.Ar directories +defined. + +.Sh OPTIONS +.Bl -tag -width Ds + +.It Fl h , Fl help +Print options and exit. + +.It Fl v , Fl verbose +More warnings. + +.It Fl f , Fl force +Force overwriting old cat pages. Normally only those pages will be formatted +which are not up to date. This option is a waste of time, CPU and RAM. + +.It Fl p , Fl print +Don't actually format man pages. Show what would be done. + +.Sh EXAMPLES +.Pp +.Dl $ catman +.Pp +Format man pages in +.Ar /usr/share/man +if neccessary. + +.Pp +.Dl $ catman $MANPATH +.Pp +Format all your man pages if neccessary. + +.Pp +.Dl $ catman -o /usr/local/man/man1 /usr/local/man/manl +.Pp +Force reformatting of all man pages in +.Pa /usr/local/man/man1 +and +.Pa /usr/local/man/manl . + +.Pp +.Dl $ catman -p /usr/X11/man +.Pp +Show only. + +.Sh FILES +.Bl -tag -width /etc/master.passwdxx -compact +.Pa /etc/weekly : +start this program +.Po +or +.Pa /etc/daily +.Pc +.El + +.Sh FEATURES +Very fast if all man pages already formatted. + +.Sh BUGS +.Xr man 1 +is a setuid program. Be careful that user +.Sq man +has write permissions to the catman directories. + +.Nm Catman +does not check for any +.Sq .so +in man page sources. Use hard or symlinks +to avoid redundant formatted man pages. + +.Sh SEE ALSO +.Xr man 1 , +.Xr manpath 1 , +.Xr makewhatis 1 . + +.Sh HISTORY +This version of +.Nm catman +command appeared in FreeBSD 2.1 + +.Sh AUTHOR +Wolfram Schneider +.Aq wosch@cs.tu-berlin.de , +Germany. diff --git a/gnu/usr.bin/man/catman/catman.perl b/gnu/usr.bin/man/catman/catman.perl new file mode 100644 index 000000000000..05decb48ae23 --- /dev/null +++ b/gnu/usr.bin/man/catman/catman.perl @@ -0,0 +1,337 @@ +#!/usr/bin/perl +# +# Copyright (c) March 1995 Wolfram Schneider. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. All advertising materials mentioning features or use of this software +# must display the following acknowledgement: +# This product includes software developed by Wolfram Schneider +# 4. The name of the author may not be used to endorse or promote products +# derived from this software without specific prior written permission +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# /usr/bin/catman - preformat man pages +# +# /etc/weekly: catman `manpath -q` +# +# Bugs: sure +# Email: Wolfram Schneider +# +# $Id: catman.perl,v 1.9 1995/03/15 01:27:11 w Exp $ +# + +sub usage { + +warn <= 0; + return @defaultmanpath if $#defaultmanpath >= 0; + + warn "Missing directories\n"; &usage; +} + +# stript unused '/' +# e.g.: //usr///home// -> /usr/home +sub stripdir { + local($dir) = @_; + + $dir =~ s|/+|/|g; # delete double '/' + $dir =~ s|/$||; # delete '/' at end + return $dir if $dir ne ""; + return '/'; +} + +# read man directory +sub parse_dir { + local($dir) = @_; + local($subdir, $catdir); + local($pwd); + + # not absolute path + if ($dir !~ /^\//) { + chop($cwd = `pwd`); + $dir = "$cwd/$dir"; + } + + if ($dir =~ /man$/) { + warn "open manpath directory ``$dir''\n" if $verbose; + if (!opendir(DIR, $dir)) { + warn "opendir ``$dir'':$!\n"; $exit = 1; return 0; + } + foreach $subdir (sort(readdir(DIR))) { + if ($subdir =~ /^man\w+$/) { + $subdir = "$dir/$subdir"; + &catdir_create($subdir) && &parse_subdir($subdir); + } + } + closedir DIR + + } elsif ($dir =~ /man\w+$/) { + &catdir_create($dir) && &parse_subdir($dir); + } else { + warn "Assume ``$dir'' is not a man directory.\n"; + $exit = 1; + } +} + +# create cat subdirectory if neccessary +# e.g.: man9 exist, but cat9 not +sub catdir_create { + local($subdir) = @_; + local($catdir) = $subdir; + + $catdir = &man2cat($subdir); + if (-d $catdir) { + return 1 if -w _; + if (!chmod(755, $catdir)) { + warn "Cannot write $catdir, chmod: $!\n"; + $exit = 1; + return 0; + } + } + + warn "mkdir ``$catdir''\n" if $verbose || $print; + unless ($print) { + unlink($catdir); # be paranoid + if (!mkdir($catdir, 0755)) { + warn "Cannot make $catdir: $!\n"; + $exit = 1; + return 0; + } + } + return 1; +} + +# I: /usr/share/man/man9 +# O: usr/share/man/cat9 +sub man2cat { + local($man) = @_; + + $man =~ s/man(\w+)/cat$1/; + return $man; +} + +sub parse_subdir { + local($subdir) = @_; + local($file, $f, $catdir, $catdir_short); + local($mtime_man, $mtime_cat); + local($read); + + if (!opendir(D, $subdir)) { + warn "opendir ``$subdir'': $!\n"; return 0; + } + + $catdir = &man2cat($subdir); + + # optimize NAMI lookup, use short filenames + warn "chdir to: $subdir\n" if $verbose; + chdir($subdir); + + $catdir_short = $catdir; + $catdir_short =~ s|.*/(.*)|../$1|; + + warn "open man directory: ``$subdir''\n" if $verbose; + + foreach $file (readdir(D)) { + next if $file =~ /^(\.|\.\.)$/; # skip current and parent directory + + $read{$file} = 1; + + # replace readable_file with stat && ... + # faster, hackers choise :-) + if (!(($mtime_man = ((stat("$file"))[9])) && -r _ && -f _)) { + if (! -d _) { + warn "Cannot read file: ``$subdir/$file''\n"; + $exit = 1; + next; + } + warn "Ignore subsubdirectory: ``$subdir/$file''\n" + if $verbose; + next; + } + + # fo_09-o.bar0 + if ($file !~ /^[\w\-\[\.]+\.\w+$/) { + warn "Assume garbage: ``$subdir/$file''\n"; + next; + } + + # Assume catpages always compressed + # if ($mtime_cat = &readable_file("$catdir_short/$file")) { + if (($mtime_cat = ((stat("$catdir_short/$file"))[9])) + && -r _ && -f _) { + if ($mtime_man > $mtime_cat || $force) { + &nroff("$subdir/$file", "$catdir/$file"); + } else { + warn "up to date: $subdir/$file\n" if $verbose; + } + } elsif (($mtime_cat = ((stat("$catdir_short/$file$ext"))[9])) + && -r _ && -f _) { + if ($mtime_man > $mtime_cat || $force) { + &nroff("$subdir/$file", "$catdir/$file"); + } else { + warn "up to date: $subdir/$file\n" if $verbose; + } + } else { + # be paranoid + unlink("$catdir/$file"); + + &nroff("$subdir/$file", "$catdir/$file"); + } + } + closedir D; + + + if (!opendir(D, $catdir)) { + warn "opendir ``$catdir'': $!\n"; return 0; + } + + warn "open cat directory: ``$catdir''\n" if $verbose; + foreach $file (readdir(D)) { + next if $file =~ /^(\.|\.\.)$/; # skip current and parent directory + + if ($file !~ /^[\w\-\[\.]+\.\w+$/) { + warn "Assume garbage: ``$catdir/$file''\n" + unless -d "$catdir/$file"; + } + + unless ($read{$file}) { + # maybe a bug in man(1) + # if both manpage and catpage are uncompressed, man reformats + # the manpage and puts a compressed catpage to the + # already existing uncompressed catpage + $f = $file; $f =~ s/$ext$//; + # man page is uncompressed + next if $read{$f}; + + warn "Catpage without manpage: $catdir/$file\n"; + } + } + closedir D; +} + +sub nroff { + local($man,$cat) = @_; + local($nroff) = "groff -Tlatin1 -man | col"; + local($dev, $ino) = (stat($man))[01]; + + # It's a link + if ($link{"$dev.$ino"}) { + warn "Link: $link{\"$dev.$ino\"} -> $cat\n" if $verbose || $print; + + if (!$print && !link($link{"$dev.$ino"}, $cat)) { + warn "Link $cat: $!\n"; + $exit = 1; + } + } else { + $cat = "$cat$ext" if $cat !~ /$ext$/; + warn "Format: $man -> $cat\n" if $verbose || $print; + + unless($print) { + # man page is compressed + if ($man =~ /$ext$/) { + $nroff = "zcat $man | tbl | $nroff"; + } else { + $nroff = "tbl $man | $nroff"; + } + + # start formatting + $tmp = "$cat.$tmp"; # for cleanup after signals + system("$nroff | gzip > $cat.tmp"); + if ($?) { + # assume a fatal signal to nroff + &Exit("INT to system() funktion") if ($? == 2); + } else { + rename("$cat.tmp", $cat); + } + } + } + + # dev/ino from manpage, path from catpage + $link{"$dev.$ino"} = $cat; +} + +############# +# main +warn "Don't start this program as root, use:\n" . + "echo $0 @ARGV | nice -5 su -m man\n" unless $>; + +&variables; +foreach $dir (&parse(split(/[ :]/, join($", @ARGV)))) { #" + if (-e $dir && -d _ && -r _ && -x _) { + warn "``$dir'' is not writable for you,\n" . + "can only write to existing cat subdirs (if any)\n" + if ! -w _ && $verbose; + &parse_dir(&stripdir($dir)); + } else { + warn "``$dir'' is not a directory or not read-/searchable for you\n"; + $exit = 1; + } +} +exit($exit);