If you've ever tried compiling the -current sources from an older OpenBSD release, you're aware that the process isn't always straightforward. This Mini-FAQ is an attempt to address the most common issues encountered when upgrading between OpenBSD releases, or from the releases to -current
4.2.1 - i386 and sparc are no longer #define'ed4.3: My make build dies with unimplemented syscall errors.
4.2.2 - Build fails in xlint
4.2.3 - Core Dump on uthread_autoinit.c
4.2.4 - egcs seems much slower than gcc
4.2.5 - egcs generates larger code than gcc
4.2.6 - After installing egcs I have very little disk space left
4.2.7 - My build fails to build libcurses
4.2.8 - make obj fails
Prior to OpenBSD 2.7, OpenBSD development happened from a single, unbranched source tree. As of 2.7, a patch branch was introduced.
At approximately six-month intervals, OpenBSD releases are produced. These are numbered in the conventional (2.x) manner. The current OpenBSD release is 2.8.
-current, short for openbsd-current, refers to the up-to-the-minute version of the source tree contained in the CVS repository. This is the tree most commonly used by OpenBSD developers. The -current tree contains all the code that is planned for the next release. From time to time, brave souls will abandon the formal releases and run openbsd-current, usually to take advantage of features that have not yet made it into the formal releases. Because of its uncertain nature, however, upgrading to -current is not recommended for non-technical users.
Between formal releases, a series of snapshot releases are made available. Snapshots are test releases of the -current source tree. Because they reflect the current state of development, there is no guarantee that snapshot releases will work correctly (or even at all). Snapshots are quite useful when moving from a formal release (or older version of -current) to the current tree.
As of OpenBSD 2.7, a patch branch (called -stable) was introduced. This branch contains the base release, and any important patches or fixes (important being the errata patches, plus others that are obvious and simple, but do not deserve an errata entry).
Due to changes in the underlying libraries, moving directly from a release to -current is not always easy. The most painless way to move up to -current is to first upgrade to the latest snapshot (usually, via an FTP install). Once the snapshot is installed, the latest source can be fetched and built. This procedure should eliminate most toolchain and library problems.
Snapshots may be removed as they become old (or no longer relevant). If no snapshot is available, you should upgrade to the most recent release and build the remainder of the way from source.
For example. To retrieve the entire tree via CVS: (using the bash shell. Others substitute setenv for export)
# export CVSROOT=anoncvs@anoncvs.ca.openbsd.org:/cvs # export CVS_RSH=/usr/local/bin/ssh # cd /usr # cvs -q get -PA src
Basic instructions are in /usr/src/Makefile. This is a slightly expanded version.
If you created a separate /usr/obj directory, clean that, and rebuild the symbolic links:
# rm -rf /usr/obj # mkdir /usr/obj # cd /usr/src # make objIf you find yourself performing this step a lot, you may find it faster to place /usr/obj onto its own partition, and use newfs instead of rm. For example, I do a:
# umount /dev/wd0h (the /usr/obj partition) # newfs wd0h # mount -a # make objIf you're worried there are object files in your source tree, do this:
# cd /usr/src # find . -type l -name obj | xargs rm # make cleandir # rm -rf /usr/obj # mkdir /usr/obj # make obj
# cd /usr/src/etc && make DESTDIR=/ distrib-dirs
# cd /usr/src/sys/arch/`machine`/conf # cp GENERIC MYKERNEL # vi MYKERNEL (edit MYKERNEL to your liking) # config MYKERNEL # cd ../compile/MYKERNEL # make clean && make depend && make (arc architecture only) copy bsd.ecoff to your FAT partition # cp /bsd /bsd.old && cp bsd /bsd # chown root.wheel /bsd (if you compiled as someone else) (reboot)
# cd /usr/src # make build
# mkdir /home/newroot # export DESTDIR=/home/newroot # cd /usr/src/etc && make distribution-etc-root-varNow compare the files in /home/newroot with their installed counterparts. Replace or update the files as necessary.
# rm -rf /home/newroot (when done)
I would, but if you really want to pick up where you left off, do a:
# cd /usr/src # make -n buildThis will show you what make build is doing. For example, mine tells me:
(cd /usr/src/share/mk && make install) (cd /usr/src/include; make prereq; make includes) make cleandir (cd /usr/src/lib && make depend && make && make install) (cd /usr/src/gnu/lib && make depend && make && make install) (cd /usr/src/kerberosIV/lib && make depend && make && make install) (cd /usr/src/gnu/usr.bin/perl && make -f Makefile.bsd-wrapper config.sh && mak e -f Makefile.bsd-wrapper depend && make -f Makefile.bsd-wrapper perl.lib && make -f Makefile.bsd-wrapper install.lib) make depend && make && make installTo pick up where you left off, just reissue the commands from the point where the compile died.
If you do this procedure a lot, you may want to create a new target in your makefile. Simply copy the entry for build (to build-noclean, for example), and remove the make cleandir reference.
Because upgrading a compiler is a bit of a chicken-and-egg problem, changes to the in-tree compiler require a little extra attention. In general, you'll want to perform the following procedure:
(and yes, you are building it twice)
$ rm -r /usr/obj/gnu/egcs/gcc/* $ cd /usr/src/gnu/egcs/gcc $ make -f Makefile.bsd-wrapper clean $ make -f Makefile.bsd-wrapper obj $ make -f Makefile.bsd-wrapper depend $ make -f Makefile.bsd-wrapper $ sudo make -f Makefile.bsd-wrapper install $ make -f Makefile.bsd-wrapper clean $ make -f Makefile.bsd-wrapper depend $ make -f Makefile.bsd-wrapper $ sudo make -f Makefile.bsd-wrapper installAnd then run a normal make build.
You may be able to speed this process up by using the BOOTSTRAP procedure:
$ cd /usr/src/gnu/egcs/gcc $ make -f Makefile.bsd-wrapper clean $ make -f Makefile.bsd-wrapper obj $ make -f Makefile.bsd-wrapper -DBOOTSTRAP $ sudo make -f Makefile.bsd-wrapper -DBOOTSTRAP install $ make -f Makefile.bsd-wrapper clean $ make -f Makefile.bsd-wrapper $ sudo make -f Makefile.bsd-wrapper install
Short Answer: By Hand.
Long answer:
As a policy, software in the OpenBSD tree does not modify files in /etc automatcally. This means it is always up to the administrator to make the necessary modifications there. Upgrades are no exception. To update files in these directories, first determine what changes have occurred to the base (distribution) files, and then manually reapply these changes.
For example, to see the files in the tree that have changed most recently, do a:
# cd /usr/src/etc # ls -lt |moreTo see all the changes in /etc between arbitrary versions of OpenBSD, you can use CVS. For example, to see the changes between 2.6 and 2.7, do a:
# cd /usr/src/etc # cvs diff -u -rOPENBSD_2_6 -rOPENBSD_2_7Once you have identified the changes, reapply them to your local tree, preserving any local configuration you may have done.
# cd /usr/src # cvs -q -d anoncvs@some.anon.server:/cvs up -PAd # find . -type l -name obj | xargs rm # make -k cleandir # rm -rf /usr/obj/* # make objIf you're still having trouble, you may want to try adding -I ! -I CVS -I obj to your CVS updates. This will identify any extra cruft in your source tree.
Add the following entry to /etc/passwd using vipw
named:*:70:70::0:0:BIND Daemon:/var/named:/sbin/nologinAdd the following to /etc/group:
named:*:70:
Short Answer:
Create this user prior to the build.
Long Answer:
The named user is required in order to set permissions correctly. If this user is missing, part of the build process fails. If you capture your build to a file (say, with a make build &>/tmp/build.log) you will notice the following message:
(cd /usr/src/etc && make DESTDIR=/ distrib-dirs) install -d -o root -g wheel -m 755 / mtree -def mtree/4.4BSD.dist -p // -u mtree: unknown user named mtree: failed at line 1632 of the specification *** Error code 1 (ignored)Unfortunately for us, the build continued happily on its way, totally ignoring the fact that an error occurred.
If the named user exists, mtree works properly:
missing: ./var/named (created) missing: ./var/named/dev (created) missing: ./var/named/etc (created) missing: ./etc/afs (created) missing: ./etc/ssl (created) missing: ./etc/ssl/private (created) missing: ./usr/obj (not created: File exists) missing: ./usr/share/doc/html (created) missing: ./usr/share/doc/html/lynx_help (created) missing: ./usr/share/doc/html/lynx_help/keystrokes (created) missing: ./usr/share/doc/usd/13.viref (created) missing: ./usr/share/man/cat4/powerpc (created) missing: ./usr/share/man/man4/alpha (created) missing: ./usr/share/man/man4/pmax (created) missing: ./usr/share/man/man4/powerpc (created) missing: ./usr/share/tmac/mdoc (created) missing: ./var/www/htdocs/manual/vhosts (created) missing: ./usr/include/ssl (created)The reason for the fail, then, is that the /usr/include/ssl directory was never created. Without the header files, the ssleay build fails.
Fix:
Create the named user and group. Remove /usr/include/ssl, /var/named, and any other directory from the list above that was mistakenly created as a normal file by the make build.
Your directory tree is incomplete. Specifically, the /usr/share/man/cat4/powerpc directory is missing.
Quick Fix:
Create this directory and proceed with the compilation
Complete Fix:
Create the entire directory tree. Do a:
# cd /usr/src/etc && make DESTDIR=/ distrib-dirsYou will likely see an output like the following:
install -d -o root -g wheel -m 755 / mtree -def mtree/4.4BSD.dist -p // -u missing: ./var/named (created) missing: ./var/named/dev (created) missing: ./var/named/etc (created) missing: ./etc/afs (created) missing: ./etc/ssl (created) missing: ./etc/ssl/private (created) missing: ./usr/obj (not created: File exists) missing: ./usr/share/doc/html (created) missing: ./usr/share/doc/html/lynx_help (created) missing: ./usr/share/doc/html/lynx_help/keystrokes (created) missing: ./usr/share/doc/usd/13.viref (created) missing: ./usr/share/man/cat4/powerpc (created) missing: ./usr/share/man/man4/alpha (created) missing: ./usr/share/man/man4/pmax (created) missing: ./usr/share/man/man4/powerpc (created) missing: ./usr/share/tmac/mdoc (created) missing: ./var/www/htdocs/manual/vhosts (created) missing: ./usr/include/ssl (created)Note that /usr/share/man/cat4/powerpc was one of the directories created by this process.
# cd /usr/src/usr.bin/cap_mkdb # make clean && make && make installThe make build should then run to completion
The following pages should be removed:
/usr/share/man/cat1/ipf.0 /usr/share/man/cat1/ipnat.0 /usr/share/man/cat1/ipsecadm.0
/usr/src/games/snake.
A make build resulted in an error like this:
cap_mkdb -i -f terminfo terminfo.src cap_mkdb: illegal option -- i usage: cap_mkdb [-v] [-f outfile] file1 [file2 ...] *** Error code 1Quick Fix:
You need to build a new cap_mkdb. See 3.1.
# cd /usr/src/usr.bin/make # make clean && make && make installThen go ahead and rebuild the new Perl. You will need to clean out the Perl
obj directory by hand before building.
Perl developers should take note of the latest changes. From millert@openbsd.org:
The version of perl in the OpenBSD source tree (post 2.5) has been upgraded to 5.005_03. The build method has changed somewhat but most of that should be invisible. The important changes that affect people are as follows: 1) Perl lib files have moved from /usr/lib/perl5 to the more correct /usr/libdata/perl5 2) The default site_perl directories now live in /usr/local. Ie: if you install a perl module, it will place itself in /usr/local/libdata/perl5/site_lib. This makes it easy to see what non-stock modules you have. It also means that we can have perl modules in the ports system easily. 3) The perl library man pages are now install in /usr/share/man/cat3p You'll need to update your man.conf based on the src/etc/man.conf to take advantage of them. This means you can now do "man 3p less" and get info on the less pragma but "man less" will still get you the less pager manpage. If you have modules or other non-stock perl files the simplest thing to do is to move /usr/lib/perl5 to /usr/libdata/perl5 and add a link from /usr/lib/perl5 to /usr/libdata/perl5. Alternately, you could just edit the installed Config.pm file and fix up the paths there.
First, note that some platforms have not been bootstrapped successfully yet. To date, the following should work, if you are careful:
To test whether your platform can be bootstrapped, grab and install the egcs-snapshot, available from the ports collection. If this works, the in-tree version likely will, too. This is the safest method of proceeding.
Now, before going any further, ensure that your copies of binutils, gas, and ld are up to date. Note that there are two copies of gas and ld in the tree. On i386 and sparc, the binutils versions are not used. Check /usr/src/gnu/usr.bin/gas and /usr/src/gnu/usr.bin/ld instead.
The following instructions referred to the original egcs snapshot (egcs-990517). Since that time, a second snapshot (egcs-990608) has gone into the tree. If you are coming from vanilla 2.5, it is unlikely that you will be able to build the latest version directly. In this event, you will have to bootstrap an intermediate version using these instructions.
From espie@openbsd.org:
If you made it through this procedure, and everything is still working, congratulations. If not, check the following sections for advice. Problems not listed here should be posted to tech@openbsd.org.Today, the compiler changes. Exit gcc 2.8.1, enter egcs... or more precisely, gcc 2.95 prerelease. This is probably going to be a rough ride, but I can't work out all the kinks on every architecture by myself. I'm going to start importing stuff *now*. There will be a second message to tech@ once things are settled... Thanks to everyone who helped me sorting stuff out, most especially niklas, turan, and millert. Why the switch -------------- as most of you already know, egcs is now the *official* compiler supported by the FSF. The upcoming july release as been re-christened gcc 2.95. Just looking at the log messages will show you many improvements: support for newer processors is better, C++ is more accurately matching the ANSI/ISO standards, Fortran 77 is more closely integrated. There are also countless bug-fixes and code generation improvements. Also the development is more open. There is a cvs tree, there are several mailing-lists available, and we are cooperating closely with the egcs team. More precisely, I've been feeding patches back to the egcs team so that OpenBSD configurations are officially supported. Also, the development team is highly responsive to bug-reports, and problems get fixed. There also is a band-wagon phenomenon: everyone is switching to egcs, which means lots of code to test the compiler on, and that we can benefit from related projects. Why now ------- egcs-1.1 was unfit for some purposes. Specifically, code size on i386 was larger than gcc 2.8.1, which yielded floppy-disks problems. At 2.5 freeze, the only code fit to include was a somewhat unstable snapshot. In the interest of stability, after much pondering, egcs was not put into 2.5. Right now, the egcs project is going through a release cycle which will yield egcs 1.2. Judging from their time schedule, there is ample margin between egcs 1.2 and the next release of OpenBSD. Also, we want to get in now, so that we get a chance to report problems on less frequently used architectures, and get everything fixed for 1.2. egcs `feature freeze' is supposed to occur on may 7th, and the current snapshot 19990502 looks solid. What works and what doesn't --------------------------- egcs runs an i386 OpenBSD system without problems. m68k works as well, with a few work-arounds linked to obscure bugs that will get fixed. sparc seems to be running as well. There is some linker trouble on some other arches that needs to be fixed before our next release. Right now, constructors across dynamic libraries are not quite ready. egcs now features a stand-alone cpp which is going to be better than the current hackish solution we use. This means a few interface changes and possibly weird warnings. Keeping gcc 2.8.1 ? ------------------- due to size constraints, as soon as egcs is imported, gcc is going to move to cvs Attic. If you don't want to deal with egcs now, you'll have to be careful through your cvs updates. Some Makefiles are bound to change: includes, gnu/usr.bin, and gnu/lib. xlint and cpp.sh are going to change as well. How to bootstrap the compiler ----------------------------- the simplest way is probably to trust the various arch maintainers and download a snapshot. If you want to do stuff the hard way, you must first remake proper obj dirs: cd /usr/src make obj If you run i386, gas must be up-to-date. If you run sparc, ld must be up-to-date. then build libiberty: cd /usr/src/gnu/egcs/libiberty make -f Makefile.bsd-wrapper clean make -f Makefile.bsd-wrapper depend make -f Makefile.bsd-wrapper make -f Makefile.bsd-wrapper install then the C compiler: cd /usr/src/gnu/egcs/gcc make -f Makefile.bsd-wrapper clean make -f Makefile.bsd-wrapper depend make -f Makefile.bsd-wrapper make -f Makefile.bsd-wrapper install rebuild the C compiler with the new version: cd /usr/src/gnu/egcs/gcc make -f Makefile.bsd-wrapper clean make -f Makefile.bsd-wrapper depend make -f Makefile.bsd-wrapper make -f Makefile.bsd-wrapper install rebuild the includes cd /usr/src/include make includes build all egcs libraries and install them cd /usr/src/gnu/egcs make -f Makefile.bsd-wrapper clean make -f Makefile.bsd-wrapper depend make -f Makefile.bsd-wrapper make -f Makefile.bsd-wrapper install install the new cpp driver cd /usr/src/usr.bin/cpp make install then you're all set, and a standard make build should work...[author note: Actually, it doesn't quite work. xlint will fail to build. The fix is simple though. Simply do amake && make installin the/usr/src/usr.bin/xlint/xlintdirectory before you attempt a make build and proceed. See 4.2.2.]If it doesn't, you're using an arch that didn't go through make build yet. The most probably occurrence is an Internal Compiler Error, as known as an ICE. First try to see if the ICE will go away with -O1 or -O0. In that case, you can put a work-around in the Makefile until it's fixed (see /usr/src/lib/libm/Makefile for an example of how to put in such work-arounds for m68k). Then the error needs to be reported to the egcs-bugs mailing list. At a minimum, you must run the source through the same compiler invocation, with an addition of -v -save-temps to the options. -v yields the precise sequence of commands invoked by gcc. -save-temps will give you a pre-processed C file (.i) or C++ (.ii) that the egcs people can make sense of... you can't ask them to run OpenBSD on their boxes. If you have more time, you can try to trim down the pre-processed C file to the bare minimum that triggers the bug. Dichotomy works nicely.
Do a:
# cd /usr/src/usr.bin/xlint/xlint # make && make installnow re-run make, and the build should continue.
From: Marc Espie <Marc.Espie@liafa.jussieu.fr>
Subject: egcs core-dumping on uthread_autoinit.c
If this happens to you, this is a known linker problem... the cc1 you have
was linked in a weird way.
Initially, I made cc1 link against static /usr/lib/libiberty.a to avoid this
problem, but this was cutting things too close, and the bug reappeared,
probably thanks to unrelated changes in libc or elsewhere...
The tree has been patched with a work-around in
src/gnu/egcs/f/lang-options.h
make sure you have the kludged version of that file (at least rev 1.2),
recompile and reinstall cc1, the problem should go away.
What's going on is that the 386 linker gets something wrong because of
the huge strings array in toplev.c, and something gets mislinked, so
that
void f(void) __attribute((constructor)) {}
kills cc1.
As a work-around, I've killed Fortran options help texts, until someone finds
where the linker errs.
# cd /usr/src/usr.bin/cpp && make installAnd try the make build again.
===> lib/libkvm
"Makefile", line 30: Malformed conditional ((${UVM} == "yes"))
"Makefile", line 30: Missing dependency operator
"Makefile", line 32: if-less endif
"Makefile", line 32: Need an operator
Fatal errors encountered -- cannot continue
This can be solved by rebuilding the makefile includes. Do a:
cd /usr/src/share/mk && make installand try the build again.
The kernel structure statfs has changed. You will need to recompile the kernel before attempting a make build.
Long Answer:
The kernel structure statfs has changed. The new struct statfs has the following features:
When upgrading to 2.6 you'll need to create one simple link for gcc.
cd /usr/lib/gcc-lib
ln -s ${ARCH}-unknown-openbsd2.5 ${ARCH}-unknown-openbsd2.6
tar: Unable to remove directory ./usr/include/machine <Directory not empty>
In 2.5, /usr/include/machine was a directory, and /usr/include/i386 was a link to it. In 2.6, this situation is reversed.
To correct the problem, escape to the shell, remove the /usr/include/machine directory, and retry the upgrade.
There is a new termcaps.master file. You will need to regenerate the terminfo and termcaps files with the current version of tic(1). If you are upgrading via make build, the correct version of tic(1) will be used and this will be done for you. If not, you will get the following error:
terminfo.src is corrupt! You need to update /usr/bin/tic
In this case, you must either rebuild and install tic(1) (being sure to use the current version of libcurses) or simply build the version of tic(1) in your source tree.
(Note: pn is used below for simplicity. This should be taken to read pn, mx, al, or ax as appropriate)
These four drivers were replaced with the a unified dc driver. You must change all occurences of pn*, mx, al, or ax in your configuration files. This includes:
If you are modifying a custom kernel, make sure you have included the dcphy device in your kernel config, as follows:
dcphy* at mii? phy ? # Digital Clone PHYs
While you are at it, you may also want to add:
ukphy* at mii? phy ? # "unknown" PHYs
gcc 2.95.2 was merged into the OpenBSD source tree around January 19, 2000. In order for gcc to build properly, a more recent (post 2.6) libiberty is required. To build this library, do the following:
cd /usr/src/gnu/egcs/libiberty make -f Makefile.bsd-wrapper clean make -f Makefile.bsd-wrapper obj make -f Makefile.bsd-wrapper make -f Makefile.bsd-wrapper installNOTE: On mips-based architectures, such as pmax, you must perform an explicit ldconfig after new libraries are build.
Once libiberty is build, you may proceed with a standard gcc bootstrap:
cd /usr/src/gnu/egcs/gcc make -f Makefile.bsd-wrapper clean make -f Makefile.bsd-wrapper obj make -f Makefile.bsd-wrapper -DBOOTSTRAP make -f Makefile.bsd-wrapper -DBOOTSTRAP install make -f Makefile.bsd-wrapper clean make -f Makefile.bsd-wrapper make -f Makefile.bsd-wrapper install
For Kerberos IV to build correctly, you will have to perform the following steps:
# cd /usr/src/usr.bin/compile_et # make clean && make depend && make && make install
# cd /usr/src/lib/libcom_err # make clean && make depend && make && make install
# rm -r /usr/include/kerberosIV/* # cd /usr/src/kerberosIV # make includes
# cd /usr/src/kerberosIV/lib # make clean && make depend && make && make install
# cd /usr/src/kerberosIV # make cleandir && make depend && make && make install
The version of m4 that shipped with OpenBSD 2.6 will get into an infinite loop while processing the sendmail .mc files into .cf files. Because of this you will need to install the new version of m4 before you attempt a make build. In other words:
# cd /usr/src/usr.bin/m4
# make && make install && make cleandir
In sendmail 8.10.X, locations (and names) of the sendmail configuration files have changed. Everything but the pid file now lives in /etc/mail. Additionally, several files have changed names.
| OLD | NEW |
| /etc/sendmail.cf | /etc/mail/sendmail.cf |
| /etc/sendmail.cw | /etc/mail/local-host-names |
| /etc/sendmail.ct | /etc/mail/trusted-users |
| /etc/sendmail.oE | /etc/mail/error-header |
| /etc/aliases | /etc/mail/aliases |
| /etc/service.switch | /etc/mail/service.switch |
| /etc/userdb | /etc/mail/userdb |
| /usr/share/misc/sendmail.hf | /etc/mail/helpfile |
There are a couple of ways to convert from the old sendmail config to the new, but the first step is always the same.
include(`../m4/cf.m4')since it will be included for you by make. Also note that when adding machines to class w (via "Cw machinename"), you now need to do that in the LOCAL_CONFIG section (see openbsd-lists.mc for an example).
$ cd /usr/src/gnu/usr.bin/ld $ make clean && make obj && make $ sudo make install
$ cd /usr/src/sys/arch/`machine`/conf $ config GENERIC $ cd ../compile/GENERIC $ make clean && make depend && make
# echo "lookup file bind" >> /etc/resolv.conf
# cd /usr/src/sys/arch/`machine`/compile/GENERIC # mv /bsd /bsd.old # mv bsd /bsd # chown root.wheel /bsd # shutdown -r now(If this step fails, you can recover by booting the old kernel - bsd.old - at the boot> prompt.)
$ cd /usr/src/usr.bin/make $ make clean && make obj && make depend && make $ sudo make install $ cd /usr/src/share/mk $ sudo make install
$ cd /usr/src/etc/mtree $ sudo install -c -o root -g wheel -m 444 4.4BSD.dist /etc/mtree $ sudo mtree -qdef /etc/mtree/
# cd /usr/src && make build
auth:*:11:
# cd /dev # ./MAKEDEV allIf you are running X, change the Pointer section of /etc/XF86Config to contain the following:
Protocol "wsmouse"
Device "/dev/wsmouse"
Undefined symbol `_pdevnames_size' referenced Undefined symbol `_pdevnames' referencedTo correct this, compile and install the new config:
$ cd /usr/src/usr.sbin/config $ make clean && make depend && make $ sudo make installNow, recompile a new kernel as before.
--
$OpenBSD: upgrade-minifaq.html,v 1.47 2001/02/07 22:20:14 kjell Exp $
Copyright © 1998-2001, Kjell Wooding.
Please send any comments, questions, or suggestions to
kjell@openbsd.org