summaryrefslogtreecommitdiffstats
path: root/gnu/usr.bin/man
diff options
context:
space:
mode:
authorjkh <jkh@FreeBSD.org>1993-07-07 23:07:02 +0000
committerjkh <jkh@FreeBSD.org>1993-07-07 23:07:02 +0000
commit73606c73729da848d3173c01390dc2a78d2997e1 (patch)
treebe8b89723d6c423c5cae81f73a3ff71296581e51 /gnu/usr.bin/man
downloadFreeBSD-src-73606c73729da848d3173c01390dc2a78d2997e1.zip
FreeBSD-src-73606c73729da848d3173c01390dc2a78d2997e1.tar.gz
Newer new man page reader.
Diffstat (limited to 'gnu/usr.bin/man')
-rw-r--r--gnu/usr.bin/man/COPYING339
-rw-r--r--gnu/usr.bin/man/Makefile10
-rw-r--r--gnu/usr.bin/man/Makefile.inc6
-rw-r--r--gnu/usr.bin/man/README134
-rw-r--r--gnu/usr.bin/man/TODO123
-rw-r--r--gnu/usr.bin/man/apropos/Makefile26
-rw-r--r--gnu/usr.bin/man/apropos/apropos64
-rw-r--r--gnu/usr.bin/man/apropos/apropos.127
-rw-r--r--gnu/usr.bin/man/apropos/apropos.man27
-rw-r--r--gnu/usr.bin/man/apropos/apropos.sh64
-rw-r--r--gnu/usr.bin/man/lib/Makefile10
-rw-r--r--gnu/usr.bin/man/lib/config.h216
-rw-r--r--gnu/usr.bin/man/lib/gripes.c180
-rw-r--r--gnu/usr.bin/man/lib/gripes.h30
-rw-r--r--gnu/usr.bin/man/lib/util.c150
-rw-r--r--gnu/usr.bin/man/makewhatis/Makefile17
-rw-r--r--gnu/usr.bin/man/makewhatis/makewhatis79
-rw-r--r--gnu/usr.bin/man/makewhatis/makewhatis.sh79
-rw-r--r--gnu/usr.bin/man/man/Makefile14
-rw-r--r--gnu/usr.bin/man/man/glob.c680
-rw-r--r--gnu/usr.bin/man/man/man.1132
-rw-r--r--gnu/usr.bin/man/man/man.c1382
-rw-r--r--gnu/usr.bin/man/man/man.man132
-rw-r--r--gnu/usr.bin/man/man/manpath.c520
-rw-r--r--gnu/usr.bin/man/man/manpath.h26
-rw-r--r--gnu/usr.bin/man/man/ndir.h51
-rw-r--r--gnu/usr.bin/man/man/strdup.c39
-rw-r--r--gnu/usr.bin/man/man/version.h17
-rw-r--r--gnu/usr.bin/man/manpath/Makefile14
-rw-r--r--gnu/usr.bin/man/manpath/manpath.c520
-rw-r--r--gnu/usr.bin/man/manpath/manpath.config30
-rw-r--r--gnu/usr.bin/man/manpath/manpath.h26
-rw-r--r--gnu/usr.bin/man/manpath/manpath.man56
-rw-r--r--gnu/usr.bin/man/whatis/Makefile26
-rw-r--r--gnu/usr.bin/man/whatis/whatis66
-rw-r--r--gnu/usr.bin/man/whatis/whatis.127
-rw-r--r--gnu/usr.bin/man/whatis/whatis.man27
-rw-r--r--gnu/usr.bin/man/whatis/whatis.sh66
38 files changed, 5432 insertions, 0 deletions
diff --git a/gnu/usr.bin/man/COPYING b/gnu/usr.bin/man/COPYING
new file mode 100644
index 0000000..a43ea21
--- /dev/null
+++ b/gnu/usr.bin/man/COPYING
@@ -0,0 +1,339 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 675 Mass Ave, Cambridge, MA 02139, USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ Appendix: How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) 19yy <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) 19yy name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/gnu/usr.bin/man/Makefile b/gnu/usr.bin/man/Makefile
new file mode 100644
index 0000000..1777b66
--- /dev/null
+++ b/gnu/usr.bin/man/Makefile
@@ -0,0 +1,10 @@
+# Master Makefile for man, manpath, apropos, whatis, and makewhatis
+#
+# You may distribute under the terms of the GNU General Public
+# License as specified in the README file that comes with the man 1.0
+# distribution.
+#
+
+SUBDIR = lib man manpath apropos whatis makewhatis
+
+.include <bsd.subdir.mk>
diff --git a/gnu/usr.bin/man/Makefile.inc b/gnu/usr.bin/man/Makefile.inc
new file mode 100644
index 0000000..b3ccb46
--- /dev/null
+++ b/gnu/usr.bin/man/Makefile.inc
@@ -0,0 +1,6 @@
+BINDIR?= /usr/bin
+libdir= /etc
+bindir= ${BINDIR}
+pager= /usr/gnu/bin/less -sC
+manpath_config_file= /etc/manpath.config
+troff= /usr/bin/groff -Tps -man
diff --git a/gnu/usr.bin/man/README b/gnu/usr.bin/man/README
new file mode 100644
index 0000000..d8fc4d4
--- /dev/null
+++ b/gnu/usr.bin/man/README
@@ -0,0 +1,134 @@
+README file for man(1).
+
+This is a replacement for Un*x man(1), apropos(1), whatis(1), and
+manpath(1). It has all kinds of neat features that other versions of
+man don't, including support for multiple man page directory trees,
+preformatted man pages, and troff. It is provided without any
+warranty whatever. I hope you find it useful.
+
+This program is not a GNU product but it is distributed under the
+terms of the GNU copyleft which is described in the file COPYING.
+
+There is a solution written in perl which is probably superior in
+every way, but, like me, you may prefer this one anyway.
+:-)
+
+If you compile with support for preformatted man pages, man(1) will
+try to update the preformatted page if the man page source is newer.
+
+If you compile with support for troff, you can say things like
+`man -t foo | psdit > foo.ps' and have fabulous printed documentation
+as well.
+
+I have resisted the temptation to handle all the bizarre ways various
+vendors have of organizing man pages. This version of man assumes
+that directory trees have the structure:
+
+ .../man
+ /manSect
+ /foo.Sect*
+ ...
+ /catSect
+ /foo.Sect*
+ ...
+
+where Sect is some number or string and should be listed in the set of
+sections to be searched. It is not necessary to have both the cat*
+and man* subdirectories, but you must have at least one. :-)
+
+
+INSTALLATION
+
+1. Run configure. This will grope around your system a bit and then
+ ask you a number of questions. It will create a Makefile from the
+ file Makefile.in, and a config.h file from config.h.in. You may
+ have to do some fine tuning to get things to work exactly right on
+ your system. If you do, I'd like to know what changes you had to
+ make to get things working.
+
+2. Edit the manpath.config file. This determines the system-wide
+ mappings for bin directories and man page directories.
+
+3. Do a `make all', try it out, and then if you're happy with that, do
+ a `make install'. You don't need to be root to use this set of
+ programs.
+
+4. Install the whatis database(s) by running makewhatis. If you want
+ to keep things absolutely current, you'll need to run this whenever
+ you add new man pages. You might want to add an entry in your
+ crontab.
+
+BUGS
+
+If you find one of these, please tell me about it. If you have a fix,
+that's even better. If not, I can't guarantee that I'll fix it, but I
+would like to know about them.
+
+John Eaton
+jwe@che.utexas.edu
+Department of Chemical Engineering
+The University of Texas at Austin
+Austin, Texas 78712
+
+
+CHANGES
+
+Partial list of changes since version 1.0:
+
+Installation made easier (this was the intent anyway) with the
+introduction of a configure script.
+
+Commands like `man 3f intro' handled properly when the name of the
+file we want is something like .../man3/intro.3f.
+
+Man can now run set uid to a special user so formatted man pages don't
+have to be world writable.
+
+Man now works with compressed (.Z) frozen (.F) and yabba (.Y) cat
+files. Frozen files are compressed files using freeze/melt, some
+combination of LZW and tree coding. Sources for it came out on
+comp.sources.misc or alt.sources or ... a few months ago. Yabba files
+are compressed using yabba/unyabba, a data compression scheme posted
+to alt.sources by Dan Bernstein.
+
+Man now uses a more reasonable default for the search order:
+1, n, l, 6, 8, 2, 3, 4, 5, 7, p, o
+
+Man now allows for user-definable section search order via -S or
+MANSECT.
+
+Glob.c can work even if you don't have alloca, and works properly on
+Suns with the Sun C compiler.
+
+There is now a way to automatically to run preprocessors like the Sun
+man program. The first line of the man page indicates which
+preprocessors should be run:
+
+ If the first line is a string of the form:
+
+ '\" X
+
+ where X is separated from the the `"' by a single SPACE and
+ consists of any combination of characters in the following
+ list, man pipes its input to troff(1) or nroff(1) through
+ the corresponding preprocessors.
+
+ e eqn(1), or neqn for nroff
+ g grap(1)
+ p pic(1)
+ r refer(1)
+ t tbl(1), and col(1V) for nroff
+ v vgrind(1)
+
+Preprocessors may also be set on the command line with -p or from the
+environment with MANROFFSEQ.
+
+The tbl preprocessor is run by default.
+
+Manpath now stat()'s the directories in MANPATH to avoid including
+directories that don't exist.
+
+The output of apropos and whatis are now piped through PAGER.
+
+There is a new option to show where you would find a man page
+(-w option) and in what order (-w with -a).
diff --git a/gnu/usr.bin/man/TODO b/gnu/usr.bin/man/TODO
new file mode 100644
index 0000000..19060ad
--- /dev/null
+++ b/gnu/usr.bin/man/TODO
@@ -0,0 +1,123 @@
+Things that would be nice but aren't really necessary:
+
+0. Update the documentation.
+
+XX Come up with an easier way to install this thing. There are now
+ lots of options and dependent flags to set. Should I worry too
+ much about this?
+
+XX Properly handle commands like `man 3f intro' when the name of the
+ file we want is something like .../man3/intro.3f. The way this is
+ done right now seems sort of kludgey but it mostly works. See
+ man.c for details.
+
+2. Malloc everything instead of having fixed limits... Or at least
+ check the limits everywhere. If you're paranoid about this, make
+ the limits big (famous last words: really, there aren't that many
+ things that could go wrong :-).
+
+3. Try to do a little better job of memory management. There are a
+ lot of little temporary strings that are malloc'd and never freed.
+ This is probably ok for a standalone program but not so good if
+ you wanted to call man() from another program.
+
+XX Come up with a clear view of the cat directory file permissions
+ problem. What's a good solution, other than having man run setuid
+ to some special user? (Make directories writable by all, cat
+ files 666.)
+
+XX Allow a compile time option that makes man run setuid to some
+ other user that owns all the cat pages, so that they don't have to
+ be world writable.
+
+XX Allow man to deal with compressed (.Z) frozen (.F) and yabba (.Y)
+ cat files. Frozen files are compressed files using freeze/melt,
+ some combination of LZW and tree coding. Sources for it came out
+ on comp.sources.misc or alt.sources or ... a few months ago.
+ Yabba files are compressed using yabba/unyabba, a data compression
+ scheme posted to alt.sources by Dan Bernstein.
+
+XX Choose a more reasonable default for the search order. Perhaps
+ this: 1, n, l, 6, 8, 2, 3, 4, 5, 7, p, o
+
+XX Fix glob.c so it doesn't need alloca, and/or fix it so that it can
+ work on a Sun:
+
+ #ifdef __GNUC__
+ #define alloca __builtin_alloca
+ #else /* !__GNUC__ */
+ #ifdef sparc
+ #include <alloca.h>
+ #endif /* sparc */
+ #endif /* __GNUC__ */
+
+XX Add some way to automatically to run preprocessors. The Sun man
+ program has a convention that the first line of the man page can
+ indicate which preprocessors should be run. Here's an excerpt from
+ its man page:
+
+ Preprocessing Manual Pages
+ If the first line is a string of the form:
+
+ '\" X
+
+ where X is separated from the the `"' by a single SPACE and
+ consists of any combination of characters in the following
+ list, man pipes its input to troff(1) or nroff(1) through
+ the corresponding preprocessors.
+
+ e eqn(1), or neqn for nroff
+ r refer(1)
+ t tbl(1), and col(1V) for nroff
+ v vgrind(1)
+
+ If eqn or neqn is invoked, it will automatically read the
+ file /usr/pub/eqnchar (see eqnchar(7)).
+
+XX Have manpath stat() the directories in MANPATH to avoid including
+ directories that don't exist. Some versions of man and whatis
+ complain when the directories (like /usr/new/man) don't exist.
+
+XX Pipe the output of apropos and whatis through a pager.
+
+XX I've been using your man(1) package for a while now and I ran into
+ a problem with the X man pages that use tbl commands. Is it
+ possible to configure your man(1) package to use a general command
+ string. For example, a user could set an environment variable:
+
+ setenv ROFFLINE 'pic $* | tbl | nroff -man'
+
+13. Fix makewhatis so that it can handle stuff like this (from the
+ Motif 1.1 man pages):
+
+ .TH XmRowColumn 3X "" "" "" ""
+ .SH NAME
+ .mc |
+ \fBXmRowColumn \(em the RowColumn widget class.\fP
+ .mc
+ .iX "XmRowColumn"
+ .iX "widget class" "RowColumn"
+ .sp 1
+ .SH SYNOPSIS
+
+14. Consider changing the format of the awk command's printf to use
+ "%s" instead of the standard 20.20s to accomodate the extra long
+ file names used by Motif. Maybe there's a better way to handle
+ this?
+
+15. Add ability to run man on a local file
+
+16. Handle per-tree tmac macros
+
+XX Allow user-definable section search order via -S or $MANSECT.
+ Thus programmers can get stty(3) before stty(1).
+
+XX Show all the places you would find a man page (-w option) and in
+ what order.
+
+19. Support for multi-char sections like man1m/*.1m or manavs/*.avs
+ (can I have a section that doesn't start with a numeral?)
+
+20. Implement man -K for regexp apropos
+
+21. An option to grep through all the man pages in $MANPATH
diff --git a/gnu/usr.bin/man/apropos/Makefile b/gnu/usr.bin/man/apropos/Makefile
new file mode 100644
index 0000000..892af95
--- /dev/null
+++ b/gnu/usr.bin/man/apropos/Makefile
@@ -0,0 +1,26 @@
+.include "../Makefile.inc"
+
+all: apropos apropos.1
+
+obj depend rcsfreeze all:
+ @echo -n
+
+cleandir: clean
+
+clean:
+ @rm -f apropos apropos.1
+
+apropos: apropos.sh
+ sed -e 's,%libdir%,${libdir},' -e 's,%bindir%,${bindir},' \
+ -e 's,%pager%,${pager},' \
+ apropos.sh > apropos
+
+apropos.1: apropos.man
+ sed -e 's,%libdir%,${libdir},' -e 's,%bindir%,${bindir},' \
+ -e 's,%pager%,${pager},' -e 's,%troff%,${troff},' \
+ -e 's,%manpath_config_file%,${manpath_config_file},' \
+ apropos.man > apropos.1
+
+install: apropos apropos.1
+ install -c -o bin -g bin -m 555 apropos /usr/bin
+ install -c -o bin -g bin -m 444 apropos.1 /usr/share/man/man1
diff --git a/gnu/usr.bin/man/apropos/apropos b/gnu/usr.bin/man/apropos/apropos
new file mode 100644
index 0000000..8735e5f
--- /dev/null
+++ b/gnu/usr.bin/man/apropos/apropos
@@ -0,0 +1,64 @@
+#!/bin/sh
+#
+# apropos -- search the whatis database for keywords.
+#
+# Copyright (c) 1990, 1991, John W. Eaton.
+#
+# You may distribute under the terms of the GNU General Public
+# License as specified in the README file that comes with the man
+# distribution.
+#
+# John W. Eaton
+# jwe@che.utexas.edu
+# Department of Chemical Engineering
+# The University of Texas at Austin
+# Austin, Texas 78712
+
+PATH=/usr/local/bin:/bin:/usr/ucb:/usr/bin
+
+libdir=/etc
+
+if [ $# = 0 ]
+then
+ echo "usage: `basename $0` keyword ..."
+ exit 1
+fi
+
+manpath=`/usr/bin/manpath -q | tr : '\040'`
+
+if [ "$manpath" = "" ]
+then
+ echo "whatis: manpath is null"
+ exit 1
+fi
+
+if [ "$PAGER" = "" ]
+then
+ PAGER="/usr/gnu/bin/less -sC"
+fi
+
+while [ $1 ]
+do
+ found=0
+ for d in $manpath /usr/lib
+ do
+ if [ -f $d/whatis ]
+ then
+ grep -i "$1" $d/whatis
+ status=$?
+ if [ "$status" = "0" ]
+ then
+ found=1
+ fi
+ fi
+ done
+
+ if [ "$found" = "0" ]
+ then
+ echo "$1: nothing appropriate"
+ fi
+
+ shift
+done | $PAGER
+
+exit
diff --git a/gnu/usr.bin/man/apropos/apropos.1 b/gnu/usr.bin/man/apropos/apropos.1
new file mode 100644
index 0000000..3bb3e17
--- /dev/null
+++ b/gnu/usr.bin/man/apropos/apropos.1
@@ -0,0 +1,27 @@
+.\" Man page for apropos
+.\"
+.\" Copyright (c) 1990, 1991, John W. Eaton.
+.\"
+.\" You may distribute under the terms of the GNU General Public
+.\" License as specified in the README file that comes with the man 1.0
+.\" distribution.
+.\"
+.\" John W. Eaton
+.\" jwe@che.utexas.edu
+.\" Department of Chemical Engineering
+.\" The University of Texas at Austin
+.\" Austin, Texas 78712
+.\"
+.TH apropos 1 "Jan 15, 1991"
+.LO 1
+.SH NAME
+apropos \- search the whatis database for strings
+.SH SYNOPSIS
+.BI apropos
+keyword ...
+.SH DESCRIPTION
+apropos searches a set of database files containing short descriptions
+of system commands for keywords and displays the result on the
+standard output.
+.SH "SEE ALSO"
+whatis(1), man(1).
diff --git a/gnu/usr.bin/man/apropos/apropos.man b/gnu/usr.bin/man/apropos/apropos.man
new file mode 100644
index 0000000..3bb3e17
--- /dev/null
+++ b/gnu/usr.bin/man/apropos/apropos.man
@@ -0,0 +1,27 @@
+.\" Man page for apropos
+.\"
+.\" Copyright (c) 1990, 1991, John W. Eaton.
+.\"
+.\" You may distribute under the terms of the GNU General Public
+.\" License as specified in the README file that comes with the man 1.0
+.\" distribution.
+.\"
+.\" John W. Eaton
+.\" jwe@che.utexas.edu
+.\" Department of Chemical Engineering
+.\" The University of Texas at Austin
+.\" Austin, Texas 78712
+.\"
+.TH apropos 1 "Jan 15, 1991"
+.LO 1
+.SH NAME
+apropos \- search the whatis database for strings
+.SH SYNOPSIS
+.BI apropos
+keyword ...
+.SH DESCRIPTION
+apropos searches a set of database files containing short descriptions
+of system commands for keywords and displays the result on the
+standard output.
+.SH "SEE ALSO"
+whatis(1), man(1).
diff --git a/gnu/usr.bin/man/apropos/apropos.sh b/gnu/usr.bin/man/apropos/apropos.sh
new file mode 100644
index 0000000..070b848
--- /dev/null
+++ b/gnu/usr.bin/man/apropos/apropos.sh
@@ -0,0 +1,64 @@
+#!/bin/sh
+#
+# apropos -- search the whatis database for keywords.
+#
+# Copyright (c) 1990, 1991, John W. Eaton.
+#
+# You may distribute under the terms of the GNU General Public
+# License as specified in the README file that comes with the man
+# distribution.
+#
+# John W. Eaton
+# jwe@che.utexas.edu
+# Department of Chemical Engineering
+# The University of Texas at Austin
+# Austin, Texas 78712
+
+PATH=/usr/local/bin:/bin:/usr/ucb:/usr/bin
+
+libdir=%libdir%
+
+if [ $# = 0 ]
+then
+ echo "usage: `basename $0` keyword ..."
+ exit 1
+fi
+
+manpath=`%bindir%/manpath -q | tr : '\040'`
+
+if [ "$manpath" = "" ]
+then
+ echo "whatis: manpath is null"
+ exit 1
+fi
+
+if [ "$PAGER" = "" ]
+then
+ PAGER="%pager%"
+fi
+
+while [ $1 ]
+do
+ found=0
+ for d in $manpath /usr/lib
+ do
+ if [ -f $d/whatis ]
+ then
+ grep -i "$1" $d/whatis
+ status=$?
+ if [ "$status" = "0" ]
+ then
+ found=1
+ fi
+ fi
+ done
+
+ if [ "$found" = "0" ]
+ then
+ echo "$1: nothing appropriate"
+ fi
+
+ shift
+done | $PAGER
+
+exit
diff --git a/gnu/usr.bin/man/lib/Makefile b/gnu/usr.bin/man/lib/Makefile
new file mode 100644
index 0000000..33bd40b
--- /dev/null
+++ b/gnu/usr.bin/man/lib/Makefile
@@ -0,0 +1,10 @@
+LIB = man
+
+CFLAGS+= -I${.CURDIR} -DSTDC_HEADERS -DPOSIX -DHAS_TROFF -DDO_UNCOMPRESS -DALT_SYSTEMS
+
+SRCS = util.c gripes.c
+
+install:
+ @echo -n
+
+.include <bsd.lib.mk>
diff --git a/gnu/usr.bin/man/lib/config.h b/gnu/usr.bin/man/lib/config.h
new file mode 100644
index 0000000..2c23168
--- /dev/null
+++ b/gnu/usr.bin/man/lib/config.h
@@ -0,0 +1,216 @@
+/*
+ * config.h
+ *
+ * If you haven't read the README file, now might be a good time.
+ *
+ * This file is edited by configure, so you shouldn't have to.
+ * If that doesn't work, edit this file to match your site.
+ *
+ * Sorry it's so long, but there are lots of things you might want to
+ * customize for your site.
+ *
+ * Copyright (c) 1990, 1991, John W. Eaton.
+ *
+ * You may distribute under the terms of the GNU General Public
+ * License as specified in the file COPYING that comes with the man
+ * distribution.
+ *
+ * John W. Eaton
+ * jwe@che.utexas.edu
+ * Department of Chemical Engineering
+ * The University of Texas at Austin
+ * Austin, Texas 78712
+ */
+
+#ifdef COMPRESS
+#define DO_COMPRESS
+#define DO_UNCOMPRESS
+#endif
+
+/*
+ * This is the size of a number of internal buffers. It should
+ * probably not be less than 512.
+ */
+#ifndef BUFSIZ
+#define BUFSIZ 1024
+#endif
+
+/*
+ * This should be at least the size of the longest path.
+ */
+#ifndef MAXPATHLEN
+#define MAXPATHLEN 1024
+#endif
+
+/*
+ * This is the maximum number of directories expected in the manpath.
+ */
+#ifndef MAXDIRS
+#define MAXDIRS 64
+#endif
+
+/*
+ * This is the name of the group that owns the preformatted man pages.
+ * If you are running man as a setgid program, you should make sure
+ * that all of the preformatted man pages and the directories that
+ * they live in are readable and writeable and owned by this group.
+ */
+#ifdef SECURE_MAN_UID
+#define MAN_USER ""
+#endif
+
+/*
+ * It's probably best to define absolute paths to all of these. If
+ * you don't, you'll be depending on the user's path to be correct
+ * when system () is called. This can result in weird behavior that's
+ * hard to track down, especially after you forget how this program
+ * works... If you don't have some of these programs, simply define
+ * them to be empty strings (i.e. ""). As a minimum, you must have
+ * nroff installed.
+ */
+#ifndef APROPOS
+#define APROPOS "/usr/bin/apropos"
+#endif
+
+#ifndef WHATIS
+#define WHATIS "/usr/bin/whatis"
+#endif
+
+#ifndef PAGER
+#define PAGER "/usr/gnu/bin/less -sC"
+#endif
+
+#ifdef HAS_TROFF
+#ifndef TROFF
+#define TROFF "/usr/bin/groff -Tps -man"
+#endif
+#endif
+
+#ifndef NROFF
+#define NROFF "/usr/bin/groff -Tascii -man"
+#endif
+
+#ifndef EQN
+#define EQN "/usr/bin/eqn -Tps"
+#endif
+
+#ifndef NEQN
+#define NEQN "/usr/bin/eqn -Tascii"
+#endif
+
+#ifndef TBL
+#define TBL "/usr/bin/tbl"
+#endif
+
+#ifndef COL
+#define COL "/usr/bin/col"
+#endif
+
+#ifndef VGRIND
+#define VGRIND "/usr/bin/vgrind"
+#endif
+
+#ifndef REFER
+#define REFER "/usr/bin/refer"
+#endif
+
+#ifndef GRAP
+#define GRAP ""
+#endif
+
+#ifndef PIC
+#define PIC "/usr/bin/pic"
+#endif
+
+/*
+ * Define the absolute path to the configuration file.
+ */
+#ifndef MAN_MAIN
+ static char config_file[] = "/etc/manpath.config";
+#endif
+
+/*
+ * Define the uncompression program(s) to use for those preformatted
+ * pages that end in the given character. If you add extras here, you
+ * may need to change man.c.
+ */
+#ifdef DO_UNCOMPRESS
+/* .F files */
+#define FCAT ""
+/* .Y files */
+#define YCAT ""
+/* .Z files */
+#define ZCAT "/usr/bin/zcat"
+#endif
+
+/*
+ * This is the standard program to use on this system for compressing
+ * pages once they have been formatted, and the character to tack on
+ * to the end of those files. The program listed is expected to read
+ * from the standard input and write compressed output to the standard
+ * output.
+ */
+#ifdef DO_COMPRESS
+#define COMPRESSOR ""
+#define COMPRESS_EXT ""
+#endif
+
+/*
+ * Define the standard manual sections. For example, if your man
+ * directory tree has subdirectories man1, man2, man3, mann,
+ * and man3foo, std_sections[] would have "1", "2", "3", "n", and
+ * "3foo". Directories are searched in the order they appear. Having
+ * extras isn't fatal, it just slows things down a bit.
+ *
+ * Note that this is just for directories to search. If you have
+ * files like .../man3/foobar.3Xtc, you don't need to have "3Xtc" in
+ * the list below -- this is handled separately, so that `man 3Xtc foobar',
+ * `man 3 foobar', and `man foobar' should find the file .../man3/foo.3Xtc,
+ * (assuming, of course, that there isn't a .../man1/foo.1 or somesuch
+ * that we would find first).
+ *
+ * Note that this list should be in the order that you want the
+ * directories to be searched. Is there a standard for this? What is
+ * the normal order? If anyone knows, please tell me!
+ */
+#ifndef MANPATH_MAIN
+ static char *std_sections[] =
+ {
+ "1", "n", "l", "6", "8", "2", "3", "4", "5", "7", "p", "o", NULL
+ };
+#endif
+
+/*
+ * Not all systems define these in stat.h.
+ */
+#ifndef S_IRUSR
+#define S_IRUSR 00400 /* read permission: owner */
+#endif
+#ifndef S_IWUSR
+#define S_IWUSR 00200 /* write permission: owner */
+#endif
+#ifndef S_IRGRP
+#define S_IRGRP 00040 /* read permission: group */
+#endif
+#ifndef S_IWGRP
+#define S_IWGRP 00020 /* write permission: group */
+#endif
+#ifndef S_IROTH
+#define S_IROTH 00004 /* read permission: other */
+#endif
+#ifndef S_IWOTH
+#define S_IWOTH 00002 /* write permission: other */
+#endif
+
+/*
+ * This is the mode used for formatted pages that we create. If you
+ * are using the setgid option, you should use 664. If you are not,
+ * you should use 666 and make the cat* directories mode 777.
+ */
+#ifndef CATMODE
+#ifdef SECURE_MAN_UID
+#define CATMODE S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH
+#else
+#define CATMODE S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH
+#endif
+#endif
diff --git a/gnu/usr.bin/man/lib/gripes.c b/gnu/usr.bin/man/lib/gripes.c
new file mode 100644
index 0000000..76f8e70
--- /dev/null
+++ b/gnu/usr.bin/man/lib/gripes.c
@@ -0,0 +1,180 @@
+/*
+ * gripes.c
+ *
+ * Copyright (c) 1990, 1991, John W. Eaton.
+ *
+ * You may distribute under the terms of the GNU General Public
+ * License as specified in the file COPYING that comes with the man
+ * distribution.
+ *
+ * John W. Eaton
+ * jwe@che.utexas.edu
+ * Department of Chemical Engineering
+ * The University of Texas at Austin
+ * Austin, Texas 78712
+ */
+
+#include <stdio.h>
+#include "gripes.h"
+
+#ifdef STDC_HEADERS
+#include <stdlib.h>
+#else
+extern int fprintf ();
+extern int fflush ();
+extern int exit ();
+#endif
+
+extern char *prognam;
+
+void
+gripe_no_name (section)
+ char *section;
+{
+ if (section)
+ fprintf (stderr, "What manual page do you want from section %s?\n",
+ section);
+ else
+ fprintf (stderr, "What manual page do you want?\n");
+
+ fflush (stderr);
+}
+
+void
+gripe_reading_man_file (name)
+ char *name;
+{
+ fprintf (stderr, "Read access denied for file %s\n", name);
+
+ fflush (stderr);
+}
+
+void
+gripe_converting_name (name, to_cat)
+ char *name;
+ int to_cat;
+{
+ if (to_cat)
+ fprintf (stderr, "Error converting %s to cat name\n", name);
+ else
+ fprintf (stderr, "Error converting %s to man name\n", name);
+
+ fflush (stderr);
+
+ exit (1);
+}
+
+void
+gripe_system_command (status)
+ int status;
+{
+ fprintf (stderr, "Error executing formatting or display command.\n");
+ fprintf (stderr, "system command exited with status %d\n", status);
+
+ fflush (stderr);
+}
+
+void
+gripe_not_found (name, section)
+ char *name, *section;
+{
+ if (section)
+ fprintf (stderr, "No entry for %s in section %s of the manual\n",
+ name, section);
+ else
+ fprintf (stderr, "No manual entry for %s\n", name);
+
+ fflush (stderr);
+}
+
+void
+gripe_incompatible (s)
+ char *s;
+{
+ fprintf (stderr, "%s: incompatible options %s\n", prognam, s);
+
+ fflush (stderr);
+
+ exit (1);
+}
+
+void
+gripe_getting_mp_config (file)
+ char *file;
+{
+ fprintf (stderr, "%s: unable to find the file %s\n", prognam, file);
+
+ fflush (stderr);
+
+ exit (1);
+}
+
+void
+gripe_reading_mp_config (file)
+ char *file;
+{
+ fprintf (stderr, "%s: unable to make sense of the file %s\n", prognam, file);
+
+ fflush (stderr);
+
+ exit (1);
+}
+
+void
+gripe_invalid_section (section)
+ char *section;
+{
+ fprintf (stderr, "%s: invalid section (%s) selected\n", prognam, section);
+
+ fflush (stderr);
+
+ exit (1);
+}
+
+void
+gripe_manpath ()
+{
+ fprintf (stderr, "%s: manpath is null\n", prognam);
+
+ fflush (stderr);
+
+ exit (1);
+}
+
+void
+gripe_alloc (bytes, object)
+ int bytes;
+ char *object;
+{
+ fprintf (stderr, "%s: can't malloc %d bytes for %s\n",
+ prognam, bytes, object);
+
+ fflush (stderr);
+
+ exit (1);
+}
+
+void
+gripe_roff_command_from_file (file)
+ char *file;
+{
+ fprintf (stderr, "Error parsing *roff command from file %s\n", file);
+
+ fflush (stderr);
+}
+
+void
+gripe_roff_command_from_env ()
+{
+ fprintf (stderr, "Error parsing MANROFFSEQ. Using system defaults.\n");
+
+ fflush (stderr);
+}
+
+void
+gripe_roff_command_from_command_line ()
+{
+ fprintf (stderr, "Error parsing *roff command from command line.\n");
+
+ fflush (stderr);
+}
diff --git a/gnu/usr.bin/man/lib/gripes.h b/gnu/usr.bin/man/lib/gripes.h
new file mode 100644
index 0000000..e3be4a0
--- /dev/null
+++ b/gnu/usr.bin/man/lib/gripes.h
@@ -0,0 +1,30 @@
+/*
+ * gripes.h
+ *
+ * Copyright (c) 1990, 1991, John W. Eaton.
+ *
+ * You may distribute under the terms of the GNU General Public
+ * License as specified in the file COPYING that comes with the man
+ * distribution.
+ *
+ * John W. Eaton
+ * jwe@che.utexas.edu
+ * Department of Chemical Engineering
+ * The University of Texas at Austin
+ * Austin, Texas 78712
+ */
+
+extern void gripe_no_name ();
+extern void gripe_converting_name ();
+extern void gripe_system_command ();
+extern void gripe_reading_man_file ();
+extern void gripe_not_found ();
+extern void gripe_invalid_section ();
+extern void gripe_manpath ();
+extern void gripe_alloc ();
+extern void gripe_incompatible ();
+extern void gripe_getting_mp_config ();
+extern void gripe_reading_mp_config ();
+extern void gripe_roff_command_from_file ();
+extern void gripe_roff_command_from_env ();
+extern void gripe_roff_command_from_command_line ();
diff --git a/gnu/usr.bin/man/lib/util.c b/gnu/usr.bin/man/lib/util.c
new file mode 100644
index 0000000..b0babed
--- /dev/null
+++ b/gnu/usr.bin/man/lib/util.c
@@ -0,0 +1,150 @@
+/*
+ * util.c
+ *
+ * Copyright (c) 1990, 1991, John W. Eaton.
+ *
+ * You may distribute under the terms of the GNU General Public
+ * License as specified in the file COPYING that comes with the man
+ * distribution.
+ *
+ * John W. Eaton
+ * jwe@che.utexas.edu
+ * Department of Chemical Engineering
+ * The University of Texas at Austin
+ * Austin, Texas 78712
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#ifdef STDC_HEADERS
+#include <stdlib.h>
+#else
+extern int fprintf ();
+extern int tolower ();
+#endif
+
+extern char *strdup ();
+extern int system ();
+
+#include "gripes.h"
+
+/*
+ * Extract last element of a name like /foo/bar/baz.
+ */
+char *
+mkprogname (s)
+ register char *s;
+{
+ char *t;
+
+ t = strrchr (s, '/');
+ if (t == (char *)NULL)
+ t = s;
+ else
+ t++;
+
+ return strdup (t);
+}
+
+void
+downcase (s)
+ char *s;
+{
+ register char c;
+ while ((c = *s) != '\0')
+ {
+ if (isalpha (c))
+ *s++ = tolower (c);
+ }
+}
+
+/*
+ * Is file a newer than file b?
+ *
+ * case:
+ *
+ * a newer than b returns 1
+ * a older than b returns 0
+ * stat on a fails returns -1
+ * stat on b fails returns -2
+ * stat on a and b fails returns -3
+ */
+int
+is_newer (fa, fb)
+ register char *fa;
+ register char *fb;
+{
+ struct stat fa_sb;
+ struct stat fb_sb;
+ register int fa_stat;
+ register int fb_stat;
+ register int status = 0;
+
+ fa_stat = stat (fa, &fa_sb);
+ if (fa_stat != 0)
+ status = 1;
+
+ fb_stat = stat (fb, &fb_sb);
+ if (fb_stat != 0)
+ status |= 2;
+
+ if (status != 0)
+ return -status;
+
+ return (fa_sb.st_mtime > fb_sb.st_mtime);
+}
+
+/*
+ * Is path a directory?
+ */
+int
+is_directory (path)
+ char *path;
+{
+ struct stat sb;
+ register int status;
+
+ status = stat (path, &sb);
+
+ if (status != 0)
+ return -1;
+
+ return ((sb.st_mode & S_IFDIR) == S_IFDIR);
+
+}
+
+/*
+ * Attempt a system () call. Return 1 for success and 0 for failure
+ * (handy for counting successes :-).
+ */
+int
+do_system_command (command)
+ char *command;
+{
+ int status = 0;
+ extern int debug;
+
+ /*
+ * If we're debugging, don't really execute the command -- you never
+ * know what might be in that mangled string :-O.
+ */
+ if (debug)
+ fprintf (stderr, "\ntrying command: %s\n", command);
+ else
+ status = system (command);
+
+ /*
+ * Ultrix returns 127 for failure. Is this normal?
+ */
+ if (status == 127)
+ {
+ gripe_system_command (status);
+ return 0;
+ }
+ else
+ return 1;
+}
diff --git a/gnu/usr.bin/man/makewhatis/Makefile b/gnu/usr.bin/man/makewhatis/Makefile
new file mode 100644
index 0000000..8c26f08
--- /dev/null
+++ b/gnu/usr.bin/man/makewhatis/Makefile
@@ -0,0 +1,17 @@
+.include "../Makefile.inc"
+
+all: makewhatis
+
+obj depend rcsfreeze all:
+ @echo -n
+
+cleandir: clean
+
+clean:
+ @rm -f makewhatis
+
+install:
+ install -c -o bin -g bin -m 444 makewhatis /usr/bin
+
+makewhatis: makewhatis.sh
+ sed -e 's/%sections%/ "1", "n", "l", "6", "8", "2", "3", "4", "5", "7", "p", "o", NULL/' makewhatis.sh > makewhatis
diff --git a/gnu/usr.bin/man/makewhatis/makewhatis b/gnu/usr.bin/man/makewhatis/makewhatis
new file mode 100644
index 0000000..e6c238c
--- /dev/null
+++ b/gnu/usr.bin/man/makewhatis/makewhatis
@@ -0,0 +1,79 @@
+#!/bin/sh
+#
+# makewhatis -- update the whatis database in the man directories.
+#
+# Copyright (c) 1990, 1991, John W. Eaton.
+#
+# You may distribute under the terms of the GNU General Public
+# License as specified in the README file that comes with the man
+# distribution.
+#
+# John W. Eaton
+# jwe@che.utexas.edu
+# Department of Chemical Engineering
+# The University of Texas at Austin
+# Austin, Texas 78712
+
+PATH=/bin:/usr/local/bin:/usr/ucb:/usr/bin
+
+if [ $# = 0 ]
+then
+ echo "usage: makewhatis directory [...]"
+ exit 1
+fi
+
+for dir in $*
+do
+ cd $dir
+ for subdir in man*
+ do
+ if [ -d $subdir ]
+ then
+ for f in `find . -name '*' -print`
+ do
+ sed -n '/^\.TH.*$/p
+ /^\.SH[ ]*NAME/,/^\.SH/p' $f |\
+ sed -e 's/\\[ ]*\-/-/
+ s/^.PP.*$//
+ s/\\(em//
+ s/\\fI//
+ s/\\fR//' |\
+ awk 'BEGIN {insh = 0} {
+ if ($1 == ".TH")
+ sect = $3
+ else if ($1 == ".SH" && insh == 1) {
+ if (i > 0 && name != NULL) {
+ namesect = sprintf("%s (%s)", name, sect)
+ printf("%-20.20s", namesect)
+ printf(" - ")
+ for (j = 0; j < i-1; j++)
+ printf("%s ", desc[j])
+ printf("%s\n", desc[i-1])
+ }
+ } else if ($1 == ".SH" && insh == 0) {
+ insh = 1
+ count = 0
+ i = 0
+ } else if (insh == 1) {
+ count++
+ if (count == 1 && NF > 2) {
+ start = 2
+ if ($2 == "-") start = 3
+ if (NF > start + 1)
+ for (j = start; j <= NF; j++)
+ desc[i++] = $j
+ name = $1
+ } else {
+ for (j = 1; j <= NF; j++)
+ desc[i++] = $j
+ }
+ }
+ }'
+ done
+ cd ..
+ fi
+ done | sort | colrm 80 > $dir/whatis.db.tmp
+ mv $dir/whatis.db.tmp $dir/whatis
+done
+
+exit
diff --git a/gnu/usr.bin/man/makewhatis/makewhatis.sh b/gnu/usr.bin/man/makewhatis/makewhatis.sh
new file mode 100644
index 0000000..e6c238c
--- /dev/null
+++ b/gnu/usr.bin/man/makewhatis/makewhatis.sh
@@ -0,0 +1,79 @@
+#!/bin/sh
+#
+# makewhatis -- update the whatis database in the man directories.
+#
+# Copyright (c) 1990, 1991, John W. Eaton.
+#
+# You may distribute under the terms of the GNU General Public
+# License as specified in the README file that comes with the man
+# distribution.
+#
+# John W. Eaton
+# jwe@che.utexas.edu
+# Department of Chemical Engineering
+# The University of Texas at Austin
+# Austin, Texas 78712
+
+PATH=/bin:/usr/local/bin:/usr/ucb:/usr/bin
+
+if [ $# = 0 ]
+then
+ echo "usage: makewhatis directory [...]"
+ exit 1
+fi
+
+for dir in $*
+do
+ cd $dir
+ for subdir in man*
+ do
+ if [ -d $subdir ]
+ then
+ for f in `find . -name '*' -print`
+ do
+ sed -n '/^\.TH.*$/p
+ /^\.SH[ ]*NAME/,/^\.SH/p' $f |\
+ sed -e 's/\\[ ]*\-/-/
+ s/^.PP.*$//
+ s/\\(em//
+ s/\\fI//
+ s/\\fR//' |\
+ awk 'BEGIN {insh = 0} {
+ if ($1 == ".TH")
+ sect = $3
+ else if ($1 == ".SH" && insh == 1) {
+ if (i > 0 && name != NULL) {
+ namesect = sprintf("%s (%s)", name, sect)
+ printf("%-20.20s", namesect)
+ printf(" - ")
+ for (j = 0; j < i-1; j++)
+ printf("%s ", desc[j])
+ printf("%s\n", desc[i-1])
+ }
+ } else if ($1 == ".SH" && insh == 0) {
+ insh = 1
+ count = 0
+ i = 0
+ } else if (insh == 1) {
+ count++
+ if (count == 1 && NF > 2) {
+ start = 2
+ if ($2 == "-") start = 3
+ if (NF > start + 1)
+ for (j = start; j <= NF; j++)
+ desc[i++] = $j
+ name = $1
+ } else {
+ for (j = 1; j <= NF; j++)
+ desc[i++] = $j
+ }
+ }
+ }'
+ done
+ cd ..
+ fi
+ done | sort | colrm 80 > $dir/whatis.db.tmp
+ mv $dir/whatis.db.tmp $dir/whatis
+done
+
+exit
diff --git a/gnu/usr.bin/man/man/Makefile b/gnu/usr.bin/man/man/Makefile
new file mode 100644
index 0000000..d116ad9
--- /dev/null
+++ b/gnu/usr.bin/man/man/Makefile
@@ -0,0 +1,14 @@
+PROG= man
+SRCS= man.c manpath.c glob.c
+MAN1= man.1
+LDADD+= -L${.CURDIR}/../lib -lman
+
+CFLAGS+= -I${.CURDIR}/../lib -DSTDC_HEADERS -DPOSIX -DHAS_TROFF -DDO_UNCOMPRESS -DALT_SYSTEMS
+
+man.1: man.man
+ sed -e 's,%libdir%,${libdir},' -e 's,%bindir%,${bindir},' \
+ -e 's,%pager%,${pager},' -e 's,%troff%,${troff},' \
+ -e 's,%manpath_config_file%,${manpath_config_file},' \
+ man.man > man.1
+
+.include <bsd.prog.mk>
diff --git a/gnu/usr.bin/man/man/glob.c b/gnu/usr.bin/man/man/glob.c
new file mode 100644
index 0000000..5bfb1bf
--- /dev/null
+++ b/gnu/usr.bin/man/man/glob.c
@@ -0,0 +1,680 @@
+/* File-name wildcard pattern matching for GNU.
+ Copyright (C) 1985, 1988, 1989, 1990, 1991 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 1, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+/* To whomever it may concern: I have never seen the code which most
+ Unix programs use to perform this function. I wrote this from scratch
+ based on specifications for the pattern matching. --RMS. */
+
+#ifdef SHELL
+#include "config.h"
+#endif /* SHELL */
+
+#include <sys/types.h>
+
+#if defined (USGr3) && !defined (DIRENT)
+#define DIRENT
+#endif /* USGr3 */
+#if defined (Xenix) && !defined (SYSNDIR)
+#define SYSNDIR
+#endif /* Xenix */
+
+#if defined (POSIX) || defined (DIRENT) || defined (__GNU_LIBRARY__)
+#include <dirent.h>
+#define direct dirent
+#define D_NAMLEN(d) strlen((d)->d_name)
+#else /* not POSIX or DIRENT or __GNU_LIBRARY__ */
+#define D_NAMLEN(d) ((d)->d_namlen)
+#ifdef USG
+#if defined (SYSNDIR)
+#include <sys/ndir.h>
+#else /* SYSNDIR */
+#include "ndir.h"
+#endif /* not SYSNDIR */
+#else /* not USG */
+#include <sys/dir.h>
+#endif /* USG */
+#endif /* POSIX or DIRENT or __GNU_LIBRARY__ */
+
+#if defined (_POSIX_SOURCE)
+/* Posix does not require that the d_ino field be present, and some
+ systems do not provide it. */
+#define REAL_DIR_ENTRY(dp) 1
+#else
+#define REAL_DIR_ENTRY(dp) (dp->d_ino != 0)
+#endif /* _POSIX_SOURCE */
+
+#if defined (STDC_HEADERS) || defined (__GNU_LIBRARY__)
+#include <stdlib.h>
+#include <string.h>
+#define STDC_STRINGS
+#else /* STDC_HEADERS or __GNU_LIBRARY__ */
+
+#if defined (USG)
+#include <string.h>
+#ifndef POSIX
+#include <memory.h>
+#endif /* POSIX */
+#define STDC_STRINGS
+#else /* not USG */
+#ifdef NeXT
+#include <string.h>
+#else /* NeXT */
+#include <strings.h>
+#endif /* NeXT */
+/* Declaring bcopy causes errors on systems whose declarations are different.
+ If the declaration is omitted, everything works fine. */
+#endif /* not USG */
+
+extern char *malloc ();
+extern char *realloc ();
+extern void free ();
+
+#ifndef NULL
+#define NULL 0
+#endif
+#endif /* Not STDC_HEADERS or __GNU_LIBRARY__. */
+
+#ifdef STDC_STRINGS
+#define bcopy(s, d, n) memcpy ((d), (s), (n))
+#define index strchr
+#define rindex strrchr
+#endif /* STDC_STRINGS */
+
+#ifndef alloca
+#ifdef __GNUC__
+#define alloca __builtin_alloca
+#else /* Not GCC. */
+#ifdef sparc
+#include <alloca.h>
+#else /* Not sparc. */
+extern char *alloca ();
+#endif /* sparc. */
+#endif /* GCC. */
+#endif
+
+/* Nonzero if '*' and '?' do not match an initial '.' for glob_filename. */
+int noglob_dot_filenames = 1;
+
+static int glob_match_after_star ();
+
+/* Return nonzero if PATTERN has any special globbing chars in it. */
+
+int
+glob_pattern_p (pattern)
+ char *pattern;
+{
+ register char *p = pattern;
+ register char c;
+ int open = 0;
+
+ while ((c = *p++) != '\0')
+ switch (c)
+ {
+ case '?':
+ case '*':
+ return 1;
+
+ case '[': /* Only accept an open brace if there is a close */
+ open++; /* brace to match it. Bracket expressions must be */
+ continue; /* complete, according to Posix.2 */
+ case ']':
+ if (open)
+ return 1;
+ continue;
+
+ case '\\':
+ if (*p++ == '\0')
+ return 0;
+ }
+
+ return 0;
+}
+
+
+/* Match the pattern PATTERN against the string TEXT;
+ return 1 if it matches, 0 otherwise.
+
+ A match means the entire string TEXT is used up in matching.
+
+ In the pattern string, `*' matches any sequence of characters,
+ `?' matches any character, [SET] matches any character in the specified set,
+ [!SET] matches any character not in the specified set.
+
+ A set is composed of characters or ranges; a range looks like
+ character hyphen character (as in 0-9 or A-Z).
+ [0-9a-zA-Z_] is the set of characters allowed in C identifiers.
+ Any other character in the pattern must be matched exactly.
+
+ To suppress the special syntactic significance of any of `[]*?!-\',
+ and match the character exactly, precede it with a `\'.
+
+ If DOT_SPECIAL is nonzero,
+ `*' and `?' do not match `.' at the beginning of TEXT. */
+
+int
+glob_match (pattern, text, dot_special)
+ char *pattern, *text;
+ int dot_special;
+{
+ register char *p = pattern, *t = text;
+ register char c;
+
+ while ((c = *p++) != '\0')
+ switch (c)
+ {
+ case '?':
+ if (*t == '\0' || (dot_special && t == text && *t == '.'))
+ return 0;
+ else
+ ++t;
+ break;
+
+ case '\\':
+ if (*p++ != *t++)
+ return 0;
+ break;
+
+ case '*':
+ if (dot_special && t == text && *t == '.')
+ return 0;
+ return glob_match_after_star (p, t);
+
+ case '[':
+ {
+ register char c1 = *t++;
+ int invert;
+
+ if (c1 == '\0')
+ return 0;
+
+ invert = (*p == '!');
+
+ if (invert)
+ p++;
+
+ c = *p++;
+ while (1)
+ {
+ register char cstart = c, cend = c;
+
+ if (c == '\\')
+ {
+ cstart = *p++;
+ cend = cstart;
+ }
+
+ if (cstart == '\0')
+ return 0; /* Missing ']'. */
+
+ c = *p++;
+
+ if (c == '-')
+ {
+ cend = *p++;
+ if (cend == '\\')
+ cend = *p++;
+ if (cend == '\0')
+ return 0;
+ c = *p++;
+ }
+ if (c1 >= cstart && c1 <= cend)
+ goto match;
+ if (c == ']')
+ break;
+ }
+ if (!invert)
+ return 0;
+ break;
+
+ match:
+ /* Skip the rest of the [...] construct that already matched. */
+ while (c != ']')
+ {
+ if (c == '\0')
+ return 0;
+ c = *p++;
+ if (c == '\0')
+ return 0;
+ if (c == '\\')
+ p++;
+ }
+ if (invert)
+ return 0;
+ break;
+ }
+
+ default:
+ if (c != *t++)
+ return 0;
+ }
+
+ return *t == '\0';
+}
+
+/* Like glob_match, but match PATTERN against any final segment of TEXT. */
+
+static int
+glob_match_after_star (pattern, text)
+ char *pattern, *text;
+{
+ register char *p = pattern, *t = text;
+ register char c, c1;
+
+ while ((c = *p++) == '?' || c == '*')
+ if (c == '?' && *t++ == '\0')
+ return 0;
+
+ if (c == '\0')
+ return 1;
+
+ if (c == '\\')
+ c1 = *p;
+ else
+ c1 = c;
+
+ --p;
+ while (1)
+ {
+ if ((c == '[' || *t == c1) && glob_match (p, t, 0))
+ return 1;
+ if (*t++ == '\0')
+ return 0;
+ }
+}
+
+/* Return a vector of names of files in directory DIR
+ whose names match glob pattern PAT.
+ The names are not in any particular order.
+ Wildcards at the beginning of PAT do not match an initial period
+ if noglob_dot_filenames is nonzero.
+
+ The vector is terminated by an element that is a null pointer.
+
+ To free the space allocated, first free the vector's elements,
+ then free the vector.
+
+ Return NULL if cannot get enough memory to hold the pointer
+ and the names.
+
+ Return -1 if cannot access directory DIR.
+ Look in errno for more information. */
+
+char **
+glob_vector (pat, dir)
+ char *pat;
+ char *dir;
+{
+ struct globval
+ {
+ struct globval *next;
+ char *name;
+ };
+
+ DIR *d;
+ register struct direct *dp;
+ struct globval *lastlink;
+ register struct globval *nextlink;
+ register char *nextname;
+ unsigned int count;
+ int lose;
+ register char **name_vector;
+ register unsigned int i;
+#ifdef ALLOCA_MISSING
+ struct globval *templink;
+#endif
+
+ d = opendir (dir);
+ if (d == NULL)
+ return (char **) -1;
+
+ lastlink = NULL;
+ count = 0;
+ lose = 0;
+
+ /* Scan the directory, finding all names that match.
+ For each name that matches, allocate a struct globval
+ on the stack and store the name in it.
+ Chain those structs together; lastlink is the front of the chain. */
+ while (1)
+ {
+#if defined (SHELL)
+ /* Make globbing interruptible in the bash shell. */
+ extern int interrupt_state;
+
+ if (interrupt_state)
+ {
+ closedir (d);
+ lose = 1;
+ goto lost;
+ }
+#endif /* SHELL */
+
+ dp = readdir (d);
+ if (dp == NULL)
+ break;
+ if (REAL_DIR_ENTRY (dp)
+ && glob_match (pat, dp->d_name, noglob_dot_filenames))
+ {
+#ifdef ALLOCA_MISSING
+ nextlink = (struct globval *) malloc (sizeof (struct globval));
+#else
+ nextlink = (struct globval *) alloca (sizeof (struct globval));
+#endif
+ nextlink->next = lastlink;
+ i = D_NAMLEN (dp) + 1;
+ nextname = (char *) malloc (i);
+ if (nextname == NULL)
+ {
+ lose = 1;
+ break;
+ }
+ lastlink = nextlink;
+ nextlink->name = nextname;
+ bcopy (dp->d_name, nextname, i);
+ count++;
+ }
+ }
+ closedir (d);
+
+ if (!lose)
+ {
+ name_vector = (char **) malloc ((count + 1) * sizeof (char *));
+ lose |= name_vector == NULL;
+ }
+
+ /* Have we run out of memory? */
+#ifdef SHELL
+ lost:
+#endif
+ if (lose)
+ {
+ /* Here free the strings we have got. */
+ while (lastlink)
+ {
+ free (lastlink->name);
+#ifdef ALLOCA_MISSING
+ templink = lastlink->next;
+ free ((char *) lastlink);
+ lastlink = templink;
+#else
+ lastlink = lastlink->next;
+#endif
+ }
+ return NULL;
+ }
+
+ /* Copy the name pointers from the linked list into the vector. */
+ for (i = 0; i < count; ++i)
+ {
+ name_vector[i] = lastlink->name;
+#ifdef ALLOCA_MISSING
+ templink = lastlink->next;
+ free ((char *) lastlink);
+ lastlink = templink;
+#else
+ lastlink = lastlink->next;
+#endif
+ }
+
+ name_vector[count] = NULL;
+ return name_vector;
+}
+
+/* Return a new array, replacing ARRAY, which is the concatenation
+ of each string in ARRAY to DIR.
+ Return NULL if out of memory. */
+
+static char **
+glob_dir_to_array (dir, array)
+ char *dir, **array;
+{
+ register unsigned int i, l;
+ int add_slash = 0;
+ char **result;
+
+ l = strlen (dir);
+ if (l == 0)
+ return array;
+
+ if (dir[l - 1] != '/')
+ add_slash++;
+
+ for (i = 0; array[i] != NULL; i++)
+ ;
+
+ result = (char **) malloc ((i + 1) * sizeof (char *));
+ if (result == NULL)
+ return NULL;
+
+ for (i = 0; array[i] != NULL; i++)
+ {
+ result[i] = (char *) malloc (1 + l + add_slash + strlen (array[i]));
+ if (result[i] == NULL)
+ return NULL;
+ strcpy (result[i], dir);
+ if (add_slash)
+ result[i][l] = '/';
+ strcpy (result[i] + l + add_slash, array[i]);
+ }
+ result[i] = NULL;
+
+ /* Free the input array. */
+ for (i = 0; array[i] != NULL; i++)
+ free (array[i]);
+ free ((char *) array);
+ return result;
+}
+
+/* Do globbing on PATHNAME. Return an array of pathnames that match,
+ marking the end of the array with a null-pointer as an element.
+ If no pathnames match, then the array is empty (first element is null).
+ If there isn't enough memory, then return NULL.
+ If a file system error occurs, return -1; `errno' has the error code.
+
+ Wildcards at the beginning of PAT, or following a slash,
+ do not match an initial period if noglob_dot_filenames is nonzero. */
+
+char **
+glob_filename (pathname)
+ char *pathname;
+{
+ char **result;
+ unsigned int result_size;
+ char *directory_name, *filename;
+ unsigned int directory_len;
+
+ result = (char **) malloc (sizeof (char *));
+ result_size = 1;
+ if (result == NULL)
+ return NULL;
+
+ result[0] = NULL;
+
+ /* Find the filename. */
+ filename = rindex (pathname, '/');
+ if (filename == NULL)
+ {
+ filename = pathname;
+ directory_name = "";
+ directory_len = 0;
+ }
+ else
+ {
+ directory_len = (filename - pathname) + 1;
+#ifdef ALLOCA_MISSING
+ directory_name = (char *) malloc (directory_len + 1);
+#else
+ directory_name = (char *) alloca (directory_len + 1);
+#endif
+ bcopy (pathname, directory_name, directory_len);
+ directory_name[directory_len] = '\0';
+ ++filename;
+ }
+
+ /* If directory_name contains globbing characters, then we
+ have to expand the previous levels. Just recurse. */
+ if (glob_pattern_p (directory_name))
+ {
+ char **directories;
+ register unsigned int i;
+
+ if (directory_name[directory_len - 1] == '/')
+ directory_name[directory_len - 1] = '\0';
+
+ directories = glob_filename (directory_name);
+#ifdef ALLOCA_MISSING
+ free ((char *) directory_name);
+#endif
+ if (directories == NULL)
+ goto memory_error;
+ else if (directories == (char **) -1)
+ return (char **) -1;
+ else if (*directories == NULL)
+ {
+ free ((char *) directories);
+ return (char **) -1;
+ }
+
+ /* We have successfully globbed the preceding directory name.
+ For each name in DIRECTORIES, call glob_vector on it and
+ FILENAME. Concatenate the results together. */
+ for (i = 0; directories[i] != NULL; i++)
+ {
+ char **temp_results = glob_vector (filename, directories[i]);
+ if (temp_results == NULL)
+ goto memory_error;
+ else if (temp_results == (char **) -1)
+ /* This filename is probably not a directory. Ignore it. */
+ ;
+ else
+ {
+ char **array = glob_dir_to_array (directories[i], temp_results);
+ register unsigned int l;
+
+ l = 0;
+ while (array[l] != NULL)
+ ++l;
+
+ result = (char **) realloc (result,
+ (result_size + l) * sizeof (char *));
+ if (result == NULL)
+ goto memory_error;
+
+ for (l = 0; array[l] != NULL; ++l)
+ result[result_size++ - 1] = array[l];
+ result[result_size - 1] = NULL;
+ free ((char *) array);
+ }
+ }
+ /* Free the directories. */
+ for (i = 0; directories[i] != NULL; i++)
+ free (directories[i]);
+ free ((char *) directories);
+
+ return result;
+ }
+
+ /* If there is only a directory name, return it. */
+ if (*filename == '\0')
+ {
+ result = (char **) realloc ((char *) result, 2 * sizeof (char *));
+ if (result != NULL)
+ {
+ result[0] = (char *) malloc (directory_len + 1);
+ if (result[0] == NULL)
+ {
+#ifdef ALLOCA_MISSING
+ free ((char *) directory_name);
+#endif
+ goto memory_error;
+ }
+ bcopy (directory_name, result[0], directory_len + 1);
+ result[1] = NULL;
+ }
+#ifdef ALLOCA_MISSING
+ free ((char *) directory_name);
+#endif
+ return result;
+ }
+ else
+ {
+ /* Otherwise, just return what glob_vector
+ returns appended to the directory name. */
+ char **temp_results = glob_vector (filename,
+ (directory_len == 0
+ ? "." : directory_name));
+
+ if (temp_results == NULL || temp_results == (char **) -1)
+ {
+#ifdef NO_ALLOCA
+ free ((char *) directory_name);
+#endif
+ return temp_results;
+ }
+
+ temp_results = glob_dir_to_array (directory_name, temp_results);
+#ifdef NO_ALLOCA
+ free ((char *) directory_name);
+#endif
+ return temp_results;
+ }
+
+ /* We get to memory error if the program has run out of memory, or
+ if this is the shell, and we have been interrupted. */
+ memory_error:
+ if (result != NULL)
+ {
+ register unsigned int i;
+ for (i = 0; result[i] != NULL; ++i)
+ free (result[i]);
+ free ((char *) result);
+ }
+#if defined (SHELL)
+ {
+ extern int interrupt_state;
+
+ if (interrupt_state)
+ throw_to_top_level ();
+ }
+#endif /* SHELL */
+ return NULL;
+}
+
+#ifdef TEST
+
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ char **value;
+ int i, optind;
+
+ for (optind = 1; optind < argc; optind++)
+ {
+ value = glob_filename (argv[optind]);
+ if (value == NULL)
+ puts ("virtual memory exhausted");
+ else if (value == (char **) -1)
+ perror (argv[optind]);
+ else
+ for (i = 0; value[i] != NULL; i++)
+ puts (value[i]);
+ }
+ exit (0);
+}
+
+#endif /* TEST */
diff --git a/gnu/usr.bin/man/man/man.1 b/gnu/usr.bin/man/man/man.1
new file mode 100644
index 0000000..f17aced
--- /dev/null
+++ b/gnu/usr.bin/man/man/man.1
@@ -0,0 +1,132 @@
+.\" Man page for man
+.\"
+.\" Copyright (c) 1990, 1991, John W. Eaton.
+.\"
+.\" You may distribute under the terms of the GNU General Public
+.\" License as specified in the README file that comes with the man 1.0
+.\" distribution.
+.\"
+.\" John W. Eaton
+.\" jwe@che.utexas.edu
+.\" Department of Chemical Engineering
+.\" The University of Texas at Austin
+.\" Austin, Texas 78712
+.\"
+.TH man 1 "Jan 5, 1991"
+.LO 1
+.SH NAME
+man \- format and display the on-line manual pages
+.SH SYNOPSIS
+man [\-adfhktw] [\-m system] [\-p string] [\-M path] [\-P pager]
+[\-S list] [section] name ...
+.SH DESCRIPTION
+man formats and displays the on-line manual pages. This version knows
+about the MANPATH and PAGER environment variables, so you can have
+your own set(s) of personal man pages and choose whatever program you
+like to display the formatted pages. If section is specified, man
+only looks in that section of the manual. You may also specify the
+order to search the sections for entries and which preprocessors to
+run on the source files via command line options or environment
+variables.
+.SH OPTIONS
+.TP
+.B \-\^M " path"
+Specify an alternate manpath. By default, man uses
+.B manpath
+to determine the path to search. This option overrides the
+.B MANPATH
+environment variable.
+.TP
+.B \-\^P " pager"
+Specify which pager to use. By default, man uses
+.B /usr/local/bin/less -sC,
+This option overrides the
+.B PAGER
+environment variable.
+.TP
+.B \-\^S " list"
+List is a colon separated list of manual sections to search.
+This option overrides the
+.B MANSECT
+environment variable.
+.TP
+.B \-\^a
+By default, man will exit after displaying the first manual page it
+finds. Using this option forces man to display all the manual pages
+that match
+.B name,
+not just the first.
+.TP
+.B \-\^d
+Don't actually display the man pages, but do print gobs of debugging
+information.
+.TP
+.B \-\^f
+Equivalent to
+.B whatis.
+.TP
+.B \-\^h
+Print a one line help message and exit.
+.TP
+.B \-\^k
+Equivalent to
+.B apropos.
+.TP
+.B \-\^m " system"
+Specify an alternate set of man pages to search based on the system
+name given.
+.TP
+.B \-\^p " string"
+Specify the sequence of preprocessors to run before nroff or troff.
+Not all installations will have a full set of preprocessors.
+Some of the preprocessors and the letters used to designate them are:
+eqn (e), grap (g), pic (p), tbl (t), vgrind (v), refer (r).
+This option overrides the
+.B MANROFFSEQ
+environment variable.
+.TP
+.B \-\^t
+Use
+.B /usr/bin/groff -Tps -man
+to format the manual page, passing the output to
+.B stdout.
+The output from
+.B /usr/bin/groff -Tps -man
+may need to be passed through some filter or another before being
+printed.
+.TP
+.B \-\^w
+Don't actually display the man pages, but do print the location(s) of
+the files that would be formatted or displayed.
+.SH ENVIRONMENT
+.TP \w'MANROFFSEQ\ \ 'u
+.B MANPATH
+If
+.B MANPATH
+is set, its value is used as the path to search for manual pages.
+.TP
+.B MANROFFSEQ
+If
+.B MANROFFSEQ
+is set, its value is used to determine the set of preprocessors run
+before running nroff or troff. By default, pages are passed through
+the table preprocessor before nroff.
+.TP
+.B MANSEC
+If
+.B MANSEC
+is set, its value is used to determine which manual sections to search.
+.TP
+.B PAGER
+If
+.B PAGER
+is set, its value is used as the name of the program to use to display
+the man page. By default,
+.B /usr/local/bin/less -sC
+is used.
+.SH "SEE ALSO"
+apropos(1), whatis(1), manpath(1), less(1), groff(1).
+.SH BUGS
+The
+.B \-t
+option only works if a troff-like program is installed.
diff --git a/gnu/usr.bin/man/man/man.c b/gnu/usr.bin/man/man/man.c
new file mode 100644
index 0000000..3983689
--- /dev/null
+++ b/gnu/usr.bin/man/man/man.c
@@ -0,0 +1,1382 @@
+/*
+ * man.c
+ *
+ * Copyright (c) 1990, 1991, John W. Eaton.
+ *
+ * You may distribute under the terms of the GNU General Public
+ * License as specified in the file COPYING that comes with the man
+ * distribution.
+ *
+ * John W. Eaton
+ * jwe@che.utexas.edu
+ * Department of Chemical Engineering
+ * The University of Texas at Austin
+ * Austin, Texas 78712
+ */
+
+#define MAN_MAIN
+
+#include <stdio.h>
+#include <ctype.h>
+#include <string.h>
+#include <sys/file.h>
+#include <signal.h>
+#include "config.h"
+#include "gripes.h"
+#include "version.h"
+
+#ifndef POSIX
+#include <unistd.h>
+#else
+#ifndef R_OK
+#define R_OK 4
+#endif
+#endif
+
+#ifdef SECURE_MAN_UID
+extern uid_t getuid ();
+extern int setuid ();
+#endif
+
+#ifdef STDC_HEADERS
+#include <stdlib.h>
+#else
+extern char *malloc ();
+extern char *getenv ();
+extern void free ();
+extern int system ();
+extern int strcmp ();
+extern int strncmp ();
+extern int exit ();
+extern int fflush ();
+extern int printf ();
+extern int fprintf ();
+extern FILE *fopen ();
+extern int fclose ();
+extern char *sprintf ();
+#endif
+
+extern char *strdup ();
+
+extern char **glob_vector ();
+extern char **glob_filename ();
+extern int access ();
+extern int unlink ();
+extern int system ();
+extern int chmod ();
+extern int is_newer ();
+extern int is_directory ();
+extern int do_system_command ();
+
+char *prognam;
+static char *pager;
+static char *manp;
+static char *manpathlist[MAXDIRS];
+static char *section;
+static char *colon_sep_section_list;
+static char **section_list;
+static char *roff_directive;
+static int apropos;
+static int whatis;
+static int findall;
+static int print_where;
+
+#ifdef ALT_SYSTEMS
+static int alt_system;
+static char *alt_system_name;
+#endif
+
+static int troff = 0;
+
+int debug;
+
+#ifdef HAS_TROFF
+#ifdef ALT_SYSTEMS
+static char args[] = "M:P:S:adfhkm:p:tw?";
+#else
+static char args[] = "M:P:S:adfhkp:tw?";
+#endif
+#else
+#ifdef ALT_SYSTEMS
+static char args[] = "M:P:S:adfhkm:p:w?";
+#else
+static char args[] = "M:P:S:adfhkp:w?";
+#endif
+#endif
+
+int
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ int status = 0;
+ char *nextarg;
+ char *tmp;
+ extern int optind;
+ extern char *mkprogname ();
+ char *is_section ();
+ char **get_section_list ();
+ void man_getopt ();
+ void do_apropos ();
+ void do_whatis ();
+ int man ();
+
+ prognam = mkprogname (argv[0]);
+
+ man_getopt (argc, argv);
+
+ if (optind == argc)
+ gripe_no_name ((char *)NULL);
+
+ section_list = get_section_list ();
+
+ if (optind == argc - 1)
+ {
+ tmp = is_section (argv[optind]);
+
+ if (tmp != NULL)
+ gripe_no_name (tmp);
+ }
+
+ while (optind < argc)
+ {
+ nextarg = argv[optind++];
+
+ /*
+ * See if this argument is a valid section name. If not,
+ * is_section returns NULL.
+ */
+ tmp = is_section (nextarg);
+
+ if (tmp != NULL)
+ {
+ section = tmp;
+
+ if (debug)
+ fprintf (stderr, "\nsection: %s\n", section);
+
+ continue;
+ }
+
+ if (apropos)
+ do_apropos (nextarg);
+ else if (whatis)
+ do_whatis (nextarg);
+ else
+ {
+ status = man (nextarg);
+
+ if (status == 0)
+ gripe_not_found (nextarg, section);
+ }
+ }
+ return status;
+}
+
+void
+usage ()
+{
+ static char usage_string[1024] = "%s, version %s\n\n";
+
+#ifdef HAS_TROFF
+#ifdef ALT_SYSTEMS
+ static char s1[] =
+ "usage: %s [-adfhktw] [section] [-M path] [-P pager] [-S list]\n\
+ [-m system] [-p string] name ...\n\n";
+#else
+ static char s1[] =
+ "usage: %s [-adfhktw] [section] [-M path] [-P pager] [-S list]\n\
+ [-p string] name ...\n\n";
+#endif
+#else
+#ifdef ALT_SYSTEMS
+ static char s1[] =
+ "usage: %s [-adfhkw] [section] [-M path] [-P pager] [-S list]\n\
+ [-m system] [-p string] name ...\n\n";
+#else
+ static char s1[] =
+ "usage: %s [-adfhkw] [section] [-M path] [-P pager] [-S list]\n\
+ [-p string] name ...\n\n";
+#endif
+#endif
+
+static char s2[] = " a : find all matching entries\n\
+ d : print gobs of debugging information\n\
+ f : same as whatis(1)\n\
+ h : print this help message\n\
+ k : same as apropos(1)\n";
+
+#ifdef HAS_TROFF
+ static char s3[] = " t : use troff to format pages for printing\n";
+#endif
+
+ static char s4[] = " w : print location of man page(s) that would be displayed\n\n\
+ M path : set search path for manual pages to `path'\n\
+ P pager : use program `pager' to display pages\n\
+ S list : colon separated section list\n";
+
+#ifdef ALT_SYSTEMS
+ static char s5[] = " m system : search for alternate system's man pages\n";
+#endif
+
+ static char s6[] = " p string : string tells which preprocessors to run\n\
+ e - [n]eqn(1) p - pic(1) t - tbl(1)\n\
+ g - grap(1) r - refer(1) v - vgrind(1)\n";
+
+ strcat (usage_string, s1);
+ strcat (usage_string, s2);
+
+#ifdef HAS_TROFF
+ strcat (usage_string, s3);
+#endif
+
+ strcat (usage_string, s4);
+
+#ifdef ALT_SYSTEMS
+ strcat (usage_string, s5);
+#endif
+
+ strcat (usage_string, s6);
+
+ fprintf (stderr, usage_string, prognam, version, prognam);
+ exit(1);
+}
+
+char **
+add_dir_to_mpath_list (mp, p)
+ char **mp;
+ char *p;
+{
+ int status;
+
+ status = is_directory (p);
+
+ if (status < 0)
+ {
+ fprintf (stderr, "Warning: couldn't stat file %s!\n", p);
+ }
+ else if (status == 0)
+ {
+ fprintf (stderr, "Warning: %s isn't a directory!\n", p);
+ }
+ else if (status == 1)
+ {
+ if (debug)
+ fprintf (stderr, "adding %s to manpathlist\n", p);
+
+ *mp++ = strdup (p);
+ }
+ return mp;
+}
+
+/*
+ * Get options from the command line and user environment.
+ */
+void
+man_getopt (argc, argv)
+ register int argc;
+ register char **argv;
+{
+ register int c;
+ register char *p;
+ register char *end;
+ register char **mp;
+ extern char *optarg;
+ extern int getopt ();
+ extern void downcase ();
+ extern char *manpath ();
+
+ while ((c = getopt (argc, argv, args)) != EOF)
+ {
+ switch (c)
+ {
+ case 'M':
+ manp = strdup (optarg);
+ break;
+ case 'P':
+ pager = strdup (optarg);
+ break;
+ case 'S':
+ colon_sep_section_list = strdup (optarg);
+ break;
+ case 'a':
+ findall++;
+ break;
+ case 'd':
+ debug++;
+ break;
+ case 'f':
+ if (troff)
+ gripe_incompatible ("-f and -t");
+ if (apropos)
+ gripe_incompatible ("-f and -k");
+ if (print_where)
+ gripe_incompatible ("-f and -w");
+ whatis++;
+ break;
+ case 'k':
+ if (troff)
+ gripe_incompatible ("-k and -t");
+ if (whatis)
+ gripe_incompatible ("-k and -f");
+ if (print_where)
+ gripe_incompatible ("-k and -w");
+ apropos++;
+ break;
+#ifdef ALT_SYSTEMS
+ case 'm':
+ alt_system++;
+ alt_system_name = strdup (optarg);
+ break;
+#endif
+ case 'p':
+ roff_directive = strdup (optarg);
+ break;
+#ifdef HAS_TROFF
+ case 't':
+ if (apropos)
+ gripe_incompatible ("-t and -k");
+ if (whatis)
+ gripe_incompatible ("-t and -f");
+ if (print_where)
+ gripe_incompatible ("-t and -w");
+ troff++;
+ break;
+#endif
+ case 'w':
+ if (apropos)
+ gripe_incompatible ("-w and -k");
+ if (whatis)
+ gripe_incompatible ("-w and -f");
+ if (troff)
+ gripe_incompatible ("-w and -t");
+ print_where++;
+ break;
+ case 'h':
+ case '?':
+ default:
+ usage();
+ break;
+ }
+ }
+
+ if (pager == NULL || *pager == '\0')
+ if ((pager = getenv ("PAGER")) == NULL)
+ pager = strdup (PAGER);
+
+ if (debug)
+ fprintf (stderr, "\nusing %s as pager\n", pager);
+
+ if (manp == NULL)
+ {
+ if ((manp = manpath (0)) == NULL)
+ gripe_manpath ();
+
+ if (debug)
+ fprintf (stderr,
+ "\nsearch path for pages determined by manpath is\n%s\n\n",
+ manp);
+ }
+
+#ifdef ALT_SYSTEMS
+ if (alt_system_name == NULL || *alt_system_name == '\0')
+ if ((alt_system_name = getenv ("SYSTEM")) != NULL)
+ alt_system_name = strdup (alt_system_name);
+
+ if (alt_system_name != NULL && *alt_system_name != '\0')
+ downcase (alt_system_name);
+#endif
+
+ /*
+ * Expand the manpath into a list for easier handling.
+ */
+ mp = manpathlist;
+ for (p = manp; ; p = end+1)
+ {
+ if ((end = strchr (p, ':')) != NULL)
+ *end = '\0';
+
+#ifdef ALT_SYSTEMS
+ if (alt_system)
+ {
+ char buf[BUFSIZ];
+
+ if (debug)
+ fprintf (stderr, "Alternate system `%s' specified\n",
+ alt_system_name);
+
+ strcpy (buf, p);
+ strcat (buf, "/");
+ strcat (buf, alt_system_name);
+
+ mp = add_dir_to_mpath_list (mp, buf);
+ }
+ else
+ {
+ mp = add_dir_to_mpath_list (mp, p);
+ }
+#else
+ mp = add_dir_to_mpath_list (mp, p);
+#endif
+ if (end == NULL)
+ break;
+
+ *end = ':';
+ }
+ *mp = NULL;
+}
+
+/*
+ * Check to see if the argument is a valid section number. If the
+ * first character of name is a numeral, or the name matches one of
+ * the sections listed in section_list, we'll assume that it's a section.
+ * The list of sections in config.h simply allows us to specify oddly
+ * named directories like .../man3f. Yuk.
+ */
+char *
+is_section (name)
+ register char *name;
+{
+ register char **vs;
+
+ for (vs = section_list; *vs != NULL; vs++)
+ if ((strcmp (*vs, name) == NULL) || (isdigit (name[0])))
+ return strdup (name);
+
+ return NULL;
+}
+
+/*
+ * Handle the apropos option. Cheat by using another program.
+ */
+void
+do_apropos (name)
+ register char *name;
+{
+ register int len;
+ register char *command;
+
+ len = strlen (APROPOS) + strlen (name) + 2;
+
+ if ((command = (char *) malloc(len)) == NULL)
+ gripe_alloc (len, "command");
+
+ sprintf (command, "%s %s", APROPOS, name);
+
+ (void) do_system_command (command);
+
+ free (command);
+}
+
+/*
+ * Handle the whatis option. Cheat by using another program.
+ */
+void
+do_whatis (name)
+ register char *name;
+{
+ register int len;
+ register char *command;
+
+ len = strlen (WHATIS) + strlen (name) + 2;
+
+ if ((command = (char *) malloc(len)) == NULL)
+ gripe_alloc (len, "command");
+
+ sprintf (command, "%s %s", WHATIS, name);
+
+ (void) do_system_command (command);
+
+ free (command);
+}
+
+/*
+ * Change a name of the form ...man/man1/name.1 to ...man/cat1/name.1
+ * or a name of the form ...man/cat1/name.1 to ...man/man1/name.1
+ */
+char *
+convert_name (name, to_cat)
+ register char *name;
+ register int to_cat;
+{
+ register char *to_name;
+ register char *t1;
+ register char *t2 = NULL;
+
+#ifdef DO_COMPRESS
+ if (to_cat)
+ {
+ int len = strlen (name) + 3;
+ to_name = (char *) malloc (len);
+ if (to_name == NULL)
+ gripe_alloc (len, "to_name");
+ strcpy (to_name, name);
+ strcat (to_name, ".Z");
+ }
+ else
+ to_name = strdup (name);
+#else
+ to_name = strdup (name);
+#endif
+
+ t1 = strrchr (to_name, '/');
+ if (t1 != NULL)
+ {
+ *t1 = NULL;
+ t2 = strrchr (to_name, '/');
+ *t1 = '/';
+ }
+
+ if (t2 == NULL)
+ gripe_converting_name (name, to_cat);
+
+ if (to_cat)
+ {
+ *(++t2) = 'c';
+ *(t2+2) = 't';
+ }
+ else
+ {
+ *(++t2) = 'm';
+ *(t2+2) = 'n';
+ }
+
+ if (debug)
+ fprintf (stderr, "to_name in convert_name () is: %s\n", to_name);
+
+ return to_name;
+}
+
+/*
+ * Try to find the man page corresponding to the given name. The
+ * reason we do this with globbing is because some systems have man
+ * page directories named man3 which contain files with names like
+ * XtPopup.3Xt. Rather than requiring that this program know about
+ * all those possible names, we simply try to match things like
+ * .../man[sect]/name[sect]*. This is *much* easier.
+ *
+ * Note that globbing is only done when the section is unspecified.
+ */
+char **
+glob_for_file (path, section, name, cat)
+ register char *path;
+ register char *section;
+ register char *name;
+ register int cat;
+{
+ char pathname[BUFSIZ];
+ char **gf;
+
+ if (cat)
+ sprintf (pathname, "%s/cat%s/%s.%s*", path, section, name, section);
+ else
+ sprintf (pathname, "%s/man%s/%s.%s*", path, section, name, section);
+
+ if (debug)
+ fprintf (stderr, "globbing %s\n", pathname);
+
+ gf = glob_filename (pathname);
+
+ if ((gf == (char **) -1 || *gf == NULL) && isdigit (*section))
+ {
+ if (cat)
+ sprintf (pathname, "%s/cat%s/%s.%c*", path, section, name, *section);
+ else
+ sprintf (pathname, "%s/man%s/%s.%c*", path, section, name, *section);
+
+ gf = glob_filename (pathname);
+ }
+ return gf;
+}
+
+/*
+ * Return an un-globbed name in the same form as if we were doing
+ * globbing.
+ */
+char **
+make_name (path, section, name, cat)
+ register char *path;
+ register char *section;
+ register char *name;
+ register int cat;
+{
+ register int i = 0;
+ static char *names[3];
+ char buf[BUFSIZ];
+
+ if (cat)
+ sprintf (buf, "%s/cat%s/%s.%s", path, section, name, section);
+ else
+ sprintf (buf, "%s/man%s/%s.%s", path, section, name, section);
+
+ if (access (buf, R_OK) == 0)
+ names[i++] = strdup (buf);
+
+ /*
+ * If we're given a section that looks like `3f', we may want to try
+ * file names like .../man3/foo.3f as well. This seems a bit
+ * kludgey to me, but what the hey...
+ */
+ if (section[1] != '\0')
+ {
+ if (cat)
+ sprintf (buf, "%s/cat%c/%s.%s", path, section[0], name, section);
+ else
+ sprintf (buf, "%s/man%c/%s.%s", path, section[0], name, section);
+
+ if (access (buf, R_OK) == 0)
+ names[i++] = strdup (buf);
+ }
+
+ names[i] = NULL;
+
+ return &names[0];
+}
+
+#ifdef DO_UNCOMPRESS
+char *
+get_expander (file)
+ char *file;
+{
+ char *expander = NULL;
+ int len = strlen (file);
+
+ if (file[len - 2] == '.')
+ {
+ switch (file[len - 1])
+ {
+#ifdef FCAT
+ case 'F':
+ if (strcmp (FCAT, "") != 0)
+ expander = strdup (FCAT);
+ break;
+#endif
+#ifdef YCAT
+ case 'Y':
+ if (strcmp (YCAT, "") != 0)
+ expander = strdup (YCAT);
+ break;
+#endif
+#ifdef ZCAT
+ case 'Z':
+ if (strcmp (ZCAT, "") != 0)
+ expander = strdup (ZCAT);
+ break;
+#endif
+ default:
+ break;
+ }
+ }
+ return expander;
+}
+#endif
+
+/*
+ * Simply display the preformatted page.
+ */
+int
+display_cat_file (file)
+ register char *file;
+{
+ register int found;
+ char command[BUFSIZ];
+
+ found = 0;
+
+ if (access (file, R_OK) == 0)
+ {
+#ifdef DO_UNCOMPRESS
+ char *expander = get_expander (file);
+
+ if (expander != NULL)
+ sprintf (command, "%s %s | %s", expander, file, pager);
+ else
+ sprintf (command, "%s %s", pager, file);
+#else
+ sprintf (command, "%s %s", pager, file);
+#endif
+
+ found = do_system_command (command);
+ }
+ return found;
+}
+
+/*
+ * Try to find the ultimate source file. If the first line of the
+ * current file is not of the form
+ *
+ * .so man3/printf.3s
+ *
+ * the input file name is returned.
+ */
+char *
+ultimate_source (name, path)
+ char *name;
+ char *path;
+{
+ FILE *fp;
+ char buf[BUFSIZ];
+ char ult[BUFSIZ];
+ char *beg;
+ char *end;
+
+ strcpy (ult, name);
+ strcpy (buf, name);
+
+ next:
+
+ if ((fp = fopen (ult, "r")) == NULL)
+ return buf;
+
+ if (fgets (buf, BUFSIZ, fp) == NULL)
+ return ult;
+
+ if (strlen (buf) < 5)
+ return ult;
+
+ beg = buf;
+ if (*beg++ == '.' && *beg++ == 's' && *beg++ == 'o')
+ {
+ while ((*beg == ' ' || *beg == '\t') && *beg != '\0')
+ beg++;
+
+ end = beg;
+ while (*end != ' ' && *end != '\t' && *end != '\n' && *end != '\0')
+ end++;
+
+ *end = '\0';
+
+ strcpy (ult, path);
+ strcat (ult, "/");
+ strcat (ult, beg);
+
+ strcpy (buf, ult);
+
+ goto next;
+ }
+
+ if (debug)
+ fprintf (stderr, "found ultimate source file %s\n", ult);
+
+ return ult;
+}
+
+void
+add_directive (first, d, file, buf)
+ int *first;
+ char *d;
+ char *file;
+ char *buf;
+{
+ if (strcmp (d, "") != 0)
+ {
+ if (*first)
+ {
+ *first = 0;
+ strcpy (buf, d);
+ strcat (buf, " ");
+ strcat (buf, file);
+ }
+ else
+ {
+ strcat (buf, " | ");
+ strcat (buf, d);
+ }
+ }
+}
+
+int
+parse_roff_directive (cp, file, buf)
+ char *cp;
+ char *file;
+ char *buf;
+{
+ char c;
+ int first = 1;
+ int tbl_found = 0;
+
+ while ((c = *cp++) != '\0')
+ {
+ switch (c)
+ {
+ case 'e':
+
+ if (debug)
+ fprintf (stderr, "found eqn(1) directive\n");
+
+ if (troff)
+ add_directive (&first, EQN, file, buf);
+ else
+ add_directive (&first, NEQN, file, buf);
+
+ break;
+
+ case 'g':
+
+ if (debug)
+ fprintf (stderr, "found grap(1) directive\n");
+
+ add_directive (&first, GRAP, file, buf);
+
+ break;
+
+ case 'p':
+
+ if (debug)
+ fprintf (stderr, "found pic(1) directive\n");
+
+ add_directive (&first, PIC, file, buf);
+
+ break;
+
+ case 't':
+
+ if (debug)
+ fprintf (stderr, "found tbl(1) directive\n");
+
+ tbl_found++;
+ add_directive (&first, TBL, file, buf);
+ break;
+
+ case 'v':
+
+ if (debug)
+ fprintf (stderr, "found vgrind(1) directive\n");
+
+ add_directive (&first, VGRIND, file, buf);
+ break;
+
+ case 'r':
+
+ if (debug)
+ fprintf (stderr, "found refer(1) directive\n");
+
+ add_directive (&first, REFER, file, buf);
+ break;
+
+ case ' ':
+ case '\t':
+ case '\n':
+
+ goto done;
+
+ default:
+
+ return -1;
+ }
+ }
+
+ done:
+
+ if (first)
+ return 1;
+
+#ifdef HAS_TROFF
+ if (troff)
+ {
+ strcat (buf, " | ");
+ strcat (buf, TROFF);
+ }
+ else
+#endif
+ {
+ strcat (buf, " | ");
+ strcat (buf, NROFF);
+ }
+
+ if (tbl_found && !troff && strcmp (COL, "") != 0)
+ {
+ strcat (buf, " | ");
+ strcat (buf, COL);
+ }
+
+ return 0;
+}
+
+char *
+make_roff_command (file)
+ char *file;
+{
+ FILE *fp;
+ char line [BUFSIZ];
+ static char buf [BUFSIZ];
+ int status;
+ char *cp;
+
+ if (roff_directive != NULL)
+ {
+ if (debug)
+ fprintf (stderr, "parsing directive from command line\n");
+
+ status = parse_roff_directive (roff_directive, file, buf);
+
+ if (status == 0)
+ return buf;
+
+ if (status == -1)
+ gripe_roff_command_from_command_line (file);
+ }
+
+ if ((fp = fopen (file, "r")) != NULL)
+ {
+ cp = &line[0];
+ fgets (line, 100, fp);
+ if (*cp++ == '\'' && *cp++ == '\\' && *cp++ == '"' && *cp++ == ' ')
+ {
+ if (debug)
+ fprintf (stderr, "parsing directive from file\n");
+
+ status = parse_roff_directive (cp, file, buf);
+
+ fclose (fp);
+
+ if (status == 0)
+ return buf;
+
+ if (status == -1)
+ gripe_roff_command_from_file (file);
+ }
+ }
+ else
+ {
+ /*
+ * Is there really any point in continuing to look for
+ * preprocessor options if we can't even read the man page source?
+ */
+ gripe_reading_man_file (file);
+ return NULL;
+ }
+
+ if ((cp = getenv ("MANROFFSEQ")) != NULL)
+ {
+ if (debug)
+ fprintf (stderr, "parsing directive from environment\n");
+
+ status = parse_roff_directive (cp, file, buf);
+
+ if (status == 0)
+ return buf;
+
+ if (status == -1)
+ gripe_roff_command_from_env ();
+ }
+
+ if (debug)
+ fprintf (stderr, "using default preprocessor sequence\n");
+
+#ifdef HAS_TROFF
+ if (troff)
+ {
+ if (strcmp (TBL, "") != 0)
+ {
+ strcpy (buf, TBL);
+ strcat (buf, " ");
+ strcat (buf, file);
+ strcat (buf, " | ");
+ strcat (buf, TROFF);
+ }
+ else
+ {
+ strcpy (buf, TROFF);
+ strcat (buf, " ");
+ strcat (buf, file);
+ }
+ }
+ else
+#endif
+ {
+ if (strcmp (TBL, "") != 0)
+ {
+ strcpy (buf, TBL);
+ strcat (buf, " ");
+ strcat (buf, file);
+ strcat (buf, " | ");
+ strcat (buf, NROFF);
+ }
+ else
+ {
+ strcpy (buf, NROFF);
+ strcat (buf, " ");
+ strcat (buf, file);
+ }
+
+ if (strcmp (COL, "") != 0)
+ {
+ strcat (buf, " | ");
+ strcat (buf, COL);
+ }
+ }
+ return buf;
+}
+
+/*
+ * Try to format the man page and create a new formatted file. Return
+ * 1 for success and 0 for failure.
+ */
+int
+make_cat_file (path, man_file, cat_file)
+ register char *path;
+ register char *man_file;
+ register char *cat_file;
+{
+ int status;
+ int mode;
+ FILE *fp;
+ char *roff_command;
+ char command[BUFSIZ];
+
+ if ((fp = fopen (cat_file, "w")) != NULL)
+ {
+ fclose (fp);
+ unlink (cat_file);
+
+ roff_command = make_roff_command (man_file, 0);
+ if (roff_command == NULL)
+ return 0;
+ else
+#ifdef DO_COMPRESS
+ sprintf (command, "(cd %s ; %s | %s > %s)", path,
+ roff_command, COMPRESSOR, cat_file);
+#else
+ sprintf (command, "(cd %s ; %s > %s)", path,
+ roff_command, cat_file);
+#endif
+ /*
+ * Don't let the user interrupt the system () call and screw up
+ * the formmatted man page if we're not done yet.
+ */
+ signal (SIGINT, SIG_IGN);
+
+ fprintf (stderr, "Formatting page, please wait...\n");
+
+ status = do_system_command (command);
+
+ if (status == 1)
+ {
+ mode = CATMODE;
+ chmod (cat_file, mode);
+
+ if (debug)
+ fprintf (stderr, "mode of %s is now %o\n", cat_file, mode);
+ }
+
+ signal (SIGINT, SIG_DFL);
+
+ return 1;
+ }
+ else
+ {
+ if (debug)
+ fprintf (stderr, "Couldn't open %s for writing.\n", cat_file);
+
+ return 0;
+ }
+}
+
+/*
+ * Try to format the man page source and save it, then display it. If
+ * that's not possible, try to format the man page source and display
+ * it directly.
+ *
+ * Note that we've already been handed the name of the ultimate source
+ * file at this point.
+ */
+int
+format_and_display (path, man_file, cat_file)
+ register char *path;
+ register char *man_file;
+ register char *cat_file;
+{
+ int status;
+ register int found;
+ char *roff_command;
+ char command[BUFSIZ];
+
+ found = 0;
+
+ if (access (man_file, R_OK) != 0)
+ return 0;
+
+ if (troff)
+ {
+ roff_command = make_roff_command (man_file, 1);
+ if (roff_command == NULL)
+ return 0;
+ else
+ sprintf (command, "(cd %s ; %s)", path, roff_command);
+
+ found = do_system_command (command);
+ }
+ else
+ {
+ status = is_newer (man_file, cat_file);
+ if (debug)
+ fprintf (stderr, "status from is_newer() = %d\n");
+
+ if (status == 1 || status == -2)
+ {
+ /*
+ * Cat file is out of date. Try to format and save it.
+ */
+ if (print_where)
+ {
+ printf ("%s\n", man_file);
+ found++;
+ }
+ else
+ {
+ found = make_cat_file (path, man_file, cat_file);
+#ifdef SECURE_MAN_UID
+ if (!found)
+ {
+ /*
+ * Try again as real user. Note that for private
+ * man pages, we won't even get this far unless the
+ * effective user can read the real user's man page
+ * source. Also, if we are trying to find all the
+ * man pages, this will probably make it impossible
+ * to make cat files in the system directories if
+ * the real user's man directories are searched
+ * first, because there's no way to undo this (is
+ * there?). Yikes, am I missing something obvious?
+ */
+ setuid (getuid ());
+
+ found = make_cat_file (path, man_file, cat_file);
+ }
+#endif
+ if (found)
+ {
+ /*
+ * Creating the cat file worked. Now just display it.
+ */
+ (void) display_cat_file (cat_file);
+ }
+ else
+ {
+ /*
+ * Couldn't create cat file. Just format it and
+ * display it through the pager.
+ */
+ roff_command = make_roff_command (man_file, 0);
+ if (roff_command == NULL)
+ return 0;
+ else
+ sprintf (command, "(cd %s ; %s | %s)", path,
+ roff_command, pager);
+
+ found = do_system_command (command);
+ }
+ }
+ }
+ else if (access (cat_file, R_OK) == 0)
+ {
+ /*
+ * Formatting not necessary. Cat file is newer than source
+ * file, or source file is not present but cat file is.
+ */
+ if (print_where)
+ {
+ printf ("%s (source: %s)\n", cat_file, man_file);
+ found++;
+ }
+ else
+ {
+ found = display_cat_file (cat_file);
+ }
+ }
+ }
+ return found;
+}
+
+/*
+ * See if the preformatted man page or the source exists in the given
+ * section.
+ */
+int
+try_section (path, section, name, glob)
+ register char *path;
+ register char *section;
+ register char *name;
+ register int glob;
+{
+ register int found = 0;
+ register int to_cat;
+ register int cat;
+ register char **names;
+ register char **np;
+
+ if (debug)
+ {
+ if (glob)
+ fprintf (stderr, "trying section %s with globbing\n", section);
+ else
+ fprintf (stderr, "trying section %s without globbing\n", section);
+ }
+
+#ifndef NROFF_MISSING
+ /*
+ * Look for man page source files.
+ */
+ cat = 0;
+ if (glob)
+ names = glob_for_file (path, section, name, cat);
+ else
+ names = make_name (path, section, name, cat);
+
+ if (names == (char **) -1 || *names == NULL)
+ /*
+ * No files match. See if there's a preformatted page around that
+ * we can display.
+ */
+#endif /* NROFF_MISSING */
+ {
+ if (!troff)
+ {
+ cat = 1;
+ if (glob)
+ names = glob_for_file (path, section, name, cat);
+ else
+ names = make_name (path, section, name, cat);
+
+ if (names != (char **) -1 && *names != NULL)
+ {
+ for (np = names; *np != NULL; np++)
+ {
+ if (print_where)
+ {
+ printf ("%s\n", *np);
+ found++;
+ }
+ else
+ {
+ found += display_cat_file (*np);
+ }
+ }
+ }
+ }
+ }
+#ifndef NROFF_MISSING
+ else
+ {
+ for (np = names; *np != NULL; np++)
+ {
+ register char *cat_file = NULL;
+ register char *man_file;
+
+ man_file = ultimate_source (*np, path);
+
+ if (!troff)
+ {
+ to_cat = 1;
+
+ cat_file = convert_name (man_file, to_cat);
+
+ if (debug)
+ fprintf (stderr, "will try to write %s if needed\n", cat_file);
+ }
+
+ found += format_and_display (path, man_file, cat_file);
+ }
+ }
+#endif /* NROFF_MISSING */
+ return found;
+}
+
+/*
+ * Search for manual pages.
+ *
+ * If preformatted manual pages are supported, look for the formatted
+ * file first, then the man page source file. If they both exist and
+ * the man page source file is newer, or only the source file exists,
+ * try to reformat it and write the results in the cat directory. If
+ * it is not possible to write the cat file, simply format and display
+ * the man file.
+ *
+ * If preformatted pages are not supported, or the troff option is
+ * being used, only look for the man page source file.
+ *
+ */
+int
+man (name)
+ char *name;
+{
+ register int found;
+ register int glob;
+ register char **mp;
+ register char **sp;
+
+ found = 0;
+
+ fflush (stdout);
+ if (section != NULL)
+ {
+ for (mp = manpathlist; *mp != NULL; mp++)
+ {
+ if (debug)
+ fprintf (stderr, "\nsearching in %s\n", *mp);
+
+ glob = 0;
+
+ found += try_section (*mp, section, name, glob);
+
+ if (found && !findall) /* i.e. only do this section... */
+ return found;
+ }
+ }
+ else
+ {
+ for (sp = section_list; *sp != NULL; sp++)
+ {
+ for (mp = manpathlist; *mp != NULL; mp++)
+ {
+ if (debug)
+ fprintf (stderr, "\nsearching in %s\n", *mp);
+
+ glob = 1;
+
+ found += try_section (*mp, *sp, name, glob);
+
+ if (found && !findall) /* i.e. only do this section... */
+ return found;
+ }
+ }
+ }
+ return found;
+}
+
+char **
+get_section_list ()
+{
+ int i;
+ char *p;
+ char *end;
+ static char *tmp_section_list[100];
+
+ if (colon_sep_section_list == NULL)
+ {
+ if ((p = getenv ("MANSECT")) == NULL)
+ {
+ return std_sections;
+ }
+ else
+ {
+ colon_sep_section_list = strdup (p);
+ }
+ }
+
+ i = 0;
+ for (p = colon_sep_section_list; ; p = end+1)
+ {
+ if ((end = strchr (p, ':')) != NULL)
+ *end = '\0';
+
+ tmp_section_list[i++] = strdup (p);
+
+ if (end == NULL)
+ break;
+ }
+
+ tmp_section_list [i] = NULL;
+ return tmp_section_list;
+}
diff --git a/gnu/usr.bin/man/man/man.man b/gnu/usr.bin/man/man/man.man
new file mode 100644
index 0000000..2c034fe
--- /dev/null
+++ b/gnu/usr.bin/man/man/man.man
@@ -0,0 +1,132 @@
+.\" Man page for man
+.\"
+.\" Copyright (c) 1990, 1991, John W. Eaton.
+.\"
+.\" You may distribute under the terms of the GNU General Public
+.\" License as specified in the README file that comes with the man 1.0
+.\" distribution.
+.\"
+.\" John W. Eaton
+.\" jwe@che.utexas.edu
+.\" Department of Chemical Engineering
+.\" The University of Texas at Austin
+.\" Austin, Texas 78712
+.\"
+.TH man 1 "Jan 5, 1991"
+.LO 1
+.SH NAME
+man \- format and display the on-line manual pages
+.SH SYNOPSIS
+man [\-adfhktw] [\-m system] [\-p string] [\-M path] [\-P pager]
+[\-S list] [section] name ...
+.SH DESCRIPTION
+man formats and displays the on-line manual pages. This version knows
+about the MANPATH and PAGER environment variables, so you can have
+your own set(s) of personal man pages and choose whatever program you
+like to display the formatted pages. If section is specified, man
+only looks in that section of the manual. You may also specify the
+order to search the sections for entries and which preprocessors to
+run on the source files via command line options or environment
+variables.
+.SH OPTIONS
+.TP
+.B \-\^M " path"
+Specify an alternate manpath. By default, man uses
+.B manpath
+to determine the path to search. This option overrides the
+.B MANPATH
+environment variable.
+.TP
+.B \-\^P " pager"
+Specify which pager to use. By default, man uses
+.B %pager%,
+This option overrides the
+.B PAGER
+environment variable.
+.TP
+.B \-\^S " list"
+List is a colon separated list of manual sections to search.
+This option overrides the
+.B MANSECT
+environment variable.
+.TP
+.B \-\^a
+By default, man will exit after displaying the first manual page it
+finds. Using this option forces man to display all the manual pages
+that match
+.B name,
+not just the first.
+.TP
+.B \-\^d
+Don't actually display the man pages, but do print gobs of debugging
+information.
+.TP
+.B \-\^f
+Equivalent to
+.B whatis.
+.TP
+.B \-\^h
+Print a one line help message and exit.
+.TP
+.B \-\^k
+Equivalent to
+.B apropos.
+.TP
+.B \-\^m " system"
+Specify an alternate set of man pages to search based on the system
+name given.
+.TP
+.B \-\^p " string"
+Specify the sequence of preprocessors to run before nroff or troff.
+Not all installations will have a full set of preprocessors.
+Some of the preprocessors and the letters used to designate them are:
+eqn (e), grap (g), pic (p), tbl (t), vgrind (v), refer (r).
+This option overrides the
+.B MANROFFSEQ
+environment variable.
+.TP
+.B \-\^t
+Use
+.B %troff%
+to format the manual page, passing the output to
+.B stdout.
+The output from
+.B %troff%
+may need to be passed through some filter or another before being
+printed.
+.TP
+.B \-\^w
+Don't actually display the man pages, but do print the location(s) of
+the files that would be formatted or displayed.
+.SH ENVIRONMENT
+.TP \w'MANROFFSEQ\ \ 'u
+.B MANPATH
+If
+.B MANPATH
+is set, its value is used as the path to search for manual pages.
+.TP
+.B MANROFFSEQ
+If
+.B MANROFFSEQ
+is set, its value is used to determine the set of preprocessors run
+before running nroff or troff. By default, pages are passed through
+the table preprocessor before nroff.
+.TP
+.B MANSEC
+If
+.B MANSEC
+is set, its value is used to determine which manual sections to search.
+.TP
+.B PAGER
+If
+.B PAGER
+is set, its value is used as the name of the program to use to display
+the man page. By default,
+.B %pager%
+is used.
+.SH "SEE ALSO"
+apropos(1), whatis(1), manpath(1), less(1), groff(1).
+.SH BUGS
+The
+.B \-t
+option only works if a troff-like program is installed.
diff --git a/gnu/usr.bin/man/man/manpath.c b/gnu/usr.bin/man/man/manpath.c
new file mode 100644
index 0000000..ccf7a55
--- /dev/null
+++ b/gnu/usr.bin/man/man/manpath.c
@@ -0,0 +1,520 @@
+/*
+ * manpath.c
+ *
+ * Copyright (c) 1990, 1991, John W. Eaton.
+ *
+ * You may distribute under the terms of the GNU General Public
+ * License as specified in the file COPYING that comes with the man
+ * distribution.
+ *
+ * John W. Eaton
+ * jwe@che.utexas.edu
+ * Department of Chemical Engineering
+ * The University of Texas at Austin
+ * Austin, Texas 78712
+ */
+
+#define MANPATH_MAIN
+
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include "config.h"
+#include "manpath.h"
+#include "gripes.h"
+
+#ifdef STDC_HEADERS
+#include <stdlib.h>
+#else
+extern int fprintf ();
+extern int strcmp ();
+extern int strncmp ();
+extern char *memcpy ();
+extern char *getenv();
+extern char *malloc();
+extern void free ();
+extern int exit ();
+#endif
+
+extern char *strdup ();
+extern int is_directory ();
+
+#ifndef MAIN
+extern int debug;
+#endif
+
+#ifdef MAIN
+
+#ifndef STDC_HEADERS
+extern char *strcpy ();
+extern int fflush ();
+#endif
+
+char *prognam;
+int debug;
+
+/*
+ * Examine user's PATH and print a reasonable MANPATH.
+ */
+int
+main(argc, argv)
+ int argc;
+ char **argv;
+{
+ int c;
+ int quiet;
+ char *mp;
+ extern int getopt ();
+ extern char *mkprogname ();
+ void usage ();
+ char *manpath ();
+
+ quiet = 1;
+
+ prognam = mkprogname (argv[0]);
+
+ while ((c = getopt (argc, argv, "dhq?")) != EOF)
+ {
+ switch (c)
+ {
+ case 'd':
+ debug++;
+ break;
+ case 'q':
+ quiet = 0;
+ break;
+ case '?':
+ case 'h':
+ default:
+ usage();
+ break;
+ }
+ }
+
+ mp = manpath (quiet);
+
+ fprintf (stdout, "%s\n", mp);
+ fflush (stdout);
+
+ return 0;
+}
+
+void
+usage ()
+{
+ fprintf (stderr, "usage: %s [-q]\n", prognam);
+ exit (1);
+}
+#endif /* MAIN */
+
+/*
+ * If the environment variable MANPATH is set, return it.
+ * If the environment variable PATH is set and has a nonzero length,
+ * try to determine the corresponding manpath, otherwise, return the
+ * default manpath.
+ *
+ * The manpath.config file is used to map system wide /bin directories
+ * to top level man page directories.
+ *
+ * For directories which are in the user's path but not in the
+ * manpath.config file, see if there is a subdirectory `man' or `MAN'.
+ * If so, add that directory to the path. Example: user has
+ * $HOME/bin in his path and the directory $HOME/bin/man exists -- the
+ * directory $HOME/bin/man will be added to the manpath.
+ */
+char *
+manpath (perrs)
+ register int perrs;
+{
+ register int len;
+ register char *manpathlist;
+ register char *path;
+ int get_dirlist ();
+ char *def_path ();
+ char *get_manpath ();
+
+ if (get_dirlist ())
+ gripe_reading_mp_config ();
+
+ if ((manpathlist = getenv ("MANPATH")) != NULL)
+ /*
+ * This must be it.
+ */
+ {
+ if (perrs)
+ fprintf (stderr, "(Warning: MANPATH environment variable set)\n");
+ return strdup (manpathlist);
+ }
+ else if ((path = getenv ("PATH")) == NULL)
+ /*
+ * Things aren't going to work well, but hey...
+ */
+ {
+ if (perrs)
+ fprintf (stderr, "Warning: path not set\n");
+ return def_path (perrs);
+ }
+ else
+ {
+ if ((len = strlen (path)) == 0)
+ /*
+ * Things aren't going to work well here either...
+ */
+ {
+ if (perrs)
+ fprintf (stderr, "Warning: path set but has zero length\n");
+ return def_path (perrs);
+ }
+ return get_manpath (perrs, path);
+ }
+}
+
+/*
+ * Get the list of bin directories and the corresponding man
+ * directories from the manpath.config file.
+ *
+ * This is ugly.
+ */
+int
+get_dirlist ()
+{
+ int i;
+ char *bp;
+ char *p;
+ char buf[BUFSIZ];
+ DIRLIST *dlp = list;
+ FILE *config;
+
+ if ((config = fopen (config_file, "r")) == NULL)
+ gripe_getting_mp_config (config_file);
+
+ while ((bp = fgets (buf, BUFSIZ, config)) != NULL)
+ {
+ while (*bp && (*bp == ' ' || *bp == '\t'))
+ bp++;
+
+ if (*bp == '#' || *bp == '\n')
+ continue;
+
+ if (!strncmp ("MANBIN", bp, 6))
+ continue;
+
+ if (!strncmp ("MANDATORY_MANPATH", bp, 17))
+ {
+ if ((p = strchr (bp, ' ')) == NULL)
+ if ((p = strchr (bp, '\t')) == NULL)
+ return -1;
+
+ bp = p;
+
+ dlp->mandatory = 1;
+
+ while (*bp && *bp != '\n' && (*bp == ' ' || *bp == '\t'))
+ bp++;
+
+ i = 0;
+ while (*bp && *bp != '\n' && *bp != ' ' && *bp != '\t')
+ dlp->mandir[i++] = *bp++;
+ dlp->mandir[i] = '\0';
+
+ if (debug)
+ fprintf (stderr, "found mandatory man directory %s\n",
+ dlp->mandir);
+ }
+ else if (!strncmp ("MANPATH_MAP", bp, 11))
+ {
+ if ((p = strchr (bp, ' ')) == NULL)
+ if ((p = strchr (bp, '\t')) == NULL)
+ return -1;
+
+ bp = p;
+
+ dlp->mandatory = 0;
+
+ while (*bp && *bp != '\n' && (*bp == ' ' || *bp == '\t'))
+ bp++;
+
+ i = 0;
+ while (*bp && *bp != '\n' && *bp != ' ' && *bp != '\t')
+ dlp->bin[i++] = *bp++;
+ dlp->bin[i] = '\0';
+
+ while (*bp && *bp != '\n' && (*bp == ' ' || *bp == '\t'))
+ bp++;
+
+ i = 0;
+ while (*bp && *bp != '\n' && *bp != ' ' && *bp != '\t')
+ dlp->mandir[i++] = *bp++;
+ dlp->mandir[i] = '\0';
+
+ if (debug)
+ fprintf (stderr, "found manpath map %s --> %s\n",
+ dlp->bin, dlp->mandir);
+ }
+ else
+ {
+ gripe_reading_mp_config ();
+ }
+ dlp++;
+ }
+
+ dlp->bin[0] = '\0';
+ dlp->mandir[0] = '\0';
+ dlp->mandatory = 0;
+
+ return 0;
+}
+
+/*
+ * Construct the default manpath. This picks up mandatory manpaths
+ * only.
+ */
+char *
+def_path (perrs)
+ int perrs;
+{
+ register int len;
+ register char *manpathlist, *p;
+ register DIRLIST *dlp;
+
+ len = 0;
+ dlp = list;
+ while (dlp->mandatory != 0)
+ {
+ len += strlen (dlp->mandir) + 1;
+ dlp++;
+ }
+
+ manpathlist = (char *) malloc (len);
+ if (manpathlist == NULL)
+ gripe_alloc (len, "manpathlist");
+
+ *manpathlist = '\0';
+
+ dlp = list;
+ p = manpathlist;
+ while (dlp->mandatory != 0)
+ {
+ int status;
+ char *path = dlp->mandir;
+
+ status = is_directory(path);
+
+ if (status < 0 && perrs)
+ {
+ fprintf (stderr, "Warning: couldn't stat file %s!\n", path);
+ }
+ else if (status == 0 && perrs)
+ {
+ fprintf (stderr, "Warning: standard directory %s doesn't exist!\n",
+ path);
+ }
+ else if (status == 1)
+ {
+ len = strlen (path);
+ memcpy (p, path, len);
+ p += len;
+ *p++ = ':';
+ dlp++;
+ }
+ }
+
+ p[-1] = '\0';
+
+ return manpathlist;
+}
+
+/*
+ * For each directory in the user's path, see if it is one of the
+ * directories listed in the manpath.config file. If so, and it is
+ * not already in the manpath, add it. If the directory is not listed
+ * in the manpath.config file, see if there is a subdirectory `man' or
+ * `MAN'. If so, and it is not already in the manpath, add it.
+ * Example: user has $HOME/bin in his path and the directory
+ * $HOME/bin/man exists -- the directory $HOME/bin/man will be added
+ * to the manpath.
+ */
+char *
+get_manpath (perrs, path)
+ register int perrs;
+ register char *path;
+{
+ register int len;
+ register char *tmppath;
+ register char *t;
+ register char *p;
+ register char **lp;
+ register char *end;
+ register char *manpathlist;
+ register DIRLIST *dlp;
+ void add_dir_to_list ();
+ char *has_subdirs ();
+
+ tmppath = strdup (path);
+
+ for (p = tmppath; ; p = end+1)
+ {
+ if (end = strchr(p, ':'))
+ *end = '\0';
+
+ if (debug)
+ fprintf (stderr, "\npath directory %s ", p);
+
+ /*
+ * The directory we're working on is in the config file.
+ * If we haven't added it to the list yet, do.
+ */
+ for (dlp = list; dlp->mandir[0] != '\0'; dlp++)
+ if (dlp->bin[0] != '\0' && !strcmp (p, dlp->bin))
+ {
+ if (debug)
+ fprintf (stderr, "is in the config file\n");
+
+ add_dir_to_list (tmplist, dlp->mandir, perrs);
+ goto found;
+ }
+
+ /*
+ * The directory we're working on isn't in the config file. See
+ * if it has man or MAN subdirectories. If so, and it hasn't
+ * been added to the list, do.
+ */
+ if (debug)
+ fprintf (stderr, "is not in the config file\n");
+
+ t = has_subdirs (p);
+ if (t != NULL)
+ {
+ if (debug)
+ fprintf (stderr, "but it does have a man or MAN subdirectory\n");
+
+ add_dir_to_list (tmplist, t, perrs);
+ free (t);
+ }
+ else
+ {
+ if (debug)
+ fprintf (stderr, "and doesn't have man or MAN subdirectories\n");
+ }
+
+ found:
+
+ if (!end)
+ break;
+ }
+
+ if (debug)
+ fprintf (stderr, "\nadding mandatory man directories\n\n");
+
+ dlp = list;
+ while (dlp->mandatory != 0)
+ {
+ add_dir_to_list (tmplist, dlp->mandir, perrs);
+ dlp++;
+ }
+
+ len = 0;
+ lp = tmplist;
+ while (*lp != NULL)
+ {
+ len += strlen (*lp) + 1;
+ lp++;
+ }
+
+ manpathlist = (char *) malloc (len);
+ if (manpathlist == NULL)
+ gripe_alloc (len, "manpathlist");
+
+ *manpathlist = '\0';
+
+ lp = tmplist;
+ p = manpathlist;
+ while (*lp != NULL)
+ {
+ len = strlen (*lp);
+ memcpy (p, *lp, len);
+ p += len;
+ *p++ = ':';
+ lp++;
+ }
+
+ p[-1] = '\0';
+
+ return manpathlist;
+}
+
+/*
+ * Add a directory to the manpath list if it isn't already there.
+ */
+void
+add_dir_to_list (lp, dir, perrs)
+ char **lp;
+ char *dir;
+ int perrs;
+{
+ extern char *strdup ();
+ int status;
+
+ while (*lp != NULL)
+ {
+ if (!strcmp (*lp, dir))
+ {
+ if (debug)
+ fprintf (stderr, "%s is already in the manpath\n", dir);
+ return;
+ }
+ lp++;
+ }
+ /*
+ * Not found -- add it.
+ */
+ status = is_directory(dir);
+
+ if (status < 0 && perrs)
+ {
+ fprintf (stderr, "Warning: couldn't stat file %s!\n", dir);
+ }
+ else if (status == 0 && perrs)
+ {
+ fprintf (stderr, "Warning: %s isn't a directory!\n", dir);
+ }
+ else if (status == 1)
+ {
+ if (debug)
+ fprintf (stderr, "adding %s to manpath\n", dir);
+
+ *lp = strdup (dir);
+ }
+}
+
+/*
+ * Check to see if the current directory has man or MAN
+ * subdirectories.
+ */
+char *
+has_subdirs (p)
+ register char *p;
+{
+ int len;
+ register char *t;
+
+ len = strlen (p);
+
+ t = (char *) malloc ((unsigned) len + 5);
+ if (t == NULL)
+ gripe_alloc (len+5, "p\n");
+
+ memcpy (t, p, len);
+ strcpy (t + len, "/man");
+
+ if (is_directory (t) == 1)
+ return t;
+
+ strcpy (t + len, "/MAN");
+
+ if (is_directory (t) == 1)
+ return t;
+
+ return NULL;
+}
diff --git a/gnu/usr.bin/man/man/manpath.h b/gnu/usr.bin/man/man/manpath.h
new file mode 100644
index 0000000..a61761f
--- /dev/null
+++ b/gnu/usr.bin/man/man/manpath.h
@@ -0,0 +1,26 @@
+/*
+ * manpath.h
+ *
+ * Copyright (c) 1990, 1991, John W. Eaton.
+ *
+ * You may distribute under the terms of the GNU General Public
+ * License as specified in the file COPYING that comes with the man
+ * distribution.
+ *
+ * John W. Eaton
+ * jwe@che.utexas.edu
+ * Department of Chemical Engineering
+ * The University of Texas at Austin
+ * Austin, Texas 78712
+ */
+
+typedef struct
+{
+ char mandir[MAXPATHLEN];
+ char bin[MAXPATHLEN];
+ int mandatory;
+} DIRLIST;
+
+DIRLIST list[MAXDIRS];
+
+char *tmplist[MAXDIRS];
diff --git a/gnu/usr.bin/man/man/ndir.h b/gnu/usr.bin/man/man/ndir.h
new file mode 100644
index 0000000..438d5c2
--- /dev/null
+++ b/gnu/usr.bin/man/man/ndir.h
@@ -0,0 +1,51 @@
+/*
+ <dir.h> -- definitions for 4.2BSD-compatible directory access
+
+ last edit: 09-Jul-1983 D A Gwyn
+*/
+
+#ifdef VMS
+#ifndef FAB$C_BID
+#include <fab.h>
+#endif
+#ifndef NAM$C_BID
+#include <nam.h>
+#endif
+#ifndef RMS$_SUC
+#include <rmsdef.h>
+#endif
+#include "dir.h"
+#endif /* VMS */
+
+#define DIRBLKSIZ 512 /* size of directory block */
+#ifdef VMS
+#define MAXNAMLEN (DIR$S_NAME + 7) /* 80 plus room for version #. */
+#define MAXFULLSPEC NAM$C_MAXRSS /* Maximum full spec */
+#else
+#define MAXNAMLEN 15 /* maximum filename length */
+#endif /* VMS */
+ /* NOTE: MAXNAMLEN must be one less than a multiple of 4 */
+
+struct direct /* data from readdir() */
+ {
+ long d_ino; /* inode number of entry */
+ unsigned short d_reclen; /* length of this record */
+ unsigned short d_namlen; /* length of string in d_name */
+ char d_name[MAXNAMLEN+1]; /* name of file */
+ };
+
+typedef struct
+ {
+ int dd_fd; /* file descriptor */
+ int dd_loc; /* offset in block */
+ int dd_size; /* amount of valid data */
+ char dd_buf[DIRBLKSIZ]; /* directory block */
+ } DIR; /* stream data from opendir() */
+
+extern DIR *opendir();
+extern struct direct *readdir();
+extern long telldir();
+extern void seekdir();
+extern void closedir();
+
+#define rewinddir( dirp ) seekdir( dirp, 0L )
diff --git a/gnu/usr.bin/man/man/strdup.c b/gnu/usr.bin/man/man/strdup.c
new file mode 100644
index 0000000..4e5af07
--- /dev/null
+++ b/gnu/usr.bin/man/man/strdup.c
@@ -0,0 +1,39 @@
+/* strdup.c -- return a newly allocated copy of a string
+ Copyright (C) 1990 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#ifdef STDC_HEADERS
+#include <string.h>
+#include <stdlib.h>
+#else
+char *malloc ();
+char *strcpy ();
+#endif
+
+/* Return a newly allocated copy of STR,
+ or 0 if out of memory. */
+
+char *
+strdup (str)
+ char *str;
+{
+ char *newstr;
+
+ newstr = (char *) malloc (strlen (str) + 1);
+ if (newstr)
+ strcpy (newstr, str);
+ return newstr;
+}
diff --git a/gnu/usr.bin/man/man/version.h b/gnu/usr.bin/man/man/version.h
new file mode 100644
index 0000000..4d9eb63
--- /dev/null
+++ b/gnu/usr.bin/man/man/version.h
@@ -0,0 +1,17 @@
+/*
+ * version.h
+ *
+ * Copyright (c) 1990, 1991, John W. Eaton.
+ *
+ * You may distribute under the terms of the GNU General Public
+ * License as specified in the file COPYING that comes with the man
+ * distribution.
+ *
+ * John W. Eaton
+ * jwe@che.utexas.edu
+ * Department of Chemical Engineering
+ * The University of Texas at Austin
+ * Austin, Texas 78712
+ */
+
+static char version[] = "1.1";
diff --git a/gnu/usr.bin/man/manpath/Makefile b/gnu/usr.bin/man/manpath/Makefile
new file mode 100644
index 0000000..81897ab
--- /dev/null
+++ b/gnu/usr.bin/man/manpath/Makefile
@@ -0,0 +1,14 @@
+PROG= manpath
+MAN1= manpath.1
+SRCS= manpath.c
+LDADD+= -L${.CURDIR}/../lib -lman
+
+CFLAGS+= -I${.CURDIR}/../lib -DMAIN -DSTDC_HEADERS -DPOSIX -DHAS_TROFF -DDO_UNCOMPRESS -DALT_SYSTEMS
+
+manpath.1: manpath.man
+ sed -e 's,%libdir%,${libdir},' -e 's,%bindir%,${bindir},' \
+ -e 's,%pager%,${pager},' -e 's,%troff%,${troff},' \
+ -e 's,%manpath_config_file%,${manpath_config_file},' \
+ manpath.man > manpath.1
+
+.include <bsd.prog.mk>
diff --git a/gnu/usr.bin/man/manpath/manpath.c b/gnu/usr.bin/man/manpath/manpath.c
new file mode 100644
index 0000000..ccf7a55
--- /dev/null
+++ b/gnu/usr.bin/man/manpath/manpath.c
@@ -0,0 +1,520 @@
+/*
+ * manpath.c
+ *
+ * Copyright (c) 1990, 1991, John W. Eaton.
+ *
+ * You may distribute under the terms of the GNU General Public
+ * License as specified in the file COPYING that comes with the man
+ * distribution.
+ *
+ * John W. Eaton
+ * jwe@che.utexas.edu
+ * Department of Chemical Engineering
+ * The University of Texas at Austin
+ * Austin, Texas 78712
+ */
+
+#define MANPATH_MAIN
+
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include "config.h"
+#include "manpath.h"
+#include "gripes.h"
+
+#ifdef STDC_HEADERS
+#include <stdlib.h>
+#else
+extern int fprintf ();
+extern int strcmp ();
+extern int strncmp ();
+extern char *memcpy ();
+extern char *getenv();
+extern char *malloc();
+extern void free ();
+extern int exit ();
+#endif
+
+extern char *strdup ();
+extern int is_directory ();
+
+#ifndef MAIN
+extern int debug;
+#endif
+
+#ifdef MAIN
+
+#ifndef STDC_HEADERS
+extern char *strcpy ();
+extern int fflush ();
+#endif
+
+char *prognam;
+int debug;
+
+/*
+ * Examine user's PATH and print a reasonable MANPATH.
+ */
+int
+main(argc, argv)
+ int argc;
+ char **argv;
+{
+ int c;
+ int quiet;
+ char *mp;
+ extern int getopt ();
+ extern char *mkprogname ();
+ void usage ();
+ char *manpath ();
+
+ quiet = 1;
+
+ prognam = mkprogname (argv[0]);
+
+ while ((c = getopt (argc, argv, "dhq?")) != EOF)
+ {
+ switch (c)
+ {
+ case 'd':
+ debug++;
+ break;
+ case 'q':
+ quiet = 0;
+ break;
+ case '?':
+ case 'h':
+ default:
+ usage();
+ break;
+ }
+ }
+
+ mp = manpath (quiet);
+
+ fprintf (stdout, "%s\n", mp);
+ fflush (stdout);
+
+ return 0;
+}
+
+void
+usage ()
+{
+ fprintf (stderr, "usage: %s [-q]\n", prognam);
+ exit (1);
+}
+#endif /* MAIN */
+
+/*
+ * If the environment variable MANPATH is set, return it.
+ * If the environment variable PATH is set and has a nonzero length,
+ * try to determine the corresponding manpath, otherwise, return the
+ * default manpath.
+ *
+ * The manpath.config file is used to map system wide /bin directories
+ * to top level man page directories.
+ *
+ * For directories which are in the user's path but not in the
+ * manpath.config file, see if there is a subdirectory `man' or `MAN'.
+ * If so, add that directory to the path. Example: user has
+ * $HOME/bin in his path and the directory $HOME/bin/man exists -- the
+ * directory $HOME/bin/man will be added to the manpath.
+ */
+char *
+manpath (perrs)
+ register int perrs;
+{
+ register int len;
+ register char *manpathlist;
+ register char *path;
+ int get_dirlist ();
+ char *def_path ();
+ char *get_manpath ();
+
+ if (get_dirlist ())
+ gripe_reading_mp_config ();
+
+ if ((manpathlist = getenv ("MANPATH")) != NULL)
+ /*
+ * This must be it.
+ */
+ {
+ if (perrs)
+ fprintf (stderr, "(Warning: MANPATH environment variable set)\n");
+ return strdup (manpathlist);
+ }
+ else if ((path = getenv ("PATH")) == NULL)
+ /*
+ * Things aren't going to work well, but hey...
+ */
+ {
+ if (perrs)
+ fprintf (stderr, "Warning: path not set\n");
+ return def_path (perrs);
+ }
+ else
+ {
+ if ((len = strlen (path)) == 0)
+ /*
+ * Things aren't going to work well here either...
+ */
+ {
+ if (perrs)
+ fprintf (stderr, "Warning: path set but has zero length\n");
+ return def_path (perrs);
+ }
+ return get_manpath (perrs, path);
+ }
+}
+
+/*
+ * Get the list of bin directories and the corresponding man
+ * directories from the manpath.config file.
+ *
+ * This is ugly.
+ */
+int
+get_dirlist ()
+{
+ int i;
+ char *bp;
+ char *p;
+ char buf[BUFSIZ];
+ DIRLIST *dlp = list;
+ FILE *config;
+
+ if ((config = fopen (config_file, "r")) == NULL)
+ gripe_getting_mp_config (config_file);
+
+ while ((bp = fgets (buf, BUFSIZ, config)) != NULL)
+ {
+ while (*bp && (*bp == ' ' || *bp == '\t'))
+ bp++;
+
+ if (*bp == '#' || *bp == '\n')
+ continue;
+
+ if (!strncmp ("MANBIN", bp, 6))
+ continue;
+
+ if (!strncmp ("MANDATORY_MANPATH", bp, 17))
+ {
+ if ((p = strchr (bp, ' ')) == NULL)
+ if ((p = strchr (bp, '\t')) == NULL)
+ return -1;
+
+ bp = p;
+
+ dlp->mandatory = 1;
+
+ while (*bp && *bp != '\n' && (*bp == ' ' || *bp == '\t'))
+ bp++;
+
+ i = 0;
+ while (*bp && *bp != '\n' && *bp != ' ' && *bp != '\t')
+ dlp->mandir[i++] = *bp++;
+ dlp->mandir[i] = '\0';
+
+ if (debug)
+ fprintf (stderr, "found mandatory man directory %s\n",
+ dlp->mandir);
+ }
+ else if (!strncmp ("MANPATH_MAP", bp, 11))
+ {
+ if ((p = strchr (bp, ' ')) == NULL)
+ if ((p = strchr (bp, '\t')) == NULL)
+ return -1;
+
+ bp = p;
+
+ dlp->mandatory = 0;
+
+ while (*bp && *bp != '\n' && (*bp == ' ' || *bp == '\t'))
+ bp++;
+
+ i = 0;
+ while (*bp && *bp != '\n' && *bp != ' ' && *bp != '\t')
+ dlp->bin[i++] = *bp++;
+ dlp->bin[i] = '\0';
+
+ while (*bp && *bp != '\n' && (*bp == ' ' || *bp == '\t'))
+ bp++;
+
+ i = 0;
+ while (*bp && *bp != '\n' && *bp != ' ' && *bp != '\t')
+ dlp->mandir[i++] = *bp++;
+ dlp->mandir[i] = '\0';
+
+ if (debug)
+ fprintf (stderr, "found manpath map %s --> %s\n",
+ dlp->bin, dlp->mandir);
+ }
+ else
+ {
+ gripe_reading_mp_config ();
+ }
+ dlp++;
+ }
+
+ dlp->bin[0] = '\0';
+ dlp->mandir[0] = '\0';
+ dlp->mandatory = 0;
+
+ return 0;
+}
+
+/*
+ * Construct the default manpath. This picks up mandatory manpaths
+ * only.
+ */
+char *
+def_path (perrs)
+ int perrs;
+{
+ register int len;
+ register char *manpathlist, *p;
+ register DIRLIST *dlp;
+
+ len = 0;
+ dlp = list;
+ while (dlp->mandatory != 0)
+ {
+ len += strlen (dlp->mandir) + 1;
+ dlp++;
+ }
+
+ manpathlist = (char *) malloc (len);
+ if (manpathlist == NULL)
+ gripe_alloc (len, "manpathlist");
+
+ *manpathlist = '\0';
+
+ dlp = list;
+ p = manpathlist;
+ while (dlp->mandatory != 0)
+ {
+ int status;
+ char *path = dlp->mandir;
+
+ status = is_directory(path);
+
+ if (status < 0 && perrs)
+ {
+ fprintf (stderr, "Warning: couldn't stat file %s!\n", path);
+ }
+ else if (status == 0 && perrs)
+ {
+ fprintf (stderr, "Warning: standard directory %s doesn't exist!\n",
+ path);
+ }
+ else if (status == 1)
+ {
+ len = strlen (path);
+ memcpy (p, path, len);
+ p += len;
+ *p++ = ':';
+ dlp++;
+ }
+ }
+
+ p[-1] = '\0';
+
+ return manpathlist;
+}
+
+/*
+ * For each directory in the user's path, see if it is one of the
+ * directories listed in the manpath.config file. If so, and it is
+ * not already in the manpath, add it. If the directory is not listed
+ * in the manpath.config file, see if there is a subdirectory `man' or
+ * `MAN'. If so, and it is not already in the manpath, add it.
+ * Example: user has $HOME/bin in his path and the directory
+ * $HOME/bin/man exists -- the directory $HOME/bin/man will be added
+ * to the manpath.
+ */
+char *
+get_manpath (perrs, path)
+ register int perrs;
+ register char *path;
+{
+ register int len;
+ register char *tmppath;
+ register char *t;
+ register char *p;
+ register char **lp;
+ register char *end;
+ register char *manpathlist;
+ register DIRLIST *dlp;
+ void add_dir_to_list ();
+ char *has_subdirs ();
+
+ tmppath = strdup (path);
+
+ for (p = tmppath; ; p = end+1)
+ {
+ if (end = strchr(p, ':'))
+ *end = '\0';
+
+ if (debug)
+ fprintf (stderr, "\npath directory %s ", p);
+
+ /*
+ * The directory we're working on is in the config file.
+ * If we haven't added it to the list yet, do.
+ */
+ for (dlp = list; dlp->mandir[0] != '\0'; dlp++)
+ if (dlp->bin[0] != '\0' && !strcmp (p, dlp->bin))
+ {
+ if (debug)
+ fprintf (stderr, "is in the config file\n");
+
+ add_dir_to_list (tmplist, dlp->mandir, perrs);
+ goto found;
+ }
+
+ /*
+ * The directory we're working on isn't in the config file. See
+ * if it has man or MAN subdirectories. If so, and it hasn't
+ * been added to the list, do.
+ */
+ if (debug)
+ fprintf (stderr, "is not in the config file\n");
+
+ t = has_subdirs (p);
+ if (t != NULL)
+ {
+ if (debug)
+ fprintf (stderr, "but it does have a man or MAN subdirectory\n");
+
+ add_dir_to_list (tmplist, t, perrs);
+ free (t);
+ }
+ else
+ {
+ if (debug)
+ fprintf (stderr, "and doesn't have man or MAN subdirectories\n");
+ }
+
+ found:
+
+ if (!end)
+ break;
+ }
+
+ if (debug)
+ fprintf (stderr, "\nadding mandatory man directories\n\n");
+
+ dlp = list;
+ while (dlp->mandatory != 0)
+ {
+ add_dir_to_list (tmplist, dlp->mandir, perrs);
+ dlp++;
+ }
+
+ len = 0;
+ lp = tmplist;
+ while (*lp != NULL)
+ {
+ len += strlen (*lp) + 1;
+ lp++;
+ }
+
+ manpathlist = (char *) malloc (len);
+ if (manpathlist == NULL)
+ gripe_alloc (len, "manpathlist");
+
+ *manpathlist = '\0';
+
+ lp = tmplist;
+ p = manpathlist;
+ while (*lp != NULL)
+ {
+ len = strlen (*lp);
+ memcpy (p, *lp, len);
+ p += len;
+ *p++ = ':';
+ lp++;
+ }
+
+ p[-1] = '\0';
+
+ return manpathlist;
+}
+
+/*
+ * Add a directory to the manpath list if it isn't already there.
+ */
+void
+add_dir_to_list (lp, dir, perrs)
+ char **lp;
+ char *dir;
+ int perrs;
+{
+ extern char *strdup ();
+ int status;
+
+ while (*lp != NULL)
+ {
+ if (!strcmp (*lp, dir))
+ {
+ if (debug)
+ fprintf (stderr, "%s is already in the manpath\n", dir);
+ return;
+ }
+ lp++;
+ }
+ /*
+ * Not found -- add it.
+ */
+ status = is_directory(dir);
+
+ if (status < 0 && perrs)
+ {
+ fprintf (stderr, "Warning: couldn't stat file %s!\n", dir);
+ }
+ else if (status == 0 && perrs)
+ {
+ fprintf (stderr, "Warning: %s isn't a directory!\n", dir);
+ }
+ else if (status == 1)
+ {
+ if (debug)
+ fprintf (stderr, "adding %s to manpath\n", dir);
+
+ *lp = strdup (dir);
+ }
+}
+
+/*
+ * Check to see if the current directory has man or MAN
+ * subdirectories.
+ */
+char *
+has_subdirs (p)
+ register char *p;
+{
+ int len;
+ register char *t;
+
+ len = strlen (p);
+
+ t = (char *) malloc ((unsigned) len + 5);
+ if (t == NULL)
+ gripe_alloc (len+5, "p\n");
+
+ memcpy (t, p, len);
+ strcpy (t + len, "/man");
+
+ if (is_directory (t) == 1)
+ return t;
+
+ strcpy (t + len, "/MAN");
+
+ if (is_directory (t) == 1)
+ return t;
+
+ return NULL;
+}
diff --git a/gnu/usr.bin/man/manpath/manpath.config b/gnu/usr.bin/man/manpath/manpath.config
new file mode 100644
index 0000000..b9c1171
--- /dev/null
+++ b/gnu/usr.bin/man/manpath/manpath.config
@@ -0,0 +1,30 @@
+# manpath.config
+#
+# This file is read by manpath to configure the mandatory manpath, to
+# map each path element to a manpath element and to determine where the
+# "man" binary lives. The format is:
+#
+# MANBIN pathname
+# MANDATORY_MANPATH manpath_element
+# MANPATH_MAP path_element manpath_element
+#
+# MANBIN is optional
+#
+#MANBIN /usr/local/bin/man
+#
+# every automatically generated MANPATH includes these fields
+#
+MANDATORY_MANPATH /usr/share/man
+MANDATORY_MANPATH /usr/local/man
+MANDATORY_MANPATH /usr/X386/man
+MANDATORY_MANPATH /usr/gnu/man
+#
+# set up PATH to MANPATH mapping
+#
+MANPATH_MAP /bin /usr/share/man
+MANPATH_MAP /usr/bin /usr/share/man
+MANPATH_MAP /usr/ucb /usr/share/man
+MANPATH_MAP /usr/local/mh /usr/local/mh/man
+MANPATH_MAP /usr/local/bin /usr/local/man
+MANPATH_MAP /usr/gnu /usr/gnu/man
+MANPATH_MAP /usr/X386 /usr/X386/man
diff --git a/gnu/usr.bin/man/manpath/manpath.h b/gnu/usr.bin/man/manpath/manpath.h
new file mode 100644
index 0000000..a61761f
--- /dev/null
+++ b/gnu/usr.bin/man/manpath/manpath.h
@@ -0,0 +1,26 @@
+/*
+ * manpath.h
+ *
+ * Copyright (c) 1990, 1991, John W. Eaton.
+ *
+ * You may distribute under the terms of the GNU General Public
+ * License as specified in the file COPYING that comes with the man
+ * distribution.
+ *
+ * John W. Eaton
+ * jwe@che.utexas.edu
+ * Department of Chemical Engineering
+ * The University of Texas at Austin
+ * Austin, Texas 78712
+ */
+
+typedef struct
+{
+ char mandir[MAXPATHLEN];
+ char bin[MAXPATHLEN];
+ int mandatory;
+} DIRLIST;
+
+DIRLIST list[MAXDIRS];
+
+char *tmplist[MAXDIRS];
diff --git a/gnu/usr.bin/man/manpath/manpath.man b/gnu/usr.bin/man/manpath/manpath.man
new file mode 100644
index 0000000..9212324
--- /dev/null
+++ b/gnu/usr.bin/man/manpath/manpath.man
@@ -0,0 +1,56 @@
+.\" Man page for manpath
+.\"
+.\" Copyright (c) 1990, 1991, John W. Eaton.
+.\"
+.\" You may distribute under the terms of the GNU General Public
+.\" License as specified in the README file that comes with the man 1.0
+.\" distribution.
+.\"
+.\" John W. Eaton
+.\" jwe@che.utexas.edu
+.\" Department of Chemical Engineering
+.\" The University of Texas at Austin
+.\" Austin, Texas 78712
+.\"
+.TH manpath 1 "Jan 5, 1991"
+.LO 1
+.SH NAME
+manpath \- determine user's search path for man pages
+.SH SYNOPSIS
+manpath [\-q]
+.SH DESCRIPTION
+manpath tries to determine the user's manpath from a set of system
+defaults and the user's
+.B PATH ,
+echoing the result to the standard output. Warnings and errors are
+written to the standard error.
+If a directory in the user's path is not listed in the manpath.config
+file, manpath looks for the subdirectories man or MAN. If they exist,
+they are added to the search path.
+.PP
+manpath is used by
+.B man
+to determine the search path, so user's normally don't need to set the
+.B MANPATH
+environment variable directly.
+.SH OPTIONS
+.TP
+.B \-\^q
+Operate quietly. Only echo the final manpath.
+.SH ENVIRONMENT
+.TP \w'MANPATH\ \ 'u
+.B MANPATH
+If
+.B MANPATH
+is set,
+.B manpath
+echoes its value on the standard output and issues a warning on the
+standard error.
+.SH FILES
+.TP \w'%manpath_config_file%'u+2n
+.BI %manpath_config_file%
+System configuration file.
+.SH "SEE ALSO"
+apropos(1), whatis(1), man(1).
+.SH BUGS
+None known.
diff --git a/gnu/usr.bin/man/whatis/Makefile b/gnu/usr.bin/man/whatis/Makefile
new file mode 100644
index 0000000..1e9c1c1
--- /dev/null
+++ b/gnu/usr.bin/man/whatis/Makefile
@@ -0,0 +1,26 @@
+.include "../Makefile.inc"
+
+all: whatis whatis.1
+
+obj depend rcsfreeze all:
+ @echo -n
+
+cleandir: clean
+
+clean:
+ @rm -f whatis whatis.1
+
+whatis: whatis.sh
+ sed -e 's,%libdir%,${libdir},' -e 's,%bindir%,${bindir},' \
+ -e 's,%pager%,${pager},' \
+ whatis.sh > whatis
+
+whatis.1: whatis.man
+ sed -e 's,%libdir%,${libdir},' -e 's,%bindir%,${bindir},' \
+ -e 's,%pager%,${pager},' -e 's,%troff%,${troff},' \
+ -e 's,%manpath_config_file%,${manpath_config_file},' \
+ whatis.man > whatis.1
+
+install: whatis whatis.1
+ install -c -o bin -g bin -m 555 whatis /usr/bin
+ install -c -o bin -g bin -m 444 whatis.1 /usr/share/man/man1
diff --git a/gnu/usr.bin/man/whatis/whatis b/gnu/usr.bin/man/whatis/whatis
new file mode 100644
index 0000000..e8cae0a
--- /dev/null
+++ b/gnu/usr.bin/man/whatis/whatis
@@ -0,0 +1,66 @@
+#!/bin/sh
+#
+# whatis -- search the whatis database for keywords. Like apropos,
+# but match only commands (as whole words).
+#
+# Copyright (c) 1990, 1991, John W. Eaton.
+#
+# You may distribute under the terms of the GNU General Public
+# License as specified in the README file that comes with the man
+# distribution.
+#
+# John W. Eaton
+# jwe@che.utexas.edu
+# Department of Chemical Engineering
+# The University of Texas at Austin
+# Austin, Texas 78712
+
+PATH=/usr/local/bin:/bin:/usr/ucb:/usr/bin
+
+libdir=/etc
+
+if [ $# = 0 ]
+then
+ echo "usage: `basename $0` name ..."
+ exit 1
+fi
+
+manpath=`/usr/bin/manpath -q | tr : '\040'`
+
+if [ "$manpath" = "" ]
+then
+ echo "whatis: manpath is null"
+ exit 1
+fi
+
+if [ "$PAGER" = "" ]
+then
+ PAGER="/usr/gnu/bin/less -sC"
+fi
+
+while [ $1 ]
+do
+ found=0
+ for d in $manpath /usr/lib
+ do
+ if [ -f $d/whatis ]
+ then
+ grep -iw "^$1" $d/whatis
+ status=$?
+ if [ "$status" = "0" ]
+ then
+ found=1
+ export found;
+ fi
+ fi
+ done
+
+ if [ "$found" = "0" ]
+ then
+ echo "$1: nothing appropriate"
+ fi
+
+ shift
+done | $PAGER
+
+exit
diff --git a/gnu/usr.bin/man/whatis/whatis.1 b/gnu/usr.bin/man/whatis/whatis.1
new file mode 100644
index 0000000..9e5528d
--- /dev/null
+++ b/gnu/usr.bin/man/whatis/whatis.1
@@ -0,0 +1,27 @@
+.\" Man page for whatis
+.\"
+.\" Copyright (c) 1990, 1991, John W. Eaton.
+.\"
+.\" You may distribute under the terms of the GNU General Public
+.\" License as specified in the README file that comes with the man 1.0
+.\" distribution.
+.\"
+.\" John W. Eaton
+.\" jwe@che.utexas.edu
+.\" Department of Chemical Engineering
+.\" The University of Texas at Austin
+.\" Austin, Texas 78712
+.\"
+.TH whatis 1 "Jan 5, 1991"
+.LO 1
+.SH NAME
+whatis \- search the whatis database for complete words.
+.SH SYNOPSIS
+.BI whatis
+keyword ...
+.SH DESCRIPTION
+whatis searches a set of database files containing short descriptions
+of system commands for keywords and displays the result on the
+standard output. Only complete word matches are displayed.
+.SH "SEE ALSO"
+apropos(1), man(1).
diff --git a/gnu/usr.bin/man/whatis/whatis.man b/gnu/usr.bin/man/whatis/whatis.man
new file mode 100644
index 0000000..9e5528d
--- /dev/null
+++ b/gnu/usr.bin/man/whatis/whatis.man
@@ -0,0 +1,27 @@
+.\" Man page for whatis
+.\"
+.\" Copyright (c) 1990, 1991, John W. Eaton.
+.\"
+.\" You may distribute under the terms of the GNU General Public
+.\" License as specified in the README file that comes with the man 1.0
+.\" distribution.
+.\"
+.\" John W. Eaton
+.\" jwe@che.utexas.edu
+.\" Department of Chemical Engineering
+.\" The University of Texas at Austin
+.\" Austin, Texas 78712
+.\"
+.TH whatis 1 "Jan 5, 1991"
+.LO 1
+.SH NAME
+whatis \- search the whatis database for complete words.
+.SH SYNOPSIS
+.BI whatis
+keyword ...
+.SH DESCRIPTION
+whatis searches a set of database files containing short descriptions
+of system commands for keywords and displays the result on the
+standard output. Only complete word matches are displayed.
+.SH "SEE ALSO"
+apropos(1), man(1).
diff --git a/gnu/usr.bin/man/whatis/whatis.sh b/gnu/usr.bin/man/whatis/whatis.sh
new file mode 100644
index 0000000..34abaaa
--- /dev/null
+++ b/gnu/usr.bin/man/whatis/whatis.sh
@@ -0,0 +1,66 @@
+#!/bin/sh
+#
+# whatis -- search the whatis database for keywords. Like apropos,
+# but match only commands (as whole words).
+#
+# Copyright (c) 1990, 1991, John W. Eaton.
+#
+# You may distribute under the terms of the GNU General Public
+# License as specified in the README file that comes with the man
+# distribution.
+#
+# John W. Eaton
+# jwe@che.utexas.edu
+# Department of Chemical Engineering
+# The University of Texas at Austin
+# Austin, Texas 78712
+
+PATH=/usr/local/bin:/bin:/usr/ucb:/usr/bin
+
+libdir=%libdir%
+
+if [ $# = 0 ]
+then
+ echo "usage: `basename $0` name ..."
+ exit 1
+fi
+
+manpath=`%bindir%/manpath -q | tr : '\040'`
+
+if [ "$manpath" = "" ]
+then
+ echo "whatis: manpath is null"
+ exit 1
+fi
+
+if [ "$PAGER" = "" ]
+then
+ PAGER="%pager%"
+fi
+
+while [ $1 ]
+do
+ found=0
+ for d in $manpath /usr/lib
+ do
+ if [ -f $d/whatis ]
+ then
+ grep -iw "^$1" $d/whatis
+ status=$?
+ if [ "$status" = "0" ]
+ then
+ found=1
+ export found;
+ fi
+ fi
+ done
+
+ if [ "$found" = "0" ]
+ then
+ echo "$1: nothing appropriate"
+ fi
+
+ shift
+done | $PAGER
+
+exit
OpenPOWER on IntegriCloud