aboutsummaryrefslogtreecommitdiffstats
path: root/contrib
diff options
context:
space:
mode:
authorsvn2git <svn2git@FreeBSD.org>1994-07-01 00:00:00 -0800
committersvn2git <svn2git@FreeBSD.org>1994-07-01 00:00:00 -0800
commit5e0e9b99dc3fc0ecd49d929db0d57c784b66f481 (patch)
treee779b5a6edddbb949b7990751b12d6f25304ba86 /contrib
parenta16f65c7d117419bd266c28a1901ef129a337569 (diff)
downloadsrc-5e0e9b99dc3fc0ecd49d929db0d57c784b66f481.tar.gz
src-5e0e9b99dc3fc0ecd49d929db0d57c784b66f481.zip
Release FreeBSD 1.1.5.1release/1.1.5.1_cvsreleng/1
This commit was manufactured to restore the state of the 1.1.5.1-RELEASE image. Releases prior to 5.3-RELEASE are omitting the secure/ and crypto/ subdirs.
Diffstat (limited to 'contrib')
-rw-r--r--contrib/FAQ/FreeBSD.FAQ954
-rw-r--r--contrib/FAQ/OTHER-FAQS/FreeBSD.current.policy162
-rw-r--r--contrib/FAQ/OTHER-FAQS/FreeBSD.kdebug.FAQ33
-rw-r--r--contrib/FAQ/OTHER-FAQS/FreeBSD.mailing-list.FAQ77
-rw-r--r--contrib/FAQ/OTHER-FAQS/FreeBSD.ports.supfile18
-rw-r--r--contrib/FAQ/OTHER-FAQS/FreeBSD.slip.dialup.faq172
-rw-r--r--contrib/FAQ/OTHER-FAQS/FreeBSD.standard.supfile16
-rw-r--r--contrib/FAQ/OTHER-FAQS/FreeBSD.sup.faq98
-rw-r--r--contrib/FAQ/OTHER-FAQS/FreeBSDvsLinux70
-rw-r--r--contrib/FAQ/OTHER-FAQS/NFS77
-rw-r--r--contrib/FAQ/OTHER-FAQS/Systems.FAQ266
-rw-r--r--contrib/FAQ/code/printcap01/Makefile22
-rw-r--r--contrib/FAQ/code/printcap01/README14
-rw-r--r--contrib/FAQ/code/printcap01/hpf.c38
-rw-r--r--contrib/FAQ/code/printcap01/printcap.sample9
-rw-r--r--contrib/FAQ/code/printcap01/ps2lj34
-rw-r--r--contrib/Makefile4
-rwxr-xr-xcontrib/adduser/AddIt249
-rw-r--r--contrib/adduser/README40
-rw-r--r--contrib/adduser/dot.cshrc27
-rw-r--r--contrib/adduser/dot.login15
-rw-r--r--contrib/adduser/dot.profile2
-rw-r--r--contrib/adduser/userids1
-rwxr-xr-xcontrib/configit/ConfigIt761
-rw-r--r--contrib/configit/README32
-rw-r--r--contrib/configit/TODO9
-rw-r--r--contrib/crunch/COPYRIGHT25
-rw-r--r--contrib/crunch/Makefile4
-rw-r--r--contrib/crunch/Makefile.inc2
-rw-r--r--contrib/crunch/README88
-rw-r--r--contrib/crunch/crunchgen/Makefile9
-rw-r--r--contrib/crunch/crunchgen/crunched_main.c102
-rw-r--r--contrib/crunch/crunchgen/crunchgen.1266
-rw-r--r--contrib/crunch/crunchgen/crunchgen.c856
-rwxr-xr-xcontrib/crunch/crunchgen/mkskel.sh15
-rw-r--r--contrib/crunch/crunchide/Makefile4
-rw-r--r--contrib/crunch/crunchide/crunchide.168
-rw-r--r--contrib/crunch/crunchide/crunchide.c321
-rw-r--r--contrib/crunch/examples/Makefile32
-rw-r--r--contrib/crunch/examples/filesystem.conf26
-rw-r--r--contrib/crunch/examples/fixit.conf41
-rw-r--r--contrib/crunch/examples/kcopy.conf18
-rw-r--r--contrib/crunch/examples/really-big.conf146
-rw-r--r--contrib/manctl/Makefile11
-rw-r--r--contrib/manctl/manctl.sh376
-rw-r--r--contrib/tcpdump/tcpdump/tcpdump.12
-rw-r--r--contrib/tcpdump/tcpslice/tcpslice.12
-rw-r--r--contrib/xntpd/COPYRIGHT6
-rw-r--r--contrib/xntpd/Makefile.inc4
-rw-r--r--contrib/xntpd/README.FreeBSD76
-rw-r--r--contrib/xntpd/RELNOTES6
-rw-r--r--contrib/xntpd/VERSION2
-rw-r--r--contrib/xntpd/authstuff/authspeed.c2
-rw-r--r--contrib/xntpd/compilers/.keep_me0
-rw-r--r--contrib/xntpd/conf/Config.local4
-rw-r--r--contrib/xntpd/conf/Config.plain190
-rw-r--r--contrib/xntpd/doc/README.kern2015
-rw-r--r--contrib/xntpd/doc/notes.txt2
-rw-r--r--contrib/xntpd/gadget/.keep_me0
-rw-r--r--contrib/xntpd/hints/.keep_me0
-rw-r--r--contrib/xntpd/include/l_stdlib.h8
-rw-r--r--contrib/xntpd/include/ntp.h30
-rw-r--r--contrib/xntpd/include/ntp_control.h1
-rw-r--r--contrib/xntpd/include/ntp_if.h4
-rwxr-xr-xcontrib/xntpd/include/ntp_in.h259
-rw-r--r--contrib/xntpd/include/ntp_io.h1
-rw-r--r--contrib/xntpd/include/ntp_machine.h82
-rw-r--r--contrib/xntpd/include/ntp_request.h95
-rw-r--r--contrib/xntpd/include/ntp_stdlib.h1
-rw-r--r--contrib/xntpd/include/ntp_timex.h265
-rw-r--r--contrib/xntpd/include/ntpd.h13
-rw-r--r--contrib/xntpd/include/parse.h82
-rw-r--r--contrib/xntpd/kernel/.keep_me0
-rw-r--r--contrib/xntpd/lib/Makefile4
-rw-r--r--contrib/xntpd/lib/clocktypes.c2
-rw-r--r--contrib/xntpd/lib/netof.c25
-rw-r--r--contrib/xntpd/lib/numtohost.c5
-rw-r--r--contrib/xntpd/lib/systime.c3
-rw-r--r--contrib/xntpd/machines/.keep_me0
-rw-r--r--contrib/xntpd/ntpdate/ntpdate.h4
-rw-r--r--contrib/xntpd/ntpq/ntpq.c76
-rw-r--r--contrib/xntpd/parse/README.new_clocks212
-rw-r--r--contrib/xntpd/parse/README.parse_clocks263
-rw-r--r--contrib/xntpd/parse/clk_dcf7000.c7
-rw-r--r--contrib/xntpd/parse/clk_meinberg.c22
-rw-r--r--contrib/xntpd/parse/clk_rawdcf.c16
-rw-r--r--contrib/xntpd/parse/clk_schmid.c12
-rw-r--r--contrib/xntpd/parse/clk_trimble.c5
-rw-r--r--contrib/xntpd/parse/parse.c35
-rw-r--r--contrib/xntpd/parse/parse_conf.c7
-rw-r--r--contrib/xntpd/parse/parsesolaris.c35
-rw-r--r--contrib/xntpd/parse/parsestreams.c78
-rw-r--r--contrib/xntpd/parse/util/parsetest.c18
-rw-r--r--contrib/xntpd/parse/util/testdcf.c4
-rw-r--r--contrib/xntpd/ppsclock/ppstest/.keep_me0
-rw-r--r--contrib/xntpd/ppsclock/sys/genassym/.keep_me0
-rw-r--r--contrib/xntpd/ppsclock/sys/os/.keep_me0
-rw-r--r--contrib/xntpd/ppsclock/sys/sun/.keep_me0
-rw-r--r--contrib/xntpd/ppsclock/sys/sun4c/.keep_me0
-rw-r--r--contrib/xntpd/ppsclock/sys/sun4c/conf/.keep_me0
-rw-r--r--contrib/xntpd/ppsclock/sys/sun4m/conf/.keep_me0
-rw-r--r--contrib/xntpd/ppsclock/sys/sundev/.keep_me0
-rw-r--r--contrib/xntpd/ppsclock/sys/sys/.keep_me0
-rw-r--r--contrib/xntpd/refclocks/rclk.TRAK29
-rwxr-xr-xcontrib/xntpd/scripts/Guess.sh8
-rw-r--r--contrib/xntpd/scripts/README2
-rw-r--r--contrib/xntpd/scripts/stats/README35
-rw-r--r--contrib/xntpd/scripts/stats/dupe.awk3
-rw-r--r--contrib/xntpd/scripts/stats/ensemble.S5
-rw-r--r--contrib/xntpd/scripts/stats/etf.S15
-rw-r--r--contrib/xntpd/scripts/stats/itf.S5
-rw-r--r--contrib/xntpd/scripts/stats/loop.S7
-rw-r--r--contrib/xntpd/scripts/stats/loop.awk10
-rw-r--r--contrib/xntpd/scripts/stats/psummary.awk2
-rw-r--r--contrib/xntpd/scripts/stats/rms.awk41
-rwxr-xr-xcontrib/xntpd/scripts/stats/summary.sh95
-rw-r--r--contrib/xntpd/scripts/stats/tdata.S5
-rwxr-xr-xcontrib/xntpd/scripts/support/bin/monl3
-rw-r--r--contrib/xntpd/util/ntptime.c85
-rw-r--r--contrib/xntpd/util/tickadj.c71
-rw-r--r--contrib/xntpd/xntpd/Makefile4
-rw-r--r--contrib/xntpd/xntpd/minpoll (renamed from contrib/xntpd/adjtime/.keep_me)0
-rw-r--r--contrib/xntpd/xntpd/ntp_config.c201
-rw-r--r--contrib/xntpd/xntpd/ntp_control.c35
-rw-r--r--contrib/xntpd/xntpd/ntp_intres.c15
-rw-r--r--contrib/xntpd/xntpd/ntp_io.c95
-rw-r--r--contrib/xntpd/xntpd/ntp_loopfilter.c252
-rw-r--r--contrib/xntpd/xntpd/ntp_monitor.c51
-rw-r--r--contrib/xntpd/xntpd/ntp_peer.c26
-rw-r--r--contrib/xntpd/xntpd/ntp_proto.c225
-rw-r--r--contrib/xntpd/xntpd/ntp_refclock.c30
-rw-r--r--contrib/xntpd/xntpd/ntp_request.c175
-rw-r--r--contrib/xntpd/xntpd/ntp_restrict.c166
-rw-r--r--contrib/xntpd/xntpd/ntp_unixclock.c32
-rw-r--r--contrib/xntpd/xntpd/ntpd.c20
-rw-r--r--contrib/xntpd/xntpd/refclock_chu.c19
-rw-r--r--contrib/xntpd/xntpd/refclock_conf.c8
-rw-r--r--contrib/xntpd/xntpd/refclock_irig.c6
-rw-r--r--contrib/xntpd/xntpd/refclock_msfees.c2
-rw-r--r--contrib/xntpd/xntpd/refclock_parse.c103
-rw-r--r--contrib/xntpd/xntpd/refclock_trak.c1006
-rw-r--r--contrib/xntpd/xntpdc/ntpdc.c12
-rw-r--r--contrib/xntpd/xntpdc/ntpdc_ops.c297
-rw-r--r--contrib/xntpd/xntpres/xntpres.c18
144 files changed, 11135 insertions, 1649 deletions
diff --git a/contrib/FAQ/FreeBSD.FAQ b/contrib/FAQ/FreeBSD.FAQ
new file mode 100644
index 000000000000..9ea99a15613f
--- /dev/null
+++ b/contrib/FAQ/FreeBSD.FAQ
@@ -0,0 +1,954 @@
+
+ FreeBSD
+ Frequently Asked Questions
+ For Versions 1.1 and above
+
+Please mail all suggestions and additions to <FreeBSD-FAQ@freefall.cdrom.com>
+
+
+Revision: $Id: FreeBSD.FAQ,v 1.36 1994/06/28 15:33:58 jkh Exp $
+
+All entries are assumed to be relevant to both FreeBSD 1.1 and FreeBSD 1.1.5,
+unless otherwise noted.
+
+
+Table of Contents
+-----------------
+
+0 Preface
+1 Installation
+2 Hardware Compatibility
+3 Commercial applications
+4 User Applications
+5 Miscellaneous Questions
+6 Kernel Configuration
+7 System Administration
+8 Networking
+9 Serial Communications
+
+
+
+0 Preface
+---------
+
+Welcome to the FreeBSD 1.1 FAQ! This document tries to answer some of
+the most frequently asked questions about FreeBSD 1.1 (or later,
+unless specifically indicated). If there's something you're having
+trouble with and you just don't see it here, then please send mail to:
+
+ <FreeBSD-questions@freefall.cdrom.com>
+
+
+Some of the instructions here will also refer to auxiliary utilities
+in the /usr/src/contrib/FAQ directory. CDROM purchasers and net folks
+who've grabbed the FreeBSD 1.1 `srcdist' will have these files. If
+you don't have the source distribution, then you can either grab the
+whole thing from:
+
+ FreeBSD.cdrom.com:pub/FreeBSD/FreeBSD-1.1
+
+Or you can grab only those files you're interested in straight out of
+the FreeBSD-current distribution in:
+
+ FreeBSD.cdrom.com:pub/FreeBSD/FreeBSD-current/src
+
+0.1: What is FreeBSD?
+
+FreeBSD is a UN*X type operating system based on William Jolitz's port
+of U.C. Berkeley's Networking Release 2 to the i386, 386BSD. It is no
+longer correct to say that FreeBSD is only 386BSD with the patchkit
+applied! There have been many additions and bug fixes made throughout
+the entire system, some of the highlights of which are:
+
+ More robust and extensive PC device support
+ System V-style IPC, messaging and semaphores
+ Shared Libraries
+ Much improved virtual memory code
+ Better console driver support
+ Network booting (diskless) support
+ /proc filesystem
+ Yellow Pages support
+ `LDT' support for WINE (primitive but developing Windows emulation)
+ Too many additional utilities and applications to mention
+
+
+0.2: My friends told me that FreeBSD was illegal and I shouldn't use it.
+ Is this really true?
+
+FreeBSD versions up to and including 1.1 have included code from
+Berkeley's Net/2 distribution. UNIX Systems Laboratories (now Novell)
+sued Berkeley claiming that Net/2 included some code that belonged to
+USL. In February of 1994, USL and Berkeley announced a settlement in
+which neither side admitted to doing anything wrong, but UCB agreed to
+stop distributing the disputed software.
+
+Since Berkeley will no longer defend this code, we have been requested
+to stop distributing it, and will be integrating all the improvements
+we have made in the VM system and i386-specific code into Berkeley's
+4.4-Lite distribution; the result will form the basis of FreeBSD 2.0.
+We expect the integration to take place over a period of three to six
+months, during which time we will have to stop work on 1.1 and
+concentrate all our efforts on the merge, and we expect to make more
+information available on the status of the merge effort as the situation
+progresses.
+
+However, to answer the question, "No. FreeBSD is not illegal." We
+have been allowed by USL to distribute 1.1 as the last Net/2 derived
+version, after which we have committed to move to 4.4 as previously
+stated.
+
+We expect to make more information available on the status of the
+merge effort as the situation progresses.
+
+0.3: What are the FreeBSD mailing lists, and how can I get on them?
+
+The following mailing lists are provided for FreeBSD users and
+developers. For more information, send to
+<majordomo@freefall.cdrom.com> and include a single line saying
+``help'' in the body of your message.
+
+FreeBSD-announce: For announcements about or on FreeBSD.
+FreeBSD-hackers: Useful for persons wishing to work on the internals.
+FreeBSD-questions: General questions on FreeBSD.
+FreeBSD-bugs: Where bugs should be sent.
+FreeBSD-commit: This list carries the commit messages for freefall. Useful
+ for tracking ongoing work.
+FreeBSD-SCSI: Mailing list for SCSI developers.
+FreeBSD-current: This list is for persons wishing to run FreeBSD-current
+ and carries announcements and discussions on current.
+
+Please see also the FreeBSD mailing list FAQ in:
+
+ /usr/src/contrib/FAQ/OTHER-FAQS/FreeBSD.mailing-list.FAQ
+
+0.4: What are the various FreeBSD news groups?
+
+While there are no groups currently dedicated to FreeBSD, you may find
+the following groups useful.
+
+comp.os.386bsd.announce: For announcements
+comp.os.386bsd.apps: For applications
+comp.os.386bsd.questions: For questions
+comp.os.386bsd.development: For working on the internals
+comp.os.386bsd.bugs: About bugs
+comp.os.386bsd.misc: For items that don't fit anywhere else
+
+NOTE: These groups cover all the *BSDs (FreeBSD, NetBSD, 386BSD).
+
+
+
+1 Installation
+--------------
+
+1.1: I just installed my system and rebooted. Now I can't find the
+ extract or configure programs, where did they go?
+
+These two commands are just shell functions defined in /.profile. To
+get these back, boot FreeBSD with a `-s' at the boot prompt.
+
+
+1.2: I want to install FreeBSD onto a SCSI disk that has more than
+ 1024 cylinders. How do I do it?
+
+This depends. If you don't have DOS (or another operating system) on
+the system, you can just keep the drive in native mode and simply make
+sure that your root partition is below 1024 so the BIOS can boot the
+kernel from it. It you also have DOS/some other OS on the drive then
+your best bet is to find out what parameters that it thinks you have
+before installing FreeBSD. When FreeBSD's installation procedure
+prompts you for these values, you should then enter them rather than
+simply going with the defaults.
+
+There is a freely available utility distributed with FreeBSD called
+`pfdisk' (located in the tools/ subdirectory) which can be used for
+this purpose.
+
+
+1.3: When I boot FreeBSD it says ``Missing Operating System''.
+
+See question 1.2. This is classically a case of FreeBSD and DOS or
+some other OS conflicting over their ideas of disk geometry. You will
+have to reinstall FreeBSD, but obeying the instructions given above
+will almost always get you going.
+
+
+1.4: I have an IDE drive with lots of bad blocks on it and FreeBSD doesn't
+ seem to install properly.
+
+FreeBSD's bad block (bad144) handling is still not 100% (to put it
+charitably) and it must unfortunately be said that if you've got an
+IDE or ESDI drive with lots of bad blocks, then FreeBSD is probably
+not for you! That said, it does work on thousands of IDE based
+systems, so you'd do well to try it first before simply giving up.
+
+IDE drives are *supposed* to come with built-in bad-block remapping;
+if you have documentation for your drive, you may want to see if this
+feature has been disabled on your drive. However, ESDI, RLL, and
+ST-506 drives normally do not do this.
+
+<1.1.5>
+FreeBSD-current has better bad block handling due to improvments made
+to the wd driver.
+
+1.5: I have 32MB of memory, should I expect any special problems?
+
+If you have an IDE controller, no. Likewise, if you have a full EISA
+system with EISA disk controller or a working local bus controller
+(read further) you'll have no problems. If you have an ISA system, or
+an EISA system with an ISA disk controller then you will most
+certainly have problems with the upper 16MB of memory due to the ISA
+24 bit DMA limitation (which ISA cards in EISA systems will also
+exhibit). If you have a local bus disk controller, then you should be
+OK, UNLESS it's a Buslogic Bt445S with a revision less than `D' (BIOS
+3.36 or earlier).
+
+<1.1.5>
+1.1.5 has bounce-buffer support that make all of the above scenarios work
+with a full 32MB of memory or more. You are therefore advised to simply pull
+16MB of memory out, install, and then see about upgrading to FreeBSD 1.1.5
+so that you can put it back.
+
+
+1.6: Do I need to install the complete sources?
+
+In general, no. However, we would strongly recommend that you
+install, at a minimum, the `base' source kit, which includes several
+of the files mentioned here, and the `sys' (kernel) source kit, which
+includes sources for the kernel. There is nothing in the system which
+requires the presence of the sources to operate, however, except for
+the kernel-configuration program config(8). With the exception of the
+kernel sources, our build structure is set up so that you can
+read-only mount the sources from elsewhere via NFS and still be able
+to make new binaries. (Because of the kernel-source restriction, we
+recommend that you not mount this on /usr/src directly, but rather in
+some other location with appropriate symbolic links to duplicate the
+top-level structure of the source tree.)
+
+Having the sources on-line and knowing how to build a system with them
+will make it much easier for you to upgrade to future releases of
+FreeBSD.
+
+1.7: DES encryption software can not be exported from the United
+ States. If I live outside the US, how can I encrypt passwords?
+
+Since the DES encryption algorithm, which is used by passwd(1) and
+friends to encrypt passwords cannot legally be exported from the US,
+non-US users should not download this software from US FTP sites.
+
+There is however a replacement libcrypt available, based on sources
+written in Australia by David Burren. This code is now available on
+some non-US FreeBSD mirror sites. Sources for the unencumbered
+libcrypt, and binaries of the programs which use it, can be obtained
+from the following FTP sites:
+
+ South Africa: braae.ru.ac.za:/pub/FreeBSD/securedist/
+ owl.und.ac.za (currently uncertain)
+ Iceland: ftp.veda.is:/pub/crypt/FreeBSD/
+
+The non-US securedist can be used as a direct replacement for the
+encumbered US securedist. This securedist package is installed the
+same way as the US package (see installation notes for details). If
+you are going to install DES encryption, you should do so as soon as
+possible, before installing other software.
+
+Non-US users should please not download any encryption software from
+the USA. This can get the maintainers of the sites from which the
+software is downloaded into severe legal difficulties.
+
+A non-US distribution of Kerberos is also being developed, and current
+versions can generally be obtained by anonymous FTP from
+braae.ru.ac.za.
+
+There is also a mailing list for the discussion of non-US encryption
+software. For more information, send an email message with a single
+line saying ``help'' in the body of your message to
+<majordomo@braae.ru.ac.za>.
+
+1.8 HELP! My keyboard locked up during the install!
+
+Some keyboard controllers are not a friend to FreeBSD. Among these are
+those on certain models of Gateway, IBM and AST machines. The most frequent
+symptom encountered in such cases is that the keyboard refuses to respond
+to input when at the `kcopy>' prompt in the second phase of bootstrapping
+FreeBSD. Fortunately, there is a work-around that may get you all the
+way home. Reset the machine and boot the kcopy floppy again, but this
+time, as the kernel is booting, tap periodically on the num-lock key
+until the kcopy prompt appears. Your keyboard should respond properly.
+
+Once your system is on the hard disk the problem generally goes away.
+Some folks for whom the problem persists even after this stage find
+relief in switching to the SYSCONS console driver (see /sys/i386/conf/SYSCONS),
+which is in any case far more featureful than pccons and a recommended
+upgrade.
+
+
+
+2 Hardware compatibility
+------------------------
+
+2.1: What kind of hard drives does FreeBSD run on?
+
+FreeBSD supports ST-506 (sometimes called ``MFM''), RLL, and ESDI
+drives, which are usually connected to WD-1002, WD-1003, or WD-1006
+controllers (although clones should also work). FreeBSD also supports
+IDE and SCSI hard drives.
+
+2.2: What SCSI controllers are supported?
+
+FreeBSD supports the following SCSI controllers:
+
+Adaptec AH-1542 Series <ISA>
+ AH-1742 Series <EISA>
+Buslogic BT-445 Series <VLB> (but see section 1.5)
+ BT-545 Series <ISA>
+ BT-742 Series <EISA>
+ BT-747 Series <EISA>
+Future Domain TMC-8XX/950 Series <ISA> (1.1.5 ONLY)
+Seagate ST-01/02 Series <ISA> (1.1.5 ONLY)
+UltraStor UH-14f Series <ISA>
+ UH-34f Series <EISA/VLB>
+
+There is supposed to be a UltraStor 24f driver floating around, but
+we're not sure where (could someone please point us at it?).
+
+2.3: What CD-ROM drives are supported by FreeBSD?
+
+Any SCSI drive connected to a supported controller. Mitsumi
+LU002(8bit), LU005(16bit) and FX001D(16bit 2x Speed).
+
+FreeBSD does NOT support drives connected to a Sound Blaster or
+non-SCSI SONY or Panasonic drives. A general rule of thumb when
+selecting a CDROM drive for FreeBSD use is to buy a very standard SCSI
+model; they cost more, but deliver very solid performance in return.
+Do not be fooled by very cheap drives that, in turn, deliver VERY LOW
+performance! As always, you get what you pay for.
+
+The Mitsumi driver is known to be extremely slow compared to SCSI
+drives.
+
+
+2.4: What multi-port serial cards are supported by FreeBSD?
+
+AST/4 and BOCA 4/8/16 port cards. Some unnamed clone cards have also
+been known to work, especially those that claim to be AST compatible.
+Check the sio(4) man page to get more information on configuring such
+cards.
+
+
+2.5: Does FreeBSD support the AHA-2742 SCSI adapter from Adaptec?
+
+No, FreeBSD does not. This is due to Adaptec's unwillingness to
+supply programming information under other than non-disclosure. This
+is unfortunate, but there's nothing we can do about it.
+
+
+2.6: I have a Mumbleco bus mouse. Is it supported and if so, how do I set
+ it up for XFree86?
+
+FreeBSD supports the Logitech and ATI Inport bus mice. You need to
+add the following line to the kernel config file and recompile for the
+Logitech and ATI mice:
+
+ device mse0 at isa? port 0x23c tty irq6 vector mseintr
+
+
+2.7: I have a PS/2 mouse (`keyboard' mouse) [Alternatively: I have a
+ laptop with a track-ball mouse]. How do I use it?
+
+<1.1>: For the PS/2 mouse you need to look in
+/usr/src/contrib/FAQ/programs/psm, which is John Solhed's port of the
+Linux PS/2 mouse driver.
+
+Follow the directions in the package. You will also need to change
+your Xconfig file to point to the mouse.
+
+<1.1.5>: The PS/2 mouse is part of the system. See the psm0 driver
+description in /sys/doc/options.doc.
+
+
+2.8: What types of tape drives are supported under FreeBSD?
+
+FreeBSD supports SCSI, QIC-02 and QIC-40/80 (Floppy based) tape
+drives. This includes 8-mm (aka Exabyte) and DAT drives.
+
+
+2.9: What sound cards are supported by FreeBSD?
+
+FreeBSD supports the SoundBlaster, SoundBlaster Pro, Pro Audio
+Spectrum 16, AdLib and Gravis UltraSound sound cards. There is also
+limited support for MPU-401 and compatible MIDI cards. The
+SoundBlaster 16 and SoundBlaster 16 ASP cards are not yet supported.
+NOTE: This is only for sound! This driver does not support CD-ROMs,
+SCSI or joysticks on these cards.
+
+
+2.10: What network cards does FreeBSD support?
+
+There is support for the following cards:
+
+`ed' driver:
+ NE2000 and 1000
+ WD/SMC 8003, 8013 and Elite Ultra (8216)
+ 3Com 3c503
+ And clones of the above
+
+`ie' driver:
+ AT&T EN100/StarLAN 10
+
+`is' driver:
+ Isolan AT 4141-0
+ Isolink 4110
+
+`ep' driver:
+ 3com 3c509 (*)
+
+
+(*)The `ep' driver is known to have some problems; see the
+/usr/src/KNOWNBUGS file for more details.
+
+
+2.11: I have a 386/486sx/486SLC machine without a math co-processor.
+ Will this cause me any problems?
+
+Generally no, but there are circumstances where you will take a hit,
+either in performance or accuracy of the math emulation code (see
+section 4.1). In particular, drawing arcs in X will be VERY slow. It
+is highly recommended that you lay out the $50 or so for a math
+co-processor; it's well worth it. NOTE: Some math co-processors are
+better than others. It pains us to say it, but nobody ever got fired
+for buying Intel. Unless you're sure it works with FreeBSD, beware of
+clones.
+
+2.12: I am about to buy a new machine to run FreeBSD on and
+ want an idea of what other people are running. Is there list
+ of other systems anywhere?
+
+Yes. Please look at the file FAQ/OTHER-FAQS/Systems.FAQ. This file
+is a listing of hardware that people are running in their machines.
+Please note, this is a raw listing of equipment that other users
+have sent in.
+
+
+
+3 Commercial Applications
+-------------------------
+
+Note: This section is still very sparse, though we're hoping, of
+course, that companies will add to it! :) The FreeBSD group has no
+financial interest in any of the companies listed here but simply
+lists them as a public service (and feels that commercial interest in
+FreeBSD can have very positive effects on FreeBSD's long-term
+viability). We encourage commercial software vendors to send their
+entries here for inclusion.
+
+
+3.1: Where can I get Motif for FreeBSD?
+
+Sequoia International provides commercial quality Motif 1.2.3
+development kits for FreeBSD 1.1 (with full shared library support)
+under the product name of `SWiM'. Due to licensing restrictions from
+the OSF, and the fact that Sequoia needs to make a living, these are
+NOT FREE, but nonetheless quite reasonably priced in comparison to
+many other commercial Motif distributions. Send electronic mail to
+<info@seq.com> for further information.
+
+3.2: What about other commercial quality development systems for FreeBSD?
+
+ParcPlace Systems, Inc., who currently provides their excellent
+`Object Interface & Object Builder' GUI development environment free
+of charge to Linux users, is considering the the FreeBSD platform and
+will make their intentions known fairly shortly.
+
+
+
+4 User Applications
+-------------------
+
+4.1: I want to run X, how do I go about it?
+
+First, get the XFree86 distribution of X11R5 from XFree86.cdrom.com.
+The version you want for FreeBSD 1.1 and later is XFree86 2.1. Follow
+the instructions for installation carefully. You may then wish to read
+the documentation for the ConfigXF86 tool, which assists you in
+configuring XFree86 for your particular graphics card/mouse/etc.
+
+
+4.1: I've been trying to run ghostscript on a 386 (or 486sx) with no
+ math co-processor and I keep getting errors. What's up?
+
+<1.1>: The problem here is due to the current FreeBSD math-emulator. You
+need to pick up the sources to an alternate emulation package, which
+you may find in:
+
+ /usr/src/contrib/FAQ/programs/fpu-emu
+
+Follow the instructions supplied.
+
+This is a port of an older Linux math-emulator. At some point,
+FreeBSD's default math emulator will be good enough that you can
+forget about having to do this.
+
+<1.1.5>: For 1.1.5 you may add the following to your kernel config file and
+it will be compiled in.
+options GPL_MATH_EMULATE
+
+NOTE: You will need to remove the MATH_EMULATE option when you do this.
+
+
+4.2: If I want something like seyon, term, Kermit, emacs or any one of
+ hundreds of popular freeware utilities, is there a good place to
+ search through first?
+
+Yes, the FreeBSD `ports collection' was put together for just that
+purpose. It contains some of the most often requested languages,
+editors, mail and news reading programs, network software and many
+many megabytes of other types of useful goodies. CDROM people will
+probably have the ports collection already in /usr/ports, other folks
+can get at the latest snapshot of the entire collection in:
+
+ FreeBSD.cdrom.com:pub/FreeBSD/FreeBSD-current/ports
+
+Note that this FTP server permits getting entire directories as one
+(optionally gzipped or compressed) tar file. Read the FTP welcome
+banner carefully for details.
+
+
+4.3: I want all this neat software, but I haven't got the space or
+ CPU power to compile it all myself. Is there any way of getting
+ binaries?
+
+Yes. We support the concept of a `package', which is essentially a
+gzipped binary distribution with a little extra intelligence embedded
+in it for doing any custom installation work required. Packages can
+also be installed or deinstalled again easily without having to know
+the gory details. CDROM people will have a packages/ directory on
+their CD, others can get the currently available packages from:
+
+ FreeBSD.cdrom.com:pub/FreeBSD/packages-1.1
+
+Note that all ports may not be available as packages, and that new
+packages are constantly being added. It is always a good idea to
+check periodically to see which packages are available. A README file
+in the packages directory provides more details on the care and
+feeding of the package software, so no explicit details will be given
+here.
+
+4.4: I'm trying to get Perl to work properly, but I keep getting
+ errors about dbm failures when I test it. How can I fix this?
+
+The problem here is that the tests are written for an older version of
+the dbm code. There is nothing wrong with perl and the errors can
+be ignored.
+
+
+
+5 Miscellaneous Questions
+----------------
+
+5.1: I've heard of something called FreeBSD-current. How do I run it, and
+ where can I get more information?
+
+Read the file /usr/src/contrib/FAQ/OTHER-FAQS/FreeBSD.current.policy,
+it will tell you all you need to know.
+
+
+5.2: What is this thing called `sup', and how do I use it?
+
+SUP stands for Software Update Protocol, and was developed by CMU for
+keeping their development trees in sync. We use it to keep remote
+sites in sync with our central development sources.
+
+To use it, you need to have direct internet connectivity (not just
+mail or news). First, pick up the sup_bin.tgz package from:
+
+ FreeBSD.cdrom.com:pub/FreeBSD/packages
+
+Second, read the file /usr/src/contrib/FAQ/OTHER-FAQS/FreeBSD.sup.faq.
+
+This file describes how to setup sup on your machine. You may also
+want to look at /usr/src/contrib/FAQ/OTHER-FAQS/FreeBSD.*.supfile,
+which are a set of supfiles for supping from freefall.cdrom.com
+
+
+5.3: How do I create customized installation disks that I can give
+ out to other people at my site?
+
+The entire process of creating installation disks and source and
+binary archives is automated by various targets in
+/usr/src/etc/Makefile. The information there should be enough to get
+you started.
+
+5.4: How do I re-build my system without clobbering the existing
+ installed binaries?
+
+If you define the environment variable DESTDIR while running `make
+world' or `make install', the newly-created binaries will be deposited
+in a directory tree identical to the installed one, rooted at
+${DESTDIR}. Some random combination of shared libraries modifications
+and program rebuilds can cause this to fail in `make world', however.
+
+
+5.5: When my system booted, it told me that ``(bus speed defaulted)''.
+ What does that mean?
+
+The Adaptec 1542 SCSI host adapters allow the user to configure their
+bus access speed in software. Previous versions of the 1542 driver tried
+to determine the fastest usable speed and set the adapter to that. We
+found that this breaks some users' systems, so you now have to define
+the ``TUNE_1542''' kernel configuration option in order to have this
+take place. Using it on those systems where it works may make your
+disks run faster, but on those systems where it doesn't, your data could
+be corrupted.
+
+5.6: I would like to track changes to current and do not have net access.
+ Is there any way besides downloading the whole tree?
+
+Yes, Poul-Henning has set up a source tracking list. Please email
+majordomo@ref.tfs.com with a body of "get ctm-src-cur README" for
+futher information.
+
+5.7: How do I split up large binary files into smaller 240k files
+ like the distribution does?
+
+Newer BSD based systems have a "-b" option to split that allows them to
+split files on arbitary byte bondaries.
+
+Here is an example from /usr/src/Makefile.
+bin-tarball:
+ (cd ${DISTDIR}; \
+ tar cf - . \
+ gzip --no-name -9 -c | \
+ split -b 240640 - \
+ ${RELEASEDIR}/tarballs/bindist/bin_tgz.)
+
+5.8: I'm running Syscons and every morning my console locks up. What
+ is going on here?
+
+This sounds like the "kill -1 syslogd" problem. Make sure that the
+following is correct on your system.
+1. The attributes of the following nodes are correct.
+/dev/console
+crw------- 1 root 0, 0 May 23 15:32 /dev/console
+/dev/ttyv0
+crw------- 1 root 12, 0 May 23 15:32 /dev/ttyv0
+The part you are concerned with are the major and minor device numbers.
+
+2. Make sure that getty is running on ttyv0 and NOT console.
+
+3. If /dev/vga exists that it is a symlink to /dev/ttyv0.
+
+5.9: I've had a couple of system panics and would like to be able
+ browse the system dumps. The normal kernel is stripped and
+ I don't want to run a bloated kernel. What can I do?
+
+Please retrieve the file FAQ/OTHER-FAQS/FreeBSD.kdebug.FAQ. This
+file covers the instructions for looking at system dumps.
+
+
+6 Kernel Configuration
+----------------------
+
+6.1: When I compile a kernel with multi-port serial code, it tells me
+ that only the first port is probed and the rest skipped due to
+ interrupt conflicts. How do I fix this?
+
+The problem here is that FreeBSD has code built-in to keep the kernel
+from getting trashed due to hardware or software conflicts. The way
+to fix this is to leave out the IRQ settings on other ports besides
+the first. Here is a example:
+
+#
+# Multiport high-speed serial line - 16550 UARTS
+#
+device sio2 at isa? port 0x2a0 tty irq 5 flags 0x501 vector siointr
+device sio3 at isa? port 0x2a8 tty flags 0x501 vector siointr
+device sio4 at isa? port 0x2b0 tty flags 0x501 vector siointr
+device sio5 at isa? port 0x2b8 tty flags 0x501 vector siointr
+
+
+6.2: FreeBSD is supposed to come with support for QIC-40/80 drives but
+ when I look, I can't find it.
+
+You need to uncomment the following line in the generic config file
+(or add it to your config file) and recompile.
+
+controller fdc0 at isa? port "IO_FD1" bio irq 6 drq 2 vector fdintr
+disk fd0 at fdc0 drive 0
+disk fd1 at fdc0 drive 1
+#tape ft0 at fdc0 drive 2
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+You will have a device called /dev/ft0, which you can write to through
+a special program to manage it called `ft' - see the man page on ft for
+further details. Versions previous to -current also had some trouble dealing
+wiht bad tape media; if you have trouble where ft seems to go back and forth
+over the same spot, try grabbing the latest version of ft from /usr/src/sbin/ft
+in current and try that.
+
+
+6.3: Does FreeBSD support IPC primitives like those in System V?
+
+Yes, FreeBSD supports System V-style IPC. This includes shared
+memory, messages and semaphores. You need to add the following lines
+to your kernel config to enable them.
+
+options SYSVSHM
+options "SHMMAXPGS=64" # 256Kb of sharable memory
+options SYSVSEM # enable for semaphores
+options SYSVMSG # enable for messaging
+
+Recompile and install.
+
+
+6.4: Are there any utilities that make configuring a kernel easier?
+
+Well, yes and no. Look in /sys/i386/doc/options.doc (/sys/doc on post
+1.1 systems) for a list of kernel options you can set, and what they
+do. For a friendlier front-end to the process, see
+/usr/src/contrib/configit
+
+
+6.5: Will FreeBSD ever support other architectures?
+
+Several different groups have expressed interest in working on
+multi-architecture support for FreeBSD. If you are interested in
+doing so, please contact the developers at
+<FreeBSD-hackers@freefall.cdrom.com> for more information on our
+strategy for porting.
+
+
+6.6: I just wrote a device driver for a Foobar Systems, Inc.
+ Integrated Adaptive Gronkulator card. How do I get the
+ appropriate major numbers assigned?
+
+This depends on whether or not you plan on making the driver publicly
+available. If you do, then please send us a copy of the driver source
+code, plus the appropriate modifications to files.i386, a sample
+configuration file entry, and the appropriate MAKEDEV code to create
+any special files your device uses. If you do not, or are unable to
+because of licensing restrictions, then character major number 32 and
+block major number 8 have been reserved specifically for this purpose;
+please use them. In any case, we'd appreciate hearing about your
+driver on <FreeBSD-hackers@freefall.cdrom.com>.
+
+6.7: I'm wanting to switch console drivers to Syscons. I changed my
+ kernel config file to run Syscons, but when I reboot the system
+ locks up! How do I fix it?
+
+There are four things that need to be done to properly install syscons
+on a system.
+1. Add the following line to your kernel config file while deleting the
+ line for pccons.
+device sc0 at isa? port "IO_KBD" tty irq 1 vector scintr
+(Note the changed vector 'scintr'. It is a common error to change the
+device name but NOT the vector.
+
+2. Add the following option to your config file.
+options "NCONS=6" # Change to reflect the number of consoles
+
+3. Modify /etc/ttys to enable gettys on ttyv0 - ttyv??. Here is an
+example line.
+ttyv0 "/usr/libexec/getty Pc" Pc3 on secure
+Please make sure that you have disabled the getty on /dev/console.
+
+4. Create the device nodes in /dev. This is done useing the MAKEDEV
+script located in that directory. Here is a command line that will create
+6 virtual consoles.
+MAKEDEV vty6
+If /dev/vga exists, it should now be a symlink to /dev/ttyv0.
+
+NOTE: If you are going to be running X, you will need an unused vty that
+ has no getty running on it.
+
+
+
+7 System Administration
+-----------------------
+
+7.1: How do I add a user easily? I read the man page and am more confused
+ than ever! [Alternatively: I didn't read the man page, I never read
+ man pages! :-) ]
+
+Look at Gary Clark's Perl package ``AddIt'', which may be found in
+/usr/src/contrib/adduser. This is a first attempt at solving the
+problem and may be replaced with a more complex but capable solution
+later.
+
+
+7.2: I'm trying to use my printer and keep running into problems. I tried
+ looking at /etc/printcap, but it's close to useless. Any ideas?
+
+Yes, you can pick up Andreas Klemm's apsfilter package from:
+
+ftp.germany.eu.net:pub/comp/i386/Linux/Local.EUnet/People/akl/apsfilter-1.11.gz
+
+This is a complete package for printing text, PS and DVI files. It
+requires ghostscript and dvips.
+
+If you are looking for a simple printcap just for PS and text files,
+try picking up the printcap01 sources in:
+
+ /usr/src/contrib/FAQ/code/printcap01
+
+NOTE: We're looking for printcap entries for all printers. If you
+have one, or a filter for one, please send it or mail us a pointer to
+<FreeBSD-FAQ@freefall.cdrom.com>. Thanks!
+
+
+8 Networking
+------------
+
+8.1: Where can I get information booting FreeBSD `diskless', that is
+ booting and running a FreeBSD box from a server rather than having
+ a local disk?
+
+Please read /sys/i386/netboot/netboot.doc.
+
+
+8.2: I've heard that you can use a FreeBSD box as a dedicated network
+ router - is there any easy support for this?
+
+Internet standards and good engineering practice prohibit us from
+providing packet forwarding by default in FreeBSD. You can enable
+this support by adding `options GATEWAY' to your kernel configuration
+file and recompiling. In most cases, you will also need to run a
+routing process to tell other systems on your network about your
+router; FreeBSD comes with the standard BSD routing daemon routed(8),
+or for more complex situations you may want to try GateD (available by
+FTP from gated.Cornell.edu).
+
+It is our duty to warn you that, even when FreeBSD is configured in
+this way, it does not completely comply with the Internet standard
+requirements for routers; however, it comes close enough for ordinary
+usage.
+
+There is a standard `router floppy' that you can boot on a FreeBSD
+machine to configure it as a network router. Please look in:
+
+ freefall.cdrom.com:pub/incoming/freertr
+
+and follow the instructions.
+
+
+8.3: Does FreeBSD support SLIP and PPP?
+
+Yes. See the man pages for slattach(8) and/or pppd(8) if you're using
+FreeBSD to connect to another site. If you're using FreeBSD as a
+server for other machines, look at the man page for sliplogin(8).
+You may also want to take a look at the slip FAQ in:
+ FAQ/OTHER-FAQS/FreeBSD.slip.dialup.faq
+
+8.4: How do I set up NTP?
+
+NTP configuration is so complex and widely variable from site to site
+that it would be impossible to make a blanket statement here. Your
+best bet is to ask whoever's in charge of NTP at your site or network
+provider; chances are that they are running a similar version of NTP
+to the one that we provide, and they can probably provide you with the
+right configuration files to get things going.
+
+If you can't find anyone in charge, you should examine the files in
+/usr/src/contrib/xntpd/doc and see if they help any. If not, you
+could ask on the comp.protocols.time.ntp newsgroup, or the
+<ntp@ni.umd.edu> mailing-list.
+
+8.5: How do I get my network set up? I don't see how to make my
+ /dev/ed0 device!
+
+In the Berkeley networking framework, network interfaces are only
+directly accessible by kernel code. Please see the /etc/netstart file
+and the manual pages for the various network programs mentioned there
+for more information. If this leaves you totally confused, then you
+should pick up a book describing network administration on another
+BSD-related operating system; with few significant exceptions,
+administering networking on FreeBSD is basically the same as on SunOS
+4.0 or Ultrix.
+
+8.6: How do I get my 3C503 to use the other network port?
+
+Use `ifconfig ed0' to see whether the ALTPHYS flag is set, and then
+use either `ifconfig ed0 altphys' if it was off, or `ifconfig ed0
+-altphys' if it was on.
+
+8.7: I'm having problems with NFS to/from FreeBSD and my Wuffotronics
+ Workstation / generic NFS appliance, where should I look first?
+
+Certain PC network cards are better than others (to put it mildly) and
+can sometimes cause problems with network intensive applications like
+NFS. See /usr/src/contrib/FAQ/OTHER-FAQS/NFS for more information on this
+topic.
+
+8.8: I want to enable IP multicast support on my FreeBSD box, how do I do it?
+ [Alternatively: What the heck IS multicasting and what applications
+ make use of it?]
+
+First off, to you'll need to rebuild a kernel with multicast support in it.
+This requires that you have the sources to at least the kernel and the config
+utility. See /usr/src/sys/i386/conf/LINT for its comments on multicast; you'll
+need to set the MROUTING and MULTICAST options as shown there.
+
+Further reading/exploration for those interested in multicast:
+
+Product Description Where
+--------------- ----------------------- ---------------------------------------
+faq.txt Mbone FAQ ftp.isi.edu:/mbone/faq.txt
+imm/immserv IMage Multicast ftp.hawaii.edu:/paccom/imm.src.tar.Z
+ for jpg/gif images.
+nv Network Video. ftp.parc.xerox.com:
+ /pub/net-reseach/exp/nv3.3alpha.tar.Z
+vat LBL Visual Audio Tool. ftp.ee.lbl.gov:
+ /conferencing/vat/i386-vat.tar.Z
+wb LBL White Board. ftp.ee.lbl.gov:
+ /conferencing/wb/i386-wb.tar.Z
+mmcc MultiMedia Conference ftp.isi.edu:
+ Control program /confctrl/mmcc/mmcc-intel.tar.Z
+rtpqual Tools for testing the ftp.psc.edu:/pub/net_tools/rtpqual.c
+ quality of RTP packets.
+vat_nv_record Recording tools for vat ftp.sics.se:archive/vat_nv_record.tar.Z
+ and nv.
+
+[Many thanks to Jim Lowe for providing multicast support for FreeBSD, and this
+information]
+
+
+9 Serial Communications
+-----------------------
+
+9.1: When I do a set line in Kermit it locks up, what's the problem?
+
+The problem here is that FreeBSD thinks it's talking to a incoming
+modem connection, and is waiting for carrier to come up on it before
+completing the open. To disable modem control, do an:
+
+ stty -f /dev/ttyXX clocal
+
+(Where `ttyXX' is the tty port you're using). If you use a given port
+only for outgoing connections, you may wish to put this command in
+your /etc/rc.local to avoid having to do it every time you reboot your
+system.
+
+
+NOTE: Anyone wishing to submit a FAQ entry on how to get tip and cu working
+ would have it much appreciated! We all use Kermit over here! :-)
+
+-----------------------------------------------------------------------------
+If you see a problem with this FAQ, or wish to submit an entry, please
+mail us at <FreeBSD-FAQ@freefall.cdrom.com>. We appreciate your
+feedback, and cannot make this a better FAQ without your help!
+
+
+ FreeBSD Core Team
+
+-----------------------------------------------------------------------------
+
+ACKNOWLEDGMENTS:
+
+Gary Clark II - Our head FreeBSD FAQ maintenance man
+Jordan Hubbard - Janitorial services (I don't do windows)
+Garrett Wollman - Networking and formatting
+Robert Oliver, Jr. - Ideas and dumb questions (That made me think)
+Ollivier Robert - Invaluable feedback and contributions
+The FreeBSD Team - Kvetching, moaning, submitting data
+
+And to any others we've forgotten, apologies and heartfelt thanks!
+
diff --git a/contrib/FAQ/OTHER-FAQS/FreeBSD.current.policy b/contrib/FAQ/OTHER-FAQS/FreeBSD.current.policy
new file mode 100644
index 000000000000..cdebbc72bbbf
--- /dev/null
+++ b/contrib/FAQ/OTHER-FAQS/FreeBSD.current.policy
@@ -0,0 +1,162 @@
+ THE FREEBSD CURRENT POLICY
+
+Last updated: $Date: 1994/05/07 11:39:26 $
+
+This document attempts to explain the rationale behind FreeBSD-current,
+what you should expect should you decide to run it, and states some
+prerequisites for making sure the process goes as smoothly as possible.
+
+
+1. What is FreeBSD-current?
+
+FreeBSD-current is, quite literally, nothing more than a daily snapshot of
+the working sources for FreeBSD. These include work in progress, experimental
+changes, and transitional mechanisms that may or may not be present in
+the next official release of the software. While many of us compile
+almost daily from FreeBSD-current sources, there are periods of time when
+the sources are literally uncompilable. These problems are generally resolved
+as expeditiously as possible, but whether or not FreeBSD-current sources bring
+disaster or greatly desired functionality can literally be a matter of which
+part of any given 24 hour period you grabbed them in! Please read on..
+
+Under certain circumstances we will sometimes make binaries for parts of
+FreeBSD-current available, but only because we're interested in getting
+something tested, not because we're in the business of providing binary
+releases of current. If we don't offer, please don't ask! It takes far
+too much time to do this as a general task.
+
+
+2. Who needs FreeBSD-current?
+
+FreeBSD-current is made generally available for 3 primary interest groups:
+
+ 1. Members of the FreeBSD group who are actively working on one
+ part or another of the source tree and for whom keeping `current'
+ is an absolute requirement.
+
+ 2. Members of the FreeBSD group who are active ALPHA/BETA testers
+ and willing to spend time working through problems in order to
+ ensure that FreeBSD-current remains as sane as possible. These
+ are also people who wish to make topical suggestions on changes
+ and the general direction of FreeBSD.
+
+ 3. Peripheral members of the FreeBSD (or some other) group who merely
+ wish to keep an eye on things and use the current sources for
+ reference purposes (e.g. for *reading*, not running). These
+ people also make the occasional comment or contribute code.
+
+
+3. What is FreeBSD-current _NOT_?
+
+ 1. A fast-track to getting pre-release bits because there's something
+ you heard was pretty cool in there and you want to be the first on
+ your block to have it.
+
+ 2. A quick way of getting bug fixes.
+
+ 3. In any way "officially supported" by us.
+
+ We do our best to help people genuinely in one of the 3
+ "legitimate" FreeBSD-current catagories, but we simply DO NOT
+ HAVE THE TIME to help every person who jumps into FreeBSD-current
+ with more enthusiasm than knowledge of how to deal with
+ experimental system software. This is not because we're mean and
+ nasty people who don't like helping people out (we wouldn't even be
+ doing FreeBSD if we were), it's literally because we can't answer
+ 400 messages a day AND actually work on FreeBSD! I'm sure if
+ given the choice between having us answer lots of questions or
+ continue to improve FreeBSD, most of you would vote for us
+ improving it (and so would we! :-).
+
+
+4. Ok. I still think I "qualify" for FreeBSD-current, so what do I do?
+
+ 1. Join the freebsd-hackers and freebsd-commit mailing lists.
+ This is not just a good idea, it's ESSENTIAL. If you aren't on
+ freebsd-hackers, you won't read the comments that people are
+ making about the current state of the system and thus will end
+ up stumbling over a lot of problems that others have already
+ found and solved. Even more importantly, you will miss out on
+ potentially critical information (e.g. "Yo, Everybody! Before you
+ rebuild /usr/src, you MUST rebuild the kernel or your system
+ will crash horribly!").
+
+ The freebsd-commit list will allow you to see the commit log
+ entry for each change as its made. This can also contain
+ important information, and will let you know what parts of the
+ system are being actively changed.
+
+ To join these lists, send mail to `majordomo@freefall.cdrom.com'
+ and say:
+
+ subscribe freebsd-hackers
+ subscribe freebsd-commit
+
+ In the body of your message. Optionally, you can also say `help'
+ and MajorDomo will send you full help on how to subscribe and
+ unsubscribe to the various other mailing lists we support.
+
+ 2. Grab the sources from freebsd.cdrom.com. You can do this in
+ two ways:
+
+ 1. Use the CMU `sup' program (Software Update Protocol).
+ This is the most recommended method, since it allows you
+ to grab the entire collection once and then only what's
+ changed from then on. Many people run sup from cron
+ and keep their sources up-to-date automatically.
+
+ To get a binary of the sup program for FreeBSD, as well
+ as the documentation and some sample configuration files,
+ look in:
+
+ freefall.cdrom.com:~ftp/pub/sup
+
+ 2. Use ftp. The source tree for FreeBSD-current is always
+ "exported" on:
+
+ freebsd.cdrom.com:~ftp/pub/FreeBSD/FreeBSD-current
+
+ We use `wu-ftpd' which allows compressed/tar'd grabbing
+ of whole trees. e.g. you see:
+
+ usr.bin/lex
+
+ You can do:
+
+ ftp> cd usr.bin
+ ftp> get lex.tar.Z
+
+ And it will get the whole directory for you as a compressed
+ tar file.
+
+ 3. If you're grabbing the sources to run, and not just look at,
+ then grab ALL of current, not just selected portions. The
+ reason for this is that various parts of the source depend on
+ updates elsewhere and trying to compile just a subset is almost
+ guaranteed to get you into trouble.
+
+ 4. Before compiling current, read the Makefile in /usr/src
+ carefully. You'll see one-time targets like `bootstrapld'
+ which *MUST* be run as part of the upgrading process. Reading
+ freebsd-hackers will keep you up-to-date on other bootstrapping
+ procedures that sometimes become necessary as we move towards
+ the next release.
+
+ 5. Be active! If you're running FreeBSD-current, we want to know
+ what you have to say about it, especially if you have suggestions
+ for enhancements or bug fixes. Suggestions with accompanying code
+ are received most enthusiastically! :-)
+
+
+Thank you for taking the time to read this all the way through. We're
+always very keen to remain "open" and share the fruits of our labor
+with the widest possible audience, but sharing development sources has
+always had certain pitfalls associated with it (which is why most
+commercial organizations won't even consider it) and I want to make
+sure that people at least come into this with their eyes open, and
+don't make the leap unless they're good at working without a net!
+
+ Jordan
+
+
+
diff --git a/contrib/FAQ/OTHER-FAQS/FreeBSD.kdebug.FAQ b/contrib/FAQ/OTHER-FAQS/FreeBSD.kdebug.FAQ
new file mode 100644
index 000000000000..150fb8aac735
--- /dev/null
+++ b/contrib/FAQ/OTHER-FAQS/FreeBSD.kdebug.FAQ
@@ -0,0 +1,33 @@
+ Kernel debugging FAQ
+ FreeBSD
+
+Last modified: $Id: FreeBSD.kdebug.FAQ,v 1.1 1994/06/12 15:12:21 gclarkii Exp $
+
+Here are some instructions for getting kernel debugging working on
+a crash dump, it assumes that you have enough swap space for a crash
+dump.
+
+*** Start ***
+
+Config you're kernel using config -g
+
+Remove ${STRIP} -x $@; from the Makefile for the kernel so it doesn't
+get stripped.
+
+When the kernel's been built make a copy of it, say 386BSD.debug, and
+then run strip -x on the original. Install the original as normal.
+
+Now, after a crash dump, go to /sys/compile/WHATEVER and run kgdb. From kgdb
+do:
+
+symbol-file 386BSD.debug
+exec-file /var/crash/system.0
+core-file /var/crash/ram.0
+
+and viola, you can debug the crash dump using the kernel sources just like
+you can for any other program.
+
+
+
+ Paul Richards, FreeBSD core team member.
+
diff --git a/contrib/FAQ/OTHER-FAQS/FreeBSD.mailing-list.FAQ b/contrib/FAQ/OTHER-FAQS/FreeBSD.mailing-list.FAQ
new file mode 100644
index 000000000000..f522e79f782a
--- /dev/null
+++ b/contrib/FAQ/OTHER-FAQS/FreeBSD.mailing-list.FAQ
@@ -0,0 +1,77 @@
+ THE FREEBSD MAILING LIST FAQ
+
+Last updated: $Date: 1994/05/07 11:42:03 $
+
+Though many of the FreeBSD development members read USENET, we cannot
+always guarantee that we'll get to your questions in a timely fashion
+(or at all) if you post them only to one of the comp.os.386bsd.*
+groups. By addressing your questions to the appropriate mailing list
+you will reach both us and a concentrated FreeBSD audience, invariably
+assuring a better (or at least faster) response.
+
+The following is a summary of the mailing lists:
+
+List Purpose
+-----------------------------------------------------------------------------
+freebsd-admim Administrative issues (limited)
+freebsd-arch Architecture and design discussions (limited)
+freebsd-scsi Discussions concerning the SCSI system
+freebsd-bugs Bug reports
+freebsd-tz Discussions of proper timezone handling
+freebsd-hackers Technical discussions and suggestions
+freebsd-questions User questions
+freebsd-announce Important events / milestones
+freebsd-current Discussions about the use of FreeBSD-current
+
+-----------------------------------------------------------------------------
+
+Of all the lists, freebsd-arch and freebsd-admin have closed memberships
+limited to a small subset of core team members and developers, though anyone
+is free to send suggestions and commentary to them. The other lists may
+be freely joined by anyone.
+
+All mailing lists live on `freefall.cdrom.com', so to post to a list you
+simply mail to `<listname>@freefall.cdrom.com'. It will then be redistributed
+to mailing list members throughout the world.
+
+To subscribe to a list, send mail to:
+
+ majordomo@freefall.cdrom.com
+
+And include the keyword
+
+ subscribe <listname> [<optional address>]
+
+In the body of your message. For example, to subscribe yourself to
+freebsd-hackers, you'd do:
+
+ % mail majordomo@freefall.cdrom.com
+ subscribe freebsd-hackers
+ ^D
+
+If you want to subscribe yourself under a different name, or submit a
+subscription request for a local mailing list (note: this is more efficient
+if you have several interested parties at one site, and highly appreciated by
+us!), you would do something like:
+
+ % mail majordomo@freefall.cdrom.com
+ subscribe freebsd-hackers local-hackers@somesite.com
+ ^D
+
+Finally, it is also possible to unsubscribe yourself from a list, get a
+list of other list members or see the list of mailing lists again by
+sending other types of control messages to majordomo. For a complete
+list of available commands, do this:
+
+ % mail majordomo@freefall.cdrom.com
+ help
+ ^D
+
+Finally, it is suggested that you only join the freebsd-hackers or
+freebsd-questions mailing lists if you're also willing to see upwards
+of 100 messages a day (peak)! If you're only interested in the "high points",
+then it's suggested that you join freebsd-announce, which will contain
+only infrequent traffic.
+
+ Thank you!
+
diff --git a/contrib/FAQ/OTHER-FAQS/FreeBSD.ports.supfile b/contrib/FAQ/OTHER-FAQS/FreeBSD.ports.supfile
new file mode 100644
index 000000000000..60d30bfedac5
--- /dev/null
+++ b/contrib/FAQ/OTHER-FAQS/FreeBSD.ports.supfile
@@ -0,0 +1,18 @@
+
+ports-audio release=current host=freefall.cdrom.com hostbase=/home base=/usr prefix=/usr/ports delete compress
+ports-base release=current host=freefall.cdrom.com hostbase=/home base=/usr prefix=/usr/ports delete compress
+ports-comm release=current host=freefall.cdrom.com hostbase=/home base=/usr prefix=/usr/ports delete compress
+ports-db release=current host=freefall.cdrom.com hostbase=/home base=/usr prefix=/usr/ports delete compress
+ports-devel release=current host=freefall.cdrom.com hostbase=/home base=/usr prefix=/usr/ports delete compress
+ports-editor release=current host=freefall.cdrom.com hostbase=/home base=/usr prefix=/usr/ports delete compress
+ports-game release=current host=freefall.cdrom.com hostbase=/home base=/usr prefix=/usr/ports delete compress
+ports-lang release=current host=freefall.cdrom.com hostbase=/home base=/usr prefix=/usr/ports delete compress
+ports-mail release=current host=freefall.cdrom.com hostbase=/home base=/usr prefix=/usr/ports delete compress
+ports-math release=current host=freefall.cdrom.com hostbase=/home base=/usr prefix=/usr/ports delete compress
+ports-net release=current host=freefall.cdrom.com hostbase=/home base=/usr prefix=/usr/ports delete compress
+ports-news release=current host=freefall.cdrom.com hostbase=/home base=/usr prefix=/usr/ports delete compress
+ports-print release=current host=freefall.cdrom.com hostbase=/home base=/usr prefix=/usr/ports delete compress
+ports-shell release=current host=freefall.cdrom.com hostbase=/home base=/usr prefix=/usr/ports delete compress
+ports-util release=current host=freefall.cdrom.com hostbase=/home base=/usr prefix=/usr/ports delete compress
+ports-x11 release=current host=freefall.cdrom.com hostbase=/home base=/usr prefix=/usr/ports delete compress
+
diff --git a/contrib/FAQ/OTHER-FAQS/FreeBSD.slip.dialup.faq b/contrib/FAQ/OTHER-FAQS/FreeBSD.slip.dialup.faq
new file mode 100644
index 000000000000..23734d4c8ec4
--- /dev/null
+++ b/contrib/FAQ/OTHER-FAQS/FreeBSD.slip.dialup.faq
@@ -0,0 +1,172 @@
+***********************************************************************
+*** How to Set Up SLIP on FreeBSD ***
+***********************************************************************
+
+Last updated: $Date: 1994/06/01 09:03:08 $
+ $Id: FreeBSD.slip.dialup.faq,v 1.1 1994/06/01 09:03:08 asami Exp $
+
+The following is I (asami) set up my FreeBSD machine for SLIP on a
+static host network. For dynamic hostname assignments (i.e., your
+address changes each time you dial up), you probably need to do
+something much fancier.
+
+This is just "what I did, and it worked for me". I'm sharing this
+just for your reference, I'm no expert in SLIP nor networking so your
+mileage may vary.
+
+First, make sure you have
+
+pseudo-device sl 2
+
+in your kernel's config file. It is included in the GENERICAH and
+GENERICBT kernels, so this won't be a problem unless you deleted it.
+
+Things you have to do only once:
+
+(1) Add your home machine, the gateway and nameservers to your
+ /etc/hosts file. Mine looks like this:
+
+127.0.0.1 localhost loghost
+136.152.64.181 silvia.HIP.Berkeley.EDU silvia.HIP silvia
+
+136.152.64.1 inr-3.Berkeley.EDU inr-3 slip-gateway
+128.32.136.9 ns1.Berkeley.edu ns1
+128.32.136.12 ns2.Berkeley.edu ns2
+
+ By the way, silvia is the name of the car that I had when I was
+ back in Japan (it's called 2?0SX here in U.S.).
+
+(2) Make sure you have "hosts" before "bind" in your /etc/host.conf.
+ Otherwise, funny things may happen.
+
+(3) Edit the /etc/netstart and add this to the end of the file:
+
+# set up slip
+gateway=slip-gateway
+ifconfig sl0 inet $hostname $gateway netmask 0xffffff00
+route add default $gateway
+
+ Note that because of the "slip-gateway" entry in /etc/hosts, there
+ is no local dependency in the netstart file. Also, you might want
+ to un-comment the "route add $hostname localhost" line.
+
+(3') Make a file /etc/resolv.conf which contains:
+
+domain HIP.Berkeley.EDU
+nameserver 128.32.136.9
+nameserver 128.32.136.12
+
+ As you can see, these set up the nameserver hosts. Of course, the
+ actual addresses depend on your environment.
+
+(4) Set the password for root and toor (and any other accounts that
+ doesn't have a password). Use passwd, don't edit the passwd or
+ passwd.master files!
+
+(5) Edit /etc/myname and reboot the machine.
+
+How to set up the connection:
+
+(6) Dial up, type "slip" at the prompt, enter your machine name and
+ password. The things you need to enter depends on your
+ environment. I use kermit, with a script like this:
+
+# kermit setup
+set modem hayes
+set line /dev/tty01
+set speed 57600
+set parity none
+set flow rts/cts
+set terminal bytesize 8
+set file type binary
+# The next macro will dial up and login
+define slip dial 643-9600, input 10 =>, if failure stop, -
+output slip\x0d, input 10 Username:, if failure stop, -
+output silvia\x0d, input 10 Password:, if failure stop, -
+output ***\x0d, echo \x0aCONNECTED\x0a
+
+ (of course, you have to change the hostname and password to fit
+ yours). Then you can just type "slip" from the kermit prompt to
+ get connected.
+
+ Note: leaving your password in plain text anywhere in the
+ filesystem is generally a BAD idea. Do it at your own risk. I'm
+ just too lazy.
+
+ If kermit doesn't give you a prompt, try "stty -f /dev/tty01
+ clocal". I put this in /etc/rc.local so that it works the first
+ time I boot the machine.
+
+(7) Leave the kermit there (you can suspend it by "z") and as root,
+ type
+
+slattach -h -c -s 57600 /dev/tty01
+
+ if you are able to "ping" hosts on campus, you are connected!
+
+ If it doesn't work, you might want to try "-a" instead of "-c".
+
+(8) Happy slipping!
+
+How to shutdown the connection:
+
+(9) Type "ps gx" (as root) to find out the PID of slattach, and use
+ "kill -INT" to kill it.
+
+ Then go back to kermit ("fg" if you suspended it) and exit from it
+ ("q").
+
+ The slattach man page says you have to use "ifconfig sl0 down" to
+ mark the interface down, but this doesn't seem to make any
+ difference for me. ("ifconfig sl0" reports the same thing.)
+
+ Some times, your modem might refuse to drop the carrier (mine
+ often does). In that case, simply start kermit and quit it again.
+ It usually goes out on the second try.
+
+ When you want to connect again, go back to (6). You may have to
+ watch out for clocal mode. If "stty -f /dev/tty01" doesn't tell
+ you it's clocal, you need to re-set it before kermitting.
+
+TROUBLESHOOTING:
+
+If it doesn't work, feel free to ask me. The things that people
+tripped over so far:
+
+* Not using "-c" or "-a" in slattach (I have no idea why this can be
+ fatal, but adding this flag solved the problem for at least one
+ person)
+
+* Using "s10" instead of "sl0" (might be hard to see the difference on
+ some fonts :)
+
+Try "ifconfig sl0" to see your interface status. I get:
+
+silvia# ifconfig sl0
+sl0: flags=10<POINTOPOINT>
+ inet 136.152.64.181 --> 136.152.64.1 netmask ffffff00
+
+Also, "netstat -r" will give the routing table, in case you get the
+"no route to host" messages from ping. Mine looks like:
+
+silvia# netstat -r
+Routing tables
+Destination Gateway Flags Refs Use IfaceMTU Rtt
+Netmasks:
+(root node)
+(root node)
+
+Route Tree for Protocol Family inet:
+(root node) =>
+default inr-3.Berkeley.EDU UG 8 224515 sl0 - -
+localhost.Berkel localhost.Berkeley UH 5 42127 lo0 - 0.438
+inr-3.Berkeley.E silvia.HIP.Berkele UH 1 0 sl0 - -
+silvia.HIP.Berke localhost.Berkeley UGH 34 47641234 lo0 - 0.438
+(root node)
+
+(this is after transferring a bunch of files, your numbers should be
+smaller).
+
+---
+Satoshi Asami
+asami@cs.berkeley.edu
diff --git a/contrib/FAQ/OTHER-FAQS/FreeBSD.standard.supfile b/contrib/FAQ/OTHER-FAQS/FreeBSD.standard.supfile
new file mode 100644
index 000000000000..531a98110b38
--- /dev/null
+++ b/contrib/FAQ/OTHER-FAQS/FreeBSD.standard.supfile
@@ -0,0 +1,16 @@
+base release=current host=freefall.cdrom.com hostbase=/home base=/usr prefix=/usr/src delete old compress
+bin release=current host=freefall.cdrom.com hostbase=/home base=/usr prefix=/usr/src delete old compress
+contrib release=current host=freefall.cdrom.com hostbase=/home base=/usr prefix=/usr/src delete old compress
+crypt release=current host=freefall.cdrom.com hostbase=/home base=/usr prefix=/usr/src delete old compress
+etc release=current host=freefall.cdrom.com hostbase=/home base=/usr prefix=/usr/src delete old compress
+games release=current host=freefall.cdrom.com hostbase=/home base=/usr prefix=/usr/src delete old compress
+gnu release=current host=freefall.cdrom.com hostbase=/home base=/usr prefix=/usr/src delete old compress
+include release=current host=freefall.cdrom.com hostbase=/home base=/usr prefix=/usr/src delete old compress
+ksrc release=current host=freefall.cdrom.com hostbase=/home base=/usr prefix=/usr/src delete old compress
+lib release=current host=freefall.cdrom.com hostbase=/home base=/usr prefix=/usr/src delete old compress
+libexec release=current host=freefall.cdrom.com hostbase=/home base=/usr prefix=/usr/src delete old compress
+sbin release=current host=freefall.cdrom.com hostbase=/home base=/usr prefix=/usr/src delete old compress
+share release=current host=freefall.cdrom.com hostbase=/home base=/usr prefix=/usr/src delete old compress
+usrbin release=current host=freefall.cdrom.com hostbase=/home base=/usr prefix=/usr/src delete old compress
+usrsbin release=current host=freefall.cdrom.com hostbase=/home base=/usr prefix=/usr/src delete old compress
+
diff --git a/contrib/FAQ/OTHER-FAQS/FreeBSD.sup.faq b/contrib/FAQ/OTHER-FAQS/FreeBSD.sup.faq
new file mode 100644
index 000000000000..35c552168d6b
--- /dev/null
+++ b/contrib/FAQ/OTHER-FAQS/FreeBSD.sup.faq
@@ -0,0 +1,98 @@
+
+ FreeBSD
+ Sup FAQ
+
+Last updated: $Date: 1994/05/11 22:40:48 $
+
+ SUP is a network based software update tool developed at CMU. The
+purpose of this document is get the beginner up and running with sup.
+
+ First off you will need to pick up the sup binaries. The easiest
+way of doing this is to grab the sup_bin.tgz package from:
+
+ freebsd.cdrom.com:~ftp/pub/FreeBSD/packages
+ (FreeBSD 1.1 or later)
+ freebsd.cdrom.com:~ftp/pub/FreeBSD/packages-1.0
+ (FreeBSD 1.0.2 or earlier)
+
+Install the sup package using pkg_add and add the following line to your
+/etc/services file:
+
+ sup 871/tcp #sup
+
+
+ SUP gets the information it needs to run from a configuration file
+called a supfile. This file tells sup what collections it will be updating
+and/or installing and where they go. There are already two files that
+have been created for supping FreeBSD, both of which may be gotten from:
+
+ freebsd.cdrom.com:~ftp/pub/FreeBSD/FAQ/OTHER-FAQS
+
+The file `FreeBSD.standard.supfile' is used for supping from the
+/usr/src tree, the file `FreeBSD.ports.supfile' for the /usr/ports tree.
+These two files can be installed whereever it is convient to do so.
+
+ Next you will have to comment out whichever distributions you do
+not wish to receive with a # at the begining of the distribution line.
+You will find a list of distributions and a description for each at the
+end of this file.
+
+ Once this is setup, you're ready to go.
+
+To start sup type:
+
+ sup supfile
+
+If you wish to see what sup is doing "verbosely", give it the -v option,
+like so:
+
+ sup -v supfile
+
+ Thats all there is to it! Remember that if you're running current,
+which is what you will have if you sup, please join the freebsd-current
+mailing list. For more information on current please see the file:
+
+freefall.cdrom.com:~ftp/pub/FreeBSD/FAQ/OTHER-FAQS/FreeBSD.current.policy
+
+Gary Clark II
+FreeBSD maintainance person
+
+----
+
+FreeBSD SUP distributions
+
+From FreeBSD.standard.supfile:
+
+base: Just those files at the top of /usr/src.
+bin: /bin
+contrib: Sources to programs located in /usr/src/contrib, including the FAQ.
+crypt: Sources to libcrypt. NOTE: This is for use by US and Canadians only!!
+etc: /etc
+games: /usr/games
+gnu: Software that is under the GPL, like gcc, groff and uucp.
+include: /usr/include
+ksrc: The kernel sources
+lib: /usr/lib
+libexec: /usr/libexec
+sbin: /sbin
+usrbin: /usr/bin
+usrsbin: /usr/sbin
+
+From FreeBSD.ports.supfile
+
+ports-audio: Audio applications
+ports-base: Just those files at the top of /usr/ports.
+ports-comm: Communications software
+ports-db: Database software
+ports-devel: Development software
+ports-editor: Editing software
+ports-game: Game software
+ports-lang: Programming Languages
+ports-mail: Mail software
+ports-math: Math software
+ports-net: Network software
+ports-news: USENET news software
+ports-print: Printing software
+ports-shell: User shell software
+ports-util: Utility software
+ports-x11: X11 software
diff --git a/contrib/FAQ/OTHER-FAQS/FreeBSDvsLinux b/contrib/FAQ/OTHER-FAQS/FreeBSDvsLinux
new file mode 100644
index 000000000000..c282475d60e5
--- /dev/null
+++ b/contrib/FAQ/OTHER-FAQS/FreeBSDvsLinux
@@ -0,0 +1,70 @@
+[ Note: You could very well simply substitute the word "NetBSD" for Linux
+ in the argument that follows ]
+
+From time to time, a thread in both the comp.os.386bsd.misc and
+comp.os.linux.misc groups flares up regarding which operating system is
+"better", FreeBSD or Linux. This generally provokes controversy from
+users on both sides, with one group claiming that their OS is "better"
+for some reason and the other group claiming that the first group
+doesn't know what the heck it's talking about.
+
+Both arguments are a waste of time.
+
+Rather than trying to win a rather questionable debate on relative
+(and constantly changing) technical merits, we should be asking ourselves
+what both groups are REALLY about and what they represent. This is
+naturally going to be a matter of personal opinion, but I believe even the
+most seriously at-odds members would agree that both operating systems
+represent a unique and long-awaited opportunity: The ability to run a
+fully featured operating system on popular, easily affordable hardware
+and for which all source code is freely available.
+
+Those who have been in computing for awhile will remember when the term
+`operating system' referred almost exclusively to something provided solely
+by the hardware vendor, with very little in the way of alternative options.
+It was never EVER given out with source code, and true "wizard" status could
+only be achieved by exerting mind-numbing amounts of effort and patience in
+digging through forbidden bits of binary data. By comparison, the situation
+today seems almost too good to be true! Certainly, the feeling of achievement
+that came from finally ferreting out some esoteric bit of information from
+a 4MB printed system dump was high, but I don't think that anyone would argue
+that it was hardly the most optimal way of truly getting to know your
+operating system! :-)
+
+So now, within a very short space of time, we're almost spoiled for choice in
+having machines several times more powerful than the first multi-user VAX
+machines and available for under $2000, and we've got not one but SEVERAL
+perfectly reasonable free operating systems to chose from. We are in a
+comparative paradise, and what are some of us doing? *Complaining* about it!
+I suppose too much is never enough, eh? :-)
+
+So, my essential point is simply this: For the first time ever we
+have what previous computing generations could only dream about;
+powerful computers at a reasonable prices and a wonderful selection of
+things to run on them. Be happy, read the source code you're so
+privileged to now have available (*believe* me! What I wouldn't have
+given, even 5 years ago!) and spend your energy in making constructive
+use of it, not in arguing with the guys on the other side of the
+fence!
+
+Additionally, it should be said that none of the FreeBSD team has
+anything but the highest degree of respect for Linus Torvalds and his
+"team" of dedicated volunteers (and we occasional exchange gripe mail
+about the huge volume of messages each of us gets as a direct result
+of being insane enough to volunteer to do something like this :-).
+Our common commitment to the Intel platform also gives us more common
+ground (and interests) than one might think and, if anything, it's a pity
+that we do not endevor to share more code and effort - ideologically,
+at least, I'd say we share pretty similar goals.
+
+As to which is "best", I have only one standard reply: Try them both,
+see for yourself, think for yourself. Both groups have given you
+something for free, at considerable personal effort, and the least you
+can do is give them the benefit of exerting enough effort to try what
+they're offering out before passing judgment (or worse, blindly
+accepting someone else's!).
+
+Whichever you run, you're getting a great deal - enjoy!
+
+
+ Jordan Hubbard
diff --git a/contrib/FAQ/OTHER-FAQS/NFS b/contrib/FAQ/OTHER-FAQS/NFS
new file mode 100644
index 000000000000..e6f7af8fc511
--- /dev/null
+++ b/contrib/FAQ/OTHER-FAQS/NFS
@@ -0,0 +1,77 @@
+FreeBSD and NFS [for a FAQ]
+
+Certain Ethernet adapters for ISA PC systems have limitations which
+can lead to serious network problems, particularly with NFS. This
+difficulty is not specific to FreeBSD, but FreeBSD systems are affected
+by it.
+
+The problem nearly always occurs when (FreeBSD) PC systems are networked
+with high-performance workstations, such as those made by Silicon Graphics,
+Inc., and Sun Microsystems, Inc. The NFS mount will work fine, and some
+operations may succeed, but suddenly the server will seem to become
+unresponsive to the client, even though requests to and from other systems
+continue to be processed. This happens to the client system, whether the
+client is the FreeBSD system or the workstation. On many systems, there is
+no way to shut down the client gracefully once this problem has manifested
+itself. The only solution is often to reset the client, because the NFS
+situation cannot be resolved.
+
+Though the "correct" solution is to get a higher performance and capacity
+Ethernet adapter for the FreeBSD system, there is a simple workaround that
+will allow satisfactory operation. If the FreeBSD system is the SERVER,
+include the option "wsize=1024" on the mount from the client. If the
+FreeBSD system is the CLIENT, then mount the NFS file system with the
+option "rsize=1024". These options may be specified using the fourth
+field of the fstab entry on the client for automatic mounts, or by using
+the "-o" parameter of the mount command for manual mounts.
+
+In the following examples, "fastws" is the host (interface) name of a
+high-performance workstation, and "freebox" is the host (interface) name of
+a FreeBSD system with a lower-performance Ethernet adapter. Also,
+"/sharedfs" will be the exported NFS filesystem (see "man exports"), and
+"/project" will be the mount point on the client for the exported file
+system. In all cases, note that additional options, such as "hard" or
+"soft" and "bg" may be desireable in your application.
+
+Examples for the FreeBSD system ("freebox") as the client:
+ in /etc/fstab on freebox:
+fastws:/sharedfs /project nfs rw,rsize=1024 0 0
+ as a manual mount command on freebox:
+mount -t nfs -o rsize=1024 fastws:/sharedfs /project
+
+Examples for the FreeBSD system as the server:
+ in /etc/fstab on fastws:
+freebox:/sharedfs /project nfs rw,wsize=1024 0 0
+ as a manual mount command on fastws:
+mount -t nfs -o wsize=1024 freebox:/sharedfs /project
+
+Nearly any 16-bit Ethernet adapter will allow operation without the above
+restrictions on the read or write size.
+
+For anyone who cares, here is what happens when the failure occurs, which
+also explains why it is unrecoverable. NFS typically works with a "block"
+size of 8k (though it may do fragments of smaller sizes). Since the maximum
+Ethernet packet is around 1500 bytes, the NFS "block" gets split into
+multiple Ethernet packets, even though it is still a single unit to the
+upper-level code, and must be received, assembled, and ACKNOWLEDGED as a
+unit. The high-performance workstations can pump out the packets which
+comprise the NFS unit one right after the other, just as close together as
+the standard allows. On the smaller, lower capacity cards, the later
+packets overrun the earlier packets of the same unit before they can be
+transferred to the host and the unit as a whole cannot be reconstructed or
+acknowledged. As a result, the workstation will time out and try again,
+but it will try again with the entire 8K unit, and the process will be
+repeated, ad infinitum.
+
+By keeping the unit size below the Ethernet packet size limitation, we
+ensure that any complete Ethernet packet received can be acknowledged
+individually, avoiding the deadlock situation.
+
+Overruns may still occur when a high-performance workstations is slamming
+data out to a PC system, but with the better cards, such overruns are
+not guarranteed on NFS "units". When an overrun occurs, the units affected
+will be retransmitted, and there will be a fair chance that they will be
+received, assembled, and acknowledged.
+--
+ John Lind, Starfire Consulting Services
+E-mail: john@starfire.MN.ORG USnail: PO Box 17247, Mpls MN 55417
diff --git a/contrib/FAQ/OTHER-FAQS/Systems.FAQ b/contrib/FAQ/OTHER-FAQS/Systems.FAQ
new file mode 100644
index 000000000000..c2e3e2ed5177
--- /dev/null
+++ b/contrib/FAQ/OTHER-FAQS/Systems.FAQ
@@ -0,0 +1,266 @@
+ Systems FAQ
+ For FreeBSD
+ Last Modified: $Id: Systems.FAQ,v 1.1 1994/06/11 17:59:19 gclarkii Exp $
+
+This FAQ is a list of systems that people have sent to the FAQ maintnance
+person for inclusion. If you have a system you would like to be included
+please send it to FreeBSD-FAQ@freefall.cdrom.com.
+
+Disclaimer: This document is composed of systems that people have sent to
+the FAQ maintnance person. It is the not to be taken as an endorsement
+for any system or manufacture.
+
+
+1.
+
+386DX/20 real AMI, ISA
+Oak SVGA (no X)
+8MB
+Adaptec 1542B, WD1007V ESDI
+Wren VI and Miniscribe 660MB 20Mbit/sec ESDI
+WD 8013EBT
+
+2.
+
+486DX/25 clone, AMI BIOS, ISA
+Orchid PCIII gas plasma (yes, VGA16)
+8MB
+Adaptec 1542B
+Micropolis 1684 SCSI
+SMC 8013EEWC
+
+3.
+
+ ??? OPTI chipset AMI BIOS 486/50 ISA
+ISA ET4000 w/ X11 (not so slow)
+16 Mb - 48 Mb swap
+ISA aha1542 B
+ISA no-name IDE w/ floppies
+FUJITSU M2623S-512 405MB set to SCSI2
+SEAGATE ST3283N 237MB SCSI2
+SANYO CRD-400I SCSI2 cdromcdrom
+
+4.
+
+Lipizzan LDO-1 486DX-33 motherboard
+Orchid ProIIs (1M) video
+8 MB memory
+Generic 2S/1P/2FD/IDE controller:
+Maxtor 7213 AT
+WDC AC2420H
+PAS-16 + Sony CDU31A CD drive (Fusion 16 package).
+ *** The CD drive does not currently work with FreeBSD.
+
+5.
+
+Asus VL/ISA-486SV2 (ISA-VLB as you can see)
+Orchid Fahrenheit 1280+ VLB (yes)
+20MB
+Some no-name IDE VLB controller
+Conner CP30504 (I think....the 540MB IDE one)
+Zoltrix 14.4/14.4 Fax/Modem on tty01
+Intel 486DX2/66 CPU + fan
+Conner CP30104 (120MB....for DOS)
+
+6.
+
+AIR 486El (running with AMD486/40)
+ATI Graphics Ultra Pro running XFree862.1
+16M
+Adaptec 1742
+Micropolis 2217
+Wangtec 6130FS DAT drive (Some problems)
+
+7.
+
+Compudyne 486 DX2/66
+ATI Local Bus GUP w/ 2megs
+16 Megs Memory
+504 IDE Hard Drive
+Colorado 250 meg QIC-80 tape drive
+
+8.
+
+American Megatrends Enterprise III, 486DX2-66
+ATI VLB Mach 32 (with X)
+16 meg
+Adaptec 1742 EISA SCSI with floppy
+Toshiba 5030 SCSI-II
+Toshiba 5157 SCSI-II
+SMC Elite16T ISA Ethernet (ISA)
+
+9.
+
+American Megatrends Enterprise III, 486DX
+ATI VLB Mach 32 (with X)
+32 meg
+Adaptec 1742 EISA SCSI with floppy
+Maxtor P0-12S SCSI
+Digital DSP5200S SCSI-II
+Pro Audio Spectrum 16
+Wonder Board, 4 serial (16550), 3 parallel, each on a different interrupt
+
+10.
+
+NoName 486DX/33, Intel Chipset, EISA-Bus
+ATI Graphics Ultra Pro EISA,
+17" Nanao (Eizo) F550-i Monitor
+Running the Mach32 X-Server XFree86-2.1.1 with fonts created from source.
+16 MB RAM (planning to add another 8 MB).
+AHA1742A
+Conner CP3100
+Fujitsu 520 MB
+Archive 525MB streamer tape.
+Gravis UltraSound - works for mod-files.
+
+11.
+
+ASUS SP3 PCI Board with i486 DX/2 66 MHz
+ISA ET4000 (I already tested a S3 805 PCI card successfully)
+Adaptec 1542B
+Toshiba XM3301TA CD-Rom
+CDC Harddisk, 572 MB (I don't know the exact specs)
+
+12.
+
+Mylex MAE486/33 EISA Motherboard
+16MB memory
+Actix GE32+ S3 801 gfx
+Adaptec 1742A controller
+Seagate ST3160 drive
+Seagate ST5120 drive
+Archive Viper 150MB tape
+Roland SCC-1 sound card
+Gravis Ultrasound card
+Longshine SMC/Novell compatable ethernet card
+
+13.
+
+Model: DECpc LPv 466d2
+Config: Local (Motherboard) S3 801 gfx, IDE controller, PS/2 mouse, 12MB memory
+
+14.
+
+
+??? 486/DX266 EISA/VLB Motherboard
+16MB memory
+#9 GXE L12 VLB 3MB graphics card
+Bt445S VLB disk controller
+DEC DSP3105S drive
+MAXSTOR P-17S drive
+Tandberg 525MB tape drive
+Toshiba XM3301 CDROM
+Soundblaster 2.0
+Longshine SMC/Novell compatable ethernet card
+
+15.
+
+M407 PC chips with 33Mhz 486.
+Had to disable external cache due to DMA problems. Board uses write-through
+cache unless a second chip is added to allow write-back.write-back.
+Orchid ProDesigner II (yes)
+16Mb
+IDE
+Maxtor 7213 AT and Maxtor 7120 AT
+2 BICC Isolans (Lance based cards)
+
+16.
+
+Gigabyte EISA/VLB motherboard with SIS chipset, AMI bios, 32 MB ram
+Adaptec 1742 SCSI 2 controller with floppy controller enabled
+Spea/V7 Mirage - S3/805 based localbus graphics card with 1 MB d-ram
+no name wd8013 compatible ethernet card
+Gravis Ultrasound card with 1 MB ram
+2 Fujitsu 400 MB and 1 Seagate 500 MB SCSI 2 harddisks
+5 1/4 + 3 1/2 inch floppy drives
+Tandberg TDC3600 60 MB + Tandberg TDC3800 525 MB Streamer (these don't work
+quite properly yet)
+
+17.
+
+i486DX33, 16 Mb RAM, 256 Kb external cache, VLB board
+no-name IDE/floppy controller
+Western Digital Caviar 2340 (325 Mb)
+Kalok KL-343 (40 Mb)
+Chips & Technologies 451 SuperVGA card (800x600, 16 colours, 256Kb)
+
+18.
+
+no name EISA i486DX/33 board, 16 MB RAM
+Adaptec AHA-1540*A* (not knowing if the current -current might cause
+ problems, my kernel is from end of march)
+Maxtor MXT-1240S, 1.2Gig very fast SCSI disk
+Seagate ST-1144A, just to boot off the beast (also has a messdos partition yet)
+Archive Viper 150 tape; has a firmware braindeadness when appending files,
+ works very well otherwise
+ELSA Winner 1000 ISA/EISA, 1MB VRAM, S3 86C928 (unfortunately, D-step chip)
+Nokia 447-B 17in monitor, running ~ 1100x800 resolution, very nice
+true `Mouse Systems' optical mouse, fine thing!
+sometimes a Toshiba XM-3301 CDROM, rather old, but solid & reliable
+
+19.
+
+older south-east Asia made notebook, i386SX/16, 5 MB RAM (where the 384 k hole
+ can be re-mapped, so all the 5 MB are useable)
+Seagate ST-9145AG, 120 MB 2.5in IDE disk, very low power consumption, but
+ rather slow transfer rate, only about 350 K/s, so paging is a mess
+640x480 LCD, ~ 16 gray tones distinguishable, Cirrus Logic CL-GD610/620
+ chipset; runs generic VGA-Mono and VGA-16 XFree86[tm] servers; needs
+ some hacks in rc.local to give full contrast when running with the
+ pcvt display driver (due to their different default attribute handling)
+
+
+20.
+
+Data General Dasher 386sx/16, 8 MB RAM
+Adaptec AHA-1542B
+Seagate ST-3655N, 525 MB SCSI disk
+Conner CP-3044, 40 MB IDE disk
+has been working with a Western Digital WD-1007V ESDI controller (on
+ secondary wdc address), and a Micropolis 1664-7 330 MB ESDI disk -
+ but this beast was terribly slow, loud (& unreliable) and therefore
+ had to go
+ET-3000 based 512 K VGA, slow (wrt. XFree86), but reliable
+3Com 3C503 Ethernet adaptor, suffers from the `do not nfs mount with
+ too large packets' problem, but works well otherwise
+`Mouse Systems' optical mouse
+Toshiba XM-3301 CDROM
+already ran with a Micropolis 1664-3 330 MB SCSI disk (same drive as
+ above, but different interface)
+already ran with an IBM 2Gig SCSI disk (don't remember the type)
+
+
+21.
+
+Mylex MNA 486/33 EISA Motherboard
+16Mb of Memory
+1.2 GB Toshiba 538 SCSI disk
+400Mb IBM SCSI disk
+150/250Mb Tandberg SCSI tape drive
+Toshiba 3401 SCSI CD-ROM
+Tseng 4000 Video Controller
+Logitech Bus Mouse
+Mediavision Pro Audio Stereo Sound Card
+Adaptech 1742A SCSI controller
+WD8013EBT Ethernet Card
+
+22.
+
+386DX-40 w/Cyrix math co-processor
+ET-4000 running X
+16MB
+IDE
+540MB Western Digital
+WD8003EP
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/contrib/FAQ/code/printcap01/Makefile b/contrib/FAQ/code/printcap01/Makefile
new file mode 100644
index 000000000000..fda6ebb83586
--- /dev/null
+++ b/contrib/FAQ/code/printcap01/Makefile
@@ -0,0 +1,22 @@
+#
+# Makefile for the FAQ/printcap
+#
+
+PROG = hpf
+SRCS = hpf.c
+
+
+install:
+ if test -d /usr/libexec/lpr; \
+ then \
+ true; \
+ else \
+ mkdir /usr/libexec/lpr;
+ fi;
+
+ install -c -o bin -g bin -m 555 hpf /usr/libexec/lpr
+ install -c -o bin -g bin -m 555 ps2lj3 /usr/libexec/lpr
+ install -c -o bin -g bin -m 555 printcap.sample /etc/printcap
+
+.include <bsd.prog.mk>
+
diff --git a/contrib/FAQ/code/printcap01/README b/contrib/FAQ/code/printcap01/README
new file mode 100644
index 000000000000..c13eb72ddb65
--- /dev/null
+++ b/contrib/FAQ/code/printcap01/README
@@ -0,0 +1,14 @@
+This print cap package was created by Curt Mayer. Please contact hime for more
+information.
+
+Curt Mayer
+curt@toad.com
+415-387-0217 home
+
+To install this package, type make then make install. This will copy the
+printcap.sample to /etc/printcap and create the directory /usr/libexec/lpr
+and copy the hpf filter to there.
+
+Thanks
+Gary Clark II
+FreeBSD FAQ Person
diff --git a/contrib/FAQ/code/printcap01/hpf.c b/contrib/FAQ/code/printcap01/hpf.c
new file mode 100644
index 000000000000..8d78c092f902
--- /dev/null
+++ b/contrib/FAQ/code/printcap01/hpf.c
@@ -0,0 +1,38 @@
+/*
+source to my hp filter, installed as /usr/libexec/lpr/hpf:
+*/
+#include "stdio.h"
+#include <signal.h>
+#include <sys/file.h>
+#include <sys/ioctl.h>
+#include <sgtty.h>
+
+main(ac, av)
+int ac;
+char **av;
+{
+ int c;
+ struct sgttyb nbuf;
+ unsigned long lbits;
+
+ setbuf(stdout, NULL);
+ lbits = LDECCTQ | LPASS8 | LLITOUT;
+ ioctl(fileno(stdout), TIOCLSET, &lbits);
+ ioctl(fileno(stdout), TIOCGETP, &nbuf);
+ nbuf.sg_flags &= ~(ECHO | XTABS | CRMOD);
+ ioctl(fileno(stdout), TIOCSETP, &nbuf);
+
+ fputs("\033E\033&k2G", stdout);
+
+ while (1) {
+ if ((c = getchar()) != EOF) {
+ putchar(c);
+ } else {
+ break;
+ }
+ }
+
+ fputs("\033&l0H", stdout);
+
+ exit(0);
+}
diff --git a/contrib/FAQ/code/printcap01/printcap.sample b/contrib/FAQ/code/printcap01/printcap.sample
new file mode 100644
index 000000000000..10e87ba2d386
--- /dev/null
+++ b/contrib/FAQ/code/printcap01/printcap.sample
@@ -0,0 +1,9 @@
+
+ps|postscript emulation:\
+ :lp=/dev/lpa0:sd=/var/spool/lpd:lf=/var/log/lpd-errs:\
+ :if=/usr/libexec/lpr/ps2lj3:sh:mx#0:sf:
+
+lp|epson|lj|local line printer:\
+ :lp=/dev/lpa0:sd=/var/spool/lpd:lf=/var/log/lpd-errs:\
+ :if=/usr/libexec/lpr/hpf:\
+ :sh:mx#0:pw#80:
diff --git a/contrib/FAQ/code/printcap01/ps2lj3 b/contrib/FAQ/code/printcap01/ps2lj3
new file mode 100644
index 000000000000..8dc9ff384011
--- /dev/null
+++ b/contrib/FAQ/code/printcap01/ps2lj3
@@ -0,0 +1,4 @@
+
+#!/bin/sh
+/usr/gnu/bin/gs -dNOPAUSE -r300 -q -sDEVICE=ljet3 -sOutputFile=- -f -
+
diff --git a/contrib/Makefile b/contrib/Makefile
index c1625896c8f4..24d96987e809 100644
--- a/contrib/Makefile
+++ b/contrib/Makefile
@@ -1,6 +1,6 @@
-# $Id: Makefile,v 1.3 1993/12/21 21:18:14 wollman Exp $
+# $Id: Makefile,v 1.5 1994/06/15 21:08:47 jkh Exp $
-SUBDIR= tcpdump xntpd
+SUBDIR= crunch manctl tcpdump xntpd
# Not ported: isode
diff --git a/contrib/adduser/AddIt b/contrib/adduser/AddIt
new file mode 100755
index 000000000000..64f6f945013b
--- /dev/null
+++ b/contrib/adduser/AddIt
@@ -0,0 +1,249 @@
+#!/usr/local/bin/perl
+
+# Copyright (c) 1994 GB Data Consulting
+# All rights reserved.
+# VERSION 0.8 BETA
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# 3. The name of the Author may not be used to endorse or promote products
+# derived from this software without specific prior written permission.
+# 4. This license extends only to beta and network distributed versions.
+# All even number versions are non-network.
+# THIS SOFTWARE IS PROVIDED BY GB DATA AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL GB DATA OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+
+# You will need to define these if you wish to have defaults or use
+# that function.
+
+$defgroupid = 30; # Default ID
+$defusrdir = "\/usr\/u"; # Default User Dir
+$usequota = ""; # Use quotas
+$usemail = ""; # Use mailings
+$mailfile = ""; # File to use with mailings
+$userdefshell = "\/bin\/csh"; # Default user shell
+$useforward = ""; # Use a forward file
+$protouser= ""; # Prototypical user for quotas
+
+# Start getting information and print a banner
+
+print " AddIt\n";
+print " A system utility for adding users with defaults\n";
+print " Copyright 1994 GB Data Consulting\n";
+print "\n\n";
+
+#
+# User ID
+#
+
+print "Please enter the login name of the user: ";
+chop ($userlogin = <STDIN>);
+print "Please enter the user id or hit enter for the next id: ";
+chop ($userid = <STDIN>);
+
+if (!$userid) {
+ open (USERID, "+<userids");
+ chop ($xxuserid = <USERID>);
+ $userid = $xxuserid + 1;
+ close USERID;
+ open (USERID, "+>userids");
+ print (USERID "$userid\n");
+ close USERID;
+ }
+
+#
+# Group ID
+#
+
+print "Please enter the group id or hit enter for the default id: ";
+chop ($groupid = <STDIN>);
+
+if (!$groupid) {
+$groupid = "$defgroupid";
+}
+
+#
+# User name
+#
+
+print "Please enter the user's name: ";
+chop ($username = <STDIN>);
+
+#
+# Home directory
+#
+
+print "Please enter the users home directory or hit enter for default: ";
+chop ($userdir = <STDIN>);
+
+if (!$userdir) {
+ $userdir = "$defusrdir\/$userlogin";
+ print "$userdir\n";
+}
+
+#
+# Login Shell
+#
+
+print "Please enter the users login shell or hit enter for default: ";
+chop ($usershell = <STDIN>);
+
+if (!$usershell) {
+ $usershell = "$userdefshell";
+ print "$usershell\n";
+}
+
+#
+# Create password file entry
+#
+
+print "Opening and locking passwd file in blocking mode.\n";
+open (PASS, '>>/etc/master.passwd');
+flock (PASS, 2) || die "Can't lock passwd file, must be in use!!\n";
+print (PASS "$userlogin::$userid:$groupid::0:0:$username,,,:$userdir:$usershell\n");
+print "Unlocking and closing password file\n";
+flock (PASS,8);
+close PASS;
+print "Re-indexing password databases\n";
+system 'pwd_mkdb -p /etc/master.passwd';
+system "passwd $userlogin";
+
+#
+# Create user directory
+#
+print "Creating user directory\n";
+if (! -e $defusrdir)
+ {
+ print "$defusrdir does not exist, exiting!\n";
+ exit;
+ }
+system "mkdir $userdir";
+if (! -e $userdir)
+ {
+ print "$userdir does not exist!!\n";
+ print "This may be due to a parent dir not being there...\n";
+ exit;
+ }
+
+print "Copying user shell files\n";
+system "cp dot.login $userdir\/\.login";
+system "cp dot.profile $userdir\/\.profile";
+
+if ($usershell eq "\/bin\/csh" || $usershell eq "\/usr\/local\/bin\/tcsh")
+ {
+ system "cp dot.cshrc $userdir\/.cshrc";
+ }
+system "chmod -R 654 $userdir";
+system "chown -R $userid.$groupid $userdir";
+
+#
+# Mailings
+#
+if ($usemail)
+ {
+ print "Mailing new user notice\n";
+ system "elm \-s \"New User Mailing\" $userid $mailfile";
+ }
+
+#
+# Quotas
+#
+if ($usequota)
+ {
+ print "Editing quotas for user $userlogin\n";
+ if ($protouser) {
+ system "edquota -u -p $protouser $userlogin";
+ } else {
+ system "edquota -u $userlogin";
+ }
+}
+
+#
+# Forward files
+#
+if ($useforward)
+ {
+ print "Please enter the name of the account to forward to:";
+ chop ($account = <STDIN>);
+ if (!$account)
+ {
+ $acc = $defaccount;
+ }
+ else
+ {
+ $acc = $account;
+ }
+ print "Please enter the name of the system to forward to:";
+ chop ($system = <STDIN>);
+ if (!$system)
+ {
+ $sys = $defsystem;
+ }
+ else
+ {
+ $sys = $system;
+ }
+ print "Creating \.forward file for user $userlogin\n";
+ open (FORWARD, ">$userdir\/\.forward");
+ print (FORWARD "$acc@$sys\n");
+ close FORWARD;
+ system "chown $userid\.$groupid $userdir\/\.forward";
+}
+
+#
+# Print out information used in creation of this account
+#
+print "\n\n";
+print "Information used to create this account follows.\n";
+print "\n";
+print "Login Name: $userlogin\n";
+print "UserId: $userid\n";
+print "GroupId: $groupid\n";
+print "UserName: $username\n";
+print "HomeDir: $userdir\n";
+print "Shell: $usershell\n";
+if ($usemail)
+ {
+ $mailyn = "Using mailing";
+ }
+else
+ {
+ $mailyn = "Not using mailing";
+ }
+print "Mailing: $mailyn\n";
+if ($usequota)
+ {
+ $quotayn = "Using quotas";
+ }
+else
+ {
+ $quotayn = "Not using quotas";
+ }
+print "Quotas: $quotayn\n";
+if ($useforward)
+ {
+ $forwardyn = "forwarded to $acc@$sys";
+ }
+else
+ {
+ $forwardyn = "Not using forward file";
+ }
+print "ForwardFile: $forwardyn\n";
+print "\nDONE\n\n";
+
+
+
diff --git a/contrib/adduser/README b/contrib/adduser/README
new file mode 100644
index 000000000000..7ac1013e3f00
--- /dev/null
+++ b/contrib/adduser/README
@@ -0,0 +1,40 @@
+ AddIt
+ Version 0.8-Beta
+
+
+This is the README file for AddIt version 0.8Beta. AddIt is a
+perl script that is intended to make adding a user to the system simple
+and easy. Installation and use are very easy and directions follow.
+
+1. Un-tar the distribution on your system. It must have its own directory
+ due to other files it uses.
+2. Use vi to edit the userids file if your planning on using the auto id
+ option of the system. Make the userid one lower than what you want
+ to start at.
+3. Edit AddIt itself to configure the following options for use with the
+ system.
+
+ A. $defgroupid: This is the default group id the system will use.
+ B. $defusrdir: This is the default place for the system to create
+ user directories and copy needed files.
+ C. $usequota: Define this variable if you wish to use quotas on your
+ system. Make sure that you have a kernel that has this defined.
+ D. $usemail: Define this variable if you wish to have a flyer
+ mailed to the user after account creation.
+ E. $usedefshell: Define this to be the default shell on your system.
+ F. $useforward: Define this variable if you wish to have .forward
+ files created for use on the system.
+ G. $protouser: Define this variable to be the proto user for use with
+ quotas.
+ H. $mailfile: This is the file to mail to a new user when $usemail is
+ defined.
+
+5. Make sure that the default user directory ($defusrdir) exists.
+6. Run AddIt. The program will ask you questions about the user and
+ automaticly create their directory, copy startup files and then
+ do other things depending on how you have the system configured.
+
+
+As normal sugestions and bug reports to bugs@radon.gbdata.com.
+
+
diff --git a/contrib/adduser/dot.cshrc b/contrib/adduser/dot.cshrc
new file mode 100644
index 000000000000..d1e8a36ee1e4
--- /dev/null
+++ b/contrib/adduser/dot.cshrc
@@ -0,0 +1,27 @@
+# .cshrc initialization
+
+alias df df -k
+alias du du -k
+alias f finger
+alias h 'history -r | more'
+alias j jobs -l
+alias la ls -a
+alias lf ls -FA
+alias ll ls -lgsA
+alias su su -m
+alias tset 'set noglob histchars=""; eval `\tset -s \!*`; unset noglob histchars'
+alias x exit
+alias z suspend
+
+set path = (~/bin /bin /usr/{bin,new,games,local,old} .)
+
+if ($?prompt) then
+ # An interactive shell -- set some stuff up
+ set filec
+ set history = 1000
+ set ignoreeof
+ set mail = (/var/mail/$USER)
+ set mch = `hostname -s`
+ set prompt = "$mch:q:$cwd:t {\!} "
+ umask 2
+endif
diff --git a/contrib/adduser/dot.login b/contrib/adduser/dot.login
new file mode 100644
index 000000000000..bdbc7506830f
--- /dev/null
+++ b/contrib/adduser/dot.login
@@ -0,0 +1,15 @@
+#csh login file
+
+if ( ! $?TERMCAP ) then
+ tset -Q '-mdialup:?vt100' $TERM
+endif
+
+stty newcrt crterase
+
+set savehist=100
+set ignoreeof
+
+setenv EXINIT 'set ai sm noeb'
+setenv HOSTALIASES $HOME/.hostaliases
+
+/usr/games/fortune
diff --git a/contrib/adduser/dot.profile b/contrib/adduser/dot.profile
new file mode 100644
index 000000000000..95ed15cdc5ba
--- /dev/null
+++ b/contrib/adduser/dot.profile
@@ -0,0 +1,2 @@
+PATH=/bin:/usr/bin:/usr/new:/usr/local:/usr/games:/usr/old:.
+export PATH HOME TERM
diff --git a/contrib/adduser/userids b/contrib/adduser/userids
new file mode 100644
index 000000000000..2bc4cd64b870
--- /dev/null
+++ b/contrib/adduser/userids
@@ -0,0 +1 @@
+510
diff --git a/contrib/configit/ConfigIt b/contrib/configit/ConfigIt
new file mode 100755
index 000000000000..0899cba4faad
--- /dev/null
+++ b/contrib/configit/ConfigIt
@@ -0,0 +1,761 @@
+#!/usr/bin/perl
+#
+# Copyright (c) 1994 GB Data Consulting
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# 3. The name of the Author may not be used to endorse or promote products
+# derived from this software without specific prior written permission.
+# 4. This license extends only to network distributed versions.
+# All even number versions are non-network.
+# THIS SOFTWARE IS PROVIDED BY GB DATA AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL GB DATA OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+#
+#
+#
+# $Id: ConfigIt,v 1.2 1994/05/02 06:57:47 gclarkii Exp $
+#
+
+&config;
+&standard_devices;
+&menu;
+
+sub menu {
+system "clear";
+
+print " ConfigIt!\n";
+print " A auto-configuration system\n";
+print "\n\n\n";
+
+print " 1 Disk devices\n";
+print " 2 Serial devices\n";
+print " 3 Network devices\n";
+print " 4 Console devices\n";
+print " 5 Tape devices\n";
+print " 6 Misc devices and options\n";
+print " 7 Parallel devices\n";
+print "\n\n";
+print "Please enter you choice or q to quit: ";
+chop ($choice = <STDIN>);
+
+if ($choice eq ('q' || 'Q'))
+ {
+ print (CONFIG "\n\n\n");
+ close CONFIG;
+ exit; }
+ elsif ($choice == 1)
+ { &disk_devices; }
+ elsif ($choice == 2 && !$serdevsflag)
+ { &serial_devices; }
+ elsif ($choice == 3 && !$netdevsflag)
+ { &network_devices; }
+ elsif ($choice == 4)
+ { &console_devices; }
+ elsif ($choice == 5)
+ { &tape_devices; }
+ elsif ($choice == 6)
+ { &misc_dev_option; }
+ elsif ($choice == 7)
+ { &parallel_ports; }
+ else
+ { &menu; }
+&menu;
+
+}
+
+
+sub config {
+system "clear";
+print " ConfigIt!\n";
+print " A Auto-configuration System\n\n";
+print "Please enter the name of your system: ";
+chop ($systemname = <STDIN>);
+$systemname =~ tr/a-z/A-Z/;
+open (CONFIG, ">>$systemname");
+
+}
+
+
+sub config_serial_devices {
+print (CONFIG "\n#Multi-port Config\n");
+print "Multi-port Comm-Cards are not supported at this time....\n\n";
+sleep 3;
+
+}
+
+
+sub console_devices {
+system "clear";
+print " Console Devices\n\n";
+print " 1 Syscons\n";
+print " 2 Pccons\n";
+print "\n\n\n";
+print "Please enter your choice (q or Q to quit): ";
+chop ($cdevs = <STDIN>);
+
+if ($cdevs == 1 && !$condevsflag)
+ { &syscons; }
+elsif ($cdevs == 2 && !$condevsflag)
+ { &pccons; }
+elsif ($cdevs eq 'q')
+ { return; }
+elsif ($cdevs eq 'Q')
+ { return; }
+else {
+ &console_devices; }
+}
+
+
+
+sub disk_devices {
+
+ system "clear";
+ local ($choice);
+ print " Disk Device Sub-section\n\n";
+ print " 1 WD drives\n";
+ print " 2 SCSI drives\n";
+ print " 3 Floppy & QIC-40/80 Drives\n";
+ print " 4 Mitsumi CD-ROM Drive\n";
+ print "\n\n";
+ print "Please enter your choice: ";
+ chop ($choice = <STDIN>);
+
+ if ($choice eq ('q' || 'Q'))
+ { return; }
+ elsif ($choice == 1 && !$wdflag)
+ { &wd_drives; }
+ elsif ($choice == 2 && !$scsidevflag)
+ { &scsi_drives; }
+ elsif ($choice == 3 && !$floppyflag)
+ { &floppy_drives; }
+ elsif ($choice == 4 && !$mitsumiflag)
+ { &mitsumi_drive; }
+ else
+ { &disk_devices; }
+}
+
+
+sub doonecard {
+$cardnum = @_[0];
+
+system "clear";
+print " 1 AT&T EN100/STARLAN 10\n";
+print " 2 ISOLAN AT 4141-0\n or ISOLINK 4110\n";
+print " 3 WD/SMC 8003 & 8013\n";
+print " 4 SMC Ultra Elite 16\n";
+print " 5 3com 3c503\n";
+print " 6 NE1000/NE2000\n";
+print "\n\nPlease enter the type of network card number $cardnum : ";
+chop ($netcardchoice = <STDIN>);
+print "Please enter the port (in hex) address of the card: ";
+chop ($netcardadd = <STDIN>);
+print "Please enter the irq of the card: ";
+chop ($netcardirq = <STDIN>);
+
+if ($netcardchoice != 2)
+ { print "Please enter the I/O mem of the card: ";
+ chop ($netcardiomem = <STDIN>);
+ }
+
+if ($netcardchoice != (2 || 1))
+ {
+ if ($ednum < 1) {
+ $cardty = 'ed0';
+ $ednum++;
+ } else {
+ $cardty = "ed$ednum";
+ $ednum++;
+ }
+ $interp = 'edintr';
+ }
+
+if ($netcardchoice == 2)
+ {
+ if ($isnum < 1) {
+ $cardty = 'is0';
+ $isnum++;
+ } else {
+ $cardty = "is$isnum";
+ $isnum++;
+ }
+ $interp = 'isintr';
+ }
+
+if ($netcardchoice == 1)
+ {
+ if ($ienum < 1) {
+ $cardty = 'ie0';
+ $ienum++;
+ } else {
+ $cardty = "ie$ienum";
+ $ienum++
+ }
+ $interp = 'ieintr';
+ }
+
+print (CONFIG "device $cardty at isa? port $netcardadd net irq $netcardirq iomem $netcardiomem vector $interp\n");
+
+}
+
+
+sub floppy_drives
+{
+$floppyflag = 1;
+system "clear";
+print (CONFIG "\n#Disk devices\n\n");
+
+print "How many floppys do you have?: ";
+chop ($flch = <STDIN>);
+if ($flch > 0)
+ {
+ print (CONFIG "controller fdc0 at isa? port \"IO_FD1\" bio irq 6 drq 2 vector fdintr\n");
+ print (CONFIG "disk fd0 at fdc0 drive 0\n");
+ print (CONFIG "disk fd1 at fdc0 drive 1\n");
+ }
+if ($flch > 0)
+ {
+ print "Do you have a QIC-40/80 drive?: ";
+ chop ($qic40 = <STDIN>);
+ if ($qic40 eq 'y' || $qic40 eq 'Y')
+ {
+ print (CONFIG "tape ft0 at fdc0 drive 2\n");
+ }
+ }
+}
+
+
+sub misc_dev_option {
+system "clear";
+$miscdevflag = 1;
+print (CONFIG "\n# Misc Devices\n");
+print "Do you want kernel tracing?: ";
+chop ($ktrace = <STDIN>);
+if ($ktrace eq ('y' || 'Y'))
+ {
+ print (CONFIG "options KTRACE\n");
+ }
+print "Do you want kernel debugging?: ";
+chop ($kddb = <STDIN>);
+if ($kddb eq ('y' || 'Y'))
+ {
+ print (CONFIG "pseudo-device ddb\n");
+ }
+print "Do you want fast symlinks?: ";
+chop ($fastlinks = <STDIN>);
+if ($fastlinks eq ('y' || 'Y'))
+ {
+ print (CONFIG "options FASTLINKS\n");
+ }
+print "Do you want PC file system support?: ";
+chop ($pcfs = <STDIN>);
+if ($pcfs eq ('y' || 'Y'))
+ {
+ print (CONFIG "options PCFS\n");
+ }
+print "Do you want Memory File System support?: ";
+chop ($mfs = <STDIN>);
+if ($mfs eq ('y' || 'Y'))
+ {
+ print (CONFIG "options MFS\n");
+ }
+print "Do you want QUOTA support?: ";
+chop ($quota = <STDIN>);
+if ($quota eq ('y' || 'Y'))
+ {
+ print (CONFIG "options QUOTA\n");
+ }
+print "Do you want FIFO support?: ";
+chop ($fifo = <STDIN>);
+if ($fifo eq ('y' || 'Y'))
+ {
+ print (CONFIG "options FIFO\n");
+ }
+print "Do you want ISO File System support?: ";
+chop ($isofs = <STDIN>);
+if ($isofs eq ('y' || 'Y'))
+ {
+ print (CONFIG "options ISOFS\n");
+ }
+
+}
+
+
+sub mitsumi_drive {
+system "clear";
+$mitsumiflag = 1;
+print (CONFIG "\n#Disk devices\n\n");
+
+print "What address (hex) is the mitsumi controller at?: ";
+chop ($mitadd = <STDIN>);
+print "What interupt is the mitsumi controller at?: ";
+chop ($mitint = <STDIN>);
+print (CONFIG "device mcd at isa? port $mitadd bio irq $mitint vector mcdint\n");
+}
+
+#
+# Multi-port support for serial_devices.pl
+#
+# $Id: ConfigIt,v 1.2 1994/05/02 06:57:47 gclarkii Exp $
+#
+
+
+sub multiport {
+$numstandm = @_[0];
+system "clear";
+print "NOTE: Only 1 multiport card is supported by ConfigIt.\n";
+print "Please enter the number of ports on the card: ";
+ chop ($multinum = <STDIN>);
+print "Please enter the starting port of the card: ";
+ chop ($startm = <STDIN>);
+print "Please enter the port number of the master port or 0 if none: ";
+ chop ($multimaster = <STDIN>);
+print "Please enter the intrupt of the card: ";
+ chop ($multiint = <STDIN>);
+print (CONFIG "\n#Multi-port serial devices\n\n");
+print (CONFIG "options \"COM_MULTIPORT\"\n");
+
+$portm = $startm;
+$startm =~ tr/a-z/A-Z/;
+
+ for ($i = 1; $i < $multinum + 1; $i++) {
+ $siom = $i + $numstandm;
+ $siom = $siom - 1;
+ if ($siom < 10) { $sio = "sio0"; } else { $sio = "sio"; }
+
+ if ($multimaster != $i) {
+ print (CONFIG "device $sio$siom at isa? port $portm flags 0x501 vector siointr\n");
+ } else {
+ print (CONFIG "device $sio$siom at isa? port $portm tty irq $multiint flags 0x501 vector siointr\n");
+ }
+$portm =~ tr/A-Z/a-z/;
+$numorig = hex ("$portm");
+$numadd = hex ("0x08");
+$numend = $numadd + $numorig;
+$endm = sprintf ("%lx", $numend);
+$end1m = $endm;
+$portm = "0x$end1m";
+$portm =~ tr/a-z/A-Z/;
+
+ }
+if ($numstandm > 0) { &standard_serial; }
+}
+
+sub network_devices {
+system "clear";
+$netdevsflag = 1;
+print (CONFIG "\n# Network devices\n");
+print "How many networking cards do you have: ";
+chop ($numnet = <STDIN>);
+
+if ($numnet != 0) {
+for ($i = 1; $i <= $numnet ; $i++)
+{
+ &doonecard($i);
+ }
+}
+
+print "Do you need the SLIP device in the kernel?: ";
+chop ($slipch = <STDIN>);
+if ($slipch eq ('y' || 'Y'))
+ {
+ print "How many slip devices do you need: ";
+ chop ($slipno = <STDIN>);
+ print (CONFIG "pseudo-device slip $slipno\n");
+ }
+
+print "Do you need the PPP device in the kernel?: ";
+chop ($pppch = <STDIN>);
+if ($pppch eq ('y' || 'Y'))
+ {
+ print "How many PPP devices do you need: ";
+ chop ($pppno = <STDIN>);
+ print (CONFIG "pseudo-device ppp $pppno\n");
+ }
+
+print "Do you want Berkeley Packet Filter support?: ";
+chop ($bpf = <STDIN>);
+if ($bpf eq ('y' || 'Y'))
+ {
+ print (CONFIG "pseudo-device bpf\n");
+ }
+
+print "Do you want Internetwork Gateway support?: ";
+chop ($gateway = <STDIN>);
+if ($gateway eq ('y' || 'Y'))
+ {
+ print (CONFIG "option GATEWAY\n");
+ }
+
+print "Do you want NFS support?: ";
+chop ($nfs = <STDIN>);
+if ($nfs eq ('y' || 'Y'))
+ {
+ print (CONFIG "option NFS\n");
+ }
+
+print "How many pty's do you want?: ";
+chop ($ptyno = <STDIN>);
+if ($ptyno eq ('y' || 'Y'))
+ {
+ print (CONFIG "pseudo-device pty $ptyno\n");
+ }
+
+}
+
+
+#
+#
+#
+
+sub parallel_ports {
+
+print "How many parallel ports do you have: ";
+ chop ($paranum = <STDIN>);
+
+if ($paranum) {
+print (CONFIG "\n#Parallel devices\n\n");
+
+for ($i = 1; $i <= $paranum; $i++) {
+ $lpanum = $i - 1;
+ print "Please enter the address for parallel port number $i : ";
+ chop ($paraport = <STDIN>);
+ print "If you are running with out interupts on this port please\n";
+ print "anwser 0 to the following question.\n";
+ print "Please enter the interupt for parallel port number $i : ";
+ chop ($paraint = <STDIN>);
+ if ($paraint) {
+ print (CONFIG "device lpa$lpanum at isa? port $paraport tty irq $paraint vector lptintr\n");
+ } else {
+ print (CONFIG "device lpa$lpanum at isa? port $paraport tty vector lptintr\n");
+ }
+
+ }
+
+ }
+
+}
+
+sub pccons {
+$condevsflag = 1;
+print (CONFIG "\n# Console devices\n\n");
+print (CONFIG "device pc0 at isa? port \"IO_KBD\" tty irq 1 vector pcrint\n");
+
+}
+
+
+sub scsi_drives {
+$scsidevsflag = 1;
+system "clear";
+print (CONFIG "\n# SCSI Devices\n\n");
+print " 1 Adaptec 1542/Bustec 542\n";
+print " 2 Adaptec 1742\n";
+print " 3 Bustec 742\n";
+print " 4 Ultrastore 14F/34F\n";
+print "\n\n";
+print "Enter your choice or q to quit: ";
+chop ($scsicho = <STDIN>);
+
+if ($scsicho eq 'q' || $scsicho eq 'Q')
+ {
+ return;
+ }
+elsif ($scsicho == 1)
+ {
+ $scsicard = "aha0";
+ $scsiio = "\"IO_AHA0\"";
+ $scsiint = "ahaintr";
+ }
+elsif ($scsicho == 2)
+ {
+ $scsicard = "ahb0";
+ $scsiint = "ahbintr";
+ }
+elsif ($scsicho == 3)
+ {
+ $scsicard = "bt0";
+ $scsiio = "\"IO_BT0\"";
+ $scsiint = "btintr";
+ }
+elsif ($scsicho == 4)
+ {
+ $scsicard = "uha0";
+ $scsiio = "\"IO_UHA0\"";
+ $scsiio = "uhaintr";
+ }
+else { &scsi_drives; }
+
+if ($scsicho == 2)
+ {
+ print "Please enter the interupt the AHA-1742 is on: ";
+ chop ($scsiirq = <STDIN>);
+ print (CONFIG "contoller ahb0 at isa? bio irq $scsiirq vector $scsiint\n");
+ }
+elsif ($scsicho == 1 || $scsicho == 4)
+ {
+ print "Please enter the interupt the SCSI controller is on: ";
+ chop ($scsiirq = <STDIN>);
+ print "Please enter the dma channel the SCSI controller is on: ";
+ chop ($scsidrq = <STDIN>);
+ print (CONFIG "controller $scsicard at isa? port $scsiio bio irq $scsiirq drq $scsidrq vector $scsiint\n");
+ }
+else
+ {
+ print "Please enter the interupt the SCSI controller is on: ";
+ chop ($scsiirq = <STDIN>);
+ print (CONFIG "controller $scsicard at isa? port $scsiio bio irq $scsiirq vector $scsiint\n");
+ }
+
+print (CONFIG "device sd0\n");
+print (CONFIG "device sd1\n");
+print (CONFIG "device sd2\n");
+print (CONFIG "device sd3\n");
+print (CONFIG "device st1\n");
+print (CONFIG "device st2\n");
+print (CONFIG "device cd0\n");
+
+}
+
+#
+# Do serial ports, only standard ones are here
+#
+#
+
+sub serial_devices {
+system "clear";
+$serdevsflag = 1;
+
+print "Do you have a multi-port card (Non-standard serial card): ";
+ chop ($multicard = <STDIN>);
+print "Please enter the number of standard serial ports you have: ";
+ chop ($numstand = <STDIN>);
+
+ if ($multicard eq ( 'y' || 'Y')) {
+ print "Please enter the number of standard serial ports you also have: ";
+ &multiport($numstand);
+ } else {
+ &standard_serial($numstand);
+ }
+print "Do you wish to have bidirectionl serial ports: ";
+ chop ($bidir = <STDIN>);
+ if ($bidir eq ('y' || 'Y')) {
+ print (CONFIG "options \"COM_BIDIR\"\n");
+ }
+}
+
+
+sub standard_devices {
+system "clear";
+print "What timezone are you in? (cst = 6): ";
+chop ($time = <STDIN>);
+print "What type of cpu do you have? ( 386 or 486 ): ";
+chop ($cputype = <STDIN>);
+
+if ($cputype == 386)
+ {
+ print "Do you have a 387?: ";
+ chop ($mathco = <STDIN>);
+ }
+
+if ($cputype == 486)
+ {
+ print "Is it a DX or SX?: ";
+ chop ($dxsx = <STDIN>);
+ if ($dxsz eq 'SX' || $dxsx eq 'sx')
+ {
+ $mathco = 'n';
+ }
+ }
+
+chop ($date = `date`);
+chop ($whoami = `whoami`);
+
+print (CONFIG "\n#\n#Config file for $systemname\n");
+print (CONFIG "#Generated by ConfigIt!\n");
+print (CONFIG "#Generated at $date by $whoami\n#\n#\n\n");
+
+print (CONFIG "#Generic Items\n\n");
+print (CONFIG "machine \"i386\"\n");
+print (CONFIG "cpu \"I","$cputype","_CPU\"\n");
+
+if ($mathco eq 'n' || $mathco eq 'N')
+ {
+ print "Do you wish to use the new math emulator (its better): ";
+ chop ($choicesti = <STDIN>);
+ if ($choicesti eq ('y' || 'Y')) {
+ print (CONFIG "options GPL_MATH_EMULATE\n");
+ } else {
+ print (CONFIG "options MATH_EMULATE\n");
+ }
+}
+
+print "The following is used to set certain parameters.\n";
+print "Please enter the number of users you expect: ";
+ chop ($maxusers = <STDIN>);
+if ($maxusers <= 10) { $maxusers = 10; }
+print (CONFIG "ident $systemname\n");
+print (CONFIG "maxusers $maxusers\n");
+print (CONFIG "maxfdescs 2000\n");
+print (CONFIG "timezone $time dst\n");
+print (CONFIG "options \"COMPAT_43\"\n");
+print (CONFIG "options UCONSOLE\n");
+print (CONFIG "options XSERVER\n");
+print (CONFIG "options INET\n");
+print "What device is root on? (e.g. \"wd0\"): ";
+chop ($root = <STDIN>);
+if ($root) {
+$roots = "root on $root";
+} else { print "ABORTING you must have a root!\n"; exit; }
+
+print "What device is swap on? (e.g. \"wd0\" or \"wd0 and wd1\"): ";
+chop ($swap = <STDIN>);
+if ($swap) {
+$swaps = "swap on $swap";
+}
+print "What device is dump on? (e.g. \"wd0\"): ";
+chop ($dump = <STDIN>);
+if ($dumps) {
+$dumps = "dumps on $dump";
+}
+
+print (CONFIG "config \"386bsd\" $roots $swaps $dumps \n");
+print (CONFIG "pseudo-device vnodepager\n");
+print (CONFIG "pseudo-device swappager\n");
+print (CONFIG "pseudo-device devpager\n");
+print (CONFIG "pseudo-device ether\n");
+print (CONFIG "pseudo-device loop\n");
+print (CONFIG "pseudo-device log\n");
+print (CONFIG "pseudo-device speaker\n");
+print (CONFIG "device isa0\n");
+
+}
+
+
+#
+# Do standard serial ports
+#
+
+sub standard_serial {
+$sernumss = @_[0];
+
+ print "Are the $sernumss standard ports at the standard location and interup: ";
+ chop ($standss = <STDIN>);
+if ($standss eq ('y' || 'Y')) {
+
+ if ($sernumss == 0 || $sernumss > 4)
+ { print "invalid number of serial ports!!\n\n";
+ print "Please hit any key to continue.";
+ while (!($kbhit = <STDIN>)) {}
+ &serial_devices;}
+
+ if ($sernumss < 3) {
+ print (CONFIG "\n#Standard serial devices\n\n");
+ print (CONFIG "device sio00 at isa? port \"IO_COM1\" tty irq 4 vector siointr\n");
+ print (CONFIG "device sio01 at isa? port \"IO_COM2\" tty irq 3 vector siointr\n");
+ } else {
+ print (CONFIG "\n#Standard serial devices\n\n");
+ print (CONFIG "device sio00 at isa? port \"IO_COM1\" tty irq 4 vector siointr\n");
+ print (CONFIG "device sio01 at isa? port \"IO_COM2\" tty irq 3 vector siointr\n");
+ print (CONFIG "device sio02 at isa? port \"IO_COM3\" tty irq 5 vector siointr\n");
+ print (CONFIG "device sio03 at isa? port \"IO_COM4\" tty irq 9 vector siointr\n"); }
+
+} else {
+ print (CONFIG "\n#Standard serial devices\n\n");
+
+ for ($i = 1;$i <= $sernum;$i++) {
+ print "Please enter the intrupt for serial port number $i: ";
+ chop ($intt = <STDIN>);
+ print "Please enter the address for serial port number $i: ";
+ chop ($portk = <STDIN>);
+ $iik = $i - 1;
+ print (CONFIG "device sio0$iik at isa port $portk tty irq $intt vector siointr\n");
+
+ }
+ }
+}
+
+
+
+sub syscons {
+print (CONFIG "\n#Console device\n");
+
+$condevsflag = 1;
+system "clear";
+print (CONFIG "device sc0 at isa? port \"IO_KBD\" tty irq 1 vector scintr\n");
+print "How many virtual terminals do you want? (max 8): ";
+chop ($numvty = <STDIN>);
+if ($numvty == 0 || $numvty > 8)
+ { $numvty = 1; }
+print (CONFIG "options \"NCONS=$numvty\"\n");
+print (CONFIG "options \"STAR_SAVER\"\n");
+print (CONFIG "options \"FADE_SAVER\"\n");
+print (CONFIG "options \"SNAKE_SAVER\"\n");
+print (CONFIG "options \"BLANK_SAVER\"\n");
+
+}
+
+
+sub tape_devices
+{
+system "clear";
+print (CONFIG "\n# QIC-02 Tape devices\n\n");
+$tapdevsflag = 1;
+print "Do you have a QIC-02 tape drive?: ";
+chop ($qic02 = <STDIN>);
+if ($qic02 eq ('y' || 'Y'))
+ {
+print "What address is it at? (Hex): ";
+chop ($qic02add = <STDIN>);
+print "What interupt is it at?: ";
+chop ($qic02int = <STDIN>);
+print (CONFIG "device wt0 at isa? port $qic02add bio irq $qic02int drq 1 vector wtintr\n");
+ }
+}
+
+
+sub wd_drives {
+ $wdflag = 1;
+ local ($choice);
+ system "clear";
+ print (CONFIG "\n#Disk devices\n\n");
+
+ print " WD Drive Configuration\n\n";
+ print "How many WD drives do you have (Max of 4): ";
+ chop ($choice = <STDIN>);
+
+ if ($choice >= 3 ) {
+ print "\n";
+ print (CONFIG "controller wdc0 at isa? port \"IO_WD1\" bio irq 14 vector wdintr\n");
+ print "\n";
+ print (CONFIG "disk wd0 at wdc0 drive 0\n");
+ print (CONFIG "disk wd1 at wdc1 drive 1\n");
+ print (CONFIG "controller wdc1 at isa? port \"IO_WD2\" bio irq 15 vector wdintr\n");
+ print (CONFIG "disk wd2 at wdc1 drive 0\n");
+ print (CONFIG "disk wd3 at wdc1 drive 1\n");
+ print "\n";
+ } else {
+ print "\n";
+ print (CONFIG "controller wdc0 at isa? port \"IO_WD1\" bio irq 14 vector wdintr\n");
+ print "\n";
+ print (CONFIG "disk wd0 at wdc0 drive 0\n");
+ print (CONFIG "disk wd1 at wdc0 drive 1\n");
+ print "\n";
+ }
+}
+
diff --git a/contrib/configit/README b/contrib/configit/README
new file mode 100644
index 000000000000..cf3481d06846
--- /dev/null
+++ b/contrib/configit/README
@@ -0,0 +1,32 @@
+
+
+
+This is the README file for ConfigIt!, a kernel configuration file generator
+for FreeBSD 1.1Beta and above. ConfigIt! is a menu driven program that
+askes what options and devices you want in your kernel. For more information
+on what the various options and devices are please see the file options.texi
+in /sys/i386/doc.
+
+To run ConfigIt! you must have Perl 4.036 (It has not been tested with Perl 5).
+
+Steps needed to run ConfigIt!:
+1. Make sure that you have Perl installed on your system.
+2. Untar the archive in the directory where you wish to run it.
+3. Run the program.
+4. Copy the resulting config file to /sys/i386/conf.
+5. Run config SYSTEM_NAME.
+6. Change directory to /sys/compile/SYSTEM_NAME.
+7. Run make depend and then make in /sys/compile/SYSTEM_NAME.
+
+And thats it!
+
+If you have any questions, suggestions or whatever you can reach me
+at gclarkii@freefall.cdrom.com. Please DO NOT send questions about ConfigIt!
+to the mailing lists.
+
+Enjoy,
+
+Gary Clark II
+gclarkii@freefall.cdrom.com
+
+
diff --git a/contrib/configit/TODO b/contrib/configit/TODO
new file mode 100644
index 000000000000..9ab174419219
--- /dev/null
+++ b/contrib/configit/TODO
@@ -0,0 +1,9 @@
+TODO list for ConfigIt!
+Version 0.1 BETA
+
+1. Make the system more robust in taking anwsers to questions.
+2. Better SCSI support.
+3. Make it faster.
+4. Add more options that it will configure.
+5. Clean up code so that columns are lined up.
+
diff --git a/contrib/crunch/COPYRIGHT b/contrib/crunch/COPYRIGHT
new file mode 100644
index 000000000000..c7b4d2f9ae57
--- /dev/null
+++ b/contrib/crunch/COPYRIGHT
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 1994 University of Maryland
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of U.M. not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. U.M. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: James da Silva, Systems Design and Analysis Group
+ * Computer Science Department
+ * University of Maryland at College Park
+ */
diff --git a/contrib/crunch/Makefile b/contrib/crunch/Makefile
new file mode 100644
index 000000000000..a38e0b9061df
--- /dev/null
+++ b/contrib/crunch/Makefile
@@ -0,0 +1,4 @@
+
+SUBDIR=crunchgen crunchide
+
+.include <bsd.subdir.mk>
diff --git a/contrib/crunch/Makefile.inc b/contrib/crunch/Makefile.inc
new file mode 100644
index 000000000000..da4210505219
--- /dev/null
+++ b/contrib/crunch/Makefile.inc
@@ -0,0 +1,2 @@
+# modify to taste
+BINDIR?= /usr/bin
diff --git a/contrib/crunch/README b/contrib/crunch/README
new file mode 100644
index 000000000000..27c2d0298afb
--- /dev/null
+++ b/contrib/crunch/README
@@ -0,0 +1,88 @@
+
+CRUNCH 0.2 README 6/14/94
+
+Crunch is available via anonymous ftp to ftp.cs.umd.edu in
+ pub/bsd/crunch-0.2.tar.gz
+
+
+WHAT'S NEW IN 0.2
+
+* The prototype awk script has been replaced by a more capable and
+ hopefully more robust C program.
+* No fragile template makefiles or dependencies on the details of the
+ bsd build environment.
+* You can build crunched binaries even with no sources on-line, you
+ just need the .o files. Crunchgen still will try to figure out as
+ much as possible on its own, but you can override its guessing by
+ specifying the list of .o files explicitly.
+* Crunch itself has been bmake'd and some man pages written, so it
+ should be ready to install.
+
+
+INTRODUCTION
+
+Crunch is a little package that helps create "crunched" binaries for use
+on boot, install, and fixit floppies. A crunched binary in this case is
+one where many programs have been linked together into one a.out file.
+The different programs are run depending on the value of argv[0], so
+hard links to the crunched binary suffice to simulate a perfectly normal
+system.
+
+As an example, I have created an 980K crunched "fixit" binary containing
+the following programs in their entirety:
+
+ cat chmod cp date dd df echo ed expr hostname kill ln ls mkdir
+ mt mv pwd rcp rm rmdir sh sleep stty sync test [ badsect chown
+ clri disklabel dump rdump dmesg fdisk fsck halt ifconfig init
+ mknod mount newfs ping reboot restore rrestore swapon umount
+ ftp rsh sed telnet rlogin vi cpio gzip gunzip gzcat
+
+Note carefully: vi, cpio, gzip, ed, sed, dump/restore, some networking
+utilities, and the disk management utilities, all in a binary small
+enough to fit on a 1.2 MB root filesystem floppy (albeit with the kernel
+on its own boot floppy). A more reasonable subset can be made to fit
+easily with a kernel for a decent one-disk fixit filesystem.
+
+The linking together of different programs by hand is an old
+space-saving technique. Crunch automates the process by building the
+necessary stub files and makefile for you (via the crunchgen program),
+and by doctoring the symbol tables of the component .o files to allow
+them to link without "symbol multiply defined" conflicts (via the
+crunchide program).
+
+
+BUILDING CRUNCH
+
+Just type make, then make install.
+
+Crunch was written and tested under NetBSD/i386, but should work under
+other PC BSD systems that use GNU ld.
+
+The crunchgen(1) and crunchide(1) man pages have more details on using
+crunch, and the examples subdirectory contains some working .conf files
+and a sample Makefile.
+
+CREDITS
+
+Thanks to the NetBSD team for a consistently high quality effort in
+bringing together a solid, state of the art development environment.
+
+Thanks to the FreeBSD guys; Rod Grimes, Nate Williams and Jordan
+Hubbard; and to Bruce Evans, for immediate and detailed feedback on
+crunch 0.1, and for pressing me to make the prototype more useable.
+
+Crunch was written for the Maruti Hard Real-Time Operating System
+project at the University of Maryland, to help make for better install
+and recovery procedures for our NetBSD-based development environment. It
+is copyright (c) 1994 by the University of Maryland under a UCB-style
+freely- redistributable notice. See the file COPYRIGHT for details.
+
+Please let me know of any problems or of enhancements you make to this
+package. I'm particularly interested in the details of what you found
+was good to put on your fixit or install disks. Thanks!
+
+Share and Enjoy,
+Jaime
+............................................................................
+: Stand on my shoulders, : jds@cs.umd.edu : James da Silva
+: not on my toes. : uunet!mimsy!jds : http://www.cs.umd.edu/users/jds
diff --git a/contrib/crunch/crunchgen/Makefile b/contrib/crunch/crunchgen/Makefile
new file mode 100644
index 000000000000..71acb214dca0
--- /dev/null
+++ b/contrib/crunch/crunchgen/Makefile
@@ -0,0 +1,9 @@
+
+PROG=crunchgen
+SRCS=crunchgen.c crunched_skel.c
+CFLAGS+=-g -Wall
+
+crunched_skel.c: crunched_main.c
+ ${.CURDIR}/mkskel.sh ${.CURDIR}/crunched_main.c >crunched_skel.c
+
+.include <bsd.prog.mk>
diff --git a/contrib/crunch/crunchgen/crunched_main.c b/contrib/crunch/crunchgen/crunched_main.c
new file mode 100644
index 000000000000..a07317aa5a6b
--- /dev/null
+++ b/contrib/crunch/crunchgen/crunched_main.c
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 1994 University of Maryland
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of U.M. not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. U.M. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: James da Silva, Systems Design and Analysis Group
+ * Computer Science Department
+ * University of Maryland at College Park
+ */
+/*
+ * crunched_main.c - main program for crunched binaries, it branches to a
+ * particular subprogram based on the value of argv[0]. Also included
+ * is a little program invoked when the crunched binary is called via
+ * its EXECNAME. This one prints out the list of compiled-in binaries,
+ * or calls one of them based on argv[1]. This allows the testing of
+ * the crunched binary without creating all the links.
+ */
+#include <stdio.h>
+#include <string.h>
+
+struct stub {
+ char *name;
+ int (*f)();
+};
+
+extern struct stub entry_points[];
+
+int main(int argc, char **argv)
+{
+ char *slash, *basename;
+ struct stub *ep;
+
+ if(argv[0] == NULL || *argv[0] == '\0')
+ crunched_usage();
+
+ slash = strrchr(argv[0], '/');
+ basename = slash? slash+1 : argv[0];
+
+ for(ep=entry_points; ep->name != NULL; ep++)
+ if(!strcmp(basename, ep->name)) break;
+
+ if(ep->name)
+ return ep->f(argc, argv);
+ else {
+ fprintf(stderr, "%s: %s not compiled in\n", EXECNAME, basename);
+ crunched_usage();
+ }
+}
+
+
+int crunched_main(int argc, char **argv)
+{
+ struct stub *ep;
+ int columns, len;
+
+ if(argc <= 1)
+ crunched_usage();
+
+ return main(--argc, ++argv);
+}
+
+
+int crunched_usage()
+{
+ int columns, len;
+ struct stub *ep;
+
+ fprintf(stderr, "Usage: %s <prog> <args> ..., where <prog> is one of:\n",
+ EXECNAME);
+ columns = 0;
+ for(ep=entry_points; ep->name != NULL; ep++) {
+ len = strlen(ep->name) + 1;
+ if(columns+len < 80)
+ columns += len;
+ else {
+ fprintf(stderr, "\n");
+ columns = len;
+ }
+ fprintf(stderr, " %s", ep->name);
+ }
+ fprintf(stderr, "\n");
+ exit(1);
+}
+
+/* end of crunched_main.c */
+
diff --git a/contrib/crunch/crunchgen/crunchgen.1 b/contrib/crunch/crunchgen/crunchgen.1
new file mode 100644
index 000000000000..8c97d66cf1de
--- /dev/null
+++ b/contrib/crunch/crunchgen/crunchgen.1
@@ -0,0 +1,266 @@
+.\"
+.\" Copyright (c) 1994 University of Maryland
+.\" All Rights Reserved.
+.\"
+.\" Permission to use, copy, modify, distribute, and sell this software and its
+.\" documentation for any purpose is hereby granted without fee, provided that
+.\" the above copyright notice appear in all copies and that both that
+.\" copyright notice and this permission notice appear in supporting
+.\" documentation, and that the name of U.M. not be used in advertising or
+.\" publicity pertaining to distribution of the software without specific,
+.\" written prior permission. U.M. makes no representations about the
+.\" suitability of this software for any purpose. It is provided "as is"
+.\" without express or implied warranty.
+.\"
+.\" U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
+.\" BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+.\" IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+.\"
+.\" Author: James da Silva, Systems Design and Analysis Group
+.\" Computer Science Department
+.\" University of Maryland at College Park
+.\"
+.Dd June 14, 1994
+.Dt CRUNCHGEN 1
+.Os BSD 4
+.Sh NAME
+.Nm \&crunchgen
+.Nd generates build environment for a crunched binary
+.Sh SYNOPSIS
+.Nm \&crunchgen
+.Op Fl fq
+.Op Fl m Ar makefile-name
+.Op Fl c Ar c-file-name
+.Op Fl e Ar exec-file-name
+.Op Ar conf-file
+.Sh DESCRIPTION
+
+A crunched binary is a program made up of many other programs linked
+together into a single executable. The crunched binary main()
+function determines which component program to run by the contents of
+argv[0]. The main reason to crunch programs together is for fitting
+as many programs as possible onto an installation or system recovery
+floppy.
+
+.Pp
+.Nm Crunchgen
+reads in the specifications in
+.Ar conf-file
+for a crunched binary, and generates a Makefile and accompanying
+top-level C source file that when built create the crunched executable
+file from the component programs. For each component program,
+.Nm crunchgen
+can optionally attempt to determine the object (.o) files that make up
+the program from its source directory Makefile. This information is
+cached between runs.
+.Nm Crunchgen
+uses the companion program
+.Nm crunchide
+to eliminate link-time conflicts between the component programs by
+hiding all unnecessary symbols.
+
+.Pp
+After
+.Nm crunchgen
+is run, the crunched binary can be built by running ``make -f
+<conf-name>.mk''. The component programs' object files must already
+be built. A ``objs'' target, included in the output makefile, will
+run make in each component program's source dir to build the object
+files for the user. This is not done automatically since in release
+engineering circumstances it is generally not desireable to be
+modifying objects in other directories.
+
+.Pp
+The options are as follows:
+.Bl -tag -width indent
+.It Fl c Ar c-file-name
+Set output C file name to
+.Ar c-file-name .
+The default name is ``<conf-name>.c''.
+.It Fl e Ar exec-file-name
+Set crunched binary executable file name to
+.Ar exec-file-name .
+The default name is ``<conf-name>''.
+.It Fl f
+Flush cache. Forces the recalculation of cached parameters.
+.It Fl m Ar makefile-name
+Set output Makefile name to
+.Ar makefile-name .
+The default name is ``<conf-name>.mk''.
+.It Fl q
+Quiet operation. Status messages are suppressed.
+.El
+.Sh CRUNCHGEN CONFIGURATION FILE COMMANDS
+
+.Nm Crunchgen
+reads specifications from the
+.Ar conf-file
+that describe the components of the crunched binary. In its simplest
+use, the component program names are merely listed along with the
+top-level source directories in which their sources can be found.
+.Nm Crunchgen
+then calculates (via the source makefiles) and caches the
+list of object files and their locations. For more specialized
+situations, the user can specify by hand all the parameters that
+.Nm crunchgen
+needs.
+.Pp
+The
+.Ar conf-file
+commands are as follows:
+.Bl -tag -width indent
+.It Nm srcdirs Ar dirname ...
+A list of source trees in which the source directories of the
+component programs can be found. These dirs are searched using the
+BSD ``<source-dir>/<progname>/'' convention. Multiple
+.Nm srcdirs
+lines can be specified. The directories are searched in the order
+they are given.
+.It Nm progs Ar progname ...
+A list of programs that make up the crunched binary. Multiple
+.Nm progs
+lines can be specified.
+.It Nm libs Ar libspec ...
+A list of library specifications to be included in the crunched binary link.
+Multiple
+.Nm libs
+lines can be specified.
+.It Nm ln Ar progname linkname
+Causes the crunched binary to invoke
+.Ar progname
+whenever
+.Ar linkname
+appears in argv[0]. This allows programs that change their behavior when
+run under different names to operate correctly.
+.El
+
+To handle specialized situations, such as when the source is not
+available or not built via a conventional Makefile, the following
+.Nm special
+commands can be used to set
+.Nm crunchgen
+parameters for a component program.
+.Bl -tag -width indent
+.It Nm special Ar progname Nm srcdir Ar pathname
+Set the source directory for
+.Ar progname .
+This is normally calculated by searching the specified
+.Nm srcdirs
+for a directory named
+.Ar progname .
+.It Nm special Ar progname Nm objdir Ar pathname
+Set the obj directory for
+.Ar progname .
+This is normally calculated by looking for a directory named
+.Dq Pa obj
+under the
+.Ar srcdir ,
+and if that is not found, the
+.Ar srcdir
+itself becomes the
+.Ar objdir .
+.It Nm special Ar progname Nm objs Ar object-file-name ...
+Set the list of object files for program
+.Ar progname .
+This is normally calculated by constructing a temporary makefile that includes
+.Dq Nm srcdir / Pa Makefile
+and outputs the value of $(OBJS).
+.It Nm special Ar progname Nm objpaths Ar full-pathname-to-object-file ...
+Sets the pathnames of the object files for program
+.Ar progname .
+This is normally calculated by prepending the
+.Nm objdir
+pathname to each file in the
+.Nm objs
+list.
+.El
+
+.Pp
+Only the
+.Nm objpaths
+parameter is actually needed by
+.Nm crunchgen ,
+but it is calculated from
+.Nm objdir
+and
+.Nm objs ,
+which are in turn calculated from
+.Nm srcdir ,
+so is sometimes convenient to specify the earlier parameters and let
+.Nm crunchgen
+calculate forward from there if it can.
+
+.Pp
+The makefile produced by
+.Nm crunchgen
+contains an optional
+.Ar objs
+target that will build the object files for each component program by
+running make inside that program's source directory. For this to work the
+.Nm srcdir
+and
+.Nm objs
+parameters must also be valid. If they are not valid for a particular program, that
+program is skipped in the
+.Ar objs
+target.
+.Sh EXAMPLE
+Here is an example
+.Nm crunchgen
+input conf file, named
+.Dq Pa kcopy.conf :
+.Pp
+.nf
+ srcdirs /usr/src/bin /usr/src/sbin
+
+ progs test cp echo sh fsck halt init mount umount myinstall
+ ln test [ # test can be invoked via [
+ ln sh -sh # init invokes the shell with "-sh" in argv[0]
+
+ special myprog objpaths /homes/leroy/src/myinstall.o # no sources
+
+ libs -lutil -lcrypt
+.fi
+.Pp
+This conf file specifies a small crunched binary consisting of some
+basic system utilities plus a homegrown install program ``myinstall'',
+for which no source directory is specified, but its object file is
+specified directly with the
+.Nm special
+line.
+.Pp
+The crunched binary ``kcopy'' can be built as follows:
+.Pp
+.nf
+ % crunchgen -m Makefile kcopy.conf # gen Makefile and kcopy.c
+ % make objs # build the component progams' .o files
+ % make # build the crunched binary kcopy
+ % kcopy sh # test that this invokes a sh shell
+ $ # it works!
+.fi
+.Pp
+At this point the binary ``kcopy'' can be copied onto an install floppy
+and hard-linked to the names of the component programs.
+.Sh SEE ALSO
+.Xr crunchide 1
+.Sh CAVEATS
+While
+.Nm crunch
+takes care to eliminate link conflicts between the component programs
+of a crunched binary, conflicts are still possible between the
+libraries that are linked in. Some shuffling in the order of
+libraries may be required, and in some rare cases two libraries may
+have an unresolveable conflict and thus cannot be crunched together.
+.Pp
+Some versions of the BSD build environment do not by default build the
+intermediate object file for single-source file programs. The ``make
+objs'' target must then be used to get those object files built, or
+some other arrangements made.
+.Sh AUTHOR
+.Nm Crunch
+was written by James da Silva <jds@cs.umd.edu>.
+.sp 0
+Copyright (c) 1994 University of Maryland. All Rights Reserved.
diff --git a/contrib/crunch/crunchgen/crunchgen.c b/contrib/crunch/crunchgen/crunchgen.c
new file mode 100644
index 000000000000..6e9af1880dd9
--- /dev/null
+++ b/contrib/crunch/crunchgen/crunchgen.c
@@ -0,0 +1,856 @@
+/*
+ * Copyright (c) 1994 University of Maryland
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of U.M. not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. U.M. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: James da Silva, Systems Design and Analysis Group
+ * Computer Science Department
+ * University of Maryland at College Park
+ */
+/*
+ * ========================================================================
+ * crunchgen.c
+ *
+ * Generates a Makefile and main C file for a crunched executable,
+ * from specs given in a .conf file.
+ */
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <string.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/param.h>
+
+#define CRUNCH_VERSION "0.2"
+
+#define MAXLINELEN 16384
+#define MAXFIELDS 2048
+
+
+/* internal representation of conf file: */
+
+/* simple lists of strings suffice for most parms */
+
+typedef struct strlst {
+ struct strlst *next;
+ char *str;
+} strlst_t;
+
+/* progs have structure, each field can be set with "special" or calculated */
+
+typedef struct prog {
+ struct prog *next;
+ char *name, *ident;
+ char *srcdir, *objdir;
+ strlst_t *objs, *objpaths;
+ strlst_t *links;
+ int goterror;
+} prog_t;
+
+
+/* global state */
+
+strlst_t *srcdirs = NULL;
+strlst_t *libs = NULL;
+prog_t *progs = NULL;
+
+char line[MAXLINELEN];
+
+char confname[MAXPATHLEN], infilename[MAXPATHLEN];
+char outmkname[MAXPATHLEN], outcfname[MAXPATHLEN], execfname[MAXPATHLEN];
+char tempfname[MAXPATHLEN], cachename[MAXPATHLEN], curfilename[MAXPATHLEN];
+int linenum = -1;
+int goterror = 0;
+
+char *pname = "crunchgen";
+
+int verbose, readcache; /* options */
+int reading_cache;
+
+/* general library routines */
+
+void status(char *str);
+void out_of_memory(void);
+void add_string(strlst_t **listp, char *str);
+int is_dir(char *pathname);
+int is_nonempty_file(char *pathname);
+
+/* helper routines for main() */
+
+void usage(void);
+void parse_conf_file(void);
+void gen_outputs(void);
+
+
+int main(int argc, char **argv)
+{
+ char *p;
+ int optc;
+ extern int optind;
+ extern char *optarg;
+
+ verbose = 1;
+ readcache = 1;
+ *outmkname = *outcfname = *execfname = '\0';
+
+ if(argc > 0) pname = argv[0];
+
+ while((optc = getopt(argc, argv, "m:c:e:fq")) != -1) {
+ switch(optc) {
+ case 'f': readcache = 0; break;
+ case 'q': verbose = 0; break;
+
+ case 'm': strcpy(outmkname, optarg); break;
+ case 'c': strcpy(outcfname, optarg); break;
+ case 'e': strcpy(execfname, optarg); break;
+
+ case '?':
+ default: usage();
+ }
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ if(argc != 1) usage();
+
+ /*
+ * generate filenames
+ */
+
+ strcpy(infilename, argv[0]);
+
+ /* confname = `basename infilename .conf` */
+
+ if((p=strrchr(infilename, '/')) != NULL) strcpy(confname, p+1);
+ else strcpy(confname, infilename);
+ if((p=strrchr(confname, '.')) != NULL && !strcmp(p, ".conf")) *p = '\0';
+
+ if(!*outmkname) sprintf(outmkname, "%s.mk", confname);
+ if(!*outcfname) sprintf(outcfname, "%s.c", confname);
+ if(!*execfname) sprintf(execfname, "%s", confname);
+
+ sprintf(cachename, "%s.cache", confname);
+ sprintf(tempfname, ".tmp_%sXXXXXX", confname);
+ if(mktemp(tempfname) == NULL) {
+ perror(tempfname);
+ exit(1);
+ }
+
+ parse_conf_file();
+ gen_outputs();
+
+ exit(goterror);
+}
+
+
+void usage(void)
+{
+ fprintf(stderr,
+ "%s [-fq] [-m <makefile>] [-c <c file>] [-e <exec file>] <conffile>\n",
+ pname);
+ exit(1);
+}
+
+
+/*
+ * ========================================================================
+ * parse_conf_file subsystem
+ *
+ */
+
+/* helper routines for parse_conf_file */
+
+void parse_one_file(char *filename);
+void parse_line(char *line, int *fc, char **fv, int nf);
+void add_srcdirs(int argc, char **argv);
+void add_progs(int argc, char **argv);
+void add_link(int argc, char **argv);
+void add_libs(int argc, char **argv);
+void add_special(int argc, char **argv);
+
+prog_t *find_prog(char *str);
+void add_prog(char *progname);
+
+
+void parse_conf_file(void)
+{
+ if(!is_nonempty_file(infilename)) {
+ fprintf(stderr, "%s: fatal: input file \"%s\" not found.\n",
+ pname, infilename);
+ exit(1);
+ }
+ parse_one_file(infilename);
+ if(readcache && is_nonempty_file(cachename)) {
+ reading_cache = 1;
+ parse_one_file(cachename);
+ }
+}
+
+
+void parse_one_file(char *filename)
+{
+ char *fieldv[MAXFIELDS];
+ int fieldc;
+ void (*f)(int c, char **v);
+ FILE *cf;
+
+ sprintf(line, "reading %s", filename);
+ status(line);
+ strcpy(curfilename, filename);
+
+ if((cf = fopen(curfilename, "r")) == NULL) {
+ perror(curfilename);
+ goterror = 1;
+ return;
+ }
+
+ linenum = 0;
+ while(fgets(line, MAXLINELEN, cf) != NULL) {
+ linenum++;
+ parse_line(line, &fieldc, fieldv, MAXFIELDS);
+ if(fieldc < 1) continue;
+ if(!strcmp(fieldv[0], "srcdirs")) f = add_srcdirs;
+ else if(!strcmp(fieldv[0], "progs")) f = add_progs;
+ else if(!strcmp(fieldv[0], "ln")) f = add_link;
+ else if(!strcmp(fieldv[0], "libs")) f = add_libs;
+ else if(!strcmp(fieldv[0], "special")) f = add_special;
+ else {
+ fprintf(stderr, "%s:%d: skipping unknown command `%s'.\n",
+ curfilename, linenum, fieldv[0]);
+ goterror = 1;
+ continue;
+ }
+ if(fieldc < 2) {
+ fprintf(stderr,
+ "%s:%d: %s command needs at least 1 argument, skipping.\n",
+ curfilename, linenum, fieldv[0]);
+ goterror = 1;
+ continue;
+ }
+ f(fieldc, fieldv);
+ }
+
+ if(ferror(cf)) {
+ perror(curfilename);
+ goterror = 1;
+ }
+ fclose(cf);
+}
+
+
+void parse_line(char *line, int *fc, char **fv, int nf)
+{
+ char *p;
+
+ p = line;
+ *fc = 0;
+ while(1) {
+ while(isspace(*p)) p++;
+ if(*p == '\0' || *p == '#') break;
+
+ if(*fc < nf) fv[(*fc)++] = p;
+ while(*p && !isspace(*p) && *p != '#') p++;
+ if(*p == '\0' || *p == '#') break;
+ *p++ = '\0';
+ }
+ if(*p) *p = '\0'; /* needed for '#' case */
+}
+
+
+void add_srcdirs(int argc, char **argv)
+{
+ int i;
+
+ for(i=1;i<argc;i++) {
+ if(is_dir(argv[i]))
+ add_string(&srcdirs, argv[i]);
+ else {
+ fprintf(stderr, "%s:%d: `%s' is not a directory, skipping it.\n",
+ curfilename, linenum, argv[i]);
+ goterror = 1;
+ }
+ }
+}
+
+
+void add_progs(int argc, char **argv)
+{
+ int i;
+
+ for(i=1;i<argc;i++)
+ add_prog(argv[i]);
+}
+
+
+void add_prog(char *progname)
+{
+ prog_t *p1, *p2;
+
+ /* add to end, but be smart about dups */
+
+ for(p1 = NULL, p2 = progs; p2 != NULL; p1 = p2, p2 = p2->next)
+ if(!strcmp(p2->name, progname)) return;
+
+ p2 = malloc(sizeof(prog_t));
+ if(p2) p2->name = strdup(progname);
+ if(!p2 || !p2->name)
+ out_of_memory();
+
+ p2->next = NULL;
+ if(p1 == NULL) progs = p2;
+ else p1->next = p2;
+
+ p2->ident = p2->srcdir = p2->objdir = NULL;
+ p2->links = p2->objs = NULL;
+ p2->goterror = 0;
+}
+
+
+void add_link(int argc, char **argv)
+{
+ int i;
+ prog_t *p = find_prog(argv[1]);
+
+ if(p == NULL) {
+ fprintf(stderr,
+ "%s:%d: no prog %s previously declared, skipping link.\n",
+ curfilename, linenum, argv[1]);
+ goterror = 1;
+ return;
+ }
+ for(i=2;i<argc;i++)
+ add_string(&p->links, argv[i]);
+}
+
+
+void add_libs(int argc, char **argv)
+{
+ int i;
+
+ for(i=1;i<argc;i++)
+ add_string(&libs, argv[i]);
+}
+
+
+void add_special(int argc, char **argv)
+{
+ int i;
+ prog_t *p = find_prog(argv[1]);
+
+ if(p == NULL) {
+ if(reading_cache) return;
+ fprintf(stderr,
+ "%s:%d: no prog %s previously declared, skipping special.\n",
+ curfilename, linenum, argv[1]);
+ goterror = 1;
+ return;
+ }
+
+ if(!strcmp(argv[2], "ident")) {
+ if(argc != 4) goto argcount;
+ if((p->ident = strdup(argv[3])) == NULL)
+ out_of_memory();
+ }
+ else if(!strcmp(argv[2], "srcdir")) {
+ if(argc != 4) goto argcount;
+ if((p->srcdir = strdup(argv[3])) == NULL)
+ out_of_memory();
+ }
+ else if(!strcmp(argv[2], "objdir")) {
+ if(argc != 4) goto argcount;
+ if((p->objdir = strdup(argv[3])) == NULL)
+ out_of_memory();
+ }
+ else if(!strcmp(argv[2], "objs")) {
+ p->objs = NULL;
+ for(i=3;i<argc;i++)
+ add_string(&p->objs, argv[i]);
+ }
+ else if(!strcmp(argv[2], "objpaths")) {
+ p->objpaths = NULL;
+ for(i=3;i<argc;i++)
+ add_string(&p->objpaths, argv[i]);
+ }
+ else {
+ fprintf(stderr, "%s:%d: bad parameter name `%s', skipping line.\n",
+ curfilename, linenum, argv[2]);
+ goterror = 1;
+ }
+ return;
+
+
+ argcount:
+ fprintf(stderr,
+ "%s:%d: too %s arguments, expected \"special %s %s <string>\".\n",
+ curfilename, linenum, argc < 4? "few" : "many", argv[1], argv[2]);
+ goterror = 1;
+}
+
+
+prog_t *find_prog(char *str)
+{
+ prog_t *p;
+
+ for(p = progs; p != NULL; p = p->next)
+ if(!strcmp(p->name, str)) return p;
+
+ return NULL;
+}
+
+
+/*
+ * ========================================================================
+ * gen_outputs subsystem
+ *
+ */
+
+/* helper subroutines */
+
+void remove_error_progs(void);
+void fillin_program(prog_t *p);
+void gen_specials_cache(void);
+void gen_output_makefile(void);
+void gen_output_cfile(void);
+
+void fillin_program_objs(prog_t *p, char *path);
+void top_makefile_rules(FILE *outmk);
+void prog_makefile_rules(FILE *outmk, prog_t *p);
+void output_strlst(FILE *outf, strlst_t *lst);
+char *genident(char *str);
+char *dir_search(char *progname);
+
+
+void gen_outputs(void)
+{
+ prog_t *p;
+
+ for(p = progs; p != NULL; p = p->next)
+ fillin_program(p);
+
+ remove_error_progs();
+ gen_specials_cache();
+ gen_output_cfile();
+ gen_output_makefile();
+ status("");
+ fprintf(stderr,
+ "Run \"make -f %s objs exe\" to build crunched binary.\n",
+ outmkname);
+}
+
+
+void fillin_program(prog_t *p)
+{
+ char path[MAXPATHLEN];
+ char *srcparent;
+ strlst_t *s;
+
+ sprintf(line, "filling in parms for %s", p->name);
+ status(line);
+
+ if(!p->ident)
+ p->ident = genident(p->name);
+ if(!p->srcdir) {
+ srcparent = dir_search(p->name);
+ if(srcparent)
+ sprintf(path, "%s/%s", srcparent, p->name);
+ if(is_dir(path))
+ p->srcdir = strdup(path);
+ }
+ if(!p->objdir && p->srcdir) {
+ sprintf(path, "%s/obj", p->srcdir);
+ if(is_dir(path))
+ p->objdir = strdup(path);
+ else
+ p->objdir = p->srcdir;
+ }
+
+ if(p->srcdir) sprintf(path, "%s/Makefile", p->srcdir);
+ if(!p->objs && p->srcdir && is_nonempty_file(path))
+ fillin_program_objs(p, path);
+
+ if(!p->objpaths && p->objdir && p->objs)
+ for(s = p->objs; s != NULL; s = s->next) {
+ sprintf(line, "%s/%s", p->objdir, s->str);
+ add_string(&p->objpaths, line);
+ }
+
+ if(!p->srcdir && verbose)
+ fprintf(stderr, "%s: %s: warning: could not find source directory.\n",
+ infilename, p->name);
+ if(!p->objs && verbose)
+ fprintf(stderr, "%s: %s: warning: could not find any .o files.\n",
+ infilename, p->name);
+
+ if(!p->objpaths) {
+ fprintf(stderr,
+ "%s: %s: error: no objpaths specified or calculated.\n",
+ infilename, p->name);
+ p->goterror = goterror = 1;
+ }
+}
+
+void fillin_program_objs(prog_t *p, char *path)
+{
+ char *obj, *cp;
+ int rc;
+ FILE *f;
+
+ /* discover the objs from the srcdir Makefile */
+
+ if((f = fopen(tempfname, "w")) == NULL) {
+ perror(tempfname);
+ goterror = 1;
+ return;
+ }
+
+ fprintf(f, ".include \"%s\"\n", path);
+ fprintf(f, ".if defined(PROG) && !defined(OBJS)\n");
+ fprintf(f, "OBJS=${PROG}.o\n");
+ fprintf(f, ".endif\n");
+ fprintf(f, "crunchgen_objs:\n\t@echo 'OBJS= '${OBJS}\n");
+ fclose(f);
+
+ sprintf(line, "make -f %s crunchgen_objs 2>&1", tempfname);
+ if((f = popen(line, "r")) == NULL) {
+ perror("submake pipe");
+ goterror = 1;
+ return;
+ }
+
+ while(fgets(line, MAXLINELEN, f)) {
+ if(strncmp(line, "OBJS= ", 6)) {
+ fprintf(stderr, "make error: %s", line);
+ goterror = 1;
+ continue;
+ }
+ cp = line + 6;
+ while(isspace(*cp)) cp++;
+ while(*cp) {
+ obj = cp;
+ while(*cp && !isspace(*cp)) cp++;
+ if(*cp) *cp++ = '\0';
+ add_string(&p->objs, obj);
+ while(isspace(*cp)) cp++;
+ }
+ }
+ if((rc=pclose(f)) != 0) {
+ fprintf(stderr, "make error: make returned %d\n", rc);
+ goterror = 1;
+ }
+ unlink(tempfname);
+}
+
+void remove_error_progs(void)
+{
+ prog_t *p1, *p2;
+
+ p1 = NULL; p2 = progs;
+ while(p2 != NULL) {
+ if(!p2->goterror)
+ p1 = p2, p2 = p2->next;
+ else {
+ /* delete it from linked list */
+ fprintf(stderr, "%s: %s: ignoring program because of errors.\n",
+ infilename, p2->name);
+ if(p1) p1->next = p2->next;
+ else progs = p2->next;
+ p2 = p2->next;
+ }
+ }
+}
+
+void gen_specials_cache(void)
+{
+ FILE *cachef;
+ prog_t *p;
+
+ sprintf(line, "generating %s", cachename);
+ status(line);
+
+ if((cachef = fopen(cachename, "w")) == NULL) {
+ perror(cachename);
+ goterror = 1;
+ return;
+ }
+
+ fprintf(cachef, "# %s - parm cache generated from %s by crunchgen %s\n\n",
+ cachename, infilename, CRUNCH_VERSION);
+
+ for(p = progs; p != NULL; p = p->next) {
+ fprintf(cachef, "\n");
+ if(p->srcdir)
+ fprintf(cachef, "special %s srcdir %s\n", p->name, p->srcdir);
+ if(p->objdir)
+ fprintf(cachef, "special %s objdir %s\n", p->name, p->objdir);
+ if(p->objs) {
+ fprintf(cachef, "special %s objs", p->name);
+ output_strlst(cachef, p->objs);
+ }
+ fprintf(cachef, "special %s objpaths", p->name);
+ output_strlst(cachef, p->objpaths);
+ }
+ fclose(cachef);
+}
+
+
+void gen_output_makefile(void)
+{
+ prog_t *p;
+ FILE *outmk;
+
+ sprintf(line, "generating %s", outmkname);
+ status(line);
+
+ if((outmk = fopen(outmkname, "w")) == NULL) {
+ perror(outmkname);
+ goterror = 1;
+ return;
+ }
+
+ fprintf(outmk, "# %s - generated from %s by crunchgen %s\n\n",
+ outmkname, infilename, CRUNCH_VERSION);
+
+ top_makefile_rules(outmk);
+
+ for(p = progs; p != NULL; p = p->next)
+ prog_makefile_rules(outmk, p);
+
+ fprintf(outmk, "\n# ========\n");
+ fclose(outmk);
+}
+
+
+void gen_output_cfile(void)
+{
+ extern char *crunched_skel[];
+ char **cp;
+ FILE *outcf;
+ prog_t *p;
+ strlst_t *s;
+
+ sprintf(line, "generating %s", outcfname);
+ status(line);
+
+ if((outcf = fopen(outcfname, "w")) == NULL) {
+ perror(outcfname);
+ goterror = 1;
+ return;
+ }
+
+ fprintf(outcf,
+ "/* %s - generated from %s by crunchgen %s */\n",
+ outcfname, infilename, CRUNCH_VERSION);
+
+ fprintf(outcf, "#define EXECNAME \"%s\"\n", execfname);
+ for(cp = crunched_skel; *cp != NULL; cp++)
+ fprintf(outcf, "%s\n", *cp);
+
+ for(p = progs; p != NULL; p = p->next)
+ fprintf(outcf, "extern int _crunched_%s_stub();\n", p->ident);
+
+ fprintf(outcf, "\nstruct stub entry_points[] = {\n");
+ for(p = progs; p != NULL; p = p->next) {
+ fprintf(outcf, "\t{ \"%s\", _crunched_%s_stub },\n",
+ p->name, p->ident);
+ for(s = p->links; s != NULL; s = s->next)
+ fprintf(outcf, "\t{ \"%s\", _crunched_%s_stub },\n",
+ s->str, p->ident);
+ }
+
+ fprintf(outcf, "\t{ EXECNAME, crunched_main },\n");
+ fprintf(outcf, "\t{ NULL, NULL }\n};\n");
+ fclose(outcf);
+}
+
+
+char *genident(char *str)
+{
+ char *n,*s,*d;
+
+ /*
+ * generates a Makefile/C identifier from a program name, mapping '-' to
+ * '_' and ignoring all other non-identifier characters. This leads to
+ * programs named "foo.bar" and "foobar" to map to the same identifier.
+ */
+
+ if((n = strdup(str)) == NULL)
+ return NULL;
+ for(d = s = n; *s != '\0'; s++) {
+ if(*s == '-') *d++ = '_';
+ else if(*s == '_' || isalnum(*s)) *d++ = *s;
+ }
+ *d = '\0';
+ return n;
+}
+
+
+char *dir_search(char *progname)
+{
+ char path[MAXPATHLEN];
+ strlst_t *dir;
+
+ for(dir=srcdirs; dir != NULL; dir=dir->next) {
+ sprintf(path, "%s/%s", dir->str, progname);
+ if(is_dir(path)) return dir->str;
+ }
+ return NULL;
+}
+
+
+void top_makefile_rules(FILE *outmk)
+{
+ prog_t *p;
+
+ fprintf(outmk, "LIBS=");
+ output_strlst(outmk, libs);
+
+ fprintf(outmk, "CRUNCHED_OBJS=");
+ for(p = progs; p != NULL; p = p->next)
+ fprintf(outmk, " %s.lo", p->name);
+ fprintf(outmk, "\n");
+
+ fprintf(outmk, "SUBMAKE_TARGETS=");
+ for(p = progs; p != NULL; p = p->next)
+ fprintf(outmk, " %s_make", p->ident);
+ fprintf(outmk, "\n\n");
+
+ fprintf(outmk, "%s: %s.o $(CRUNCHED_OBJS)\n",
+ execfname, execfname);
+ fprintf(outmk, "\t$(CC) -static -o %s %s.o $(CRUNCHED_OBJS) $(LIBS)\n",
+ execfname, execfname);
+ fprintf(outmk, "\tstrip %s\n", execfname);
+ fprintf(outmk, "all: objs exe\nobjs: $(SUBMAKE_TARGETS)\n");
+ fprintf(outmk, "exe: %s\n", execfname);
+ fprintf(outmk, "clean:\n\trm -f %s *.lo *.o *_stub.c\n",
+ execfname);
+}
+
+
+void prog_makefile_rules(FILE *outmk, prog_t *p)
+{
+ fprintf(outmk, "\n# -------- %s\n\n", p->name);
+
+ if(p->srcdir && p->objs) {
+ fprintf(outmk, "%s_SRCDIR=%s\n", p->ident, p->srcdir);
+ fprintf(outmk, "%s_OBJS=", p->ident);
+ output_strlst(outmk, p->objs);
+ fprintf(outmk, "%s_make:\n", p->ident);
+ fprintf(outmk, "\t(cd $(%s_SRCDIR); make $(%s_OBJS))\n\n",
+ p->ident, p->ident);
+ }
+ else
+ fprintf(outmk, "%s_make:\n\t@echo \"** cannot make objs for %s\"\n\n",
+ p->ident, p->name);
+
+ fprintf(outmk, "%s_OBJPATHS=", p->ident);
+ output_strlst(outmk, p->objpaths);
+
+ fprintf(outmk, "%s_stub.c:\n", p->name);
+ fprintf(outmk, "\techo \""
+ "int _crunched_%s_stub(int argc, char **argv, char **envp)"
+ "{return main(argc,argv,envp);}\" >%s_stub.c\n",
+ p->ident, p->name);
+ fprintf(outmk, "%s.lo: %s_stub.o $(%s_OBJPATHS)\n",
+ p->name, p->name, p->ident);
+ fprintf(outmk, "\tld -dc -r -o %s.lo %s_stub.o $(%s_OBJPATHS)\n",
+ p->name, p->name, p->ident);
+ fprintf(outmk, "\tcrunchide -k __crunched_%s_stub %s.lo\n",
+ p->ident, p->name);
+}
+
+void output_strlst(FILE *outf, strlst_t *lst)
+{
+ for(; lst != NULL; lst = lst->next)
+ fprintf(outf, " %s", lst->str);
+ fprintf(outf, "\n");
+}
+
+
+/*
+ * ========================================================================
+ * general library routines
+ *
+ */
+
+void status(char *str)
+{
+ static int lastlen = 0;
+ int len, spaces;
+
+ if(!verbose) return;
+
+ len = strlen(str);
+ spaces = lastlen - len;
+ if(spaces < 1) spaces = 1;
+
+ fprintf(stderr, " [%s]%*.*s\r", str, spaces, spaces, " ");
+ fflush(stderr);
+ lastlen = len;
+}
+
+
+void out_of_memory(void)
+{
+ fprintf(stderr, "%s: %d: out of memory, stopping.\n", infilename, linenum);
+ exit(1);
+}
+
+
+void add_string(strlst_t **listp, char *str)
+{
+ strlst_t *p1, *p2;
+
+ /* add to end, but be smart about dups */
+
+ for(p1 = NULL, p2 = *listp; p2 != NULL; p1 = p2, p2 = p2->next)
+ if(!strcmp(p2->str, str)) return;
+
+ p2 = malloc(sizeof(strlst_t));
+ if(p2) p2->str = strdup(str);
+ if(!p2 || !p2->str)
+ out_of_memory();
+
+ p2->next = NULL;
+ if(p1 == NULL) *listp = p2;
+ else p1->next = p2;
+}
+
+
+int is_dir(char *pathname)
+{
+ struct stat buf;
+
+ if(stat(pathname, &buf) == -1)
+ return 0;
+ return S_ISDIR(buf.st_mode);
+}
+
+int is_nonempty_file(char *pathname)
+{
+ struct stat buf;
+
+ if(stat(pathname, &buf) == -1)
+ return 0;
+
+ return S_ISREG(buf.st_mode) && buf.st_size > 0;
+}
diff --git a/contrib/crunch/crunchgen/mkskel.sh b/contrib/crunch/crunchgen/mkskel.sh
new file mode 100755
index 000000000000..fd53d78bbbac
--- /dev/null
+++ b/contrib/crunch/crunchgen/mkskel.sh
@@ -0,0 +1,15 @@
+#! /bin/sh
+# idea and sed lines taken straight from flex
+
+cat <<!EOF
+/* File created via mkskel.sh */
+
+char *crunched_skel[] = {
+!EOF
+
+sed 's/\\/&&/g' $* | sed 's/"/\\"/g' | sed 's/.*/ "&",/'
+
+cat <<!EOF
+ 0
+};
+!EOF
diff --git a/contrib/crunch/crunchide/Makefile b/contrib/crunch/crunchide/Makefile
new file mode 100644
index 000000000000..f6e1a8a45263
--- /dev/null
+++ b/contrib/crunch/crunchide/Makefile
@@ -0,0 +1,4 @@
+
+PROG= crunchide
+
+.include <bsd.prog.mk>
diff --git a/contrib/crunch/crunchide/crunchide.1 b/contrib/crunch/crunchide/crunchide.1
new file mode 100644
index 000000000000..38a04cf6b93f
--- /dev/null
+++ b/contrib/crunch/crunchide/crunchide.1
@@ -0,0 +1,68 @@
+.\"
+.\" Copyright (c) 1994 University of Maryland
+.\" All Rights Reserved.
+.\"
+.\" Permission to use, copy, modify, distribute, and sell this software and its
+.\" documentation for any purpose is hereby granted without fee, provided that
+.\" the above copyright notice appear in all copies and that both that
+.\" copyright notice and this permission notice appear in supporting
+.\" documentation, and that the name of U.M. not be used in advertising or
+.\" publicity pertaining to distribution of the software without specific,
+.\" written prior permission. U.M. makes no representations about the
+.\" suitability of this software for any purpose. It is provided "as is"
+.\" without express or implied warranty.
+.\"
+.\" U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
+.\" BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+.\" IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+.\"
+.\" Author: James da Silva, Systems Design and Analysis Group
+.\" Computer Science Department
+.\" University of Maryland at College Park
+.\"
+.Dd June 14, 1994
+.Dt CRUNCHIDE 1
+.Os BSD 4
+.Sh NAME
+.Nm crunchide
+.Nd hides symbol names from ld, for crunching programs together
+.Sh SYNOPSIS
+.Nm crunchide
+.Op Fl f Ar keep-list-file
+.Op Fl k Ar keep-symbol
+.Op Ar object-file ...
+.Sh DESCRIPTION
+
+.Nm Crunchide
+hides the global symbols of
+.Ar object-file
+such that they are ignored by subsequent runs of the linker,
+.Xr ld 1 .
+Some symbols may be left visible via the
+.Fl k Ar keep-symbol
+and
+.Fl f Ar keep-list-file
+options. The
+.Ar keep-list-file
+must contain a list of symbols to keep visible, one symbol per line.
+Note that the C compiler prepends an underscore in front of
+symbols, so to keep the C function ``foo'' visible, the option
+\&``-k _foo'' must be used.
+
+.Pp
+.Nm Crunchide
+is designed as a companion program for
+.Xr crunchgen 1 ,
+which automates the process of creating crunched binaries from
+multiple component programs.
+.Sh SEE ALSO
+.Xr crunchgen 1 ,
+.Xr ld 1
+.Sh AUTHOR
+.Nm Crunch
+was written by James da Silva <jds@cs.umd.edu>.
+.sp 0
+Copyright (c) 1994 University of Maryland. All Rights Reserved.
diff --git a/contrib/crunch/crunchide/crunchide.c b/contrib/crunch/crunchide/crunchide.c
new file mode 100644
index 000000000000..ae54da08cf58
--- /dev/null
+++ b/contrib/crunch/crunchide/crunchide.c
@@ -0,0 +1,321 @@
+/*
+ * Copyright (c) 1994 University of Maryland
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of U.M. not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. U.M. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: James da Silva, Systems Design and Analysis Group
+ * Computer Science Department
+ * University of Maryland at College Park
+ */
+/*
+ * crunchide.c - tiptoes through an a.out symbol table, hiding all defined
+ * global symbols. Allows the user to supply a "keep list" of symbols
+ * that are not to be hidden. This program relies on the use of the
+ * linker's -dc flag to actually put global bss data into the file's
+ * bss segment (rather than leaving it as undefined "common" data).
+ *
+ * The point of all this is to allow multiple programs to be linked
+ * together without getting multiple-defined errors.
+ *
+ * For example, consider a program "foo.c". It can be linked with a
+ * small stub routine, called "foostub.c", eg:
+ * int foo_main(int argc, char **argv){ return main(argc, argv); }
+ * like so:
+ * cc -c foo.c foostub.c
+ * ld -dc -r foo.o foostub.o -o foo.combined.o
+ * crunchide -k _foo_main foo.combined.o
+ * at this point, foo.combined.o can be linked with another program
+ * and invoked with "foo_main(argc, argv)". foo's main() and any
+ * other globals are hidden and will not conflict with other symbols.
+ *
+ * TODO:
+ * - resolve the theoretical hanging reloc problem (see check_reloc()
+ * below). I have yet to see this problem actually occur in any real
+ * program. In what cases will gcc/gas generate code that needs a
+ * relative reloc from a global symbol, other than PIC? The
+ * solution is to not hide the symbol from the linker in this case,
+ * but to generate some random name for it so that it doesn't link
+ * with anything but holds the place for the reloc.
+ * - arrange that all the BSS segments start at the same address, so
+ * that the final crunched binary BSS size is the max of all the
+ * component programs' BSS sizes, rather than their sum.
+ */
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <a.out.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/errno.h>
+
+char *pname = "crunchide";
+
+void usage(void);
+
+void add_to_keep_list(char *symbol);
+void add_file_to_keep_list(char *filename);
+
+void hide_syms(char *filename);
+
+
+int main(argc, argv)
+int argc;
+char **argv;
+{
+ int ch;
+
+ if(argc > 0) pname = argv[0];
+
+ while ((ch = getopt(argc, argv, "k:f:")) != EOF)
+ switch(ch) {
+ case 'k':
+ add_to_keep_list(optarg);
+ break;
+ case 'f':
+ add_file_to_keep_list(optarg);
+ break;
+ default:
+ usage();
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ if(argc == 0) usage();
+
+ while(argc) {
+ hide_syms(*argv);
+ argc--, argv++;
+ }
+
+ return 0;
+}
+
+void usage(void)
+{
+ fprintf(stderr,
+ "Usage: %s [-k <symbol-name>] [-f <keep-list-file>] <files> ...\n",
+ pname);
+ exit(1);
+}
+
+/* ---------------------------- */
+
+struct keep {
+ struct keep *next;
+ char *sym;
+} *keep_list;
+
+void add_to_keep_list(char *symbol)
+{
+ struct keep *newp, *prevp, *curp;
+ int cmp;
+
+ for(curp = keep_list, prevp = NULL; curp; prevp = curp, curp = curp->next)
+ if((cmp = strcmp(symbol, curp->sym)) <= 0) break;
+
+ if(curp && cmp == 0)
+ return; /* already in table */
+
+ newp = (struct keep *) malloc(sizeof(struct keep));
+ if(newp) newp->sym = strdup(symbol);
+ if(newp == NULL || newp->sym == NULL) {
+ fprintf(stderr, "%s: out of memory for keep list\n", pname);
+ exit(1);
+ }
+
+ newp->next = curp;
+ if(prevp) prevp->next = newp;
+ else keep_list = newp;
+}
+
+int in_keep_list(char *symbol)
+{
+ struct keep *curp;
+ int cmp;
+
+ for(curp = keep_list; curp; curp = curp->next)
+ if((cmp = strcmp(symbol, curp->sym)) <= 0) break;
+
+ return curp && cmp == 0;
+}
+
+void add_file_to_keep_list(char *filename)
+{
+ FILE *keepf;
+ char symbol[1024];
+ int len;
+
+ if((keepf = fopen(filename, "r")) == NULL) {
+ perror(filename);
+ usage();
+ }
+
+ while(fgets(symbol, 1024, keepf)) {
+ len = strlen(symbol);
+ if(len && symbol[len-1] == '\n')
+ symbol[len-1] = '\0';
+
+ add_to_keep_list(symbol);
+ }
+ fclose(keepf);
+}
+
+/* ---------------------- */
+
+int nsyms, ntextrel, ndatarel;
+struct exec *hdrp;
+char *aoutdata, *strbase;
+struct relocation_info *textrel, *datarel;
+struct nlist *symbase;
+
+
+#define SYMSTR(sp) &strbase[(sp)->n_un.n_strx]
+
+/* is the symbol a global symbol defined in the current file? */
+#define IS_GLOBAL_DEFINED(sp) \
+ (((sp)->n_type & N_EXT) && ((sp)->n_type & N_TYPE) != N_UNDF)
+
+/* is the relocation entry dependent on a symbol? */
+#define IS_SYMBOL_RELOC(rp) \
+ ((rp)->r_extern||(rp)->r_baserel||(rp)->r_jmptable)
+
+void check_reloc(char *filename, struct relocation_info *relp);
+
+void hide_syms(char *filename)
+{
+ int inf, outf, rc;
+ struct stat infstat;
+ struct relocation_info *relp;
+ struct nlist *symp;
+
+ /*
+ * Open the file and do some error checking.
+ */
+
+ if((inf = open(filename, O_RDWR)) == -1) {
+ perror(filename);
+ return;
+ }
+
+ if(fstat(inf, &infstat) == -1) {
+ perror(filename);
+ close(inf);
+ return;
+ }
+
+ if(infstat.st_size < sizeof(struct exec)) {
+ fprintf(stderr, "%s: short file\n", filename);
+ close(inf);
+ return;
+ }
+
+ /*
+ * Read the entire file into memory. XXX - Really, we only need to
+ * read the header and from TRELOFF to the end of the file.
+ */
+
+ if((aoutdata = (char *) malloc(infstat.st_size)) == NULL) {
+ fprintf(stderr, "%s: too big to read into memory\n", filename);
+ close(inf);
+ return;
+ }
+
+ if((rc = read(inf, aoutdata, infstat.st_size)) < infstat.st_size) {
+ fprintf(stderr, "%s: read error: %s\n", filename,
+ rc == -1? strerror(errno) : "short read");
+ close(inf);
+ return;
+ }
+
+ /*
+ * Check the header and calculate offsets and sizes from it.
+ */
+
+ hdrp = (struct exec *) aoutdata;
+
+ if(N_BADMAG(*hdrp)) {
+ fprintf(stderr, "%s: bad magic: not an a.out file\n", filename);
+ close(inf);
+ return;
+ }
+
+#ifdef __FreeBSD__
+ textrel = (struct relocation_info *) (aoutdata + N_RELOFF(*hdrp));
+ datarel = (struct relocation_info *) (aoutdata + N_RELOFF(*hdrp) +
+ hdrp->a_trsize);
+#else
+ textrel = (struct relocation_info *) (aoutdata + N_TRELOFF(*hdrp));
+ datarel = (struct relocation_info *) (aoutdata + N_DRELOFF(*hdrp));
+#endif
+ symbase = (struct nlist *) (aoutdata + N_SYMOFF(*hdrp));
+ strbase = (char *) (aoutdata + N_STROFF(*hdrp));
+
+ ntextrel = hdrp->a_trsize / sizeof(struct relocation_info);
+ ndatarel = hdrp->a_drsize / sizeof(struct relocation_info);
+ nsyms = hdrp->a_syms / sizeof(struct nlist);
+
+ /*
+ * Zap the type field of all globally-defined symbols. The linker will
+ * subsequently ignore these entries. Don't zap any symbols in the
+ * keep list.
+ */
+
+ for(symp = symbase; symp < symbase + nsyms; symp++)
+ if(IS_GLOBAL_DEFINED(symp) && !in_keep_list(SYMSTR(symp)))
+ symp->n_type = 0;
+
+ /*
+ * Check whether the relocation entries reference any symbols that we
+ * just zapped. I don't know whether ld can handle this case, but I
+ * haven't encountered it yet. These checks are here so that the program
+ * doesn't fail silently should such symbols be encountered.
+ */
+
+ for(relp = textrel; relp < textrel + ntextrel; relp++)
+ check_reloc(filename, relp);
+ for(relp = datarel; relp < datarel + ndatarel; relp++)
+ check_reloc(filename, relp);
+
+ /*
+ * Write the .o file back out to disk. XXX - Really, we only need to
+ * write the symbol table entries back out.
+ */
+ lseek(inf, 0, SEEK_SET);
+ if((rc = write(inf, aoutdata, infstat.st_size)) < infstat.st_size) {
+ fprintf(stderr, "%s: write error: %s\n", filename,
+ rc == -1? strerror(errno) : "short write");
+ }
+
+ close(inf);
+}
+
+
+void check_reloc(char *filename, struct relocation_info *relp)
+{
+ /* bail out if we zapped a symbol that is needed */
+ if(IS_SYMBOL_RELOC(relp) && symbase[relp->r_symbolnum].n_type == 0) {
+ fprintf(stderr,
+ "%s: oops, have hanging relocation for %s: bailing out!\n",
+ filename, SYMSTR(&symbase[relp->r_symbolnum]));
+ exit(1);
+ }
+}
diff --git a/contrib/crunch/examples/Makefile b/contrib/crunch/examples/Makefile
new file mode 100644
index 000000000000..861e3028cb87
--- /dev/null
+++ b/contrib/crunch/examples/Makefile
@@ -0,0 +1,32 @@
+
+CRUNCHED= fixit
+
+# below is boiler-plate to make $(CRUNCHED) from $(CRUNCHED).conf
+# I'd use PROG instead of CRUNCHED, but the system makefiles REALLY want
+# to build things in the normal way if you use PROG.
+
+CONF= $(CRUNCHED).conf
+
+OUTMK= $(CRUNCHED).mk
+OUTPUTS= $(OUTMK) $(CRUNCHED).c $(CRUNCHED).cache
+
+NOMAN=
+CLEANFILES+=$(CRUNCHED) *.o *.lo *.c *.mk *.cache
+CLEANDIRFILES+=$(OUTPUTS)
+
+all: $(CRUNCHED)
+exe: $(CRUNCHED)
+
+$(OUTPUTS): $(CONF)
+ crunchgen ${.CURDIR}/$(CONF)
+
+$(CRUNCHED): $(OUTPUTS) submake
+
+submake:
+ make -f $(OUTMK)
+objs:
+ make -f $(OUTMK) objs
+cleandir:
+ rm -f $(CLEANDIRFILES)
+
+.include <bsd.prog.mk>
diff --git a/contrib/crunch/examples/filesystem.conf b/contrib/crunch/examples/filesystem.conf
new file mode 100644
index 000000000000..c5bcb372dc81
--- /dev/null
+++ b/contrib/crunch/examples/filesystem.conf
@@ -0,0 +1,26 @@
+# $Id: filesystem.conf,v 1.2 1994/06/24 16:39:29 jkh Exp $
+
+srcdirs /usr/src/bin /usr/src/sbin /usr/src/gnu/usr.bin /usr/src/usr.sbin
+
+# /bin
+progs sh expr ls mkdir rm sync test
+ln test [
+
+# These are needed because of UN*X's idiotic way of indicating that something
+# is a login shell.
+ln sh -
+ln sh -sh
+
+# /sbin
+progs disklabel fdisk halt init mount mount_pcfs newfs umount
+
+# /usr/bin
+progs cpio gzip
+ln gzip gunzip
+ln gzip gzcat
+ln gzip zcat
+
+# /usr/sbin
+progs bad144
+
+libs -lutil
diff --git a/contrib/crunch/examples/fixit.conf b/contrib/crunch/examples/fixit.conf
new file mode 100644
index 000000000000..2298d41386be
--- /dev/null
+++ b/contrib/crunch/examples/fixit.conf
@@ -0,0 +1,41 @@
+# fixit.conf - put in anything we think we might want on a fixit floppy
+
+# first, we list the source dirs that our programs reside in. These are
+# searched in order listed to find the dir containing each program.
+
+srcdirs /usr/src/bin /usr/src/sbin /usr/src/usr.bin /usr/src/usr.sbin
+srcdirs /usr/src/gnu/usr.bin
+
+# second, we list all the programs we want to include in our crunched binary.
+# The order doesn't matter. Any program that needs hard links to it gets an
+# `ln' directive.
+
+# /bin stuff
+
+progs cat chmod cp date dd df echo ed expr hostname kill ln ls mkdir
+progs mt mv pwd rcp rm rmdir sh sleep stty sync test
+
+ln test [
+ln sh -sh # init invokes the shell this way
+
+# /sbin stuff
+
+progs badsect chown clri disklabel dump dmesg fdisk fsck halt ifconfig init
+progs mknod mount newfs ping reboot restore swapon umount
+ln dump rdump
+ln restore rrestore
+
+# /usr/bin stuff
+
+progs ftp rsh sed telnet rlogin vi
+
+# gnu stuff
+
+progs cpio gzip
+ln gzip gunzip
+ln gzip gzcat
+
+# finally, we specify the libraries to link in with our binary
+
+libs -lcrypt -ltelnet -lutil -ll
+libs -lcurses -ltermcap
diff --git a/contrib/crunch/examples/kcopy.conf b/contrib/crunch/examples/kcopy.conf
new file mode 100644
index 000000000000..a50f6f28df52
--- /dev/null
+++ b/contrib/crunch/examples/kcopy.conf
@@ -0,0 +1,18 @@
+# $Id: kcopy.conf,v 1.3 1994/06/24 16:39:30 jkh Exp $
+
+srcdirs /usr/src/bin /usr/src/sbin
+
+# Programs from bin/
+progs sh cp echo test
+ln test [
+
+# These are needed because of UN*X's idiotic way of indicating that something
+# is a login shell.
+ln sh -
+ln sh -sh
+
+#
+# Programs from sbin/
+progs mount mount_isofs mount_pcfs fsck halt init umount
+
+libs -lutil
diff --git a/contrib/crunch/examples/really-big.conf b/contrib/crunch/examples/really-big.conf
new file mode 100644
index 000000000000..ce5083f7051c
--- /dev/null
+++ b/contrib/crunch/examples/really-big.conf
@@ -0,0 +1,146 @@
+# really-big.conf - just about everything, just for testing.
+# This ends up having some good examples of the use of specials for
+# those hard-to-reach programs. I stopped when I got tired, but we
+# could probably get even more stuff (like libexec stuff) in here.
+#
+# This produces a 4608000 byte binary. Pretty sick and twisted, eh?
+
+# =========================================================================
+
+srcdirs /usr/src/bin
+
+progs cat chmod cp csh date dd df domainname echo ed expr hostname kill
+progs ln ls mkdir mt mv ps pwd rcp rm rmail rmdir sh sleep stty sync test
+
+ln test [
+ln sh -sh
+
+
+# =========================================================================
+
+srcdirs /usr/src/sbin
+
+progs badsect bim clri disklabel dmesg dump dumpfs fdisk fsck halt
+progs ifconfig init mknod modload modunload mount mount_fdesc mount_isofs
+progs mount_kernfs mount_lofs mount_msdos mount_portal mount_procfs mountd
+progs newfs nfsd nfsiod ping quotacheck reboot restore route routed savecore
+progs shutdown slattach swapon ttyflags tunefs umount
+# shell scripts: fastboot
+
+ln dump rdump
+ln restore rrestore
+
+
+# =========================================================================
+
+srcdirs /usr/src/usr.bin
+
+progs apropos ar asa at basename biff cal calendar cap_mkdb checknr chpass
+progs cksum cmp col colcrt colrm column comm compress crontab ctags cut
+progs dirname du env error expand false file find finger fmt fold fpr from
+progs fsplit fstat ftp getconf getopt gprof head hexdump id indent ipcrm
+progs ipcs join kdump ktrace last lastcomm leave lex lock logger locate
+progs login logname look m4 machine mail make man mesg mkfifo
+progs mkstr modstat more msgs netstat newsyslog nfsstat nice nm nohup
+progs pagesize passwd paste patch pr printenv printf quota ranlib
+progs renice rev rlogin rpcgen rpcinfo rsh rup ruptime rusers rwall rwho
+progs script sed showmount size soelim split strings strip su tail talk
+progs tcopy tee telnet tftp time tip tn3270 touch tput tr true tset tsort
+progs tty ul uname unexpand unifdef uniq units unvis users uudecode uuencode
+progs vacation vgrind vi vis vmstat w wall wc what whatis whereis who
+progs whois window write xargs xinstall xstr yacc yes ypcat ypmatch ypwhich
+
+# shell scripts: lorder mkdep shar which
+# problems: rdist uses libcompat.a(regex.o), which conflicts with
+# libedit(readline.o) over regerror().
+
+# special requirements
+
+special locate srcdir /usr/src/usr.bin/locate/locate
+special tn3270 srcdir /usr/src/usr.bin/tn3270/tn3270
+
+
+# =========================================================================
+
+srcdirs /usr/src/usr.sbin
+
+progs ac accton amd arp bad144 catman chown chroot config config.new cron
+progs dev_mkdb diskpart edquota flcopy gettable grfinfo hilinfo htable inetd
+progs iostat iteconfig kvm_mkdb mrouted mtree named portmap pppd
+progs pstat pwd_mkdb quot quotaon rarpd rbootd repquota rmt rpc.bootparamd
+progs rwhod sa sliplogin slstats spray sysctl syslogd tcpdump
+progs traceroute trpt trsp update vipw vnconfig ypbind yppoll ypset
+
+special amd srcdir /usr/src/usr.sbin/amd/amd
+special amd objs vers.amd.o afs_ops.o am_ops.o clock.o util.o xutil.o efs_ops.o mapc.o info_file.o info_hes.o info_ndbm.o info_passwd.o info_nis.o info_union.o map.o srvr_afs.o srvr_nfs.o mntfs.o misc_rpc.o mount_fs.o mtab.o mtab_bsd.o nfs_ops.o nfs_prot_svc.o nfs_start.o nfs_subr.o opts.o pfs_ops.o rpc_fwd.o sched.o sfs_ops.o amq_svc.o amq_subr.o umount_fs.o host_ops.o nfsx_ops.o ufs_ops.o ifs_ops.o amd.o get_args.o restart.o wire.o
+
+
+srcdirs /usr/src/usr.sbin/lpr # lpr subsystem
+progs lpr lpc lpq lprm pac lptest
+special lpr srcdir /usr/src/usr.sbin/lpr/lpr
+
+srcdirs /usr/src/usr.sbin/sendmail # sendmail subsystem
+progs mailstats makemap praliases sendmail
+special sendmail srcdir /usr/src/usr.sbin/sendmail/src
+ln sendmail newaliases
+ln sendmail mailq
+
+srcdirs /usr/src/usr.sbin/timed # timed & timedc
+progs timed timedc
+special timed srcdir /usr/src/usr.sbin/timed/timed
+
+srcdirs /usr/src/usr.sbin/yp # yp subsystem
+progs ypbind ypwhich ypcat ypmatch ypset yppoll
+
+
+# =========================================================================
+
+srcdirs /usr/src/gnu/usr.bin
+
+progs bc cpio diff diff3 gas gawk grep gzip sdiff sort tar
+# shell scripts: send-pr
+
+srcdirs /usr/src/gnu/usr.bin/ld # ldd and ldconfig
+progs ld ldd ldconfig
+
+# rcs stuff loses because there are cross dependencies between librcs.a and
+# the individual programs. The solution would be to specify the objpaths
+# directly for each one, and include the full path to librcs.a each the
+# objpaths.
+
+# srcdirs /usr/src/gnu/usr.bin/rcs # rcs subsystem
+# progs ci co ident merge rcs rcsclean rcsdiff rcsmerge rlog
+# # shell script: rcsfreeze
+# special rcs srcdir /usr/src/gnu/usr.bin/rcs/rcs
+# libs /usr/src/gnu/usr.bin/rcs/lib/obj/librcs.a
+
+# gdb loses too
+# progs gdb
+# special gdb srcdir /usr/src/gnu/usr.bin/gdb/gdb
+# libs /usr/src/gnu/usr.bin/gdb/bfd/obj/libbfd.a
+# libs /usr/src/gnu/usr.bin/gdb/readline/obj/libreadline.a
+# libs /usr/src/gnu/usr.bin/gdb/libiberty/obj/libiberty.a
+
+# groff has the same problem as rcs
+# srcdirs /usr/src/gnu/usr.bin/groff # groff subsystem
+# progs groff troff tbl pic eqn grops grotty grodvi refer lookbib
+# progs indxbib lkbib tfmtodit addftinfo pfbtops psbb
+# shell script: nroff
+# special groff srcdir /usr/src/gnu/usr.bin/groff/groff
+# libs /usr/src/gnu/usr.bin/groff/libgroff/obj/libgroff.a
+# libs /usr/src/gnu/usr.bin/groff/libbib/obj/libbib.a
+# libs /usr/src/gnu/usr.bin/groff/libdriver/obj/libdriver.a
+
+srcdirs /usr/src/gnu/usr.bin/gcc2 # gcc & friends
+progs cc cpp cc1
+
+# cc1 has the same problem as rcs and groff, but since there's only one program
+# I'll go ahead and solve it as an example.
+
+special cc1 objpaths /usr/src/gnu/usr.bin/gcc2/cc1/obj/c-parse.o /usr/src/gnu/usr.bin/gcc2/cc1/obj/c-lang.o /usr/src/gnu/usr.bin/gcc2/cc1/obj/c-lex.o /usr/src/gnu/usr.bin/gcc2/cc1/obj/c-pragma.o /usr/src/gnu/usr.bin/gcc2/cc1/obj/c-decl.o /usr/src/gnu/usr.bin/gcc2/cc1/obj/c-typeck.o /usr/src/gnu/usr.bin/gcc2/cc1/obj/c-convert.o /usr/src/gnu/usr.bin/gcc2/cc1/obj/c-aux-info.o /usr/src/gnu/usr.bin/gcc2/cc1/obj/c-iterate.o /usr/src/gnu/usr.bin/gcc2/common/obj/libcc1.a
+
+ln gzip gunzip
+ln gzip gzcat
+
+libs -ledit -lgnumalloc -lc -lcrypt -ltermcap -lcurses -ltelnet -lutil -lkvm
+libs -ll -ly -lm -lresolv -lrpcsvc -lcompat
diff --git a/contrib/manctl/Makefile b/contrib/manctl/Makefile
new file mode 100644
index 000000000000..7a2ae922f572
--- /dev/null
+++ b/contrib/manctl/Makefile
@@ -0,0 +1,11 @@
+# Makefile
+# $Id: Makefile,v 1.4 1994/05/26 20:16:49 csgr Exp $
+
+all:
+ @echo -n
+
+install: all
+ install -c -o ${BINOWN} -g ${BINGRP} -m 555 ${.CURDIR}/manctl.sh \
+ ${DESTDIR}/usr/sbin/manctl
+
+.include <bsd.prog.mk>
diff --git a/contrib/manctl/manctl.sh b/contrib/manctl/manctl.sh
new file mode 100644
index 000000000000..97116cfb31c4
--- /dev/null
+++ b/contrib/manctl/manctl.sh
@@ -0,0 +1,376 @@
+#!/bin/sh
+#
+# Copyright (c) 1994 Geoffrey M. Rehmet, Rhodes University
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# 3. All advertising materials mentioning features or use of this software
+# must display the following acknowledgement:
+# This product includes software developed by Geoffrey M. Rehmet
+# 4. Neither the name of Geoffrey M. Rehmet nor that of Rhodes University
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL GEOFFREY M. REHMET OR RHODES UNIVERSITY BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+# $Id: manctl.sh,v 1.4 1994/04/18 18:46:50 csgr Exp $
+#
+# manctl:
+# a utility for manipulating manual pages
+# functions:
+# compress uncompressed man pages (elliminating .so's)
+# this is now two-pass. If possible, .so's
+# are replaced with hard links
+# uncompress compressed man pages
+# purge old formatted man pages (not implemented yet)
+# Things to watch out for:
+# Hard links - careful with g(un)zipping!
+# .so's - throw everything through soelim before gzip!
+# symlinks - ignore these - eg: expn is its own man page:
+# don't want to compress this!
+#
+PATH=/bin:/sbin:/usr/bin:/usr/sbin
+
+#
+# purge cat? directories
+#
+do_purge()
+{
+ echo "purge $@" 2>&1
+ echo "not implemented yet\n" 2>&1
+}
+
+
+#
+# Uncompress one page
+#
+uncompress_page()
+{
+ local pname
+ local fname
+ local sect
+ local ext
+
+ # break up file name
+ pname=$1
+ IFS='.' ; set $pname
+ # less than 3 fields - don't know what to do with this
+ if [ $# -lt 3 ] ; then
+ IFS=" " ; echo ignoring $pname 1>&2 ; return 0 ;
+ fi
+ # construct name and section
+ fname=$1 ; shift
+ while [ $# -gt 2 ] ; do
+ fname=$fname.$1
+ shift
+ done
+ sect=$1
+ ext=$2
+
+ IFS=" "
+ case "$ext" in
+ gz|Z) {
+ IFS=" " ; set `file $pname`
+ if [ $2 != "gzip" ] ; then
+ echo moving hard link $pname 1>&2
+ mv $pname $fname.$ext # link
+ else
+ if [ $2 != "symbolic" ] ; then
+ echo gunzipping page $pname 1>&2
+ gunzip -c $pname > /tmp/manager.$$
+ chmod u+w $pname
+ cp /tmp/manager.$$ $pname
+ chmod 444 $pname
+ mv $pname $fname.$sect
+ rm /tmp/manager.$$
+ else
+ # skip symlinks - this can be
+ # a program like expn, which is
+ # its own man page !
+ echo skipping symlink $pname 1>&2
+ fi
+ fi };;
+ *) {
+ IFS=" "
+ echo skipping file $pname 1>&2
+ } ;;
+ esac
+ # reset IFS - this is important!
+ IFS=" "
+}
+
+
+#
+# Uncompress manpages in paths
+#
+do_uncompress()
+{
+ local i
+ local dir
+ local workdir
+
+ workdir=`pwd`
+ while [ $# != 0 ] ; do
+ if [ -d $1 ] ; then
+ dir=$1
+ cd $dir
+ for i in * ; do
+ case $i in
+ *cat?) ;; # ignore cat directories
+ *) {
+ if [ -d $i ] ; then
+ do_uncompress $i
+ else
+ if [ -e $i ] ; then
+ uncompress_page $i
+ fi
+ fi } ;;
+ esac
+ done
+ cd $workdir
+ else
+ echo "directory $1 not found" 1>&2
+ fi
+ shift
+ done
+}
+
+#
+# Remove .so's from one file
+#
+so_purge_page()
+{
+ local so_entries
+ local lines
+ local fname
+
+ so_entries=`grep "^\.so" $1 | wc -l`
+ if [ $so_entries -eq 0 ] ; then ; return 0 ; fi
+
+ # we have a page with a .so in it
+ echo $1 contains a .so entry 2>&1
+
+ # now check how many lines in the file
+ lines=`wc -l < $1`
+
+ # if the file is only one line long, we can replace it
+ # with a hard link!
+ if [ $lines -eq 1 ] ; then
+ fname=$1;
+ echo replacing $fname with a hard link
+ set `cat $fname`;
+ rm -f $fname
+ ln ../$2 $fname
+ else
+ echo inlining page $fname 1>&2
+ cat $fname | \
+ (cd .. ; soelim ) > /tmp/manager.$$
+ chmod u+w $fname
+ cp /tmp/manager.$$ $fname
+ chmod 444 $fname
+ fi
+}
+
+#
+# Remove .so entries from man pages
+# If a page consists of just one line with a .so,
+# replace it with a hard link
+#
+remove_so()
+{
+ local pname
+ local fname
+ local sect
+
+ # break up file name
+ pname=$1
+ IFS='.' ; set $pname
+ if [ $# -lt 2 ] ; then
+ IFS=" " ; echo ignoring $pname 1>&2 ; return 0 ;
+ fi
+ # construct name and section
+ fname=$1 ; shift
+ while [ $# -gt 1 ] ; do
+ fname=$fname.$1
+ shift
+ done
+ sect=$1
+
+ IFS=" "
+ case "$sect" in
+ gz) { echo file $pname already gzipped 1>&2 ; } ;;
+ Z) { echo file $pname already compressed 1>&2 ; } ;;
+ [12345678ln]*){
+ IFS=" " ; set `file $pname`
+ if [ $2 = "gzip" ] ; then
+ echo moving hard link $pname 1>&2
+ mv $pname $pname.gz # link
+ else
+ if [ $2 != "symbolic" ] ; then
+ echo "removing .so's in page $pname" 1>&2
+ so_purge_page $pname
+ else
+ # skip symlink - this can be
+ # a program like expn, which is
+ # its own man page !
+ echo skipping symlink $pname 1>&2
+ fi
+ fi };;
+ *) {
+ IFS=" "
+ echo skipping file $pname 1>&2
+ } ;;
+ esac
+ # reset IFS - this is important!
+ IFS=" "
+}
+
+
+#
+# compress one page
+# We need to watch out for hard links here.
+#
+compress_page()
+{
+ local pname
+ local fname
+ local sect
+
+ # break up file name
+ pname=$1
+ IFS='.' ; set $pname
+ if [ $# -lt 2 ] ; then
+ IFS=" " ; echo ignoring $pname 1>&2 ; return 0 ;
+ fi
+ # construct name and section
+ fname=$1 ; shift
+ while [ $# -gt 1 ] ; do
+ fname=$fname.$1
+ shift
+ done
+ sect=$1
+
+ IFS=" "
+ case "$sect" in
+ gz) { echo file $pname already gzipped 1>&2 ; } ;;
+ Z) { echo file $pname already compressed 1>&2 ; } ;;
+ [12345678ln]*){
+ IFS=" " ; set `file $pname`
+ if [ $2 = "gzip" ] ; then
+ echo moving hard link $pname 1>&2
+ mv $pname $pname.gz # link
+ else
+ if [ $2 != "symbolic" ] ; then
+ echo gzipping page $pname 1>&2
+ cat $pname | \
+ (cd .. ; soelim )| gzip -c -- > /tmp/manager.$$
+ chmod u+w $pname
+ cp /tmp/manager.$$ $pname
+ chmod 444 $pname
+ mv $pname $pname.gz
+ rm /tmp/manager.$$
+ else
+ # skip symlink - this can be
+ # a program like expn, which is
+ # its own man page !
+ echo skipping symlink $pname 1>&2
+ fi
+ fi };;
+ *) {
+ IFS=" "
+ echo skipping file $pname 1>&2
+ } ;;
+ esac
+ # reset IFS - this is important!
+ IFS=" "
+}
+
+#
+# Compress man pages in paths
+#
+do_compress_so()
+{
+ local i
+ local dir
+ local workdir
+ local what
+
+ what=$1
+ shift
+ workdir=`pwd`
+ while [ $# != 0 ] ; do
+ if [ -d $1 ] ; then
+ dir=$1
+ cd $dir
+ for i in * ; do
+ case $i in
+ *cat?) ;; # ignore cat directories
+ *) {
+ if [ -d $i ] ; then
+ do_compress_so $what $i
+ else
+ if [ -e $i ] ; then
+ $what $i
+ fi
+ fi } ;;
+ esac
+ done
+ cd $workdir
+ else
+ echo "directory $1 not found" 1>&2
+ fi
+ shift
+ done
+}
+
+#
+# Display a usage message
+#
+ctl_usage()
+{
+ echo "usage : $1 -compress <path> ... " 1>&2
+ echo " $1 -uncompress <path> ... " 1>&2
+ echo " $1 -purge <days> <path> ... " 1>&2
+ echo " $1 -purge expire <path> ... " 1>&2
+ exit 1
+}
+
+#
+# remove .so's and do compress
+#
+do_compress()
+{
+ # First remove all so's from the pages to be compressed
+ do_compress_so remove_so "$@"
+ # now do ahead and compress the pages
+ do_compress_so compress_page "$@"
+}
+
+#
+# dispatch options
+#
+if [ $# = 0 ] ; then ; ctl_usage $0 ; fi ;
+
+case "$1" in
+ -compress) shift ; do_compress "$@" ;;
+ -uncompress) shift ; do_uncompress "$@" ;;
+ -purge) shift ; do_purge "$@" ;;
+ *) ctl_usage $0 ;;
+esac
diff --git a/contrib/tcpdump/tcpdump/tcpdump.1 b/contrib/tcpdump/tcpdump/tcpdump.1
index 61148f494014..da584b45b954 100644
--- a/contrib/tcpdump/tcpdump/tcpdump.1
+++ b/contrib/tcpdump/tcpdump/tcpdump.1
@@ -1,4 +1,4 @@
-.\" @(#) $Header: /home/cvs/386BSD/src/contrib/tcpdump/tcpdump/tcpdump.1,v 1.1.1.1.2.1 1994/05/01 16:00:56 jkh Exp $ (LBL)
+.\" @(#) $Header: /home/cvs/386BSD/src/contrib/tcpdump/tcpdump/tcpdump.1,v 1.2 1994/04/24 01:19:05 jkh Exp $ (LBL)
.\"
.\" Copyright (c) 1988, 1989, 1990, 1991, 1992
.\" The Regents of the University of California.
diff --git a/contrib/tcpdump/tcpslice/tcpslice.1 b/contrib/tcpdump/tcpslice/tcpslice.1
index 92af935f2897..1e0f7dca8b19 100644
--- a/contrib/tcpdump/tcpslice/tcpslice.1
+++ b/contrib/tcpdump/tcpslice/tcpslice.1
@@ -1,4 +1,4 @@
-.\" @(#) $Header: /home/cvs/386BSD/src/contrib/tcpdump/tcpslice/tcpslice.1,v 1.1.1.1.2.1 1994/05/01 16:01:05 jkh Exp $ (LBL)
+.\" @(#) $Header: /home/cvs/386BSD/src/contrib/tcpdump/tcpslice/tcpslice.1,v 1.1.1.1 1993/06/12 14:42:16 rgrimes Exp $ (LBL)
.\"
.\" Copyright (c) 1988-1990 The Regents of the University of California.
.\" All rights reserved.
diff --git a/contrib/xntpd/COPYRIGHT b/contrib/xntpd/COPYRIGHT
index 711a8f1efcb4..b9ce773f163a 100644
--- a/contrib/xntpd/COPYRIGHT
+++ b/contrib/xntpd/COPYRIGHT
@@ -1,6 +1,6 @@
/******************************************************************************
* *
- * Copyright (c) David L. Mills 1992, 1993, 1994 *
+ * Copyright (c) David L. Mills 1992, 1993, 1994 *
* *
* Permission to use, copy, modify, and distribute this software and its *
* documentation for any purpose and without fee is hereby granted, provided *
@@ -55,4 +55,6 @@
* Torsten Duwe <duwe@immd4.informatik.uni-erlangen.de> (Linux Port)
* Paul A Vixie <vixie@vix.com> (TrueTime GPS driver)
* Jim Jagielski <jim@jagubox.gsfc.nasa.gov> (A/UX port)
-*/
+ * Ray Schnitzler <schnitz@unipress.com> (First pass at a Unixware1 port.)
+ * Ajit Thyagarajan <ajit@ee.udel.edu> (IP multicast support)
+ */
diff --git a/contrib/xntpd/Makefile.inc b/contrib/xntpd/Makefile.inc
index 0983df967f72..f38f0a91a3dc 100644
--- a/contrib/xntpd/Makefile.inc
+++ b/contrib/xntpd/Makefile.inc
@@ -1,7 +1,7 @@
DEFS_LOCAL=-DREFCLOCK -DPARSE
-NTPDEFS= -DSYS_FREEBSD -DSYS_386BSD -DHAVE_TERMIOS
+NTPDEFS= -DSYS_FREEBSD -DSYS_386BSD
AUTHDEFS= -DMD5
CLOCKDEFS= -DLOCAL_CLOCK -DPST -DWWVB -DAS2201 -DGOES -DGPSTM -DOMEGA \
- -DLEITCH
+ -DLEITCH -DTRAK
CFLAGS+= ${NTPDEFS} ${DEFS_LOCAL} ${AUTHDEFS} ${CLOCKDEFS} ${COPTS}
BINDIR?= /usr/sbin
diff --git a/contrib/xntpd/README.FreeBSD b/contrib/xntpd/README.FreeBSD
index 437d4783d1ed..8fd237e1640c 100644
--- a/contrib/xntpd/README.FreeBSD
+++ b/contrib/xntpd/README.FreeBSD
@@ -1,6 +1,8 @@
+ $Id: README.FreeBSD,v 1.7 1994/04/21 21:10:20 wollman Exp $
+
This version of NTP was converted to the BSD-style Makefile system by
Garrett Wollman (wollman@freefall.cdrom.com); it is based on version
-3.3z (late beta) from the University of Delaware.
+3.3s (late beta) from the University of Delaware.
Besides the Makefile changes, the DES code has been completely removed
in order to make this code exportable. If you have a legal copy of
@@ -8,3 +10,75 @@ in order to make this code exportable. If you have a legal copy of
to the AUTHDEFS in Makefile.inc.
You can change CLOCKDEFS in the same file to add other reference clocks.
+
+This version of xntpd knows how to talk to the kernelized NTP PLL which is
+present in versions of FreeBSD-current after 21 April 1994. When this code
+is more widely released, I'll provide the patches to Mills.
+
+----------------------------------------------------
+Support for Conrad electronic's "DCF-77 Uhr, Mobil".
+----------------------------------------------------
+Conrad electronic in Germany,, Phone (+49) 962230111 (?), sells a gadget
+called "DCF77 Uhr, mobil", which is a DCF77 timecode receiver with a
+rs-232 interface. The price is around DM130.
+ 9-pin interface is Order# 97 94 57 66
+ 25-pin interface is Order# 97 94 81 66
+
+You must define
+ -DDCF77 -DPPS -DFREEBSD_CONRAD -DDEBUG
+when you compile xntpd. You can later remove -DDEBUG, if you feel like it.
+
+You must also have
+ options COM_BIDIR
+defined in your kernel, and finally the ttyport you intend to use must
+have special interrupt vector:
+ device sio1 at isa? port "IO_COM2" tty irq 3 vector siointrts
+ ^^^^^^^^^^^^
+connect the radio-clock to the tty port and link it to /dev/refclock-0:
+
+ cd /dev
+ sh MAKEDEV cua1
+ ln -s /dev/cua01 /dev/refclock-0
+
+make a directory to gather statistics in:
+ mkdir /var/tmp/ntp
+
+Create a /etc/ntp.conf along these lines:
+
+ # DCF77 without PPS
+ server 127.127.8.20
+ # DCF77 with PPS
+ #server 127.127.8.148 prefer
+
+ driftfile /var/tmp/ntp/ntp.drift
+ statsdir /var/tmp/ntp
+ statistics loopstats
+ statistics peerstats
+ statistics clockstats
+ filegen peerstats file peerstats type day enable
+ filegen loopstats file loopstats type day enable
+ filegen clockstats file clockstats type day enable
+
+Try to start it:
+ comcontrol ttyd1 bidir
+ tickadj -A
+ xntpd -d -d -d
+
+You should see the red LED flash on the receiver every second now. You
+may have to experiment a bit with the location, and possibly adjust the
+minute variable resistor inside to get a good signal. Be aware, that just
+because you see the light flash, is not the same as the signal being
+received by the computer. The chip doing the work in the reciver uses
+less than 1 micro-ampere, so even if RTS isn't pulled low, it will happily
+receive, but be unable to buffer the signal to the rs-232 levels needed.
+
+You can see what's going on in /var/log/messages, and query the
+daemon using xntpdc and ntpq, in particular the "clockvar" command
+of ntpq will tell about the clocks healt.
+
+I live in Slagelse, Denmark, which is ~1000 Km from Mainflingen, yet
+I have +/- 2 ms precision from this cheap gadget. If you have a very
+stable signal, you can use the 'pps' address instead to improve your
+timing.
+
+Have fun... Poul-Henning Kamp <phk@login.dkuug.dk>
diff --git a/contrib/xntpd/RELNOTES b/contrib/xntpd/RELNOTES
index 1b9d9c02c3b3..411ef452195b 100644
--- a/contrib/xntpd/RELNOTES
+++ b/contrib/xntpd/RELNOTES
@@ -31,6 +31,10 @@ this distribution. To make these programs:
For custom tailored configuration copying Config.local.dist to Config.local
and editing Config.local to suit the local needs is neccessary (at most
3 lines to change), or use one of the make's above and then tweak it.
+ Config.local can also be used to override common settings from the
+ machines/* files like the AUTHDEFS= to select very specific configurations.
+ Please use this feature with care and don't be disappointed if it doesn't
+ work the way you expect.
(2) Type "make" to compile everything of general interest. Expect few or
no warnings using cc and a moderate level of warnings using gcc.
@@ -140,6 +144,7 @@ the meal. The converse is not always true.
PC BSD/386 1.0 gcc LOCAL_CLOCK possibly see "build problems"
PC Linux (pl14) gcc LOCAL_CLOCK (dw 93/10/30)
PC Dell SVR4 v2.2 gcc ? (tl 93/12/30)
+ PC Unixware1/SVR4 cc no tickadj, ? (ras 93/04/11)
NCR3445 NCR SVR4 cc LOCAL_CLOCK (tm 93/11/29)
pb: Piete Brooks
@@ -149,6 +154,7 @@ the meal. The converse is not always true.
tl: Tony Lill <ajlill@tlill.hookup.net>
tm: Tom Moore <Tom.Moore@DaytonOH.NCR.COM>
jmj: Jim Jagielski <jim@jagubox.gsfc.nasa.gov>
+ ras: Ray Schnitzler <schnitz@unipress.com>
Build Problems (and workaround):
diff --git a/contrib/xntpd/VERSION b/contrib/xntpd/VERSION
index 85051bd4db45..c145b870451f 100644
--- a/contrib/xntpd/VERSION
+++ b/contrib/xntpd/VERSION
@@ -1 +1 @@
-version=3.3c (beta)
+version=3.3s (beta multicast)
diff --git a/contrib/xntpd/authstuff/authspeed.c b/contrib/xntpd/authstuff/authspeed.c
index c83d5b24497e..ecddbcd96ba1 100644
--- a/contrib/xntpd/authstuff/authspeed.c
+++ b/contrib/xntpd/authstuff/authspeed.c
@@ -2,7 +2,7 @@
* authspeed - figure out how LONG it takes to do an NTP encryption
*/
-#if defined(SYS_HPUX) || defined(SYS_AUX3) || defined(SYS_AUX2) || defined(SOLARIS) || defined(SYS_SVR4) || defined(SYS_PTX)
+#if defined(SYS_HPUX) || defined(SYS_AUX3) || defined(SYS_AUX2) || defined(SOLARIS) || defined(SYS_SVR4) || defined(SYS_PTX) || defined(SYS_UNIXWARE1)
#define FAKE_RUSAGE
#endif
diff --git a/contrib/xntpd/compilers/.keep_me b/contrib/xntpd/compilers/.keep_me
deleted file mode 100644
index e69de29bb2d1..000000000000
--- a/contrib/xntpd/compilers/.keep_me
+++ /dev/null
diff --git a/contrib/xntpd/conf/Config.local b/contrib/xntpd/conf/Config.local
index 12a6dfece755..22c12a36e90a 100644
--- a/contrib/xntpd/conf/Config.local
+++ b/contrib/xntpd/conf/Config.local
@@ -78,7 +78,7 @@ DEFS_OPT=-DDEBUG
# special distribution.
#
# Note: following line must always start with DEFS_LOCAL= $(DEFS_OPT)
-DEFS_LOCAL= $(DEFS_OPT) -DREFCLOCK -DPPSPPS -DKERNEL_PLL
+DEFS_LOCAL= $(DEFS_OPT) -DREFCLOCK -DKERNEL_PLL -DMCAST
#
# Radio clock support definitions (these only make sense if -DREFCLOCK
@@ -182,7 +182,7 @@ DEFS_LOCAL= $(DEFS_OPT) -DREFCLOCK -DPPSPPS -DKERNEL_PLL
# under Ultrix 4.2a/3. If the MX4200 is removed, all the rest compile on a DEC
# OSF/1 Alpha.
#
-CLOCKDEFS= -DLOCAL_CLOCK -DAS2201PPS -DCHUPPS -DGOES -DIRIG -DMX4200PPS -DOMEGA -DPSTCLK -DTPRO -DWWVBCLK -DMSFEESPPS -DLEITCH
+CLOCKDEFS= -DLOCAL_CLOCK -DAS2201PPS -DCHUPPS -DGOES -DIRIG -DMX4200PPS -DOMEGA -DPSTCLK -DTPRO -DWWVBCLK -DLEITCH
#
# Directory into which binaries should be installed (default /usr/local)
diff --git a/contrib/xntpd/conf/Config.plain b/contrib/xntpd/conf/Config.plain
new file mode 100644
index 000000000000..67dd70ad50e6
--- /dev/null
+++ b/contrib/xntpd/conf/Config.plain
@@ -0,0 +1,190 @@
+# This is the local configure file (distribution version).
+# You must modify it to fit your particular configuration
+# and name it Config.local
+# The following configuratiions can be auto-generated:
+#
+# make Config.local.green
+# make a Config.local that supports a local clock
+# (i.e. allow fallback to use of the CPU's own clock)
+# make Config.local.NO.clock
+# make a Config.local that supports no clocks
+#
+#
+# NOTE TO GREENHORNS
+#
+# For plug-'n-play and no radios or other complicated gadgetry,
+# use "make Config.local.green" as above.
+#
+# Following defines can be set in the DEFS_OPT= define:
+#
+# The flag -DDEBUG includes some debugging code. To use this, include
+# the define and start the daemon with one or more -d flags, depending
+# on your calibration of pearannoya. The daemon will not detach your
+# terminal in this case. Judicious use of grep will reduce the speaker
+# volume to bearable levels.
+#
+# To change the location of the configuration file, use a
+# -DCONFIG_FILE=\\"/local/etc/ntp.conf\\" or something similar.
+#
+# The -DSYSLOG_FILE defines allows logging messages that are normally
+# reported via syslof() in a file. The file name can be configured using
+# the configuration line "logfile <filename>" in CONFIG_FILE.
+#
+# There are three serial port system software interfaces, each of
+# which is peculiar to one or more Unix versions. Define
+# -DHAVE_SYSV_TTYS for basic System V compatibility; define -DSTREAM
+# for POSIX compatibility including System V Streams, and
+# HAVE_BSD_TTYS for 4.3bsd compatibility. Only one of these three
+# should be defined. If none are defined, HAVE_BSD_TTYS is assumed.
+# Usually these defines are already set correctly.
+#
+DEFS_OPT=-DDEBUG
+
+#
+# The DEFS_LOCAL define picks up all flags from DEFS_OPT (do not delete that)
+# and one of the following:
+#
+# The flag -DREFCLOCK causes the basic reference clock support to be
+# compiled into the daemon. If you set this you may also want to
+# configure the particular clock drivers you want in the CLOCKDEFS= line
+# below. This flag affects xntpd only. This define is included by
+# default when using the "make makeconfig" script.
+#
+# The next two sets of defines are meaningful only when radio clock
+# drivers or special 1-pps signals are to be used. For systems without
+# these features, these delicious complexities can be avoided. Ordinarily,
+# the "make makeconfig" script figures out which ones to use, but your
+# mileage may vary.
+#
+# There are three ways to utilize external 1-pps signals. Define
+# -DPPS to include just the pps routine, such as used by the DCF77(PARSE)
+# clock driver. Define -DPPSCLK to include a serial device driver
+# which avoids much of the jitter due to upper level port
+# processing. This requires a dedicated serial port and either the
+# tty_clock line discipline or tty_clk_streams module, both of
+# which are in the ./kernel directory. Define -DPPSCD to include a
+# special driver which intercepts carrier-detect transitions
+# generated by the pps signal. This requires a nondedicated serial
+# port and the ppsclock streams module in the ./kernel directory.
+# Only one of these three flags should be defined.
+#
+# The flag KERNEL_PLL causes code to be compiled for a special feature of
+# the kernel that (a) implements the phase-lock loop and (b) provides
+# a user interface to learn time, maximum error and estimated error.
+# See the file README.kern in the doc directory for further info.
+# This code is activated only if the relevant kernel features have
+# been configured; it does not affect operation of unmodified kernels.
+# To compile it, however, requires a few header files from the
+# special distribution.
+#
+# Note: following line must always start with DEFS_LOCAL= $(DEFS_OPT)
+DEFS_LOCAL= $(DEFS_OPT) -DREFCLOCK -DKERNEL_PLL -DMCAST
+
+#
+# Radio clock support definitions (these only make sense if -DREFCLOCK
+# used), which is normally the case. Note that a configuration can include
+# no clocks, more than one type of clock and even multiple clocks of the
+# same type.
+#
+# For most radio clocks operating with serial ports, accuracy can
+# be considerably improved through use of the tty_clk line
+# discipline or tty_clk_STREAMS streams module found in the
+# ./kernel directory. These gizmos capture a timestamp upon
+# occurrence of an intercept character and stuff it in the data
+# stream for the clock driver to munch. To select this mode,
+# postfix the driver name with the string CLK; that is, WWVB
+# becomes WWVBCLK. If more than one clock is in use, the CLK
+# postfix can be used with any or all of them.
+#
+# Alternatively, for the best accuracy, use the ppsclock streams
+# module in the ./ppsclock directory to steal the carrier-detect
+# transition and capture a precision timestamp. At present this
+# works only with SunOS 4.1.1 or later. To select this mode,
+# postfix the driver name with the string PPS; that is, AS2201
+# becomes AS2201PPS. If more than one clock is in use, the PPS
+# postfix should be used with only one of them. If any PPS
+# postfix is defined, the -DPPSPPS define should be used on the
+# DEFS above.
+#
+# Define -DLOCAL_CLOCK for a local pseudo-clock to masquerade as a
+# reference clock for those subnets without access to the real thing.
+# Works in all systems and requires no hardware support. This is defined
+# by default when using the "make makeconfig" script and greenhorn
+# configuraiton.
+#
+# Define -DPST for a PST/Traconex 1020 WWV/H receiver. The driver
+# supports both the CLK and PPS modes. It should work in all systems
+# with a serial port.
+#
+# Define -DWWVB for a Spectracom 8170 or Netclock/2 WWVB receiver. It
+# should work in all systems with a serial port. The driver supports
+# both the CLK and PPS modes if the requisite kernel support is installed.
+#
+# Define -DCHU for a special CHU receiver using an ordinary shortwave
+# radio. This requires the chu_clk line discipline or chu_clk_STREAMS
+# module in the ./kernel directory. At present, this driver works only
+# on SunOS4.1.x; operation in other systems has not been confirmed.
+# Construction details for a suitable modem can be found in the ./gadget
+# directory. The driver supports # neither the CLK nor PPS modes.
+#
+# Define -DPARSE for a DCF77/GPS(GENERIC) receiver. For best performance
+# this requires a special parsestreams STREAMS (SunOS 4.x) module in the
+# ./parse directory. Define -DPARSEPPS for PPS support via the
+# DCF77/GPS (GENERIC) receiver; also, define -DPPS in the DEFS above.
+# Define: -DCLOCK_MEINBERG for Meinberg clocks
+# -DCLOCK_SCHMID for Schmid receivers
+# -DCLOCK_DCF7000 for ELV DCF7000
+# -DCLOCK_RAWDCF for simple receivers (100/200ms pulses on Rx)
+# -DCLOCK_TRIMSV6 for Trimble SV6 GPS receiver
+#
+# Define -DMX4200PPS for a Magnavox 4200 GPS receiver. At present, this
+# driver works only on SunOS4.1.x with CPU serial ports only. The PPS
+# mode is required.
+#
+# Define -DAS2201 for an Austron 2200A or 2201A GPS receiver. It should
+# work in all systems with a serial port. The driver does not support the
+# CLK mode, but does support the PPS mode. If the radio is connected to
+# more than one machine, the PPS mode is required.
+#
+# Define -DGOES for a Kinemetrics/TrueTime 468-DC GOES receiver. This
+# driver is known to work with some other TrueTime products as well,
+# including the GPS-DC GPS receiver. It should work in all systems with
+# a serial port. The driver does not support the CLK mode, but does
+# support the PPS mode.
+#
+# Define -DOMEGA for a Kinemetrics/TrueTime OM-DC OMEGA receiver. It
+# should work in all systems with a serial port. The driver does not
+# support the CLK mode, but does support the PPS mode.
+#
+# Define -DTPRO for a KSI/Odetics TPRO-S IRIG-B timecode reader. This
+# requires the SunOS interface driver available from KSI. The driver
+# supports neither the CLK nor PPS modes.
+#
+# Define -DLEITCH for a Leitch CSD 5300 Master Clock System Driver for
+# the HP 5061B Cesium Clock. It should work in all systems with a serial
+# port. The driver does not support the CLK mode, but does support the
+# PPS mode.
+#
+# Define -DMSFEESPPS for an EES M201 MSF receiver. It currently only works
+# under SunOS 4.x with the PPSCD (ppsclock) STREAMS module, but the RCS
+# files on cl.cam.ac.uk still has support for CLK and CBREAK modes.
+#
+# Define -DIRIG for a IRIG-B timecode timecode using the audio codec of
+# the Sun SPARCstations. This requires a modified BSD audio driver and
+# exclusive access to the audio port. A memo describing how it works and
+# how to install the driver is in the README.irig file in the ./doc
+# directory.
+#
+# Note: The following defines result in compilation of all the above radio
+# clocks. This works on a Sun 4.1.x system which has tty_clk, chu_clk and
+# ppsclock STREAMS modules installed. If the trailing CLK and PPS suffixes
+# are removed and the IRIG, PARSE* and CLOCK* deleted, all of the rest compile
+# under Ultrix 4.2a/3. If the MX4200 is removed, all the rest compile on a DEC
+# OSF/1 Alpha.
+#
+CLOCKDEFS= -DLOCAL_CLOCK -DCHU -DGOES -DOMEGA -DPST -DWWVB -DLEITCH
+
+#
+# Directory into which binaries should be installed (default /usr/local)
+#
+BINDIR= /usr/local/bin
diff --git a/contrib/xntpd/doc/README.kern b/contrib/xntpd/doc/README.kern
index 1b791c325ccf..aac26fa2e62b 100644
--- a/contrib/xntpd/doc/README.kern
+++ b/contrib/xntpd/doc/README.kern
@@ -1,567 +1,756 @@
- Unix Kernel Modifications for Precision Timekeeping
-
- Revised 3 December 1993
-
-Note: This information file is included in the distributions for the
-SunOS, Ultrix and OSF/1 kernels and in the NTP Version 3 distribution
-(xntp3.tar.Z) as the file README.kern. Availability of the kernel
-distributions, which involve licensed code, will be announced
-separately. The NTP Version 3 distribution can be obtained via anonymous
-ftp from louie.udel.edu in the directory pub/ntp. In order to utilize
-all features of this distribution, the NTP version number should be 3.3
+ A Kernel Model for Precision Timekeeping
+
+ Revised 3 April 1994
+
+Note: This memorandum is a substantial revision of RFC-1589, "A Kernel
+Model for Precision Timekeeping," March, 1994. It includes several
+changes to the daemon and user interfaces, as well as a new feature
+which disciplines the CPU clock oscillator in both time and frequency to
+a source of precision time signals. This memorandum is included in the
+distributions for the SunOS, Ultrix and OSF/1 kernels and in the NTP
+Version 3 distribution (xntp3.v.tar.Z) as the file README.kern, where v
+is the version identifier. Availability of the kernel distributions,
+which involve licensed code, will be announced separately. The NTP
+Version 3 distribution can be obtained via anonymous ftp from
+louie.udel.edu in the directory pub/ntp. In order to utilize all
+features of this distribution, the NTP version identifier should be 3q
or later.
+Overview
+
+This memorandum describes an engineering model which implements a
+precision time-of-day function for a generic operating system. The model
+is based on the principles of disciplined oscillators and phase-lock
+loops (PLL) and frequency-lock loops (FLL) often found in the
+engineering literature. It has been implemented in the Unix kernels for
+several workstations, including those made by Sun Microsystems and
+Digital Equipment. The model changes the way the system clock is
+adjusted in time and frequency, as well as provides mechanisms to
+discipline its frequency to an external precision timing source. The
+model incorporates a generic system-call interface for use with the
+Network Time Protocol (NTP) or similar time synchronization protocol.
+The NTP Version 3 daemon xntpd operates with this model to provide
+synchronization limited in principle only by the accuracy and stability
+of the external timing source.
+
+This memorandum does not obsolete or update any RFC. It does not propose
+a standard protocol, specification or algorithm. It is intended to
+provoke comment, refinement and implementations for kernels not
+considered herein. While a working knowledge of NTP is not required for
+an understanding of the design principles or implementation of the
+model, it may be helpful in understanding how the model behaves in a
+fully functional timekeeping system. The architecture and design of NTP
+is described in [MIL91], while the current NTP Version 3 protocol
+specification is given in RFC-1305 [MIL92a] and a subset of the
+protocol, the Simple Network Time Protocol (SNTP), is given in RFC-1361
+[MIL92c].
+
+The model has been implemented in the Unix kernels for three Sun
+Microsystems and Digital Equipment workstations. In addition, for the
+Digital machines the model provides improved precision to one
+microsecond (us). Since these specific implementations involve
+modifications to licensed code, they cannot be provided directly.
+Inquiries should be directed to the manufacturer's representatives.
+However, the engineering model for these implementations, including a
+simulator with code segments almost identical to the implementations,
+but not involving licensed code, is available via anonymous FTP from
+host louie.udel.edu in the directory pub/ntp and compressed tar archive
+kernel.tar.Z. The NTP Version 3 distribution can be obtained via
+anonymous ftp from the same host and directory in the compressed tar
+archive xntp3.3q.tar.Z, where the version number shown as 3.3q may be
+adjusted for new versions as they occur.
+
1. Introduction
-This memo describes modifications to certain SunOS, Ultrix and OSF/1
-kernel software that manage the system clock and timer functions. They
-provide improved accuracy and stability through the use of a disciplined
-clock interface for use with the Network Time Protocol (NTP) or similar
-time-synchronization protocol. In addition, for the DEC 3000 AXP (Alpha)
-and DECstation 5000/240 machines, the modifications provide improved
-precision within one microsecond (us) (SunOS 4.1.x already does provide
-precision to this order). The NTP Version 3 daemon xntpd operates with
-these kernel modifications to provide synchronization in principle to
-within this order, but in practice this is limited by the short-term
-stability of the timer oscillator to within the order of 100 usec.
-
-This memo describes the principles behind the design and operation of
-the new software. There are three versions: one that operates with the
-SunOS 4.1.x kernels, a second that operates with the Ultrix 4.x kernels
-and a third that operates with the OSF/1 V1.x kernels. A detailed
-description of the variables and algorithms is given in the hope that
-similar functionality can be incorporated in Unix kernels for other
-machines. The algorithms involve only minor changes to the system clock
-and interval timer routines and include interfaces for application
-programs to learn the system clock status and certain statistics of the
-time-synchronization process. Detailed installation instructions are
-given in a companion README.install file included in the kernel
-distributions. The kernel software itself is not provided for public
-distribution, since it involves licensed code. Detailed instructions on
-how to obtain it for either SunOS, Ultrix or OSF/1 will be given
-separately.
-
-The principal feature added to the Unix kernels is to change the way the
-system clock is controlled, in order to provide precision time and
-frequency adjustments. Another feature utilizes an undocumented bus-
-cycle counter in the DEC 3000 AXP and DECstation 5000/240 to provide
-precise time to the microsecond. This feature can in principle be used
-with any DEC machine that has this counter, although this has not been
-verified. The addition of these features does not affect the operation
-of existing Unix system calls such as gettimeofday(), settimeofday() and
-adjtime(); however, if the new features are in use, the operations of
-adjtime() are controlled instead by a new system call ntp_adjtime().
-
-Most Unix programs read the system clock using the gettimeofday() system
-call, which returns only the system time and timezone data. For some
-applications it is useful to know the maximum error of the reported time
-due to all causes, including clock reading errors, oscillator frequency
-errors and accumulated latencies on the path to a primary reference
-source. However, the new software can adjust the system clock to
-compensate for its intrinsic frequency error, so that the timing errors
-expected in normal operation will usually be much less than the maximum
-error. The user application interface includes a new system call
-ntp_gettime(), which returns the system time, as well as the maximum
-error and estimated error. This interface is intended to support
-applications that need such things, including distributed file systems,
-multimedia teleconferencing and other real-time applications. The
-protocol daemon application interface includes a new system call
-ntp_adjtime(), which can be used to read and write kernel variables used
-for precision timekeeping, including time and frequency adjustments,
-controlling time constant, leap-second warning and related data.
-
-In this memo, NTP Version 3 and the Unix implementation xntpd are used
-as an example application of the new system calls for use by a protocol
-daemon. In principle, the new system calls can be used by other
-protocols and daemon implementations as well. Even in cases where the
+This memorandum describes a model and programming interface for generic
+operating system software that manages the system clock and timer
+functions. The model provides improved accuracy and stability for most
+computers using the Network Time Protocol (NTP) or similar time
+synchronization protocol. This memorandum describes the design
+principles and implementations of the model, while related technical
+reports discuss the design approach, engineering analysis and
+performance evaluation of the model as implemented in Unix kernels for
+modern workstations. The NTP Version 3 daemon xntpd operates with these
+implementations to provide improved accuracy and stability, together
+with diminished overhead in the operating system and network. In
+addition, the model supports the use of external timing sources, such as
+precision pulse-per-second (PPS) signals and the industry standard IRIG
+timing signals. The NTP daemon automatically detects the presence of the
+new features and utilizes them when available.
+
+There are three prototype implementations of the model presented in this
+memorandum, one each for the Sun Microsystems SPARCstation with the
+SunOS 4.1.x kernel, Digital Equipment DECstation 5000 with the Ultrix
+4.x kernel and Digital Equipment 3000 AXP Alpha with the OSF/1 V1.x
+kernel. In addition, for the DECstation 5000/240 and 3000 AXP Alpha
+machines, a special feature provides improved precision to 1 us (stock
+Sun kernels already do provide this precision). Other than improving the
+system clock accuracy, stability and precision, these implementations do
+not change the operation of existing Unix system calls which manage the
+system clock, such as gettimeofday(), settimeofday() and adjtime();
+however, if the new features are in use, the operations of
+gettimeofday() and adjtime() can be controlled instead by new system
+calls ntp_gettime() and ntp_adjtime() as described below.
+
+A detailed description of the variables and algorithms that operate upon
+them is given in the hope that similar functionality can be incorporated
+in Unix kernels for other machines. The algorithms involve only minor
+changes to the system clock and interval timer routines and include
+interfaces for application programs to learn the system clock status and
+certain statistics of the time synchronization process. Detailed
+installation instructions are given in a specific README files included
+in the kernel distributions.
+
+In this memorandum, NTP Version 3 and the Unix implementation xntp3 are
+used as an example application of the new system calls for use by a
+synchronization daemon. In principle, these system calls can be used by
+other protocols and implementations as well. Even in cases where the
local time is maintained by periodic exchanges of messages at relatively
-long intervals, such as using the NIST Automated Computer Time Service,
-the ability to precisely adjust the local clock frequency simplifies the
-synchronization procedures and allows the call frequency to be
-considerably reduced.
-
-2. Design Principles
-
-In order to understand how the new software works, it is useful to
-consider how most Unix systems maintain the system time. In the original
-design a hardware timer interrupts the kernel at a fixed rate: 100 Hz in
-the SunOS kernel, 256 Hz in the Ultrix kernel and 1024 Hz in the OSF/1
-kernel. Since the Ultrix kernel rate does not evenly divide one second
-in microseconds, the kernel adds 64 microseconds once each second, so
-the timescale consists of 255 advances of 3906 usec plus one of 3970
-usec. Similarly, the OSF/1 kernel adds 576 usec once each second, so its
-timescale consists of 1023 advances of 976 usec plus one of 1552 usec.
-
-In all Unix kernels considered in this memo, it is possible to slew the
-system clock to a new offset using the standard Unix adjtime() system
-call. To do this the clock frequency is changed by adding or subtracting
-a fixed amount (tickadj) at each timer interrupt (tick) for a calculated
-number of ticks. Since this calculation involves dividing the requested
-offset by tickadj, it is possible to slew to a new offset with a
-precision only of tickadj, which is usually in the neighborhood of 5 us,
-but sometimes much higher. This results in an amortization error which
-can accumulate to unacceptable levels, so that special provisions must
-be made in the clock adjustment procedures of the protocol daemon.
-
-In order to maintain the system clock within specified bounds with this
-scheme, it is necessary to call adjtime() on a regular basis. For
-instance, let the bound be set at 100 usec, which is a reasonable value
-for NTP-synchronized hosts on a local network, and let the onboard
-oscillator tolerance be 100 parts-per-million (ppm), which is a
-reasonably conservative assumption. This requires that adjtime() be
-called at intervals not exceeding 1 second (s), which is in fact what
-the unmodified NTP software daemon does.
-
-In the new software this scheme is replaced by another that extends the
-low-order bits of the system clock to provide very precise clock
-adjustments. At each timer interrupt a precisely calibrated quantity is
-added to the composite time value and overflows handled as required. The
-quantity is computed from the measured clock offset and in addition a
-frequency adjustment, which is automatically calculated from previous
-time adjustments. This implementation operates as an adaptive-parameter
-first-order, type-II, phase-lock loop (PLL), which in principle provides
-precision control of the system clock phase to within +-1 us and
-frequency to within +-5 nanoseconds (ns) per day.
-
-This PLL model is identical to the one implemented in NTP, except that
-in NTP the software daemon has to simulate the PLL using only the
-original adjtime() system call. The daemon is considerably complicated
-by the need to parcel time adjustments at frequent intervals in order to
-maintain the accuracy to specified bounds. The modified kernel routines
-do this directly, allowing vast gobs of ugly daemon code to be avoided
-at the expense of only a small amount of new code in the kernel. In
-fact, the amount of code added to the kernel for the new scheme is about
-the amount needed to implement the old scheme. A new system call
-ntp_adjtime(), which operates in a way similar to the original
-adjtime(), is called only as each new time update is determined, which
-in NTP occurs at intervals of from 16 s to 1024 s. In addition, doing
-the frequency correction in the kernel means that the system time runs
-true even if the daemon were to cease operation or the network paths to
-the primary reference source fail. The addition of the new ntp_adjtime()
-system call does not affect the original adjtime() system call, which
-continues to operate in its traditional fashion. However, the two system
-calls canot be used at the same time; only one of the two should be used
-on any given system.
-
-It is the intent in the design that settimeofday() be used for changes
-in system time greater than +-128 ms. It has been the Internet
-experience that the need to change the system time in increments greater
-than +-128 milliseconds is extremely rare and is usually associated with
-a hardware or software malfunction or system reboot. Once the system
-clock has been set in this way, the ntp_adjtime() system call is used to
-provide periodic updates including the time offset, maximum error,
-estimated error and PLL time constant. With NTP the update interval
-depends on the measured error and time constant; however, the scheme is
-quite forgiving and neither moderate loss of updates nor variations in
-the length of the polling interval are serious.
-
-In addition, the kernel adjusts the maximum error to grow by an amount
-equal to the oscillator frequency tolerance times the elapsed time since
-the last update. The default engineering parameters have been optimized
-for intervals not greater than about 16 s. For longer intervals the PLL
-time constant can be adjusted to optimize the dynamic response up to
-intervals of 1024 s. Normally, this is automatically done by NTP. In any
-case, if updates are suspended, the PLL coasts at the frequency last
+long intervals, such as using the NIST Automated Computer Time Service
+[LEV89], the ability to precisely adjust the system clock frequency
+simplifies the synchronization procedures and allows the telephone call
+frequency to be considerably reduced.
+
+2. Design Approach
+
+While not strictly necessary for an understanding or implementation of
+the model, it may be helpful to briefly describe how NTP operates to
+control the system clock in a client computer. As described in [MIL91],
+the NTP protocol exchanges timestamps with one or more peers sharing a
+synchronization subnet to calculate the time offsets between peer clocks
+and the local clock. These offsets are processed by several algorithms
+which refine and combine the offsets to produce an ensemble average,
+which is then used to adjust the local clock time and frequency. The
+manner in which the local clock is adjusted represents the main topic of
+this memorandum. The goal in the enterprise is the most accurate and
+stable system clock possible with the available computer hardware and
+kernel software.
+
+In order to understand how the new model works, it is useful to review
+how most Unix kernels maintain the system clock. In the Unix design a
+hardware counter interrupts the kernel at a fixed rate: 100 Hz in the
+SunOS kernel, 256 Hz in the Ultrix kernel and 1024 Hz in the OSF/1
+kernel. Since the Ultrix timer interval (reciprocal of the rate) does
+not evenly divide one second in microseconds, the kernel adds 64 us once
+each second, so the timescale consists of 255 advances of 3906 us plus
+one of 3970 us. Similarly, the OSF/1 kernel adds 576 us once each
+second, so its timescale consists of 1023 advances of 976 us plus one of
+1552 us.
+
+2.1. Mechanisms to Adjust Time and Frequency
+
+In most Unix kernels it is possible to slew the system clock to a new
+offset relative to the current time by using the adjtime() system call.
+To do this the clock frequency is changed by adding or subtracting a
+fixed amount (tickadj) at each timer interrupt (tick) for a calculated
+number of timer interrupts. Since this calculation involves dividing the
+requested offset by tickadj, it is possible to slew to a new offset with
+a precision only of tickadj, which is usually in the neighborhood of 5
+us, but sometimes much larger. This results in a roundoff error which
+can accumulate to an unacceptable degree, so that special provisions
+must be made in the clock adjustment procedures of the synchronization
+daemon.
+
+In order to implement a frequency discipline function, it is necessary
+to provide time offset adjustments to the kernel at regular adjustment
+intervals using the adjtime() system call. In order to reduce the system
+clock jitter to the regime consistent with the model, it is necessary
+that the adjustment interval be relatively small, in the neighborhood of
+1 s. However, the Unix adjtime() implementation requires each offset
+adjustment to complete before another one can be begun, which means that
+large adjustments must be amortized over possibly many adjustment
+intervals. The requirement to implement the adjustment interval and
+compensate for roundoff error considerably complicates the synchronizing
+daemon implementation.
+
+In the new model this scheme is replaced by another that represents the
+system clock as a multiple-word, precision-time variable in order to
+provide very precise clock adjustments. At each timer interrupt a
+precisely calibrated quantity is added to the kernel time variable and
+overflows propagated as required. The quantity is computed as in the NTP
+local clock model described in [MIL92b], which operates as an adaptive-
+parameter, first-order, type-II phase-lock loop (PLL). In principle,
+this PLL design can provide precision control of the system clock
+oscillator within 1 us and frequency to within parts in 10^11. While
+precisions of this order are surely well beyond the capabilities of the
+CPU clock oscillator used in typical workstations, they are appropriate
+using precision external oscillators, as described below.
+
+The PLL design is identical to the one originally implemented in NTP and
+described in [MIL92b]. In the original design the software daemon
+simulates the PLL using the adjtime() system call; however, the daemon
+implementation is considerably complicated by the considerations
+described above. The modified kernel routines implement the PLL in the
+kernel using precision time and frequency representations, so that these
+complications are avoided. A new system call ntp_adjtime() is called
+only as each new time update is determined, which in NTP occurs at
+intervals of from 16 s to 1024 s. In addition, doing frequency
+compensation in the kernel means that the system clock runs true even if
+the daemon were to cease operation or the network paths to the primary
+synchronization source fail.
+
+In the new model the new ntp_adjtime() operates in a way similar to the
+original adjtime() system call, but does so independently of adjtime(),
+which continues to operate in its traditional fashion. When used with
+NTP, it is the design intent that settimeofday() or adjtime() be used
+only for system clock adjustments greater than +-128 ms, although the
+dynamic range of the new model is much larger at +-512 ms. It has been
+the Internet experience that the need to change the system clock in
+increments greater than +-128 ms is extremely rare and is usually
+associated with a hardware or software malfunction or system reboot.
+
+The easiest way to set the time is with the settimeofday() system call;
+however, this can under some conditions cause the clock to jump
+backwards. If this cannot be tolerated, adjtime() can be used to slew
+the clock to the new value without running backward or affecting the
+frequency discipline process. Once the system clock has been set within
++-128 ms, the ntp_adjtime() system call is used to provide periodic
+updates including the time offset, maximum error, estimated error and
+PLL time constant. With NTP the update interval and time constant depend
+on the measured delay and dispersion; however, the scheme is quite
+forgiving and neither moderate loss of updates nor variations in the
+update interval are serious.
+
+2.2 Daemon and Application Interface
+
+Unix application programs can read the system clock using the
+gettimeofday() system call, which returns only the system time and
+timezone data. For some applications it is useful to know the maximum
+error of the reported time due to all causes, including clock reading
+errors, oscillator frequency errors and accumulated latencies on the
+path to the primary synchronization source. However, in the new model
+the PLL adjusts the system clock to compensate for its intrinsic
+frequency error, so that the time error expected in normal operation
+will usually be much less than the maximum error. The programming
+interface includes a new system call ntp_gettime(), which returns the
+system time, as well as the maximum error and estimated error. This
+interface is intended to support applications that need such things,
+including distributed file systems, multimedia teleconferencing and
+other real-time applications. The programming interface also includes a
+new system call ntp_adjtime(), which can be used to read and write
+kernel variables for time and frequency adjustment, PLL time constant,
+leap-second warning and related data.
+
+In addition, the kernel adjusts the indicated maximum error to grow by
+an amount equal to the maximum oscillator frequency tolerance times the
+elapsed time since the last update. The default engineering parameters
+have been optimized for update intervals in the order of 64 s. As shown
+in [MIL93], this is near the optimum interval for NTP used with ordinary
+room-temperature quartz oscillators. For other intervals the PLL time
+constant can be adjusted to optimize the dynamic response over intervals
+of 16-1024 s. Normally, this is automatically done by NTP. In any case,
+if updates are suspended, the PLL coasts at the frequency last
determined, which usually results in errors increasing only to a few
-tens of milliseconds over a day.
-
-The new code needs to know the initial frequency offset and time
-constant for the PLL, and the daemon needs to know the current frequency
-offset computed by the kernel for monitoring purposes. These data are
-exchanged between the kernel and protocol daemon using ntp_adjtime() as
-documented later in this memo. Provisions are made to exchange related
-timing information, such as the maximum error and estimated error,
-between the kernel and daemon and between the kernel and application
-programs.
-
-In the DEC 3000 AXP, DECstation 5000/240 and possibly other DEC
-machines there is an undocumented hardware register that counts system
-bus cycles at a rate of 25 MHz. The new kernel microtime() routine tests
-for the CPU type and, in the case of these machines, use this register
-to interpolate system time between hardware timer interrupts. This
-results in a precision of +-1 us for all time values obtained via the
-gettimeofday() and ntp_gettime() system calls. These routines call the
-microtime() routine, which returns the actual interpolated value but
-does not change the kernel time variable. Therefore, other kernel
-routines that access the kernel time variable directly and do not call
-either gettimeofday(), ntp_gettime() or microtime() will continue their
-present behavior. The microtime() feature is independent of other
-features described here and is operative even if the kernel PLL or new
-system calls have not been implemented.
-
-While any protocol daemon can in principle be modified to use the new
-system calls, the most likely will be users of the NTP Version 3 daemon
-xntpd. The xntpd code determines whether the new system calls are
+tens of milliseconds over a day using typical modern workstations.
+
+While any synchronization daemon can in principle be modified to use the
+new system calls, the most likely will be users of the NTP Version 3
+daemon xntpd. The xntpd code determines whether the new system calls are
implemented and automatically reconfigures as required. When
-implemented, the daemon reads the frequency offset from a file and
-provides it and the initial time constant via ntp_adjtime(). In
-subsequent calls to ntp_adjtime(), only the time adjustment and time
+implemented, the daemon reads the frequency offset from a system file
+and provides it and the initial time constant via ntp_adjtime(). In
+subsequent calls to ntp_adjtime(), only the time offset and time
constant are affected. The daemon reads the frequency from the kernel
-using ntp_adjtime() at intervals of about one hour and writes it to the
-system log file. This information is recovered when the daemon is
-restarted after reboot, for example, so the sometimes extensive training
-period to learn the frequency separately for each system can be avoided.
-
-3. Kernel Interfaces
-
-This section describes the kernel interfaces to the protocol daemon and
-user applications. The ideas are based on suggestions from Jeff Mogul
-and Philip Gladstone and a similar interface designed by the latter. It
-is important to point out that the functionality of the original Unix
-adjtime() system call is preserved, so that the modified kernel will
-work as the unmodified one should the kernel PLL not be in use. In this
-case the ntp_adjtime() system call can still be used to read and write
-kernel variables that might be used by a protocol daemon other than NTP,
-for example.
-
-3.1. The ntp_gettime() System Call
-
-The syntax and semantics of the ntp_gettime() call are given in the
-following fragment of the timex.h header file. This file is identical in
-the SunOS, Ultrix and OSF/1 kernel distributions. Note that the timex.h
-file calls the syscall.h system header file, which must be modified to
-define the SYS_ntp_gettime system call specific to each system type. The
-kernel distributions include directions on how to do this.
-
-/*
- * This header file defines the Network Time Protocol (NTP) interfaces
- * for user and daemon application programs. These are implemented using
- * private system calls and data structures and require specific kernel
- * support.
- *
- * NAME
- * ntp_gettime - NTP user application interface
- *
- * SYNOPSIS
- * #include <sys/timex.h>
- *
- * int system call(SYS_ntp_gettime, tptr)
- *
- * int SYS_ntp_gettime defined in syscall.h header file
- * struct ntptimeval *tptr pointer to ntptimeval structure
- *
- * NTP user interface - used to read kernel clock values
- * Note: maximum error = NTP synch distance = dispersion + delay / 2;
- * estimated error = NTP dispersion.
- */
-struct ntptimeval {
- struct timeval time; /* current time */
- long maxerror; /* maximum error (usec) */
- long esterror; /* estimated error (usec) */
-};
-
-The ntp_gettime() system call returns three values in the ntptimeval
-structure: the current time in unix timeval format plus the maximum and
-estimated errors in microseconds. While the 32-bit long data type limits
-the error quantities to something more than an hour, in practice this is
-not significant, since the protocol itself will declare an
-unsynchronized condition well below that limit. If the protocol computes
-either of these values in excess of 16 seconds, they are clamped to that
-value and the local clock declared unsynchronized.
-
-Following is a detailed description of the ntptimeval structure members.
-
-struct timeval time;
-
- This member is set to the current system time, expressed as a Unix
- timeval structure. The timeval structure consists of two 32-bit
- words, one for the number of seconds past 1 January 1970 and the
- other the number of microseconds past the most recent second's
- epoch.
-
-long maxerror;
-
- This member is set to the value of the time_maxerror kernel
- variable, which establishes the maximum error of the indicated time
- relative to the primary reference source, in microseconds. This
- variable can also be set and read by the ntp_adjtime() system call.
- For NTP, the value is determined as the synchronization distance,
- which is equal to the root dispersion plus one-half the root delay.
- It is increased by a small amount (time_tolerance) each second to
- reflect the clock frequency tolerance. This variable is computed by
- the time-synchronization daemon and the kernel and returned in a
- ntp_gettime() system call, but is otherwise not used by the kernel.
-
-long esterror;
-
- This member is set to the value of the time_esterror kernel
- variable, which establishes the expected error of the indicated
- time relative to the primary reference source, in microseconds.
- This variable can also be set and read by the ntp_adjtime() system
- call. For NTP, the value is determined as the root dispersion,
- which represents the best estimate of the actual error of the
- system clock based on its past behavior, together with observations
- of multiple clocks within the peer group. This variable is computed
- by the time-synchronization daemon and returned in a ntp_gettime()
- system call, but is otherwise not used by the kernel.
-
-3.2. The ntp_adjtime() System Call
-
-The syntax and semantics of the ntp_adjtime() call is given in the
-following fragment of the timex.h header file. Note that, as in the
-ntp_gettime() system call, the the syscall.h system header file must be
-modified to define the SYS_ntp_adjtime system call specific to each
-system type.
-
-/*
- * NAME
- * ntp_adjtime - NTP daemon application interface
- *
- * SYNOPSIS
- * #include <sys/timex.h>
- *
- * int system call(SYS_ntp_adjtime, mode, tptr)
- *
- * int SYS_ntp_adjtime defined in syscall.h header file
- * struct timex *tptr pointer to timex structure
- *
- * NTP daemon interface - used to discipline kernel clock oscillator
- */
-struct timex {
- int mode; /* mode selector */
- long offset; /* time offset (usec) */
- long frequency; /* frequency offset (scaled ppm) */
- long maxerror; /* maximum error (usec) */
- long esterror; /* estimated error (usec) */
- int status; /* clock command/status */
- long time_constant; /* pll time constant */
- long precision; /* clock precision (usec) (read only) */
- long tolerance; /* clock frequency tolerance (ppm)
- * (read only)
- */
-};
-
-The ntp_adjtime() system call is used to read and write certain time-
-related kernel variables summarized in this and subsequent sections.
-Writing these variables can only be done in superuser mode. To write a
-variable, the mode structure member is set with one or more bits, one of
-which is assigned each of the following variables in turn. The current
-values for all variables are returned in any case; therefore, a mode
-argument of zero means to return these values without changing anything.
-
-Following is a description of the timex structure members.
-
-int mode;
-
- This is a bit-coded variable selecting one or more structure
- members, with one bit assigned each member. If a bit is set, the
- value of the associated member variable is copied to the
- corresponding kernel variable; if not, the member is ignored. The
- bits are assigned as given in the following fragment of the timex.h
- header file. Note that the precision and tolerance are intrinsic
- properties of the kernel configuration and cannot be changed.
-
- /*
- * Mode codes (timex.mode)
- */
- #define ADJ_OFFSET 0x0001 /* time offset */
- #define ADJ_FREQUENCY 0x0002 /* frequency offset */
- #define ADJ_MAXERROR 0x0004 /* maximum time error */
- #define ADJ_ESTERROR 0x0008 /* estimated time error */
- #define ADJ_STATUS 0x0010 /* clock status */
- #define ADJ_TIMECONST 0x0020 /* pll time constant */
-
-long offset;
-
- If selected, this member (scaled) replaces the value of the
- time_offset kernel variable, which defines the current time offset
- of the phase-lock loop. The value must be in the range +-512 ms in
- the present implementation. If so, the clock status is
- automatically set to TIME_OK.
-
-long time_constant;
-
- If selected, this member replaces the value of the time_constant
- kernel variable, which establishes the bandwidth of "stiffness" of
- the kernel PLL. The value is used as a shift, with the effective
- PLL time constant equal to a multiple of (1 << time_constant), in
- seconds. The optimum value for the time_constant variable is
- log2(update_interval) - 4, where update_interval is the nominal
- interval between clock updates, in seconds. With an ordinary crystal
- oscillator the optimum value for time_constant is about 2, giving
- an update_interval of 4 (64 s). Values of time_constant between zero
- and 2 can be used if quick convergence is necessary; values between
- 2 and 6 can be used to reduce network load, but at a modest cost in
- accuracy. Values above 6 are appropriate only if a precision
- oscillator is available.
-
-long frequency;
-
- If selected, this member (scaled) replaces the value of the
- time_frequency kernel variable, which establishes the intrinsic
- frequency of the local clock oscillator. This variable is scaled by
- (1 << SHIFT_USEC) in parts-per-million (ppm), giving it a maximum
- value of about +-31 ms/s and a minimum value (frequency resolution)
- of about 2e-11, which is appropriate for even the best quartz
- oscillator.
-
-long maxerror;
-
- If selected, this member replaces the value of the time_maxerror
- kernel variable, which establishes the maximum error of the
- indicated time relative to the primary reference source, in
- microseconds. This variable can also be read by the ntp_gettime()
- system call. For NTP, the value is determined as the
- synchronization distance, which is equal to the root dispersion
- plus one-half the root delay. It is increased by a small amount
- (time_tolerance) each second to reflect the clock frequency
- tolerance. This variable is computed by the time-synchronization
- daemon and the kernel and returned in a ntp_gettime() system call,
- but is otherwise not used by the kernel.
-
-long esterror;
-
- If selected, this member replaces the value of the time_esterror
- kernel variable, which establishes the expected error of the
- indicated time relative to the primary reference source, in
- microseconds. This variable can also be read by the ntp_gettime()
- system call. For NTP, the value is determined as the root
- dispersion, which represents the best estimate of the actual error
- of the system clock based on its past behavior, together with
- observations of multiple clocks within the peer group. This
- variable is computed by the time-synchronization daemon and
- returned in a ntp_gettime() system call, but is otherwise not used
- by the kernel.
-
-int status;
-
- If selected, this member replaces the value of the time_status
- kernel variable, which records whether the clock is synchronized,
- waiting for a leap second, etc. In order to set this variable
- explicitly, either (a) the current clock status is TIME_OK or (b)
- the member value is TIME_BAD; that is, the ntp_adjtime() call can
- always set the clock to the unsynchronized state or, if the clock
- is running correctly, can set it to any state. In any case, the
- ntp_adjtime() call always returns the current state in this member,
- so the caller can determine whether or not the request succeeded.
-
-long precision;
-
- This member is set equal to the time_precision kernel in
- microseconds variable upon return from the system call. The
- time_precision variable cannot be written. This variable represents
- the maximum error in reading the system clock, which is ordinarily
- equal to the kernel variable tick, 10000 usec in the SunOS kernel,
- 3906 usec in Ultrix kernel and 976 usec in the OSF/1 kernel.
- However, in cases where the time can be interpolated with
- microsecond resolution, such as in the SunOS kernel and modified
- Ultrix and OSF/1 kernels, the precision is specified as 1 usec.
- This variable is computed by the kernel for use by the time-
- synchronization daemon, but is otherwise not used by the kernel.
-
-long tolerance;
-
- This member is set equal to the time_tolerance kernel variable in
- parts-per-million (ppm) upon return from the system call. The
- time_tolerance variable cannot be written. This variable represents
- the maximum frequency error or tolerance of the particular platform
- and is a property of the architecture and manufacturing process.
-
-3.3. Command/Status Codes
-
-The kernel routines use the system clock status variable time_status,
-which records whether the clock is synchronized, waiting for a leap
-second, etc. The value of this variable is returned as the result code
-by both the ntp_gettime() and ntp_adjtime() system calls. In addition,
-it can be explicitly read and written using the ntp_adjtime() system
-call, but can be written only in superuser mode. Values presently
-defined in the timex.h header file are as follows:
-
-/*
- * Clock command/status codes (timex.status)
- */
-#define TIME_OK 0 /* clock synchronized */
-#define TIME_INS 1 /* insert leap second */
-#define TIME_DEL 2 /* delete leap second */
-#define TIME_OOP 3 /* leap second in progress */
-#define TIME_BAD 4 /* clock not synchronized */
-
-A detailed description of these codes as used by the leap-second state
-machine is given later in this memo. In case of a negative result code,
-the kernel has intercepted an invalid address or (in case of the
-ntp_adjtime() system call), a superuser violation.
-
-4. Technical Summary
-
-In order to more fully understand the workings of the PLL, a stand-alone
-simulator kern.c is included in the kernel distributions. This is an
-implementation of an adaptive-parameter, first-order, type-II phase-lock
-loop. The system clock is implemented using a set of variables and
-algorithms defined in the simulator and driven by explicit offsets
-generated by the simulator. The algorithms include code fragments
-identical to those in the modified kernel routines and operate in the
-same way, but the operations can be understood separately from any
-licensed source code into which these fragments may be integrated. The
-code segments themselves are not derived from any licensed code.
-
-4.1. PLL Simulation
-
-In the simulator the hardupdate() fragment is called by ntp_adjtime() as
-each update is computed to adjust the system clock phase and frequency.
-Note that the time constant is in units of powers of two, so that
-multiplies can be done by simple shifts. The phase variable is computed
-as the offset multiplied by the time constant. Then, the time since the
-last update is computed and clamped to a maximum (for robustness) and to
-zero if initializing. The offset is multiplied (sorry about the ugly
-multiply) by the result and by the square of the time constant and then
-added to the frequency variable. Finally, the frequency variable is
-clamped not to exceed the tolerance. Note that all shifts are assumed to
-be positive and that a shift of a signed quantity to the right requires
-a little dance.
-
-With the defines given, the maximum time offset is determined by the
-size in bits of the long type (32) less the SHIFT_UPDATE scale factor or
-18 bits (signed). The scale factor is chosen so that there is no loss of
-significance in later steps, which may involve a right shift up to 14
-bits. This results in a maximum offset of about +-130 ms. Since
+using ntp_adjtime() at intervals of about one hour and writes it to a
+system file. This information is recovered when the daemon is restarted
+after reboot, for example, so the sometimes extensive training period to
+learn the frequency separately for each oscillator can be avoided.
+
+2.3. Precision Clocks for DECstation 5000/240 and 3000 AXP Alpha
+
+The stock microtime() routine in the Ultrix kernel for Digital Equipment
+MIPS-based workstations returns system time to the precision of the
+timer interrupt interval, which is in the 1-4 ms range. However, in the
+DECstation 5000/240 and possibly other machines of that family, there is
+an undocumented IOASIC hardware register that counts system bus cycles
+at a rate of 25 MHz. The new microtime() routine for the Ultrix kernel
+uses this register to interpolate system time between timer interrupts.
+This results in a precision of 1 us for all time values obtained via the
+gettimeofday() and ntp_gettime() system calls. For the Digital Equipment
+3000 AXP Alpha, the architecture provides a hardware Process Cycle
+Counter and a machine instruction (rpcc) to read it. This counter
+operates at the fundamental frequency of the CPU clock or some
+submultiple of it, 133.333 MHz for the 3000/400 for example. The new
+microtime() routine for the OSF/1 kernel uses this counter in the same
+fashion as the Ultrix routine. Support for this feature is conditionally
+compiled in the kernel only if the MICRO option is used in the kernel
+configuration file.
+
+In both the Ultrix and OSF/1 kernels the gettimeofday() and
+ntp_gettime() system call use the new microtime() routine, which returns
+the interpolated value to 1-us resolution, but does not change the
+kernel time variable. Therefore, other routines that access the kernel
+time variable directly and do not call either gettimeofday(),
+ntp_gettime() or microtime() will continue their present behavior. The
+microtime() feature is independent of other features described here and
+is operative even if the kernel PLL or new system calls have not been
+implemented.
+
+The SunOS kernel already includes a system clock with 1-us resolution;
+so, in principle, no microtime() routine is necessary. An existing
+kernel routine uniqtime() implements this function, but it is coded in
+the C language and is rather slow at 42-85 us per call on a SPARCstation
+IPC. A replacement microtime() routine coded in assembler language is
+available in the NTP Version 3 distribution and is much faster at about
+3 us per call. Note that, as explained later, this routine should be
+called at an interrupt priority level not greater than that of the timer
+interrupt routine. Otherwise, it is possible to miss a tick increment,
+with result the time returned can be late by one tick. This is always
+true in the case of gettimeofday() and ntp_gettime(), but might not be
+true in other cases, such as when using the PPS signal described later
+in this memorandum.
+
+2.4. External Time and Frequency Discipline
+
+The overall accuracy of a time synchronization subnet with respect to
+Coordinated Universal Time (UTC) depends on the accuracy and stability
+of the primary synchronization source, usually a radio or satellite
+receiver, and the CPU clock oscillator of the primary server. As
+discussed in [MIL93], the traditional interface using a ASCII serial
+timecode and RS232 port precludes the full accuracy of most radio
+clocks. In addition, the poor frequency stability of typical CPU clock
+oscillators limits the accuracy, whether or not precision time sources
+are available. There are, however, several ways in which the system
+clock accuracy and stability can be improved to the degree limited only
+by the accuracy and stability of the synchronization source and the
+jitter of the interface and operating system.
+
+Many radio clocks produce special signals that can be used by external
+equipment to precisely synchronize time and frequency. Most produce a
+pulse-per-second (PPS) signal that can be read via a modem-control lead
+of a serial port and some produce a special IRIG signal that can be read
+directly by a bus peripheral, such as the KSI/Odetics TPRO IRIG SBus
+interface, or indirectly via the audio codec of some workstations, as
+described in [MIL93]. In the NTP Version 3 daemon xntpd, the PPS signal
+can be used to augment the less precise ASCII serial timecode to improve
+accuracy to the order of a few tens of microseconds. Support is also
+included in the NTP distribution for the TPRO interface, as well as the
+audio codec; however, the latter requires a modified kernel audio driver
+contained in the compressed tar archive bsd_audio.tar.Z in the same host
+and directory as the NTP Version 3 distribution mentioned previously.
+2.4.1. PPS Signal
+
+The most convenient way to interface a PPS signal to a computer is
+usually with a serial port and RS232-compatible signal; however, the PPS
+signal produced by most radio clocks and laboratory instruments is
+usually a TTL pulse signal. Therefore, some kind of level
+converter/pulse generator is necessary to adapt the PPS signal to a
+serial port. An example design, including schematic and printed-circuit
+board artwork, is in the compressed tar archive gadget.tar.Z in the same
+host and directory as the NTP Version 3 distribution mentioned
+previously. There are several ways the PPS signal can be used in
+conjunction with the NTP Version 3 daemon xntpd, as described in [MIL93]
+and in the documentation included in the distribution.
+
+The NTP Version 3 distribution includes a special ppsclock module for
+the SunOS 4.1.x kernel that captures the PPS signal presented via a
+modem-control lead of a serial port. Normally, the ppsclock module
+produces a timestamp at each transition of the PPS signal and provides
+it to the synchronization daemon for integration with the serial ASCII
+timecode, also produced by the radio clock. With the conventional PLL
+implementation in either the daemon or the kernel as described in
+[MIL93], the accuracy of this scheme is limited by the intrinsic
+stability of the CPU clock oscillator to a millisecond or two, depending
+on environmental temperature variations.
+
+The ppsclock module has been modified to in addition call a new kernel
+routine hardpps() once each second. In addition, the Ultrix 4.3 kernel
+has been modified to provide a similar functionality. The hardpps()
+routine compares the timestamp with a sample of the CPU clock oscillator
+in order to discipline the oscillator to the time and frequency of the
+PPS signal. Using this method, the time accuracy is improved to
+typically 20 us or less and frequency stability a few parts in 10^8,
+which is about two orders of magnitude better than the undisciplined
+oscillator. The new feature is conditionally compiled in the code
+described below only if the PPS_SYNC option is used in the kernel
+configuration file.
+
+When using the PPS signal to adjust the time, there is a problem with
+some kernels which is very difficult to fix. The serial port interrupt
+routine often operates at an interrupt priority level above the timer
+interrupt routine. Thus, as explained below, it is possible that a tick
+increment can be missed and the time returned late by one tick. It may
+happen that, if the CPU clock oscillator frequency is close to the PPS
+oscillator frequency (less than a few ppm), this condition can persist
+for two or more successive PPS interrupts. A useful workaround in the
+code is to use a glitch detector and median filter to process the PPS
+sample offsets. The glitch detector suppresses offset bursts greater
+than half the tick interval and which last less than 30 successive PPS
+interrupts. The median filter ranks the offsets in a moving window of
+three samples and uses the median as the output and the difference
+between the other two as a dispersion measure.
+
+2.4.2. External Clocks
+
+It is possible to replace the system clock function with an external bus
+peripheral. The TPRO device mentioned previously can be used to provide
+IRIG-synchronized time with a precision of 1 us. A driver for this
+device tprotime.c and header file tpro.h are included in the
+kernel.tar.Z distribution mentioned previously. Using this device, the
+system clock is read directly from the interface; however, the device
+does not record the year, so special provisions have been made to obtain
+the year from the kernel time variable and initialize the driver
+accordingly. Support for this feature is conditionally compiled in the
+kernel only if the EXT_CLOCK and TPRO options are used in the kernel
+configuration file.
+
+While the system clock function is provided directly by the microtime()
+routine in the driver, the kernel time variable must be disciplined as
+well, since not all system timing functions use the microtime() routine.
+This is done by measuring the time difference between the microtime()
+clock and kernel time variable and using it to adjust the kernel PLL as
+if the adjustment were provided by an external peer and NTP.
+
+A good deal of error checking is done in the TPRO driver, since the
+system clock is vulnerable to a misbehaving radio clock, IRIG signal
+source, interface cables and TPRO device itself. Unfortunately, there is
+no practical way to utilize the extensive diversity and redundancy
+capabilities available in the NTP synchronization daemon. In order to
+avoid disruptions that might occur if the TPRO time is far different
+from the kernel time variable, the latter is used instead of the former
+if the difference between the two exceeds 1000 s; presumably in that
+case operator intervention is required.
+
+2.4.2. External Oscillators
+
+Even if a source of PPS or IRIG signals is not available, it is still
+possible to improve the stability of the system clock through the use of
+a specialized bus peripheral. In order to explore the benefits of such
+an approach, a special SBus peripheral called HIGHBALL has been
+constructed. The device includes a pair of 32-bit hardware counters in
+Unix timeval format, together with a precision, oven-controlled quartz
+oscillator with a stability of a few parts in 10^9. A driver for this
+device hightime.c and header file high.h are included in the
+kernel.tar.Z distribution mentioned previously. Support for this feature
+is conditionally compiled in the kernel only if the EXT_CLOCK and
+HIGHBALL options are used in the kernel configuration file.
+
+Unlike the external clock case, where the system clock function is
+provided directly by the microtime() routine in the driver, the HIGHBALL
+counter offsets with respect to UTC must be provided first. This is done
+using the ordinary kernel PLL, but controlling the counter offsets
+directly, rather than the kernel time variable. At first, this might
+seem to defeat the purpose of the design, since the jitter and wander of
+the synchronization source will affect the counter offsets and thus the
+accuracy of the time. However, the jitter is much reduced by the PLL and
+the wander is small, especially if using a radio clock or another
+primary server disciplined in the same way. In practice, the scheme
+works to reduce the incidental wander to a few parts in 10^8, or about
+the same as using the PPS signal.
+
+As in the previous case, the kernel time variable must be disciplined as
+well, since not all system timing functions use the microtime() routine.
+However, the kernel PLL cannot be used for this, since it is already in
+use providing offsets for the HIGHBALL counters. Therefore, a special
+correction is calculated from the difference between the microtime()
+clock and the kernel time variable and used to adjust the kernel time
+variable at the next timer interrupt. This somewhat roundabout approach
+is necessary in order that the adjustment does not cause the kernel time
+variable to jump backwards and possibly lose or duplicate a timer event.
+
+2.5 Other Features
+
+It is a design feature of the NTP architecture that the system clocks in
+a synchronization subnet are to read the same or nearly the same values
+before during and after a leap-second event, as declared by national
+standards bodies. The new model is designed to implement the leap event
+upon command by an ntp_adjtime() argument. The intricate and sometimes
+arcane details of the model and implementation are discussed in [MIL92b]
+and [MIL93]. Further details are given in the technical summary later in
+this memorandum.
+3. Technical Summary
+
+In order to more fully understand the workings of the model, a stand-
+alone simulator kern.c and header file timex.h are included in the
+kernel.tar.Z distribution mentioned previously. In addition, an example
+kernel module kern_ntptime.c which implements the ntp_gettime() and
+ntp_adjtime() system calls is included. Neither of these programs
+incorporate licensed code. Since the distribution is somewhat large, due
+to copious comments and ornamentation, it is impractical to include a
+listing of these programs in this memorandum. In any case, implementors
+may choose to snip portions of the simulator for use in new kernel
+designs; but, due to formatting conventions, this would be difficult if
+included in this memorandum.
+
+The kern.c program is an implementation of an adaptive-parameter, first-
+order, type-II phase-lock loop. The system clock is implemented using a
+set of variables and algorithms defined in the simulator and driven by
+explicit offsets generated by the main() routine in the program. The
+algorithms include code fragments almost identical to those in the
+machine-specific kernel implementations and operate in the same way, but
+the operations can be understood separately from any licensed source
+code into which these fragments may be integrated. The code fragments
+themselves are not derived from any licensed code. The following
+discussion assumes that the simulator code is available for inspection.
+
+3.1. PLL Simulation
+
+The simulator operates in conformance with the analytical model
+described in [MIL92b]. The main() program operates as a driver for the
+fragments hardupdate(), hardclock(), second_overflow(), hardpps() and
+microtime(), although not all functions implemented in these fragments
+are simulated. The program simulates the PLL at each timer interrupt and
+prints a summary of critical program variables at each time update.
+
+There are three defined options in the kernel configuration file
+specific to each implementation. The PPS_SYNC option provides support
+for a pulse-per-second (PPS) signal, which is used to discipline the
+frequency of the CPU clock oscillator. The EXT_CLOCK option provides
+support for an external kernel-readable clock, such as the KSI/Odetics
+TPRO IRIG interface or HIGHBALL precision oscillator, both for the SBus.
+The TPRO option provides support for the former, while the HIGHBALL
+option provides support for the latter. External clocks are implemented
+as the microtime() clock driver, with the specific source code selected
+by the kernel configuration file.
+
+The PPS signal is carefully monitored for error conditions which can
+affect accuracy, stability and reliability. The time_status kernel
+variable contains bits that both control the use of the PPS signal and
+reveal its operational status. The function of each bit is described in
+a later section of this memo.
+
+3.1.1. The hardupdate() Fragment
+
+The hardupdate() fragment is called by ntp_adjtime() as each update is
+computed to adjust the system clock phase and frequency. Note that the
+time constant is in units of powers of two, so that multiplies can be
+done by simple shifts. The phase variable is computed as the offset
+divided by the time constant, but clamped to a maximum (for robustness).
+Then, the time since the last update is computed and clamped to a
+maximum and to zero if initializing. The offset is multiplied (sorry
+about the ugly multiply) by the result and divided by the square of the
+time constant and then added to the frequency variable. Note that all
+shifts are assumed to be positive and that a shift of a signed quantity
+to the right requires a little dance.
+
+The STA_PLL and STA_PPSTIME status bits, which are set by the
+ntp_adjtime() system call, serve to enable or inhibit the kernel PLL and
+PPS time-discipline functions. The STA_PPSSIGNAL status bit is set by
+the hardpps() code fragment when the PPS signal is present and operating
+within nominal bounds. Time discipline from the PPS signal operates only
+if both the STA_PPSTIME and STA_PPSSIGNAL bits are set; otherwise, the
+discipline operates from the offset given in the ntp_adjtime() system
+call. In the intended mode of operation, the synchronization daemon sets
+STA_PLL to enable the PLL when first initialized, then sets STA_PPSTIME
+when reliable synchronization to within +-128 ms has been achieved with
+either a radio clock or external peer. The daemon can detect and
+indicate this condition for monitoring purposes by noting that both
+STA_PPSTIME and STA_PPSSIGNAL are set.
+
+With the defines given in the program and header files, the maximum time
+offset is determined by the size in bits of the long type (32 or 64)
+less the SHIFT_UPDATE scale factor (12) or at least 20 bits (signed).
+The scale factor is chosen so that there is no loss of significance in
+later steps, which may involve a right shift up to SHIFT_UPDATE bits.
+This results in a time adjustment range over +-512 ms. Since
time_constant must be greater than or equal to zero, the maximum
-frequency offset is determined by the SHIFT_KF (20) scale factor, or
-about +-130 ppm. In the addition step, the value of offset * mtemp is
-represented in 18 + 10 = 28 bits, which will not overflow a long add.
-There could be a loss of precision due to the right shift of up to eight
-bits, since time_constant is bounded at 6. This results in a net worst-
-case frequency error of about 2^-16 us or well down into the oscillator
-phase noise. While the time_offset value is assumed checked before
-entry, the time_phase variable is an accumulator, so is clamped to the
-tolerance on every call. This helps to damp transients before the
-oscillator frequency has been determined, as well as to satisfy the
-correctness assertions if the time-synchronization protocol comes
-unstuck.
+frequency offset is determined by the SHIFT_USEC scale factor (16) or at
+least 16 bits (signed). This results in a frequency adjustment range
+over +-31,500 ppm.
+
+In the addition step, the value of offset * mtemp is not greater than
+MAXPHASE * MAXSEC = 31 bits (signed), which will not overflow a long add
+on a 32-bit machine. There could be a loss of precision due to the right
+shift of up to 12 bits, since time_constant is bounded at 6. This
+results in a net worst-case frequency resolution of about .063 ppm,
+which is not significant for most quartz oscillators. The worst case
+could be realized only if the NTP peer misbehaves according to the
+protocol specification.
+
+The time_offset value is clamped upon entry. The time_phase variable is
+an accumulator, so is clamped to the tolerance on every call. This helps
+to damp transients before the oscillator frequency has been stabilized,
+as well as to satisfy the correctness assertions if the time
+synchronization protocol or implementation misbehaves.
+
+3.1.2. The hardclock() Fragment
The hardclock() fragment is inserted in the hardware timer interrupt
-routine at the point the system clock is to be incremented. Previous to
-this fragment the time_update variable has been initialized to the value
-computed by the adjtime() system call in the stock Unix kernel, normally
-the value of tick plus/minus the tickadj value, which is usually in the
-order of 5 microseconds. When the kernel PLL is in use, adjtime() is
-not, so the time_update value at this point is the value of tick. This
-value, the phase adjustment (time_adj) and the clock phase (time_phase)
-are summed and the total tested for overflow of the microsecond. If an
-overflow occurs, the microsecond (tick) is incremented or decremented,
-depending on the sign of the overflow.
+routine at the point the system clock is to be incremented by the value
+of tick. Previous to this fragment the time_update variable has been
+initialized to the tick increment plus the value computed by the
+adjtime() system call in the stock Unix kernel, normally plus/minus the
+tickadj value, which is usually in the order of 5 us. The time_phase
+variable, which represents the instantaneous phase of the system clock,
+is advanced by time_adj, which is calculated in the second_overflow()
+fragment described below. If the value of time_phase exceeds 1 us in
+scaled units, time_update is increased by the (signed) excess and
+time_phase retains the residue.
+
+In those cases where a PPS signal is connected by a serial port
+operating at an interrupt priority level greater than the timer
+interrupt, special consideration should be given the location of the
+hardclock() fragment in the timer interrupt routine. The system clock
+should be advanced as early in the routine as possible, preferably
+before the hardware timer interrupt flag is cleared. This reduces or
+eliminates the possibility that the microtime() routine may latch the
+time after the flag is cleared, but before the system clock is advanced,
+which results in a returned time late by one tick.
+
+Except in the case of an external oscillator such as the HIGHBALL
+interface, the hardclock() fragment advances the system clock by the
+value of tick plus time_update. However, in the case of an external
+oscillator, the system clock is obtained directly from the interface and
+time_update used to discipline that interface instead. However, the
+system clock must still be disciplined as explained previously, so the
+value of clock_cpu computed by the second_overflow() fragment is used
+instead.
+
+3.1.3. The second_overflow() Fragment
The second_overflow() fragment is inserted at the point where the
microseconds field of the system time variable is being checked for
-overflow. On rollover of the second the maximum error is increased by
-the tolerance and the time offset is divided by the phase weight
-(SHIFT_KG) and time constant. The time offset is then reduced by the
-result and the result is scaled and becomes the value of the phase
-adjustment. The phase adjustment is then corrected for the calculated
-frequency offset and a fixed offset determined from the fixtick variable
-in some kernel implementations. On rollover of the day, the leap-warning
-indicator is checked and the apparent time adjusted +-1 s accordingly.
-The microtime() routine insures that the reported time is always
-monotonically increasing.
+overflow. Upon overflow the maximum error time_maxerror is increased by
+time_tolerance to reflect the maximum time offset due to oscillator
+frequency error. Then, the increment time_adj to advance the kernel time
+variable is calculated from the (scaled) time_offset and time_freq
+variables updated at the last call to the hardclock() fragment.
+
+The phase adjustment is calculated as a (signed) fraction of the
+time_offset remaining, where the fraction is added to time_adj, then
+subtracted from time_offset. This technique provides a rapid convergence
+when offsets are high, together with good resolution when offsets are
+low. The frequency adjustment is the sum of the (scaled) time_freq
+variable, an adjustment necessary when the tick interval does not evenly
+divide one second fixtick and PPS frequency adjustment pps_freq (if
+configured).
+
+The scheme of approximating exact multiply/divide operations with shifts
+produces good results, except when an exact calculation is required,
+such as when the PPS signal is being used to discipline the CPU clock
+oscillator frequency as described below. As long as the actual
+oscillator frequency is a power of two in Hz, no correction is required.
+However, in the SunOS kernel the clock frequency is 100 Hz, which
+results in an error factor of 0.78. In this case the code increases
+time_adj by a factor of 1.25, which results in an overall error less
+than three percent.
+
+On rollover of the day, the leap-second state machine described below
+determines whether a second is to be inserted or deleted in the
+timescale. The microtime() routine insures that the reported time is
+always monotonically increasing.
+
+3.1.4. The hardpps() Fragment
+
+The hardpps() fragment is operative only if the PPS_SYNC option is
+specified in the kernel configuration file. It is called from the serial
+port driver or equivalent interface at the on-time transition of the PPS
+signal. The code operates as a first-order, type-I, frequency-lock loop
+(FLL) controlled by the difference between the frequency represented by
+the pps_freq variable and the frequency of the hardware clock
+oscillator. It also provides offsets to the hardupdate() fragment in
+order to discipline the system clock time.
+
+In order to avoid calling the microtime() routine more than once for
+each PPS transition, the interface requires the calling program to
+capture the system time and hardware counter contents at the on-time
+transition of the PPS signal and provide a pointer to the timestamp
+(Unix timeval) and counter contents as arguments to the hardpps() call.
+The hardware counter contents are determined by saving the microseconds
+field of the system time, calling the microtime() routine, and
+subtracting the saved value. If a microseconds overflow has occurred
+during the process, the resulting microseconds value will be negative,
+in which case the caller adds 1000000 to normalize the microseconds
+field.
+
+In order to avoid large jitter when the PPS interrupt occurs during the
+timer interrupt routine before the system clock is advanced, a glitch
+detector is used. The detector latches when an offset exceeds a
+threshold tick/2 and stays latched until either a subsequent offset is
+less than the threshold or a specified interval MAXGLITCH (30 s) has
+elapsed. As long as the detector remains latched, it outputs the offset
+immediately preceding the latch, rather than the one received.
+
+A three-stage median filter is used to suppress jitter less than the
+glitch threshold. The median sample drives the PLL, while the difference
+between the other two samples represents the time dispersion. Time
+dispersion samples are averaged and used as a jitter estimate. If this
+estimate exceeds a threshold MAXTIME/2 (100 us), an error bit
+STA_PPSJITTER is raised in the status word.
+
+The frequency of the hardware oscillator is determined from the
+difference in hardware counter readings at the beginning and end of the
+calibration interval divided by the duration of the interval. However,
+the oscillator frequency tolerance, as much as 100 ppm, may cause the
+difference to exceed the tick value, creating an ambiguity. In order to
+avoid this ambiguity, the hardware counter value at the beginning of the
+interval is increased by the current pps_freq value once each second,
+but computed modulo the tick value. At the end of the interval, the
+difference between this value and the value computed from the hardware
+counter is the control signal for the FLL.
+
+Control signal samples which exceed the frequency tolerance MAXFREQ (100
+ppm) are discarded, as well as samples resulting from excessive interval
+duration jitter. In these cases an error bit STA_PPSERROR is raised in
+the status word. Surviving samples are then processed by a three-stage
+median filter. The median sample drives the FLL, while the difference
+between the other two samples represents the frequency dispersion.
+Frequency dispersion samples are averaged and used as a stabiity
+estimate. If this estimate is below a threshold MAXFREQ/4 (25 ppm), the
+median sample is used to correct the oscillator frequency pps_freq with
+a weight expressed as a shift PPS_AVG (2).
+
+Initially, an approximate value for the oscillator frequency is not
+known, so the duration of the calibration interval must be kept small to
+avoid overflowing the tick. The time difference at the end of the
+calibration interval is measured. If greater than tick/4, the interval
+is reduced by half. If less than this fraction for four successive
+calibration intervals, the interval is doubled. This design
+automatically adapts to nominal jitter in the PPS signal, as well as the
+value of tick. The duration of the calibration interval is set by the
+pps_shift variable as a shift in powers of two. The minimum value
+PPS_SHIFT (2) is chosen so that with the highest CPU oscillator
+frequency 1024 Hz and frequency tolerance 100 ppm the tick will not
+overflow. The maximum value PPS_SHIFTMAX (8) is chosen such that the
+maximum averaging time is about 1000 s as determined by measurements of
+Allan variance [MIL93].
+
+Should the PPS signal fail, the current frequency estimate pps_freq
+continues to be used, so the nominal frequency remains correct subject
+only to the instability of the undisciplined oscillator. The procedure
+to save and restore the frequency estimate works as follows. When
+setting the frequency from a file, the time_freq value is set as the
+file value minus the pps_freq value; when retrieving the frequency, the
+two values are added before saving in the file. This scheme provides a
+seamless interface should the PPS signal fail or the kernel
+configuration change. Note that the frequency discipline is active
+whether or not the synchronization daemon is active. Since all Unix
+systems take some time after reboot to build a running system, usually
+by that time the discipline process has already settled down and the
+initial transients due to frequency discipline have damped out.
+3.1.4. External Clock Interface
+
+The external clock driver interface is implemented with two routines,
+microtime(), which returns the current clock time, and clock_set(),
+which furnishes the apparent system time derived from the kernel time
+variable. The latter routine is called only when the clock is set using
+the settimeofday() system call, but can be called from within the
+driver, such as when the year rolls over, for example.
+
+In the stock SunOS kernel and modified Ultrix and OSF/1 kernels, the
+microtime() routine returns the kernel time variable plus an
+interpolation between timer interrupts based on the contents of a
+hardware counter. In the case of an external clock, such as described
+above, the system clock is read directly from the hardware clock
+registers. Examples of external clock drivers are in the tprotime.c and
+hightime.c routines included in the kernel.tar.Z distribution.
+
+The external clock routines return a status code which indicates whether
+the clock is operating correctly and the nature of the problem, if not.
+The return code is interpreted by the ntp_gettime() system call, which
+transitions the status state machine to the TIME_ERR state if an error
+code is returned. This is the only error checking implemented for the
+external clock in the present version of the code.
The simulator has been used to check the PLL operation over the design
-envelope of +-128 ms in time error and +-100 ppm in frequency error.
+envelope of +-512 ms in time error and +-100 ppm in frequency error.
This confirms that no overflows occur and that the loop initially
converges in about 15 minutes for timer interrupt rates from 50 Hz to
-1024 Hz. The loop has a normal overshoot of about seven percent and a
-final convergence time of several hours, depending on the initial time
-and frequency error.
+1024 Hz. The loop has a normal overshoot of a few percent and a final
+convergence time of several hours, depending on the initial time and
+frequency error.
-4.2. Leap Seconds
+3.2. Leap Seconds
It does not seem generally useful in the user application interface to
provide additional details private to the kernel and synchronization
@@ -571,205 +760,615 @@ independently evaluate the quality of time and project into the future
how long this time might be "valid." However, to do that properly would
duplicate the functionality of the synchronization protocol and require
knowledge of many mundane details of the platform architecture, such as
-the subnet configuration, reachability status and related variables.
-However, for the curious, the ntp_adjtime() system call can be used to
-reveal some of these mysteries.
+the subnet configuration, reachability status and related variables. For
+the curious, the ntp_adjtime() system call can be used to reveal some of
+these mysteries.
However, the user application may need to know whether a leap second is
scheduled, since this might affect interval calculations spanning the
event. A leap-warning condition is determined by the synchronization
protocol (if remotely synchronized), by the timecode receiver (if
available), or by the operator (if awake). This condition is set by the
-protocol daemon on the day the leap second is to occur (30 June or 31
-December, as announced) by specifying in a ntp_adjtime() system call a
-clock status of either TIME_DEL, if a second is to be deleted, or
-TIME_INS, if a second is to be inserted. Note that, on all occasions
+synchronization daemon on the day the leap second is to occur (30 June
+or 31 December, as announced) by specifying in a ntp_adjtime() system
+call a status bit of either STA_DEL, if a second is to be deleted, or
+STA_INS, if a second is to be inserted. Note that, on all occasions
since the inception of the leap-second scheme, there has never been a
-deletion occasion. If the value is TIME_DEL, the kernel adds one second
-to the system time immediately following second 23:59:58 and resets the
-clock status to TIME_OK. If the value is TIME_INS, the kernel subtracts
-one second from the system time immediately following second 23:59:59
-and resets the clock status to TIME_OOP, in effect causing system time
-to repeat second 59. Immediately following the repeated second, the
-kernel resets the clock status to TIME_OK.
+deletion, nor is there likely to be one in future. If the bit is
+STA_DEL, the kernel adds one second to the system time immediately
+following second 23:59:58 and resets the clock state to TIME_WAIT. If
+the bit is STA_INS, the kernel subtracts one second from the system time
+immediately following second 23:59:59 and resets the clock stateto
+TIME_OOP, in effect causing system time to repeat second 59. Immediately
+following the repeated second, the kernel resets the clock status to
+TIME_WAIT.
+
+Following the leap operations, the clock remains in the TIME_WAIT state
+until both the STA_DEL and STA_INS status bits are reset. This provides
+both an unambiguous indication that a leap recently occured, as well as
+time for the daemon or operator to clear the warning condition.
Depending upon the system call implementation, the reported time during
a leap second may repeat (with the TIME_OOP return code set to advertise
that fact) or be monotonically adjusted until system time "catches up"
to reported time. With the latter scheme the reported time will be
correct before and shortly after the leap second (depending on the
-number of microtime() calls during the leap second itself), but freeze
-or slowly advance during the leap second itself. However, Most programs
+number of microtime() calls during the leap second), but freeze or
+slowly advance during the leap second itself. However, Most programs
will probably use the ctime() library routine to convert from timeval
(seconds, microseconds) format to tm format (seconds, minutes,...). If
this routine is modified to use the ntp_gettime() system call and
inspect the return code, it could simply report the leap second as
second 60.
-To determine local midnight without fuss, the kernel simply finds the
-residue of the time.tv_sec value mod 86,400, but this requires a messy
-divide. Probably a better way to do this is to initialize an auxiliary
-counter in the settimeofday() routine using an ugly divide and increment
-the counter at the same time the time.tv_sec is incremented in the timer
-interrupt routine. For future embellishment.
+3.3. Clock Status State Machine
+
+The various options possible with the system clock model described in
+this memorandum require a careful examination of the state transitions,
+status indications and recovery procedures should a crucial signal or
+interface fail. In this section is presented a prototype state machine
+designed to support leap second insertion and deletion, as well as
+reveal various kinds of errors in the synchronization process. The
+states of this machine are decoded as follows:
+
+ TIME_OK If a PPS signal or external clock is present, it is
+ working properly and the system clock is derived
+ from it. If not, the synchronization daemon is
+ working properly and the system clock is
+ synchronized to a radio clock or one or more peers.
+
+ TIME_INS An insertion of one second in the system clock has
+ been declared following the last second of the
+ current day, but has not yet been executed.
+
+ TIME_DEL A deletion of the last second of the current day has
+ been declared, but not yet executed.
+
+ TIME_OOP An insertion of one second in the system clock has
+ been declared following the last second of the
+ current day. The second is in progress, but not yet
+ completed. Library conversion routines should
+ interpret this second as 23:59:60.
+
+ TIME_WAIT The scheduled leap event has occurred, but the
+ STA_DEL and STA_INS status bits have not yet been
+ cleared.
+
+ TIME_ERROR Either (a) the synchronization daemon has declared
+ the protocol is not working properly, (b) all
+ sources of outside synchronization have been lost or
+ (c) a PPS signal or external clock is present, but
+ not working properly.
+
+In all states the system clock is derived from either a PPS signal or
+external clock, if present, or the kernel time variable, if not. If a
+PPS error condition is recognized, the PPS signal is disabled and
+ntp_adjtime() updates are used instead. If an external clock error
+condition is recognized, the external clock is disabled and the kernel
+time variable is used instead.
+
+The state machine makes a transition once each second at an instant
+where the microseconds field of the kernel time variable overflows and
+one second is added to the seconds field. However, this condition is
+checked when the timer overflows, which may not coincide with the actual
+seconds increment. This may lead to some interesting anomalies, such as
+a status indication of a leap second in progress (TIME_OOP) when the
+leap second has already expired. This ambiguity is unavoidable, unless
+the timer interrupt is made synchronous with the system clock.
+
+The following state transitions are executed automatically by the kernel
+at rollover of the microseconds field:
+
+ any state -> TIME_ERROR This transition occurs when an error
+ condition is recognized and continues as long
+ as the condition persists. The error indication
+ overrides the normal state indication, but does
+ not affect the actual clock state. Therefore,
+ when the condition is cleared, the normal state
+ indication resumes.
+
+ TIME_OK->TIME_DEL This transition occurs if the STA_DEL bit is
+ set in the status word.
+
+ TIME_OK->TIME_INS This transition occurs if the STA_INS bit is
+ set in the status word.
+
+ TIME_INS->TIME_OOP This transition occurs immediately following
+ second 86,400 of the current day when an
+ insert-second event has been declared.
+
+ TIME_OOP->TIME_WAIT This transition occurs immediately following
+ second 86,401 of the current day; that is, one
+ second after entry to the TIME_OOP state.
+
+ TIME_DEL->TIME_WAIT This transition occurs immediately following
+ second 86,399 of the current day when a delete-
+ second event has been declared.
+
+ TIME_WAIT->TIME_OK This transition occurs when the STA_DEL and
+ STA_INS bits are cleared by an ntp_adjtime()
+ call.
+
+The following table summarizes the actions just before, during and just
+after a leap-second event. Each line in the table shows the UTC and NTP
+times at the beginning of the second. The left column shows the behavior
+when no leap event is to occur. In the middle column the state machine
+is in TIME_INS at the end of UTC second 23:59:59 and the NTP time has
+just reached 400. The NTP time is set back one second to 399 and the
+machine enters TIME_OOP. At the end of the repeated second the machine
+enters TIME_OK and the UTC and NTP times are again in correspondence. In
+the right column the state machine is in TIME_DEL at the end of UTC
+second 23:59:58 and the NTP time has just reached 399. The NTP time is
+incremented, the machine enters TIME_OK and both UTC and NTP times are
+again in correspondence.
+
+ No Leap Leap Insert Leap Delete
+ UTC NTP UTC NTP UTC NTP
+ ---------------------------------------------
+ 23:59:58|398 23:59:58|398 23:59:58|398
+ | | |
+ 23:59:59|399 23:59:59|399 00:00:00|400
+ | | |
+ 00:00:00|400 23:59:60|399 00:00:01|401
+ | | |
+ 00:00:01|401 00:00:00|400 00:00:02|402
+ | | |
+ 00:00:02|402 00:00:01|401 00:00:03|403
+ | | |
+To determine local midnight without fuss, the kernel code simply finds
+the residue of the time.tv_sec (or time.tv_sec + 1) value mod 86,400,
+but this requires a messy divide. Probably a better way to do this is to
+initialize an auxiliary counter in the settimeofday() routine using an
+ugly divide and increment the counter at the same time the time.tv_sec
+is incremented in the timer interrupt routine. For future embellishment.
+
+4. Programming Model and Interfaces
+
+This section describes the programming model for the synchronization
+daemon and user application programs. The ideas are based on suggestions
+from Jeff Mogul and Philip Gladstone and a similar interface designed by
+the latter. It is important to point out that the functionality of the
+original Unix adjtime() system call is preserved, so that the modified
+kernel will work as the unmodified one, should the new features not be
+in use. In this case the ntp_adjtime() system call can still be used to
+read and write kernel variables that might be used by a synchronization
+daemon other than NTP, for example.
+
+The kernel routines use the clock state variable time_state, which
+records whether the clock is synchronized, waiting for a leap second,
+etc. The value of this variable is returned as the result code by both
+the ntp_gettime() and ntp_adjtime() system calls. It is set implicitly
+by the STA_DEL and STA_INS status bits, as described previously. Values
+presently defined in the timex.h header file are as follows:
+
+ TIME_OK 0 no leap second warning
+ TIME_INS 1 insert leap second warning
+ TIME_DEL 2 delete leap second warning
+ TIME_OOP 3 leap second in progress
+ TIME_WAIT 4 leap second has occured
+ TIME_ERROR 5 clock not synchronized
+
+In case of a negative result code, the kernel has intercepted an invalid
+address or (in case of the ntp_adjtime() system call), a superuser
+violation.
+
+4.1. The ntp_gettime() System Call
+
+The syntax and semantics of the ntp_gettime() call are given in the
+following fragment of the timex.h header file. This file is identical,
+except for the SHIFT_HZ define, in the SunOS, Ultrix and OSF/1 kernel
+distributions. (The SHIFT_HZ define represents the logarithm to the base
+2 of the clock oscillator frequency specific to each system type.) Note
+that the timex.h file calls the syscall.h system header file, which must
+be modified to define the SYS_ntp_gettime system call specific to each
+system type. The kernel distributions include directions on how to do
+this.
+
+ /*
+ * This header file defines the Network Time Protocol (NTP)
+ * interfaces for user and daemon application programs. These are
+ * implemented using private system calls and data structures and
+ * require specific kernel support.
+ *
+ * NAME
+ * ntp_gettime - NTP user application interface
+ *
+ * SYNOPSIS
+ * #include <sys/timex.h>
+ *
+ * int system call(SYS_ntp_gettime, tptr)
+ *
+ * int SYS_ntp_gettime defined in syscall.h header file
+ * struct ntptimeval *tptr pointer to ntptimeval structure
+ *
+ * NTP user interface - used to read kernel clock values
+ * Note: maximum error = NTP synch distance = dispersion + delay /
+ * 2
+ * estimated error = NTP dispersion.
+ */
+ struct ntptimeval {
+ struct timeval time; /* current time (ro) */
+ long maxerror; /* maximum error (us) (ro) */
+ long esterror; /* estimated error (us) (ro) */
+ };
+
+The ntp_gettime() system call returns three read-only (ro) values in the
+ntptimeval structure: the current time in unix timeval format plus the
+maximum and estimated errors in microseconds. While the 32-bit long data
+type limits the error quantities to something more than an hour, in
+practice this is not significant, since the protocol itself will declare
+an unsynchronized condition well below that limit. In the NTP Version 3
+specification, if the protocol computes either of these values in excess
+of 16 seconds, they are clamped to that value and the system clock
+declared unsynchronized.
+
+Following is a detailed description of the ntptimeval structure members.
+
+struct timeval time (ro)
-4.2. Kernel Variables
+ This member is the current system time expressed as a Unix timeval
+ structure. The timeval structure consists of two 32-bit words; the
+ first is the number of seconds past 1 January 1970 assuming no
+ intervening leap-second insertions or deletions, while the second
+ is the number of microseconds within the second.
-The following kernel variables are defined by the new code:
+long maxerror (ro)
-long time_offset = 0; /* time adjustment (us) */
+ This member is the value of the time_maxerror kernel variable,
+ which represents the maximum error of the indicated time relative
+ to the primary synchronization source, in microseconds. For NTP,
+ the value is initialized by a ntp_adjtime() call to the
+ synchronization distance, which is equal to the root dispersion
+ plus one-half the root delay. It is increased by a small amount
+ (time_tolerance) each second to reflect the maximum clock frequency
+ error. This variable is provided bu a ntp-adjtime() system call and
+ modified by the kernel, but is otherwise not used by the kernel.
- This variable is used by the PLL to adjust the system time in small
- increments. It is scaled by (1 << SHIFT_UPDATE) in binary
- microseconds. The maximum value that can be represented is about +-
- 512 ms and the minimum value or precision is one microsecond.
+long esterror (ro)
-long time_constant = 0; /* pll time constant */
+ This member is the value of the time_esterror kernel variable,
+ which represents the expected error of the indicated time relative
+ to the primary synchronization source, in microseconds. For NTP,
+ the value is determined as the root dispersion, which represents
+ the best estimate of the actual error of the system clock based on
+ its past behavior, together with observations of multiple clocks
+ within the peer group. This variable is provided bu a ntp-adjtime()
+ system call, but is otherwise not used by the kernel.
+
+4.2. The ntp_adjtime() System Call
+
+The syntax and semantics of the ntp_adjtime() call are given in the
+following fragment of the timex.h header file. Note that, as in the
+ntp_gettime() system call, the syscall.h system header file must be
+modified to define the SYS_ntp_adjtime system call specific to each
+system type. In the fragment, rw = read/write, ro = read-only, wo =
+write-only.
+
+ /*
+ * NAME
+ * ntp_adjtime - NTP daemon application interface
+ *
+ * SYNOPSIS
+ * #include <sys/timex.h>
+ *
+ * int system call(SYS_ntp_adjtime, mode, tptr)
+ *
+ * int SYS_ntp_adjtime defined in syscall.h header file
+ * struct timex *tptr pointer to timex structure
+ *
+ * NTP daemon interface - used to discipline kernel clock
+ * oscillator
+ */
+ struct timex {
+ unsigned int mode; /* mode selector (wo) */
+ long offset; /* time offset (us) (rw) */
+ long frequency; /* frequency offset (scaled ppm) (rw)
+ */
+ long maxerror; /* maximum error (us) (rw) */
+ long esterror; /* estimated error (us) (rw) */
+ int status; /* clock status bits (rw) */
+ long constant; /* pll time constant (rw) */
+ long precision; /* clock precision (us) (ro) */
+ long tolerance; /* clock frequency tolerance (scaled
+ * ppm) (ro) */
+ /*
+ * The following read-only structure members are implemented
+ * only if the PPS signal discipline is configured in the
+ * kernel.
+ */
+ long ppsfreq; /* pps frequency (scaled ppm) (ro) */
+ long jitter; /* pps jitter (us) (ro) */
+ int shift; /* interval duration (s) (shift) (ro)
+ */
+ long stabil; /* pps stability (scaled ppm) (ro) */
+ long jitcnt; /* jitter limit exceeded (ro) */
+ long calcnt; /* calibration intervals (ro) */
+ long errcnt; /* calibration errors (ro) */
+ long stbcnt; /* stability limit exceeded (ro) */
+ };
- This variable determines the bandwidth or "stiffness" of the PLL.
- It is used as a shift, with the effective value in positive powers
- of two. The default value (0) corresponds to a PLL time constant of
- about 4 minutes.
+The ntp_adjtime() system call is used to read and write certain time-
+related kernel variables summarized below. Writing these variables can
+only be done in superuser mode. To write a variable, the mode structure
+member is set with one or more bits, one of which is assigned each of
+the following variables in turn. The current values for all variables
+are returned in any case; therefore, a mode argument of zero means to
+return these values without changing anything.
-long time_tolerance = MAXFREQ; /* frequency tolerance (ppm) */
+Following is a description of the timex structure members.
- This variable represents the maximum frequency error or tolerance
- of the particular platform and is a property of the architecture.
- It is expressed as a positive number greater than zero in parts-
- per-million (ppm). The default MAXFREQ (100) is appropriate for
- conventional workstations.
+mode (wo)
-long time_precision = 1000000 / HZ; /* clock precision (us) */
+ This is a bit-coded variable selecting one or more structure
+ members, with one bit assigned each member. If a bit is set, the
+ value of the associated member variable is copied to the
+ corresponding kernel variable; if not, the member is ignored. The
+ bits are assigned as given in the following, with the variable name
+ indicated in parens. Note that the precision, tolerance and PPS
+ variables are determined by the kernel and cannot be changed by
+ ntp_adjtime().
+
+ MOD_OFFSET 0x0001 time offset (offset)
+ MOD_FREQUENCY 0x0002 frequency offset (frequency)
+ MOD_MAXERROR 0x0004 maximum time error (maxerror)
+ MOD_ESTERROR 0x0008 estimated time error (esterror)
+ MOD_STATUS 0x0010 clock status (status)
+ MOD_TIMECONST 0x0020 pll time constant (constant)
+ MOD_CLKB 0x4000 set clock B
+ MOD_CLKA 0x8000 set clock A
+
+ Note that the MOD_CLK0 and MOD_CLK1 bits are intended for those
+ systems where more than one hardware clock is available for backup,
+ such as in Tandem Non-Stop computers. Presumably, in such cases
+ each clock would have its own oscillator and require a separate PLL
+ for each. Refinements to this model are for further study. The
+ interpretation of these bits is as follows:
+
+offset (rw)
+
+ If selected, this member specifies the time adjustment, in
+ microseconds. The absolute value must be less than MAXPHASE
+ (128000) microseconds defined in the timex.h header file. On
+ return, this member contains the residual offset remaining between
+ a previously specified offset and the current system time, in
+ microseconds.
+
+frequency (rw)
+
+ If selected, this member replaces the value of the time_frequency
+ kernel variable. The value is in ppm, with the integer part in the
+ high order 16 bits and fraction in the low order 16 bits. The
+ absolute value must be in the range less than MAXFREQ (100) ppm
+ defined in the timex.h header file.
+
+ The time_freq variable represents the frequency offset of the CPU
+ clock oscillator. It is recalculated as each update to the system
+ clock is determined by the offset member of the timex structure. It
+ is usually set from a value stored in a file when the
+ synchronization daemon is first started. The current value is
+ usually retrieved via this member and written to the file about
+ once per hour.
+
+maxerror (rw)
- This variable represents the maximum error in reading the system
- clock. It is expressed as a positive number greater than zero in
- microseconds and is usually based on the number of microseconds
- between timer interrupts, 3906 usec for the Ultrix kernel, 976 usec
- for the OSF/1 kernel. However, in cases where the time can be
- interpolated between timer interrupts with microsecond resolution,
- such as in the unmodified SunOS kernel and modified Ultrix and
- OSF/1 kernels, the precision is specified as 1 usec. This variable
- is computed by the kernel for use by the time-synchronization
- daemon, but is otherwise not used by the kernel.
+ If selected, this member replaces the value of the time_maxerror
+ kernel variable, in microseconds. This is the same variable as in
+ the ntp_getime() system call.
-long time_maxerror; /* maximum error */
+esterror (rw)
- This variable establishes the maximum error of the indicated time
- relative to the primary reference source, in microseconds. For NTP,
- the value is determined as the synchronization distance, which is
- equal to the root dispersion plus one-half the root delay. It is
- increased by a small amount (time_tolerance) each second to reflect
- the clock frequency tolerance. This variable is computed by the
- time-synchronization daemon and the kernel, but is otherwise not
- used by the kernel.
+ If selected, this member replaces the value of the time_esterror
+ kernel variable, in microseconds. This is the same variable as in
+ the ntp_getime() system call.
-long time_esterror; /* estimated error */
+int status (rw)
- This variable establishes the expected error of the indicated time
- relative to the primary reference source, in microseconds. For NTP,
- the value is determined as the root dispersion, which represents
- the best estimate of the actual error of the system clock based on
- its past behavior, together with observations of multiple clocks
- within the peer group. This variable is computed by the time-
- synchronization daemon and returned in system calls, but is
- otherwise not used by the kernel.
-
-long time_phase = 0; /* phase offset (scaled us) */
-long time_freq = 0; /* frequency offset (scaled ppm) */
-time_adj = 0; /* tick adjust (scaled 1 / HZ) */
-
- These variables control the phase increment and the frequency
- increment of the system clock at each tick. The time_phase variable
- is scaled by (1 << SHIFT_SCALE) (24) in microseconds, giving a
- maximum adjustment of about +-128 us/tick and a resolution of about
- 60 femtoseconds/tick. The time_freq variable is scaled by (1 <<
- SHIFT_KF) in parts-per-million (ppm), giving it a maximum value of
- over +-2000 ppm and a minimum value (frequency resolution) of about
- 1e-5 ppm. The time_adj variable is the actual phase increment in
- scaled microseconds to add to time_phase once each tick. It is
- computed from time_phase and time_freq once per second.
-
-long time_reftime = 0; /* time at last adjustment (s) */
-
- This variable is the second's portion of the system time on the
- last call to adjtime(). It is used to adjust the time_freq variable
- as the time since the last update increases.
-
-int fixtick = 1000000 % HZ; /* amortization factor */
-
- In some systems such as the Ultrix and OSF/1 kernels, the local
- clock runs at some frequency that does not divide the number of
- microseconds in the second. In order that the clock runs at a
- precise rate, it is necessary to introduce an amortization factor
- into the local timescale, in effect a leap-multimicrosecond. This
- is not a new kernel variable, but a new use of an existing kernel
- variable.
-
-4.3. Architecture Constants
-
-Following is a list of the important architecture constants that
-establish the response and stability of the PLL and provide maximum
-bounds on behavior in order to satisfy correctness assertions made in
-the protocol specification.
-
-#define HZ 256 /* timer interrupt frequency (Hz) */
-#define SHIFT_HZ 8 /* log2(HZ) */
-
- The HZ define (a variable in some kernels) establishes the timer
- interrupt frequency, 100 Hz for the SunOS kernel, 256 Hz for the
- Ultrix kernel and 1024 Hz for the OSF/1 kernel. The SHIFT_HZ define
- expresses the same value as the nearest power of two in order to
- avoid hardware multiply operations. These are the only parameters
- that need to be changed for different kernel timer interrupt
- frequencies.
-
-#define SHIFT_KG 6 /* shift for phase increment */
-#define SHIFT_KF 16 /* shift for frequency increment */
-#define MAXTC 6 /* maximum time constant (shift) */
-
- These defines establish the response and stability characteristics
- of the PLL model. The SHIFT_KG and SHIFT_KF defines establish the
- damping of the PLL and are chosen by analysis for a slightly
- underdamped convergence characteristic. The MAXTC define
- establishes the maximum time constant of the PLL.
-
-#define SHIFT_SCALE (SHIFT_KF + SHIFT_HZ) /* shift for scale factor */
-#define SHIFT_UPDATE (SHIFT_KG + MAXTC) /* shift for offset scale
- * factor */
-#define SHIFT_USEC 16 /* shift for 1 us in external units */
-#define FINEUSEC (1 << SHIFT_SCALE) /* 1 us in scaled units */
-
- The SHIFT_SCALE define establishes the decimal point on the
- time_phase variable which serves as a an extension to the low-order
- bits of the system clock variable. The SHIFT_UPDATE define
- establishes the decimal point of the phase portion of the
- ntp_adjtime() update. The SHIFT_USEC define represents 1 us in
- external units (shift), while the FINEUSEC define represents 1 us
- in internal units.
-
-#define MAXPHASE 128000 /* max phase error (usec) */
-#define MAXFREQ 100 /* max frequency error (ppm) */
-#define MINSEC 16 /* min interval between updates (s) */
-#define MAXSEC 1200 /* max interval between updates (s) */
-
- These defines establish the performance envelope of the PLL, one to
- bound the maximum phase error, another to bound the maximum
- frequency error and two others to bound the minimum and maximum
- time between updates. The intent of these bounds is to force the
- PLL to operate within predefined limits in order to conform to the
- correctness models assumed by time-synchronization protocols like
- NTP and DTSS. An excursion which exceeds these bounds is clamped to
- the bound and operation proceeds accordingly. In practice, this can
- occur only if something has failed or is operating out of
- tolerance, but otherwise the PLL continues to operate in a stable
- mode. Note that the MAXPHASE define conforms to the maximum offset
- allowed in NTP before the system time is reset (by settimeofday(),
- rather than incrementally adjusted (by ntp_adjtime().
+ If selected, this member replaces the value of the time_status
+ kernel variable. This variable controls the state machine used to
+ insert or delete leap seconds and shows the status of the
+ timekeeping system, PPS signal and external oscillator, if
+ configured.
+
+ STA_PLL 0x0001 enable PLL updates (r/w)
+ STA_PPSFREQ 0x0002 enable PPS freq discipline (r/w)
+ STA_PPSTIME 0x0004 enable PPS time discipline (r/w)
+ STA_INS 0x0010 insert leap (r/w)
+ STA_DEL 0x0020 delete leap (r/w)
+ STA_UNSYNC 0x0040 clock unsynchronized (r/w)
+ STA_PPSSIGNAL 0x0100 PPS signal present (r)
+ STA_PPSJITTER 0x0200 PPS signal jitter exceeded (r)
+ STA_PPSWANDER 0x0400 PPS signal wander exceeded (r)
+ STA_PPSERROR 0x0800 PPS signal calibration error (r)
+ STA_CLOCKERR 0x1000 clock hardware fault (r)
+
+ The interpretation of these bits is as follows:
+
+ STA_PLL set/cleared by the caller to enable PLL updates
+
+ STA_PPSFREQ set/cleared by the caller to enable PPS frequency
+ discipline
+
+ STA_PPSTIME set/cleared by the caller to enable PPS time
+ discipline
+
+ STA_INS set by the caller to insert a leap second at the end
+ of the current day; cleared by the caller after the
+ event
+
+ STA_DEL set by the caller to delete a leap second at the end
+ of the current day; cleared by the caller after the
+ event
+
+ STA_UNSYNC set/cleared by the caller to indicate clock
+ unsynchronized (e.g., when no peers are reachable)
+
+ STA_PPSSIGNAL set/cleared by the hardpps() fragment to indicate
+ PPS signal present
+
+ STA_PPSJITTER set/cleared by the hardpps() fragment to indicates
+ PPS signal jitter exceeded
+
+ STA_PPSWANDER set/cleared by the hardpps() fragment to indicates
+ PPS signal wander exceeded
+
+ STA_PPSERROR set/cleared by the hardpps() fragment to indicates
+ PPS signal calibration error
+
+ STA_CLOCKERR set/cleared by the external hardware clock driver to
+ indicate hardware fault
+
+ An error condition is raised when (a) either STA_UNSYNC or
+ STA_CLOCKERR is set (loss of synchronization), (b) STA_PPSFREQ or
+ STA_PPSTIME is set and STA_PPSSIGNAL is clear (loss of PPS signal),
+ (c) STA_PPSTIME and STA_PPSJITTER are both set (jitter exceeded),
+ (d) STA_PPSFREQ is set and either STA_PPSWANDER or STA_PPSERROR is
+ set (wander exceeded). An error condition results in a system call
+ return code of TIME_ERROR.
+
+constant (rw)
+
+ If selected, this member replaces the value of the time_constant
+ kernel variable. The value must be between zero and MAXTC (6)
+ defined in the timex.h header file.
+
+ The time_constant variable determines the bandwidth or "stiffness"
+ of the PLL. The value is used as a shift between zero and MAXTC
+ (6), with the effective PLL time constant equal to a multiple of (1
+ << time_constant), in seconds. For room-temperature quartz
+ oscillators, the recommended default value is 2, which corresponds
+ to a PLL time constant of about 900 s and a maximum update interval
+ of about 64 s. The maximum update interval scales directly with the
+ time constant, so that at the maximum time constant of 6, the
+ update interval can be as large as 1024 s.
+
+ Values of time_constant between zero and 2 can be used if quick
+ convergence is necessary; values between 2 and 6 can be used to
+ reduce network load, but at a modest cost in accuracy. Values above
+ 6 are appropriate only if an precision external oscillator is
+ present.
+
+precision (ro)
+
+ This is the current value of the time_precision kernel variable in
+ microseconds.
+
+ The time_precision variable represents the maximum error in reading
+ the system clock, in microseconds. It is usually based on the
+ number of microseconds between timer interrupts (tick), 10000 us
+ for the SunOS kernel, 3906 us for the Ultrix kernel, 976 us for the
+ OSF/1 kernel. However, in cases where the time can be interpolated
+ between timer interrupts with microsecond resolution, such as in
+ the stock SunOS kernel and modified Ultrix and OSF/1 kernels, the
+ precision is specified as 1 us. In cases where a PPS signal or
+ external oscillator is available, the precision can depend on the
+ operating condition of the signal or oscillator. This variable is
+ determined by the kernel for use by the synchronization daemon, but
+ is otherwise not used by the kernel.
+
+tolerance (ro)
+
+ This is the current value of the time_tolerance kernel variable.
+ The value is in ppm, with the integer part in the high order 16
+ bits and fraction in the low order 16 bits.
+
+ The time_tolerance variable represents the maximum frequency error
+ in ppm of the particular CPU clock oscillator and is a property of
+ the hardware; however, in principle it could change as result of
+ the presence of external discipline signals, for instance.
+
+ The recommended value for time_tolerance MAXFREQ (200) ppm is
+ appropriate for room-temperature quartz oscillators used in typical
+ workstations. However, it can change due to the operating condition
+ of the PPS signal and/or external oscillator. With either the PPS
+ signal or external oscillator, the recommended value for MAXFREQ is
+ 100 ppm.
+
+The following members are defined only if the PPS_SYNC option is
+specified in the kernel configuration file. These members are useful
+primarily as a monitoring and evalutation tool. These variables can be
+written only by the kernel.
+
+ppsfreq (ro)
+
+ This is the current value of the pps_freq kernel variable, which is
+ the CPU clock oscillator frequency offset relative to the PPS
+ discipline signal. The value is in ppm, with the integer part in
+ the high order 16 bits and fraction in the low order 16 bits.
+
+jitter (ro)
+
+ This is the current value of the pps_jitter kernel variable, which
+ is the average PPS time dispersion measured by the time-offset
+ median filter, in microseconds.
+
+shift (ro)
+
+ This is the current value of the pps_shift kernel variable, which
+ determines the duration of the calibration interval as the value of
+ 1 << pps_shift, in seconds.
+stabil (ro)
+
+ This is the current value of the pps_stabil kernel variable, which
+ is the average PPS frequency dispersion measured by the frequency-
+ offset median filter. The value is in ppm, with the integer part in
+ the high order 16 bits and fraction in the low order 16 bits.
+
+jitcnt (ro)
+
+ This is the current value of the pps_jitcnt kernel variable, counts
+ the number of PPS signals where the average jitter exceeds the
+ threshold MAXTIME (200 us).
+
+calcnt (ro)
+
+ This is the current value of the pps_calcnt kernel variable, which
+ counts the number of frequency calibration intervals. The duration
+ of these intervals can range from 4 to 256 seconds, as determined
+ by the pps_shift kernel variable.
+
+errcnt (ro)
+
+ This is the current value of the pps_errcnt kernel variable, which
+ counts the number of frequency calibration cycles where (a) the
+ apparent frequency offset is greater than MAXFREQ (100 ppm) or (b)
+ the interval jitter exceeds tick * 2.
+
+stbcnt (ro)
+
+ This is the current value of the pps_discnt kernel variable, which
+ counts the number of calibration intervals where the average
+ stability exceeds the threshold MAXFREQ / 4 (25 ppm).
+
+7. References
+
+[MIL91] Mills, D.L. Internet time synchronization: the Network Time
+Protocol, IEEE Trans. Communications COM-39, 10 (October 1991),
+1482-1493. Also in: Yang, Z., and T.A. Marsland (Eds.). Global
+States and Time in Distributed Systems, IEEE Press, Los Alamitos,
+CA, 91-102.
+
+[MIL92a] Mills, D.L. Network Time Protocol (Version 3) specification,
+implementation and analysis, RFC 1305, University of Delaware, March
+1992, 113 pp.
+
+[MIL92b] Mills, D.L. Modelling and analysis of computer network clocks,
+Electrical Engineering Department Report 92-5-2, University of Delaware,
+May 1992, 29 pp.
+
+[MIL92c] Mills, D.L. Simple Network Time Protocol (SNTP), RFC 1361,
+University of Delaware, August 1992, 10 pp.
+
+[MIL93] Mills, D.L. Precision synchronizatin of computer network clocks,
+Electrical Engineering Department Report 93-11-1, University of
+Delaware, November 1993, 66 pp.
+
+[LEV89] Levine, J., M. Weiss, D. Davis, D. Allan, and D. Sullivan. The
+NIST automated computer time service. J. Research National Institute of
+Standards and Technology 94, 5 (September-October 1989), 311-321.
David L. Mills <mills@udel.edu>
Electrical Engineering Department
University of Delaware
Newark, DE 19716
302 831 8247 fax 302 831 4316
-
-1 April 1992
+3 April 1994
diff --git a/contrib/xntpd/doc/notes.txt b/contrib/xntpd/doc/notes.txt
index 5ea2b3318bb3..1dd59f25b3ac 100644
--- a/contrib/xntpd/doc/notes.txt
+++ b/contrib/xntpd/doc/notes.txt
@@ -785,7 +785,7 @@ configuration functionality (though the only thing you can currently do
with mode-6 messages is set the leap-second warning bits) and the ntpq
program provides generic support for the latter. The leap bits that can be
set in the leap_warning variable (up to one month ahead) and in the
-leap_indication variable have a slighly different encoding than the
+leap_indication variable have a slightly different encoding than the
usual interpretation:
Value Action
diff --git a/contrib/xntpd/gadget/.keep_me b/contrib/xntpd/gadget/.keep_me
deleted file mode 100644
index e69de29bb2d1..000000000000
--- a/contrib/xntpd/gadget/.keep_me
+++ /dev/null
diff --git a/contrib/xntpd/hints/.keep_me b/contrib/xntpd/hints/.keep_me
deleted file mode 100644
index e69de29bb2d1..000000000000
--- a/contrib/xntpd/hints/.keep_me
+++ /dev/null
diff --git a/contrib/xntpd/include/l_stdlib.h b/contrib/xntpd/include/l_stdlib.h
index 89a8092853b5..e0b7c474095c 100644
--- a/contrib/xntpd/include/l_stdlib.h
+++ b/contrib/xntpd/include/l_stdlib.h
@@ -70,11 +70,11 @@ extern int getppid P((void));
extern int close P((int));
extern int ioctl P((int, int, char *));
-extern int read P((int, char *, unsigned));
+extern int read P((int, void *, unsigned));
extern int rename P((char *, char *));
-extern int write P((int, char *, int));
-extern int unlink P((char *));
-extern int link P((char *, char *));
+extern int write P((int, const void *, unsigned));
+extern int unlink P((const char *));
+extern int link P((const char *, const char *));
#ifdef FILE
extern int fclose P((FILE *));
diff --git a/contrib/xntpd/include/ntp.h b/contrib/xntpd/include/ntp.h
index 310353f1cda2..01bfa16a7ad8 100644
--- a/contrib/xntpd/include/ntp.h
+++ b/contrib/xntpd/include/ntp.h
@@ -173,6 +173,7 @@ struct interface {
#define INT_BROADCAST 1 /* can broadcast out this interface */
#define INT_BCASTOPEN 2 /* broadcast socket is open */
#define INT_LOOPBACK 4 /* the loopback interface */
+#define INT_MULTICAST 8 /* multicasting enabled */
/*
* Define flasher bits (tests 1 through 8 in packet procedure)
@@ -222,7 +223,7 @@ struct peer {
U_LONG keyid; /* encription key ID */
U_LONG pkeyid; /* keyid used to encrypt last message */
u_short associd; /* association ID, a unique integer */
- u_char unused;
+ u_char ttl; /* time to live (multicast) */
/* **Start of clear-to-zero area.*** */
/* Everything that is cleared to zero goes below here */
u_char valid; /* valid counter */
@@ -248,12 +249,6 @@ struct peer {
s_fp soffset; /* fp version of above */
s_fp synch; /* synch distance from above */
u_fp selectdisp; /* select dispersion */
-
- /*
- * Stuff related to the experimental broadcast delay
- * determination code. The registers will probably go away
- * later.
- */
U_LONG estbdelay; /* broadcast delay, as a ts fraction */
/*
@@ -346,7 +341,7 @@ struct peer {
*/
#define REFCLK_NONE 0 /* unknown or missing */
#define REFCLK_LOCALCLOCK 1 /* external (e.g., ACTS) */
-#define REFCLK_WWV_HEATH 2 /* Heath GC-1000 WWV/H */
+#define REFCLK_GPS_TRAK 2 /* TRAK 8810 GPS Receiver */
#define REFCLK_WWV_PST 3 /* PST/Traconex 1020 WWV/H */
#define REFCLK_WWVB_SPECTRACOM 4 /* Spectracom 8170/Netclock WWVB */
#define REFCLK_GOES_TRUETIME 5 /* TrueTime 468-DC GOES */
@@ -579,8 +574,8 @@ struct recvbuf {
#define PROTO_AUTHENTICATE 3
#define PROTO_BROADDELAY 4
#define PROTO_AUTHDELAY 5
-#define PROTO_MAXSKEW 6
-#define PROTO_SELECT 7
+#define PROTO_MULTICAST_ADD 6
+#define PROTO_MULTICAST_DEL 7
/*
* Configuration items for the loop filter
@@ -603,7 +598,7 @@ struct recvbuf {
*/
#define DEFPRECISION (-5) /* conservatively low */
#define DEFBROADDELAY (0x020c49ba) /* 8 ms. This is round trip delay */
-
+#define INADDR_NTP 0xe0000101 /* NTP multicast address 224.0.1.1 */
/*
* Structure used optionally for monitoring when this is turned on.
*/
@@ -612,6 +607,9 @@ struct mon_data {
struct mon_data *hash_prev; /* previous structure in hash list */
struct mon_data *mru_next; /* next structure in MRU list */
struct mon_data *mru_prev; /* previous structure in MRU list */
+ struct mon_data *fifo_next; /* next structure in FIFO list */
+ struct mon_data *fifo_prev; /* previous structure in FIFO list */
+ U_LONG lastdrop; /* last time dropped due to RES_LIMIT*/
U_LONG lasttime; /* last time data updated */
U_LONG firsttime; /* time structure initialized */
U_LONG count; /* count we have seen */
@@ -621,7 +619,12 @@ struct mon_data {
u_char version; /* version of incoming packet */
};
-
+/*
+ * Values used with mon_enabled to indicate reason for enabling monitoring
+ */
+#define MON_OFF 0x00 /* no monitoring */
+#define MON_ON 0x01 /* monitoring explicitly enabled */
+#define MON_RES 0x02 /* implicit monitoring for RES_LIMITED */
/*
* Structure used for restrictlist entries
*/
@@ -645,10 +648,11 @@ struct restrictlist {
#define RES_NOPEER 0x20 /* don't allocate memory resources */
#define RES_NOTRAP 0x40 /* don't allow him to set traps */
#define RES_LPTRAP 0x80 /* traps set by him are low priority */
+#define RES_LIMITED 0x100 /* limit per net number of clients */
#define RES_ALLFLAGS \
(RES_IGNORE|RES_DONTSERVE|RES_DONTTRUST|RES_NOQUERY\
- |RES_NOMODIFY|RES_NOPEER|RES_NOTRAP|RES_LPTRAP)
+ |RES_NOMODIFY|RES_NOPEER|RES_NOTRAP|RES_LPTRAP|RES_LIMITED)
/*
* Match flags
diff --git a/contrib/xntpd/include/ntp_control.h b/contrib/xntpd/include/ntp_control.h
index 74f75f17f51a..1e193835660d 100644
--- a/contrib/xntpd/include/ntp_control.h
+++ b/contrib/xntpd/include/ntp_control.h
@@ -68,6 +68,7 @@ struct ntp_control {
#define CTL_SST_TS_UDPTIME 7 /* time source UDP/TIME */
#define CTL_SST_TS_WRSTWTCH 8 /* time source is wristwatch */
#define CTL_SST_TS_TELEPHONE 9 /* time source is telephone modem */
+#define CTL_SST_TS_PPS 0x20 /* time source is PPS signal */
#define CTL_SYS_MAXEVENTS 15
diff --git a/contrib/xntpd/include/ntp_if.h b/contrib/xntpd/include/ntp_if.h
index 1a76ca02da4b..45a70c51bcd5 100644
--- a/contrib/xntpd/include/ntp_if.h
+++ b/contrib/xntpd/include/ntp_if.h
@@ -16,6 +16,10 @@
#include <sys/sockio.h>
#endif
+#if defined(SYS_UNIXWARE1)
+#include <sys/sockio.h>
+#endif
+
#if defined(SYS_PTX) || defined(SYS_SINIXM)
#include <sys/stream.h>
#include <sys/stropts.h>
diff --git a/contrib/xntpd/include/ntp_in.h b/contrib/xntpd/include/ntp_in.h
new file mode 100755
index 000000000000..80aa45151fc6
--- /dev/null
+++ b/contrib/xntpd/include/ntp_in.h
@@ -0,0 +1,259 @@
+/* @(#)in.h 1.19 90/07/27 SMI; from UCB 7.5 2/22/88 */
+
+/*
+ * Copyright (c) 1982, 1986 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that this notice is preserved and that due credit is given
+ * to the University of California at Berkeley. The name of the University
+ * may not be used to endorse or promote products derived from this
+ * software without specific prior written permission. This software
+ * is provided ``as is'' without express or implied warranty.
+ */
+
+/*
+ * Constants and structures defined by the internet system,
+ * Per RFC 790, September 1981.
+ */
+
+#ifndef _netinet_in_h
+#define _netinet_in_h
+#define _NETINET_IN_H_
+#define _SYS_IN_INCLUDED
+#define __IN_HEADER
+
+/*
+ * Protocols
+ */
+#define IPPROTO_IP 0 /* dummy for IP */
+#define IPPROTO_ICMP 1 /* control message protocol */
+#define IPPROTO_IGMP 2 /* group control protocol */
+#define IPPROTO_GGP 3 /* gateway^2 (deprecated) */
+#define IPPROTO_ST 5 /* st */
+#define IPPROTO_TCP 6 /* tcp */
+#define IPPROTO_EGP 8 /* exterior gateway protocol */
+#define IPPROTO_PUP 12 /* pup */
+#define IPPROTO_UDP 17 /* user datagram protocol */
+#define IPPROTO_IDP 22 /* xns idp */
+#define IPPROTO_HELLO 63 /* "hello" routing protocol */
+#define IPPROTO_ND 77 /* UNOFFICIAL net disk proto */
+#define IPPROTO_OSPF 89 /* Open SPF IGP */
+
+#define IPPROTO_RAW 255 /* raw IP packet */
+#define IPPROTO_MAX 256
+
+/*
+ * Port/socket numbers: network standard functions
+ */
+#define IPPORT_ECHO 7
+#define IPPORT_DISCARD 9
+#define IPPORT_SYSTAT 11
+#define IPPORT_DAYTIME 13
+#define IPPORT_NETSTAT 15
+#define IPPORT_FTP 21
+#define IPPORT_TELNET 23
+#define IPPORT_SMTP 25
+#define IPPORT_TIMESERVER 37
+#define IPPORT_NAMESERVER 42
+#define IPPORT_WHOIS 43
+#define IPPORT_MTP 57
+
+/*
+ * Port/socket numbers: host specific functions
+ */
+#define IPPORT_TFTP 69
+#define IPPORT_RJE 77
+#define IPPORT_FINGER 79
+#define IPPORT_TTYLINK 87
+#define IPPORT_SUPDUP 95
+
+/*
+ * UNIX TCP sockets
+ */
+#define IPPORT_EXECSERVER 512
+#define IPPORT_LOGINSERVER 513
+#define IPPORT_CMDSERVER 514
+#define IPPORT_EFSSERVER 520
+
+/*
+ * UNIX UDP sockets
+ */
+#define IPPORT_BIFFUDP 512
+#define IPPORT_WHOSERVER 513
+#define IPPORT_ROUTESERVER 520 /* 520+1 also used */
+
+/*
+ * Ports < IPPORT_RESERVED are reserved for
+ * privileged processes (e.g. root).
+ * Ports > IPPORT_USERRESERVED are reserved
+ * for servers, not necessarily privileged.
+ */
+#define IPPORT_RESERVED 1024
+#define IPPORT_USERRESERVED 5000
+
+/*
+ * Link numbers
+ */
+#define IMPLINK_IP 155
+#define IMPLINK_LOWEXPER 156
+#define IMPLINK_HIGHEXPER 158
+
+/*
+ * Internet address
+ * This definition contains obsolete fields for compatibility
+ * with SunOS 3.x and 4.2bsd. The presence of subnets renders
+ * divisions into fixed fields misleading at best. New code
+ * should use only the s_addr field.
+ */
+struct in_addr {
+ union {
+ struct { u_char s_b1,s_b2,s_b3,s_b4; } S_un_b;
+ struct { u_short s_w1,s_w2; } S_un_w;
+ u_long S_addr;
+ } S_un;
+#define s_addr S_un.S_addr /* should be used for all code */
+#define s_host S_un.S_un_b.s_b2 /* OBSOLETE: host on imp */
+#define s_net S_un.S_un_b.s_b1 /* OBSOLETE: network */
+#define s_imp S_un.S_un_w.s_w2 /* OBSOLETE: imp */
+#define s_impno S_un.S_un_b.s_b4 /* OBSOLETE: imp # */
+#define s_lh S_un.S_un_b.s_b3 /* OBSOLETE: logical host */
+};
+
+/*
+ * Definitions of bits in internet address integers.
+ * On subnets, the decomposition of addresses to host and net parts
+ * is done according to subnet mask, not the masks here.
+ */
+#define IN_CLASSA(i) (((long)(i) & 0x80000000) == 0)
+#define IN_CLASSA_NET 0xff000000
+#define IN_CLASSA_NSHIFT 24
+#define IN_CLASSA_HOST 0x00ffffff
+#define IN_CLASSA_MAX 128
+
+#define IN_CLASSB(i) (((long)(i) & 0xc0000000) == 0x80000000)
+#define IN_CLASSB_NET 0xffff0000
+#define IN_CLASSB_NSHIFT 16
+#define IN_CLASSB_HOST 0x0000ffff
+#define IN_CLASSB_MAX 65536
+
+#define IN_CLASSC(i) (((long)(i) & 0xe0000000) == 0xc0000000)
+#define IN_CLASSC_NET 0xffffff00
+#define IN_CLASSC_NSHIFT 8
+#define IN_CLASSC_HOST 0x000000ff
+
+#define IN_CLASSD(i) (((long)(i) & 0xf0000000) == 0xe0000000)
+#define IN_CLASSD_NET 0xf0000000 /* These ones aren't really */
+#define IN_CLASSD_NSHIFT 28 /* net and host fields, but */
+#define IN_CLASSD_HOST 0x0fffffff /* routing needn't know. */
+#define IN_MULTICAST(i) IN_CLASSD(i)
+
+#define IN_EXPERIMENTAL(i) (((long)(i) & 0xe0000000) == 0xe0000000)
+#define IN_BADCLASS(i) (((long)(i) & 0xf0000000) == 0xf0000000)
+
+#define INADDR_ANY (u_long)0x00000000
+#define INADDR_LOOPBACK (u_long)0x7F000001
+#define INADDR_BROADCAST (u_long)0xffffffff /* must be masked */
+
+#define INADDR_UNSPEC_GROUP (u_long)0xe0000000 /* 224.0.0.0 */
+#define INADDR_ALLHOSTS_GROUP (u_long)0xe0000001 /* 224.0.0.1 */
+#define INADDR_MAX_LOCAL_GROUP (u_long)0xe00000ff /* 224.0.0.255 */
+
+#define IN_LOOPBACKNET 127 /* official! */
+
+/*
+ * Define a macro to stuff the loopback address into an Internet address
+ */
+#define IN_SET_LOOPBACK_ADDR(a) {(a)->sin_addr.s_addr = htonl(INADDR_LOOPBACK); \
+ (a)->sin_family = AF_INET;}
+
+/*
+ * Socket address, internet style.
+ */
+struct sockaddr_in {
+ short sin_family;
+ u_short sin_port;
+ struct in_addr sin_addr;
+ char sin_zero[8];
+};
+
+/*
+ * Options for use with [gs]etsockopt at the IP level.
+ */
+#define IP_OPTIONS 1 /* set/get IP per-packet options */
+#define IP_MULTICAST_IF 2 /* set/get IP multicast interface */
+#define IP_MULTICAST_TTL 3 /* set/get IP multicast timetolive */
+#define IP_MULTICAST_LOOP 4 /* set/get IP multicast loopback */
+#define IP_ADD_MEMBERSHIP 5 /* add an IP group membership */
+#define IP_DROP_MEMBERSHIP 6 /* drop an IP group membership */
+
+#define IP_DEFAULT_MULTICAST_TTL 1 /* normally limit m'casts to 1 hop */
+#define IP_DEFAULT_MULTICAST_LOOP 1 /* normally hear sends if a member */
+#define IP_MAX_MEMBERSHIPS 20 /* per socket; must fit in one mbuf */
+
+/*
+ * Argument structure for IP_ADD_MEMBERSHIP and IP_DROP_MEMBERSHIP.
+ */
+struct ip_mreq {
+ struct in_addr imr_multiaddr; /* IP multicast address of group */
+ struct in_addr imr_interface; /* local IP address of interface */
+};
+
+#if !defined(vax) && !defined(ntohl) && !defined(i386)
+/*
+ * Macros for number representation conversion.
+ */
+#define ntohl(x) (x)
+#define ntohs(x) (x)
+#define htonl(x) (x)
+#define htons(x) (x)
+#endif
+
+#if !defined(ntohl) && (defined(vax) || defined(i386))
+u_short ntohs(), htons();
+u_long ntohl(), htonl();
+#endif
+
+#ifdef KERNEL
+extern struct domain inetdomain;
+extern struct protosw inetsw[];
+struct in_addr in_makeaddr();
+u_long in_netof(), in_lnaof();
+#endif
+
+#ifndef BYTE_ORDER
+/*
+ * Definitions for byte order,
+ * according to byte significance from low address to high.
+ */
+#define LITTLE_ENDIAN 1234 /* least-significant byte first (vax) */
+#define BIG_ENDIAN 4321 /* most-significant byte first (IBM, net) */
+#define PDP_ENDIAN 3412 /* LSB first in word, MSW first in long (pdp) */
+
+#if defined(vax) || defined(i386)
+#define BYTE_ORDER LITTLE_ENDIAN
+#else
+#define BYTE_ORDER BIG_ENDIAN /* mc68000, tahoe, most others */
+#endif
+#endif BYTE_ORDER
+
+/*
+ * Macros for number representation conversion.
+ */
+#if BYTE_ORDER==LITTLE_ENDIAN
+#define NTOHL(d) ((d) = ntohl((d)))
+#define NTOHS(d) ((d) = ntohs((d)))
+#define HTONL(d) ((d) = htonl((d)))
+#define HTONS(d) ((d) = htons((d)))
+#else
+#define ntohl(x) (x)
+#define ntohs(x) (x)
+#define htonl(x) (x)
+#define htons(x) (x)
+#define NTOHL(d)
+#define NTOHS(d)
+#define HTONL(d)
+#define HTONS(d)
+#endif
+
+#endif /*!_netinet_in_h*/
diff --git a/contrib/xntpd/include/ntp_io.h b/contrib/xntpd/include/ntp_io.h
index c3b79be0616c..d60f08359b84 100644
--- a/contrib/xntpd/include/ntp_io.h
+++ b/contrib/xntpd/include/ntp_io.h
@@ -3,6 +3,7 @@
* SEEK_SET symbol form <untisd.h>.
*/
#if defined(NTP_POSIX_SOURCE)
+
/*
* POSIX way
*/
diff --git a/contrib/xntpd/include/ntp_machine.h b/contrib/xntpd/include/ntp_machine.h
index 1c3983e4a9ef..16c3fbf6da83 100644
--- a/contrib/xntpd/include/ntp_machine.h
+++ b/contrib/xntpd/include/ntp_machine.h
@@ -44,11 +44,16 @@ Signaled IO - Signled IO defines.
WHICH TERMINAL MODEL TO USE - I would assume HAVE_TERMIOS if
NTP_POSIX_SOURCE was set but can't. The
posix tty driver is too restrictive on most systems.
- It defined if you define STREAMS.
+ It is defined if you define STREAMS.
+ We do not put these defines in the ntp_machine.h as some systems
+ offer multiple interfaces and refclock configuration likes to
+ peek into the configuration defines for tty model restrictions.
+ Thus all tty definitions should be in the files in the machines directory.
+
+ HAVE_TERMIOS - Use POSIX termios.h
HAVE_SYSV_TTYS - Use SYSV termio.h
HAVE_BSD_TTYS - Use BSD stty.h
- HAVE_TERMIOS - Use POSIX termios.h
THIS MAKES PORTS TO NEW SYSTEMS EASY - You only have to wory about
kernel mucking.
@@ -79,6 +84,7 @@ INFO ON NEW KERNEL PLL SYS CALLS
NTP_SYSCALLS_STD - use the "normal" ones
NTP_SYSCALL_GET - SYS_ntp_gettime id
NTP_SYSCALL_ADJ - SYS_ntp_adjtime id
+ NTP_SYSCALLS_LIBC - ntp_adjtime() and ntp_gettime() are in libc.
HOW TO GET IP INTERFACE INFORMATION
@@ -274,7 +280,6 @@ in this file.
#ifndef STR_SYSTEM
#define STR_SYSTEM "UNIX/Ultrix"
#endif
-#define HAVE_TERMIOS
#endif
/*
@@ -297,9 +302,9 @@ in this file.
#define FORCE_NTPDATE_STEP
#define RETSIGTYPE void
#define HAVE_ATT_SETPGRP
-#define HAVE_BSD_TTYS
#define LOG_NTP LOG_LOCAL1
#define HAVE_SIGNALED_IO
+#define NTP_NEED_BOPS
#ifndef STR_SYSTEM
#define STR_SYSTEM "UNIX/AUX"
#endif
@@ -309,6 +314,7 @@ in this file.
* Next
*/
#if defined(SYS_NEXT)
+#define RETSIGTYPE void
#define DOSYNCTODR
#define HAVE_READKMEM
#define HAVE_BSD_NICE
@@ -329,8 +335,12 @@ in this file.
#define setlinebuf(f) setvbuf(f, NULL, _IOLBF, 0)
#define NO_SIGNED_CHAR_DECL
#define LOCK_PROCESS
-#define HAVE_NO_NICE /* HPUX uses rtprio instead */
#define RETSIGTYPE void
+#if (SYS_HPUX < 9)
+#define HAVE_NO_NICE /* HPUX uses rtprio instead */
+#else
+#define HAVE_BSD_NICE /* new at 9.X */
+#endif
#if (SYS_HPUX < 10)
#define NOKMEM
#else
@@ -352,8 +362,6 @@ in this file.
#ifndef STR_SYSTEM
#define STR_SYSTEM "UNIX/BSDI"
#endif
-#define HAVE_BSD_TTYS
-#define HAVE_TERMIOS
#endif
/*
@@ -387,6 +395,13 @@ in this file.
#define STR_SYSTEM "UNIX/*BSD"
#endif
#endif
+#ifdef SYS_FREEBSD
+#define HAVE_TERMIOS
+#define HAVE_UNAME
+#define HAVE_SYS_TIMEX_H
+#define NTP_SYSCALLS_LIBC
+#define KERNEL_PLL
+#endif
/*
* DEC AXP OSF/1
@@ -441,9 +456,6 @@ in this file.
*/
#if defined(SYS_PTX)
#define NO_SIGNED_CHAR_DECL
-#ifndef HAVE_SYSV_TTYS
-#define HAVE_SYSV_TTYS
-#endif
#define STREAMS_TLI
#define HAVE_ATT_SETPGRP
#define HAVE_SIGNALED_IO
@@ -458,6 +470,7 @@ in this file.
#define HAVE_READKMEM
#define UDP_WILDCARD_DELIVERY
#define NTP_POSIX_SOURCE
+#define memmove(x, y, z) memcpy(x, y, z)
struct timezone { int __0; }; /* unused placebo */
/*
* no comment !@!
@@ -521,13 +534,46 @@ typedef unsigned long u_long;
#endif
/*
+ * (Univel/Novell) Unixware1 SVR4 on intel x86 processor
+ */
+#if defined(SYS_UNIXWARE1)
+/* #define _POSIX_SOURCE */
+#undef HAVE_ATT_SETPGRP
+#define USE_PROTOTYPES
+#define NTP_POSIX_SOURCE
+#define HAVE_ATT_NICE
+#define HAVE_READKMEM
+#define USE_TTY_SIGPOLL
+#define USE_UDP_SIGPOLL
+#define UDP_WILDCARD_DELIVERY
+#undef HAVE_SIGNALED_IO
+#define STREAM
+#define STREAMS
+#ifndef STREAMS_TLI
+/*#define STREAMS_TLI*/
+#endif
+/* #define USE_STREAMS_DEVICE_FOR_IF_CONFIG */
+#undef STEP_SLEW /* TWO step */
+#define LOCK_PROCESS
+#define NO_SIGNED_CHAR_DECL
+#undef SYSV_TIMEOFDAY
+#define SIZE_RETURNED_IN_BUFFER
+#define RETSIGTYPE void
+#include <sys/sockio.h>
+#include <sys/types.h>
+#include <netinet/in_systm.h>
+#ifndef STR_SYSTEM
+#define STR_SYSTEM "UNIX/Unixware1"
+#endif
+#endif
+
+/*
* DomainOS
*/
#if defined(SYS_DOMAINOS)
#define HAVE_BSD_NICE
#define NOKMEM
#define HAVE_SIGNALED_IO
-#define HAVE_BSD_TTYS
#define NTP_SYSCALLS_STD
#define USE_PROTOTYPES
#define UDP_WILDCARD_DELIVERY
@@ -565,6 +611,20 @@ typedef unsigned long u_long;
ERROR You_must_define_one_of_the_HAVE_xx_NICE_defines
#endif
+/*
+ * use only one tty model - no use in initialising
+ * a tty in three ways
+ * HAVE_TERMIOS is preferred over HAVE_SYSV_TTYS over HAVE_BSD_TTYS
+ */
+#ifdef HAVE_TERMIOS
+#undef HAVE_BSD_TTYS
+#undef HAVE_SYSV_TTYS
+#endif
+
+#ifdef HAVE_SYSV_TTYS
+#undef HAVE_BSD_TTYS
+#endif
+
#if !defined(HAVE_SYSV_TTYS) \
&& !defined(HAVE_BSD_TTYS) \
&& !defined(HAVE_TERMIOS)
diff --git a/contrib/xntpd/include/ntp_request.h b/contrib/xntpd/include/ntp_request.h
index e94cb452aac7..b1a947291316 100644
--- a/contrib/xntpd/include/ntp_request.h
+++ b/contrib/xntpd/include/ntp_request.h
@@ -254,9 +254,8 @@ struct resp_pkt {
#define REQ_GET_LEAPINFO 35 /* get leap information */
#define REQ_GET_CLOCKINFO 36 /* get clock information */
#define REQ_SET_CLKFUDGE 37 /* set clock fudge factors */
-#define REQ_SET_MAXSKEW 38 /* set the maximum skew factor */
+#define REQ_GET_KERNEL 38 /* get kernel pll/pps information */
#define REQ_GET_CLKBUGINFO 39 /* get clock debugging info */
-#define REQ_SET_SELECT_CODE 40 /* set selection algorithm */
#define REQ_SET_PRECISION 41 /* set clock precision */
@@ -267,8 +266,9 @@ struct resp_pkt {
#define INFO_FLAG_SYSPEER 0x2
#define INFO_FLAG_MINPOLL 0x4
#define INFO_FLAG_REFCLOCK 0x8
+#define INFO_FLAG_MCLIENT 0x8 /* danger */
#define INFO_FLAG_BCLIENT 0x10
-#define INFO_FLAG_PREFER 0x10 /* SHARES BCLIENT bit - ok since mutually exclusive - Oh why ist flags a u_char ? */
+#define INFO_FLAG_PREFER 0x10 /* danger */
#define INFO_FLAG_AUTHENABLE 0x20
#define INFO_FLAG_SEL_CANDIDATE 0x40
#define INFO_FLAG_SHORTLIST 0x80
@@ -323,10 +323,10 @@ struct info_peer {
u_char valid; /* peer.valid */
u_char reach; /* peer.reach */
u_char unreach; /* peer.unreach */
- u_char trust; /* peer.trust */
- u_char unused1;
- u_char unused2;
- u_char unused3;
+ u_char flash; /* peer.flash */
+ u_char ttl; /* peer.ttl */
+ u_char unused8; /* (obsolete) */
+ u_char unused9;
u_short associd; /* association ID */
U_LONG keyid; /* auth key in use */
U_LONG pkeyid; /* peer.pkeyid */
@@ -344,7 +344,14 @@ struct info_peer {
s_fp delay; /* peer.estdelay */
u_fp dispersion; /* peer.estdisp */
l_fp offset; /* peer.estoffset */
- U_LONG bdelay[NTP_SHIFT]; /* broadcast delay filters */
+ u_fp selectdisp; /* peer select dispersion */
+ LONG unused1; /* (obsolete) */
+ LONG unused2;
+ LONG unused3;
+ LONG unused4;
+ LONG unused5;
+ LONG unused6;
+ LONG unused7;
U_LONG estbdelay; /* broadcast delay */
};
@@ -406,12 +413,13 @@ struct info_sys {
U_LONG refid; /* reference ID of sync source */
l_fp reftime; /* system reference time */
U_LONG poll; /* system poll interval */
- u_short flags; /* system flags */
- u_char selection; /* selection algorithm code */
- u_char unused;
- l_fp bdelay; /* default broadcast delay, a ts fraction */
+ u_char flags; /* system flags */
+ u_char unused1; /* unused */
+ u_char unused2; /* unused */
+ u_char unused3; /* unused */
+ l_fp bdelay; /* default broadcast delay */
l_fp authdelay; /* default authentication delay */
- u_fp maxskew; /* maximum skew parameter (obsolete) */
+ u_fp maxskew; /* (obsolete) */
};
@@ -428,6 +436,24 @@ struct info_sys_stats {
U_LONG badlength; /* packets with bad length */
U_LONG processed; /* packets processed */
U_LONG badauth; /* packets dropped because of authorization */
+ U_LONG wanderhold; /* (obsolete) */
+ U_LONG limitrejected; /* rejected because of client limitation */
+};
+
+
+/*
+ * System stats - old version
+ */
+struct old_info_sys_stats {
+ U_LONG timeup; /* time we have been up and running */
+ U_LONG timereset; /* time since these were last cleared */
+ U_LONG badstratum; /* packets claiming an invalid stratum */
+ U_LONG oldversionpkt; /* old version packets received */
+ U_LONG newversionpkt; /* new version packets received */
+ U_LONG unknownversion; /* don't know version packets */
+ U_LONG badlength; /* packets with bad length */
+ U_LONG processed; /* packets processed */
+ U_LONG badauth; /* packets dropped because of authorization */
U_LONG wanderhold;
};
@@ -486,7 +512,8 @@ struct conf_peer {
u_char minpoll; /* min host poll interval */
u_char maxpoll; /* max host poll interval */
u_char flags; /* flags for this request */
- u_char unused;
+ u_char ttl; /* time to live (multicast) */
+ u_short unused; /* unused */
U_LONG keyid; /* key to use for this association */
};
@@ -516,6 +543,7 @@ struct conf_sys_flags {
*/
#define SYS_FLAG_BCLIENT 0x1
#define SYS_FLAG_AUTHENTICATE 0x2
+#define SYS_FLAG_MCLIENT 0x4
/*
* Structure used for returning restrict entries
@@ -546,6 +574,7 @@ struct conf_restrict {
struct info_monitor {
U_LONG lasttime; /* last packet from this host */
U_LONG firsttime; /* first time we received a packet */
+ U_LONG lastdrop; /* last time we rejected a packet due to client limitation policy */
U_LONG count; /* count of packets received */
U_LONG addr; /* host address */
u_short port; /* port number of last reception */
@@ -553,6 +582,18 @@ struct info_monitor {
u_char version; /* version number of last packet */
};
+/*
+ * Structure used for returning monitor data (old format
+ */
+struct old_info_monitor {
+ U_LONG lasttime; /* last packet from this host */
+ U_LONG firsttime; /* first time we received a packet */
+ U_LONG count; /* count of packets received */
+ U_LONG addr; /* host address */
+ u_short port; /* port number of last reception */
+ u_char mode; /* mode of last packet */
+ u_char version; /* version number of last packet */
+};
/*
* Structure used for passing indication of flags to clear
@@ -711,3 +752,29 @@ struct info_clkbug {
U_LONG values[NUMCBUGVALUES];
l_fp times[NUMCBUGTIMES];
};
+
+/*
+ * Structure used for returning kernel pll/PPS information
+ */
+struct info_kernel {
+ LONG offset;
+ LONG freq;
+ LONG maxerror;
+ LONG esterror;
+ u_short status;
+ u_short shift;
+ LONG constant;
+ LONG precision;
+ LONG tolerance;
+
+/*
+ * Variables used only if PPS signal discipline is implemented
+ */
+ LONG ppsfreq;
+ LONG jitter;
+ LONG stabil;
+ LONG jitcnt;
+ LONG calcnt;
+ LONG errcnt;
+ LONG stbcnt;
+};
diff --git a/contrib/xntpd/include/ntp_stdlib.h b/contrib/xntpd/include/ntp_stdlib.h
index 0ec062581616..f68c768d82d3 100644
--- a/contrib/xntpd/include/ntp_stdlib.h
+++ b/contrib/xntpd/include/ntp_stdlib.h
@@ -79,6 +79,7 @@ extern char * inttoa P((LONG));
extern char * mfptoa P((U_LONG, U_LONG, int));
extern char * mfptoms P((U_LONG, U_LONG, int));
extern char * modetoa P((int));
+extern U_LONG netof P((U_LONG));
extern char * numtoa P((U_LONG));
extern char * numtohost P((U_LONG));
extern int octtoint P((const char *, U_LONG *));
diff --git a/contrib/xntpd/include/ntp_timex.h b/contrib/xntpd/include/ntp_timex.h
index 1756e2e07f21..cb8396ac23fe 100644
--- a/contrib/xntpd/include/ntp_timex.h
+++ b/contrib/xntpd/include/ntp_timex.h
@@ -1,6 +1,6 @@
/******************************************************************************
* *
- * Copyright (c) David L. Mills 1993 *
+ * Copyright (c) David L. Mills 1993, 1994 *
* *
* Permission to use, copy, modify, and distribute this software and its *
* documentation for any purpose and without fee is hereby granted, provided *
@@ -17,12 +17,18 @@
/*
* Modification history timex.h
*
+ * 19 Mar 94 David L. Mills
+ * Moved defines from kernel routines to header file and added new
+ * defines for PPS phase-lock loop.
+ *
+ * 20 Feb 94 David L. Mills
+ * Revised status codes and structures for external clock and PPS
+ * signal discipline.
+ *
* 28 Nov 93 David L. Mills
- * Adjusted parameters to improve stability and increase poll interval
+ * Adjusted parameters to improve stability and increase poll
+ * interval.
*
- * 10 Oct 93 Torsten Duwe
- * Changed to ntp_timex.h (#ifdef'd HAVE_SYS_TIMEX_H)
- *
* 17 Sep 93 David L. Mills
* Created file
*/
@@ -41,7 +47,7 @@
* int syscall(SYS_ntp_gettime, tptr)
*
* int SYS_ntp_gettime defined in syscall.h header file
- * struct ntptimeval *tptr pointer to ntptimeval structure
+ * struct ntptimeval *tptr pointer to ntptimeval structure
*
* NAME
* ntp_adjtime - NTP daemon application interface
@@ -55,104 +61,213 @@
* struct timex *tptr pointer to timex structure
*
*/
-#ifndef _NTP_TIMEX_H
-#define _NTP_TIMEX_H
+#ifndef MSDOS /* Microsoft specific */
+#include <sys/syscall.h>
+#endif /* MSDOS */
/*
- * Include system timex.h (if appropriate)
+ * The following defines establish the engineering parameters of the
+ * phase-lock loop (PLL) model used in the kernel implementation. These
+ * parameters have been carefully chosen by analysis for good stability
+ * and wide dynamic range.
+ *
+ * The hz variable is defined in the kernel build environment. It
+ * establishes the timer interrupt frequency, 100 Hz for the SunOS
+ * kernel, 256 Hz for the Ultrix kernel and 1024 Hz for the OSF/1
+ * kernel. SHIFT_HZ expresses the same value as the nearest power of two
+ * in order to avoid hardware multiply operations.
+ *
+ * SHIFT_KG and SHIFT_KF establish the damping of the PLL and are chosen
+ * for a slightly underdamped convergence characteristic.
+ *
+ * MAXTC establishes the maximum time constant of the PLL. With the
+ * SHIFT_KG and SHIFT_KF values given and a time constant range from
+ * zero to MAXTC, the PLL will converge in 15 minutes to 16 hours,
+ * respectively.
*/
-#ifdef HAVE_SYS_TIMEX_H
-#include <sys/timex.h>
-#else /* provide definitions */
-#include <sys/syscall.h>
-
-extern int syscall P((int, void *, ...));
+#define SHIFT_HZ 7 /* log2(hz) */
+#define SHIFT_KG 6 /* phase factor (shift) */
+#define SHIFT_KF 16 /* frequency factor (shift) */
+#define MAXTC 6 /* maximum time constant (shift) */
-#define ntp_gettime(t) syscall(SYS_ntp_gettime, (t))
-#define ntp_adjtime(t) syscall(SYS_ntp_adjtime, (t))
+/*
+ * The following defines establish the scaling of the various variables
+ * used by the PLL. They are chosen to allow the greatest precision
+ * possible without overflow of a 32-bit word.
+ *
+ * SHIFT_SCALE defines the scaling (shift) of the time_phase variable,
+ * which serves as a an extension to the low-order bits of the system
+ * clock variable time.tv_usec.
+ *
+ * SHIFT_UPDATE defines the scaling (shift) of the time_offset variable,
+ * which represents the current time offset with respect to standard
+ * time.
+ *
+ * SHIFT_USEC defines the scaling (shift) of the time_freq and
+ * time_tolerance variables, which represent the current frequency
+ * offset and maximum frequency tolerance.
+ *
+ * FINEUSEC is 1 us in SHIFT_UPDATE units of the time_phase variable.
+ */
+#define SHIFT_SCALE 23 /* phase scale (shift) */
+#define SHIFT_UPDATE (SHIFT_KG + MAXTC) /* time offset scale (shift) */
+#define SHIFT_USEC 16 /* frequency offset scale (shift) */
+#define FINEUSEC (1L << SHIFT_SCALE) /* 1 us in phase units */
/*
- * The following defines establish the engineering parameters of the PLL
- * model. The HZ variable establishes the timer interrupt frequency, 100 Hz
- * for the SunOS kernel, 256 Hz for the Ultrix kernel and 1024 Hz for the
- * OSF/1 kernel. The SHIFT_HZ define expresses the same value as the
- * nearest power of two in order to avoid hardware multiply operations.
+ * The following defines establish the performance envelope of the PLL.
+ * They insure it operates within predefined limits, in order to satisfy
+ * correctness assertions. An excursion which exceeds these bounds is
+ * clamped to the bound and operation proceeds accordingly. In practice,
+ * this can occur only if something has failed or is operating out of
+ * tolerance, but otherwise the PLL continues to operate in a stable
+ * mode.
+ *
+ * MAXPHASE must be set greater than or equal to CLOCK.MAX (128 ms), as
+ * defined in the NTP specification. CLOCK.MAX establishes the maximum
+ * time offset allowed before the system time is reset, rather than
+ * incrementally adjusted. Here, the maximum offset is clamped to
+ * MAXPHASE only in order to prevent overflow errors due to defective
+ * protocol implementations.
+ *
+ * MAXFREQ is the maximum frequency tolerance of the CPU clock
+ * oscillator plus the maximum slew rate allowed by the protocol. It
+ * should be set to at least the frequency tolerance of the oscillator
+ * plus 100 ppm for vernier frequency adjustments. If the kernel
+ * PPS discipline code is configured (PPS_SYNC), the oscillator time and
+ * frequency are disciplined to an external source, presumably with
+ * negligible time and frequency error relative to UTC, and MAXFREQ can
+ * be reduced.
+ *
+ * MAXTIME is the maximum jitter tolerance of the PPS signal if the
+ * kernel PPS discipline code is configured (PPS_SYNC).
+ *
+ * MINSEC and MAXSEC define the lower and upper bounds on the interval
+ * between protocol updates.
*/
-#define SHIFT_HZ 7 /* log2(HZ) */
+#define MAXPHASE 128000L /* max phase error (us) */
+#ifdef PPS_SYNC
+#define MAXFREQ (100L << SHIFT_USEC) /* max freq error (100 ppm) */
+#define MAXTIME (200L << PPS_AVG) /* max PPS error (jitter) (200 us) */
+#else
+#define MAXFREQ (200L << SHIFT_USEC) /* max freq error (200 ppm) */
+#endif /* PPS_SYNC */
+#define MINSEC 16L /* min interval between updates (s) */
+#define MAXSEC 1200L /* max interval between updates (s) */
+#ifdef PPS_SYNC
/*
- * The SHIFT_KG and SHIFT_KF defines establish the damping of the PLL
- * and are chosen by analysis for a slightly underdamped convergence
- * characteristic. The MAXTC define establishes the maximum time constant
- * of the PLL. With the parameters given and the default time constant of
- * zero, the PLL will converge in about 15 minutes.
+ * The following defines are used only if a pulse-per-second (PPS)
+ * signal is available and connected via a modem control lead, such as
+ * produced by the optional ppsclock feature incorporated in the Sun
+ * asynch driver. They establish the design parameters of the frequency-
+ * lock loop used to discipline the CPU clock oscillator to the PPS
+ * signal.
+ *
+ * PPS_AVG is the averaging factor for the frequency loop, as well as
+ * the time and frequency dispersion.
+ *
+ * PPS_SHIFT and PPS_SHIFTMAX specify the minimum and maximum
+ * calibration intervals, respectively, in seconds as a power of two.
+ *
+ * PPS_VALID is the maximum interval before the PPS signal is considered
+ * invalid and protocol updates used directly instead.
+ *
+ * MAXGLITCH is the maximum interval before a time offset of more than
+ * MAXTIME is believed.
*/
-#define SHIFT_KG 6 /* shift for phase increment */
-#define SHIFT_KF 16 /* shift for frequency increment */
-#define MAXTC 6 /* maximum time constant (shift) */
+#define PPS_AVG 2 /* pps averaging constant (shift) */
+#define PPS_SHIFT 2 /* min interval duration (s) (shift) */
+#define PPS_SHIFTMAX 8 /* max interval duration (s) (shift) */
+#define PPS_VALID 120 /* pps signal watchdog max (s) */
+#define MAXGLITCH 30 /* pps signal glitch max (s) */
+#endif /* PPS_SYNC */
/*
- * The SHIFT_SCALE define establishes the decimal point of the time_phase
- * variable which serves as a an extension to the low-order bits of the
- * system clock variable. The SHIFT_UPDATE define establishes the decimal
- * point of the time_offset variable which represents the current offset
- * with respect to standard time. The SHIFT_USEC define represents 1 us in
- * external units (shift), while the FINEUSEC define represents 1 us in
- * internal units.
+ * The following defines and structures define the user interface for
+ * the ntp_gettime() and ntp_adjtime() system calls.
+ *
+ * Control mode codes (timex.modes)
*/
-#define SHIFT_SCALE 23 /* shift for phase scale factor */
-#define SHIFT_UPDATE (SHIFT_KG + MAXTC) /* shift for offset scale factor */
-#define SHIFT_USEC 16 /* shift for 1 us in external units */
-#define FINEUSEC (1 << SHIFT_SCALE) /* 1 us in internal units */
+#define MOD_OFFSET 0x0001 /* set time offset */
+#define MOD_FREQUENCY 0x0002 /* set frequency offset */
+#define MOD_MAXERROR 0x0004 /* set maximum time error */
+#define MOD_ESTERROR 0x0008 /* set estimated time error */
+#define MOD_STATUS 0x0010 /* set clock status bits */
+#define MOD_TIMECONST 0x0020 /* set pll time constant */
+#define MOD_CLKB 0x4000 /* set clock B */
+#define MOD_CLKA 0x8000 /* set clock A */
/*
- * Mode codes (timex.mode)
+ * Status codes (timex.status)
*/
-#define ADJ_OFFSET 0x0001 /* time offset */
-#define ADJ_FREQUENCY 0x0002 /* frequency offset */
-#define ADJ_MAXERROR 0x0004 /* maximum time error */
-#define ADJ_ESTERROR 0x0008 /* estimated time error */
-#define ADJ_STATUS 0x0010 /* clock status */
-#define ADJ_TIMECONST 0x0020 /* pll time constant */
+#define STA_PLL 0x0001 /* enable PLL updates (rw) */
+#define STA_PPSFREQ 0x0002 /* enable PPS freq discipline (rw) */
+#define STA_PPSTIME 0x0004 /* enable PPS time discipline (rw) */
+
+#define STA_INS 0x0010 /* insert leap (rw) */
+#define STA_DEL 0x0020 /* delete leap (rw) */
+#define STA_UNSYNC 0x0040 /* clock unsynchronized (rw) */
+
+#define STA_PPSSIGNAL 0x0100 /* PPS signal present (ro) */
+#define STA_PPSJITTER 0x0200 /* PPS signal jitter exceeded (ro) */
+#define STA_PPSWANDER 0x0400 /* PPS signal wander exceeded (ro) */
+#define STA_PPSERROR 0x0800 /* PPS signal calibration error (ro) */
+
+#define STA_CLOCKERR 0x1000 /* clock hardware fault (ro) */
+
+#define STA_RONLY (STA_PPSSIGNAL | STA_PPSJITTER | STA_PPSWANDER | \
+ STA_PPSERROR | STA_CLOCKERR) /* read-only bits */
/*
- * Clock command/status codes (timex.status)
+ * Clock states (time_state)
*/
-#define TIME_OK 0 /* clock synchronized */
-#define TIME_INS 1 /* insert leap second */
-#define TIME_DEL 2 /* delete leap second */
+#define TIME_OK 0 /* no leap second warning */
+#define TIME_INS 1 /* insert leap second warning */
+#define TIME_DEL 2 /* delete leap second warning */
#define TIME_OOP 3 /* leap second in progress */
-#define TIME_BAD 4 /* clock not synchronized */
+#define TIME_WAIT 4 /* leap second has occured */
+#define TIME_ERROR 5 /* clock not synchronized */
/*
- * NTP user interface - used to read kernel clock values
+ * NTP user interface (ntp_gettime()) - used to read kernel clock values
+ *
* Note: maximum error = NTP synch distance = dispersion + delay / 2;
* estimated error = NTP dispersion.
*/
struct ntptimeval {
- struct timeval time; /* current time */
- long maxerror; /* maximum error (usec) */
- long esterror; /* estimated error (usec) */
+ struct timeval time; /* current time (ro) */
+ LONG maxerror; /* maximum error (us) (ro) */
+ LONG esterror; /* estimated error (us) (ro) */
};
/*
- * NTP daemon interface - used to discipline kernel clock oscillator
+ * NTP daemon interface - (ntp_adjtime()) used to discipline CPU clock
+ * oscillator
*/
struct timex {
- int mode; /* mode selector */
- long offset; /* time offset (usec) */
- long frequency; /* frequency offset (scaled ppm) */
- long maxerror; /* maximum error (usec) */
- long esterror; /* estimated error (usec) */
- int status; /* clock command/status */
- long time_constant; /* pll time constant */
- long precision; /* clock precision (usec) (read only) */
- long tolerance; /* clock frequency tolerance (ppm)
- * (read only)
- */
-};
-
-#endif /* HAVE_SYS_TIMEX_H */
-
-#endif /* _NTP_TIMEX_H */
+ unsigned int modes; /* clock mode bits (wo) */
+ LONG offset; /* time offset (us) (rw) */
+ LONG freq; /* frequency offset (scaled ppm) (rw) */
+ LONG maxerror; /* maximum error (us) (rw) */
+ LONG esterror; /* estimated error (us) (rw) */
+ int status; /* clock status bits (rw) */
+ LONG constant; /* pll time constant (rw) */
+ LONG precision; /* clock precision (us) (ro) */
+ LONG tolerance; /* clock frequency tolerance (scaled
+ * ppm) (ro) */
+ /*
+ * The following read-only structure members are implemented
+ * only if the PPS signal discipline is configured in the
+ * kernel.
+ */
+ LONG ppsfreq; /* pps frequency (scaled ppm) (ro) */
+ LONG jitter; /* pps jitter (us) (ro) */
+ int shift; /* interval duration (s) (shift) (ro) */
+ LONG stabil; /* pps stability (scaled ppm) (ro) */
+ LONG jitcnt; /* jitter limit exceeded (ro) */
+ LONG calcnt; /* calibration intervals (ro) */
+ LONG errcnt; /* calibration errors (ro) */
+ LONG stbcnt; /* stability limit exceeded (ro) */
+};
diff --git a/contrib/xntpd/include/ntpd.h b/contrib/xntpd/include/ntpd.h
index f2c56af20b90..037e8cb366f4 100644
--- a/contrib/xntpd/include/ntpd.h
+++ b/contrib/xntpd/include/ntpd.h
@@ -63,6 +63,9 @@ extern void input_handler P((l_fp *));
extern void io_clr_stats P((void));
extern void io_setbclient P((void));
extern void io_unsetbclient P((void));
+extern void io_multicast_add P((U_LONG));
+extern void io_multicast_del P((U_LONG));
+
extern void sendpkt P((struct sockaddr_in *, struct interface *, struct pkt *, int));
#ifdef HAVE_SIGNALED_IO
extern void wait_for_signal P((void));
@@ -93,8 +96,8 @@ extern int pps_sample P((l_fp *));
/* ntp_monitor.c */
extern void init_mon P((void));
-extern void mon_start P((void));
-extern void mon_stop P((void));
+extern void mon_start P((int));
+extern void mon_stop P((int));
extern void monitor P((struct recvbuf *));
/* ntp_peer.c */
@@ -102,10 +105,10 @@ extern void init_peer P((void));
extern struct peer *findexistingpeer P((struct sockaddr_in *, struct peer *));
extern struct peer *findpeer P((struct sockaddr_in *, struct interface *));
extern struct peer *findpeerbyassoc P((int));
-extern struct peer *newpeer P((struct sockaddr_in *, struct interface *, int, int, int, int, U_LONG));
+extern struct peer *newpeer P((struct sockaddr_in *, struct interface *, int, int, int, int, int, U_LONG));
extern void peer_all_reset P((void));
extern void peer_clr_stats P((void));
-extern struct peer *peer_config P((struct sockaddr_in *, struct interface *, int, int, int, int, U_LONG, int));
+extern struct peer *peer_config P((struct sockaddr_in *, struct interface *, int, int, int, int, int, int, U_LONG));
extern void peer_reset P((struct peer *));
extern int peer_unconfig P((struct sockaddr_in *, struct interface *));
extern void unpeer P((struct peer *));
@@ -131,7 +134,7 @@ extern void clock_select P((void));
extern void clock_combine P((struct peer **, int));
extern void fast_xmit P((struct recvbuf *, int, int));
extern void init_proto P((void));
-extern void proto_config P((int, LONG));
+extern void proto_config P((int, U_LONG));
extern void proto_clr_stats P((void));
#ifdef REFCLOCK
diff --git a/contrib/xntpd/include/parse.h b/contrib/xntpd/include/parse.h
index 31041afe292f..6ce3f192754a 100644
--- a/contrib/xntpd/include/parse.h
+++ b/contrib/xntpd/include/parse.h
@@ -1,7 +1,7 @@
/*
- * /src/NTP/REPOSITORY/v3/include/parse.h,v 3.13 1994/01/25 19:04:21 kardel Exp
+ * /src/NTP/REPOSITORY/v3/include/parse.h,v 3.17 1994/03/03 09:27:20 kardel Exp
*
- * parse.h,v 3.13 1994/01/25 19:04:21 kardel Exp
+ * parse.h,v 3.17 1994/03/03 09:27:20 kardel Exp
*
* Copyright (c) 1989,1990,1991,1992,1993,1994
* Frank Kardel Friedrich-Alexander Universitaet Erlangen-Nuernberg
@@ -15,7 +15,7 @@
#ifndef __PARSE_H__
#define __PARSE_H__
#if !(defined(lint) || defined(__GNUC__))
- static char parsehrcsid[]="parse.h,v 3.13 1994/01/25 19:04:21 kardel Exp FAU";
+ static char parsehrcsid[]="parse.h,v 3.17 1994/03/03 09:27:20 kardel Exp";
#endif
#include "ntp_types.h"
@@ -81,35 +81,55 @@ extern int debug;
/*
* state flags
*/
-#define PARSEB_ANNOUNCE 0x0001 /* switch time zone warning (DST switch) */
-#define PARSEB_POWERUP 0x0002 /* no synchronisation */
-#define PARSEB_NOSYNC 0x0004 /* timecode currently not confirmed */
-#define PARSEB_DST 0x0008 /* DST in effect */
-#define PARSEB_UTC 0x0010 /* UTC time */
-#define PARSEB_LEAP 0x0020 /* LEAP warning (1 hour prior to occurence) */
-#define PARSEB_ALTERNATE 0x0040 /* alternate antenna used */
-#define PARSEB_POSITION 0x0080 /* position available */
-#define PARSEB_LEAPSECOND 0x0100 /* actual leap second */
-
-#define PARSEB_S_LEAP 0x0200 /* supports LEAP */
-#define PARSEB_S_ANTENNA 0x0400 /* supports antenna information */
-#define PARSEB_S_PPS 0x0800 /* supports PPS time stamping */
-#define PARSEB_S_POSITION 0x1000 /* supports position information (GPS) */
-
-#define PARSEB_TIMECODE 0x2000 /* valid time code sample */
-#define PARSEB_PPS 0x4000 /* valid PPS sample */
+#define PARSEB_POWERUP 0x00000001 /* no synchronisation */
+#define PARSEB_NOSYNC 0x00000002 /* timecode currently not confirmed */
+
+/*
+ * time zone information
+ */
+#define PARSEB_ANNOUNCE 0x00000010 /* switch time zone warning (DST switch) */
+#define PARSEB_DST 0x00000020 /* DST in effect */
+#define PARSEB_UTC 0x00000040 /* UTC time */
+
+/*
+ * leap information
+ */
+#define PARSEB_LEAPDEL 0x00000100 /* LEAP deletion warning */
+#define PARSEB_LEAPADD 0x00000200 /* LEAP addition warning */
+#define PARSEB_LEAPS 0x00000300 /* LEAP warnings */
+#define PARSEB_LEAPSECOND 0x00000400 /* actual leap second */
+/*
+ * optional status information
+ */
+#define PARSEB_ALTERNATE 0x00001000 /* alternate antenna used */
+#define PARSEB_POSITION 0x00002000 /* position available */
+
+/*
+ * feature information
+ */
+#define PARSEB_S_LEAP 0x00010000 /* supports LEAP */
+#define PARSEB_S_ANTENNA 0x00020000 /* supports antenna information */
+#define PARSEB_S_PPS 0x00040000 /* supports PPS time stamping */
+#define PARSEB_S_POSITION 0x00080000 /* supports position information (GPS) */
+
+/*
+ * time stamp availality
+ */
+#define PARSEB_TIMECODE 0x10000000 /* valid time code sample */
+#define PARSEB_PPS 0x20000000 /* valid PPS sample */
#define PARSE_TCINFO (PARSEB_ANNOUNCE|PARSEB_POWERUP|PARSEB_NOSYNC|PARSEB_DST|\
- PARSEB_UTC|PARSEB_LEAP|PARSEB_ALTERNATE|PARSEB_S_LEAP|\
+ PARSEB_UTC|PARSEB_LEAPS|PARSEB_ALTERNATE|PARSEB_S_LEAP|\
PARSEB_S_LOCATION|PARSEB_TIMECODE)
-#define PARSE_POWERUP(x) ((x) & PARSEB_POWERUP)
-#define PARSE_NOSYNC(x) (((x) & (PARSEB_POWERUP|PARSEB_NOSYNC)) == PARSEB_NOSYNC)
-#define PARSE_SYNC(x) (((x) & (PARSEB_POWERUP|PARSEB_NOSYNC)) == 0)
-#define PARSE_ANNOUNCE(x) ((x) & PARSEB_ANNOUNCE)
-#define PARSE_DST(x) ((x) & PARSEB_DST)
+#define PARSE_POWERUP(x) ((x) & PARSEB_POWERUP)
+#define PARSE_NOSYNC(x) (((x) & (PARSEB_POWERUP|PARSEB_NOSYNC)) == PARSEB_NOSYNC)
+#define PARSE_SYNC(x) (((x) & (PARSEB_POWERUP|PARSEB_NOSYNC)) == 0)
+#define PARSE_ANNOUNCE(x) ((x) & PARSEB_ANNOUNCE)
+#define PARSE_DST(x) ((x) & PARSEB_DST)
#define PARSE_UTC(x) ((x) & PARSEB_UTC)
-#define PARSE_LEAP(x) (PARSE_SYNC(x) && ((x) & PARSEB_LEAP))
+#define PARSE_LEAPADD(x) (PARSE_SYNC(x) && (((x) & PARSEB_LEAPS) == PARSEB_LEAPADD))
+#define PARSE_LEAPDEL(x) (PARSE_SYNC(x) && (((x) & PARSEB_LEAPS) == PARSEB_LEAPDEL))
#define PARSE_ALTERNATE(x) ((x) & PARSEB_ALTERNATE)
#define PARSE_LEAPSECOND(x) (PARSE_SYNC(x) && ((x) & PARSEB_LEAP_SECOND))
@@ -118,9 +138,9 @@ extern int debug;
#define PARSE_S_PPS(x) ((x) & PARSEB_S_PPS)
#define PARSE_S_POSITION(x) ((x) & PARSEB_S_POSITION)
-#define PARSE_TIMECODE(x) ((x) & PARSEB_TIMECODE)
+#define PARSE_TIMECODE(x) ((x) & PARSEB_TIMECODE)
#define PARSE_PPS(x) ((x) & PARSEB_PPS)
-#define PARSE_POSITION(x) ((x) & PARSEB_POSITION)
+#define PARSE_POSITION(x) ((x) & PARSEB_POSITION)
/*
* operation flags - some are also fudge flags
@@ -281,6 +301,7 @@ struct clocktime /* clock time broken up from time code */
LONG second;
LONG usecond;
LONG utcoffset; /* in seconds */
+ time_t utctime; /* the actual time - alternative to date/time */
LONG flags; /* current clock status */
};
@@ -365,6 +386,9 @@ extern unsigned LONG pps_simple P((parse_t *, int status, timestamp_t *));
* History:
*
* parse.h,v
+ * Revision 3.17 1994/03/03 09:27:20 kardel
+ * rcs ids fixed
+ *
* Revision 3.13 1994/01/25 19:04:21 kardel
* 94/01/23 reconcilation
*
diff --git a/contrib/xntpd/kernel/.keep_me b/contrib/xntpd/kernel/.keep_me
deleted file mode 100644
index e69de29bb2d1..000000000000
--- a/contrib/xntpd/kernel/.keep_me
+++ /dev/null
diff --git a/contrib/xntpd/lib/Makefile b/contrib/xntpd/lib/Makefile
index dcb4f091f82c..b6c00416c159 100644
--- a/contrib/xntpd/lib/Makefile
+++ b/contrib/xntpd/lib/Makefile
@@ -1,5 +1,5 @@
#
-# $Id: Makefile,v 1.4 1993/12/22 11:32:23 rgrimes Exp $
+# $Id: Makefile,v 1.5 1994/04/03 20:37:05 wollman Exp $
#
CFLAGS+= -I${.CURDIR}/../include
@@ -10,7 +10,7 @@ SRCS= atoint.c atolfp.c atouint.c auth12crypt.c authdecrypt.c authdes.c \
clocktime.c dofptoa.c dolfptoa.c emalloc.c fptoa.c fptoms.c \
gettstamp.c hextoint.c hextolfp.c humandate.c inttoa.c \
lib_strbuf.c mfptoa.c mfptoms.c modetoa.c mstolfp.c \
- msutotsf.c numtoa.c refnumtoa.c numtohost.c octtoint.c \
+ msutotsf.c netof.c numtoa.c refnumtoa.c numtohost.c octtoint.c \
prettydate.c ranny.c tsftomsu.c tstotv.c tvtoa.c tvtots.c \
uglydate.c uinttoa.c utvtoa.c clocktypes.c \
md5.c a_md5encrypt.c a_md5decrypt.c \
diff --git a/contrib/xntpd/lib/clocktypes.c b/contrib/xntpd/lib/clocktypes.c
index 2701e3f1d0ef..816ef0708b3e 100644
--- a/contrib/xntpd/lib/clocktypes.c
+++ b/contrib/xntpd/lib/clocktypes.c
@@ -11,7 +11,7 @@
struct clktype clktypes[] = {
{ REFCLK_NONE, "unspecified type (0)", "UNKNOWN" },
{ REFCLK_LOCALCLOCK, "local clock synchronization (1)", "LOCAL" },
- { REFCLK_WWV_HEATH, "Heathkit WWV clock (2)", "WWV_HEATH" },
+ { REFCLK_GPS_TRAK, "TRAK 8810 GPS Receiver (2)", "GPS_TRAK" },
{ REFCLK_WWV_PST, "Precision Standard Time WWV clock (3)", "WWV_PST" },
{ REFCLK_WWVB_SPECTRACOM, "Spectracom WWVB clock (4)", "WWVB_SPEC" },
{ REFCLK_GOES_TRUETIME, "True Time GPS/GOES clock (5)", "GPS_GOES_TRUE" },
diff --git a/contrib/xntpd/lib/netof.c b/contrib/xntpd/lib/netof.c
new file mode 100644
index 000000000000..286a5846eb40
--- /dev/null
+++ b/contrib/xntpd/lib/netof.c
@@ -0,0 +1,25 @@
+/*
+ * netof - return the net address part of an ip address
+ * (zero out host part)
+ */
+#include <stdio.h>
+
+#include "ntp_fp.h"
+#include "ntp_stdlib.h"
+
+U_LONG
+netof(num)
+ U_LONG num;
+{
+ register U_LONG netnum;
+
+ netnum = num;
+
+ if(IN_CLASSC(netnum))
+ netnum &= IN_CLASSC_NET;
+ else if (IN_CLASSB(netnum))
+ netnum &= IN_CLASSB_NET;
+ else /* treat als other like class A */
+ netnum &= IN_CLASSA_NET;
+ return netnum;
+}
diff --git a/contrib/xntpd/lib/numtohost.c b/contrib/xntpd/lib/numtohost.c
index e22b6231790a..2f07c2c4dac5 100644
--- a/contrib/xntpd/lib/numtohost.c
+++ b/contrib/xntpd/lib/numtohost.c
@@ -1,12 +1,11 @@
-/* numtohost.c,v 3.1 1993/07/06 01:08:40 jbj Exp
+/*
* numtohost - convert network number to host name.
*/
-#include "ntp_types.h"
#include <netdb.h>
#include "ntp_fp.h"
-#include "lib_strbuf.h"
#include "ntp_stdlib.h"
+#include "lib_strbuf.h"
#define LOOPBACKNET 0x7f000000
#define LOOPBACKHOST 0x7f000001
diff --git a/contrib/xntpd/lib/systime.c b/contrib/xntpd/lib/systime.c
index ea15734f1abb..1d6c59a5d969 100644
--- a/contrib/xntpd/lib/systime.c
+++ b/contrib/xntpd/lib/systime.c
@@ -47,12 +47,13 @@ extern int debug;
* We also remember the clock precision we computed from the kernel in
* case someone asks us.
*/
+ LONG sys_clock;
+
LONG adj_precision; /* adj precision in usec (tickadj) */
LONG tvu_maxslew; /* maximum adjust doable in 1<<CLOCK_ADJ sec (usec) */
U_LONG tsf_maxslew; /* same as above, as LONG format */
- LONG sys_clock;
l_fp sys_clock_offset; /* correction for current system time */
/*
diff --git a/contrib/xntpd/machines/.keep_me b/contrib/xntpd/machines/.keep_me
deleted file mode 100644
index e69de29bb2d1..000000000000
--- a/contrib/xntpd/machines/.keep_me
+++ /dev/null
diff --git a/contrib/xntpd/ntpdate/ntpdate.h b/contrib/xntpd/ntpdate/ntpdate.h
index 4a8ff746e772..f6d3ebf877f3 100644
--- a/contrib/xntpd/ntpdate/ntpdate.h
+++ b/contrib/xntpd/ntpdate/ntpdate.h
@@ -54,7 +54,11 @@ struct server {
* are close, or step the time if the times are farther apart. The
* following defines what is "close".
*/
+#ifdef linux
+#define NTPDATE_THRESHOLD (FP_SECOND / 8) /* 1/8 second */
+#else
#define NTPDATE_THRESHOLD (FP_SECOND >> 1) /* 1/2 second */
+#endif
/*
* When doing adjustments, ntpdate actually overadjusts (currently
diff --git a/contrib/xntpd/ntpq/ntpq.c b/contrib/xntpd/ntpq/ntpq.c
index 5cfc3daff820..73c2a351aa70 100644
--- a/contrib/xntpd/ntpq/ntpq.c
+++ b/contrib/xntpd/ntpq/ntpq.c
@@ -75,6 +75,7 @@ int jump = 0;
#define OC 12 /* integer, print in octal */
#define MD 13 /* mode */
#define AR 14 /* array of times */
+#define TST 15 /* test flags */
#define EOV 255 /* end of table */
@@ -145,7 +146,7 @@ struct ctl_var peer_var[] = {
{ CP_RECEIVED, UI, "received" }, /* 31 */
{ CP_SENT, UI, "sent" }, /* 32 */
{ CP_FILTERROR, AR, "filterror" }, /* 33 */
- { CP_FLASH, ST, "flash"}, /* 34 */
+ { CP_FLASH, TST, "flash"}, /* 34 */
{ CP_DISP, AR, "disp" }, /* 35 */
/*
* These are duplicate entires so that we can
@@ -189,6 +190,20 @@ struct codestring {
};
/*
+ * flasher bits
+ */
+static char *tstflagnames[] = {
+ "DUPLICATE PKT",
+ "BOGUS PKT",
+ "PROTO UNSYNC",
+ "PEER BOUNDS",
+ "BAD AUTH",
+ "PEER CLOCK UNSYNC",
+ "BAD STRATUM",
+ "ROOT BOUNDS"
+};
+
+/*
* Leap values
*/
struct codestring leap_codes[] = {
@@ -301,7 +316,7 @@ static int decodereach P((char *, U_LONG *));
static int decodearr P((char *, int *, l_fp *));
static char * getcode P((int, struct codestring *));
static void help P((struct parse *, FILE *));
-#if defined(sgi) || defined(SYS_BSDI)
+#if defined(sgi) || defined(SYS_BSDI) || defined(__STDC__)
static int helpsort P((const void *, const void *));
#else
static int helpsort P((char **, char **));
@@ -335,7 +350,7 @@ static void output P((FILE *, char *, char *));
static void endoutput P((FILE *));
static void outputarr P((FILE *, char *, int, l_fp *));
static void cookedprint P((int, int, char *, int, FILE *));
-#if defined(sgi) || defined(SYS_BSDI)
+#if defined(sgi) || defined(SYS_BSDI) || defined(__STDC__)
static int assoccmp P((const void *, const void *));
#else
static int assoccmp P((struct association *, struct association *));
@@ -1888,7 +1903,7 @@ help(pcmd, fp)
for (xcp = opcmds; xcp->keyword != 0; xcp++)
cmdsort[n++] = xcp->keyword;
-#if defined(sgi) || defined(SYS_BSDI)
+#if defined(sgi) || defined(SYS_BSDI) || defined(__STDC__)
qsort((void *)cmdsort, n, sizeof(char *), helpsort);
#else
qsort((char *)cmdsort, n, sizeof(char *), helpsort);
@@ -1934,7 +1949,7 @@ help(pcmd, fp)
* helpsort - do hostname qsort comparisons
*/
static int
-#if defined(sgi) || defined(SYS_BSDI)
+#if defined(sgi) || defined(SYS_BSDI) || defined(__STDC__)
helpsort(t1, t2)
const void *t1;
const void *t2;
@@ -2836,7 +2851,45 @@ outputarr(fp, name, narr, lfp)
output(fp, name, buf);
}
-
+static char *
+tstflags(val)
+ U_LONG val;
+{
+ register char *cb, *s;
+ register int i;
+ register char *sep;
+
+ sep = "";
+ i = 0;
+ s = cb = &circ_buf[nextcb][0];
+ if (++nextcb >= NUMCB)
+ nextcb = 0;
+
+ sprintf(cb, "0x%x", val);
+ cb += strlen(cb);
+ if (val <= ((1<<8)-1)) {
+ if (!val) {
+ strcat(cb, "<OK>");
+ cb += strlen(cb);
+ } else {
+ *cb++ = '<';
+ while (val) {
+ if (val & 0x1) {
+ sprintf(cb, "%s%s", sep, tstflagnames[i]);
+ sep = ";";
+ cb += strlen(cb);
+ }
+ i++;
+ val >>= 1;
+ }
+ *cb++ = '>';
+ }
+ } else {
+ *cb++ = '?';
+ }
+ *cb = '\0';
+ return s;
+}
/*
* cookedprint - output variables in cooked mode
@@ -2994,6 +3047,13 @@ cookedprint(datatype, length, data, status, fp)
outputarr(fp, name, narr, lfparr);
break;
+ case TST:
+ if (!decodeuint(value, &uval))
+ output_raw = '?';
+ else
+ output(fp, name, tstflags(uval));
+ break;
+
default:
(void) fprintf(stderr,
"Internal error in cookedprint, %s=%s, fmt %d\n",
@@ -3028,7 +3088,7 @@ void
sortassoc()
{
if (numassoc > 1)
-#if defined(sgi) || defined(SYS_BSDI)
+#if defined(sgi) || defined(SYS_BSDI) || defined(__STDC__)
qsort((void *)assoc_cache, numassoc,
sizeof(struct association), assoccmp);
#else
@@ -3042,7 +3102,7 @@ sortassoc()
* assoccmp - compare two associations
*/
static int
-#if defined(sgi) || defined(SYS_BSDI)
+#if defined(sgi) || defined(SYS_BSDI) || defined(__STDC__)
assoccmp(t1, t2)
const void *t1;
const void *t2;
diff --git a/contrib/xntpd/parse/README.new_clocks b/contrib/xntpd/parse/README.new_clocks
new file mode 100644
index 000000000000..8fdd7cbd4250
--- /dev/null
+++ b/contrib/xntpd/parse/README.new_clocks
@@ -0,0 +1,212 @@
+Here is an attempt to sketch out what you need to do in order to
+add another clock to the parse driver:
+
+Prerequisites:
+- Does the system you want the clock connect to have
+ termio.h or termios.h ? (You need that for the parse driver)
+
+What to do:
+
+Make a conversion module (parse/clk_*.c)
+
+- What ist the time code format ?
+ - find year, month, day, hour, minute, second, status (synchronised or
+ not), possibly time zone information (you need to give the offset to UTC)
+ You will have to convert the data from a string into a struct clocktime:
+ struct clocktime /* clock time broken up from time code */
+ {
+ LONG day;
+ LONG month;
+ LONG year;
+ LONG hour;
+ LONG minute;
+ LONG second;
+ LONG usecond;
+ LONG utcoffset; /* in seconds */
+ time_t utcoffset; /* true utc time instead of date/time */
+ LONG flags; /* current clock status */
+ };
+
+ Conversion is usually simple and straight forward. For the flags following
+ values can be OR'ed together:
+
+ PARSEB_ANNOUNCE switch time zone warning (informational only)
+ PARSEB_POWERUP no synchronisation - clock confused (must set then)
+ PARSEB_NOSYNC timecode currently not confirmed (must set then)
+ usually on reception error when there is still a
+ chance the the generated time is still ok.
+
+ PARSEB_DST DST in effect (informational only)
+ PARSEB_UTC timecode contains UTC time (informational only)
+ PARSEB_LEAPADD LEAP addition warning (prior to leap happening - must set when imminent)
+ also used for time code that do not encode the
+ direction (as this is currently the default).
+ PARSEB_LEAPDEL LEAP deletion warning (prior to leap happening - must set when imminent)
+ PARSEB_ALTERNATE backup transmitter (informational only)
+ PARSEB_POSITION geographic position available (informational only)
+ PARSEB_LEAPSECOND actual leap second (this time code is the leap
+ second - informational only)
+
+ These are feature flags denoting items that are supported by the clock:
+ PARSEB_S_LEAP supports LEAP - might set PARSEB_LEAP
+ PARSEB_S_ANTENNA supports ANTENNA - might set PARSEB_ALTERNATE
+ PARSEB_S_PPS supports PPS time stamping
+ PARSEB_S_POSITION supports position information (GPS)
+
+ If the utctime field is non zero this value will be take as
+ time code value. This allows for conversion routines that
+ already have the utc time value. The utctime field gives the seconds
+ since Jan 1st 1970, 0:00:00. The useconds field gives the respective
+ usec value. The fields for date and time (down to second resolution)
+ will be ignored.
+
+ Conversion is done in the cvt_* routine in parse/clk_*.c files. look in
+ them for examples. The basic structure is:
+
+ struct clockformat <yourclock>_format = {
+ lots of fields for you to fill out (see below)
+ };
+
+ static cvt_<yourclock>()
+ ...
+ {
+ if (<I do not recognize my time code>) {
+ return CVT_NONE;
+ } else {
+ if (<conversion into clockformat is ok>) {
+ <set all necessary flags>;
+ return CVT_OK;
+ } else {
+ return CVT_FAIL|CVT_BADFMT;
+ }
+ }
+
+ The struct clockformat is the interface to the rest of the parse
+ driver - it holds all information necessary for finding the
+ clock message and doing the appropriate time stamping.
+
+struct clockformat
+{
+ unsigned LONG (*convert)();
+ /* conversion routine - your routine - cvt_<yourclock> */
+ void (*syncevt)();
+ /* routine for handling RS232 sync events (time stamps) - usually sync_simple */
+ unsigned LONG (*syncpps)();
+ /* PPS input routine - usually pps_simple */
+ unsigned LONG (*synth)();
+ /* time code synthesizer - usually not used - (LONG (*)())0 */
+ void *data;
+ /* local parameters - any parameters/data/configuration info your conversion
+ routine might need */
+ char *name;
+ /* clock format name - Name of the time code */
+ unsigned short length;
+ /* maximum length of data packet for your clock format */
+ unsigned LONG flags;
+ /* information for the parser what to look for */
+ struct timeval timeout;
+ /* buffer restart after timeout (us) - some clocks preceede new data by
+ a longer period of silence - unsually not used */
+ unsigned char startsym;
+ /* start symbol - character at the beginning of the clock data */
+ unsigned char endsym;
+ /* end symbol - character at the end of the clock data */
+ unsigned char syncsym;
+ /* sync symbol - character that is "on time" - where the time stamp should be taken */
+};
+
+ The flags:
+ F_START use startsym to find the beginning of the clock data
+ F_END use endsym to find the end of the clock data
+ SYNC_TIMEOUT packet restart after timeout in timeout field
+ SYNC_START packet start is sync event (time stamp at paket start)
+ SYNC_END packet end is sync event (time stamp at paket end)
+ SYNC_CHAR special character (syncsym) is sync event
+ SYNC_ONE PPS synchronize on 'ONE' transition
+ SYNC_ZERO PPS synchronize on 'ZERO' transition
+ SYNC_SYNTHESIZE generate intermediate time stamps (very special case!)
+ CVT_FIXEDONLY convert only in fixed configuration - (data format not
+ suitable for auto-configuration)
+
+
+ The above should have given you some hints on how to build a clk_*.c
+ file with the time code conversion. See the examples and pick a clock
+ closest to yours and tweak the code to match your clock.
+
+ In order to make your clk_*.c file usable a reference to the clockformat
+ structure must be put into parse_conf.c.
+
+TTY setup and initialisation/configuration will be done in
+xntpd/refclock_parse.c
+
+- Find out the exact tty settings for your clock (baud rate, parity,
+ stop bits, character size, ...) and note them in terms of
+ termio*.h c_cflag macros.
+
+- in xntpd/refclock_parse.c fill out a new the struct clockinfo element
+ (that allocates a new "IP" address - see comments)
+ (see all the other clocks for example)
+ struct clockinfo
+ {
+ U_LONG cl_flags; /* operation flags (io modes) */
+ PARSE_F_NOPOLLONLY always do async io - read whenever input comes
+ PARSE_F_POLLONLY never do async io - only read when expecting data
+ PARSE_F_PPSPPS use loopfilter PPS code (CIOGETEV)
+ PARSE_F_PPSONSECOND PPS pulses are on second
+ usually flags stay 0 as they are used only for special setups
+
+ void (*cl_poll)(); /* active poll routine */
+ The routine to call when the clock needs data sent to it in order to
+ get a time code from the clock (e.g. Trimble clock)
+ int (*cl_init)(); /* active poll init routine */
+ The routine to call for very special initializations.
+ void (*cl_end)(); /* active poll end routine */
+ The routine to call to undo any special initialisation (free memory/timers)
+ void *cl_data; /* local data area for "poll" mechanism */
+ local data for polling routines
+ u_fp cl_rootdelay; /* rootdelay */
+ NTP rottdelay estimate (usually 0)
+ U_LONG cl_basedelay; /* current offset - unsigned l_fp fractional par
+ time (fraction) by which the RS232 time code is delayed from the actual time.
+ t */
+ U_LONG cl_ppsdelay; /* current PPS offset - unsigned l_fp fractional
+ time (fraction) by which the PPS time stamp is delayed (usually 0)
+ part */
+ char *cl_id; /* ID code (usually "DCF") */
+ Refclock id - (max 4 chars)
+ char *cl_description; /* device name */
+ Name of this device.
+ char *cl_format; /* fixed format */
+ If the data format cann not ne detected automatically this is the name
+ as in clk_*.c clockformat.
+ u_char cl_type; /* clock type (ntp control) */
+ Type if clock as in clock status word (ntp control messages) - usually 0
+ U_LONG cl_maxunsync; /* time to trust oscillator after loosing synch
+ */
+ seconds a clock can be trusted after loosing synchronisation.
+
+ U_LONG cl_cflag; /* terminal io flags */
+ U_LONG cl_iflag; /* terminal io flags */
+ U_LONG cl_oflag; /* terminal io flags */
+ U_LONG cl_lflag; /* terminal io flags */
+ termio*.h tty modes.
+ } clockinfo[] = {
+ ...,<other clocks>,...
+ { < your parameters> },
+ };
+
+
+Well, this is very sketchy, i know. But I hope it helps a little bit.
+The best way is to look which clock comes closest to your and tweak that
+code.
+Two sorts of clocks are used with parse. Clocks that automatically send
+their time code (once a second) do not need entries in the poll routines because
+they send the data all the time. The second sort are the clocks that need a
+command sent to them in order to reply with a time code (like the Trimble
+clock).
+
+For questions: kardel@informatik.uni-erlangen.de. Please include
+an exact description on how your clock works. (initialisation,
+TTY modes, strings to be sent to it, responses received from the clock).
+
+Frank Kardel
diff --git a/contrib/xntpd/parse/README.parse_clocks b/contrib/xntpd/parse/README.parse_clocks
new file mode 100644
index 000000000000..cf8d77eb76bb
--- /dev/null
+++ b/contrib/xntpd/parse/README.parse_clocks
@@ -0,0 +1,263 @@
+The parse driver currently supports several clocks with different
+query mechanisms. In order for you to find a sample that might be
+similar to a clock you might want to integrate into parse i'll sum
+up the major features of the clocks (this information is distributed
+in the parse/clk_*.c and xntpd/refclock_parse.c files).
+
+---
+ Meinberg: 127.127.8. 0- 3 (PZF535TCXO)
+ 127.127.8. 4- 7 (PZF535OCXO)
+ 127.127.8. 8-11 (DCFUA31)
+ 127.127.8.28-31 (GPS166)
+ Meinberg: start=<STX>, end=<ETX>, sync on start
+ pattern="\2D: . . ;T: ;U: . . ; \3"
+ pattern="\2 . . ; ; : : ; \3"
+ pattern="\2 . . ; ; : : ; : ; ; . . "
+
+ Meinberg is a german manufacturer of time code receivers. Those clocks
+ have a pretty common output format in the stock version. In order to
+ support NTP Meinberg was so kind to produce some special versions of
+ the firmware for the use with NTP. So, if you are going to use a
+ Meinberg clock please ask whether there is a special Uni Erlangen
+ version.
+
+ General characteristics:
+ Meinberg clocks primarily output pulse per second and a describing
+ ASCII string. This string can be produced in two modes. either upon
+ the reception of a question mark or every second. NTP uses the latter
+ mechanism. The DCF77 variants have a pretty good relationship between
+ RS232 time code and the PPS signal while the GPS receiver has no fixed
+ timeing between the datagram and the pulse (you need to use PPS with
+ GPS!) on DCF77 you might get away without the PPS signal.
+
+ The preferred tty setting for Meinberg is:
+ CFLAG (B9600|CS7|PARENB|CREAD|HUPCL)
+ IFLAG (IGNBRK|IGNPAR|ISTRIP)
+ OFLAG 0
+ LFLAG 0
+
+ The clock is run at datagram once per second.
+ Stock dataformat is:
+
+ <STX>D:<dd>.<mm>.<yy>;T:<w>;U:<hh>:<mm>:<ss>;<S><F><D><A><ETX>
+ pos: 0 00 00 0 00 0 11 111 1 111 12 2 22 2 22 2 2 2 3 3 3
+ 1 23 45 6 78 9 01 234 5 678 90 1 23 4 56 7 8 9 0 1 2
+
+ <STX> = '\002' ASCII start of text
+ <ETX> = '\003' ASCII end of text
+ <dd>,<mm>,<yy> = day, month, year(2 digits!!)
+ <w> = day of week (sunday= 0)
+ <hh>,<mm>,<ss> = hour, minute, second
+ <S> = '#' if never synced since powerup else ' ' for DCF U/A 31
+ '#' if not PZF sychronisation available else ' ' for PZF 535
+ <F> = '*' if time comes from internal quartz else ' '
+ <D> = 'S' if daylight saving time is active else ' '
+ <A> = '!' during the hour preceeding an daylight saving time
+ start/end change
+
+ For the university of Erlangen a special format was implemented to support
+ LEAP announcement and anouncement of alternate antenna.
+
+ Version for UNI-ERLANGEN Software is: PZFUERL V4.6 (Meinberg)
+
+ The use of this software release (or higher) is *ABSOLUTELY*
+ recommended (ask for PZFUERL version as some minor HW fixes have
+ been introduced) due to the LEAP second support and UTC indication.
+ The standard timecode does not indicate when the timecode is in
+ UTC (by front panel configuration) thus we have no chance to find
+ the correct utc offset. For the standard format do not ever use
+ UTC display as this is not detectable in the time code !!!
+
+ <STX><dd>.<mm>.<yy>; <w>; <hh>:<mm>:<ss>; <U><S><F><D><A><L><R><ETX>
+ pos: 0 00 0 00 0 00 11 1 11 11 1 11 2 22 22 2 2 2 2 2 3 3 3
+ 1 23 4 56 7 89 01 2 34 56 7 89 0 12 34 5 6 7 8 9 0 1 2
+ <STX> = '\002' ASCII start of text
+ <ETX> = '\003' ASCII end of text
+ <dd>,<mm>,<yy> = day, month, year(2 digits!!)
+ <w> = day of week (sunday= 0)
+ <hh>,<mm>,<ss> = hour, minute, second
+ <U> = 'U' UTC time display
+ <S> = '#' if never synced since powerup else ' ' for DCF U/A 31
+ '#' if not PZF sychronisation available else ' ' for PZF 535
+ <F> = '*' if time comes from internal quartz else ' '
+ <D> = 'S' if daylight saving time is active else ' '
+ <A> = '!' during the hour preceeding an daylight saving time
+ start/end change
+ <L> = 'A' LEAP second announcement
+ <R> = 'R' alternate antenna
+
+ Meinberg GPS166 receiver
+
+ You must get the Uni-Erlangen firmware for the GPS receiver support
+ to work to full satisfaction !
+
+ <STX><dd>.<mm>.<yy>; <w>; <hh>:<mm>:<ss>; <+/-><00:00>; <U><S><F><D><A><L><R><L>; <position...><ETX>
+ *
+ 000000000111111111122222222223333333333444444444455555555556666666
+ 123456789012345678901234567890123456789012345678901234567890123456
+ \x0209.07.93; 5; 08:48:26; +00:00; ; 49.5736N 11.0280E 373m\x03
+ *
+
+ <STX> = '\002' ASCII start of text
+ <ETX> = '\003' ASCII end of text
+ <dd>,<mm>,<yy> = day, month, year(2 digits!!)
+ <w> = day of week (sunday= 0)
+ <hh>,<mm>,<ss> = hour, minute, second
+ <+/->,<00:00> = offset to UTC
+ <S> = '#' if never synced since powerup else ' ' for DCF U/A 31
+ '#' if not PZF sychronisation available else ' ' for PZF 535
+ <U> = 'U' UTC time display
+ <F> = '*' if time comes from internal quartz else ' '
+ <D> = 'S' if daylight saving time is active else ' '
+ <A> = '!' during the hour preceeding an daylight saving time
+ start/end change
+ <L> = 'A' LEAP second announcement
+ <R> = 'R' alternate antenna (reminiscent of PZF535) usually ' '
+ <L> = 'L' on 23:59:60
+
+
+ For the Meinberg parse look into clock_meinberg.c
+
+---
+ RAWDCF: 127.127.8.20-23 (Conrad receiver module - delay 210ms)
+ 127.127.8.24-27 (FAU receiver - delay 258ms)
+ RAWDCF: end=TIMEOUT>1.5s, sync each char (any char),generate psuedo time
+ codes, fixed format
+
+ direct DCF77 code input
+ In Europe it is relatively easy/cheap the receive the german time code
+ transmitter DCF77. The simplest version to process its signal is to
+ feed the 100/200ms pulse of the demodulated AM signal via a level
+ converter to an RS232 port at 50Baud. parse/clk_rawdcf.c holds all
+ necessary decoding logic for the time code which is transmitted each
+ minute for one minute. A bit of the time code is sent once a second.
+
+ The preferred tty setting is:
+ CFLAG (B50|CS8|CREAD|CLOCAL)
+ IFLAG 0
+ OFLAG 0
+ LFLAG 0
+
+ DCF77 raw time code
+
+ From "Zur Zeit", Physikalisch-Technische Bundesanstalt (PTB), Braunschweig
+ und Berlin, Maerz 1989
+
+ Timecode transmission:
+ AM:
+ time marks are send every second except for the second before the
+ next minute mark
+ time marks consist of a reduction of transmitter power to 25%
+ of the nominal level
+ the falling edge is the time indication (on time)
+ time marks of a 100ms duration constitute a logical 0
+ time marks of a 200ms duration constitute a logical 1
+ FM:
+ see the spec. (basically a (non-)inverted psuedo random phase shift)
+
+ Encoding:
+ Second Contents
+ 0 - 10 AM: free, FM: 0
+ 11 - 14 free
+ 15 R - alternate antenna
+ 16 A1 - expect zone change (1 hour before)
+ 17 - 18 Z1,Z2 - time zone
+ 0 0 illegal
+ 0 1 MEZ (MET)
+ 1 0 MESZ (MED, MET DST)
+ 1 1 illegal
+ 19 A2 - expect leap insertion/deletion (1 hour before)
+ 20 S - start of time code (1)
+ 21 - 24 M1 - BCD (lsb first) Minutes
+ 25 - 27 M10 - BCD (lsb first) 10 Minutes
+ 28 P1 - Minute Parity (even)
+ 29 - 32 H1 - BCD (lsb first) Hours
+ 33 - 34 H10 - BCD (lsb first) 10 Hours
+ 35 P2 - Hour Parity (even)
+ 36 - 39 D1 - BCD (lsb first) Days
+ 40 - 41 D10 - BCD (lsb first) 10 Days
+ 42 - 44 DW - BCD (lsb first) day of week (1: Monday -> 7: Sunday)
+ 45 - 49 MO - BCD (lsb first) Month
+ 50 MO0 - 10 Months
+ 51 - 53 Y1 - BCD (lsb first) Years
+ 54 - 57 Y10 - BCD (lsb first) 10 Years
+ 58 P3 - Date Parity (even)
+ 59 - usually missing (minute indication), except for leap insertion
+
+---
+ Schmid clock: 127.127.8.16-19
+ Schmid clock: needs poll, binary input, end='\xFC', sync start
+
+ The Schmid clock is a DCF77 receiver that sends a binary
+ time code at the reception of a flag byte. The contents
+ if the flag byte determined the time code format. The
+ binary time code is delimited by the byte 0xFC.
+
+ TTY setup is:
+ CFLAG (B1200|CS8|CREAD|CLOCAL)
+ IFLAG 0
+ OFLAG 0
+ LFLAG 0
+
+ The command to Schmid's DCF77 clock is a single byte; each bit
+ allows the user to select some part of the time string, as follows (the
+ output for the lsb is sent first).
+
+ Bit 0: time in MEZ, 4 bytes *binary, not BCD*; hh.mm.ss.tenths
+ Bit 1: date 3 bytes *binary, not BCD: dd.mm.yy
+ Bit 2: week day, 1 byte (unused here)
+ Bit 3: time zone, 1 byte, 0=MET, 1=MEST. (unused here)
+ Bit 4: clock status, 1 byte, 0=time invalid,
+ 1=time from crystal backup,
+ 3=time from DCF77
+ Bit 5: transmitter status, 1 byte,
+ bit 0: backup antenna
+ bit 1: time zone change within 1h
+ bit 3,2: TZ 01=MEST, 10=MET
+ bit 4: leap second will be
+ added within one hour
+ bits 5-7: Zero
+ Bit 6: time in backup mode, units of 5 minutes (unused here)
+
+
+---
+ Trimble SV6: 127.127.8.32-35
+ Trimble SV6: needs poll, ascii timecode, start='>', end='<',
+ query='>QTM<', eol='<'
+
+ Trimble SV6 is a GPS receiver with PPS output. It needs to be polled.
+ It also need a special tty mode setup (EOL='<').
+
+ TTY setup is:
+ CFLAG (B4800|CS8|CREAD)
+ IFLAG (BRKINT|IGNPAR|ISTRIP|ICRNL|IXON)
+ OFLAG (OPOST|ONLCR)
+ LFLAG (ICANON|ECHOK)
+
+ Special flags are:
+ PARSE_F_PPSPPS - use CIOGETEV for PPS time stamping
+ PARSE_F_PPSONSECOND - the time code is not related to
+ the PPS pulse (so use the time code
+ only for the second epoch)
+
+ Timecode
+ 0000000000111111111122222222223333333 / char
+ 0123456789012345678901234567890123456 \ posn
+ >RTMhhmmssdddDDMMYYYYoodnnvrrrrr;*xx< Actual
+ ----33445566600112222BB7__-_____--99- Parse
+ >RTM 1 ;* <", Check
+
+---
+ ELV DCF7000: 127.127.8.12-15
+ ELV DCF7000: end='\r', pattern=" - - - - - - - \r"
+
+ The ELV DCF7000 is a cheap DCF77 receiver sending each second
+ a time code (though not very precise!) delimited by '`r'
+
+ Timecode
+ YY-MM-DD-HH-MM-SS-FF\r
+
+ FF&0x1 - DST
+ FF&0x2 - DST switch warning
+ FF&0x4 - unsynchronised
+
diff --git a/contrib/xntpd/parse/clk_dcf7000.c b/contrib/xntpd/parse/clk_dcf7000.c
index 5655d0a017f0..8b55e2f23280 100644
--- a/contrib/xntpd/parse/clk_dcf7000.c
+++ b/contrib/xntpd/parse/clk_dcf7000.c
@@ -1,8 +1,8 @@
#if defined(REFCLOCK) && (defined(PARSE) || defined(PARSEPPS)) && defined(CLOCK_DCF7000)
/*
- * /src/NTP/REPOSITORY/v3/parse/clk_dcf7000.c,v 3.10 1994/01/25 19:05:07 kardel Exp
+ * /src/NTP/REPOSITORY/v3/parse/clk_dcf7000.c,v 3.11 1994/02/02 17:45:14 kardel Exp
*
- * clk_dcf7000.c,v 3.10 1994/01/25 19:05:07 kardel Exp
+ * clk_dcf7000.c,v 3.11 1994/02/02 17:45:14 kardel Exp
*
* ELV DCF7000 module
*
@@ -121,6 +121,9 @@ cvt_dcf7000(buffer, size, format, clock)
* History:
*
* clk_dcf7000.c,v
+ * Revision 3.11 1994/02/02 17:45:14 kardel
+ * rcs ids fixed
+ *
* Revision 3.6 1993/10/09 15:01:27 kardel
* file structure unified
*
diff --git a/contrib/xntpd/parse/clk_meinberg.c b/contrib/xntpd/parse/clk_meinberg.c
index b08dfec91152..69f88b90d30e 100644
--- a/contrib/xntpd/parse/clk_meinberg.c
+++ b/contrib/xntpd/parse/clk_meinberg.c
@@ -1,8 +1,8 @@
#if defined(REFCLOCK) && (defined(PARSE) || defined(PARSEPPS)) && defined(CLOCK_MEINBERG)
/*
- * /src/NTP/REPOSITORY/v3/parse/clk_meinberg.c,v 3.11 1994/01/25 19:05:10 kardel Exp
+ * /src/NTP/REPOSITORY/v3/parse/clk_meinberg.c,v 3.14 1994/02/20 13:04:37 kardel Exp
*
- * clk_meinberg.c,v 3.11 1994/01/25 19:05:10 kardel Exp
+ * clk_meinberg.c,v 3.14 1994/02/20 13:04:37 kardel Exp
*
* Meinberg clock support
*
@@ -284,8 +284,13 @@ cvt_meinberg(buffer, size, format, clock)
clock->flags |= PARSEB_S_LEAP;
clock->flags |= PARSEB_S_ANTENNA;
+ /*
+ * DCF77 does not encode the direction -
+ * so we take the current default -
+ * earth slowing down
+ */
if (f[4] == 'A')
- clock->flags |= PARSEB_LEAP;
+ clock->flags |= PARSEB_LEAPADD;
if (f[5] == 'R')
clock->flags |= PARSEB_ALTERNATE;
@@ -394,9 +399,12 @@ cvt_mgps(buffer, size, format, clock)
/*
* oncoming leap second
+ * data format does not (yet) specify whether
+ * to add or to delete a second - thus we
+ * pick the current default
*/
if (f[5] == 'A')
- clock->flags |= PARSEB_LEAP;
+ clock->flags |= PARSEB_LEAPADD;
/*
* this is the leap second
@@ -414,6 +422,12 @@ cvt_mgps(buffer, size, format, clock)
* History:
*
* clk_meinberg.c,v
+ * Revision 3.14 1994/02/20 13:04:37 kardel
+ * parse add/delete second support
+ *
+ * Revision 3.13 1994/02/02 17:45:21 kardel
+ * rcs ids fixed
+ *
* Revision 3.11 1994/01/25 19:05:10 kardel
* 94/01/23 reconcilation
*
diff --git a/contrib/xntpd/parse/clk_rawdcf.c b/contrib/xntpd/parse/clk_rawdcf.c
index 2fd3cae20b89..6b02031b6394 100644
--- a/contrib/xntpd/parse/clk_rawdcf.c
+++ b/contrib/xntpd/parse/clk_rawdcf.c
@@ -1,8 +1,8 @@
#if defined(REFCLOCK) && (defined(PARSE) || defined(PARSEPPS)) && defined(CLOCK_RAWDCF)
/*
- * /src/NTP/REPOSITORY/v3/parse/clk_rawdcf.c,v 3.9 1994/01/25 19:05:12 kardel Exp
+ * /src/NTP/REPOSITORY/v3/parse/clk_rawdcf.c,v 3.13 1994/03/10 19:00:43 kardel Exp
*
- * clk_rawdcf.c,v 3.9 1994/01/25 19:05:12 kardel Exp
+ * clk_rawdcf.c,v 3.13 1994/03/10 19:00:43 kardel Exp
*
* Raw DCF77 pulse clock support
*
@@ -245,6 +245,7 @@ static unsigned LONG convert_rawdcf(buffer, size, dcfparam, clock)
parseprintf(DD_RAWDCF,("parse: convert_rawdcf: parity check passed\n"));
clock->flags = PARSEB_S_ANTENNA|PARSEB_S_LEAP;
+ clock->utctime= 0;
clock->usecond= 0;
clock->second = 0;
clock->minute = ext_bf(buffer, DCF_M10, dcfparam->zerobits);
@@ -278,7 +279,7 @@ static unsigned LONG convert_rawdcf(buffer, size, dcfparam, clock)
clock->flags |= PARSEB_ANNOUNCE;
if (ext_bf(buffer, DCF_A2, dcfparam->zerobits))
- clock->flags |= PARSEB_LEAP;
+ clock->flags |= PARSEB_LEAPADD; /* default: DCF77 data format deficiency */
if (ext_bf(buffer, DCF_R, dcfparam->zerobits))
clock->flags |= PARSEB_ALTERNATE;
@@ -529,6 +530,15 @@ static unsigned LONG snt_rawdcf(parseio, ptime)
* History:
*
* clk_rawdcf.c,v
+ * Revision 3.13 1994/03/10 19:00:43 kardel
+ * clear utctime field to avoid confusion on synthesize time stamps
+ *
+ * Revision 3.12 1994/02/20 13:04:39 kardel
+ * parse add/delete second support
+ *
+ * Revision 3.11 1994/02/02 17:45:23 kardel
+ * rcs ids fixed
+ *
* Revision 3.9 1994/01/25 19:05:12 kardel
* 94/01/23 reconcilation
*
diff --git a/contrib/xntpd/parse/clk_schmid.c b/contrib/xntpd/parse/clk_schmid.c
index a8ec8a64b546..8129474782bb 100644
--- a/contrib/xntpd/parse/clk_schmid.c
+++ b/contrib/xntpd/parse/clk_schmid.c
@@ -1,8 +1,8 @@
#if defined(REFCLOCK) && (defined(PARSE) || defined(PARSEPPS)) && defined(CLOCK_SCHMID)
/*
- * /src/NTP/REPOSITORY/v3/parse/clk_schmid.c,v 3.10 1994/01/25 19:05:15 kardel Exp
+ * /src/NTP/REPOSITORY/v3/parse/clk_schmid.c,v 3.13 1994/02/20 13:04:41 kardel Exp
*
- * clk_schmid.c,v 3.10 1994/01/25 19:05:15 kardel Exp
+ * clk_schmid.c,v 3.13 1994/02/20 13:04:41 kardel Exp
*
* Schmid clock support
*
@@ -152,7 +152,7 @@ cvt_schmid(buffer, size, format, clock)
if (buffer[8] & WS_LEAP)
{
- clock->flags |= PARSEB_LEAP;
+ clock->flags |= PARSEB_LEAPADD; /* default: DCF77 data format deficiency */
}
}
@@ -168,6 +168,12 @@ cvt_schmid(buffer, size, format, clock)
* History:
*
* clk_schmid.c,v
+ * Revision 3.13 1994/02/20 13:04:41 kardel
+ * parse add/delete second support
+ *
+ * Revision 3.12 1994/02/02 17:45:25 kardel
+ * rcs ids fixed
+ *
* Revision 3.10 1994/01/25 19:05:15 kardel
* 94/01/23 reconcilation
*
diff --git a/contrib/xntpd/parse/clk_trimble.c b/contrib/xntpd/parse/clk_trimble.c
index bfbf1e6bc796..187aed52a4d7 100644
--- a/contrib/xntpd/parse/clk_trimble.c
+++ b/contrib/xntpd/parse/clk_trimble.c
@@ -1,6 +1,6 @@
#if defined(REFCLOCK) && (defined(PARSE) || defined(PARSEPPS)) && defined(CLOCK_TRIMSV6)
/*
- * /src/NTP/REPOSITORY/v3/parse/clk_trimble.c,v 3.7 1994/01/25 19:05:17 kardel Exp
+ * /src/NTP/REPOSITORY/v3/parse/clk_trimble.c,v 3.9 1994/02/02 17:45:27 kardel Exp
*
* Trimble SV6 clock support
*/
@@ -106,6 +106,9 @@ cvt_trimsv6(buffer, size, format, clock)
* History:
*
* clk_trimble.c,v
+ * Revision 3.9 1994/02/02 17:45:27 kardel
+ * rcs ids fixed
+ *
* Revision 3.7 1994/01/25 19:05:17 kardel
* 94/01/23 reconcilation
*
diff --git a/contrib/xntpd/parse/parse.c b/contrib/xntpd/parse/parse.c
index ed5fd9a8fad7..84bfa39d1293 100644
--- a/contrib/xntpd/parse/parse.c
+++ b/contrib/xntpd/parse/parse.c
@@ -1,8 +1,8 @@
#if defined(REFCLOCK) && (defined(PARSE) || defined(PARSEPPS))
/*
- * /src/NTP/REPOSITORY/v3/parse/parse.c,v 3.19 1994/01/25 19:05:20 kardel Exp
+ * /src/NTP/REPOSITORY/v3/parse/parse.c,v 3.23 1994/03/25 13:09:02 kardel Exp
*
- * parse.c,v 3.19 1994/01/25 19:05:20 kardel Exp
+ * parse.c,v 3.23 1994/03/25 13:09:02 kardel Exp
*
* Parser module for reference clock
*
@@ -29,6 +29,10 @@ static char rcsid[] = "parse.c,v 3.19 1994/01/25 19:05:20 kardel Exp";
#include "sys/time.h"
#include "sys/errno.h"
+#include "ntp_fp.h"
+#include "ntp_unixtime.h"
+#include "ntp_calendar.h"
+
#include "ntp_machine.h"
#if defined(PARSESTREAM) && (defined(SYS_SUNOS4) || defined(SYS_SOLARIS)) && defined(STREAM)
@@ -49,10 +53,6 @@ static char rcsid[] = "parse.c,v 3.19 1994/01/25 19:05:20 kardel Exp";
#endif
#endif
-#include "ntp_fp.h"
-#include "ntp_unixtime.h"
-#include "ntp_calendar.h"
-
#include "parse.h"
#include "ntp_stdlib.h"
@@ -178,6 +178,10 @@ setup_bitmaps(parseio, low, high)
{
fmt = clockformats[i];
+ if (!(parseio->parse_flags & PARSE_FIXED_FMT) &&
+ (fmt->flags & CVT_FIXEDONLY))
+ continue;
+
if (fmt->flags & F_START)
{
index = fmt->startsym / 8;
@@ -556,6 +560,9 @@ parse_to_unixtime(clock, cvtrtc)
register int i;
time_t t;
+ if (clock->utctime)
+ return clock->utctime; /* if the conversion routine gets it right away - why not */
+
if (clock->year < 100)
clock->year += 1900;
@@ -628,6 +635,9 @@ parse_to_unixtime(clock, cvtrtc)
t += clock->utcoffset; /* warp to UTC */
/* done */
+
+ clock->utctime = t; /* documentray only */
+
return t;
}
@@ -890,6 +900,8 @@ timepacket(parseio)
if (parseio->parse_flags & PARSE_FIXED_FMT)
{
+ clock.utctime = 0;
+
switch ((cvtrtc = clockformats[format]->convert ? clockformats[format]->convert(parseio->parse_data, parseio->parse_index, clockformats[format]->data, &clock) : CVT_NONE) & CVT_MASK)
{
case CVT_FAIL:
@@ -941,6 +953,8 @@ timepacket(parseio)
{
do
{
+ clock.utctime = 0;
+
switch ((cvtrtc = (clockformats[format]->convert && !(clockformats[format]->flags & CVT_FIXEDONLY)) ?
clockformats[format]->convert(parseio->parse_data, parseio->parse_index, clockformats[format]->data, &clock) :
CVT_NONE) & CVT_MASK)
@@ -1148,6 +1162,15 @@ parse_setcs(dct, parse)
* History:
*
* parse.c,v
+ * Revision 3.23 1994/03/25 13:09:02 kardel
+ * considering FIXEDONLY entries only in FIXEDONLY mode
+ *
+ * Revision 3.22 1994/02/25 12:34:49 kardel
+ * allow for converter generated utc times
+ *
+ * Revision 3.21 1994/02/02 17:45:30 kardel
+ * rcs ids fixed
+ *
* Revision 3.19 1994/01/25 19:05:20 kardel
* 94/01/23 reconcilation
*
diff --git a/contrib/xntpd/parse/parse_conf.c b/contrib/xntpd/parse/parse_conf.c
index 0281c9dd1071..238dd1234e66 100644
--- a/contrib/xntpd/parse/parse_conf.c
+++ b/contrib/xntpd/parse/parse_conf.c
@@ -1,8 +1,8 @@
#if defined(REFCLOCK) && (defined(PARSE) || defined(PARSEPPS))
/*
- * /src/NTP/REPOSITORY/v3/parse/parse_conf.c,v 3.13 1994/01/25 19:05:23 kardel Exp
+ * /src/NTP/REPOSITORY/v3/parse/parse_conf.c,v 3.15 1994/02/02 17:45:32 kardel Exp
*
- * parse_conf.c,v 3.13 1994/01/25 19:05:23 kardel Exp
+ * parse_conf.c,v 3.15 1994/02/02 17:45:32 kardel Exp
*
* Parser configuration module for reference clocks
*
@@ -81,6 +81,9 @@ unsigned short nformats = sizeof(clockformats) / sizeof(clockformats[0]) - 1;
* History:
*
* parse_conf.c,v
+ * Revision 3.15 1994/02/02 17:45:32 kardel
+ * rcs ids fixed
+ *
* Revision 3.13 1994/01/25 19:05:23 kardel
* 94/01/23 reconcilation
*
diff --git a/contrib/xntpd/parse/parsesolaris.c b/contrib/xntpd/parse/parsesolaris.c
index 09fac2861f0c..23bc252e8fce 100644
--- a/contrib/xntpd/parse/parsesolaris.c
+++ b/contrib/xntpd/parse/parsesolaris.c
@@ -1,7 +1,7 @@
/*
- * /src/NTP/REPOSITORY/v3/parse/parsesolaris.c,v 3.9 1994/01/25 19:05:26 kardel Exp
+ * /src/NTP/REPOSITORY/v3/parse/parsesolaris.c,v 3.15 1994/02/15 22:20:51 kardel Exp
*
- * parsesolaris.c,v 3.9 1994/01/25 19:05:26 kardel Exp
+ * parsesolaris.c,v 3.15 1994/02/15 22:20:51 kardel Exp
*
* STREAMS module for reference clocks
* (SunOS5.x - not fully tested - buyer beware ! - OS KILLERS may still be
@@ -19,7 +19,7 @@
*/
#ifndef lint
-static char rcsid[] = "parsesolaris.c,v 3.9 1994/01/25 19:05:26 kardel Exp";
+static char rcsid[] = "parsesolaris.c,v 3.15 1994/02/15 22:20:51 kardel Exp";
#endif
/*
@@ -65,7 +65,7 @@ static struct fmodsw fmod_templ =
{
"parse", /* module name */
&parseinfo, /* module information */
- 0, /* not clean yet */
+ D_NEW|D_MP|D_MTQPAIR, /* exclusive for q pair */
/* lock ptr */
};
@@ -139,7 +139,7 @@ int Strcmp(s, t)
/*ARGSUSED*/
int _init(void)
{
- static char revision[] = "3.9";
+ static char revision[] = "3.15";
char *s, *S, *t;
/*
@@ -413,6 +413,8 @@ static int parseopen(queue_t *q, dev_t *dev, int flag, int sflag, cred_t *credp)
parse->parse_ppsclockev.tv.tv_usec = 0;
parse->parse_ppsclockev.serial = 0;
+ qprocson(q);
+
parseprintf(DD_OPEN,("parse: OPEN - initializing io subsystem q=%x\n", q));
if (!parse_ioinit(&parse->parse_io))
@@ -420,6 +422,8 @@ static int parseopen(queue_t *q, dev_t *dev, int flag, int sflag, cred_t *credp)
/*
* ok guys - beat it
*/
+ qprocsoff(q);
+
kmem_free((caddr_t)parse, sizeof(parsestream_t));
parsebusy--;
@@ -441,7 +445,7 @@ static int parseopen(queue_t *q, dev_t *dev, int flag, int sflag, cred_t *credp)
*/
if (!notice)
{
- printf("%s: Copyright (c) 1991-1993, Frank Kardel\n", modlstrmod.strmod_linkinfo);
+ printf("%s: Copyright (c) 1991-1994, Frank Kardel\n", modlstrmod.strmod_linkinfo);
notice = 1;
}
@@ -449,7 +453,12 @@ static int parseopen(queue_t *q, dev_t *dev, int flag, int sflag, cred_t *credp)
}
else
{
+ qprocsoff(q);
+
+ kmem_free((caddr_t)parse, sizeof(parsestream_t));
+
parsebusy--;
+
return EIO;
}
}
@@ -462,6 +471,8 @@ static int parseclose(queue_t *q, int flags)
parseprintf(DD_CLOSE,("parse: CLOSE\n"));
+ qprocsoff(q);
+
s = splhigh();
if (parse->parse_dqueue)
@@ -1179,6 +1190,18 @@ static void zs_xsisr(struct zscom *zs)
* History:
*
* parsesolaris.c,v
+ * Revision 3.15 1994/02/15 22:20:51 kardel
+ * rcsid fixed
+ *
+ * Revision 3.14 1994/02/15 22:06:04 kardel
+ * added qprocsx & flags for MT capability
+ *
+ * Revision 3.13 1994/02/13 19:16:47 kardel
+ * updated verbose Copyright message
+ *
+ * Revision 3.12 1994/02/02 17:45:35 kardel
+ * rcs ids fixed
+ *
* Revision 3.9 1994/01/25 19:05:26 kardel
* 94/01/23 reconcilation
*
diff --git a/contrib/xntpd/parse/parsestreams.c b/contrib/xntpd/parse/parsestreams.c
index b371aedafcee..45d296337a69 100644
--- a/contrib/xntpd/parse/parsestreams.c
+++ b/contrib/xntpd/parse/parsestreams.c
@@ -1,7 +1,7 @@
/*
- * /src/NTP/REPOSITORY/v3/parse/parsestreams.c,v 3.12 1994/01/25 19:05:30 kardel Exp
+ * /src/NTP/REPOSITORY/v3/parse/parsestreams.c,v 3.19 1994/02/24 16:33:54 kardel Exp
*
- * parsestreams.c,v 3.12 1994/01/25 19:05:30 kardel Exp
+ * parsestreams.c,v 3.19 1994/02/24 16:33:54 kardel Exp
*
* STREAMS module for reference clocks
* (SunOS4.x)
@@ -16,7 +16,7 @@
*/
#ifndef lint
-static char rcsid[] = "parsestreams.c,v 3.12 1994/01/25 19:05:30 kardel Exp";
+static char rcsid[] = "parsestreams.c,v 3.19 1994/02/24 16:33:54 kardel Exp";
#endif
#include "sys/types.h"
@@ -195,7 +195,7 @@ int xxxinit(fc, vdp, vdi, vds)
}
else
{
- static char revision[] = "3.12";
+ static char revision[] = "3.19";
char *s, *S, *t;
strncpy(ifm->f_name, mname, FMNAMESZ);
@@ -527,7 +527,7 @@ static int parseopen(q, dev, flag, sflag)
*/
if (!notice)
{
- printf("%s: Copyright (c) 1991-1993, Frank Kardel\n", parsesync_vd.Drv_name);
+ printf("%s: Copyright (c) 1991-1994, Frank Kardel\n", parsesync_vd.Drv_name);
notice = 1;
}
@@ -535,6 +535,8 @@ static int parseopen(q, dev, flag, sflag)
}
else
{
+ kmem_free((caddr_t)parse, sizeof(parsestream_t));
+
#ifdef VDDRV
parsebusy--;
#endif
@@ -1074,6 +1076,11 @@ static void close_zs_linemon(q, my_q)
#define MAXDEPTH 50 /* maximum allowed stream crawl */
+#ifdef PPS_SYNC
+extern hardpps();
+extern struct timeval time;
+#endif
+
/*
* take external status interrupt (only CD interests us)
*/
@@ -1085,15 +1092,18 @@ static void zs_xsisr(zs)
register queue_t *q;
register unsigned char zsstatus;
register int loopcheck;
- register unsigned char cdstate;
register char *dname;
+#ifdef PPS_SYNC
+ register int s;
+ register long usec;
+#endif
/*
* pick up current state
*/
zsstatus = zsaddr->zscc_control;
- if (za->za_rr0 ^ (cdstate = zsstatus & ZSRR0_CD))
+ if ((za->za_rr0 ^ zsstatus) & (ZSRR0_CD|ZSRR0_SYNC))
{
timestamp_t cdevent;
register int status;
@@ -1101,26 +1111,44 @@ static void zs_xsisr(zs)
/*
* CONDITIONAL external measurement support
*/
- SET_LED(cdstate); /*
+ SET_LED(zsstatus & (ZSRR0_CD|ZSRR0_SYNC)); /*
* inconsistent with upper SET_LED, but this
* is for oscilloscope business anyway and we
* are just interested in edge delays in the
* lower us range
*/
-
+#ifdef PPS_SYNC
+ s = splclock();
+ usec = time.tv_usec;
+#endif
/*
* time stamp
*/
uniqtime(&cdevent.tv);
-
- TIMEVAL_USADD(&cdevent.tv, xsdelay);
-
- q = za->za_ttycommon.t_readq;
+
+#ifdef PPS_SYNC
+ splx(s);
+#endif
/*
* logical state
*/
- status = cd_invert ? cdstate == 0 : cdstate != 0;
+ status = cd_invert ? (zsstatus & (ZSRR0_CD|ZSRR0_SYNC)) == 0 : (zsstatus & (ZSRR0_CD|ZSRR0_SYNC)) != 0;
+
+#ifdef PPS_SYNC
+ if (status)
+ {
+ usec = cdevent.tv.tv_usec - usec;
+ if (usec < 0)
+ usec += 1000000;
+
+ hardpps(&cdevent.tv, usec);
+ }
+#endif
+
+ TIMEVAL_USADD(&cdevent.tv, xsdelay);
+
+ q = za->za_ttycommon.t_readq;
/*
* ok - now the hard part - find ourself
@@ -1177,10 +1205,10 @@ static void zs_xsisr(zs)
/*
* only pretend that CD has been handled
*/
- za->za_rr0 = za->za_rr0 & ~ZSRR0_CD | zsstatus & ZSRR0_CD;
+ za->za_rr0 = za->za_rr0 & ~(ZSRR0_CD|ZSRR0_SYNC) | zsstatus & (ZSRR0_CD|ZSRR0_SYNC);
ZSDELAY(2);
- if (!((za->za_rr0 ^ zsstatus) & ~ZSRR0_CD))
+ if (!((za->za_rr0 ^ zsstatus) & ~(ZSRR0_CD|ZSRR0_SYNC)))
{
/*
* all done - kill status indication and return
@@ -1258,6 +1286,24 @@ static void zs_xsisr(zs)
* History:
*
* parsestreams.c,v
+ * Revision 3.19 1994/02/24 16:33:54 kardel
+ * CD events can also be posted on sync flag
+ *
+ * Revision 3.18 1994/02/24 14:12:58 kardel
+ * initial PPS_SYNC support version
+ *
+ * Revision 3.17 1994/02/20 15:18:02 kardel
+ * rcs id cleanup
+ *
+ * Revision 3.16 1994/02/15 22:39:50 kardel
+ * memory leak on open failure closed
+ *
+ * Revision 3.15 1994/02/13 19:16:50 kardel
+ * updated verbose Copyright message
+ *
+ * Revision 3.14 1994/02/02 17:45:38 kardel
+ * rcs ids fixed
+ *
* Revision 3.12 1994/01/25 19:05:30 kardel
* 94/01/23 reconcilation
*
diff --git a/contrib/xntpd/parse/util/parsetest.c b/contrib/xntpd/parse/util/parsetest.c
index 9028b4cf4cf4..21e41289a1c6 100644
--- a/contrib/xntpd/parse/util/parsetest.c
+++ b/contrib/xntpd/parse/util/parsetest.c
@@ -1,7 +1,7 @@
/*
- * /src/NTP/REPOSITORY/v3/kernel/parsetest.c,v 3.4 1993/03/17 17:16:57 kardel Exp
+ * /src/NTP/REPOSITORY/v3/parse/util/parsetest.c,v 3.13 1994/02/20 13:04:46 kardel Exp
*
- * parsetest.c,v 3.10 1994/01/23 17:22:18 kardel Exp
+ * parsetest.c,v 3.13 1994/02/20 13:04:46 kardel Exp
*
* Copyright (c) 1989,1990,1991,1992,1993,1994
* Frank Kardel Friedrich-Alexander Universitaet Erlangen-Nuernberg
@@ -11,15 +11,11 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* parsetest.c,v
- * Revision 3.4 1993/03/17 17:16:57 kardel
- * DEC OSF/1 ALPHA Integration - 930314
+ * Revision 3.13 1994/02/20 13:04:46 kardel
+ * parse add/delete second support
*
- * Revision 3.3 1993/01/18 09:24:33 kardel
- * updated copyright conditions in conjunction with
- * conditions set up in the COPYRIGHT file
- *
- * Revision 3.2 1993/01/17 13:43:00 kardel
- * 1993 initial update
+ * Revision 3.12 1994/02/02 17:45:51 kardel
+ * rcs ids fixed
*
*/
@@ -198,7 +194,7 @@ main(argc, argv)
parsetime_t parsetime;
struct strioctl strioc;
- printf("parsetest.c,v 3.10 1994/01/23 17:22:18 kardel Exp\n");
+ printf("parsetest.c,v 3.13 1994/02/20 13:04:46 kardel Exp\n");
while (ioctl(fd, I_POP, 0) == 0)
;
diff --git a/contrib/xntpd/parse/util/testdcf.c b/contrib/xntpd/parse/util/testdcf.c
index ebdfd2fded07..560ab27c4369 100644
--- a/contrib/xntpd/parse/util/testdcf.c
+++ b/contrib/xntpd/parse/util/testdcf.c
@@ -1,7 +1,7 @@
/*
- * /src/NTP/REPOSITORY/v3/parse/util/testdcf.c,v 3.9 1994/01/25 19:05:45 kardel Exp
+ * /src/NTP/REPOSITORY/v3/parse/util/testdcf.c,v 3.11 1994/02/02 17:45:55 kardel Exp
*
- * testdcf.c,v 3.9 1994/01/25 19:05:45 kardel Exp
+ * testdcf.c,v 3.11 1994/02/02 17:45:55 kardel Exp
*
* simple DCF77 100/200ms pulse test program (via 50Baud serial line)
*
diff --git a/contrib/xntpd/ppsclock/ppstest/.keep_me b/contrib/xntpd/ppsclock/ppstest/.keep_me
deleted file mode 100644
index e69de29bb2d1..000000000000
--- a/contrib/xntpd/ppsclock/ppstest/.keep_me
+++ /dev/null
diff --git a/contrib/xntpd/ppsclock/sys/genassym/.keep_me b/contrib/xntpd/ppsclock/sys/genassym/.keep_me
deleted file mode 100644
index e69de29bb2d1..000000000000
--- a/contrib/xntpd/ppsclock/sys/genassym/.keep_me
+++ /dev/null
diff --git a/contrib/xntpd/ppsclock/sys/os/.keep_me b/contrib/xntpd/ppsclock/sys/os/.keep_me
deleted file mode 100644
index e69de29bb2d1..000000000000
--- a/contrib/xntpd/ppsclock/sys/os/.keep_me
+++ /dev/null
diff --git a/contrib/xntpd/ppsclock/sys/sun/.keep_me b/contrib/xntpd/ppsclock/sys/sun/.keep_me
deleted file mode 100644
index e69de29bb2d1..000000000000
--- a/contrib/xntpd/ppsclock/sys/sun/.keep_me
+++ /dev/null
diff --git a/contrib/xntpd/ppsclock/sys/sun4c/.keep_me b/contrib/xntpd/ppsclock/sys/sun4c/.keep_me
deleted file mode 100644
index e69de29bb2d1..000000000000
--- a/contrib/xntpd/ppsclock/sys/sun4c/.keep_me
+++ /dev/null
diff --git a/contrib/xntpd/ppsclock/sys/sun4c/conf/.keep_me b/contrib/xntpd/ppsclock/sys/sun4c/conf/.keep_me
deleted file mode 100644
index e69de29bb2d1..000000000000
--- a/contrib/xntpd/ppsclock/sys/sun4c/conf/.keep_me
+++ /dev/null
diff --git a/contrib/xntpd/ppsclock/sys/sun4m/conf/.keep_me b/contrib/xntpd/ppsclock/sys/sun4m/conf/.keep_me
deleted file mode 100644
index e69de29bb2d1..000000000000
--- a/contrib/xntpd/ppsclock/sys/sun4m/conf/.keep_me
+++ /dev/null
diff --git a/contrib/xntpd/ppsclock/sys/sundev/.keep_me b/contrib/xntpd/ppsclock/sys/sundev/.keep_me
deleted file mode 100644
index e69de29bb2d1..000000000000
--- a/contrib/xntpd/ppsclock/sys/sundev/.keep_me
+++ /dev/null
diff --git a/contrib/xntpd/ppsclock/sys/sys/.keep_me b/contrib/xntpd/ppsclock/sys/sys/.keep_me
deleted file mode 100644
index e69de29bb2d1..000000000000
--- a/contrib/xntpd/ppsclock/sys/sys/.keep_me
+++ /dev/null
diff --git a/contrib/xntpd/refclocks/rclk.TRAK b/contrib/xntpd/refclocks/rclk.TRAK
new file mode 100644
index 000000000000..188ffd4445bc
--- /dev/null
+++ b/contrib/xntpd/refclocks/rclk.TRAK
@@ -0,0 +1,29 @@
+#!/bin/sh -
+CMD="$1"
+shift;
+
+. refclocks/setup
+
+case "$CMD" in
+ info)
+ echo " TRAK - TRAK 8810 GPS station clock"
+ ;;
+ check)
+ if check "$RCONFIG" '$0 ~ /TRAK/'; then
+ echo "TRAK - TRAK 8810 GPS station clock"
+ fi
+ ;;
+ config)
+ if check "$REFCONF" '$0 ~ /TRAK/' ||
+ ( [ ! "$REFCONF" ] && query "Include TRAK 8810 GPS station clock (TRAK)" n); then
+ if check "$PPSFEATURES" '$0 ~ /CD/' &&
+ [ "$PPSOK" -eq 1 ] &&
+ (check "$REFCONF" '$0 ~ /TRAKPPS/' ||
+ ( [ ! "$REFCONF" ] && query " Use TRAK for PPS" n)); then
+ echo "-DTRAKPPS" >> $RCONFIG
+ else
+ echo "-DTRAK" >> $RCONFIG
+ fi
+ fi
+ ;;
+esac
diff --git a/contrib/xntpd/scripts/Guess.sh b/contrib/xntpd/scripts/Guess.sh
index c2be5697eab7..88dcb1a5ef86 100755
--- a/contrib/xntpd/scripts/Guess.sh
+++ b/contrib/xntpd/scripts/Guess.sh
@@ -40,7 +40,11 @@ if [ -f /bin/uname -o -f /usr/bin/uname ]; then
guess="ultrix"
;;
hp-ux) case "$3" in
- *.10.*) guess="hpux10+" ;;
+ *.10.*) guess="hpux-adj" ;;
+ *.09.03) case "$5" in
+ 9000/3*) guess="hpux-adj" ;;
+ *) guess="hpux" ;;
+ esac ;;
*) guess="hpux" ;;
esac
;;
@@ -74,7 +78,7 @@ if [ -f /bin/uname -o -f /usr/bin/uname ]; then
3.2.*)
case "$4" in
v*)
- (i386) >/dev/null 2>&1 && guess=ptx;;
+ (i386) >/dev/null 2>&1 && [ -f /usr/lib/libseq.a ] && guess=ptx;;
esac
esac
fi
diff --git a/contrib/xntpd/scripts/README b/contrib/xntpd/scripts/README
index 79f1792a43d4..7439c6c6c498 100644
--- a/contrib/xntpd/scripts/README
+++ b/contrib/xntpd/scripts/README
@@ -11,7 +11,7 @@ Guess.sh script to figure out what machine and operating system
autoconf awesome script swiped from Jeff Johnson (who may have
swiped it from GNU) which delves deep into the system
files to reveal dark secrets necessary to port NTP to
- everything exceptt sewing machines. Unfinished work.
+ everything except sewing machines. Unfinished work.
makeconfig.sh shell script that calles Guess.sh and then figures out
what compiler is available, then builds the
diff --git a/contrib/xntpd/scripts/stats/README b/contrib/xntpd/scripts/stats/README
index 5aa64d4c1db9..680896342acb 100644
--- a/contrib/xntpd/scripts/stats/README
+++ b/contrib/xntpd/scripts/stats/README
@@ -3,20 +3,27 @@ Statistics processing scripts (README)
This directory contains a number of scripts for use with the filegen
facility. Those files ending in .awk are for the Unix awk utility, while
those ending in .sh are for the csh utility. Normally, the summary.sh
-script is called from a cron job once per day. This script calls the
-peer.sh script to process the peerstats file and append the summary
-statistics to the peer_summary file. Then, it callse the loop.sh script
-to process the loopstats file and append the summary statistics to the
-loop_summary file. Finally, it calls the clock.sh script to process the
-clockstats file and append the summary statistics to the clock_summary
-file.
+script is called from a cron job once per day. This script processes the
+daily loopstats, peerstats and clockstats files produced by the daemon,
+updates the loop_summary, peer_summary and clock_summary archive files,
+and deletes the daily files.
-Each of the three shell scripts peer.sh, loop.sh and clock.sh invoke
-one or more awk scripts to actually produce the data. This may result
-in multiple scans of the same input file. The input file is deleted after
-processing. In fact, the shell scripts will process all input files
-found of the correct type in chronological order, deleting each one as
-it is scanned, except the current day file.
+In the case of the Austron 2201A GPS receiver, the clockstats file
+contains a wealth of additional monitoring data. These data are summarized
+and writted to the clock_summary file, then a series of special files are
+constructed for later processing by the S utility.
+
+The summary.sh script invokes a number of awk scripts to actually produce
+the data. This may result in multiple scans of the same input file.
+The input file is deleted after processing. In fact, the shell scripts will
+process all input files found of the correct type in chronological order,
+deleting each one as it is scanned, except the current day file.
+
+The summary.sh script can produce input files for the S utility, if it
+is found on the search path. This utility makes PostScript graphs of the
+loopstats data for each day, as well as various statistics produced by
+the Austorn 220aA GPS receiver. The S utility is automatically run
+as a background job. Its control files have the .S extension.
The psummary.awk script can be used to scan the peer_summary file and
construct an historical reprise of the daily summaries.
@@ -29,4 +36,4 @@ David L. Mills
University of Delaware
mills@udel.edu
1 November 1993
-
+Revised 12 April 1994
diff --git a/contrib/xntpd/scripts/stats/dupe.awk b/contrib/xntpd/scripts/stats/dupe.awk
index 3ddc1b6f9754..317c2a4faf84 100644
--- a/contrib/xntpd/scripts/stats/dupe.awk
+++ b/contrib/xntpd/scripts/stats/dupe.awk
@@ -1,4 +1,5 @@
-# program to delete duplicate lines in a file
+#
+# delete duplicate lines
#
{
if (old != $0)
diff --git a/contrib/xntpd/scripts/stats/ensemble.S b/contrib/xntpd/scripts/stats/ensemble.S
new file mode 100644
index 000000000000..32a4dbabb820
--- /dev/null
+++ b/contrib/xntpd/scripts/stats/ensemble.S
@@ -0,0 +1,5 @@
+ensemble <- scan(file1, list(day=0, sec=0, gps=0, gpsw=0, loran=0, loranw=0, ensemble=0, std=0))
+str <- paste("eps/", file1, ".eps", sep="")
+postscript(str, , , , 5, pointsize=18)
+par(mgp=c(1, 0, 0), tck = 0.03, mar = c(2, 2, 1, 1))
+plot(ensemble$sec, ensemble$ensemble, type="l", xlab=paste("MJD", ensemble$day, "Time (s)"), ylab="Ensemble Offset (ns)", ylim=c(-400, 400))
diff --git a/contrib/xntpd/scripts/stats/etf.S b/contrib/xntpd/scripts/stats/etf.S
new file mode 100644
index 000000000000..9b9c68b937b5
--- /dev/null
+++ b/contrib/xntpd/scripts/stats/etf.S
@@ -0,0 +1,15 @@
+options(digits=4)
+file2 <- "etf_summary"
+etf <- scan(file1, list(day=0, sec=0, offset=0, stab=0))
+r <- lsfit(etf$sec, etf$offset)
+count<-length(etf$sec)
+mean<-r$coef[[1]]
+std<-sqrt(var(r$residuals))
+slope<-r$coef[[2]] * 1000
+cat("\n", file=file2 , append=TRUE, fill=FALSE, sep="")
+cat(file1, "\n", file=file2, append=TRUE, fill=FALSE, sep="")
+cat("etf1 ", count, ", T ", mean, " ns, R ", slope, " ps/s, std ", std, " us\n", file=file2, append=TRUE, fill=FALSE, sep="")
+str <- paste("eps/", file1, ".eps", sep="")
+postscript(str, , , , 5, pointsize=18)
+par(mgp=c(1, 0, 0), tck=0.03, mar=c(2, 2, 1, 1))
+plot(etf$sec, etf$offset, type="l", xlab=paste("MJD", etf$day, "Time (s)"), ylab="External Offset (ns)", ylim=c(-400, 400))
diff --git a/contrib/xntpd/scripts/stats/itf.S b/contrib/xntpd/scripts/stats/itf.S
new file mode 100644
index 000000000000..56c8c8d0cc7a
--- /dev/null
+++ b/contrib/xntpd/scripts/stats/itf.S
@@ -0,0 +1,5 @@
+itf <- scan(file1, list(day=0, sec=0, offset=0, stab=0))
+str <- paste("eps/", file1, ".eps", sep="")
+postscript(str, , , , 5, pointsize=18)
+par(mgp=c(1, 0, 0), tck=0.03, mar=c(2, 2, 1, 1))
+plot(itf$sec, itf$offset, type="l", xlab=paste("MJD", itf$day, "Time (s)"), ylab="Internal Offset (ns)", ylim=c(-400, 400))
diff --git a/contrib/xntpd/scripts/stats/loop.S b/contrib/xntpd/scripts/stats/loop.S
new file mode 100644
index 000000000000..8e564b67eb67
--- /dev/null
+++ b/contrib/xntpd/scripts/stats/loop.S
@@ -0,0 +1,7 @@
+options(digits=4)
+loop <- scan(file1, list(day=0, sec=0, offset=0, freq=0, tc=0))
+loop$offset <- loop$offset * 1e6
+str <- paste("eps/", file1, ".eps", sep="")
+postscript(str, , , , 5, pointsize=18)
+par(mgp=c(1, 0, 0), tck=0.03, mar=c(2, 2, 1, 1))
+plot(loop$sec, loop$offset, type="l", xlab=paste("MJD", loop$day, "Time (s)"), ylab="PLL Offset (us)", ylim=c(-400, 400))
diff --git a/contrib/xntpd/scripts/stats/loop.awk b/contrib/xntpd/scripts/stats/loop.awk
index 25d0bdb97d53..470b27c8bef5 100644
--- a/contrib/xntpd/scripts/stats/loop.awk
+++ b/contrib/xntpd/scripts/stats/loop.awk
@@ -35,15 +35,7 @@ BEGIN {
loop_time_rms = sqrt(loop_time_rms / loop_count - loop_time * loop_time)
loop_freq /= loop_count
loop_freq_rms = sqrt(loop_freq_rms / loop_count - loop_freq * loop_freq)
- loop_tmax = loop_tmax - loop_time
- loop_tmin = loop_time - loop_tmin
- if (loop_tmin > loop_tmax)
- loop_tmax = loop_tmin
- loop_fmax = loop_fmax - loop_freq
- loop_fmin = loop_time - loop_fmin
- if (loop_fmin > loop_fmax)
- loop_fmax = loop_fmin
- printf "loop %d, %.0f+/-%.1f, rms %.1f, freq %.2f+/-%0.3f, rms %.3f\n", loop_count, loop_time * 1e6, loop_tmax * 1e6, loop_time_rms * 1e6, loop_freq, loop_fmax, loop_freq_rms
+ printf "loop %d, %.0f+/-%.1f, rms %.1f, freq %.2f+/-%0.3f, var %.3f\n", loop_count, (loop_tmax + loop_tmin) / 2 * 1e6, (loop_tmax - loop_tmin) / 2 * 1e6, loop_time_rms * 1e6, (loop_fmax + loop_fmin) / 2, (loop_fmax - loop_fmin) / 2, loop_freq_rms
}
}
diff --git a/contrib/xntpd/scripts/stats/psummary.awk b/contrib/xntpd/scripts/stats/psummary.awk
index b7f0e922a7d6..5ef8d8eb5280 100644
--- a/contrib/xntpd/scripts/stats/psummary.awk
+++ b/contrib/xntpd/scripts/stats/psummary.awk
@@ -1,5 +1,7 @@
# program to scan peer_summary file and produce summary of daily summaries
#
+# usage: awk -f psummary.awk peer_summary
+#
{
if (NF < 8 || $1 == "ident")
continue
diff --git a/contrib/xntpd/scripts/stats/rms.awk b/contrib/xntpd/scripts/stats/rms.awk
new file mode 100644
index 000000000000..34d612ab3582
--- /dev/null
+++ b/contrib/xntpd/scripts/stats/rms.awk
@@ -0,0 +1,41 @@
+# program to scan peer_summary file
+#
+{
+ if (NF < 8 || $1 == "ident")
+ continue
+ i = n
+ for (j = 0; j < n; j++) {
+ if ($1 == peer_ident[j])
+ i = j
+ }
+ if (i == n) {
+ peer_ident[i] = $1
+ n++
+ }
+ peer_count[i]++
+ if (($7 - $6 / 2) < 400) {
+ peer_count[i]++
+ peer_mean[i] += $3
+ peer_var[i] += $4 * $4
+ if ($5 > peer_max[i])
+ peer_max[i] = $5
+ if ($5 > 1)
+ peer_1[i]++
+ if ($5 > 5)
+ peer_2[i]++
+ if ($5 > 10)
+ peer_3[i]++
+ if ($5 > 50)
+ peer_4[i]++
+ }
+} END {
+ printf " host cnt mean sd max >1 >5 >10 >50\n"
+ printf "=================================================================\n"
+ for (i = 0; i < n; i++) {
+ if (peer_count[i] <= 0)
+ continue
+ peer_mean[i] /= peer_count[i]
+ peer_var[i] = sqrt(peer_var[i] / peer_count[i])
+ printf "%15s%4d%10.3f%10.3f%10.3f%4d%4d%4d%4d\n", peer_ident[i], peer_count[i], peer_mean[i], peer_var[i], peer_max[i], peer_1[i], peer_2[i], peer_3[i], peer_4[i]
+ }
+}
diff --git a/contrib/xntpd/scripts/stats/summary.sh b/contrib/xntpd/scripts/stats/summary.sh
index ab99f4d8e8d5..caac2b0c3bec 100755
--- a/contrib/xntpd/scripts/stats/summary.sh
+++ b/contrib/xntpd/scripts/stats/summary.sh
@@ -1,17 +1,88 @@
-#!/bin/csh
+#!/bin/sh
#
# Script to summarize ipeerstats, loopstats and clockstats files
#
# This script can be run from a cron job once per day, week or month. It
# runs the file-specific summary script and appends the summary data to
-# designated files, which must be created first.
-#
-if ( -e peer_summary ) then
- peer.sh >>peer_summary
-endif
-if ( -e loop_summary ) then
- loop.sh >>loop_summary
-endif
-if ( -e clock_summary ) then
- clock.sh >>clock_summary
-endif
+# designated files.
+#
+DATE=`date +19%y%m%d`
+SIN=S.in
+SOUT=S.out
+LOOP=loop_summary
+PEER=peer_summary
+CLOCK=clock_summary
+
+rm -f $SIN $SOUT
+S=0
+if [ -f `which S | cut -f1 -d" "` ]; then
+ S=1
+fi
+#
+# Summarize loopstats files
+#
+for f in loopstats.????????; do
+ d=`echo $f | cut -f2 -d.`
+ if [ $DATE != $d ]; then
+ echo " " >>$LOOP
+ echo $f >>$LOOP
+ awk -f loop.awk $f >>$LOOP
+ if [ $S ]; then
+ echo "file1<-"\"${f}\" >>$SIN
+ echo "source("\""loop.S"\"")" >>$SIN
+ fi
+ rm -f $f
+ fi
+done
+
+#
+# Summarize peerstats files
+#
+for f in peerstats.????????; do
+ d=`echo $f | cut -f2 -d.`
+ if [ $DATE != $d ]; then
+ echo " " >>$PEER
+ echo $f >>$PEER
+ awk -f peer.awk $f >>$PEER
+ rm -f $f
+ fi
+done
+
+#
+# Summarize clockstats files
+#
+for f in clockstats.????????; do
+ d=`echo $f | cut -f2 -d.`
+ if [ $DATE != $d ]; then
+ echo " " >>$CLOCK
+ echo $f >>$CLOCK
+ awk -f clock.awk $f >>$CLOCK
+ if [ -f /dev/gps* ]; then
+ awk -f itf.awk $f >itf.$d
+ awk -f etf.awk $f >etf.$d
+ awk -f ensemble.awk $f >ensemble.$d
+ awk -f tdata.awk $f >tdata.$d
+ fi
+ rm -f $f
+ fi
+done
+
+#
+# Process clockstat files with S and generate PostScript plots
+#
+for f in itf etf ensemble tdata; do
+ for d in ${f}.????????; do
+ if [ -f $d ]; then
+ if [ $S ]; then
+ echo "file1<-"\"${d}\" >>$SIN
+ echo "source("\"${f}.S\"")" >>$SIN
+ echo "unix("\""rm ${d}"\"")" >>$SIN
+ else
+ rm -f $d
+ fi
+ fi
+ done
+done
+if [ -f $SIN ]; then
+ S BATCH $SIN $SOUT
+fi
diff --git a/contrib/xntpd/scripts/stats/tdata.S b/contrib/xntpd/scripts/stats/tdata.S
new file mode 100644
index 000000000000..f360a248c06a
--- /dev/null
+++ b/contrib/xntpd/scripts/stats/tdata.S
@@ -0,0 +1,5 @@
+tdata <- scan(file1, list(day=0, sec=0, m=0, w=0, x=0, y=0, z=0))
+str <- paste("eps/", file1, ".eps", sep="")
+postscript(str, , , , 5, pointsize=18)
+par(mgp=c(1, 0, 0), tck=0.03, mar=c(2, 2, 1, 1))
+plot(tdata$sec, tdata$m, type="l", xlab=paste("MJD", tdata$day, "Time (s)"), ylab="LORAN-M SNR (dB)")
diff --git a/contrib/xntpd/scripts/support/bin/monl b/contrib/xntpd/scripts/support/bin/monl
index 44201d0d0f99..f0c48dbf5f3f 100755
--- a/contrib/xntpd/scripts/support/bin/monl
+++ b/contrib/xntpd/scripts/support/bin/monl
@@ -143,7 +143,8 @@ foreach $hostname (@ARGV)
{
chop;
split;
- ($host, $count, $mode, $version, $lasttime, $firsttime) = (@_[$[, $[+2 .. $[+6]);
+ ($host, $count, $mode, $version, $lasttime, $firsttime) =
+ (@_[$[, $[+2 .. $[+4, $#_-1,$#_]);
$Seen{$host, $mode} = 1;
diff --git a/contrib/xntpd/util/ntptime.c b/contrib/xntpd/util/ntptime.c
index c0512df90a87..858fe7cba481 100644
--- a/contrib/xntpd/util/ntptime.c
+++ b/contrib/xntpd/util/ntptime.c
@@ -15,27 +15,29 @@
#include <signal.h>
#include <errno.h>
-#include <sys/syscall.h>
-
#include "ntp_fp.h"
#include "ntp_unixtime.h"
#include "ntp_stdlib.h"
#ifndef SYS_DECOSF1
#define BADCALL -1 /* this is supposed to be a bad syscall */
-#endif
-#include "ntp_timex.h"
+#endif /* SYS_DECOSF1 */
-#ifdef KERNEL_PLL
-#ifndef SYS_ntp_adjtime
+#ifdef KERNEL_PLL
+#include <sys/timex.h>
+#define ntp_gettime(t) syscall(SYS_ntp_gettime, (t))
+#define ntp_adjtime(t) syscall(SYS_ntp_adjtime, (t))
+#else /* KERNEL_PLL */
+#include "ntp_timex.h"
#define SYS_ntp_adjtime NTP_SYSCALL_ADJ
-#endif
-#ifndef SYS_ntp_gettime
#define SYS_ntp_gettime NTP_SYSCALL_GET
-#endif
-#endif /* KERNEL_PLL */
+#endif /* KERNEL_PLL */
+/*
+ * Function prototypes
+ */
extern int sigvec P((int, struct sigvec *, struct sigvec *));
+extern int syscall P((int, void *, ...));
void pll_trap P((void));
static struct sigvec newsigsys; /* new sigvec status */
@@ -56,50 +58,50 @@ main(argc, argv)
struct ntptimeval ntv;
struct timex ntx, _ntx;
int times[20];
- double ftemp;
+ double ftemp, gtemp;
l_fp ts;
int c;
int errflg = 0;
int cost = 0;
int rawtime = 0;
- ntx.mode = 0;
+ memset((char *)&ntx, 0, sizeof(ntx));
progname = argv[0];
while ((c = ntp_getopt(argc, argv, optargs)) != EOF) switch (c) {
case 'c':
cost++;
break;
case 'e':
- ntx.mode |= ADJ_ESTERROR;
+ ntx.modes |= MOD_ESTERROR;
ntx.esterror = atoi(ntp_optarg);
break;
case 'f':
- ntx.mode |= ADJ_FREQUENCY;
- ntx.frequency = (int) (atof(ntp_optarg)
- * (1 << SHIFT_USEC));
- if (ntx.frequency < (-100 << SHIFT_USEC)
- || ntx.frequency > ( 100 << SHIFT_USEC)) errflg++;
+ ntx.modes |= MOD_FREQUENCY;
+ ntx.freq = (int) (atof(ntp_optarg) *
+ (1 << SHIFT_USEC));
+ if (ntx.freq < (-100 << SHIFT_USEC)
+ || ntx.freq > ( 100 << SHIFT_USEC)) errflg++;
break;
case 'm':
- ntx.mode |= ADJ_MAXERROR;
+ ntx.modes |= MOD_MAXERROR;
ntx.maxerror = atoi(ntp_optarg);
break;
case 'o':
- ntx.mode |= ADJ_OFFSET;
+ ntx.modes |= MOD_OFFSET;
ntx.offset = atoi(ntp_optarg);
break;
case 'r':
rawtime++;
break;
case 's':
- ntx.mode |= ADJ_STATUS;
+ ntx.modes |= MOD_STATUS;
ntx.status = atoi(ntp_optarg);
if (ntx.status < 0 || ntx.status > 4) errflg++;
break;
case 't':
- ntx.mode |= ADJ_TIMECONST;
- ntx.time_constant = atoi(ntp_optarg);
- if (ntx.time_constant < 0 || ntx.time_constant > MAXTC)
+ ntx.modes |= MOD_TIMECONST;
+ ntx.constant = atoi(ntp_optarg);
+ if (ntx.constant < 0 || ntx.constant > MAXTC)
errflg++;
break;
default:
@@ -115,7 +117,7 @@ main(argc, argv)
-m maxerror max possible error (us)\n\
-o offset current offset (ms)\n\
-r print the unix and NTP time raw\n\
- -s status Set the status (0 .. 4)\n\
+ -l leap Set the leap bits\n\
-t timeconstant log2 of PLL time constant (0 .. %d)\n",
progname, optargs, MAXTC);
exit(2);
@@ -151,13 +153,13 @@ main(argc, argv)
times[c] = ntv.time.tv_usec;
}
if (pll_control >= 0) {
- printf("[ usec %06d:", times[0]);
+ printf("[ us %06d:", times[0]);
for (c=1; c< sizeof times / sizeof times[0]; c++) printf(" %d", times[c] - times[c-1]);
printf(" ]\n");
}
}
(void)ntp_gettime(&ntv);
- ntx.mode = 0; /* Ensure nothing is set */
+ _ntx.modes = 0; /* Ensure nothing is set */
(void)ntp_adjtime(&_ntx);
if (pll_control < 0) {
printf("NTP user interface routines are not configured in this kernel.\n");
@@ -175,9 +177,9 @@ main(argc, argv)
ts.l_uf += TS_ROUNDBIT; /* guaranteed not to overflow */
ts.l_ui += JAN_1970;
ts.l_uf &= TS_MASK;
- printf(" time: %s, (.%06d)\n",
+ printf(" time %s, (.%06d),\n",
prettydate(&ts), ntv.time.tv_usec);
- printf(" confidence interval: %ld usec, estimated error: %ld usec\n",
+ printf(" maximum error %ld us, estimated error %ld us.\n",
ntv.maxerror, ntv.esterror);
if (rawtime) printf(" ntptime=%x.%x unixtime=%x.%06d %s",
ts.l_ui, ts.l_uf,
@@ -189,15 +191,26 @@ main(argc, argv)
">> ntp_adjtime() call fails");
else {
printf("ntp_adjtime() returns code %d\n", status);
- ftemp = ntx.frequency;
+ ftemp = ntx.freq;
ftemp /= (1 << SHIFT_USEC);
- printf(" mode: %02x, offset: %ld usec, frequency: %6.3f ppm,\n",
- ntx.mode, ntx.offset, ftemp);
- printf(" confidence interval: %ld usec, estimated error: %ld usec,\n",
+ printf(" modes %04x, offset %ld us, frequency %.3f ppm, interval %d s,\n",
+ ntx.modes, ntx.offset, ftemp, 1 << ntx.shift);
+ printf(" maximum error %ld us, estimated error %ld us,\n",
ntx.maxerror, ntx.esterror);
- printf(" status: %d, time constant: %ld, precision: %ld usec, tolerance: %ld usec\n",
- ntx.status, ntx.time_constant, ntx.precision,
- ntx.tolerance);
+ ftemp = ntx.tolerance;
+ ftemp /= (1 << SHIFT_USEC);
+ printf(" status %04x, time constant %ld, precision %ld us, tolerance %.0f ppm,\n",
+ ntx.status, ntx.constant, ntx.precision, ftemp);
+ if (ntx.shift == 0)
+ return;
+ ftemp = ntx.ppsfreq;
+ ftemp /= (1 << SHIFT_USEC);
+ gtemp = ntx.stabil;
+ gtemp /= (1 << SHIFT_USEC);
+ printf(" pps frequency %.3f ppm, stability %.3f ppm, jitter %ld us,\n",
+ ftemp, gtemp, ntx.jitter);
+ printf(" intervals %ld, jitter exceeded %ld, stability exceeded %ld, errors %ld.\n",
+ ntx.calcnt, ntx.jitcnt, ntx.stbcnt, ntx.errcnt);
}
/*
diff --git a/contrib/xntpd/util/tickadj.c b/contrib/xntpd/util/tickadj.c
index ab10b3728a0e..caec06871795 100644
--- a/contrib/xntpd/util/tickadj.c
+++ b/contrib/xntpd/util/tickadj.c
@@ -1,4 +1,4 @@
-/* tickadj.c,v 3.1 1993/07/06 01:11:05 jbj Exp
+/*
* tickadj - read, and possibly modify, the kernel `tick' and
* `tickadj' variables, as well as `dosynctodr'. Note that
* this operates on the running kernel only. I'd like to be
@@ -6,6 +6,41 @@
* mastered this yet.
*/
#include <stdio.h>
+
+#ifdef SYS_LINUX
+#include <sys/timex.h>
+
+struct timex txc;
+
+int
+main(int argc, char ** argv)
+{
+ if (argc > 2)
+ {
+ fprintf(stderr, "Usage: %s [tick_value]\n", argv[0]);
+ exit(-1);
+ }
+ else if (argc == 2)
+ {
+ if ( (txc.tick = atoi(argv[1])) < 1 )
+ {
+ fprintf(stderr, "Silly value for tick: %s\n", argv[1]);
+ exit(-1);
+ }
+ txc.mode = ADJ_TICK;
+ }
+ else
+ txc.mode = 0;
+
+ if (__adjtimex(&txc) < 0)
+ perror("adjtimex");
+ else
+ printf("tick = %d\n", txc.tick);
+
+ return(0);
+}
+#else /* not Linux... kmem tweaking: */
+
#include <sys/types.h>
#include <sys/file.h>
#include <sys/stat.h>
@@ -298,10 +333,13 @@ getoffsets(filex, tick_off, tickadj_off, dosync_off, noprintf_off)
#if defined(SYS_AUX3) || defined(SYS_AUX2)
#define X_TICKADJ 0
-#define X_V 1
-#define X_TICK 2
+#define X_TICK 1
#define X_DEF
- static struct nlist nl[4];
+ static struct nlist nl[] =
+ { {"tickadj"},
+ {"tick"},
+ {""},
+ };
#endif
#ifdef NeXT
@@ -353,6 +391,22 @@ getoffsets(filex, tick_off, tickadj_off, dosync_off, noprintf_off)
#endif
#endif
+#if defined(SYS_HPUX)
+#define X_TICKADJ 0
+#define X_TICK 1
+#define X_DEF
+ static struct nlist nl[] =
+#ifdef hp9000s300
+ { {"_tickadj"},
+ {"_old_tick"},
+#else
+ { {"tickadj"},
+ {"old_tick"},
+#endif
+ {""},
+ };
+#endif
+
#if !defined(X_DEF)
#define X_TICKADJ 0
#define X_TICK 1
@@ -373,17 +427,11 @@ getoffsets(filex, tick_off, tickadj_off, dosync_off, noprintf_off)
"/kernel/unix",
"/386bsd",
"/netbsd",
+ "/hp-ux",
NULL
};
struct stat stbuf;
-#if defined(SYS_AUX3) || defined(SYS_AUX2)
- strcpy (nl[X_TICKADJ].n_name, "tickadj");
- strcpy (nl[X_V].n_name, "v");
- strcpy (nl[X_TICK].n_name, "tick");
- nl[3].n_name[0] = '\0';
-#endif
-
for (kname = kernels; *kname != NULL; kname++) {
if (stat(*kname, &stbuf) == -1)
continue;
@@ -513,3 +561,4 @@ readvar(fd, off, var)
exit(1);
}
}
+#endif /* not Linux */
diff --git a/contrib/xntpd/xntpd/Makefile b/contrib/xntpd/xntpd/Makefile
index 56f5dc2eb6eb..a4b083efde72 100644
--- a/contrib/xntpd/xntpd/Makefile
+++ b/contrib/xntpd/xntpd/Makefile
@@ -1,5 +1,5 @@
#
-# $Id: Makefile,v 1.4 1994/02/03 23:23:17 wollman Exp $
+# $Id: Makefile,v 1.5 1994/04/03 20:37:26 wollman Exp $
#
CFLAGS+= -I${.CURDIR}/../include
@@ -34,7 +34,7 @@ SRCS= ntp_config.c ntp_control.c ntp_io.c ntp_leap.c \
refclock_wwvb.c refclock_goes.c refclock_mx4200.c \
refclock_parse.c refclock_as2201.c refclock_omega.c \
refclock_tpro.c refclock_leitch.c refclock_irig.c \
- refclock_msfees.c refclock_gpstm.c ntp_intres.c \
+ refclock_msfees.c refclock_gpstm.c refclock_trak.c ntp_intres.c \
ntp_filegen.c version.c
beforedepend: version.c
diff --git a/contrib/xntpd/adjtime/.keep_me b/contrib/xntpd/xntpd/minpoll
index e69de29bb2d1..e69de29bb2d1 100644
--- a/contrib/xntpd/adjtime/.keep_me
+++ b/contrib/xntpd/xntpd/minpoll
diff --git a/contrib/xntpd/xntpd/ntp_config.c b/contrib/xntpd/xntpd/ntp_config.c
index 1b716f69fab5..8f356ac8c2e7 100644
--- a/contrib/xntpd/xntpd/ntp_config.c
+++ b/contrib/xntpd/xntpd/ntp_config.c
@@ -45,8 +45,9 @@
* peer 128.100.1.1 [ version 3 ] [ key 0 ] [ minpoll 6 ] [ maxpoll 10 ]
* server 128.100.2.2 [ version 3 ] [ key 0 ] [ minpoll 6 ] [ maxpoll 10 ]
* precision -7
- * broadcast 128.100.224.255 [ version 3 ] [ key 0 ]
- * broadcastclient yes|no
+ * broadcast 128.100.224.255 [ version 3 ] [ key 0 ] [ ttl 1 ]
+ * broadcastclient
+ * multicastclient [224.0.1.1]
* broadcastdelay 0.0102
* authenticate yes|no
* monitor yes|no
@@ -58,6 +59,16 @@
* statsdir /var/NTP/
* filegen peerstats [ file peerstats ] [ type day ] [ link ]
* resolver /path/progname
+ * clientlimit [ n ]
+ * clientperiod [ 3600 ]
+ * trustedkey [ key ]
+ * requestkey [ key]
+ * controlkey [ key ]
+ * trap [ address ]
+ * fudge [ ... ]
+ * pidfile [ ]
+ * logfile [ ]
+ * setvar [ ]
*
* And then some. See the manual page.
*/
@@ -84,22 +95,24 @@
#define CONFIG_CONTROLKEY 15
#define CONFIG_TRAP 16
#define CONFIG_FUDGE 17
-#define CONFIG_MAXSKEW 18
-#define CONFIG_RESOLVER 19
-#define CONFIG_SELECT 20
-#define CONFIG_STATSDIR 21
-#define CONFIG_FILEGEN 22
-#define CONFIG_STATISTICS 23
-#define CONFIG_PPS 24
-#define CONFIG_PIDFILE 25
-#define CONFIG_LOGFILE 26
-#define CONFIG_SETVAR 27
+#define CONFIG_RESOLVER 18
+#define CONFIG_STATSDIR 19
+#define CONFIG_FILEGEN 20
+#define CONFIG_STATISTICS 21
+#define CONFIG_PPS 22
+#define CONFIG_PIDFILE 23
+#define CONFIG_LOGFILE 24
+#define CONFIG_SETVAR 25
+#define CONFIG_CLIENTLIMIT 26
+#define CONFIG_CLIENTPERIOD 27
+#define CONFIG_MULTICASTCLIENT 28
#define CONF_MOD_VERSION 1
#define CONF_MOD_KEY 2
#define CONF_MOD_MINPOLL 3
#define CONF_MOD_MAXPOLL 4
#define CONF_MOD_PREFER 5
+#define CONF_MOD_TTL 6
#define CONF_PPS_DELAY 1
#define CONF_PPS_BAUD 2
@@ -114,6 +127,7 @@
#define CONF_RES_NOTRAP 8
#define CONF_RES_LPTRAP 9
#define CONF_RES_NTPPORT 10
+#define CONF_RES_LIMITED 11
#define CONF_TRAP_PORT 1
#define CONF_TRAP_INTERFACE 2
@@ -158,6 +172,7 @@ static struct keyword keywords[] = {
{ "driftfile", CONFIG_DRIFTFILE },
{ "broadcast", CONFIG_BROADCAST },
{ "broadcastclient", CONFIG_BROADCASTCLIENT },
+ { "multicastclient", CONFIG_MULTICASTCLIENT },
{ "authenticate", CONFIG_AUTHENTICATE },
{ "keys", CONFIG_KEYS },
{ "monitor", CONFIG_MONITOR },
@@ -170,15 +185,15 @@ static struct keyword keywords[] = {
{ "controlkey", CONFIG_CONTROLKEY },
{ "trap", CONFIG_TRAP },
{ "fudge", CONFIG_FUDGE },
- { "maxskew", CONFIG_MAXSKEW },
{ "resolver", CONFIG_RESOLVER },
- { "select", CONFIG_SELECT },
{ "statsdir", CONFIG_STATSDIR },
{ "filegen", CONFIG_FILEGEN },
{ "statistics", CONFIG_STATISTICS },
{ "pidfile", CONFIG_PIDFILE },
{ "logfile", CONFIG_LOGFILE },
{ "setvar", CONFIG_SETVAR },
+ { "clientlimit", CONFIG_CLIENTLIMIT },
+ { "clientperiod", CONFIG_CLIENTPERIOD },
{ "", CONFIG_UNKNOWN }
};
@@ -191,6 +206,7 @@ static struct keyword mod_keywords[] = {
{ "minpoll", CONF_MOD_MINPOLL },
{ "maxpoll", CONF_MOD_MAXPOLL },
{ "prefer", CONF_MOD_PREFER },
+ { "ttl", CONF_MOD_TTL },
{ "", CONFIG_UNKNOWN }
};
@@ -217,6 +233,7 @@ static struct keyword res_keywords[] = {
{ "notrap", CONF_RES_NOTRAP },
{ "lowpriotrap", CONF_RES_LPTRAP },
{ "ntpport", CONF_RES_NTPPORT },
+ { "limited", CONF_RES_LIMITED },
{ "", CONFIG_UNKNOWN }
};
@@ -318,12 +335,12 @@ extern int debug;
#endif
extern char *FindConfig();
char *progname;
-static char *xntp_options = "abc:de:f:k:l:p:r:s:t:v:V:";
+static char *xntp_options = "abc:de:f:k:l:mp:r:s:t:v:V:";
static int gettokens P((FILE *, char *, char **, int *));
static int matchkey P((char *, struct keyword *));
static int getnetnum P((char *, struct sockaddr_in *, int));
-static void save_resolve P((char *, int, int, int, int, int, U_LONG));
+static void save_resolve P((char *, int, int, int, int, int, int, U_LONG));
static void do_resolve P((char *, U_LONG, char *));
#ifdef RESOLVE_INTERNAL
static void do_resolve_internal P((void));
@@ -410,6 +427,7 @@ getconfig(argc, argv)
int peerversion;
int minpoll;
int maxpoll;
+ int ttl;
U_LONG peerkey;
int peerflags;
int hmode;
@@ -466,12 +484,15 @@ getconfig(argc, argv)
case 'a':
proto_config(PROTO_AUTHENTICATE, (LONG)1);
break;
+
case 'b':
proto_config(PROTO_BROADCLIENT, (LONG)1);
break;
+
case 'c':
config_file = ntp_optarg;
break;
+
case 'd':
#ifdef DEBUG
debug++;
@@ -516,6 +537,10 @@ getconfig(argc, argv)
}
break;
+ case 'm':
+ proto_config(PROTO_MULTICAST_ADD, INADDR_NTP);
+ break;
+
case 'p':
stats_config(STATS_PID_FILE, ntp_optarg);
break;
@@ -624,6 +649,7 @@ getconfig(argc, argv)
maxpoll = NTP_MAXPOLL;
peerkey = 0;
peerflags = 0;
+ ttl = 1;
for (i = 2; i < ntokens; i++)
switch (matchkey(tokens[i], mod_keywords)) {
case CONF_MOD_VERSION:
@@ -689,6 +715,16 @@ getconfig(argc, argv)
peerflags |= FLAG_PREFER;
break;
+ case CONF_MOD_TTL:
+ if (i >= ntokens-1) {
+ syslog(LOG_ERR,
+ "ttl: argument required");
+ errflg = 1;
+ break;
+ }
+ ttl = atoi(tokens[++i]);
+ break;
+
case CONFIG_UNKNOWN:
errflg = 1;
break;
@@ -700,14 +736,15 @@ getconfig(argc, argv)
if (errflg == 0) {
if (peer_config(&peeraddr,
(struct interface *)0, hmode, peerversion,
- minpoll, maxpoll, peerkey, peerflags) == 0) {
+ minpoll, maxpoll, peerflags, ttl, peerkey)
+ == 0) {
syslog(LOG_ERR,
"configuration of %s failed",
ntoa(&peeraddr));
}
} else if (errflg == -1) {
save_resolve(tokens[1], hmode, peerversion,
- minpoll, maxpoll, peerflags, peerkey);
+ minpoll, maxpoll, peerflags, ttl, peerkey);
}
break;
@@ -764,23 +801,20 @@ getconfig(argc, argv)
} break;
case CONFIG_BROADCASTCLIENT:
- errflg = 0;
- if (ntokens >= 2) {
- if (STREQ(tokens[1], "yes"))
- proto_config(PROTO_BROADCLIENT, (LONG)1);
- else if (STREQ(tokens[1], "no"))
- proto_config(PROTO_BROADCLIENT, (LONG)0);
- else
- errflg++;
- } else {
- errflg++;
- }
-
- if (errflg)
- syslog(LOG_ERR,
- "should be `broadcastclient yes|no'");
+ proto_config(PROTO_BROADCLIENT, (U_LONG)1);
break;
+ case CONFIG_MULTICASTCLIENT:
+ if (ntokens > 1) {
+ for (i = 1; i < ntokens; i++) {
+ if (getnetnum(tokens[i], &peeraddr, 1));
+ proto_config(PROTO_MULTICAST_ADD,
+ peeraddr.sin_addr.s_addr);
+ }
+ } else
+ proto_config(PROTO_MULTICAST_ADD, INADDR_NTP);
+ break;
+
case CONFIG_AUTHENTICATE:
errflg = 0;
if (ntokens >= 2) {
@@ -817,9 +851,9 @@ getconfig(argc, argv)
errflg = 0;
if (ntokens >= 2) {
if (STREQ(tokens[1], "yes"))
- mon_start();
+ mon_start(MON_ON);
else if (STREQ(tokens[1], "no"))
- mon_stop();
+ mon_stop(MON_ON);
else
errflg++;
} else {
@@ -965,6 +999,10 @@ getconfig(argc, argv)
peerkey |= RESM_NTPONLY;
break;
+ case CONF_RES_LIMITED:
+ peerversion |= RES_LIMITED;
+ break;
+
case CONFIG_UNKNOWN:
errflg++;
break;
@@ -1252,26 +1290,6 @@ getconfig(argc, argv)
#endif
break;
- case CONFIG_MAXSKEW:
- if (ntokens >= 2) {
- l_fp tmp;
- u_fp utmp;
-
- if (!atolfp(tokens[1], &tmp)) {
- syslog(LOG_ERR,
- "maxskew value %s undecodable",
- tokens[1]);
- } else if (tmp.l_ui != 0) {
- syslog(LOG_ERR,
- "maxskew value %s is unlikely",
- tokens[1]);
- } else {
- utmp = LFPTOFP(&tmp);
- proto_config(PROTO_MAXSKEW, (LONG)utmp);
- }
- }
- break;
-
case CONFIG_RESOLVER:
if (ntokens >= 2) {
if (strlen(tokens[1]) >= (size_t)MAXFILENAME) {
@@ -1288,18 +1306,6 @@ getconfig(argc, argv)
}
break;
- case CONFIG_SELECT:
- if (ntokens >= 2) {
- i = atoi(tokens[1]);
- if (i < SELECT_1 || i > SELECT_5)
- syslog(LOG_ERR,
- "invalid selection algorithm %s, line ignored",
- tokens[1]);
- else
- proto_config(PROTO_SELECT, (LONG)i);
- }
- break;
-
case CONFIG_STATSDIR:
if (ntokens >= 2) {
stats_config(STATS_STATSDIR,tokens[1]);
@@ -1414,6 +1420,60 @@ getconfig(argc, argv)
((((ntokens > 2) && !strcmp(tokens[2], "default"))) ? DEF : 0));
}
break;
+
+ case CONFIG_CLIENTLIMIT:
+ if (ntokens < 2)
+ {
+ syslog(LOG_ERR,
+ "no value for clientlimit command - line ignored");
+ }
+ else
+ {
+ U_LONG i;
+ if (!atouint(tokens[1], &i) || !i)
+ {
+ syslog(LOG_ERR,
+ "illegal value for clientlimit command - line ignored");
+ }
+ else
+ {
+ extern U_LONG client_limit;
+ char bp[80];
+
+ sprintf(bp, "client_limit=%d", i);
+ set_sys_var(bp, strlen(bp)+1, RO);
+
+ client_limit = i;
+ }
+ }
+ break;
+
+ case CONFIG_CLIENTPERIOD:
+ if (ntokens < 2)
+ {
+ syslog(LOG_ERR,
+ "no value for clientperiod command - line ignored");
+ }
+ else
+ {
+ U_LONG i;
+ if (!atouint(tokens[1], &i) || i < 64)
+ {
+ syslog(LOG_ERR,
+ "illegal value for clientperiod command - line ignored");
+ }
+ else
+ {
+ extern U_LONG client_limit_period;
+ char bp[80];
+
+ sprintf(bp, "client_limit_period=%d", i);
+ set_sys_var(bp, strlen(bp)+1, RO);
+
+ client_limit_period = i;
+ }
+ }
+ break;
}
}
(void) fclose(fp);
@@ -1643,13 +1703,14 @@ int sig;
* save_resolve - save configuration info into a file for later name resolution
*/
static void
-save_resolve(name, mode, version, minpoll, maxpoll, flags, keyid)
+save_resolve(name, mode, version, minpoll, maxpoll, flags, ttl, keyid)
char *name;
int mode;
int version;
int minpoll;
int maxpoll;
int flags;
+ int ttl;
U_LONG keyid;
{
if (res_fp == NULL) {
@@ -1668,8 +1729,8 @@ save_resolve(name, mode, version, minpoll, maxpoll, flags, keyid)
}
#endif
- (void) fprintf(res_fp, "%s %d %d %d %d %d %lu\n", name, mode,
- version, minpoll, maxpoll, flags, keyid);
+ (void) fprintf(res_fp, "%s %d %d %d %d %d %d %lu\n", name, mode,
+ version, minpoll, maxpoll, flags, ttl, keyid);
}
diff --git a/contrib/xntpd/xntpd/ntp_control.c b/contrib/xntpd/xntpd/ntp_control.c
index 1c7849f48820..ef9c37a6751d 100644
--- a/contrib/xntpd/xntpd/ntp_control.c
+++ b/contrib/xntpd/xntpd/ntp_control.c
@@ -264,8 +264,20 @@ static u_char def_clock_var[] = {
/*
* System and processor definitions. These will change for the gizmo board.
*/
+#ifndef HAVE_UNAME
+#ifndef STR_SYSTEM
+#define STR_SYSTEM "UNIX"
+#endif
+#ifndef STR_PROCESSOR
+#define STR_PROCESSOR "unknown"
+#endif
+
+static char str_system[] = STR_SYSTEM;
+static char str_processor[] = STR_PROCESSOR;
+#else
#include <sys/utsname.h>
static struct utsname utsname;
+#endif /* HAVE_UNAME */
/*
* Trap structures. We only allow a few of these, and send
@@ -294,7 +306,7 @@ static struct utsname utsname;
static u_char clocktypes[] = {
CTL_SST_TS_NTP, /* REFCLK_NONE */
CTL_SST_TS_UNSPEC, /* REFCLK_LOCALCLOCK */
- CTL_SST_TS_HF, /* REFCLK_WWV_HEATH */
+ CTL_SST_TS_UHF, /* REFCLK_GPS_TRAK */
CTL_SST_TS_HF, /* REFCLK_WWV_PST */
CTL_SST_TS_LF, /* REFCLK_WWVB_SPECTRACOM */
CTL_SST_TS_UHF, /* REFCLK_GOES_TRUETIME */
@@ -379,6 +391,7 @@ extern struct peer *sys_peer;
extern l_fp last_offset;
extern s_fp drift_comp;
extern int time_constant;
+extern int pll_control;
/*
* Imported from the leap module
*/
@@ -426,7 +439,9 @@ init_control()
{
int i;
+#ifdef HAVE_UNAME
uname(&utsname);
+#endif /* HAVE_UNAME */
ctl_clr_stats();
@@ -716,10 +731,12 @@ ctlsysstatus()
if (sys_peer != 0)
if (sys_peer->sstclktype != CTL_SST_TS_UNSPEC)
clock = sys_peer->sstclktype;
- else
+ else {
if (sys_peer->refclktype < sizeof(clocktypes))
clock = clocktypes[sys_peer->refclktype];
-
+ if (pps_control)
+ clock |= CTL_SST_TS_PPS;
+ }
return (u_short)CTL_SYS_STATUS(sys_leap, clock,
ctl_sys_num_events, ctl_sys_last_event);
}
@@ -1262,12 +1279,22 @@ ctl_putsys(varid)
ctl_putuint(sys_var[CS_LEAPWARNING].text, (U_LONG)leap_warning);
break;
case CS_PROCESSOR:
+#ifndef HAVE_UNAME
+ ctl_putstr(sys_var[CS_PROCESSOR].text, str_processor,
+ sizeof(str_processor) - 1);
+#else
ctl_putstr(sys_var[CS_PROCESSOR].text, utsname.machine,
strlen(utsname.machine));
+#endif /* HAVE_UNAME */
break;
case CS_SYSTEM:
- ctl_putstr(sys_var[CS_SYSTEM].text, utsname.sysname,
+#ifndef HAVE_UNAME
+ ctl_putstr(sys_var[CS_SYSTEM].text, str_system,
+ sizeof(str_system) - 1);
+#else
+ ctl_putstr(sys_var[CS_SYSTEM].text, utsname.sysname,
strlen(utsname.sysname));
+#endif /* HAVE_UNAME */
break;
case CS_KEYID:
ctl_putuint(sys_var[CS_KEYID].text, (U_LONG)0);
diff --git a/contrib/xntpd/xntpd/ntp_intres.c b/contrib/xntpd/xntpd/ntp_intres.c
index 20561e91b82d..5ff4af4d8242 100644
--- a/contrib/xntpd/xntpd/ntp_intres.c
+++ b/contrib/xntpd/xntpd/ntp_intres.c
@@ -48,6 +48,7 @@ struct conf_entry {
#define ce_minpoll ce_config.minpoll
#define ce_maxpoll ce_config.maxpoll
#define ce_flags ce_config.flags
+#define ce_ttl ce_config.ttl
#define ce_keyid ce_config.keyid
/*
@@ -102,8 +103,9 @@ static int resolve_value; /* next value of resolve timer */
#define TOK_MINPOLL 3
#define TOK_MAXPOLL 4
#define TOK_FLAGS 5
-#define TOK_KEYID 6
-#define NUMTOK 7
+#define TOK_TTL 6
+#define TOK_KEYID 7
+#define NUMTOK 8
#define MAXLINESIZE 512
@@ -128,7 +130,7 @@ extern int errno;
static RETSIGTYPE bong P((int));
static void checkparent P((void));
static void removeentry P((struct conf_entry *));
-static void addentry P((char *, int, int, int, int, int, U_LONG));
+static void addentry P((char *, int, int, int, int, int, int, U_LONG));
static int findhostaddr P((struct conf_entry *));
static void openntp P((void));
static int request P((struct conf_peer *));
@@ -279,13 +281,14 @@ removeentry(entry)
* addentry - add an entry to the configuration list
*/
static void
-addentry(name, mode, version, minpoll, maxpoll, flags, keyid)
+addentry(name, mode, version, minpoll, maxpoll, flags, ttl, keyid)
char *name;
int mode;
int version;
int minpoll;
int maxpoll;
int flags;
+ int ttl;
U_LONG keyid;
{
register char *cp;
@@ -304,6 +307,7 @@ addentry(name, mode, version, minpoll, maxpoll, flags, keyid)
ce->ce_minpoll = (u_char)minpoll;
ce->ce_maxpoll = (u_char)maxpoll;
ce->ce_flags = (u_char)flags;
+ ce->ce_ttl = (u_char)ttl;
ce->ce_keyid = htonl(keyid);
ce->ce_next = NULL;
@@ -751,7 +755,8 @@ readconf(fp, name)
*/
addentry(token[TOK_HOSTNAME], (int)intval[TOK_HMODE],
(int)intval[TOK_VERSION], (int)intval[TOK_MINPOLL],
- (int)intval[TOK_MAXPOLL], flags, intval[TOK_KEYID]);
+ (int)intval[TOK_MAXPOLL], flags, (int)intval[TOK_TTL],
+ intval[TOK_KEYID]);
}
}
diff --git a/contrib/xntpd/xntpd/ntp_io.c b/contrib/xntpd/xntpd/ntp_io.c
index 614d5c52bde9..551df510dc37 100644
--- a/contrib/xntpd/xntpd/ntp_io.c
+++ b/contrib/xntpd/xntpd/ntp_io.c
@@ -10,6 +10,10 @@
#include <sys/ioctl.h>
#include <sys/time.h>
+#ifdef MCAST
+#include "ntp_in.h"
+#endif /* MCAST */
+
#include "ntpd.h"
#include "ntp_select.h"
#include "ntp_io.h"
@@ -53,7 +57,6 @@
/*
* Block the interrupt, for critical sections.
*/
-
#if defined(HAVE_SIGNALED_IO)
#define BLOCKIO() ((void) block_sigio())
#define UNBLOCKIO() ((void) unblock_sigio())
@@ -228,6 +231,9 @@ create_sockets(port)
inter_list[0].sent = 0;
inter_list[0].notsent = 0;
inter_list[0].flags = INT_BROADCAST;
+#ifdef MCAST
+ inter_list[0].flags |= INT_MULTICAST;
+#endif /* MCAST */
#ifdef USE_STREAMS_DEVICE_FOR_IF_CONFIG
if ((vs = open("/dev/ip", O_RDONLY)) < 0) {
@@ -394,7 +400,7 @@ create_sockets(port)
maxactivefd = 0;
FD_ZERO(&activefds);
-
+
for (i = 0; i < ninterfaces; i++) {
inter_list[i].fd = open_socket(&inter_list[i].sin,
inter_list[i].flags & INT_BROADCAST);
@@ -458,23 +464,72 @@ io_setbclient()
}
+#ifdef MCAST
+/*
+ * io_multicast_add() - add multicast group address
+ */
+void
+io_multicast_add(addr)
+ U_LONG addr;
+{
+ int fd = inter_list[0].fd;
+ struct ip_mreq mreq;
+
+ if (!IN_CLASSD(addr))
+ return;
+ /*
+ * enable reception of multicast packets
+ */
+ mreq.imr_multiaddr.s_addr = addr;
+ mreq.imr_interface.s_addr = INADDR_ANY;
+ if (setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP,
+ (char *)&mreq, sizeof(mreq)) == -1)
+ syslog(LOG_ERR, "setsockopt IP_ADD_MEMBERSHIP fails: %m");
+}
+#endif /* MCAST */
+
+
/*
* io_unsetbclient - close the broadcast client sockets
*/
void
io_unsetbclient()
{
- int i;
+ int i;
for (i = 1; i < ninterfaces; i++) {
if (!(inter_list[i].flags & INT_BCASTOPEN))
continue;
close_socket(inter_list[i].bfd);
inter_list[i].flags &= ~INT_BCASTOPEN;
- }
+ }
}
+#ifdef MCAST
+/*
+ * io_multicast_del() - delete multicast group address
+ */
+void
+io_multicast_del(addr)
+ U_LONG addr;
+{
+ int fd = inter_list[0].fd;
+ struct ip_mreq mreq;
+
+ if (!IN_CLASSD(addr))
+ return;
+ /*
+ * disable reception of multicast packets
+ */
+ mreq.imr_multiaddr.s_addr = addr;
+ mreq.imr_interface.s_addr = INADDR_ANY;
+ if (setsockopt(fd, IPPROTO_IP, IP_DROP_MEMBERSHIP,
+ (char *)&mreq, sizeof(mreq)) == -1)
+ syslog(LOG_ERR, "setsockopt IP_DROP_MEMBERSHIP fails: %m");
+}
+#endif /* MCAST */
+
/*
* open_socket - open a socket, returning the file descriptor
@@ -510,7 +565,8 @@ open_socket(addr, bcast)
*/
if (bind(fd, (struct sockaddr *)addr, sizeof(*addr)) < 0) {
char buff[160];
- sprintf(buff, "bind() fd %d, family %d, port %d, addr %08x, bcast=%d fails: %%m",
+ sprintf(buff,
+ "bind() fd %d, family %d, port %d, addr %08x, bcast=%d fails: %%m",
fd,
addr->sin_family,
addr->sin_port,
@@ -557,6 +613,19 @@ Need non blocking I/O
syslog(LOG_ERR, "setsockopt SO_REUSEADDR off fails: %m");
}
+#ifdef MCAST
+ /* for the moment we use the bcast option to set multicast ttl */
+
+ if (bcast) {
+ unsigned char mttl = 127;
+
+ /* set the multicast ttl for outgoing packets */
+ if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_TTL,
+ &mttl, sizeof(mttl)) == -1) {
+ syslog(LOG_ERR, "setsockopt IP_MULTICAST_TTL fails: %m");
+ }
+ }
+#endif /* MCAST */
#ifdef SO_BROADCAST
/* if this interface can support broadcast, set SO_BROADCAST */
@@ -566,7 +635,7 @@ Need non blocking I/O
syslog(LOG_ERR, "setsockopt(SO_BROADCAST): %m");
}
}
-#endif
+#endif /* SO_BROADCAST */
#ifdef DEBUG
if (debug > 1)
@@ -608,7 +677,7 @@ struct interface *
findbcastinter(addr)
struct sockaddr_in *addr;
{
-#ifdef SIOCGIFCONF
+#ifdef SIOCGIFCONF
register int i;
register U_LONG netnum;
@@ -622,7 +691,7 @@ findbcastinter(addr)
== (netnum & NSRCADR(&inter_list[i].mask)))
return &inter_list[i];
}
-#endif
+#endif /* SIOCGIFCONF */
return any_interface;
}
@@ -744,7 +813,7 @@ sendpkt(dest, inter, pkt, len)
#ifdef DEBUG
if (debug)
- printf("sendpkt(%s, %s, %d)\n", ntoa(dest),
+ printf("sendpkt(fd=%d %s, %s, %d)\n", inter->fd, ntoa(dest),
ntoa(&inter->sin), len);
#endif
@@ -902,11 +971,16 @@ again:
}
if (FD_ISSET(fd, &fds)) {
n--;
+
/*
* Get a buffer and read the frame. If we
* haven't got a buffer, or this is received
* on the wild card socket, just dump the packet.
*/
+
+ if (!(free_recvbufs && i == 0 &&
+ inter_list[i].flags & INT_MULTICAST)) {
+
#ifdef UDP_WILDCARD_DELIVERY
/*
* these guys manage to put properly addressed packets into the wildcard queue
@@ -932,6 +1006,7 @@ again:
packets_dropped++;
continue;
}
+ }
rb = freelist;
freelist = rb->next;
@@ -958,7 +1033,7 @@ again:
if (debug)
printf("input_handler: fd=%d length %d\n", fd, rb->recv_length);
#endif
-
+
/*
* Got one. Mark how and when it got here,
* put it on the full list and do bookkeeping.
diff --git a/contrib/xntpd/xntpd/ntp_loopfilter.c b/contrib/xntpd/xntpd/ntp_loopfilter.c
index 6d79c5d52ff4..13cbd61b6741 100644
--- a/contrib/xntpd/xntpd/ntp_loopfilter.c
+++ b/contrib/xntpd/xntpd/ntp_loopfilter.c
@@ -9,9 +9,6 @@
#include "ntpd.h"
#include "ntp_io.h"
-#if defined(KERNEL_PLL)
-#include "ntp_timex.h"
-#endif /* KERNEL_PLL */
#include "ntp_unixtime.h"
#if defined(PPS) || defined(PPSCLK) || defined(PPSPPS)
@@ -46,11 +43,13 @@
#include "ntp_stdlib.h"
-#ifdef KERNEL_PLL
-#ifndef SYS_ntp_adjtime
-#define SYS_ntp_adjtime NTP_SYSCALL_ADJ
+#ifdef KERNEL_PLL
+#include <sys/timex.h>
+#ifndef NTP_SYSCALLS_LIBC
+#define ntp_gettime(t) syscall(SYS_ntp_gettime, (t))
+#define ntp_adjtime(t) syscall(SYS_ntp_adjtime, (t))
#endif
-#endif /* KERNEL_PLL */
+#endif /* KERNEL_PLL */
/*
* The loop filter is implemented in slavish adherence to the
@@ -95,17 +94,14 @@
#define RSH_DRIFT_TO_FRAC (CLOCK_DSCALE - 16)
#define RSH_DRIFT_TO_ADJ (RSH_DRIFT_TO_FRAC - CLOCK_ADJ)
#define RSH_FRAC_TO_FREQ (CLOCK_FREQ + CLOCK_ADJ - RSH_DRIFT_TO_FRAC)
+#define PPS_MAXAGE 120 /* pps signal timeout (s) */
+#define PPS_MAXUPDATE 600 /* pps update timeout (s) */
/*
- * Imported from the ntp_proto module
+ * Program variables
*/
-extern u_char sys_stratum;
-extern s_fp sys_rootdelay;
-extern u_fp sys_rootdispersion;
-extern s_char sys_precision;
-
l_fp last_offset; /* last adjustment done */
-static LONG clock_adjust; /* clock adjust register (fraction only) */
+static LONG clock_adjust; /* clock adjust (fraction only) */
s_fp drift_comp; /* drift compensation register */
static s_fp max_comp; /* drift limit imposed by max host clock slew */
@@ -114,11 +110,15 @@ static s_fp max_comp; /* drift limit imposed by max host clock slew */
static U_LONG tcadj_time; /* last time-constant adjust time */
U_LONG watchdog_timer; /* watchdog timer, in seconds */
-static int first_adjustment; /* set to 1 if waiting for first adjustment */
+static int first_adjustment; /* 1 if waiting for first adjustment */
static int tc_counter; /* time-constant hold counter */
- int pll_control; /* set nonzero if pll implemented in kernel */
- int pps_control; /* set nonzero if pps signal valid */
+static l_fp pps_offset; /* filtered pps offset */
+static u_fp pps_dispersion; /* pps dispersion */
+static U_LONG pps_time; /* last pps sample time */
+
+ int pps_control; /* true if working pps signal */
+ int pll_control; /* true if working kernel pll */
static l_fp pps_delay; /* pps tuning offset */
U_LONG pps_update; /* last pps update time */
int fdpps = -1; /* pps file descriptor */
@@ -154,29 +154,35 @@ static l_fp pps_delay; /* pps tuning offset */
( i == 300 ? B300 : 0 ))))))))
#define PPS_BAUD B38400 /* default serial port speed */
-#define PPS_MAXAGE 120 /* seconds after which we disbelieve pps */
-#define PPS_MAXUPDATE 600 /* seconds after which we disbelieve timecode */
+timecode */
#define PPS_DEV "/dev/pps" /* pps port */
#define PPS_FAC 3 /* pps shift (log2 trimmed samples) */
-#define NPPS 12 /* pps filter size (1<<PPS_FAC+2*PPS_TRIM) */
-#define PPS_TRIM 2 /* samples trimmed from median filter */
+#define PPS_TRIM 6 /* samples trimmed from median filter */
+#define NPPS ((1 << PPS_FAC) + 2 * PPS_TRIM) /* pps filter size */
#define PPS_XCPT "\377" /* intercept character */
#if defined(PPSCLK)
static struct refclockio io; /* given to the I/O handler */
static int pps_baud; /* baud rate of PPS line */
#endif /* PPSCLK */
-static l_fp pps_offset; /* filtered pps offset */
-static U_LONG pps_time; /* last pps sample time */
static U_LONG nsamples; /* number of pps samples collected */
static LONG samples[NPPS]; /* median filter for pps samples */
+
+#endif /* PPS || PPSCLK || PPSPPS */
+
+/*
+ * Imported from the ntp_proto module
+ */
+extern u_char sys_stratum;
+extern s_fp sys_rootdelay;
+extern u_fp sys_rootdispersion;
+extern s_char sys_precision;
+
/*
* Imported from ntp_io.c
*/
extern struct interface *loopback_interface;
-#endif /* PPS || PPSCLK || PPSPPS */
-
/*
* Imported from ntpd module
*/
@@ -191,10 +197,16 @@ extern U_LONG current_time; /* like it says, in seconds */
* sys_poll and sys_refskew are set here
*/
extern u_char sys_poll; /* log2 of system poll interval */
+extern u_char sys_leap; /* system leap bits */
extern l_fp sys_refskew; /* accumulated skew since last update */
extern u_fp sys_maxd; /* max dispersion of survivor list */
/*
+ * Imported from leap module
+ */
+extern u_char leapbits; /* sanitized leap bits */
+
+/*
* Function prototypes
*/
#if defined(PPS) || defined(PPSCLK) || defined(PPSPPS)
@@ -205,9 +217,15 @@ static void pps_receive P((struct recvbuf *));
#endif /* PPS || PPSCLK || PPSPPS */
#if defined(KERNEL_PLL)
+#define MOD_BITS (MOD_OFFSET | MOD_MAXERROR | MOD_ESTERROR | \
+ MOD_STATUS | MOD_TIMECONST)
extern int sigvec P((int, struct sigvec *, struct sigvec *));
+#ifndef NTP_SYSCALLS_LIBC
+extern int syscall P((int, void *, ...));
+#endif /* no NTP syscalls in libc */
void pll_trap P((void));
+static int pll_status; /* status bits for kernel pll */
static struct sigvec sigsys; /* current sigvec status */
static struct sigvec newsigsys; /* new sigvec status */
#endif /* KERNEL_PLL */
@@ -350,8 +368,8 @@ init_loopfilter()
}
}
#endif /* HAVE_BSD_TTYS */
- fdpps = fd232;
#endif /* HPUXGADGET */
+ fdpps = fd232;
/*
* Insert in device list.
@@ -399,7 +417,7 @@ local_clock(fp_offset, peer)
#ifdef DEBUG
if (debug > 1)
- printf("local_clock(%s, %s)\n", lfptoa(fp_offset, 9),
+ printf("local_clock(%s, %s)\n", lfptoa(fp_offset, 6),
ntoa(&peer->srcadr));
#endif
@@ -432,33 +450,26 @@ local_clock(fp_offset, peer)
last_offset = *fp_offset;
/*
- * If the magnitude of the offset is greater than CLOCK.MAX, step
- * the time and reset the registers.
+ * If the magnitude of the offset is greater than CLOCK.MAX,
+ * step the time and reset the registers.
*/
if (tmp_ui > CLOCK_MAX_I || (tmp_ui == CLOCK_MAX_I
&& (U_LONG)tmp_uf >= (U_LONG)CLOCK_MAX_F)) {
if (watchdog_timer < CLOCK_MINSTEP) {
/* Mustn't step yet, pretend we adjusted. */
-#ifdef SLEWALWAYS
syslog(LOG_INFO,
- "adjust: SLEW dropped (%s offset %s)\n",
- ntoa(&peer->srcadr), lfptoa(fp_offset, 9));
-#else
- syslog(LOG_INFO,
- "adjust: STEP dropped (%s offset %s)\n",
- ntoa(&peer->srcadr), lfptoa(fp_offset, 9));
-#endif
+ "clock correction %s too large (ignored)\n",
+ lfptoa(fp_offset, 6));
return (0);
}
+ syslog(LOG_NOTICE, "clock reset (%s) %s\n",
#ifdef SLEWALWAYS
- syslog(LOG_NOTICE, " ** adjust: SLEW %s offset %s **\n",
- ntoa(&peer->srcadr), lfptoa(fp_offset, 9));
+ "slew",
#else
- syslog(LOG_NOTICE, " ** adjust: STEP %s offset %s **\n",
- ntoa(&peer->srcadr), lfptoa(fp_offset, 9));
+ "step",
#endif
+ lfptoa(fp_offset, 6));
step_systime(fp_offset);
-
clock_adjust = 0;
watchdog_timer = 0;
first_adjustment = 1;
@@ -480,20 +491,24 @@ local_clock(fp_offset, peer)
* The time constant update goes after adjust and skew updates,
* as in appendix G.
*/
-#if defined(PPS) || defined(PPSCLK) || defined(PPSPPS)
/*
* If pps samples are valid, update offset, root delay and
- * root dispersion. This may be a dramatic surprise to high-
- * stratum clients, since all of a sudden this server looks
- * like a stratum-1 clock.
+ * root dispersion. Also, set the system stratum to 1, even if
+ * the source of approximate time runs at a higher stratum. This
+ * may be a dramatic surprise to high-stratum clients, since all
+ * of a sudden this server looks like a stratum-1 clock.
*/
if (pps_control) {
last_offset = pps_offset;
+ sys_maxd = pps_dispersion;
sys_stratum = 1;
sys_rootdelay = 0;
- sys_rootdispersion = sys_maxd;
+ offset = LFPTOFP(&pps_offset);
+ if (offset < 0)
+ offset = -offset;
+ sys_rootdispersion = offset + pps_dispersion;
}
-#endif /* PPS || PPSCLK || PPSPPS */
+ offset = last_offset.l_f;
/*
* The pll_control is active when the phase-lock code is
@@ -504,26 +519,56 @@ local_clock(fp_offset, peer)
* know the scaling of the frequency variable (s_fp) is the
* same as the kernel variable (1 << SHIFT_USEC = 16).
*
+ * For kernels with the PPS discipline, the current offset and
+ * dispersion are set from kernel variables to maintain
+ * beauteous displays, but don't do much of anything.
+ *
* In the case of stock kernels the phase-lock loop is
* implemented the hard way and the clock_adjust and drift_comp
* computed as required.
*/
- offset = last_offset.l_f;
if (pll_control) {
#if defined(KERNEL_PLL)
- ntv.mode = ADJ_OFFSET | ADJ_TIMECONST | ADJ_MAXERROR |
- ADJ_ESTERROR;
+ memset((char *)&ntv, 0, sizeof ntv);
+ ntv.modes = MOD_BITS;
if (offset >= 0) {
TSFTOTVU(offset, ntv.offset);
} else {
TSFTOTVU(-offset, ntv.offset);
ntv.offset = -ntv.offset;
}
- ntv.maxerror = sys_rootdispersion + sys_rootdelay / 2;
- ntv.esterror = sys_rootdispersion;
- ntv.time_constant = time_constant;
+ TSFTOTVU(sys_rootdispersion + sys_rootdelay / 2, ntv.maxerror);
+ TSFTOTVU(sys_rootdispersion, ntv.esterror);
+ ntv.status = pll_status;
+ if (pps_update)
+ ntv.status |= STA_PPSTIME;
+ if (sys_leap & LEAP_ADDSECOND &&
+ sys_leap & LEAP_DELSECOND)
+ ntv.status |= STA_UNSYNC;
+ else if (sys_leap & LEAP_ADDSECOND)
+ ntv.status |= STA_INS;
+ else if (sys_leap & LEAP_DELSECOND)
+ ntv.status |= STA_DEL;
+ ntv.constant = time_constant;
(void)ntp_adjtime(&ntv);
- drift_comp = ntv.frequency;
+ drift_comp = ntv.freq;
+ if (ntv.status & STA_PPSTIME && ntv.status & STA_PPSSIGNAL
+ && ntv.shift) {
+ if (ntv.offset >= 0) {
+ TVUTOTSF(ntv.offset, offset);
+ } else {
+ TVUTOTSF(-ntv.offset, offset);
+ offset = -offset;
+ }
+ pps_offset.l_i = pps_offset.l_f = 0;
+ M_ADDF(pps_offset.l_i, pps_offset.l_f, offset);
+ TVUTOTSF(ntv.jitter, tmp);
+ pps_dispersion = (tmp >> 16) & 0xffff;
+ pps_time = current_time;
+ record_peer_stats(&loopback_interface->sin,
+ ctlsysstatus(), &pps_offset, 0, pps_dispersion);
+ } else
+ pps_time = 0;
#endif /* KERNEL_PLL */
} else {
if (offset < 0) {
@@ -533,21 +578,14 @@ local_clock(fp_offset, peer)
}
/*
- * Calculate the new frequency error. The factor given in the
- * spec gives the adjustment per 2**CLOCK_ADJ seconds, but we
- * want it as a (scaled) pure ratio, so we include that factor
- * now and remove it later.
+ * Calculate the new frequency error. The factor given
+ * in the spec gives the adjustment per 2**CLOCK_ADJ
+ * seconds, but we want it as a (scaled) pure ratio, so
+ * we include that factor now and remove it later.
*/
if (first_adjustment) {
first_adjustment = 0;
} else {
- /*
- * Clamp the integration interval to maxpoll.
- * The bitcounting in Section 5 gives (n+1)-6 for 2**n,
- * but has a factor 2**6 missing from CLOCK_FREQ.
- * We make 2**n give n instead. If watchdog_timer is
- * zero, pretend it's one.
- */
tmp = peer->maxpoll;
tmp_uf = watchdog_timer;
if (tmp_uf == 0)
@@ -558,10 +596,11 @@ local_clock(fp_offset, peer)
}
/*
- * We apply the frequency scaling at the same time as
- * the sample interval; this ensures a safe right-shift.
- * (as long as it keeps below 31 bits, which current
- * parameters should ensure.
+ * We apply the frequency scaling at the same
+ * time as the sample interval; this ensures a
+ * safe right-shift. (as long as it keeps below
+ * 31 bits, which current parameters should
+ * ensure.
*/
tmp = (RSH_FRAC_TO_FREQ - tmp) +
time_constant + time_constant;
@@ -581,7 +620,9 @@ local_clock(fp_offset, peer)
/*
* Determine when to adjust the time constant and poll interval.
*/
- if (current_time - tcadj_time >= (1 << sys_poll)) {
+ if (pps_control)
+ time_constant = 0;
+ else if (current_time - tcadj_time >= (1 << sys_poll) && !pps_control) {
tcadj_time = current_time;
tmp = offset;
if (tmp < 0)
@@ -607,8 +648,8 @@ local_clock(fp_offset, peer)
#ifdef DEBUG
if (debug > 1)
printf("adj %s, drft %s, tau %3i\n",
- mfptoa((clock_adjust<0?-1:0), clock_adjust, 9),
- fptoa(drift_comp, 9), time_constant);
+ mfptoa((clock_adjust<0?-1:0), clock_adjust, 6),
+ fptoa(drift_comp, 6), time_constant);
#endif /* DEBUG */
(void) record_loop_stats(&last_offset, &drift_comp, time_constant);
@@ -662,20 +703,20 @@ adj_host_clock()
}
}
#endif /* PPSPPS */
- if (pps_time != 0 && current_time - pps_time > PPS_MAXAGE)
- pps_time = 0;
- if (pps_update != 0 && current_time - pps_update > PPS_MAXUPDATE)
- pps_update = 0;
- if (pps_time != 0 && pps_update != 0) {
+#endif /* PPS || PPSCLK || PPSPPS */
+ if (pps_time && current_time - pps_time > PPS_MAXAGE)
+ pps_time = 0;
+ if (pps_update && current_time - pps_update > PPS_MAXUPDATE)
+ pps_update = 0;
+ if (pps_time && pps_update) {
if (!pps_control)
- syslog(LOG_INFO, "pps synch");
+ syslog(LOG_INFO, "PPS synch");
pps_control = 1;
} else {
if (pps_control)
- syslog(LOG_INFO, "pps synch lost");
+ syslog(LOG_INFO, "PPS synch lost");
pps_control = 0;
}
-#endif /* PPS || PPSCLK || PPSPPS */
/*
* Resist the following code if the phase-lock loop has been
@@ -722,22 +763,27 @@ loop_config(item, lfp_value, int_value)
tmp = LFPTOFP(lfp_value);
if (tmp >= max_comp || tmp <= -max_comp) {
syslog(LOG_ERR,
- "loop_config: skew compensation %s too large",
+ "loop_config: frequency offset %s in ntp.conf file is too large",
fptoa(tmp, 5));
} else {
drift_comp = tmp;
#if defined(KERNEL_PLL)
/*
- * If the phase-lock code is implemented in the kernel,
- * give the time_constant and saved frequency offset
- * to the kernel. If not, no harm is done.
+ * If the phase-lock code is implemented in the
+ * kernel, give the time_constant and saved
+ * frequency offset to the kernel. If not, no
+ * harm is done.
*/
pll_control = 1;
- ntv.mode = ADJ_FREQUENCY | ADJ_STATUS | ADJ_TIMECONST;
- ntv.status = TIME_BAD;
- ntv.time_constant = time_constant;
- ntv.frequency = drift_comp;
+ pll_status = STA_PLL | STA_PPSFREQ;
+ ntv.modes = MOD_BITS | MOD_FREQUENCY;
+ ntv.offset = 0;
+ ntv.freq = drift_comp;
+ ntv.maxerror = NTP_MAXDISPERSE;
+ ntv.esterror = NTP_MAXDISPERSE;
+ ntv.status = pll_status | STA_UNSYNC;
+ ntv.constant = time_constant;
newsigsys.sv_handler = pll_trap;
newsigsys.sv_mask = 0;
newsigsys.sv_flags = 0;
@@ -748,13 +794,13 @@ loop_config(item, lfp_value, int_value)
if ((sigvec(SIGSYS, &sigsys, (struct sigvec *)NULL)))
syslog(LOG_ERR,
"sigvec() fails to restore SIGSYS trap: %m\n");
- syslog(LOG_NOTICE,
- "%susing kernel phase-lock loop",
- (pll_control) ? "" : "Not ");
-#if DEBUG
- if (debug)
- printf("pll_control %d\n", pll_control);
-#endif
+ if (pll_control)
+ syslog(LOG_NOTICE,
+ "using kernel phase-lock loop %04x",
+ ntv.status);
+ else
+ syslog(LOG_NOTICE,
+ "using xntpd phase-lock loop");
#endif /* KERNEL_PLL */
}
@@ -812,7 +858,7 @@ loop_config(item, lfp_value, int_value)
* _trap - trap processor for undefined syscalls
*
* This nugget is called by the kernel when the SYS_ntp_adjtime()
- * syscall bombs because the silly thing has not been implemented int
+ * syscall bombs because the silly thing has not been implemented in
* the kernel. In this case the phase-lock loop is emulated by
* the stock adjtime() syscall and a lot of indelicate abuse.
*/
@@ -873,12 +919,14 @@ int pps_sample(tsr)
int i, j; /* temp ints */
LONG sort[NPPS]; /* temp array for sorting */
l_fp lftemp, ts; /* l_fp temps */
+ u_fp utemp; /* u_fp temp */
LONG ltemp; /* long temp */
/*
* Note the seconds offset is already in the low-order timestamp
- * doubleword, so all we have to do is sign-extend and invert it.
- * The resulting offset is believed only if within CLOCK_MAX.
+ * doubleword, so all we have to do is sign-extend and invert
+ * it. The resulting offset is believed only if within
+ * CLOCK_MAX.
*/
ts = *tsr;
lftemp.l_i = lftemp.l_f = 0;
@@ -934,14 +982,14 @@ int pps_sample(tsr)
}
lftemp.l_i = 0;
lftemp.l_f = sort[NPPS-1-PPS_TRIM] - sort[PPS_TRIM];
- sys_maxd = LFPTOFP(&lftemp);
+ pps_dispersion = LFPTOFP(&lftemp);
#ifdef DEBUG
if (debug)
printf("pps_filter: %s %s %s\n", lfptoa(&pps_delay, 6),
lfptoa(&pps_offset, 6), lfptoa(&lftemp, 5));
#endif /* DEBUG */
- record_peer_stats(&loopback_interface->sin, ctlsysstatus(), &pps_offset,
- sys_rootdelay, sys_rootdispersion);
+ record_peer_stats(&loopback_interface->sin, ctlsysstatus(),
+ &pps_offset, 0, pps_dispersion);
return (0);
}
#endif /* PPS || PPSCLK || PPSPPS */
diff --git a/contrib/xntpd/xntpd/ntp_monitor.c b/contrib/xntpd/xntpd/ntp_monitor.c
index 63af8d4d4d97..e2d2eb51adac 100644
--- a/contrib/xntpd/xntpd/ntp_monitor.c
+++ b/contrib/xntpd/xntpd/ntp_monitor.c
@@ -58,7 +58,7 @@
static struct mon_data *mon_hash; /* Pointer to array of hash buckets */
static int *mon_hash_count; /* Point to hash count stats keeper */
struct mon_data mon_mru_list;
-
+ struct mon_data mon_fifo_list;
/*
* List of free structures structures, and counters of free and total
* structures. The free structures are linked with the hash_next field.
@@ -93,7 +93,7 @@ init_mon()
* Don't do much of anything here. We don't allocate memory
* until someone explicitly starts us.
*/
- mon_enabled = 0;
+ mon_enabled = MON_OFF;
mon_have_memory = 0;
mon_free_mem = 0;
@@ -103,6 +103,7 @@ init_mon()
mon_hash = 0;
mon_hash_count = 0;
memset((char *)&mon_mru_list, 0, sizeof mon_mru_list);
+ memset((char *)&mon_fifo_list, 0, sizeof mon_fifo_list);
}
@@ -110,13 +111,18 @@ init_mon()
* mon_start - start up the monitoring software
*/
void
-mon_start()
+mon_start(mode)
+ int mode;
{
register struct mon_data *md;
register int i;
- if (mon_enabled)
+ if (mon_enabled != MON_OFF) {
+ mon_enabled |= mode;
return;
+ }
+ if (mode == MON_OFF)
+ return; /* Ooops.. */
if (!mon_have_memory) {
mon_hash = (struct mon_data *)
@@ -142,7 +148,10 @@ mon_start()
mon_mru_list.mru_next = &mon_mru_list;
mon_mru_list.mru_prev = &mon_mru_list;
- mon_enabled = 1;
+ mon_fifo_list.fifo_next = &mon_fifo_list;
+ mon_fifo_list.fifo_prev = &mon_fifo_list;
+
+ mon_enabled = mode;
}
@@ -150,12 +159,19 @@ mon_start()
* mon_stop - stop the monitoring software
*/
void
-mon_stop()
+mon_stop(mode)
+ int mode;
{
register struct mon_data *md;
register int i;
- if (!mon_enabled)
+ if (mon_enabled == MON_OFF)
+ return;
+ if ((mon_enabled & mode) == 0 || mode == MON_OFF)
+ return;
+
+ mon_enabled &= ~mode;
+ if (mon_enabled != MON_OFF)
return;
/*
@@ -176,7 +192,8 @@ mon_stop()
mon_mru_list.mru_next = &mon_mru_list;
mon_mru_list.mru_prev = &mon_mru_list;
- mon_enabled = 0;
+ mon_fifo_list.fifo_next = &mon_fifo_list;
+ mon_fifo_list.fifo_prev = &mon_fifo_list;
}
@@ -194,7 +211,7 @@ monitor(rbufp)
register int mode;
register struct mon_data *mdhash;
- if (!mon_enabled)
+ if (mon_enabled == MON_OFF)
return;
pkt = &rbufp->recv_pkt;
@@ -220,6 +237,7 @@ monitor(rbufp)
md->mru_prev = &mon_mru_list;
mon_mru_list.mru_next->mru_prev = md;
mon_mru_list.mru_next = md;
+
return;
}
md = md->hash_next;
@@ -240,6 +258,12 @@ monitor(rbufp)
md->hash_next->hash_prev = md->hash_prev;
md->hash_prev->hash_next = md->hash_next;
*(mon_hash_count + MON_HASH(md->rmtadr)) -= 1;
+ /*
+ * Get it from FIFO list
+ */
+ md->fifo_prev->fifo_next = md->fifo_next;
+ md->fifo_next->fifo_prev = md->fifo_prev;
+
} else {
if (mon_free_mem == 0)
mon_getmoremem();
@@ -252,6 +276,7 @@ monitor(rbufp)
* Got one, initialize it
*/
md->lasttime = md->firsttime = current_time;
+ md->lastdrop = 0;
md->count = 1;
md->rmtadr = netnum;
md->rmtport = NSRCPORT(&rbufp->recv_srcadr);
@@ -260,7 +285,8 @@ monitor(rbufp)
/*
* Shuffle him into the hash table, inserting him at the
- * end. Also put him on top of the MRU list.
+ * end. Also put him on top of the MRU list
+ * and at bottom of FIFO list
*/
mdhash = mon_hash + MON_HASH(netnum);
md->hash_next = mdhash;
@@ -273,6 +299,11 @@ monitor(rbufp)
md->mru_prev = &mon_mru_list;
mon_mru_list.mru_next->mru_prev = md;
mon_mru_list.mru_next = md;
+
+ md->fifo_prev = mon_fifo_list.fifo_prev;
+ md->fifo_next = &mon_fifo_list;
+ mon_fifo_list.fifo_prev->fifo_next = md;
+ mon_fifo_list.fifo_prev = md;
}
diff --git a/contrib/xntpd/xntpd/ntp_peer.c b/contrib/xntpd/xntpd/ntp_peer.c
index cadd415346a9..9d8ec35dee78 100644
--- a/contrib/xntpd/xntpd/ntp_peer.c
+++ b/contrib/xntpd/xntpd/ntp_peer.c
@@ -340,22 +340,24 @@ unpeer(peer_to_remove)
* peer_config - configure a new peer
*/
struct peer *
-peer_config(srcadr, dstadr, hmode, version, minpoll, maxpoll, key, flags)
+peer_config(srcadr, dstadr, hmode, version, minpoll, maxpoll, flags, ttl, key)
struct sockaddr_in *srcadr;
struct interface *dstadr;
int hmode;
int version;
int minpoll;
int maxpoll;
- U_LONG key;
int flags;
+ int ttl;
+ U_LONG key;
{
register struct peer *peer;
#ifdef DEBUG
if (debug)
- printf("peer_config: addr %s mode %d version %d minpoll %d maxpoll %d key %u\n",
- ntoa(srcadr), hmode, version, minpoll, maxpoll, key);
+ printf("peer_config: addr %s mode %d version %d minpoll %d maxpoll %d flags %d ttl %d key %u\n",
+ ntoa(srcadr), hmode, version, minpoll, maxpoll, flags,
+ ttl, key);
#endif
/*
* See if we have this guy in the tables already. If
@@ -387,6 +389,7 @@ peer_config(srcadr, dstadr, hmode, version, minpoll, maxpoll, key, flags)
peer->ppoll = peer->minpoll;
peer->flags = ((u_char)(flags|FLAG_CONFIG))
|(peer->flags & (FLAG_REFCLOCK|FLAG_DEFBDELAY));
+ peer->ttl = (u_char)ttl;
peer->keyid = key;
return peer;
}
@@ -395,7 +398,8 @@ peer_config(srcadr, dstadr, hmode, version, minpoll, maxpoll, key, flags)
* If we're here this guy is unknown to us. Make a new peer
* structure for him.
*/
- peer = newpeer(srcadr, dstadr, hmode, version, minpoll, maxpoll, key);
+ peer = newpeer(srcadr, dstadr, hmode, version, minpoll, maxpoll,
+ ttl, key);
if (peer != 0)
peer->flags |= (u_char)(flags|FLAG_CONFIG);
return peer;
@@ -406,13 +410,14 @@ peer_config(srcadr, dstadr, hmode, version, minpoll, maxpoll, key, flags)
* newpeer - initialize a new peer association
*/
struct peer *
-newpeer(srcadr, dstadr, hmode, version, minpoll, maxpoll, key)
+newpeer(srcadr, dstadr, hmode, version, minpoll, maxpoll, ttl, key)
struct sockaddr_in *srcadr;
struct interface *dstadr;
int hmode;
int version;
int minpoll;
int maxpoll;
+ int ttl;
U_LONG key;
{
register struct peer *peer;
@@ -454,13 +459,10 @@ newpeer(srcadr, dstadr, hmode, version, minpoll, maxpoll, key)
peer->maxpoll = (u_char)maxpoll;
peer->hpoll = peer->minpoll;
peer->ppoll = peer->minpoll;
+ peer->ttl = ttl;
peer->keyid = key;
-
- if (hmode == MODE_BCLIENT) {
- peer->estbdelay = sys_bdelay;
- peer->flags |= FLAG_DEFBDELAY;
- }
-
+ peer->estbdelay = sys_bdelay;
+ peer->flags |= FLAG_DEFBDELAY;
peer->leap = LEAP_NOTINSYNC;
peer->precision = DEFPRECISION;
peer->dispersion = NTP_MAXDISPERSE;
diff --git a/contrib/xntpd/xntpd/ntp_proto.c b/contrib/xntpd/xntpd/ntp_proto.c
index 88e95bbf8d13..a3f744eae881 100644
--- a/contrib/xntpd/xntpd/ntp_proto.c
+++ b/contrib/xntpd/xntpd/ntp_proto.c
@@ -25,7 +25,7 @@ l_fp sys_reftime; /* time we were last updated */
l_fp sys_refskew; /* accumulated skew since last update */
struct peer *sys_peer; /* our current peer */
u_char sys_poll; /* log2 of desired system poll interval */
-LONG sys_clock; /* second part of current time */
+extern LONG sys_clock; /* second part of current time - now in systime.c */
LONG sys_lastselect; /* sys_clock at last synch-dist update */
/*
@@ -48,7 +48,7 @@ U_LONG sys_unknownversion; /* don't know version packets */
U_LONG sys_badlength; /* packets with bad length */
U_LONG sys_processed; /* packets processed */
U_LONG sys_badauth; /* packets dropped because of authorization */
-U_LONG sys_wanderhold; /* sys_peer held to prevent wandering */
+U_LONG sys_limitrejected; /* pkts rejected due toclient count per net */
/*
* Imported from ntp_timer.c
@@ -90,7 +90,8 @@ transmit(peer)
struct pkt xpkt; /* packet to send */
U_LONG peer_timer;
- if (peer->hmode != MODE_BCLIENT) {
+ if ((peer->hmode != MODE_BROADCAST && peer->hmode != MODE_BCLIENT) ||
+ (peer->hmode == MODE_BROADCAST && sys_leap != LEAP_NOTINSYNC)) {
U_LONG xkeyid;
/*
@@ -239,17 +240,14 @@ transmit(peer)
/*
* Finally, adjust the hpoll variable for special conditions.
*/
- if (peer->flags & FLAG_SYSPEER && peer->hpoll > sys_poll) {
- /* clamp it */
+ if (peer->hmode == MODE_BCLIENT)
+ peer->hpoll = peer->ppoll;
+ else if (peer->flags & FLAG_SYSPEER &&
+ peer->hpoll > sys_poll)
peer->hpoll = max(peer->minpoll, sys_poll);
- }
- if (peer->hmode == MODE_BROADCAST || peer->hmode == MODE_BCLIENT) {
- /* clamp it */
- peer->hpoll = peer->minpoll;
- }
/*
- * Arrange for our next time out. hpoll will be less than
+ * Arrange for our next timeout. hpoll will be less than
* maxpoll for sure.
*/
if (peer->event_timer.next != 0)
@@ -262,37 +260,6 @@ transmit(peer)
TIMER_ENQUEUE(timerqueue, &peer->event_timer);
}
-#if 0
-static void
-ct_die(after)
-{
- syslog(LOG_ERR, "timers garbled (%s)", after?"after":"before");
- abort();
-}
-
-void
-check_timers(after)
-{
- register int i;
- register struct event *p, *q;
-
- for (i = 0; i < TIMER_NSLOTS; i++) {
- p = &timerqueue[i];
- if (p->event_time != 0)
- ct_die(after);
- do {
- q = p;
- if ((p = p->next) == 0)
- ct_die(after);
- if (p->prev != q)
- ct_die(after);
- } while (p->event_time != 0);
- if (p != &timerqueue[i])
- ct_die(after);
- }
-}
-#endif
-
/*
* receive - Receive Procedure. See section 3.4.2 in the specification.
*/
@@ -373,6 +340,21 @@ receive(rbufp)
return;
/*
+ * See if we only accept limited number of clients
+ * from the net this guy is from.
+ * Note: the flag is determined dynamically within restrictions()
+ */
+ if (restrict & RES_LIMITED) {
+ extern U_LONG client_limit;
+
+ sys_limitrejected++;
+ syslog(LOG_NOTICE,
+ "rejected mode %d request from %s - per net client limit (%d) exceeded",
+ PKT_MODE(pkt->li_vn_mode),
+ ntoa(&rbufp->recv_srcadr), client_limit);
+ return;
+ }
+ /*
* Dump anything with a putrid stratum. These will most likely
* come from someone trying to poll us with ntpdc.
*/
@@ -517,6 +499,9 @@ receive(rbufp)
break;
case MODE_PASSIVE:
+#ifdef MCAST
+ /* process the packet to determine the rt-delay */
+#endif /* MCAST */
case MODE_SERVER:
/*
* These are obvious errors. Ignore.
@@ -534,8 +519,10 @@ receive(rbufp)
/*
* Sort of a repeat of the above...
*/
+/*
if ((restrict & RES_NOPEER) || !sys_bclient)
return;
+*/
mymode = MODE_BCLIENT;
break;
}
@@ -546,7 +533,7 @@ receive(rbufp)
*/
peer = newpeer(&rbufp->recv_srcadr, rbufp->dstadr, mymode,
PKT_VERSION(pkt->li_vn_mode), NTP_MINDPOLL,
- NTP_MAXPOLL, hiskeyid);
+ NTP_MAXPOLL, 0, hiskeyid);
if (peer == 0) {
/*
* The only way this can happen is if the
@@ -706,12 +693,11 @@ receive(rbufp)
* out to be bad.
*/
peer2 = newpeer(&rbufp->recv_srcadr,
- rbufp->dstadr, MODE_PASSIVE,
- PKT_VERSION(pkt->li_vn_mode),
- NTP_MINDPOLL, NTP_MAXPOLL,
- hiskeyid);
+ rbufp->dstadr, MODE_PASSIVE,
+ PKT_VERSION(pkt->li_vn_mode),
+ NTP_MINDPOLL, NTP_MAXPOLL, 0, hiskeyid);
if (process_packet(peer2, pkt, &rbufp->recv_time,
- has_mac, trustable) == 0) {
+ has_mac, trustable) == 0) {
/*
* Strange situation. We've been receiving
* broadcasts from him which we liked, but
@@ -769,20 +755,21 @@ process_packet(peer, pkt, recv_ts, has_mac, trustable)
sys_processed++;
peer->processed++;
-
- peer->rec = *recv_ts;
p_dist = NTOHS_FP(pkt->rootdelay);
p_disp = NTOHS_FP(pkt->rootdispersion);
NTOHL_FP(&pkt->rec, &p_rec);
NTOHL_FP(&pkt->xmt, &p_xmt);
- NTOHL_FP(&pkt->org, &p_org);
+ if (PKT_MODE(pkt->li_vn_mode) != MODE_BROADCAST)
+ NTOHL_FP(&pkt->org, &p_org);
+ else
+ p_org = peer->rec;
+ peer->rec = *recv_ts;
peer->flash = 0;
randomize = POLL_RANDOMCHANGE;
/*
* Test for old or duplicate packets (tests 1 through 3).
*/
-
if (L_ISHIS(&peer->org, &p_xmt)) /* count old packets */
peer->oldpkt++;
if (L_ISEQU(&peer->org, &p_xmt)) /* test 1 */
@@ -796,6 +783,9 @@ process_packet(peer, pkt, recv_ts, has_mac, trustable)
if ((p_rec.l_ui == 0 && p_rec.l_uf == 0) ||
(p_org.l_ui == 0 && p_org.l_uf == 0))
peer->flash |= TEST3; /* unsynchronized */
+ } else {
+ if (p_org.l_ui == 0 && p_org.l_uf == 0)
+ peer->flash |= TEST3; /* unsynchronized */
}
peer->org = p_xmt; /* reuse byte-swapped pkt->xmt */
peer->ppoll = pkt->ppoll;
@@ -901,39 +891,23 @@ process_packet(peer, pkt, recv_ts, has_mac, trustable)
ci.l_ui = t10_ui;
ci.l_uf = t10_uf;
ei = (FP_SECOND >> (-(int)sys_precision));
- if (peer->hmode == MODE_BCLIENT) {
-#ifdef notdef
- if (PKT_MODE(pkt->li_vn_mode) == MODE_CLIENT) {
- /*
- * A client mode packet, used for delay computation.
- * Give the data to the filter.
- */
- bdelay_filter(peer, t23_ui, t23_uf, t10_ui, t10_uf);
- }
-#endif
- M_ADDUF(ci.l_ui, ci.l_uf, peer->estbdelay>>1);
+
+ /*
+ * If broadcast mode, time of last reception has been fiddled
+ * to p_org, rather than originate timestamp. We use this to
+ * augment dispersion and previously calcuated estbdelay as
+ * the delay. We know NTP_SKEWFACTOR == 16, which accounts for
+ * the simplified ei calculation.
+ */
+ if (PKT_MODE(pkt->li_vn_mode) == MODE_BROADCAST) {
+ M_ADDUF(ci.l_ui, ci.l_uf, peer->estbdelay >> 1);
di = MFPTOFP(0, peer->estbdelay);
+ ei += peer->rec.l_ui - p_org.l_ui;
} else {
M_ADD(ci.l_ui, ci.l_uf, t23_ui, t23_uf);
M_RSHIFT(ci.l_i, ci.l_uf);
-
- /*
- * Calculate di in t23 in full precision, then truncate
- * to an s_fp.
- */
M_SUB(t23_ui, t23_uf, t10_ui, t10_uf);
di = MFPTOFP(t23_ui, t23_uf);
- /*
- * Calculate (t3 - t0) in t23 in full precision, convert
- * to single, shift down by MAXSKEW and add to ei.
- * We know NTP_SKEWFACTOR == 16
- */
-#if 0
- t23_ui = peer->rec.l_ui; /* peer->rec == t0 */
- t23_uf = peer->rec.l_uf;
- M_SUB(t23_ui, t23_uf, p_org.l_ui, p_org.l_uf); /*pkt->org==t3*/
- ei += (MFPTOFP(t23_ui, t23_uf) >> NTP_SKEWFACTOR);
-#endif
ei += peer->rec.l_ui - p_org.l_ui;
}
#ifdef DEBUG
@@ -1057,9 +1031,7 @@ clock_update(peer)
if (d < 0)
d = -d;
sys_rootdelay = peer->rootdelay + d;
- sys_maxd = peer->dispersion;
- if (peer->flags & FLAG_PREFER)
- sys_maxd += peer->selectdisp;
+ sys_maxd = peer->dispersion + peer->selectdisp;
d = peer->soffset;
if (d < 0)
d = -d;
@@ -1155,7 +1127,7 @@ poll_update(peer, new_hpoll, randomize)
* Catch reference clocks here. The polling interval for a
* reference clock is fixed and needn't be maintained by us.
*/
- if (peer->flags & FLAG_REFCLOCK)
+ if (peer->flags & FLAG_REFCLOCK || peer->hmode == MODE_BROADCAST)
return;
/*
@@ -1177,7 +1149,9 @@ poll_update(peer, new_hpoll, randomize)
* less that peer.timer, update peer.timer.
*/
oldpoll = peer->hpoll;
- if ((peer->flags & FLAG_SYSPEER) && new_hpoll > sys_poll)
+ if (peer->hmode == MODE_BCLIENT)
+ peer->hpoll = peer->ppoll;
+ else if ((peer->flags & FLAG_SYSPEER) && new_hpoll > sys_poll)
peer->hpoll = max(peer->minpoll, sys_poll);
else {
if (new_hpoll > peer->maxpoll)
@@ -1192,10 +1166,10 @@ poll_update(peer, new_hpoll, randomize)
newpoll = max((u_char)min(peer->ppoll, peer->hpoll), peer->minpoll);
if (randomize == POLL_MAKERANDOM ||
(randomize == POLL_RANDOMCHANGE && newpoll != oldpoll))
- new_timer = (1<<(newpoll - 1))
+ new_timer = (1 << (newpoll - 1))
+ ranp2(newpoll - 1) + current_time;
else
- new_timer = (1<<newpoll) + current_time;
+ new_timer = (1 << newpoll) + current_time;
evp = &(peer->event_timer);
if (evp->next == 0 || evp->event_time > new_timer) {
TIMER_DEQUEUE(evp);
@@ -1342,26 +1316,10 @@ clock_filter(peer, sample_offset, sample_delay, sample_error)
/*
* Find where he goes in, then shift everyone else down
*/
- if (peer->hmode == MODE_BCLIENT) {
- register s_fp *soffsetp;
- /*
- * Sort by offset. The most positive offset
- * should correspond to the minimum delay.
- */
- soffsetp = peer->filter_soffset;
- for (i = 0; i < NTP_SHIFT-1; i++)
- if (errorp[ord[i]] >= NTP_MAXDISPERSE
- || sample_soffset >= soffsetp[ord[i]])
- break;
- } else {
- /*
- * Sort by distance.
- */
- for (i = 0; i < NTP_SHIFT-1; i++)
- if (errorp[ord[i]] >= NTP_MAXDISPERSE
- || sample_distance <= distance[ord[i]])
- break;
- }
+ for (i = 0; i < NTP_SHIFT-1; i++)
+ if (errorp[ord[i]] >= NTP_MAXDISPERSE
+ || sample_distance <= distance[ord[i]])
+ break;
for (j = NTP_SHIFT-1; j > i; j--)
ord[j] = ord[j-1];
@@ -1676,7 +1634,7 @@ clock_select()
if (d < 0)
d = -d;
sdisp += d;
- sdisp = ((sdisp>>1) + sdisp) >> 1;
+ sdisp = ((sdisp >> 1) + sdisp) >> 1;
}
peer_list[i]->selectdisp = sdisp;
if (sdisp > maxd) {
@@ -1729,9 +1687,7 @@ clock_select()
for (i = 1; i < nlist; i++)
if (peer_list[i] == sys_peer)
break;
- if (i < nlist)
- sys_wanderhold++;
- else
+ if (i >= nlist)
sys_peer = peer_list[0];
}
@@ -2064,7 +2020,6 @@ init_proto()
sys_unknownversion = 0;
sys_processed = 0;
sys_badauth = 0;
- sys_wanderhold = 0;
syslog(LOG_NOTICE, "default precision is initialized to 2**%d", sys_precision);
}
@@ -2076,7 +2031,7 @@ init_proto()
void
proto_config(item, value)
int item;
- LONG value;
+ U_LONG value;
{
/*
* Figure out what he wants to change, then do it
@@ -2087,11 +2042,33 @@ proto_config(item, value)
* Turn on/off facility to listen to broadcasts
*/
sys_bclient = (int)value;
- if (sys_bclient)
+ if (value)
io_setbclient();
else
io_unsetbclient();
break;
+
+ case PROTO_MULTICAST_ADD:
+ /*
+ * Add multicast group address
+ */
+ if (!sys_bclient) {
+ sys_bclient = 1;
+ io_setbclient();
+ }
+#ifdef MCAST
+ io_multicast_add(value);
+#endif /* MCAST */
+ break;
+
+ case PROTO_MULTICAST_DEL:
+ /*
+ * Delete multicast group address
+ */
+#ifdef MCAST
+ io_multicast_del(value);
+#endif /* MCAST */
+ break;
case PROTO_PRECISION:
/*
@@ -2104,7 +2081,7 @@ proto_config(item, value)
/*
* Set default broadcast delay
*/
- sys_bdelay = (((U_LONG)value) + 0x00000800) & 0xfffff000;
+ sys_bdelay = ((value) + 0x00000800) & 0xfffff000;
break;
case PROTO_AUTHENTICATE:
@@ -2120,23 +2097,7 @@ proto_config(item, value)
* Provide an authentication delay value. Round it to
* the microsecond. This is crude.
*/
- sys_authdelay = (((U_LONG)value) + 0x00000800) & 0xfffff000;
- break;
-
- case PROTO_MAXSKEW:
- /*
- * Set the maximum skew value
- */
- syslog(LOG_ERR,
- "proto_config: attempt to set maxskew (obsolete)");
- break;
-
- case PROTO_SELECT:
- /*
- * Set the selection algorithm.
- */
- syslog(LOG_ERR,
- "proto_config: attempt to set selection algorithm (obsolete)");
+ sys_authdelay = ((value) + 0x00000800) & 0xfffff000;
break;
default:
@@ -2163,6 +2124,6 @@ proto_clr_stats()
sys_badlength = 0;
sys_processed = 0;
sys_badauth = 0;
- sys_wanderhold = 0;
sys_stattime = current_time;
+ sys_limitrejected = 0;
}
diff --git a/contrib/xntpd/xntpd/ntp_refclock.c b/contrib/xntpd/xntpd/ntp_refclock.c
index 5199a1acbd26..2cb7cc29d9a4 100644
--- a/contrib/xntpd/xntpd/ntp_refclock.c
+++ b/contrib/xntpd/xntpd/ntp_refclock.c
@@ -93,17 +93,6 @@ refclock_newpeer(peer)
peer->stratum = STRATUM_REFCLOCK;
peer->ppoll = peer->minpoll;
peer->hpoll = peer->minpoll;
- peer->maxpoll = peer->minpoll;
-
- /*
- * Check the flags. If the peer is configured in client mode
- * but prefers the broadcast client filter algorithm, change
- * him over.
- */
- if (peer->hmode == MODE_CLIENT
- && refclock_conf[clktype]->clock_flags & REF_FLAG_BCLIENT)
- peer->hmode = MODE_BCLIENT;
-
peer->event_timer.peer = peer;
peer->event_timer.event_handler = refclock_transmit;
@@ -201,20 +190,14 @@ refclock_transmit(peer)
l_fp off;
- if (peer->valid > 0) peer->valid--;
- if (peer->hpoll > peer->minpoll) peer->hpoll--;
+ if (peer->valid > 0)
+ peer->valid--;
off.l_ui = off.l_uf = 0;
clock_filter(peer, &off, 0, NTP_MAXDISPERSE);
if (peer->flags & FLAG_SYSPEER)
- clock_select();
- } else {
- if (peer->valid < NTP_SHIFT) {
- peer->valid++;
- } else {
- if (peer->hpoll < peer->maxpoll)
- peer->hpoll++;
- }
- }
+ clock_select();
+ } else if (peer->valid < NTP_SHIFT)
+ peer->valid++;
/*
* If he wants to be polled, do it.
@@ -313,9 +296,6 @@ refclock_receive(peer, offset, delay, dispersion, reftime, rectime, leap)
case MODE_CLIENT:
peer->pmode = MODE_SERVER;
break;
- case MODE_BCLIENT:
- peer->pmode = MODE_BROADCAST;
- break;
default:
syslog(LOG_ERR, "refclock_receive: internal error, mode = %d",
peer->hmode);
diff --git a/contrib/xntpd/xntpd/ntp_request.c b/contrib/xntpd/xntpd/ntp_request.c
index c19d1925a818..355b13b42b28 100644
--- a/contrib/xntpd/xntpd/ntp_request.c
+++ b/contrib/xntpd/xntpd/ntp_request.c
@@ -16,6 +16,14 @@
#include "ntp_if.h"
#include "ntp_stdlib.h"
+#ifdef KERNEL_PLL
+#include <sys/timex.h>
+#ifndef NTP_SYSCALLS_LIBC
+#define ntp_gettime(t) syscall(SYS_ntp_gettime, (t))
+#define ntp_adjtime(t) syscall(SYS_ntp_adjtime, (t))
+#endif
+#endif /* KERNEL_PLL */
+
/*
* Structure to hold request procedure information
*/
@@ -56,7 +64,7 @@ static void do_conf P((struct sockaddr_in *, struct interface *, struct req_pkt
static void do_unconf P((struct sockaddr_in *, struct interface *, struct req_pkt *));
static void set_sys_flag P((struct sockaddr_in *, struct interface *, struct req_pkt *));
static void clr_sys_flag P((struct sockaddr_in *, struct interface *, struct req_pkt *));
-static void setclr_flags P((struct sockaddr_in *, struct interface *, struct req_pkt *, int));
+static void setclr_flags P((struct sockaddr_in *, struct interface *, struct req_pkt *, U_LONG));
static void do_monitor P((struct sockaddr_in *, struct interface *, struct req_pkt *));
static void do_nomonitor P((struct sockaddr_in *, struct interface *, struct req_pkt *));
static void list_restrict P((struct sockaddr_in *, struct interface *, struct req_pkt *));
@@ -83,13 +91,14 @@ static void set_request_keyid P((struct sockaddr_in *, struct interface *, struc
static void set_control_keyid P((struct sockaddr_in *, struct interface *, struct req_pkt *));
static void get_ctl_stats P((struct sockaddr_in *, struct interface *, struct req_pkt *));
static void get_leap_info P((struct sockaddr_in *, struct interface *, struct req_pkt *));
+#ifdef KERNEL_PLL
+static void get_kernel_info P((struct sockaddr_in *, struct interface *, struct req_pkt *));
+#endif /* KERNEL_PLL */
#ifdef REFCLOCK
static void get_clock_info P((struct sockaddr_in *, struct interface *, struct req_pkt *));
static void set_clock_fudge P((struct sockaddr_in *, struct interface *, struct req_pkt *));
#endif /* REFCLOCK */
-static void set_maxskew P((struct sockaddr_in *, struct interface *, struct req_pkt *));
static void set_precision P((struct sockaddr_in *, struct interface *, struct req_pkt *));
-static void set_select_code P((struct sockaddr_in *, struct interface *, struct req_pkt *));
#ifdef REFCLOCK
static void get_clkbug_info P((struct sockaddr_in *, struct interface *, struct req_pkt *));
#endif /* REFCLOCK */
@@ -134,9 +143,10 @@ static struct req_proc xntp_codes[] = {
{ REQ_CONTROL_KEY, AUTH, sizeof(U_LONG), set_control_keyid },
{ REQ_GET_CTLSTATS, NOAUTH, 0, get_ctl_stats },
{ REQ_GET_LEAPINFO, NOAUTH, 0, get_leap_info },
- { REQ_SET_MAXSKEW, AUTH, sizeof(u_fp), set_maxskew },
{ REQ_SET_PRECISION, AUTH, sizeof(LONG), set_precision },
- { REQ_SET_SELECT_CODE, AUTH, sizeof(U_LONG), set_select_code },
+#ifdef KERNEL_PLL
+ { REQ_GET_KERNEL, NOAUTH, 0, get_kernel_info },
+#endif /* KERNEL_PLL */
#ifdef REFCLOCK
{ REQ_GET_CLOCKINFO, NOAUTH, sizeof(U_LONG), get_clock_info },
{ REQ_SET_CLKFUDGE, AUTH, sizeof(struct conf_fudge), set_clock_fudge },
@@ -162,6 +172,10 @@ U_LONG numresppkts; /* number of resp packets sent with data */
U_LONG errorcounter[INFO_ERR_AUTH+1]; /* lazy way to count errors, indexed */
/* by the error code */
+#if defined(KERNEL_PLL) && !defined(NTP_SYSCALLS_LIBC)
+extern int syscall P((int, void *, ...));
+#endif /* KERNEL_PLL */
+
/*
* Imported from the I/O module
*/
@@ -178,6 +192,11 @@ extern int debug;
extern U_LONG current_time;
/*
+ * Imported from ntp_loopfilter.c
+ */
+extern int pll_control;
+
+/*
* A hack. To keep the authentication module clear of xntp-ism's, we
* include a time reset variable for its stats here.
*/
@@ -657,6 +676,7 @@ peer_list_sum(srcadr, inter, inpkt)
ips->delay = HTONS_FP(pp->delay);
HTONL_FP(&pp->offset, &ips->offset);
ips->dispersion = HTONS_FP(pp->dispersion);
+
pp = pp->next;
ips = (struct info_peer_summary *)more_pkt();
}
@@ -724,7 +744,9 @@ peer_info (srcadr, inter, inpkt)
ip->valid = pp->valid;
ip->reach = pp->reach;
ip->unreach = pp->unreach;
- ip->trust = 0;
+ ip->flash = pp->flash;
+ ip->estbdelay = htonl(pp->estbdelay);
+ ip->ttl = pp->ttl;
ip->associd = htons(pp->associd);
ip->rootdelay = HTONS_FP(pp->rootdelay);
ip->rootdispersion = HTONS_FP(pp->rootdispersion);
@@ -745,12 +767,10 @@ peer_info (srcadr, inter, inpkt)
if (ip->order[i] >= NTP_SHIFT)
ip->order[i] -= NTP_SHIFT;
}
- ip->delay = HTONS_FP(pp->delay);
HTONL_FP(&pp->offset, &ip->offset);
+ ip->delay = HTONS_FP(pp->delay);
ip->dispersion = HTONS_FP(pp->dispersion);
- for (i = 0; i < NTP_SHIFT; i++)
- ip->bdelay[i] = 0;
- ip->estbdelay = htonl(pp->estbdelay);
+ ip->selectdisp = HTONS_FP(pp->selectdisp);
ip = (struct info_peer *)more_pkt();
}
flush_pkt();
@@ -882,12 +902,8 @@ sys_info(srcadr, inter, inpkt)
is->flags |= INFO_FLAG_BCLIENT;
if (sys_authenticate)
is->flags |= INFO_FLAG_AUTHENABLE;
- is->selection = 0; /* Obsolete */
-
HTONL_UF(sys_bdelay, &is->bdelay);
HTONL_UF(sys_authdelay, &is->authdelay);
- is->maxskew = 0;
-
(void) more_pkt();
flush_pkt();
}
@@ -915,7 +931,7 @@ sys_stats(srcadr, inter, inpkt)
extern U_LONG sys_badlength;
extern U_LONG sys_processed;
extern U_LONG sys_badauth;
- extern U_LONG sys_wanderhold;
+ extern U_LONG sys_limitrejected;
ss = (struct info_sys_stats *)prepare_pkt(srcadr, inter, inpkt,
sizeof(struct info_sys_stats));
@@ -929,8 +945,7 @@ sys_stats(srcadr, inter, inpkt)
ss->badlength = htonl(sys_badlength);
ss->processed = htonl(sys_processed);
ss->badauth = htonl(sys_badauth);
- ss->wanderhold = htonl(sys_wanderhold);
-
+ ss->limitrejected = htonl(sys_limitrejected);
(void) more_pkt();
flush_pkt();
}
@@ -1167,7 +1182,7 @@ do_conf(srcadr, inter, inpkt)
/* XXX W2DO? minpoll/maxpoll arguments ??? */
if (peer_config(&peeraddr, (struct interface *)0,
cp->hmode, cp->version, cp->minpoll, cp->maxpoll,
- cp->keyid, fl) == 0) {
+ fl, cp->ttl, cp->keyid) == 0) {
req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA);
return;
}
@@ -1252,7 +1267,7 @@ set_sys_flag(srcadr, inter, inpkt)
struct interface *inter;
struct req_pkt *inpkt;
{
- setclr_flags(srcadr, inter, inpkt, 1);
+ setclr_flags(srcadr, inter, inpkt, (U_LONG)1);
}
@@ -1265,7 +1280,7 @@ clr_sys_flag(srcadr, inter, inpkt)
struct interface *inter;
struct req_pkt *inpkt;
{
- setclr_flags(srcadr, inter, inpkt, 0);
+ setclr_flags(srcadr, inter, inpkt, (U_LONG)0);
}
@@ -1277,7 +1292,7 @@ setclr_flags(srcadr, inter, inpkt, set)
struct sockaddr_in *srcadr;
struct interface *inter;
struct req_pkt *inpkt;
- int set;
+ U_LONG set;
{
register U_LONG flags;
@@ -1289,15 +1304,20 @@ setclr_flags(srcadr, inter, inpkt, set)
flags = ((struct conf_sys_flags *)inpkt->data)->flags;
if (flags
- & ~(SYS_FLAG_BCLIENT|SYS_FLAG_AUTHENTICATE)) {
+ & ~(SYS_FLAG_BCLIENT | SYS_FLAG_MCLIENT | SYS_FLAG_AUTHENTICATE)) {
req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
return;
}
if (flags & SYS_FLAG_BCLIENT)
- proto_config(PROTO_BROADCLIENT, (LONG)set);
+ proto_config(PROTO_BROADCLIENT, set);
+ if (flags & SYS_FLAG_MCLIENT)
+ if (set)
+ proto_config(PROTO_MULTICAST_ADD, INADDR_NTP);
+ else
+ proto_config(PROTO_MULTICAST_DEL, INADDR_NTP);
if (flags & SYS_FLAG_AUTHENTICATE)
- proto_config(PROTO_AUTHENTICATE, (LONG)set);
+ proto_config(PROTO_AUTHENTICATE, set);
req_ack(srcadr, inter, inpkt, INFO_OKAY);
}
@@ -1311,7 +1331,7 @@ do_monitor(srcadr, inter, inpkt)
struct interface *inter;
struct req_pkt *inpkt;
{
- mon_start();
+ mon_start(MON_ON);
req_ack(srcadr, inter, inpkt, INFO_OKAY);
}
@@ -1325,7 +1345,7 @@ do_nomonitor(srcadr, inter, inpkt)
struct interface *inter;
struct req_pkt *inpkt;
{
- mon_stop();
+ mon_stop(MON_ON);
req_ack(srcadr, inter, inpkt, INFO_OKAY);
}
@@ -1497,6 +1517,10 @@ mon_getlist(srcadr, inter, inpkt)
md = md->mru_next) {
im->lasttime = htonl(current_time - md->lasttime);
im->firsttime = htonl(current_time - md->firsttime);
+ if (md->lastdrop)
+ im->lastdrop = htonl(current_time - md->lastdrop);
+ else
+ im->lastdrop = 0;
im->count = htonl(md->count);
im->addr = md->rmtadr;
im->port = md->rmtport;
@@ -2079,6 +2103,57 @@ get_leap_info(srcadr, inter, inpkt)
}
+#ifdef KERNEL_PLL
+/*
+ * get_kernel_info - get kernel pll/pps information
+ */
+static void
+get_kernel_info(srcadr, inter, inpkt)
+ struct sockaddr_in *srcadr;
+ struct interface *inter;
+ struct req_pkt *inpkt;
+{
+ register struct info_kernel *ik;
+ struct timex ntx;
+
+ if (!pll_control)
+ return;
+ memset((char *)&ntx, 0, sizeof(ntx));
+ (void)ntp_adjtime(&ntx);
+
+ ik = (struct info_kernel *)prepare_pkt(srcadr, inter, inpkt,
+ sizeof(struct info_kernel));
+
+ /*
+ * pll variables
+ */
+ ik->offset = htonl(ntx.offset);
+ ik->freq = htonl(ntx.freq);
+ ik->maxerror = htonl(ntx.maxerror);
+ ik->esterror = htonl(ntx.esterror);
+ ik->status = htons(ntx.status);
+ ik->constant = htonl(ntx.constant);
+ ik->precision = htonl(ntx.precision);
+ ik->tolerance = htonl(ntx.tolerance);
+
+ /*
+ * pps variables
+ */
+ ik->ppsfreq = htonl(ntx.ppsfreq);
+ ik->jitter = htonl(ntx.jitter);
+ ik->shift = htons(ntx.shift);
+ ik->stabil = htonl(ntx.stabil);
+ ik->jitcnt = htonl(ntx.jitcnt);
+ ik->calcnt = htonl(ntx.calcnt);
+ ik->errcnt = htonl(ntx.errcnt);
+ ik->stbcnt = htonl(ntx.stbcnt);
+
+ (void) more_pkt();
+ flush_pkt();
+}
+#endif /* KERNEL_PLL */
+
+
#ifdef REFCLOCK
/*
* get_clock_info - get info about a clock
@@ -2204,29 +2279,6 @@ set_clock_fudge(srcadr, inter, inpkt)
#endif
/*
- * set_maxskew - set the system maxskew parameter
- */
-static void
-set_maxskew(srcadr, inter, inpkt)
- struct sockaddr_in *srcadr;
- struct interface *inter;
- struct req_pkt *inpkt;
-{
- register u_fp maxskew;
-
- if (INFO_NITEMS(inpkt->err_nitems) > 1) {
- req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
- return;
- }
-
- maxskew = NTOHS_FP(*(u_fp *)(inpkt->data));
-
- proto_config(PROTO_MAXSKEW, (LONG)maxskew);
- req_ack(srcadr, inter, inpkt, INFO_OKAY);
-}
-
-
-/*
* set_precision - set the system precision
*/
static void
@@ -2249,31 +2301,6 @@ set_precision(srcadr, inter, inpkt)
req_ack(srcadr, inter, inpkt, INFO_OKAY);
}
-
-/*
- * set_select_code - set a select code to use
- */
-static void
-set_select_code(srcadr, inter, inpkt)
- struct sockaddr_in *srcadr;
- struct interface *inter;
- struct req_pkt *inpkt;
-{
- register U_LONG select_code;
-
- select_code = ntohl(*(U_LONG *)(inpkt->data));
-
- if (INFO_NITEMS(inpkt->err_nitems) > 1 ||
- select_code < SELECT_1 || select_code > SELECT_5) {
- req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
- return;
- }
-
- proto_config(PROTO_SELECT, (LONG)select_code);
- req_ack(srcadr, inter, inpkt, INFO_OKAY);
-}
-
-
#ifdef REFCLOCK
/*
* get_clkbug_info - get debugging info about a clock
diff --git a/contrib/xntpd/xntpd/ntp_restrict.c b/contrib/xntpd/xntpd/ntp_restrict.c
index 51d896806207..43f01f296624 100644
--- a/contrib/xntpd/xntpd/ntp_restrict.c
+++ b/contrib/xntpd/xntpd/ntp_restrict.c
@@ -1,4 +1,4 @@
-/* ntp_restrict.c,v 3.1 1993/07/06 01:11:28 jbj Exp
+/*
* ntp_restrict.c - find out what restrictions this host is running under
*/
#include <stdio.h>
@@ -60,6 +60,21 @@ U_LONG res_not_found;
U_LONG res_timereset;
/*
+ * Parameters of the RES_LIMITED restriction option.
+ * client_limit is the number of hosts allowed per source net
+ * client_limit_period is the number of seconds after which an entry
+ * is no longer considered for client limit determination
+ */
+U_LONG client_limit;
+U_LONG client_limit_period;
+/*
+ * count number of restriction entries referring to RES_LIMITED
+ * controls activation/deactivation of monitoring
+ * (with respect ro RES_LIMITED control)
+ */
+U_LONG res_limited_refcnt;
+
+/*
* Our initial allocation of list entries.
*/
static struct restrictlist resinit[INITRESLIST];
@@ -70,12 +85,18 @@ static struct restrictlist resinit[INITRESLIST];
extern U_LONG current_time;
/*
+ * debug flag
+ */
+extern int debug;
+
+/*
* init_restrict - initialize the restriction data structures
*/
void
init_restrict()
{
register int i;
+ char bp[80];
/*
* Zero the list and put all but one on the free list
@@ -108,6 +129,18 @@ init_restrict()
res_found = 0;
res_not_found = 0;
res_timereset = 0;
+
+ /*
+ * set default values for RES_LIMIT functionality
+ */
+ client_limit = 3;
+ client_limit_period = 3600;
+ res_limited_refcnt = 0;
+
+ sprintf(bp, "client_limit=%d", client_limit);
+ set_sys_var(bp, strlen(bp)+1, RO);
+ sprintf(bp, "client_limit_period=%d", client_limit_period);
+ set_sys_var(bp, strlen(bp)+1, RO);
}
@@ -150,6 +183,120 @@ restrictions(srcadr)
else
res_found++;
+ /*
+ * The following implements limiting the number of clients
+ * accepted from a given network. The notion of "same network"
+ * is determined by the mask and addr fields of the restrict
+ * list entry. The monitor mechanism has to be enabled for
+ * collecting info on current clients.
+ *
+ * The policy is as follows:
+ * - take the list of clients recorded
+ * from the given "network" seen within the last
+ * client_limit_period seconds
+ * - if there are at most client_limit entries:
+ * --> access allowed
+ * - otherwise sort by time first seen
+ * - current client among the first client_limit seen
+ * hosts?
+ * if yes: access allowed
+ * else: eccess denied
+ */
+ if (match->flags & RES_LIMITED) {
+ int lcnt;
+ struct mon_data *md, *this_client;
+ extern int mon_enabled;
+ extern struct mon_data mon_fifo_list, mon_mru_list;
+
+#ifdef DEBUG
+ if (debug > 2)
+ printf("limited clients check: %d clients, period %d seconds, net is 0x%X\n",
+ client_limit, client_limit_period,
+ netof(hostaddr));
+#endif /*DEBUG*/
+ if (mon_enabled == MON_OFF) {
+#ifdef DEBUG
+ if (debug > 4)
+ printf("no limit - monitoring is off\n");
+#endif
+ return (int)(match->flags & ~RES_LIMITED);
+ }
+
+ /*
+ * How nice, MRU list provides our current client as the
+ * first entry in the list.
+ * Monitoring was verified to be active above, thus we
+ * know an entry for our client must exist, or some
+ * brain dead set the memory limit for mon entries to ZERO!!!
+ */
+ this_client = mon_mru_list.mru_next;
+
+ for (md = mon_fifo_list.fifo_next,lcnt = 0;
+ md != &mon_fifo_list;
+ md = md->fifo_next) {
+ if ((current_time - md->lasttime)
+ > client_limit_period) {
+#ifdef DEBUG
+ if (debug > 5)
+ printf("checking: %s: ignore: too old: %d\n",
+ numtoa(md->rmtadr),
+ current_time - md->lasttime);
+#endif
+ continue;
+ }
+ if (md->mode == MODE_BROADCAST ||
+ md->mode == MODE_CONTROL ||
+ md->mode == MODE_PRIVATE) {
+#ifdef DEBUG
+ if (debug > 5)
+ printf("checking: %s: ignore mode %d\n",
+ numtoa(md->rmtadr),
+ md->mode);
+#endif
+ continue;
+ }
+ if (netof(md->rmtadr) !=
+ netof(hostaddr)) {
+#ifdef DEBUG
+ if (debug > 5)
+ printf("checking: %s: different net 0x%X\n",
+ numtoa(md->rmtadr),
+ netof(md->rmtadr));
+#endif
+ continue;
+ }
+ lcnt++;
+ if (lcnt > client_limit ||
+ md->rmtadr == hostaddr) {
+#ifdef DEBUG
+ if (debug > 5)
+ printf("considering %s: found host\n",
+ numtoa(md->rmtadr));
+#endif
+ break;
+ }
+#ifdef DEBUG
+ else {
+ if (debug > 5)
+ printf("considering %s: same net\n",
+ numtoa(md->rmtadr));
+ }
+#endif
+
+ }
+#ifdef DEBUG
+ if (debug > 4)
+ printf("this one is rank %d in list, limit is %d: %s\n",
+ lcnt, client_limit,
+ (lcnt <= client_limit) ? "ALLOW" : "REJECT");
+#endif
+ if (lcnt <= client_limit) {
+ this_client->lastdrop = 0;
+ return (int)(match->flags & ~RES_LIMITED);
+ } else {
+ this_client->lastdrop = current_time;
+ }
+ }
return (int)match->flags;
}
@@ -257,6 +404,10 @@ restrict(op, resaddr, resmask, mflags, flags)
rlprev->next = rl;
restrictcount++;
}
+ if ((rl->flags ^ (u_short)flags) & RES_LIMITED) {
+ res_limited_refcnt++;
+ mon_start(MON_RES); /* ensure data gets collected */
+ }
rl->flags |= (u_short)flags;
break;
@@ -265,8 +416,14 @@ restrict(op, resaddr, resmask, mflags, flags)
* Remove some bits from the flags. If we didn't
* find this one, just return.
*/
- if (rl != 0)
+ if (rl != 0) {
+ if ((rl->flags ^ (u_short)flags) & RES_LIMITED) {
+ res_limited_refcnt--;
+ if (res_limited_refcnt == 0)
+ mon_stop(MON_RES);
+ }
rl->flags &= (u_short)~flags;
+ }
break;
case RESTRICT_REMOVE:
@@ -280,6 +437,11 @@ restrict(op, resaddr, resmask, mflags, flags)
&& !(rl->mflags & RESM_INTERFACE)) {
rlprev->next = rl->next;
restrictcount--;
+ if (rl->flags & RES_LIMITED) {
+ res_limited_refcnt--;
+ if (res_limited_refcnt == 0)
+ mon_stop(MON_RES);
+ }
memset((char *)rl, 0, sizeof(struct restrictlist));
rl->next = resfree;
diff --git a/contrib/xntpd/xntpd/ntp_unixclock.c b/contrib/xntpd/xntpd/ntp_unixclock.c
index 6b661835dbb7..1950d8c06fb3 100644
--- a/contrib/xntpd/xntpd/ntp_unixclock.c
+++ b/contrib/xntpd/xntpd/ntp_unixclock.c
@@ -251,10 +251,23 @@ clock_parms(tickadj, tick)
* Note that this version grovels about in /dev/kmem to determine
* these values. This probably should be elsewhere.
*/
-
-/* Define the following to be what the tick and tickadj variables are
- * called in your kernel.
+#if defined(SYS_UNIXWARE1)
+/*
+ * clock_parms - return the local clock tickadj and tick parameters
+ *
+ * The values set here were determined experimentally on a 486 system
+ * I'm not confident in them. - RAS
+ *
*/
+static void
+clock_parms(tickadj, tick)
+ U_LONG *tickadj;
+ U_LONG *tick;
+{
+ *tick = 10000; /* microseconds */
+ *tickadj = 80; /* microseconds */
+}
+#else /* SYS_UNIXWARE1 */
#if defined(SYS_AUX3) || defined(SYS_AUX2) || defined(SYS_SVR4) || defined(SYS_PTX)
#define K_TICKADJ_NAME "tickadj"
@@ -373,6 +386,7 @@ clock_parms(tickadj, tick)
#undef K_TICK_NAME
#undef N_NAME
}
+#endif /* SYS_UNIXWARE1 */
#endif /* HAVE_READKMEM */
#if defined(SOLARIS)&&defined(ADJTIME_IS_ACCURATE)
@@ -421,7 +435,6 @@ clock_parms(tickadj, tick)
}
#endif /* sgi */
-
#ifdef NOKMEM
#ifndef HZ
@@ -556,13 +569,18 @@ clock_parms(tickadj, tick)
#endif /* SOLARIS */
#ifdef SYS_LINUX
-/* XXX should look this up somewhere ! */
+#include <sys/timex.h>
static void
clock_parms(tickadj, tick)
U_LONG *tickadj;
U_LONG *tick;
{
- *tickadj = (U_LONG)1;
- *tick = (U_LONG)10000;
+ struct timex txc;
+
+ txc.mode = 0;
+ __adjtimex(&txc);
+
+ *tickadj = (U_LONG)1; /* our adjtime is accurate */
+ *tick = (U_LONG)txc.tick;
}
#endif /* SYS_LINUX */
diff --git a/contrib/xntpd/xntpd/ntpd.c b/contrib/xntpd/xntpd/ntpd.c
index abe86d945151..9ed43c5c4a81 100644
--- a/contrib/xntpd/xntpd/ntpd.c
+++ b/contrib/xntpd/xntpd/ntpd.c
@@ -14,7 +14,7 @@
#include <sys/rtprio.h>
#endif
-#if defined(SYS_SVR4)
+#if defined(SYS_SVR4) || defined (SYS_UNIXWARE1)
#include <termios.h>
#endif
@@ -28,8 +28,12 @@
#include "ntp_stdlib.h"
#ifdef LOCK_PROCESS
+#ifdef SYS_SOLARIS
+#include <sys/mman.h>
+#else
#include <sys/lock.h>
#endif
+#endif
/*
* Signals we catch for debugging. If not debugging we ignore them.
@@ -139,7 +143,7 @@ main(argc, argv)
(void) dup2(0, 1);
(void) dup2(0, 2);
#ifdef NTP_POSIX_SOURCE
-#if defined(SOLARIS) || defined(SYS_PTX) || defined(SYS_AUX3) || defined(SYS_AIX)
+#if defined(SOLARIS) || defined(SYS_PTX) || defined(SYS_AUX3) || defined(SYS_AIX) || defined(SYS_ULTRIX)
(void) setsid();
#else
(void) setpgid(0, 0);
@@ -219,13 +223,23 @@ main(argc, argv)
if (rtprio(0, 120) < 0)
syslog(LOG_ERR, "rtprio() error: %m");
#else
-#if defined(PROCLOCK) && defined(LOCK_PROCESS)
+#if defined(LOCK_PROCESS)
+#if defined(MCL_CURRENT) && defined(MCL_FUTURE)
+ /*
+ * lock the process into memory
+ */
+ if (mlockall(MCL_CURRENT|MCL_FUTURE) < 0)
+ syslog(LOG_ERR, "mlockall(): %m");
+#else
+#if defined(PROCLOCK)
/*
* lock the process into memory
*/
if (plock(PROCLOCK) < 0)
syslog(LOG_ERR, "plock(): %m");
#endif
+#endif
+#endif
#if defined(NTPD_PRIO) && NTPD_PRIO != 0
/*
* Set the priority.
diff --git a/contrib/xntpd/xntpd/refclock_chu.c b/contrib/xntpd/xntpd/refclock_chu.c
index 1c7c3bfa61c1..4596db22e2f5 100644
--- a/contrib/xntpd/xntpd/refclock_chu.c
+++ b/contrib/xntpd/xntpd/refclock_chu.c
@@ -599,6 +599,25 @@ chu_receive(rbufp)
chu->lastupdate = current_time;
/*
+ * Just for fun, we can debug the whole frame if
+ * we want.
+ */
+
+#ifdef CHU_DEBUG
+ syslog(LOG_DEBUG, "CHU %s packet:", (chuc->chutype == CHU_YEAR)?
+ "year":"time");
+ for (i=0; i < NCHUCHARS; i++) {
+ char c[64];
+
+ sprintf(c,"%c%c %s",hexstring[chuc->codechars[i]&0xf],
+ hexstring[chuc->codechars[i]>>4],
+ ctime(&(chuc->codetimes[i].tv_sec)));
+ c[strlen(c)-1]=0; /* ctime() adds a damn \n */
+ syslog(LOG_DEBUG, "%s .%06d", c, chuc->codetimes[i].tv_usec);
+ }
+#endif
+
+ /*
* At this point we're assured that both halves of the
* data match because of what the kernel has done.
* But there's more than one data format. We need to
diff --git a/contrib/xntpd/xntpd/refclock_conf.c b/contrib/xntpd/xntpd/refclock_conf.c
index 430c4a60f3fa..535ca27e9ebe 100644
--- a/contrib/xntpd/xntpd/refclock_conf.c
+++ b/contrib/xntpd/xntpd/refclock_conf.c
@@ -20,6 +20,12 @@ extern struct refclock refclock_local;
#define refclock_local refclock_none
#endif
+#if defined(TRAK) || defined(TRAKCLK) || defined(TRAKPPS)
+extern struct refclock refclock_trak;
+#else
+#define refclock_trak refclock_none
+#endif
+
#if defined(PST) || defined(PSTCLK) || defined(PSTPPS)
extern struct refclock refclock_pst;
#else
@@ -107,7 +113,7 @@ extern struct refclock refclock_gpstm;
struct refclock *refclock_conf[] = {
&refclock_none, /* 0 REFCLK_NONE */
&refclock_local, /* 1 REFCLK_LOCAL */
- &refclock_none, /* 2 REFCLK_WWV_HEATH */
+ &refclock_trak, /* 2 REFCLK_GPS_TRAK */
&refclock_pst, /* 3 REFCLK_WWV_PST */
&refclock_wwvb, /* 4 REFCLK_WWVB_SPECTRACOM */
&refclock_goes, /* 5 REFCLK_GOES_TRUETIME */
diff --git a/contrib/xntpd/xntpd/refclock_irig.c b/contrib/xntpd/xntpd/refclock_irig.c
index 40345bbefde7..6167af2784ee 100644
--- a/contrib/xntpd/xntpd/refclock_irig.c
+++ b/contrib/xntpd/xntpd/refclock_irig.c
@@ -19,7 +19,7 @@
* This driver supports the IRIG audio decoder. This clever gadget uses
* a modified BSD audio driver for the Sun SPARCstation which provides
* a timestamp, raw binary timecode, status byte and decoded ASCII
- # timecode. The data are represented in the structure:
+ * timecode. The data are represented in the structure:
*
* struct irig_time {
* struct timeval stamp; timestamp
@@ -418,7 +418,9 @@ struct peer *peer;
irig->hour = MULBY10(cp[4] - '0') + cp[5] - '0';
irig->minute = MULBY10(cp[7] - '0') + cp[8] - '0';
irig->second = MULBY10(cp[10] - '0') + cp[11] - '0';
- if (cp[12] != ' ')
+ if (cp[12] = ' ')
+ irig->leap = 0;
+ else
irig->leap = LEAP_NOTINSYNC;
if (irig->day < 1 || irig->day > 366) {
irig->baddata++;
diff --git a/contrib/xntpd/xntpd/refclock_msfees.c b/contrib/xntpd/xntpd/refclock_msfees.c
index b301bc2ebb23..c2a882abb919 100644
--- a/contrib/xntpd/xntpd/refclock_msfees.c
+++ b/contrib/xntpd/xntpd/refclock_msfees.c
@@ -139,7 +139,7 @@
#define INH_DELAY_PPS BITS_TO_L_FP( 0, 9600)
#ifndef STREAM_PP1
-#define STREAM_PP1 "ppsclockd\0<-- patch space for module name1 -->"
+#define STREAM_PP1 "ppsclocd\0<-- patch space for module name1 -->"
#endif
#ifndef STREAM_PP2
#define STREAM_PP2 "ppsclock\0<-- patch space for module name2 -->"
diff --git a/contrib/xntpd/xntpd/refclock_parse.c b/contrib/xntpd/xntpd/refclock_parse.c
index 69e483764354..0d95d18908a5 100644
--- a/contrib/xntpd/xntpd/refclock_parse.c
+++ b/contrib/xntpd/xntpd/refclock_parse.c
@@ -1,8 +1,8 @@
#if defined(REFCLOCK) && (defined(PARSE) || defined(PARSEPPS))
/*
- * /src/NTP/REPOSITORY/v3/xntpd/refclock_parse.c,v 3.45 1994/01/25 19:06:27 kardel Exp
+ * /src/NTP/REPOSITORY/v3/xntpd/refclock_parse.c,v 3.53 1994/03/25 13:07:39 kardel Exp
*
- * refclock_parse.c,v 3.45 1994/01/25 19:06:27 kardel Exp
+ * refclock_parse.c,v 3.53 1994/03/25 13:07:39 kardel Exp
*
* generic reference clock driver for receivers
*
@@ -30,6 +30,8 @@
* PPS - supply loopfilter with PPS samples (if configured)
* PPSPPS - notify loopfilter of PPS file descriptor
*
+ * FREEBSD_CONRAD - Make very cheap "Conrad DCF77 RS-232" gadget work
+ * with FreeBSD.
* TTY defines:
* HAVE_BSD_TTYS - currently unsupported
* HAVE_SYSV_TTYS - will use termio.h
@@ -82,6 +84,9 @@
#include <time.h>
#include <sys/errno.h>
+#ifdef FREEBSD_CONRAD
+#include <sys/ioctl.h>
+#endif
extern int errno;
#if !defined(STREAM) && !defined(HAVE_SYSV_TTYS) && !defined(HAVE_BSD_TTYS) && !defined(HAVE_TERMIOS)
@@ -129,7 +134,7 @@ CURRENTLY NO BSD TTY SUPPORT
#include "parse.h"
#if !defined(NO_SCCSID) && !defined(lint) && !defined(__GNUC__)
-static char rcsid[]="refclock_parse.c,v 3.45 1994/01/25 19:06:27 kardel Exp";
+static char rcsid[]="refclock_parse.c,v 3.53 1994/03/25 13:07:39 kardel Exp";
#endif
/**===========================================================================
@@ -440,7 +445,12 @@ static poll_info_t wsdcf_pollinfo = { WS_POLLRATE, WS_POLLCMD, WS_CMDSIZE };
#define RAWDCF_ROOTDELAY 0x00000364 /* 13 ms */
#define RAWDCF_FORMAT "RAW DCF77 Timecode"
#define RAWDCF_MAXUNSYNC (0) /* sorry - its a true receiver - no signal - no time */
+
+#ifdef FREEBSD_CONRAD
+#define RAWDCF_CFLAG (CS8|CREAD|CLOCAL)
+#else
#define RAWDCF_CFLAG (B50|CS8|CREAD|CLOCAL)
+#endif
#define RAWDCF_IFLAG 0
#define RAWDCF_OFLAG 0
#define RAWDCF_LFLAG 0
@@ -1482,11 +1492,22 @@ local_receive(rbufp)
struct parseunit *parse = (struct parseunit *)rbufp->recv_srcclock;
register int count;
register char *s;
+#ifdef FREEBSD_CONRAD
+ struct timeval foo;
+#endif
+
/*
* eat all characters, parsing then and feeding complete samples
*/
count = rbufp->recv_length;
s = rbufp->recv_buffer;
+#ifdef FREEBSD_CONRAD
+ ioctl(parse->fd,TIOCTIMESTAMP,&foo);
+ TVTOTS(&foo, &rbufp->recv_time);
+ rbufp->recv_time.l_uf += TS_ROUNDBIT;
+ rbufp->recv_time.l_ui += JAN_1970;
+ rbufp->recv_time.l_uf &= TS_MASK;
+#endif
while (count--)
{
@@ -1653,7 +1674,8 @@ local_poll(parse)
* done if no more characters are available
*/
FD_SET(fd, &fdmask);
- if (select(fd + 1, &fdmask, 0, 0, &null_time) == 0)
+ if ((i == 0) &&
+ (select(fd + 1, &fdmask, 0, 0, &null_time) == 0))
return;
}
}
@@ -1706,7 +1728,8 @@ parsestate(state, buffer)
{ PARSEB_NOSYNC, "TIME CODE NOT CONFIRMED" },
{ PARSEB_DST, "DST" },
{ PARSEB_UTC, "UTC DISPLAY" },
- { PARSEB_LEAP, "LEAP WARNING" },
+ { PARSEB_LEAPADD, "LEAP ADD WARNING" },
+ { PARSEB_LEAPDEL, "LEAP DELETE WARNING" },
{ PARSEB_LEAPSECOND, "LEAP SECOND" },
{ PARSEB_ALTERNATE,"ALTERNATE ANTENNA" },
{ PARSEB_TIMECODE, "TIME CODE" },
@@ -2269,7 +2292,10 @@ parse_start(sysunit, peer)
tm.c_iflag = clockinfo[type].cl_iflag;
tm.c_oflag = clockinfo[type].cl_oflag;
tm.c_lflag = clockinfo[type].cl_lflag;
-
+#ifdef FREEBSD_CONRAD
+ tm.c_ispeed = 50;
+ tm.c_ospeed = 50;
+#endif
if (TTY_SETATTR(fd232, &tm) == -1)
{
syslog(LOG_ERR, "PARSE receiver #%d: parse_start: tcsetattr(%d, &tm): %m", unit, fd232);
@@ -2312,6 +2338,21 @@ parse_start(sysunit, peer)
return 0; /* well, ok - special initialisation broke */
}
+#ifdef FREEBSD_CONRAD
+ {
+ int i,j;
+ struct timeval tv;
+ ioctl(parse->fd,TIOCTIMESTAMP,&tv);
+ j = TIOCM_RTS;
+ i = ioctl(fd232, TIOCMBIC, &j);
+ if (i < 0) {
+ syslog(LOG_ERR,
+ "PARSE receiver #%d: lowrts_poll: failed to lower RTS: %m",
+ CL_UNIT(parse->unit));
+ }
+ }
+#endif
+
strcpy(tmp_ctl.parseformat.parse_buffer, parse->parse_type->cl_format);
tmp_ctl.parseformat.parse_count = strlen(tmp_ctl.parseformat.parse_buffer);
@@ -2539,9 +2580,10 @@ static void
parse_leap()
{
/*
- * PARSE does encode a leap warning... we are aware but not afraid of that
- * as long as we get a little help for the direction from the operator until
* PARSE encodes the LEAP correction direction.
+ * For timecodes that do not pass on the leap correction direction
+ * the default PARSEB_LEAPADD must be used. It may then be modified
+ * with a fudge flag (flag2).
*/
}
@@ -2821,7 +2863,7 @@ parse_control(unit, in, out)
sprintf(tt, "refclock_iomode=\"%s\"", parse->binding->bd_description);
tt = add_var(&out->kv_list, 128, RO);
- sprintf(tt, "refclock_driver_version=\"refclock_parse.c,v 3.45 1994/01/25 19:06:27 kardel Exp\"");
+ sprintf(tt, "refclock_driver_version=\"refclock_parse.c,v 3.53 1994/03/25 13:07:39 kardel Exp\"");
out->lencode = strlen(outstatus);
out->lastcode = outstatus;
@@ -3100,7 +3142,11 @@ parse_process(parse, parsetime)
L_ADD(&off, &offset);
rectime = off; /* this makes org time and xmt time somewhat artificial */
- if (parse->flags & PARSE_STAT_FILTER)
+ L_SUB(&off, &parsetime->parse_stime.fp);
+
+ if ((parse->flags & PARSE_STAT_FILTER) &&
+ (off.l_i > -60) &&
+ (off.l_i < 60)) /* take usec error only if within +- 60 secs */
{
struct timeval usecerror;
/*
@@ -3112,10 +3158,6 @@ parse_process(parse, parsetime)
sTVTOTS(&usecerror, &off);
L_ADD(&off, &offset);
}
- else
- {
- L_SUB(&off, &parsetime->parse_stime.fp);
- }
}
if (PARSE_PPS(parsetime->parse_state) && CL_PPS(parse->unit))
@@ -3245,14 +3287,24 @@ parse_process(parse, parsetime)
}
else
{
- if (PARSE_LEAP(parsetime->parse_state))
+ if (PARSE_LEAPADD(parsetime->parse_state))
{
+ /*
+ * we pick this state also for time code that pass leap warnings
+ * without direction information (as earth is currently slowing
+ * down).
+ */
leap = (parse->flags & PARSE_LEAP_DELETE) ? LEAP_DELSECOND : LEAP_ADDSECOND;
}
else
- {
- leap = LEAP_NOWARNING;
- }
+ if (PARSE_LEAPDEL(parsetime->parse_state))
+ {
+ leap = LEAP_DELSECOND;
+ }
+ else
+ {
+ leap = LEAP_NOWARNING;
+ }
}
refclock_receive(parse->peer, &off, 0, LFPTOFP(&dispersion), &reftime, &rectime, leap);
@@ -3396,6 +3448,21 @@ trimble_init(parse)
* History:
*
* refclock_parse.c,v
+ * Revision 3.53 1994/03/25 13:07:39 kardel
+ * fixed offset calculation for large (>4 Min) offsets
+ *
+ * Revision 3.52 1994/03/03 09:58:00 kardel
+ * stick -kv in cvs is no fun
+ *
+ * Revision 3.49 1994/02/20 13:26:00 kardel
+ * rcs id cleanup
+ *
+ * Revision 3.48 1994/02/20 13:04:56 kardel
+ * parse add/delete second support
+ *
+ * Revision 3.47 1994/02/02 17:44:30 kardel
+ * rcs ids fixed
+ *
* Revision 3.45 1994/01/25 19:06:27 kardel
* 94/01/23 reconcilation
*
diff --git a/contrib/xntpd/xntpd/refclock_trak.c b/contrib/xntpd/xntpd/refclock_trak.c
new file mode 100644
index 000000000000..f2b3eb11fc9d
--- /dev/null
+++ b/contrib/xntpd/xntpd/refclock_trak.c
@@ -0,0 +1,1006 @@
+/*
+ * refclock_trak.c - clock driver for the TRAK 8810 GPS STATION CLOCK
+ * Tsuruoka Tomoaki Oct 30, 1993
+ * tsuruoka@nc.fukuoka-u.ac.jp
+ * Faculty of Engineering,
+ * Fukuoka University, Fukuoka, JAPAN
+ */
+#if defined(REFCLOCK) && (defined(TRAK) || defined(TRAKCLK) || defined(TRAKPPS))
+
+#include <stdio.h>
+#include <ctype.h>
+#include <sys/time.h>
+
+#include "ntpd.h"
+#include "ntp_io.h"
+#include "ntp_refclock.h"
+#include "ntp_unixtime.h"
+
+static void gps_send();
+
+#if defined(HAVE_BSD_TTYS)
+#include <sgtty.h>
+#endif /* HAVE_BSD_TTYS */
+
+#if defined(HAVE_SYSV_TTYS)
+#include <termio.h>
+#endif /* HAVE_SYSV_TTYS */
+
+#if defined(STREAM)
+#include <termios.h>
+#include <stropts.h>
+#if defined(TRAKCLK)
+#include <sys/clkdefs.h>
+#endif /* TRAKCLK */
+#endif /* STREAM */
+
+#if defined (TRAKPPS)
+#include <sys/ppsclock.h>
+#endif /* TRAKPPS */
+
+#include "ntp_stdlib.h"
+
+/*
+ * This driver supports the TRAK 8810 GPS Receiver with
+ * Buffered RS-232-C Interface Module.
+ *
+ * Most of codes are copied from refclock_as2201.c, Thanks a lot.
+ *
+ * The program expects the radio responses once per seccond
+ * ( by "rqts,u" command or panel control )
+ * of the form "*RQTS U,ddd:hh:mm:ss.0,Q\r\n for UTC" where
+ * ddd= day of year
+ * hh= hours
+ * mm= minutes
+ * ss= seconds
+ * Q= Quality byte. Q=0 Phase error > 20 us
+ * Q=6 Pahse error < 20 us
+ * > 10 us
+ * Q=5 Pahse error < 10 us
+ * > 1 us
+ * Q=4 Pahse error < 1 us
+ * > 100 ns
+ * Q=3 Pahse error < 100 ns
+ * > 10 ns
+ * Q=2 Pahse error < 10 ns
+ * (note that my clock almost stable at 1 us per 10 hours)
+ *
+ * Request leap second status - if needed.
+ * send: rqls\n
+ * reply: RQLS yy,mm,dd
+ * where: yy is year
+ * mm is month
+ * dd is day of month.baud
+ * Note: Default data is all zeros
+ * i.e. RQLS 00,00,00
+ */
+
+/*
+ * Definitions
+ */
+#define MAXUNITS 4 /* max number of GPS units */
+#define GPS232 "/dev/gps%d" /* name of radio device */
+#define SPEED232 B9600 /* uart speed (9600 bps) */
+
+/*
+ * Radio interface parameters
+ */
+#define GPSPRECISION (-20) /* precision assumed (about 1 us) */
+#define GPSREFID "GPS" /* reference id */
+#define GPSDESCRIPTION "TRAK 8810 GPS station clock" /* who we are */
+#define GPSHSREFID 0x7f7f020a /* 127.127.2.10 refid hi strata */
+#define GMT 0 /* hour offset from Greenwich */
+#define NCODES 3 /* stages of median filter */
+#define LENTOC 25 /* *RQTS U,ddd:hh:mm:ss.0,Q datecode length */
+#define BMAX 100 /* timecode buffer length */
+#define CODEDIFF 0x20000000 /* 0.125 seconds as an l_fp fraction */
+
+/*
+ * Hack to avoid excercising the multiplier. I have no pride.
+ */
+#define MULBY10(x) (((x)<<3) + ((x)<<1))
+
+/*
+ * Imported from ntp_timer module
+ */
+extern U_LONG current_time; /* current time (s) */
+
+/*
+ * Imported from ntp_loopfilter module
+ */
+extern int fdpps; /* pps file descriptor */
+
+/*
+ * Imported from ntpd module
+ */
+extern int debug; /* global debug flag */
+
+/*
+ * GPS unit control structure.
+ */
+struct gpsunit {
+ struct peer *peer; /* associated peer structure */
+ struct refclockio io; /* given to the I/O handler */
+ l_fp lastrec; /* last data receive time */
+ l_fp lastref; /* last timecode time */
+ l_fp offset[NCODES]; /* recent sample offsets */
+ char lastcode[BMAX]; /* last timecode received */
+ u_short polled; /* when polled, means a last sample */
+ u_char lencode; /* length of last received ASCII string */
+ U_LONG lasttime; /* last time clock heard from */
+#ifdef TRAKPPS
+ U_LONG lastev; /* last ppsclock second */
+#endif /* TRAKPPS */
+ u_char unit; /* unit number for this guy */
+ u_char status; /* clock status */
+ u_char lastevent; /* last clock event */
+ u_char reason; /* reason for last abort */
+ u_char year; /* year of eternity */
+ u_short day; /* day of year */
+ u_char hour; /* hour of day */
+ u_char minute; /* minute of hour */
+ u_char second; /* seconds of minute */
+ u_short msec; /* milliseconds of second */
+ u_char leap; /* leap indicators */
+ U_LONG yearstart; /* start of current year */
+ /*
+ * Status tallies
+ */
+ U_LONG polls; /* polls sent */
+ U_LONG noreply; /* no replies to polls */
+ U_LONG coderecv; /* timecodes received */
+ U_LONG badformat; /* bad format */
+ U_LONG baddata; /* bad data */
+ U_LONG timestarted; /* time we started this */
+};
+
+
+/*
+ * Data space for the unit structures. Note that we allocate these on
+ * the fly, but never give them back.
+ */
+static struct gpsunit *gpsunits[MAXUNITS];
+static u_char unitinuse[MAXUNITS];
+
+/*
+ * Keep the fudge factors separately so they can be set even
+ * when no clock is configured.
+ */
+static l_fp fudgefactor[MAXUNITS];
+static u_char stratumtouse[MAXUNITS];
+static u_char sloppyclockflag[MAXUNITS];
+
+/*
+ * Function prototypes
+ */
+static void trak_init P(());
+static int trak_start P((u_int, struct peer *));
+static void trak_shutdown P((int));
+static void trak_report_event P((struct gpsunit *, int));
+static void trak_receive P((struct recvbuf *));
+static char trak_process P((struct gpsunit *, l_fp *, u_fp *));
+static void trak_poll P((int unit, struct peer *));
+static void trak_control P((u_int, struct refclockstat *, struct refclockstat *));
+static void trak_buginfo P((int, struct refclockbug *));
+
+/*
+ * Transfer vector
+ */
+struct refclock refclock_trak = {
+ trak_start, trak_shutdown, trak_poll,
+ trak_control, trak_init, trak_buginfo, NOFLAGS
+};
+
+/*
+ * trak_init - initialize internal gps driver data
+ */
+static void
+trak_init()
+{
+ register int i;
+ /*
+ * Just zero the data arrays
+ */
+ memset((char *)gpsunits, 0, sizeof gpsunits);
+ memset((char *)unitinuse, 0, sizeof unitinuse);
+
+ /*
+ * Initialize fudge factors to default.
+ */
+ for (i = 0; i < MAXUNITS; i++) {
+ fudgefactor[i].l_ui = 0;
+ fudgefactor[i].l_uf = 0;
+ stratumtouse[i] = 0;
+ sloppyclockflag[i] = 0;
+ }
+}
+
+
+/*
+ * trak_start - open the GPS devices and initialize data for processing
+ */
+static int
+trak_start(unit, peer)
+ u_int unit;
+ struct peer *peer;
+{
+ register struct gpsunit *gps;
+ register int i;
+ int fd232;
+ char trakdev[20];
+#ifdef TRAKPPS
+ struct ppsclockev ev;
+#endif /* TRAKPPS */
+
+ /*
+ * Check configuration info
+ */
+ if (unit >= MAXUNITS) {
+ syslog(LOG_ERR, "trak_start: unit %d invalid", unit);
+ return (0);
+ }
+ if (unitinuse[unit]) {
+ syslog(LOG_ERR, "trak_start: unit %d in use", unit);
+ return (0);
+ }
+
+ /*
+ * Open serial port
+ */
+ (void) sprintf(trakdev, GPS232, unit);
+ fd232 = open(trakdev, O_RDWR, 0777);
+ if (fd232 == -1) {
+ syslog(LOG_ERR, "trak_start: open of %s: %m", trakdev);
+ return (0);
+ }
+
+#if defined(HAVE_SYSV_TTYS)
+ /*
+ * System V serial line parameters (termio interface)
+ *
+ */
+ { struct termio ttyb;
+ if (ioctl(fd232, TCGETA, &ttyb) < 0) {
+ syslog(LOG_ERR,
+ "trak_start: ioctl(%s, TCGETA): %m", trakdev);
+ goto screwed;
+ }
+ ttyb.c_iflag = IGNBRK|IGNPAR|ICRNL;
+ ttyb.c_oflag = 0;
+ ttyb.c_cflag = SPEED232|CS8|CLOCAL|CREAD;
+ ttyb.c_lflag = ICANON;
+ ttyb.c_cc[VERASE] = ttyb.c_cc[VKILL] = '\0';
+ if (ioctl(fd232, TCSETA, &ttyb) < 0) {
+ syslog(LOG_ERR,
+ "trak_start: ioctl(%s, TCSETA): %m", trakdev);
+ goto screwed;
+ }
+ }
+#endif /* HAVE_SYSV_TTYS */
+#if defined(STREAM)
+ /*
+ * POSIX/STREAMS serial line parameters (termios interface)
+ *
+ * The TRAKCLK option provides timestamping at the driver level.
+ * It requires the tty_clk streams module.
+ *
+ * The TRAKPPS option provides timestamping at the driver level.
+ * It uses a 1-pps signal and level converter (gadget box) and
+ * requires the ppsclock streams module and SunOS 4.1.1 or
+ * later.
+ */
+ { struct termios ttyb, *ttyp;
+
+ ttyp = &ttyb;
+ if (tcgetattr(fd232, ttyp) < 0) {
+ syslog(LOG_ERR,
+ "trak_start: tcgetattr(%s): %m", trakdev);
+ goto screwed;
+ }
+ ttyp->c_iflag = IGNBRK|IGNPAR;
+ ttyp->c_oflag = 0;
+ ttyp->c_cflag = SPEED232|CS8|CLOCAL|CREAD;
+ ttyp->c_lflag = ICANON;
+ ttyp->c_cc[VERASE] = ttyp->c_cc[VKILL] = '\0';
+ if (tcsetattr(fd232, TCSANOW, ttyp) < 0) {
+ syslog(LOG_ERR,
+ "trak_start: tcsetattr(%s): %m", trakdev);
+ goto screwed;
+ }
+ if (tcflush(fd232, TCIOFLUSH) < 0) {
+ syslog(LOG_ERR,
+ "trak_start: tcflush(%s): %m", trakdev);
+ goto screwed;
+ }
+#if defined(TRAKCLK)
+ if (ioctl(fd232, I_PUSH, "clk") < 0)
+ syslog(LOG_ERR,
+ "trak_start: ioctl(%s, I_PUSH, clk): %m", trakdev);
+ if (ioctl(fd232, CLK_SETSTR, "*") < 0)
+ syslog(LOG_ERR,
+ "trak_start: ioctl(%s, CLK_SETSTR): %m", trakdev);
+#endif /* TRAKCLK */
+#if defined(TRAKPPS)
+ if (ioctl(fd232, I_PUSH, "ppsclock") < 0)
+ syslog(LOG_ERR,
+ "trak_start: ioctl(%s, I_PUSH, ppsclock): %m", trakdev);
+ else
+ fdpps = fd232;
+#endif /* TRAKPPS */
+ }
+#endif /* STREAM */
+#if defined(HAVE_BSD_TTYS)
+ /*
+ * 4.3bsd serial line parameters (sgttyb interface)
+ *
+ * The TRAKCLK option provides timestamping at the driver level.
+ * It requires the tty_clk line discipline and 4.3bsd or later.
+ */
+ { struct sgttyb ttyb;
+#if defined(TRAKCLK)
+ int ldisc = CLKLDISC;
+#endif /* TRAKCLK */
+
+ if (ioctl(fd232, TIOCGETP, &ttyb) < 0) {
+ syslog(LOG_ERR,
+ "trak_start: ioctl(%s, TIOCGETP): %m", trakdev);
+ goto screwed;
+ }
+ ttyb.sg_ispeed = ttyb.sg_ospeed = SPEED232;
+#if defined(TRAKCLK)
+ ttyb.sg_erase = ttyb.sg_kill = '\r';
+ ttyb.sg_flags = RAW;
+#else
+ ttyb.sg_erase = ttyb.sg_kill = '\0';
+ ttyb.sg_flags = EVENP|ODDP|CRMOD;
+#endif /* TRAKCLK */
+ if (ioctl(fd232, TIOCSETP, &ttyb) < 0) {
+ syslog(LOG_ERR,
+ "trak_start: ioctl(%s, TIOCSETP): %m", trakdev);
+ goto screwed;
+ }
+#if defined(TRAKCLK)
+ if (ioctl(fd232, TIOCSETD, &ldisc) < 0) {
+ syslog(LOG_ERR,
+ "trak_start: ioctl(%s, TIOCSETD): %m",trakdev);
+ goto screwed;
+ }
+#endif /* TRAKCLK */
+ }
+#endif /* HAVE_BSD_TTYS */
+
+ /*
+ * Allocate unit structure
+ */
+ if (gpsunits[unit] != 0) {
+ gps = gpsunits[unit]; /* The one we want is okay */
+ } else {
+ for (i = 0; i < MAXUNITS; i++) {
+ if (!unitinuse[i] && gpsunits[i] != 0)
+ break;
+ }
+ if (i < MAXUNITS) {
+ /*
+ * Reclaim this one
+ */
+ gps = gpsunits[i];
+ gpsunits[i] = 0;
+ } else {
+ gps = (struct gpsunit *)
+ emalloc(sizeof(struct gpsunit));
+ }
+ }
+ bzero((char *)gps, sizeof(struct gpsunit));
+ gpsunits[unit] = gps;
+
+ /*
+ * Set up the structures
+ */
+ gps->peer = peer;
+ gps->unit = (u_char)unit;
+ gps->timestarted = current_time;
+
+ gps->io.clock_recv = trak_receive;
+ gps->io.srcclock = (caddr_t)gps;
+ gps->io.datalen = 0;
+ gps->io.fd = fd232;
+#ifdef TRAKPPS
+ if (ioctl(fd232, CIOGETEV, (caddr_t)&ev) < 0) {
+ syslog(LOG_ERR,
+ "trak_start: ioctl(%s, CIOGETEV): %m", trakdev);
+ goto screwed;
+ } else
+ gps->lastev = ev.tv.tv_sec;
+#endif /* TRAKPPS */
+ if (!io_addclock(&gps->io)) {
+ goto screwed;
+ }
+
+ /*
+ * All done. Initialize a few random peer variables, then
+ * return success. Note that root delay and root dispersion are
+ * always zero for this clock.
+ */
+ peer->precision = GPSPRECISION;
+ peer->rootdelay = 0;
+ peer->rootdispersion = 0;
+ peer->stratum = stratumtouse[unit];
+ if (stratumtouse[unit] <= 1)
+ bcopy(GPSREFID, (char *)&peer->refid, 4);
+ else
+ peer->refid = htonl(GPSHSREFID);
+ unitinuse[unit] = 1;
+ /*
+ * request to give time code
+ */
+ {
+ void gps_send();
+ gps_send(gps,"\rRQTS,U\r");
+ gps_send(gps,"SEL 00\r");
+ }
+
+ return (1);
+
+ /*
+ * Something broke; abandon ship.
+ */
+screwed:
+ (void) close(fd232);
+ return (0);
+}
+
+/*
+ * trak_shutdown - shut down a GPS clock
+ */
+static void
+trak_shutdown(unit)
+ int unit;
+{
+ register struct gpsunit *gps;
+ void gps_send();
+
+ if (unit >= MAXUNITS) {
+ syslog(LOG_ERR, "trak_shutdown: unit %d invalid", unit);
+ return;
+ }
+ if (!unitinuse[unit]) {
+ syslog(LOG_ERR, "trak_shutdown: unit %d not in use", unit);
+ return;
+ }
+ gps = gpsunits[unit];
+ /*
+ * request not to give time code any more
+ */
+ gps_send(gps,"RQTX\r");
+ /*
+ * Tell the I/O module to turn us off. We're history.
+ */
+ io_closeclock(&gps->io);
+
+ unitinuse[unit] = 0;
+}
+
+
+/*
+ * trak_report_event - note the occurance of an event
+ *
+ * This routine presently just remembers the report and logs it, but
+ * does nothing heroic for the trap handler.
+ */
+static void
+trak_report_event(gps, code)
+ struct gpsunit *gps;
+ int code;
+{
+ struct peer *peer;
+
+ peer = gps->peer;
+ if (gps->status != (u_char)code) {
+ gps->status = (u_char)code;
+ if (code != CEVNT_NOMINAL)
+ gps->lastevent = (u_char)code;
+ syslog(LOG_INFO,
+ "clock %s event %x\n", ntoa(&peer->srcadr), code);
+ }
+}
+
+
+/*
+ * trak_receive - receive data from the serial interface
+ */
+static void
+trak_receive(rbufp)
+ struct recvbuf *rbufp;
+{
+ register int i,cmdtype;
+ register struct gpsunit *gps;
+
+#if defined(TRAKPPS)
+ struct ppsclockev ev;
+ l_fp trtmp;
+#endif /* TRAKPPS */
+ register u_char *dpt;
+ register u_char *cp;
+ register u_char *dpend;
+ l_fp tstmp;
+ u_fp dispersion;
+
+ /*
+ * Get the clock this applies to and pointers to the data.
+ * Edit the timecode to remove control chars and trashbits.
+ */
+ gps = (struct gpsunit *)rbufp->recv_srcclock;
+ dpt = (u_char *)&rbufp->recv_space;
+ dpend = dpt + rbufp->recv_length;
+ cp = (u_char *)gps->lastcode;
+
+ while (dpt < dpend) {
+#ifdef TRAKCLK /* prior to TRAKPPS due to timestamp */
+ if ((*cp = 0x7f & *dpt++) != '*' ) cp++;
+ else if (*cp == '*' ) { /* caught magic character */
+ if ( dpend - dpt < 8) {
+ /* short timestamp */
+ if(debug) puts("gps: short timestamp.");
+ return;
+ }
+ if (!buftvtots(dpt,&gps->lastrec)) {
+ /* screwy timestamp */
+ if(debug) puts("gps: screwy timestamp.");
+ return;
+ }
+ dpt += 8;
+ }
+#else
+#ifdef TRAKPPS
+ if ((*cp = 0x7f & *dpt++) >= ' ') cp++;
+#else
+ /* both are not specified */
+#endif /* TRAKPPS */
+#endif /* TRAKCLK */
+ }
+ *cp = '\0';
+ gps->lencode = cp - (u_char *)gps->lastcode;
+ if (gps->lencode == 0) return;
+
+#ifdef DEBUG
+ if (debug)
+ printf("gps: timecode %d %s\n",
+ gps->lencode, gps->lastcode);
+#endif
+
+ /*
+ * We check the timecode format and decode its contents. The
+ * timecode has format *........RQTS U,ddd:hh:mm:ss.0,Q\r\n).
+ * 012345678901234567890123
+ */
+#define RQTS 0
+#define RQLS 1
+ cp = (u_char *)gps->lastcode;
+ gps->leap = 0;
+ cmdtype=0;
+ if(strncmp(cp,"*RQTS",5)==0) {
+ cmdtype=RQTS;
+ cp += 8;
+ }
+ else if(strncmp(cp,"RQTS",4)==0) {
+ cmdtype=RQTS;
+ cp += 7;
+ }
+ else if(strncmp(cp,"RQLS",4)==0) {
+ cmdtype=RQLS;
+ cp += 5;
+ }
+ else
+ return;
+
+ switch( cmdtype ) {
+ case RQTS:
+ /*
+ * Check time code format of TRAK 8810
+ */
+ if( !isdigit(cp[0]) ||
+ !isdigit(cp[1]) ||
+ !isdigit(cp[2]) ||
+ cp[3] != ':' ||
+ !isdigit(cp[4]) ||
+ !isdigit(cp[5]) ||
+ cp[6] != ':' ||
+ !isdigit(cp[7]) ||
+ !isdigit(cp[8]) ||
+ cp[9] != ':' ||
+ !isdigit(cp[10])||
+ !isdigit(cp[11])) {
+ gps->badformat++;
+ trak_report_event(gps, CEVNT_BADREPLY);
+ return;
+ }
+ break;
+ case RQLS:
+ /*
+ * reply for leap second request
+ */
+ if (cp[0] !='0' || cp[1] != '0' ) gps->leap = LEAP_ADDSECOND;
+ return;
+ default:
+ return;
+
+ }
+
+ /*
+ * Convert date and check values.
+ */
+ gps->day = cp[0] - '0';
+ gps->day = MULBY10(gps->day) + cp[1] - '0';
+ gps->day = MULBY10(gps->day) + cp[2] - '0';
+ if (gps->day < 1 || gps->day > 366) {
+ gps->baddata++;
+ trak_report_event(gps, CEVNT_BADDATE);
+ return;
+ }
+ /*
+ * Convert time and check values.
+ */
+ gps->hour = MULBY10(cp[4] - '0') + cp[5] - '0';
+ gps->minute = MULBY10(cp[7] - '0') + cp[8] - '0';
+ gps->second = MULBY10(cp[10] - '0') + cp[11] - '0';
+ gps->msec = 0;
+ if (gps->hour > 23 || gps->minute > 59 || gps->second > 59) {
+ gps->baddata++;
+ trak_report_event(gps, CEVNT_BADTIME);
+ return;
+ }
+
+ if (!gps->polled) return;
+
+ /*
+ * Test for synchronization Check for quality byte.
+ */
+/*
+ switch( cp[15] ) {
+ case '0':
+ if(gps->peer->stratum == stratumtouse[gps->unit]) {
+ gps->peer->stratum = 10 ;
+ bzero(&gps->peer->refid,4);
+ }
+ break;
+ default:
+ if(gps->peer->stratum != stratumtouse[gps->unit]) {
+ gps->peer->stratum = stratumtouse[gps->unit] ;
+ bcopy(GPSREFID,&gps->peer->refid,4);
+ }
+ break;
+ }
+*/
+ if( cp[15] == '0') /* TRAK derailed from tracking satellites */
+ {
+ gps->leap = LEAP_NOTINSYNC;
+ gps->noreply++;
+ trak_report_event(gps, CEVNT_TIMEOUT);
+ }
+ else
+ {
+ gps->lasttime = current_time;
+ if( gps->lastevent == CEVNT_TIMEOUT ) {
+ gps->status = CEVNT_NOMINAL;
+ trak_report_event(gps, CEVNT_NOMINAL);
+ }
+ }
+
+ /*
+ * Now, compute the reference time value. Use the heavy
+ * machinery for the second, which presumably is the one which
+ * occured at the last pps pulse and which was captured by the
+ * loop_filter module. All we have to do here is present a
+ * reasonable facsimile of the time at that pulse so the clock-
+ * filter and selection machinery declares us truechimer. The
+ * precision offset within the second is really tuned by the
+ * loop_filter module. Note that this code does not yet know how
+ * to do the years and relies on the clock-calendar chip for
+ * sanity.
+ */
+
+#if defined(TRAKPPS)
+
+ /*
+ * timestamp must be greater than previous one.
+ */
+ if (ioctl(fdpps, CIOGETEV, (caddr_t)&ev) >= 0) {
+ ev.tv.tv_sec += (U_LONG)JAN_1970;
+ TVTOTS(&ev.tv,&gps->lastrec);
+ if (gps->lastev < ev.tv.tv_sec) {
+ gps->lastev = ev.tv.tv_sec;
+ } else { /* in case of 1-pps missing */
+ gps->lastev = ev.tv.tv_sec;
+ return;
+ }
+ }
+ else
+ return; /* failed to get timestamp */
+#endif /* TRAKPPS */
+
+ if (!clocktime(gps->day, gps->hour, gps->minute,
+ gps->second, GMT, gps->lastrec.l_ui,
+ &gps->yearstart, &gps->lastref.l_ui)) {
+ gps->baddata++;
+ trak_report_event(gps, CEVNT_BADTIME);
+#ifdef DEBUG
+ if(debug) printf("gps: bad date \n");
+#endif
+ return;
+ }
+ MSUTOTSF(gps->msec, gps->lastref.l_uf);
+ tstmp = gps->lastref;
+
+ L_SUB(&tstmp, &gps->lastrec);
+ L_ADD(&tstmp, &(fudgefactor[gps->unit]));
+ i = ((int)(gps->coderecv)) % NCODES;
+ gps->offset[i] = tstmp;
+ gps->coderecv++;
+#if DEBUG
+ if (debug)
+ printf("gps: times %s %s %s\n",
+ ulfptoa(&gps->lastref, 6), ulfptoa(&gps->lastrec, 6),
+ lfptoa(&tstmp, 6));
+#endif
+/* if( tstmp.l_ui != 0 ) return; something wrong */
+
+ /*
+ * Process the samples in the median filter, add the fudge
+ * factor and pass the offset and dispersion along. We use
+ * lastref as both the reference time and receive time in order
+ * to avoid being cute, like setting the reference time later
+ * than the receive time, which may cause a paranoid protocol
+ * module to chuck out the data.
+ */
+ if (gps->coderecv < NCODES)
+ return;
+ if (!trak_process(gps, &tstmp, &dispersion)) {
+ gps->baddata++;
+ trak_report_event(gps, CEVNT_BADTIME);
+ return;
+ }
+ refclock_receive(gps->peer, &tstmp, GMT, dispersion,
+ &gps->lastrec, &gps->lastrec, gps->leap);
+ /*
+ * after all, clear polled flag
+ */
+ gps->polled = 0;
+}
+
+/*
+ * ==================================================================
+ * gps_send(gps,cmd) Sends a command to the GPS receiver.
+ * as gps_send(gps,"rqts,u\r");
+ * ==================================================================
+ */
+static void
+gps_send(gps,cmd)
+ struct gpsunit *gps;
+ char *cmd;
+{
+ if (write(gps->io.fd, cmd, strlen(cmd)) == -1) {
+ syslog(LOG_ERR, "gps_send: unit %d: %m", gps->unit);
+ trak_report_event(gps,CEVNT_FAULT);
+ } else {
+ gps->polls++;
+ }
+}
+
+/*
+ * trak_process - process a pile of samples from the clock
+ *
+ * This routine uses a three-stage median filter to calculate offset and
+ * dispersion and reduce jitter. The dispersion is calculated as the
+ * span of the filter (max - min).
+ */
+static char
+trak_process(gps, offset, dispersion)
+ struct gpsunit *gps;
+ l_fp *offset;
+ u_fp *dispersion;
+{
+ register int i, j;
+ register U_LONG tmp_ui, tmp_uf;
+ int not_median1 = -1; /* XXX correct? */
+ int not_median2 = -1; /* XXX correct? */
+ int median;
+ u_fp disp_tmp, disp_tmp2;
+
+ /*
+ * This code implements a three-stage median filter. First, we
+ * check if the samples are within 125 ms of each other. If not,
+ * dump the sample set. We take the median of the three offsets
+ * and use that as the sample offset. There probably is not much
+ * to be gained by a longer filter, since the clock filter in
+ * ntp_proto should do its thing.
+ */
+ disp_tmp2 = 0;
+ for (i = 0; i < NCODES-1; i++) {
+ for (j = i+1; j < NCODES; j++) {
+ tmp_ui = gps->offset[i].l_ui;
+ tmp_uf = gps->offset[i].l_uf;
+ M_SUB(tmp_ui, tmp_uf, gps->offset[j].l_ui,
+ gps->offset[j].l_uf);
+ if (M_ISNEG(tmp_ui, tmp_uf)) {
+ M_NEG(tmp_ui, tmp_uf);
+ }
+ if (tmp_ui != 0 || tmp_uf > CODEDIFF) {
+ return (0);
+ }
+ disp_tmp = MFPTOFP(0, tmp_uf);
+ if (disp_tmp > disp_tmp2) {
+ disp_tmp2 = disp_tmp;
+ not_median1 = i;
+ not_median2 = j;
+ }
+ }
+ }
+ if (gps->lasttime == 0)
+ disp_tmp2 = NTP_MAXDISPERSE;
+ else
+ disp_tmp2 = current_time - gps->lasttime;
+ if (not_median1 == 0) {
+ if (not_median2 == 1)
+ median = 2;
+ else
+ median = 1;
+ } else {
+ median = 0;
+ }
+ *offset = gps->offset[median];
+ *dispersion = disp_tmp2;
+ return (1);
+}
+
+/*
+ * trak_poll - called by the transmit procedure
+ *
+ * We go to great pains to avoid changing state here, since there may be
+ * more than one eavesdropper receiving the same timecode.
+ */
+static void
+trak_poll(unit, peer)
+ int unit;
+ struct peer *peer;
+{
+ struct gpsunit *gps;
+
+ if (unit >= MAXUNITS) {
+ syslog(LOG_ERR, "trak_poll: unit %d invalid", unit);
+ return;
+ }
+ if (!unitinuse[unit]) {
+ syslog(LOG_ERR, "trak_poll: unit %d not in use", unit);
+ return;
+ }
+ gps = gpsunits[unit];
+ if ((current_time - gps->lasttime) > 150)
+ trak_report_event(gpsunits[unit], CEVNT_TIMEOUT);
+ /*
+ * usually trak_receive can get a timestamp every second
+ */
+#if !defined(TRAKPPS) && !defined(TRAKCLK)
+ gettstamp(&gps->lastrec);
+#endif
+ gps->polls++;
+ /*
+ * may be polled every 16 seconds (minpoll 4)
+ */
+ gps->polled = 1;
+}
+
+/*
+ * trak_control - set fudge factors, return statistics
+ */
+static void
+trak_control(unit, in, out)
+ u_int unit;
+ struct refclockstat *in;
+ struct refclockstat *out;
+{
+ register struct gpsunit *gps;
+
+ if (unit >= MAXUNITS) {
+ syslog(LOG_ERR, "trak_control: unit %d invalid", unit);
+ return;
+ }
+
+ if (in != 0) {
+ if (in->haveflags & CLK_HAVETIME1)
+ fudgefactor[unit] = in->fudgetime1;
+ if (in->haveflags & CLK_HAVEVAL1) {
+ stratumtouse[unit] = (u_char)(in->fudgeval1 & 0xf);
+ if (unitinuse[unit]) {
+ struct peer *peer;
+
+ /*
+ * Should actually reselect clock, but
+ * will wait for the next timecode
+ */
+ gps = gpsunits[unit];
+ peer = gps->peer;
+ peer->stratum = stratumtouse[unit];
+ if (stratumtouse[unit] <= 1)
+ bcopy(GPSREFID, (char *)&peer->refid,
+ 4);
+ else
+ peer->refid = htonl(GPSHSREFID);
+ }
+ }
+ }
+
+ if (out != 0) {
+ out->type = REFCLK_GPS_TRAK;
+ out->haveflags
+ = CLK_HAVETIME1|CLK_HAVEVAL1|CLK_HAVEVAL2;
+ out->clockdesc = GPSDESCRIPTION;
+ out->fudgetime1 = fudgefactor[unit];
+ out->fudgetime2.l_ui = 0;
+ out->fudgetime2.l_uf = 0;
+ out->fudgeval1 = (LONG)stratumtouse[unit];
+ out->fudgeval2 = 0;
+ out->flags = sloppyclockflag[unit];
+ if (unitinuse[unit]) {
+ gps = gpsunits[unit];
+ out->lencode = gps->lencode; /* LENTOC */;
+ out->lastcode = gps->lastcode;
+ out->timereset = current_time - gps->timestarted;
+ out->polls = gps->polls;
+ out->noresponse = gps->noreply;
+ out->badformat = gps->badformat;
+ out->baddata = gps->baddata;
+ out->lastevent = gps->lastevent;
+ out->currentstatus = gps->status;
+ } else {
+ out->lencode = 0;
+ out->lastcode = "";
+ out->polls = out->noresponse = 0;
+ out->badformat = out->baddata = 0;
+ out->timereset = 0;
+ out->currentstatus = out->lastevent = CEVNT_NOMINAL;
+ }
+ }
+}
+
+/*
+ * trak_buginfo - return clock dependent debugging info
+ */
+static void
+trak_buginfo(unit, bug)
+ int unit;
+ register struct refclockbug *bug;
+{
+ register struct gpsunit *gps;
+
+ if (unit >= MAXUNITS) {
+ syslog(LOG_ERR, "trak_buginfo: unit %d invalid", unit);
+ return;
+ }
+
+ if (!unitinuse[unit])
+ return;
+ gps = gpsunits[unit];
+
+ bug->nvalues = 10;
+ bug->ntimes = 5;
+ if (gps->lasttime != 0)
+ bug->values[0] = current_time - gps->lasttime;
+ else
+ bug->values[0] = 0;
+ bug->values[1] = (U_LONG)gps->reason;
+ bug->values[2] = (U_LONG)gps->year;
+ bug->values[3] = (U_LONG)gps->day;
+ bug->values[4] = (U_LONG)gps->hour;
+ bug->values[5] = (U_LONG)gps->minute;
+ bug->values[6] = (U_LONG)gps->second;
+ bug->values[7] = (U_LONG)gps->msec;
+ bug->values[8] = gps->noreply;
+ bug->values[9] = gps->yearstart;
+ bug->stimes = 0x1c;
+ bug->times[0] = gps->lastref;
+ bug->times[1] = gps->lastrec;
+ bug->times[2] = gps->offset[0];
+ bug->times[3] = gps->offset[1];
+ bug->times[4] = gps->offset[2];
+}
+#endif
diff --git a/contrib/xntpd/xntpdc/ntpdc.c b/contrib/xntpd/xntpdc/ntpdc.c
index 001bd77c1e55..3113c9ff7817 100644
--- a/contrib/xntpd/xntpdc/ntpdc.c
+++ b/contrib/xntpd/xntpdc/ntpdc.c
@@ -53,7 +53,7 @@ static int findcmd P((char *, struct xcmd *, struct xcmd *, struct xcmd **));
static int getarg P((char *, int, arg_v *));
static int getnetnum P((char *, U_LONG *, char *));
static void help P((struct parse *, FILE *));
-#if defined(sgi) || defined(SYS_BSDI)
+#if defined(sgi) || defined(SYS_BSDI) || defined(__STDC__)
static int helpsort P((const void *, const void *));
#else
static int helpsort P((char **, char **));
@@ -598,8 +598,12 @@ again:
/*
* So far, so good. Copy this data into the output array.
*/
- if ((datap + datasize) > (pktdata + pktdatasize))
+ if ((datap + datasize) > (pktdata + pktdatasize)) {
+ int offset = datap - pktdata;
growpktdata();
+ *rdata = pktdata; /* might have been realloced ! */
+ datap = pktdata + offset;
+ }
memmove(datap, (char *)rpkt.data, datasize);
datap += datasize;
if (firstpkt) {
@@ -1149,7 +1153,7 @@ help(pcmd, fp)
for (xcp = opcmds; xcp->keyword != 0; xcp++)
cmdsort[n++] = xcp->keyword;
-#if defined(sgi) || defined(SYS_BSDI)
+#if defined(sgi) || defined(SYS_BSDI) || defined(__STDC__)
qsort((void *)cmdsort, n, sizeof(char *), helpsort);
#else
qsort((char *)cmdsort, n, sizeof(char *), helpsort);
@@ -1195,7 +1199,7 @@ help(pcmd, fp)
* helpsort - do hostname qsort comparisons
*/
static int
-#if defined(sgi) || defined(SYS_BSDI)
+#if defined(sgi) || defined(SYS_BSDI) || defined(__STDC__)
helpsort(t1, t2)
const void *t1;
const void *t2;
diff --git a/contrib/xntpd/xntpdc/ntpdc_ops.c b/contrib/xntpd/xntpdc/ntpdc_ops.c
index 55483faeba10..4fa9324784cc 100644
--- a/contrib/xntpd/xntpdc/ntpdc_ops.c
+++ b/contrib/xntpd/xntpdc/ntpdc_ops.c
@@ -66,10 +66,9 @@ static void ctlstats P((struct parse *, FILE *));
static void leapinfo P((struct parse *, FILE *));
static void clockstat P((struct parse *, FILE *));
static void fudge P((struct parse *, FILE *));
-static void maxskew P((struct parse *, FILE *));
static void clkbug P((struct parse *, FILE *));
static void setprecision P((struct parse *, FILE *));
-static void setselect P((struct parse *, FILE *));
+static void kerninfo P((struct parse *, FILE *));
/*
* Commands we understand. Ntpdc imports this.
@@ -77,37 +76,37 @@ static void setselect P((struct parse *, FILE *));
struct xcmd opcmds[] = {
{ "listpeers", peerlist, { NO, NO, NO, NO },
{ "", "", "", "" },
- "print list of peers the server knows about" },
+ "display list of peers the server knows about" },
{ "peers", peers, { NO, NO, NO, NO },
{ "", "", "", "" },
- "print peer summary information" },
+ "display peer summary information" },
{ "dmpeers", dmpeers, { NO, NO, NO, NO },
{ "", "", "", "" },
- "print peer summary info the way Dave Mills likes it" },
+ "display peer summary info the way Dave Mills likes it" },
{ "showpeer", showpeer, { ADD, OPT|ADD, OPT|ADD, OPT|ADD },
{ "peer_address", "peer2_addr", "peer3_addr", "peer4_addr" },
- "print detailed information for one or more peers" },
+ "display detailed information for one or more peers" },
{ "pstats", peerstats, { ADD, OPT|ADD, OPT|ADD, OPT|ADD },
{ "peer_address", "peer2_addr", "peer3_addr", "peer4_addr" },
- "print statistical information for one or more peers" },
+ "display statistical information for one or more peers" },
{ "loopinfo", loopinfo, { OPT|STR, NO, NO, NO },
{ "oneline|multiline", "", "", "" },
- "print loop filter information" },
+ "display loop filter information" },
{ "sysinfo", sysinfo, { NO, NO, NO, NO },
{ "", "", "", "" },
- "print local server information" },
+ "display local server information" },
{ "sysstats", sysstats, { NO, NO, NO, NO },
{ "", "", "", "" },
- "print local server statistics" },
+ "display local server statistics" },
{ "memstats", memstats, { NO, NO, NO, NO },
{ "", "", "", "" },
- "print peer memory usage statistics" },
+ "display peer memory usage statistics" },
{ "iostats", iostats, { NO, NO, NO, NO },
{ "", "", "", "" },
- "print I/O subsystem statistics" },
+ "display I/O subsystem statistics" },
{ "timerstats", timerstats, { NO, NO, NO, NO },
{ "", "", "", "" },
- "print event timer subsystem statistics" },
+ "display event timer subsystem statistics" },
{ "addpeer", addpeer, { ADD, OPT|UINT, OPT|UINT, OPT|STR },
{ "addr", "keyid", "version", "minpoll|prefer" },
"configure a new peer association" },
@@ -121,14 +120,14 @@ struct xcmd opcmds[] = {
{ "peer_address", "peer2_addr", "peer3_addr", "peer4_addr" },
"unconfigure existing peer assocations" },
{ "set", set, { STR, OPT|STR, OPT|STR, OPT|STR },
- { "bclient|auth", "...", "...", "..." },
- "set a system flag (bclient, authenticate)" },
+ { "bclient|mclient|auth", "...", "...", "..." },
+ "set a system flag (bclient, mclient, auth)" },
{ "clear", sys_clear, { STR, OPT|STR, OPT|STR, OPT|STR },
- { "bclient|auth", "...", "...", "..." },
- "clear a system flag (bclient, authenticate)" },
+ { "bclient|mclient|auth", "...", "...", "..." },
+ "clear a system flag (bclient, mclient, auth)" },
{ "reslist", reslist, { NO, NO, NO, NO },
{ "", "", "", "" },
- "print the server's restrict list" },
+ "display the server's restrict list" },
{ "restrict", restrict, { ADD, ADD, STR, OPT|STR },
{ "address", "mask",
"ntpport|ignore|noserve|notrust|noquery|nomodify|nopeer",
@@ -144,7 +143,7 @@ struct xcmd opcmds[] = {
"delete a restrict entry" },
{ "monlist", monlist, { NO, NO, NO, NO },
{ "", "", "", "" },
- "print data the server's monitor routines have collected" },
+ "display data the server's monitor routines have collected" },
{ "monitor", monitor, { STR, NO, NO, NO },
{ "on|off", "", "", "" },
"turn the server's monitoring facility on or off" },
@@ -171,10 +170,10 @@ struct xcmd opcmds[] = {
"remove one or more key ID's from the trusted list" },
{ "authinfo", authinfo, { NO, NO, NO, NO },
{ "", "", "", "" },
- "obtain information concerning the state of the authentication code" },
+ "display the state of the authentication code" },
{ "traps", traps, { NO, NO, NO, NO },
{ "", "", "", "" },
- "obtain information about traps set in server" },
+ "display the traps set in the server" },
{ "addtrap", addtrap, { ADD, OPT|UINT, OPT|ADD, NO },
{ "address", "port", "interface", "" },
"configure a trap in the server" },
@@ -189,28 +188,26 @@ struct xcmd opcmds[] = {
"change the keyid the server uses to authenticate control messages" },
{ "ctlstats", ctlstats, { NO, NO, NO, NO },
{ "", "", "", "" },
- "obtain packet count statistics from the control module" },
+ "display packet count statistics from the control module" },
{ "leapinfo", leapinfo, { NO, NO, NO, NO },
{ "", "", "", "" },
- "obtain information about the current leap second state" },
+ "display the current leap second state" },
{ "clockstat", clockstat, { ADD, OPT|ADD, OPT|ADD, OPT|ADD },
{ "address", "address", "address", "address" },
- "obtain status information about the specified clock" },
+ "display clock status information" },
{ "fudge", fudge, { ADD, STR, STR, NO },
{ "address", "time1|time2|val1|val2|flags", "value", "" },
"set/change one of a clock's fudge factors" },
- { "maxskew", maxskew, { STR, NO, NO, NO },
- { "maximum_skew", "", "", "" },
- "set the server's maximum skew parameter" },
{ "clkbug", clkbug, { ADD, OPT|ADD, OPT|ADD, OPT|ADD },
{ "address", "address", "address", "address" },
- "obtain debugging information from the specified clock" },
+ "display clock debugging information" },
{ "setprecision", setprecision, { INT, NO, NO, NO },
{ "sys_precision", "", "", "" },
"set the server's advertised precision" },
- { "setselect", setselect, { UINT, NO, NO, NO },
- { "select_algorithm_number", "", "", "" },
- "change the selection weighting algorithm used by the server" },
+ { "kerninfo", kerninfo, { NO, NO, NO, NO },
+ { "", "", "", "" },
+ "display the kernel pll/pps variables" },
+
{ 0, 0, { NO, NO, NO, NO },
{ "", "", "", "" }, "" }
};
@@ -374,9 +371,9 @@ dopeers(pcmd, fp, dmstyle)
return;
(void) fprintf(fp,
- " remote local st poll reach delay offset disp\n");
+ " remote local st poll reach delay offset disp\n");
(void) fprintf(fp,
- "======================================================================\n");
+ "=======================================================================\n");
while (items > 0) {
if (!dmstyle) {
if (plist->flags & INFO_FLAG_SYSPEER)
@@ -407,13 +404,14 @@ dopeers(pcmd, fp, dmstyle)
ntp_poll = 1<<max(min3(plist->ppoll, plist->hpoll, NTP_MAXPOLL),
NTP_MINPOLL);
(void) fprintf(fp,
- "%c%-15.15s %-15.15s %2d %4d %3o %7.7s %9.9s %6.6s\n",
+ "%c%-15.15s %-15.15s %2d %4d %3o %7.7s %9.9s %7.7s\n",
c, nntohost(plist->srcadr),
numtoa(plist->dstadr),
plist->stratum, ntp_poll, plist->reach,
- fptoa(NTOHS_FP(plist->delay), 4),
+ fptoa(NTOHS_FP(plist->delay), 5),
lfptoa(&tempts, 6),
- ufptoa(NTOHS_FP(plist->dispersion), 4));
+ ufptoa(NTOHS_FP(plist->dispersion), 5));
+
plist++;
items--;
}
@@ -451,16 +449,19 @@ printpeer(pp, fp)
"leap %c%c, refid [%s], rootdistance %s, rootdispersion %s\n",
pp->leap & 0x2 ? '1' : '0',
pp->leap & 0x1 ? '1' : '0',
- str, ufptoa(HTONS_FP(pp->rootdelay), 4),
- ufptoa(HTONS_FP(pp->rootdispersion), 4));
+ str, ufptoa(HTONS_FP(pp->rootdelay), 5),
+ ufptoa(HTONS_FP(pp->rootdispersion), 5));
(void) fprintf(fp,
"ppoll %d, hpoll %d, keyid %u, version %d, association %u\n",
pp->ppoll, pp->hpoll, pp->keyid, pp->version, ntohs(pp->associd));
(void) fprintf(fp,
- "valid %d, reach %03o, unreach %d, trust %03o\n",
- pp->valid, pp->reach, pp->unreach, pp->trust);
+ "valid %d, reach %03o, unreach %d, flash %03o, ",
+ pp->valid, pp->reach, pp->unreach, pp->flash);
+
+ (void) fprintf(fp, "estbdelay %s, ttl %d\n",
+ mfptoa(0, ntohl(pp->estbdelay), 5), pp->ttl);
(void) fprintf(fp, "timer %ds, flags", ntohl(pp->timer));
if (pp->flags == 0) {
@@ -508,7 +509,8 @@ printpeer(pp, fp)
(void) fprintf(fp, "filter delay: ");
for (i = 0; i < NTP_SHIFT; i++) {
- (void) fprintf(fp, " %-8.8s", fptoa(HTONS_FP(pp->filtdelay[i]),4));
+ (void) fprintf(fp, " %-8.8s",
+ fptoa(HTONS_FP(pp->filtdelay[i]), 5));
if (i == (NTP_SHIFT>>1)-1)
(void) fprintf(fp, "\n ");
}
@@ -517,7 +519,7 @@ printpeer(pp, fp)
(void) fprintf(fp, "filter offset:");
for (i = 0; i < NTP_SHIFT; i++) {
HTONL_FP(&pp->filtoffset[i], &tempts);
- (void) fprintf(fp, " %-8.8s", lfptoa(&tempts, 5));
+ (void) fprintf(fp, " %-8.8s", lfptoa(&tempts, 6));
if (i == (NTP_SHIFT>>1)-1)
(void) fprintf(fp, "\n ");
}
@@ -531,23 +533,13 @@ printpeer(pp, fp)
}
(void) fprintf(fp, "\n");
- (void) fprintf(fp, "bdelay filter:");
- for (i = 0; i < NTP_SHIFT; i++) {
- (void) fprintf(fp, " %-8.8s",
- mfptoa(0, ntohl(pp->bdelay[i]), 5));
- if (i == (NTP_SHIFT>>1)-1)
- (void) fprintf(fp, "\n ");
- }
- (void) fprintf(fp, "\n");
-
- (void) fprintf(fp, "delay %s, estbdelay %s\n",
- fptoa(HTONS_FP(pp->delay), 4),
- mfptoa(0, ntohl(pp->estbdelay), 4));
HTONL_FP(&pp->offset, &tempts);
- (void) fprintf(fp, "offset %s, dispersion %s\n",
- lfptoa(&tempts, 6),
- ufptoa(HTONS_FP(pp->dispersion), 4));
+ (void) fprintf(fp,
+ "offset %s, delay %s, dispersion %s, selectdisp %s\n",
+ lfptoa(&tempts, 6), fptoa(HTONS_FP(pp->delay), 5),
+ ufptoa(HTONS_FP(pp->dispersion), 5),
+ ufptoa(HTONS_FP(pp->selectdisp), 5));
}
@@ -781,11 +773,10 @@ sysinfo(pcmd, fp)
is->leap & 0x1 ? '1' : '0');
(void) fprintf(fp, "stratum: %d\n", (int)is->stratum);
(void) fprintf(fp, "precision: %d\n", (int)is->precision);
- (void) fprintf(fp, "select algorithm: %d\n", (int)is->selection);
(void) fprintf(fp, "sync distance: %s\n",
- fptoa(NTOHS_FP(is->rootdelay), 4));
+ fptoa(NTOHS_FP(is->rootdelay), 5));
(void) fprintf(fp, "sync dispersion: %s\n",
- ufptoa(NTOHS_FP(is->rootdispersion), 4));
+ ufptoa(NTOHS_FP(is->rootdispersion), 5));
if (is->stratum <= 1) {
junk[4] = 0;
memmove(junk, (char *)&is->refid, 4);
@@ -799,7 +790,8 @@ sysinfo(pcmd, fp)
(void) fprintf(fp, "reference time: %s\n", prettydate(&tempts));
(void) fprintf(fp, "system flags: ");
- if ((is->flags & (INFO_FLAG_BCLIENT|INFO_FLAG_AUTHENABLE)) == 0) {
+ if ((is->flags & (INFO_FLAG_BCLIENT | INFO_FLAG_MCLIENT |
+ INFO_FLAG_AUTHENABLE)) == 0) {
(void) fprintf(fp, "none\n");
} else {
res = 0;
@@ -807,6 +799,10 @@ sysinfo(pcmd, fp)
(void) fprintf(fp, "bclient");
res = 1;
}
+ if (is->flags & INFO_FLAG_MCLIENT) {
+ (void) fprintf(fp, "mclient");
+ res = 1;
+ }
if (is->flags & INFO_FLAG_AUTHENABLE)
(void) fprintf(fp, "%sauthenticate",
res ? ", " : "");
@@ -818,8 +814,6 @@ sysinfo(pcmd, fp)
HTONL_FP(&is->authdelay, &tempts);
(void) fprintf(fp, "encryption delay: %s\n", lfptoa(&tempts, 7));
- (void) fprintf(fp, "maximum skew: %s\n",
- ufptoa(NTOHS_FP(is->maxskew), 4));
}
@@ -846,8 +840,12 @@ sysstats(pcmd, fp)
if (!check1item(items, fp))
return;
- if (!checkitemsize(itemsize, sizeof(struct info_sys_stats)))
+ if (itemsize != sizeof(struct info_sys_stats) &&
+ itemsize != sizeof(struct old_info_sys_stats)) {
+ /* issue warning according to new structure size */
+ checkitemsize(itemsize, sizeof(struct info_sys_stats));
return;
+ }
(void) fprintf(fp, "system uptime: %d\n",
ntohl(ss->timeup));
@@ -867,8 +865,11 @@ sysstats(pcmd, fp)
ntohl(ss->processed));
(void) fprintf(fp, "bad authentication: %d\n",
ntohl(ss->badauth));
- (void) fprintf(fp, "wander hold downs: %d\n",
- ntohl(ss->wanderhold));
+ if (itemsize != sizeof(struct info_sys_stats))
+ return;
+
+ (void) fprintf(fp, "limitation rejects: %d\n",
+ ntohl(ss->limitrejected));
}
@@ -1205,6 +1206,8 @@ doset(pcmd, fp, req)
for (items = 0; items < pcmd->nargs; items++) {
if (STREQ(pcmd->argval[items].string, "bclient"))
sys.flags |= SYS_FLAG_BCLIENT;
+ else if (STREQ(pcmd->argval[items].string, "mclient"))
+ sys.flags |= SYS_FLAG_MCLIENT;
else if (STREQ(pcmd->argval[items].string, "auth"))
sys.flags |= SYS_FLAG_AUTHENTICATE;
else {
@@ -1243,6 +1246,7 @@ static struct resflags resflags[] = {
{ "nopeer", RES_NOPEER },
{ "notrap", RES_NOTRAP },
{ "lptrap", RES_LPTRAP },
+ { "limited", RES_LIMITED },
{ "", 0 }
};
@@ -1463,6 +1467,7 @@ monlist(pcmd, fp)
FILE *fp;
{
struct info_monitor *ml;
+ struct old_info_monitor *oml;
int items;
int itemsize;
int res;
@@ -1476,23 +1481,49 @@ monlist(pcmd, fp)
if (!checkitems(items, fp))
return;
- if (!checkitemsize(itemsize, sizeof(struct info_monitor)))
- return;
+ if (itemsize == sizeof(struct info_monitor)) {
- (void) fprintf(fp,
- " address port count mode version lasttime firsttime\n");
- (void) fprintf(fp,
- "=====================================================================\n");
- while (items > 0) {
- (void) fprintf(fp, "%-20.20s %5d %9d %4d %3d %9u %9u\n",
- nntohost(ml->addr),
- ntohs(ml->port),
- ntohl(ml->count),
- ml->mode, ml->version,
- ntohl(ml->lasttime),
- ntohl(ml->firsttime));
- ml++;
- items--;
+ (void) fprintf(fp,
+ " address port count mode version lastdrop lasttime firsttime\n");
+ (void) fprintf(fp,
+ "===============================================================================\n");
+ while (items > 0) {
+ (void) fprintf(fp, "%-20.20s %5d %9d %4d %3d %9u %9u %9u\n",
+ nntohost(ml->addr),
+ ntohs(ml->port),
+ ntohl(ml->count),
+ ml->mode,
+ ml->version,
+ ntohl(ml->lastdrop),
+ ntohl(ml->lasttime),
+ ntohl(ml->firsttime));
+ ml++;
+ items--;
+ }<