home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-02-12 | 48.1 KB | 1,830 lines |
- #!/usr/local/bin/perl
- #
- # auto-generated by /mnt/tchrist/src/scripts/plum/tools/pb on Fri Feb 14 11:57:47 CST 1992
- #
- #!/usr/bin/perl
- #
- # man - perl rewrite of man system
- # tom christiansen <tchrist@convex.com>
- #
- # Copyright 1990 Convex Computer Corporation.
- # All rights reserved.
- #
- # --------------------------------------------------------------------------
- # begin configuration section
- #
- # this should be adequate for CONVEX systems. if you copy this script
- # to non-CONVEX systems, or have a particularly outre local setup, you may
- # wish to alter some of the defaults.
- # --------------------------------------------------------------------------
- $PAGER = $ENV{'MANPAGER'} || $ENV{'PAGER'} || 'more';
- $ADDR_CACHE = 'man.funcaddresses';
-
- # assume "less" pagers want -sf flags, all others must accept -s.
- # note: some less's prefer -r to -f. you might also add -i if supported.
- #
- $is_less = $PAGER =~ /^\S*less(\s+-\S.*)?$/;
- $PAGER .= $is_less ? ' -si' : ' -s'; # add -f if using "ul"
-
- # man roots to look in; you would really rather use a separate tree than
- # manl and mann! see %SECTIONS and $MANALT if you do.
- $MANPATH = &config_path;
-
- # default section precedence
- $MANSECT = $ENV{'MANSECT'} || 'ln16823457po';
-
- # colons optional unless you have multi-char section names
- # note that HP systems want this:
- # $MANSECT = $ENV{'MANSECT'} || '1:1m:6:8:2:3:4:5:7';
-
- # alternate architecture man pages in
- # ${MANALT}/${machine}/man(.+)/*.\11*
- $MANALT = $ENV{'MANALT'} || '/usr/local/man';
-
- # default program for -t command
- $TROFF = $ENV{'TROFF'} || 'nitroff';
-
- $NROFF = 'nroff';
- $NROFF_CAN_BOLD = 0; # if nroff puts out bold as H\bH
-
- # this are used if filters are needed
- $TBL = 'tbl';
- $NTBL = "$TBL -D"; # maybe you need -TX instead
- $NEQN = 'neqn';
- $EQN = 'eqn';
- $SED = 'sed';
-
- # define this if you don't have/want UL;
- # without ul, you probably need COL defined unless your PAGER is very smart
- # you also must use col instead of ul if you've any tbl'd man pages, such
- # as from the X man pages or the eqnchar.7 page.
- $COL = 'col';
- $UL = ''; # set to '' if you haven't got ul
- die 'need either $UL or $COL' unless $UL || $COL;
-
- # need these for .Z files or dirs
- $COMPRESS = 'compress';
- $ZCAT = 'zcat';
- $CAT = 'cat';
-
- # define COMPRESS_DIR if pages might have moved to manX.Z/page.X (like HPs)
- $COMPRESS_DIR = 1;
- # define COMPRESS_PAGE if pages might have moved to manX/page.X.Z (better)
- $COMPRESS_PAGE = 1;
-
- # Command to format man pages to be viewed on a tty or printed on a line printer
- $CATSET = "$NROFF -h -man -";
-
- $CATSET .= " | $COL" if $COL;
-
- # Command to typeset a man page
- $TYPESET = "$TROFF -man";
-
-
- # flags: GNU likes -i, BSD doesn't; both like -h, but BSD doesn't document it
- # if you don't put -i here, i'll make up for it later the hard way
- #$EGREP = '/usr/local/bin/egrep';
- #if (-x $EGREP) {
- #$EGREP .= ' -i -h';
- #} else {
- $EGREP = '/usr/bin/egrep';
- unless (-x $EGREP) {
- $EGREP = '';
- } else {
- $EGREP .= ' -h';
- }
- #}
-
- # sections that have verbose aliases
- # if you change this, change the usage message
- #
- # if you put any of these in their own trees, comment them out and make
- # a link in $MANALT so people can still say 'man local foo'; for local,
- # cd $MANALT; ln -s . local
- # for the other trees (new, old, public) put either them or links
- # to them in $MANALT
- #
- %SECTIONS = (
- 'local', 'l',
- 'new', 'n',
- 'old', 'o',
- 'public', 'p' );
-
- # turn this on if you want linked (via ".so" or otherwise) man pages
- # to be found even if the thing they are linked to doesn't know it's
- # being linked to -- that is, its NAME section doesn't have reference
- # to it. eg, if you call a man page 'gnugrep' but it's own NAME section
- # just calls it grep, then you need this. usually a good idea.
- #
- $STUPID_SO = 1;
-
- # --------------------------------------------------------------------------
- # end configuration section
- # --------------------------------------------------------------------------
-
- # CONVEX RCS keeps CHeader; others may prefer Header
- ($bogus, $version) = split(/:\s*/,'$CHeader: man 0.41 91/10/28 13:48:01 $',2);
- chop($version); chop($version);
-
- require 'getopts.pl';
-
- $winsize = "\0" x 8;
- $TIOCGWINSZ = 0x40087468;
-
- $isatty = -t STDOUT;
- if (ioctl(STDIN, $TIOCGWINSZ, $winsize)) {
- ($rows, $cols, $xpixel, $ypixel) = unpack('S4', $winsize);
- } else {
- ($rows, $cols) = (24, 80);
- }
-
- %options = (
- 'man', 'T:m:P:M:S:fkltvwdguhaAiDKn',
- 'apropos', 'm:P:MvduaK',
- 'whatis', 'm:P:M:vduh',
- 'whereis', 'm:P:M:vduh'
- );
-
- ($program = $0) =~ s,.*/,,;
-
- $apropos = $program eq 'apropos';
- $whatis = $program eq 'whatis';
- $whereis = $program eq 'whman';
- $program = 'man' unless $options{$program};
-
- &Getopts($options = $options{$program}) || &usage;
-
- if ($opt_u) {
- &version if $opt_v;
- &usage;
- # not reached
- }
-
- if ($opt_v) {
- &version;
- exit 0;
- }
-
- &usage if $#ARGV < 0;
-
- $MANPATH = $opt_P if $opt_P; # backwards contemptibility
- $MANPATH = $opt_M if $opt_M;
-
- $hard_way = $opt_h if $opt_h;
-
- if ($opt_T) {
- $opt_t = 1;
- $TYPESET =~ s/$TROFF/$opt_T/;
- $TROFF = $opt_T;
- }
-
- $MANPATH = "$MANALT/$opt_m" # want different machine type (undoc)
- if $machine = $opt_m;
-
- $MANSECT = $opt_S if $opt_S; # prefer our own section ordering
-
- $whatis = 1 if $opt_f;
- $apropos = 1 if $opt_k || $opt_K;
- $fromfile = 1 if $opt_l;
- $whereis = 1 if $opt_w;
- $grepman = 1 if $opt_g;
- $| = $debug = 1 if $opt_d;
- $full_index = 1 if $opt_i;
- $show_all = 1 if $opt_a;
- $stripBS = 1 if $opt_D;
- $query_all = $opt_A if $opt_A;
-
- $roff = $opt_t ? 'troff' : 'nroff'; # for indirect function call
-
-
- # maybe they said something like 'man vax ls'
- if ($#ARGV > 0) {
- local($machdir) = $MANALT . '/' . $ARGV[0];
- if (-d $machdir) {
- $MANPATH = $machdir;
- $machine = shift;
- }
- }
-
- @MANPATH = split(/:/,$MANPATH);
-
- # assign priorities to the sections he cares about
- # the nearer the front the higher the sorting priority
- $secidx = 0;
- $delim = ($MANSECT =~ /:/) ? ':' : ' *';
- for (reverse split(/$delim/, $MANSECT)) {
- if ($_ eq '') {
- warn "null section in $MANSECT\n";
- next;
- }
- $MANSECT{$_} = ++$secidx;
- }
-
- if ($whatis) {
- &whatis;
- } elsif ($apropos) {
- &apropos;
- } elsif ($whereis) {
- &whereis;
- } elsif ($grepman) {
- &grepman;
- } else {
- &man;
- }
-
- exit $status;
-
- # --------------------------------------------------------------------------
- # fill out @whatis array with all possible names of whatis files
- # --------------------------------------------------------------------------
-
- 1;
-
-
- # BEGIN REQUIRED MODULES
-
-
- # MODULE postcompile.pl v1.3
-
- sub postcompile {
- # local($fun) = &whowasi; # don't do that; sigh
-
- &fetch_function_addrs unless $fetched_function_addrs'already++;
-
- local($__fun__) = $__whowasi__ || &panic("dunno who i was!");
- local($__addr__);
-
- die("No address for $__fun__")
- unless $__addr__ = $Func_Addrs{$__fun__};
-
- die("$__fun__ should already be loaded")
- if $__addr__ < $Data_Start;
-
- die("can't load $__fun__ from $__fun__ on <DATA>: $!")
- unless seek(DATA,$__fun__,0);
-
- print STDERR " " x $pindent . "loading $__fun__ from $__addr__\n";
-
- seek(DATA,$__addr__,0);
-
- local($__code__,$_);
-
- {
- # local($_); # WOW: this doesn't help; change to __line__ for more fun.
- while ($_ = <DATA>) {
- $__code__ .= $_;
- last if $_ =~ /^\}/;
- }
- }
-
- die "No /^sub\\s$__fun__/in code at $__addr__:\n$__code__\n"
- unless $__code__ =~ /^sub\s+$__fun__/;
-
- local($tmp) = substr($_stub{$__fun__}, 7*4, 4);
- substr($_stub{$__fun__}, 7*4, 4) = substr($_main{$__fun__}, 7*4, 4);
- substr($_main{$__fun__}, 7*4, 4) = $tmp;
-
- eval $__code__;
-
- $@ && die(sprintf(
- "code for %s (addr %07o) didn't eval: %s\n CODE:\n%s",
- $__fun__, $Func_Addrs{$__fun__}, $@, $__code__
- )
- );
- print STDERR " " x ++$pindent ."calling new $__fun__()\n";
-
- if (wantarray) {
- local(@val) = &$__fun__;
- print STDERR " " x --$pindent. "returning from \@$__fun__()\n";
- return @val;
- } else {
- local($val) = &$__fun__;
- print STDERR " " x --$pindent. "returning from \$$__fun__()\n";
- return $val;
- }
- }
-
- sub fetch_function_addrs {
- local($count);
- local($_);
- local($hischecksum, $mychecksum);
- local($update);
-
- $Data_Start = tell(DATA);
-
- print STDERR "gathering functions: "
- if defined $ENV{'debug_plum'};
-
- seek(DATA,0,0);
- { local($/); $mychecksum = unpack("%16C*", <DATA>); }
-
- if ((stat(DATA))[9] > (stat($ADDR_CACHE))[9]) {
- print STDERR "addrcache out of date " if defined $ENV{'debug_plum'};
- $update++;
- } elsif (!open(ADDRS, $ADDR_CACHE)) {
- print STDERR "can't open addrcache $ADDR_CACHE: $! "
- if defined $ENV{'debug_plum'};
- $update++;
- } else {
- ($hischecksum) = <ADDRS> =~ /^CHECKSUM (\d+)/;
- if ($mychecksum != $hischecksum) {
- print STDERR "checksum mismatch " if defined $ENV{'debug_plum'};
- $update++;
- }
- }
-
- unless ($update) {
- print STDERR "yippee, snagged addrcache " if defined $ENV{'debug_plum'};
- split, $Func_Addrs{$_[0]} = $_[1] while <ADDRS>;
- $count = $. - 1;
- close ADDRS;
- } else {
- seek(DATA,0,0);
-
- for (local($told); <DATA>; $told = tell) {
- next unless /^\s*sub\s+((\w+')?(\w+))/;
- warn "duplicate func $1 @ $told" if defined $Func_Addrs{$1};
- $Func_Addrs{$1} = $told;
- $count++;
- }
-
- unless (open(ADDRS, ">$ADDR_CACHE")) {
- print STDERR "couldn't update addrcache: $! "
- if defined $ENV{'debug_plum'};
- } else {
- print STDERR "updating addrcache " if defined $ENV{'debug_plum'};
- local($x,$y);
- print ADDRS 'CHECKSUM ', $mychecksum, "\n";
- print ADDRS $x, ' ', $y, "\n" while ($x, $y) = each %Func_Addrs;
- close ADDRS;
- }
- }
-
- print STDERR "found $count functions\n" if defined $ENV{'debug_plum'};
-
- seek(DATA,$Data_Start,0);
- }
- # this guy makes me coredump if used to autoload
-
- sub whowasi {
- (caller(2))[3];
- }
-
-
- # FUNCTION STUBS FOR POSTLOADING FROM DATA SEGMENT
-
- ;sub PLUMBER { $__whowasi__ = "PLUMBER"; &postcompile; }
- ;sub append_sub_topic { $__whowasi__ = "append_sub_topic"; &postcompile; }
- ;sub apropos { $__whowasi__ = "apropos"; &postcompile; }
- ;sub bysection { $__whowasi__ = "bysection"; &postcompile; }
- ;sub config_path { $__whowasi__ = "config_path"; &postcompile; }
- ;sub fast_whatis { $__whowasi__ = "fast_whatis"; &postcompile; }
- ;sub fetch { $__whowasi__ = "fetch"; &postcompile; }
- ;sub find_files { $__whowasi__ = "find_files"; &postcompile; }
- ;sub find_index { $__whowasi__ = "find_index"; &postcompile; }
- ;sub genwhatis { $__whowasi__ = "genwhatis"; &postcompile; }
- ;sub get_page { $__whowasi__ = "get_page"; &postcompile; }
- ;sub get_section { $__whowasi__ = "get_section"; &postcompile; }
- ;sub getidx { $__whowasi__ = "getidx"; &postcompile; }
- ;sub grepman { $__whowasi__ = "grepman"; &postcompile; }
- ;sub insert_filters { $__whowasi__ = "insert_filters"; &postcompile; }
- ;sub load_index { $__whowasi__ = "load_index"; &postcompile; }
- ;sub man { $__whowasi__ = "man"; &postcompile; }
- ;sub no_entry { $__whowasi__ = "no_entry"; &postcompile; }
- ;sub nroff { $__whowasi__ = "nroff"; &postcompile; }
- ;sub pick_index { $__whowasi__ = "pick_index"; &postcompile; }
- ;sub print { $__whowasi__ = "print"; &postcompile; }
- ;sub prompt_RTN { $__whowasi__ = "prompt_RTN"; &postcompile; }
- ;sub quick_fetch { $__whowasi__ = "quick_fetch"; &postcompile; }
- ;sub reformat { $__whowasi__ = "reformat"; &postcompile; }
- ;sub run { $__whowasi__ = "run"; &postcompile; }
- ;sub run_topic { $__whowasi__ = "run_topic"; &postcompile; }
- ;sub show_index { $__whowasi__ = "show_index"; &postcompile; }
- ;sub slow_fetch { $__whowasi__ = "slow_fetch"; &postcompile; }
- ;sub slow_whatis { $__whowasi__ = "slow_whatis"; &postcompile; }
- ;sub tmp_cleanup { $__whowasi__ = "tmp_cleanup"; &postcompile; }
- ;sub trimdups { $__whowasi__ = "trimdups"; &postcompile; }
- ;sub troff { $__whowasi__ = "troff"; &postcompile; }
- ;sub unshell { $__whowasi__ = "unshell"; &postcompile; }
- ;sub usage { $__whowasi__ = "usage"; &postcompile; }
- ;sub verify { $__whowasi__ = "verify"; &postcompile; }
- ;sub version { $__whowasi__ = "version"; &postcompile; }
- ;sub whatis { $__whowasi__ = "whatis"; &postcompile; }
- ;sub whereis { $__whowasi__ = "whereis"; &postcompile; }
-
-
- # POSTLOADED MODULE INITIALIZATION CODE
-
- __END__
-
- # BEYOND THIS POINT LIE FUNCTIONS WE MAY NEVER COMPILE
- #--------------------------------------------------------------------------
- # in case we die writing to the pipe
- # --------------------------------------------------------------------------
-
- # MODULE PLUMBER.pl
-
- sub PLUMBER {
- warn "unlink $tmppage\n" if $debug;
- unlink $tmppage;
- die "Broken pipe while reformating $manpage\n" ;
- }
- # --------------------------------------------------------------------------
- # modify $command to prime the pager with the subsection they want
- # --------------------------------------------------------------------------
-
- # MODULE append_sub_topic.pl
-
- sub append_sub_topic {
- if (defined $idx_topic) {{
- local($key);
- last if $idx_topic eq '0';
- unless ($idx_topic) {
- $idx_topic = &pick_index;
- last if $idx_topic eq "\004" || $idx_topic eq '0';
- }
- if ($idx_topic =~ m!^/!) {
- $command .= " '+$idx_topic'";
- last;
- }
- unless ($key = &find_index($manpage, $idx_topic)) {
- warn "No subsection $idx_topic for $manpage\n\n";
- $idx_topic = '';
- redo;
- }
- $key =~ s/([!-~])/$1.$1/g unless $is_less;
- $command .= " '+/^[ \t]*$key'";
- }}
- }
- # --------------------------------------------------------------------------
- # run apropos (man -k)
- # --------------------------------------------------------------------------
-
- # MODULE apropos.pl
-
- sub apropos {
- local($_, %seeking, $target, $query);
- &genwhatis;
-
- for (@ARGV) { s/(\W)/\\$1/g unless $opt_K; }
-
- if ($EGREP) {
-
- # fold case on apropos args
- for (@ARGV) {
- y/A-Z/a-z/;
- $seeking{$_} = 1;
- }
- $query = join('|',@ARGV);
-
- # need to fake a -i flag?
- unless ($EGREP =~ /-\w*i/) {
- local($C);
- local(@pat) = split(//,$query);
- for (@pat) {
- ($C = $_) =~ y/a-z/A-Z/ && ($_ = '[' . $C . $_ . ']');
- }
- $query = join('',@pat);
- }
- if (&run("$EGREP '$query' @whatis | $PAGER")) {
- %seeking = ();
- }
- } else { # use perl
- local($code) = <<'EOF';
- if ($isatty) {
- $pid = open(PAGER, "| $PAGER");
- sleep 1;
- select(PAGER);
- }
- foreach $WHATIS (@whatis) {
- unless (open WHATIS) {
- warn "can't open $WHATIS: $!\n";
- next;
- }
- WHATIS: while (<WHATIS>) {
- EOF
- for (@ARGV) {
- if ($opt_K && split(/\|/) > 1) { # speed hack
- $code .= "OPLOOP: {\n";
- for (@_) { $code .= "\tlast OPLOOP if /$_/i;\n"; }
- $code .= "next WHATIS; }\n";
- } else {
- $code .= " next WHATIS unless /$_/i;\n";
- }
- }
- $code .= <<'EOF';
- print;
- }
- close WHATIS;
- }
- EOF
- print "$code\n" if $debug;
- eval $code;
- if ($@ =~ /(.*)at \(eval\) line (\d+)/) {
- ($message, $line) = ($1, $2);
- if ((split(/\n/,$code))[$line-1] =~ /next unless/) {
- warn "EVAL ERROR: $@ $code" if $debug;
- die "$0: $message\n";
- } else {
- die $@;
- }
- } elsif ($@) {
- die $@;
- }
- }
- close PAGER if $isatty;
- }
- # --------------------------------------------------------------------------
- # order by section. if the complete extension has a section
- # priority, use that. otherwise use the first char of extension
- # only. undefined priorities are lower than any defined one.
- # --------------------------------------------------------------------------
-
- # MODULE bysection.pl
-
- sub bysection {
- local ($e1, $e2, $p1, $p2, $s1, $s2);
-
- ($s1, $e1) = $a =~ m:.*/man([^/]+)/.*\.([^.]+)(\.Z)?$:;
- ($s2, $e2) = $b =~ m:.*/man([^/]+)/.*\.([^.]+)(\.Z)?$:;
-
- $e1 = $s1 if $e1 !~ /^${s1}.*/;
- $e2 = $s2 if $e2 !~ /^${s2}.*/;
-
- $p1 = $MANSECT{$e1} || $MANSECT{substr($e1,0,1)};
-
- $p2 = $MANSECT{$e2} || $MANSECT{substr($e2,0,1)};
-
- $p1 == $p2 ? $a cmp $b : $p2 <=> $p1;
- }
- # --------------------------------------------------------------------------
- # dynamically determine MANPATH (if unset) according to PATH
- # --------------------------------------------------------------------------
-
- # MODULE config_path.pl
-
- sub config_path {
- local($_); # for traversing $PATH
- local(%seen); # weed out duplicates
- local(*manpath); # eventual return values
-
- if (defined $ENV{'MANPATH'}) {
- $manpath = $ENV{'MANPATH'};
- } else {
- for (split(/:/, $ENV{'PATH'})) {
- next if $_ eq '.';
- next if $_ eq '..';
- s![^/+]*$!man! && -d && !$seen{$_}++ && push(@manpath,$_);
- }
- $manpath = join(':', @manpath);
- }
- # $manpath; # last expr is assign to this anyway
- }
- # --------------------------------------------------------------------------
- # do whatis lookup against dbm file(s)
- # --------------------------------------------------------------------------
-
- # MODULE fast_whatis.pl
-
- sub fast_whatis {
- local($entry, $cmd, $page, $section, $desc, @entries);
-
- for $INDEX (@whatis) {
- unless (-f "$INDEX.pag" && dbmopen(INDEX,$INDEX,0444)) {
- warn "$program: No dbm file for $INDEX: $!\n" if $debug;
- #$status = 1;
- if (-f $INDEX) {
- local(@whatis) = ($INDEX); # dynamic scoping obfuscation
- &slow_whatis;
- }
- next;
- }
- for $target (@ARGV) {
- local($ext);
- @entries = &quick_fetch($target,'INDEX');
- next if $#entries < 0;
- # $target =~ s/([^\w])/\\$1/g;
- for $entry (@entries) {
- ($cmd, $page, $section, $desc) = split(/\001/, $entry);
- # STUPID_SO is one that .so's that reference things that
- # don't know they are being referenced. STUPID_SO may cause
- # some peculiarities.
- unless ($STUPID_SO) {
- next unless $cmd =~ /$target/i || $cmd =~ /\.{3}/;
- }
-
- delete $seeking{$target};
- ($ext) = $page =~ /\.([^.]*)$/;
- printf("%-20s - %s\n", "$cmd ($ext)", $desc);
- }
- }
- dbmclose(INDEX);
- }
- }
- # --------------------------------------------------------------------------
- # lookup a given key in the given man root; returns list of hits
- # --------------------------------------------------------------------------
-
- # MODULE fetch.pl
-
- sub fetch {
- local($key,$root) = @_;
- local(%recursed);
-
- return $dbmopened{$root}
- ? &quick_fetch($key,$dbm{$root})
- : &slow_fetch($key,$root);
- }
- # --------------------------------------------------------------------------
- # what are the file names matching this target?
- # --------------------------------------------------------------------------
-
- # MODULE find_files.pl
-
- sub find_files {
- local($target) = @_;
- local($root, $entry);
- local(@retlist) = ();
- local(@tmplist) = ();
- local(@entries) = ();
- local($tar_regx);
- local($found) = 0;
- # globals: $vars, $called_before, %dbm, $hard_way (kinda)
-
- $vars = 'dbm00'; # var for magic autoincrementation
-
- ($tar_regx = $target) =~ s/(\W)/\\$1/g; # quote meta
-
- if (!$hard_way && !$called_before++) {
- # generate dbm names
- for $root (@MANPATH) {
- $dbm{$root} = $vars++; # magic incr
- $string = "dbmopen($dbm{$root},\"$root/whatis\",0444);";
- unless (-f "$root/whatis.pag" && eval $string) {
- if ($@) {
- chop $@;
- warn "Can't eval $string: $@";
- } else {
- warn "No dbm file for $root/whatis: $!\n"
- if $opt_M || $opt_P || $debug;
- }
- #$status = 1;
- next;
- }
- $dbmopened{$root} = 1;
- }
- }
-
- for $root (@MANPATH) {
- local($fullname);
- @tmplist = ();
- if ($hard_way || !$dbmopened{$root}) {
- next unless -d $root;
- warn "slow fetch on $target in $root\n" if $debug;
- @tmplist = &slow_fetch($target,$root);
- } else {
- @entries = &fetch($target,$root);
- next if $#entries < 0;
-
- for $entry (sort @entries) {
- ($cmd, $page, $section, $desc) = split(/\001/, $entry);
-
- # STUPID_SO is so that .so's that reference things that
- # don't know they are being referenced. STUPID_SO may
- # cause peculiarities.
- unless ($STUPID_SO) {
- next unless $cmd =~ /$tar_regx/i || $cmd =~ /\.{3}/;
- }
- push(@tmplist, "$root/man$section/$page");
- }
- }
- push(@retlist, sort bysection @tmplist);
- last if $#retlist >= 0 && $hard_way;
- }
- # unless (@retlist || $hard_way) {
- # # shameless (ab?)use of dynamic scoping
- # local($hard_way) = 1;
- # warn "recursing on find_files\n" if $debug;
- # return &find_files($target);
- # }
- return &trimdups(@retlist);
- }
- # --------------------------------------------------------------------------
- # find closest match on index selection in full index
- # --------------------------------------------------------------------------
-
- # MODULE find_index.pl
-
- sub find_index {
- local($manpage, $expr) = @_;
- local($_, @matches);
-
- &load_index($manpage);
-
- $expr =~ s!^/+!!;
-
- for (@ssindex) {
- s/^\s*\d+\s+//;
- s/\s+\d+\s*$//;
- }
-
- if ($expr > 0) {
- return $ssindex[$expr];
- } else {
- $ssindex[0] = '';
- if (@matches = grep (/^$expr/i, @ssindex)) {
- return $matches[0];
- } elsif (@matches = grep (/$expr/i, @ssindex)) {
- return $matches[0];
- } else {
- return '';
- }
- }
- }
-
- # MODULE genwhatis.pl
-
- sub genwhatis {
- local($elt,$whatis);
-
- for $elt (@MANPATH) {
- $whatis = "$elt/whatis";
- if (-f $whatis) {
- push(@whatis, $whatis);
- } else {
- warn "$whatis: $!\n";# if $opt_M || $opt_P; # they asked for it
- }
- }
-
- die "$program: No whatis databases found, please run makewhatis\n"
- if $#whatis < 0;
- }
- # --------------------------------------------------------------------------
- # pick the first page matching his target and search orders
- # --------------------------------------------------------------------------
-
- # MODULE get_page.pl
-
- sub get_page {
- local($target) = @_;
- local(@found, @want);
-
- warn "get_page: looking for $target";
-
- unless (@found = &find_files($target)) {
- &no_entry($target);
- return '';
- }
-
- if (!$want_section) {
- @want = @found;
- } else {{
- local($patsect); # in case it's section 3c++
- ($patsect = $want_section) =~ s/(\W)/\\$1/g;
-
- # try exact match first
- last if @want = grep (/\.$patsect$/, @found);
-
- # otherwise how about a subsection
- last if @want = grep (/\.$patsect[^.]*$/, @found);
-
- # maybe it's in the wrong place (mano is notorious for this)
- last if @want = grep (/man$patsect[^.]*\//, @found);
-
- &no_entry($target);
- return '';
- }}
-
- # WOW
- for (@want) { warn "get_page: verifying $_"; $_ = &verify($_) ; warn "get_page: verified $_"; }
- # THIS WORKS
- #for $xyzzy (@want) { warn "get_page: verifying $xyzzy"; $xyzzy = &verify($xyzzy) ; }
- $found = $want[0];
-
- if (@want > 1 && $query_all) {
- local($ans, $i);
-
- select(STDERR);
-
- print "There are ", 0+@want,
- " manual entries available for $target:\n";
- for ($i = 0; $i <= $#want; $i++) {
- printf "%3d\t%s\n", $i+1, $want[$i];
- }
- {
- print "Which section would you like? (select 0 for all) ";
- ($ans = <STDIN>) ? chop($ans) : ($ans = "\004");
-
- exit if $ans eq "\004";
- redo if $ans eq '';
-
- if ($ans eq '0') {
- # more dynamic scope abuse
- local(@ARGV) = ($target);
- local($show_all) = 1;
- &man;
- return '';
- }
- if (--$ans > $#want) {
- print "But we only have ",1+$#want, " man pages!\n";
- redo;
- }
-
- $found = $want[$ans];
- }
- }
-
-
- select(STDOUT);
-
- $found;
- }
- # --------------------------------------------------------------------------
- # find out if he wants a special section and save in $want_section
- # --------------------------------------------------------------------------
-
- # MODULE get_section.pl
-
- sub get_section {
- local($section) = $ARGV[0];
-
- # interpret stty(1) as 1 stty
- if ($section =~ /^(\S+)\((\S*)\),?\s*$/) {
- shift @ARGV;
- unshift(@ARGV, $section = $2, $1);
- }
-
- $section =~ tr/A-Z/a-z/;
-
-
- if (defined $SECTIONS{$section}) {
- $want_section = $SECTIONS{$section};
- shift @ARGV;
- } elsif (defined($MANSECT{$section}) || $section =~ /^\d\S*$/i) {
- $want_section = shift @ARGV;
- } else {
- return;
- }
-
- $want_section =~ tr/A-Z/a-z/;
-
- die "But what do you want from section $want_section?\n"
- if $want_section && $#ARGV < 0;
- }
- # --------------------------------------------------------------------------
- # create subsection index is out of date wrt source man page
- # --------------------------------------------------------------------------
-
- # MODULE getidx.pl
-
- sub getidx {
- local($manpage) = @_;
- local($is_mh);
- local($_, $i, %lines, %sec, $sname, @snames);
- local(@retlist, $maxlen, $header, @idx , @st_man, @st_idx);
- # global no_idx_file, idx_file
-
- ( $idx_file = $manpage ) =~ s:/man(\w+)(\.Z)?/:/idx$1/:;
- $idx_file =~ s/\.Z//;
-
- require 'stat.pl' unless defined &Stat;
-
- @st_man = &Stat($manpage);
- @st_idx = &Stat($idx_file);
-
- if ($st_man[$ST_MTIME] < $st_idx[$ST_MTIME]) {
- unless (open idx_file) {
- warn "$program: can't open $idx_file: $!\n";
- return ();
- }
- @retlist = <idx_file>;
- close idx_file;
- return @saveidx = @retlist;
- }
-
- if (!open(manpage, $manpage =~ /\.Z/ ? "$ZCAT < $manpage|" : $manpage)) {
- warn "$program: can't open $manpage: $!\n";
- return ();
- }
- warn "building section index\n" if $debug;
- ($header = "Subsections in $manpage") =~ s!/?\S*/!!;
- $maxlen = length($header);
- push(@snames, $sname = 'preamble');;
-
- # MH has these alias for sections and subsectdions
- if ($is_mh = $manpage =~ m:/mh/:) {
- %mh_sections = (
- "NA", "NAME",
- "SY", "SYNOPSIS",
- "DE", "DESCRIPTION",
- "Fi", "FILES",
- "Pr", "PROFILE",
- "Sa", "SEE ALSO",
- "De", "DEFAULTS",
- "Co", "CONTEXT",
- "Hh", "HELPFUL HINTS",
- "Hi", "HISTORY",
- "Bu", "BUGS"
- );
- $mh_expr = join('|',keys %mh_sections);
- }
-
- while (<manpage>) {
- if ($is_mh && /^\.($mh_expr)/) {
- $sname = $mh_sections{$+};
- $maxlen = length($sname) if $maxlen < length($sname);
- push(@snames,$sname);
- }
- if (/^\.s[sh]\s+(.*)/i ) {
- $line = $_;
- $_ = $1;
- s/"//g;
- s/\\f([PBIR]|\(..)//g; # kill font changes
- s/\\s[+-]?\d+//g; # kill point changes
- s/\\&//g; # and \&
- s/\\\((ru|ul)/_/g; # xlate to '_'
- s/\\\((mi|hy|em)/-/g; # xlate to '-'
- s/\\\*\(..//g; # no troff strings
- s/\\//g; # kill all remaining backslashes
- $sname = $_;
- $_ = $line;
- $maxlen = length($sname) if $maxlen < length($sname);
- push(@snames,$sname);
- }
- $lines{$sname}++;
- }
-
- $mask = sprintf("%%2d %%-%ds %%5d\n", $maxlen + 2);
-
- $no_idx_file = $idx_file eq $manpage || !open(idx, ">$idx_file");
-
- $line = sprintf(sprintf("Idx %%-%ds Lines\n", $maxlen + 2), $header);
- @retlist = ($line);
-
- for ($i = 1; $i <= $#snames; $i++) {
- push(@retlist, sprintf($mask, $i, $snames[$i], $lines{$snames[$i]}));
- }
- if (!$no_idx_file) {
- warn "storing section index in $idx_file\n" if $debug;
- print idx @retlist;
- close idx;
- }
- return @saveidx = @retlist;
- }
- # --------------------------------------------------------------------------
- # grep through MANPATH for a pattern
- # --------------------------------------------------------------------------
-
- # MODULE grepman.pl
-
- sub grepman {
- local($code, $_, $dir, $root, $FILE, $found);
-
- $code = "while (<FILE>) {\n";
-
- for (@ARGV) {
- s#/#\\/#g;
- $code .= <<EOCODE;
- if (/$_/) {
- print "\$path: \$_";
- \$found++;
- next;
- }
- EOCODE
- }
-
- $code .= "}\n";
-
- print "grep eval code: $code" if $debug;
-
-
- foreach $root ( split(/:/, $MANPATH)) {
- unless (chdir($root)) {
- warn "can't chdir to $root: $!";
- $status++;
- next;
- }
- foreach $dir ( <man?*> ) {
- unless (chdir($dir)) {
- warn "can't chdir to $root/$dir: $!" if $debug;
- next;
- }
- unless (opendir(DIR, '.')) {
- warn "can't opendir $root/$dir: $!" if $debug;
- next;
- }
- foreach $FILE ( readdir(DIR) ) {
- next if $FILE eq '.' || $FILE eq '..';
- $path = "$root/$dir/$FILE";
- if ($FILE !~ /\S\.\S/ || !-f $FILE) {
- print "skipping non-man file: $path\n" if $debug;
- next;
- }
- if ($FILE =~ /\.Z$/ || $dir =~ /\.Z$/) {
- $FILE = "$ZCAT $FILE|";
- }
- print STDERR "grepping $path\n" if $debug;
- unless (open FILE) {
- warn "can't open $root/$dir/$FILE: $!";
- $status++;
- next;
- }
- eval $code;
- die $@ if $@;
- }
- unless (chdir ($root)) {
- warn "can't return to $root: $!";
- $status++;
- last;
- }
- }
- }
- exit ($status || !$found);
- }
- # --------------------------------------------------------------------------
- # check if page needs tbl or eqn, modifying command if needed
- # add known problems for PR directory if applicable
- # --------------------------------------------------------------------------
-
- # MODULE insert_filters.pl
-
- sub insert_filters {
- local($filters,$eqn, $tbl, $_);
- local(*PAGE);
- local($c, $PAGE) = @_;
- local($page,$sect, $prs, $prdir);
-
- ( $page = $PAGE ) =~ s/\.Z//;
- ($prdir = $page) =~ s#/[^/]*$##;
- $prdir =~ s#man([^/]*)$#pr$1#;
- $page =~ s#.*/([^/]+)$#$1#;
-
- $PAGE = "$ZCAT < $PAGE|" if $PAGE =~ /\.Z/;
-
- (open PAGE) || die ("$program: can't open $PAGE to check filters: $!\n");
- warn "open $PAGE to check for filters in $_[0]\n" if $debug;
-
- while (<PAGE>) {
- if (/^\.EQ/) {
- $_ = <PAGE>;
- $eqn = 1 unless /\.(if|nr)/; # has eqn output not input
- }
- if (/^\.TS/) {
- $_ = <PAGE>;
- $tbl = 1 unless /\.(if|nr)/; # has tbl output not input
- }
- last if $eqn && $tbl;
- }
- close PAGE;
-
- if ($roff eq 'troff') {
- $eqn && $_[0] =~ s/(\S+roff)/$EQN | $1/;
- $tbl && $_[0] =~ s/(\S+roff)/$TBL | $1/;
- } else { # nroff
- $eqn && $_[0] =~ s/(\S+roff)/$NEQN | $1/;
- $tbl && $_[0] =~ s/(\S+roff)/$NTBL | $1/;
- }
-
- ($sect) = $page =~ /\.(\d)[^.]*$/;
- $prs = "$prdir/$page";
- if (-e $prs) {
- warn "found PRs for $page\n" if $debug;
- if ($roff eq 'nroff') {
- $_[0] =~ s/ - / - $prs/;
- } else {
- $_[0] .= " $prs";
- }
- } else {
- print "no PRS for $page in $prs\n" if $debug;
- }
- $_[0];
- }
- # --------------------------------------------------------------------------
- # read in subsection index into @ssindex
- # --------------------------------------------------------------------------
-
- # MODULE load_index.pl
-
- sub load_index {
- local($manpage) = @_;
- $no_idx_file = 0;
- &getidx($manpage) if $#saveidx < 0;
- @ssindex = @saveidx;
- die "should have have an index for $manpage" if $#saveidx < 0;
- }
- # --------------------------------------------------------------------------
- # run a normal man command
- # --------------------------------------------------------------------------
-
- # MODULE man.pl
-
- sub man {
- local($target,$page);
-
-
- while (@ARGV) {
- undef $idx_topic;
-
- &get_section;
- $target = shift @ARGV;
-
- if (!$fromfile && $target =~ m!^([^/]+)/(.*)!) {
- if (!$isatty) {
- warn "$program: no tty, so no pager to prime with index\n";
- $target = $1;
- } else {
- ($target, $idx_topic) = ($1, $2);
- }
- } else {
- undef $idx_topic;
- }
-
- if ($show_all) {
- local(@pages);
- local($was_defined) = defined $idx_topic;
- @pages = &find_files($target);
- if (!@pages) {
- &no_entry($target);
- next;
- }
- while ($tpage = shift @pages) {
- undef $idx_topic unless $was_defined;
- do $roff(&verify($tpage));
- &prompt_RTN("to read $pages[0]")
- if $roff eq 'nroff' && @pages;
- }
- } else {
- $target = &get_page($target) unless $fromfile;
- do $roff($target) if $target;
- }
- &prompt_RTN("to read man page for $ARGV[0]")
- if $roff eq 'nroff' && @ARGV;
- }
- }
- # --------------------------------------------------------------------------
- # whine about something not being found
- # --------------------------------------------------------------------------
-
- # MODULE no_entry.pl
-
- sub no_entry {
- print STDERR "No manual entry for $_[0]";
- if ($machine || $want_section) {
- print STDERR " in";
- print STDERR " section $want_section of" if $want_section;
- print STDERR " the";
- print STDERR " $machine" if $machine;
- print STDERR " manual";
- }
- print STDERR ".\n";
- $status = 1;
- }
- # --------------------------------------------------------------------------
- # just run a regular nroff, possibly showing the index first.
- # --------------------------------------------------------------------------
-
- # MODULE nroff.pl
-
- sub nroff {
- local($manpage) = $_[0];
- local($catpage);
- local($tmppage);
- local($command);
- local(@saveidx);
- local($manroot);
- local($macros);
- local($intmp);
- local(@st_cat, @st_man);
-
- die "trying to nroff a null man page" if $manpage eq '';
-
- umask 022;
-
- if ($full_index) {
- &show_index($manpage);
- return;
- }
- if ($fromfile) {
- $command = (($manpage =~ m:\.Z/:) ? $ZCAT : $CAT)
- . " < $manpage | $CATSET";
- &insert_filters($command, $manpage);
- } else {
- require 'stat.pl' unless defined &Stat;
- # compiled version has this already
-
-
- ($catpage = $manpage)
- =~ s,^(.*)/man([^\.]*)(\.Z)?/([^/]*)$,$1/cat$2/$4,;
-
- $manroot = $1;
-
- # Does the cat page exist?
- if (! -f $catpage && $COMPRESS_DIR){
- # No, maybe it is compressed?
- if (-f "$1/cat$2.Z/$4"){
- # Yes it was.
- $catpage = "$1/cat$2.Z/$4";
- } else {
- # Nope, the cat file doesn't exist.
- # Prefer the compressed cat directory if it exists.
- $catpage = "$1/cat$2.Z/$4"
- if $catpage !~ /\.Z$/ && -d "$1/cat$2.Z";
- }
- }
-
-
- @st_man = &Stat($manpage);
-
- if ($st_man[$ST_SIZE] == 0) {
- warn "$program: $manpage is length 0!\n";
- $status = 1;
- return;
- }
-
- @st_cat = &Stat($catpage);
-
-
- if ($st_cat[$ST_MTIME] < $st_man[$ST_MTIME]) {
-
- $command = (($manpage =~ m:\.Z:) ? $ZCAT : $CAT)
- . " < $manpage | $CATSET";
-
- $command = &insert_filters($command, $manpage);
- $command =~ s,-man,$manroot/tmac.an, if -e "$manroot/tmac.an";
-
- ($catdir = $catpage) =~ s!^(.*/?cat[^/]+)/[^/]*!$1!;
-
- chdir $manroot;
-
- $tmppage = "$catpage.$$";
-
- unless (-d $catdir && -w _
- && open(tmppage, ">$tmppage") # usually EROFS
- && close(tmppage) )
- {
- $catpage = $tmppage = "/tmp/man.$$";
- $intmp = 1;
- }
-
- printf STDERR "Reformatting page. Please wait ... " if $isatty;
-
- $command .= "| $COMPRESS" if $catpage =~ /\.Z/;
- $command .= "> $tmppage";
-
- $SIG{'INT'} = $SIG{'QUIT'} = $SIG{'HUP'} = $SIG{'TERM'}
- = 'tmp_cleanup';
-
- $SIG{'PIPE'} = 'PLUMBER';
-
- REFORMAT: { unless (&reformat($command)) {
- warn "$program: nroff of $manpage into $tmppage failed\n"
- unless $@;
- unlink $tmppage unless $debug;
- if (!$intmp++) {
- $catpage = $tmppage = "/tmp/man.$$";
- warn "$program: hang on... retrying into $tmppage\n";
- $command =~ s/> \S+$/> $tmppage/;
- $status = 0;
- redo REFORMAT;
- } else {
- #$status = 1;
- return;
- }
- }}
- warn "done\n" if $isatty;
-
- $intmp || rename($tmppage,$catpage) ||
- die "couldn't rename $tmppage to $catpage: $!\n";
-
- $SIG{'INT'} = $SIG{'QUIT'} = $SIG{'HUP'} = $SIG{'TERM'} =
- $SIG{'PIPE'} = 'DEFAULT';
-
- }
- $command = (($catpage =~ m:\.Z:)
- ? $ZCAT
- : $CAT)
- . " < $catpage";
- }
- if (-z $catpage) {
- unlink $catpage;
- die "$program: $catpage was length 0; disk full?\n";
- }
- $command .= "| $UL" if $UL;
- $command .= "| $SED 's/.\b//g'" if $stripBS;
-
- if ($isatty) {
- $command .= "| $PAGER";
- # If the pager is less, use the man page as the prompt, even if pipe
- if ($is_less) {
- # Escape all periods because less interprets them. We also
- # need to add an extra '\' to escape the shell intrepetation
- # of '\'. We also need to make a copy of $manpage, because
- # the substitution trashes the string and it is needed later.
- ($lessprompt = $manpage) =~ s/\./\\./g;
- $lessprompt = "$lessprompt byte %bB?s/%s .?e(END) :?pB%pB\\%.%t"
- if $ENV{'LESS'} =~ /M/; # he wants a long prompt
- $command .= " '-MPM$lessprompt'";
- }
- }
-
- &run_topic;
- unlink($tmppage) if $intmp;
- }
- # --------------------------------------------------------------------------
- # present subsections and let user select one
- # --------------------------------------------------------------------------
-
- # MODULE pick_index.pl
-
- sub pick_index {
- local($_);
- print "Valid sections for $page follow. Choose the section\n";
- print "index number or string pattern. (0 for full page, RTN to quit.)\n\n";
- &show_index;
- print "\nWhich section would you like? ";
- ($_ = <STDIN>) ? chop : ($_ = "\004");
- $_ = "\004" if 'quit' =~ /^$_/;
- return $_;
- }
- # --------------------------------------------------------------------------
- # print line with C\bC style emboldening
- # --------------------------------------------------------------------------
-
- # MODULE print.pl
-
- sub print {
- local($_) = @_;
-
- if (!$inbold) {
- print;
- } else {
- local($last);
- for (split(//)) {
- if ($last eq "\033") {
- print;
- } else {
- print /[!-~]/ ? $_."\b".$_ : $_;
- }
- $last = $_;
- }
- }
- }
- # --------------------------------------------------------------------------
- # prompt for <RET> if we're a tty and have a non-stopping pager
- # --------------------------------------------------------------------------
-
- # MODULE prompt_RTN.pl
-
- sub prompt_RTN {
- local($why) = $_[0] || "to continue";
- return unless $isatty;
- unless ($is_less && $ENV{'LESS'} !~ /E/) {
- print "Hit <RTN> $why: ";
- $_ = <STDIN>;
- }
- }
- # --------------------------------------------------------------------------
- # do a quick fetch of a key in the dbm file, recursing on indirect references
- # --------------------------------------------------------------------------
-
- # MODULE quick_fetch.pl
-
- sub quick_fetch {
- local($key,$array) = @_;
- local(@retlist) = ();
- local(@tmplist) = ();
- local($_, $entry);
- local($name, $ext);
- local(@newlist);
-
- return @retlist unless $entry = eval "\$$array".'{$key};';
-
- if ($@) { chop $@; die "bad eval: $@"; }
-
- @tmplist = split(/\002/, $entry);
- for (@tmplist) {
- if (/\001/) {
- push(@retlist, $_);
- } else {
- ($name, $ext) = /(.+)\.([^.]+)/;
- push(@retlist,
- grep(/[^\001]+\001[^\001]+\001${ext}\001/ || /[^\001]+${ext}\001/,
- &quick_fetch($name, $array)));
- # explain and diction are near duplicate man pages referencing
- # each other, requiring the $recursed check. one should be removed
- }
- }
- return @retlist;
- }
- # --------------------------------------------------------------------------
- # reformat the page with nroff, fixing up bold escapes
- # --------------------------------------------------------------------------
-
- # MODULE reformat.pl
-
- sub reformat {
- local($_) = @_;
- local($nroff, $col);
- local($inbold) = 0;
- local($status);
-
- if ($NROFF_CAN_BOLD) {
- return &run($_);
- }
-
- &unshell($_);
- ($nroff, $col) = m!(.*)\|\s*($COL.*)!;
-
- if ( $opt_n ) {
- warn "$_\n";
- return 1;
- }
-
- warn "$nroff | (this proc) | $col\n" if $debug;
-
- open (NROFF, "$nroff |");
- $colpid = open (COL, "| $col");
-
- select(COL);
-
- while (<NROFF>) {
- s/\033\+/\001/;
- s/\033\,/\002/;
- if ( /^([^\001]*)\002/ || /^([^\002]*)\001/ ) {
- &print($1);
- $inbold = !$inbold;
- $_ = $';
- redo;
- }
- &print($_);
- }
-
- close NROFF;
- if ($?) {
- warn "$program: \"$nroff\" failed! status=$?" if $debug;
- $status++;
- }
- close COL;
- if ($?) {
- warn "$program: \"$col\" failed! status=$?" if $debug;
- $status++;
- }
- select(STDOUT);
- $status == 0;
- }
- # --------------------------------------------------------------------------
- # call system on command arg, stripping of sh-isms and echoing for debugging
- # --------------------------------------------------------------------------
-
- # MODULE run.pl
-
- sub run {
- local($command) = $_[0];
-
- &unshell($command);
-
- if ( $opt_n ) {
- warn "$command\n";
- return 1;
- }
-
- warn "running: $command\n" if $debug;
- if (system $command) {
- $status = 1;
- printf STDERR "\"%s\" exited %d, sig %d\n", $command,
- ($? >> 8), ($? & 255) if $debug;
- }
- return ($? == 0);
- }
- # --------------------------------------------------------------------------
- # see whether they want to start at a subsection, then run the command
- # --------------------------------------------------------------------------
-
- # MODULE run_topic.pl
-
- sub run_topic {
- local($_);
- local($menu_rtn) = defined $idx_topic && $idx_topic eq '';
- {
- &append_sub_topic;
- last if $idx_topic eq "\004";
- if ($idx_topic eq '0') {
- $menu_rtn = 0;
- $idx_topic = '';
- $command =~ s: '\+/[^']*'::;
- }
- $fromfile ? &reformat($command) : &run($command);
- if ($menu_rtn) {
- $idx_topic = '';
- &prompt_RTN("to return to the index");
- $command =~ s! '\+/.*$!!;
- redo;
- }
- }
-
- }
- # --------------------------------------------------------------------------
- # create and display subsection index via pager
- # --------------------------------------------------------------------------
-
- # MODULE show_index.pl
-
- sub show_index {
- local($_);
- &load_index($_[0]);
- if ($#ssindex > ($rows - 4) && $isatty) {
- print "Hit <RTN> for $#ssindex subsections via pager: ";
- $_ = <STDIN>;
- if ($no_idx_file) {
- open (PAGER, "| $PAGER");
- print PAGER @ssindex;
- close PAGER;
- } else {
- &run("$PAGER $idx_file");
- }
- } else {
- print STDOUT @ssindex;
- }
- }
- # --------------------------------------------------------------------------
- # do a slow fetch for target using perl's globbing notation
- # --------------------------------------------------------------------------
-
- # MODULE slow_fetch.pl
-
- sub slow_fetch {
- local($target,$root) = @_;
- local($glob, $stem, $entry);
-
- $target =~ s/(\W)/\\$1/g; # for str$round(3V) or /bin/[
-
- if ($want_section) {
- if ($MANSECT{$want_section}) {
- $stem = $want_section;
- } else {
- $stem = substr($want_section,0,1);
- }
- $glob = "man$stem*";
- } else {
- $glob = 'man*';
- }
- $glob = "$root/$glob/$target.*";
- return <${glob}>;
- }
- # --------------------------------------------------------------------------
- # do whatis lookup the hard way
- # --------------------------------------------------------------------------
-
- # MODULE slow_whatis.pl
-
- sub slow_whatis {
- local($query);
- local($WHATIS);
-
- for (@ARGV) { s/([^\w])/\\$1/g; }
-
- $query = '^[^-]*\b?(' . join('|',@ARGV) . ')\b[^-]* -';
-
- if ($EGREP) {
- if (&run("$EGREP '$query' @whatis")) {
- # pity can't tell which i found
- %seeking = ();
- }
- } else {
- foreach $WHATIS (@whatis) {
- unless (open WHATIS) {
- warn "can't open $WHATIS: $!\n";
- next;
- }
- while (<WHATIS>) {
- next unless /$query/i;
- ($target = $+) =~ y/A-Z/a-z/;
- delete $seeking{$target};
- print;
- }
- close WHATIS;
- }
- }
- }
- # --------------------------------------------------------------------------
- # interrupted -- unlink temp page
- # --------------------------------------------------------------------------
-
- # MODULE tmp_cleanup.pl
-
- sub tmp_cleanup {
- warn "unlink $tmppage\n" if $debug;
- unlink $tmppage;
- die "Interrupted!\n";
- }
- # --------------------------------------------------------------------------
- # due to aliasing the dbase sometimes has the same thing twice
- # --------------------------------------------------------------------------
-
- # MODULE trimdups.pl
-
- sub trimdups {
- local(%seen) = ();
- local(@retlist) = ();
-
- while ($file = shift) {
- push(@retlist,$file) unless $seen{$file}++;
- }
- return @retlist;
- }
- # --------------------------------------------------------------------------
- # run through the typesetter
- # --------------------------------------------------------------------------
-
- # MODULE troff.pl
-
- sub troff {
- local ($file) = $_[0];
- local ($command);
- local ($manroot);
- local ($macros);
-
- ($manroot) = $file =~ m,^(.*)/man([^\.]*)(\.Z)?/([^/]*),;
-
- $command = ((($file =~ m:\.Z:)
- ? $ZCAT
- : $CAT)
- . " < $file | $TYPESET");
-
- $command =~ s,-man,$manroot/tmac.an, if -e "$manroot/tmac.an";
-
- &insert_filters($command,$file);
- &run($command);
- }
- # --------------------------------------------------------------------------
- # strip arg of extraneous cats and redirects
- # --------------------------------------------------------------------------
-
- # MODULE unshell.pl
-
- sub unshell {
- $_[0] =~ s/^\s*cat\s*<?\s*([^\s|]+)\s*\|\s*([^|]+)/$2 < $1/;
- $_[0] =~ s/^([^|<]+)<([^Z|<]+)$/$1 $2/;
- ($roff eq 'troff') && $_[0] =~ s#(/usr/man/pr\S+)\s+(\S+)#$2 $1#;
- }
- # --------------------------------------------------------------------------
- # print out usage message via pager and exit
- # --------------------------------------------------------------------------
-
- # MODULE usage.pl
-
- sub usage {
- unless ($opt_u) {
- warn "usage: $program [-flags] topic ...\n";
- warn " (use -u for long usage message)\n";
- } else {
- open (PIPE, "| $PAGER");
- print PIPE <<USAGE; # in case he wants a page
- USAGE SUMMARY:
- man [-flags] [section] page[/index] ...
- (section is [1-8lnop], or "new", "local", "public", "old")
- (index is section or subsection header)
-
- man [-flags] -f topic ...
- (aka "whatis")
-
- man [-flags] -k keyword ...
- (aka "apropos")
-
- FLAGS: (most only make sense when invoked as 'man')
- -a show all possible man pages for this topic
- -A ask which selection if several available
-
- -l file do man processing on local file
- -f topic list table of contents entry for topic
- -k keyword give table of contents entries containing keyword
- -K pattern as -K but allow regexps
- -g pattern grep through all man pages for patterns
- -w topic which files would be shown for a given topic
- -i topic show section and subsection index for use with topic/index
-
- -M path use colon-delimited man path for searching (also as -P)
- -S sects define new section precedence
-
- -t troff the man page
- -T path call alternate typesetter on the man page
-
- -d print out all system() commands before running them
- -h do all lookups the hard way, ignoring any DBM files
- -u this message
- -v print version string
- -D strip backspaces from output
-
- ENVIRONMENT:
- \$PAGER pager to pipe terminal-destined output through
- \$MANPATH like -M path
- \$MANSECT like -S sects
- \$MANALT used for alternate hardware types (or obsolete -m flag)
- \$TROFF like -T path
-
- CURRENT DEFAULTS:
- PAGER $PAGER
- MANPATH $MANPATH
- MANSECT $MANSECT
- MANALT $MANALT
- TROFF $TROFF
-
- NOTES: (\$manroot is each component in \$MANPATH)
- * If \$manroot/whatis DBM files do not exist, a warning will be
- printed (if -d flag) and -h will be assumed for that \$manroot only.
- * If \$manroot/tmac.an exists, it will be used for formatting
- instead of the normal -man macros.
- * Man pages may be compressed either in (for example) man1.Z/who.1
- or man1/who.1.Z; cat pages will go into corresponding places.
- * If the man page contains .EQ or .TS directives, eqn and/or tbl
- will be invoked as needed at format time.
- USAGE
- close PIPE;
- }
- warn "couldn't run long usage message thru $PAGER?!?!\n" if $?;
- exit 1;
- }
- # --------------------------------------------------------------------------
- # figure out full path name of man page, which may have been compressed
- # --------------------------------------------------------------------------
-
- # MODULE verify.pl
-
- sub verify {
- local($path) = @_;
- local($orig) = $path;
-
- warn "verify: verifying $path";
-
- return $path if -f $path;
-
- if ($COMPRESS_PAGE) {
- $path .= '.Z';
- return $path if -f $path;
- $path =~ s/.Z//;
- }
-
- if ($COMPRESS_DIR) {
- $path =~ s-(/[^/]*)$-.Z$1-;
- return $path if -f $path;
- }
-
- warn "$program: $orig has disappeared -- rerun makewhatis\n";
- $status = 1;
- return '';
- }
- # --------------------------------------------------------------------------
- # just print the version
- # --------------------------------------------------------------------------
-
- # MODULE version.pl
-
- sub version {
- warn "$program: version is \"$version\"\n" ;
- }
- # --------------------------------------------------------------------------
- # run whatis (man -f)
- # --------------------------------------------------------------------------
-
- # MODULE whatis.pl
-
- sub whatis {
- local($target, %seeking, $section, $desc, @entries);
-
- &genwhatis;
-
- for $target (@ARGV) { $seeking{$target} = 1; }
-
- if ($hard_way) {
- &slow_whatis;
- } else {
- &fast_whatis;
- }
-
- for $target (keys %seeking) {
- print "$program: $target: not found.\n";
- $status = 1;
- }
- }
- # --------------------------------------------------------------------------
- # run 'man -w'
- # --------------------------------------------------------------------------
-
- # MODULE whereis.pl
-
- sub whereis {
- local($target, @files);
-
- foreach $target (@ARGV) {
- @files = &find_files($target);
- if ($#files < $[) {
- warn "$program: $target not found\n";
- $status = 1;
- } else {
- print "$target: " if $#ARGV;
- for (@files) { print &verify($_), " "; }
- print "\n";
- }
- }
- }
-