]> err.no Git - util-linux/commitdiff
Imported from util-linux-2.5 tarball.
authorKarel Zak <kzak@redhat.com>
Wed, 6 Dec 2006 23:25:33 +0000 (00:25 +0100)
committerKarel Zak <kzak@redhat.com>
Wed, 6 Dec 2006 23:25:33 +0000 (00:25 +0100)
188 files changed:
ANNOUNCE
LSM
MCONFIG
Makefile
README
bsd/Makefile
bsd/pathnames.h
disk-utils/Makefile
disk-utils/README.fdisk
disk-utils/README.fdisk.alpha [new file with mode: 0644]
disk-utils/README.fdisk.bsd [new file with mode: 0644]
disk-utils/cfdisk.8
disk-utils/cfdisk.8.bak [new file with mode: 0644]
disk-utils/cfdisk.c
disk-utils/cfdisk.c.bak [new file with mode: 0644]
disk-utils/cfdisk.c.orig [new file with mode: 0644]
disk-utils/fdformat.c
disk-utils/fdisk.8
disk-utils/fdisk.c
disk-utils/fdisk.h [new file with mode: 0644]
disk-utils/fdisklabel.c [new file with mode: 0644]
disk-utils/fdisklabel.h [new file with mode: 0644]
disk-utils/fsck.minix.8
disk-utils/llseek.c
disk-utils/mkfs.8
disk-utils/mkfs.c
disk-utils/mkfs.minix.8
disk-utils/mkfs.minix.c
disk-utils/mkswap.8
disk-utils/mkswap.c
games/Makefile
games/ddate.6 [deleted file]
games/ddate.c [deleted file]
historic/frag.8 [new file with mode: 0644]
historic/frag.c [new file with mode: 0644]
historic/lpcntl.8 [new file with mode: 0644]
historic/lpcntl.c [new file with mode: 0644]
historic/mesg.1 [new file with mode: 0644]
historic/mesg.c [new file with mode: 0644]
historic/mkfs.c [new file with mode: 0644]
historic/mkswap.8 [new file with mode: 0644]
historic/mkswap.c [new file with mode: 0644]
historic/selection/Makefile
historic/selection/mouse.c.old [new file with mode: 0644]
historic/selection/selection.1.old [new file with mode: 0644]
install-sh [new file with mode: 0644]
login-utils/Makefile
login-utils/README.admutil
login-utils/README.poeigl
login-utils/agetty.8
login-utils/agetty.c
login-utils/checktty.c [new file with mode: 0644]
login-utils/chfn.1
login-utils/chfn.c
login-utils/chsh.1
login-utils/chsh.c
login-utils/last.1
login-utils/last.1.orig [new file with mode: 0644]
login-utils/last.c
login-utils/last.c.orig [new file with mode: 0644]
login-utils/login.1
login-utils/login.c
login-utils/mesg.1
login-utils/mesg.c
login-utils/newgrp.1
login-utils/passwd.1
login-utils/passwd.c
login-utils/setpwnam.c
login-utils/shutdown.8
login-utils/shutdown.c
login-utils/simpleinit.c
login-utils/ttymsg.c
login-utils/vipw.8
login-utils/vipw.c
login-utils/wall.c
makedev-1.4.1/LEGAL.NOTICE [deleted file]
makedev-1.4.1/MAKEDEV-C.8 [deleted file]
makedev-1.4.1/Makefile [deleted file]
makedev-1.4.1/README.MAKEDEV-C [deleted file]
makedev-1.4.1/THIS_VERSION_IS_ALTERED [deleted file]
makedev-1.4.1/devinfo [deleted file]
makedev-1.4.1/devinfo.5 [deleted file]
makedev-1.4.1/makedev.c [deleted file]
makedev-1.4.1/makedev.cfg [deleted file]
makedev-1.4.1/makedev.cfg.5 [deleted file]
makedev-1.4.1/makedev.h [deleted file]
makedev-1.4.1/makedev.syn [deleted file]
misc-utils/Makefile
misc-utils/cal.c
misc-utils/chkdupexe.1 [new file with mode: 0644]
misc-utils/chkdupexe.pl [new file with mode: 0644]
misc-utils/clear.1
misc-utils/ddate.1 [new file with mode: 0644]
misc-utils/ddate.c [new file with mode: 0644]
misc-utils/domainname.1
misc-utils/dsplit.c
misc-utils/hostname.c.orig [new file with mode: 0644]
misc-utils/mcookie.1
misc-utils/mcookie.c
misc-utils/namei.c
misc-utils/procs.c
misc-utils/reset.1
misc-utils/write.1
misc-utils/write.c
mount/Makefile
mount/fstab.5
mount/fstab.c
mount/fstab.h
mount/mount.8
mount/mount.c
mount/nfs.5
mount/sundries.c
mount/sundries.h
mount/swapon.8
mount/swapon.c
mount/umount.c
mount/version.c
sys-utils/MAKEDEV [deleted file]
sys-utils/MAKEDEV.8 [deleted file]
sys-utils/Makefile
sys-utils/README.MAKEDEV
sys-utils/clock.8
sys-utils/ctrlaltdel.8
sys-utils/cytune.8 [new file with mode: 0644]
sys-utils/cytune.c [new file with mode: 0644]
sys-utils/ipcs.c
sys-utils/sync.S
sys-utils/tunelp.8
sys-utils/tunelp.c
sys-utils/update_state.8 [deleted file]
sys-utils/update_state.sh [deleted file]
syslogd/Makefile
syslogd/syslog.conf.5
syslogd/syslogd.c
syslogd/syslogd.c.orig [new file with mode: 0644]
text-utils/Makefile
text-utils/rev.1
text-utils/rev.c
time/Makefile [deleted file]
time/README.time [deleted file]
time/Theory [deleted file]
time/africa [deleted file]
time/antarctica [deleted file]
time/asctime.c [deleted file]
time/asia [deleted file]
time/australasia [deleted file]
time/backward [deleted file]
time/date.1 [deleted file]
time/date.c [deleted file]
time/difftime.c [deleted file]
time/emkdir.c [deleted file]
time/etcetera [deleted file]
time/europe [deleted file]
time/factory [deleted file]
time/getopt.c [deleted file]
time/ialloc.c [deleted file]
time/leapseconds [deleted file]
time/localtime.c [deleted file]
time/logwtmp.c [deleted file]
time/newctime.3 [deleted file]
time/newtzset.3 [deleted file]
time/northamerica [deleted file]
time/optind.c [deleted file]
time/pacificnew [deleted file]
time/private.h [deleted file]
time/scheck.c [deleted file]
time/solar87 [deleted file]
time/solar88 [deleted file]
time/solar89 [deleted file]
time/southamerica [deleted file]
time/strftime.c [deleted file]
time/systemv [deleted file]
time/time2posix.3 [deleted file]
time/tzfile.5 [deleted file]
time/tzfile.h [deleted file]
time/usno1988 [deleted file]
time/usno1989 [deleted file]
time/usno1989a [deleted file]
time/yearistype.sh [deleted file]
time/zdump.8 [deleted file]
time/zdump.c [deleted file]
time/zic.8 [deleted file]
time/zic.c [deleted file]
uio.h-diff [new file with mode: 0644]
util-linux-2.1.Announce [new file with mode: 0644]
util-linux-2.1.bin.Notes [new file with mode: 0644]
util-linux-2.1.lsm [new file with mode: 0644]
util-linux-2.2.bin.Notes [deleted symlink]

index 4323bf5c83a3691c092f8530657536ef1a6aaa8f..8af6f911798600d682859bed90bdab164c9824d8 100644 (file)
--- a/ANNOUNCE
+++ b/ANNOUNCE
@@ -1,67 +1,71 @@
 
-[Please note that the latest fdisk is "v2.0a (>2GB)" and the latest cfdisk
-is "0.8a BETA (>2GB)".  The cannonical versions of both are in this
-package, and both should work with disks > 2GB if you have Linux 1.1.46 or
-above.]
-
-util-linux-2.2.tar.gz     (source distribution)
-util-linux-2.2.bin.tar.gz (binary distribution)
+util-linux-2.5.tar.gz     (source distribution only)
 
     WARNING: THIS COLLECTION DOES *NOT* SUPPORT SHADOW PASSWORDS.
 
     WARNING: THIS COLLECTION DOES *NOT* SUPPORT SYSTEM V INITTAB.
 
-    WARNING: USE GNU TAR -- OTHER TARS WILL FAIL SILENTLY!
-
     WARNING: DO *NOT* INSTALL WITHOUT THINKING.
 
-    WARNING: *READ* the util-linux-2.2.bin.Notes file *BEFORE* and *AFTER*
-             installation: there are a few links you must make by hand.
-
     This is a collection of many assorted utilities for Linux.  Some are
     system utilities that are not easily available anywhere elsewhere
-    (e.g., mkfs.minix, mkswap); others are BSD ports of common utilities
-    that are not yet contained in any FSF package (e.g., col); others are
-    non-System-V alternatives to common utilities (e.g., simpleinit,
-    agetty, login, passwd).
+    (e.g., mkfs.minix, mkswap, cfdisk, fdisk); others are BSD ports of
+    common utilities that are not yet contained in any FSF package (e.g.,
+    col); others are non-System-V alternatives to common utilities (e.g.,
+    simpleinit, agetty, login, passwd).
 
     The arrangement, as nearly as I can determine, conforms to the Linux
-    Filesystem Structure, Interim Release 1.1, October 9, 1994, with *NO*
+    Filesystem Structure, Interim Release 1.2, March 28, 1995, with *NO*
     exceptions.  A copy of the standards document can be found at
     tsx-11.mit.edu:/pub/linux/docs/linux-standards/fsstnd/*.
 
     Many people provided patches and suggestions.  I deeply appreciate
     this.
 
-
-HIGHLIGHTS for version 2.2:
-1) This is primarily a quick bug-fix release for version 2.1
-2) mkfs wrapper added back in, since e2fsprogs only supplies an fsck wrapper
-3) selection removed, since someone appears to be maintaining it now.  See
-   sunsite.unc.edu:/pub/linux/kernel/patches/console for recent sources.
-   For the time being, I'm keeping a copy in the historic subdirectory of
-   util-linux.  A "make install" should work find from within that
-   directory.
-4) Note that other floppy utilities are available from:
-    ftp.imag.fr:pub/Linux/ZLIBC/fdutils/fdutils-4.1.src.tar.gz
-    sunsite.unc.edu:/pub/Linux/system/Misc/fdutils-4.1.src.tar.gz
-    tsx-11.mit.edu:/pub/linux/sources/sbin/fdutils-4.1.src.tar.gz
-
-
-HIGHLIGHTS for version 2.1:
-
-1) Directory structure rearrange, with configuration support for those who
-   use shadow passwords and System V init (no support is provided for these
-   things, but your utilities won't get overwritten if you do a "make
-   install" after you properly edit MCONFIG).
-2) fdisk and cfdisk should work as expected with 2GB+ disk drives
-3) As usual, lots of stuff was updated and added, including mount, vipw,
-   readprofile
-4) Some stuff was also deleted, and can now be found elsewhere:
-    fsck wrapper: tsx-11.mit.edu:/pub/linux/ALPHA/ext2fs/e2fsprogs*
-    pwd, su: prep.ai.mit.edu:/pub/gnu/sh-utils*
-    ed: prep.ai.mit.edu:/pub/gnu/ed*
-    od: prep.ai.mit.edu:/pub/gnu/textutils*
-    uudecode/uuencode: prep.ai.mit.edu:/pub/gnu/sharutils*
-    bdflush/update: ftp.funet.fi:/pub/OS/Linux/PEOPLE/Linus/v1.1/bdflush*
-
+    This product includes software developed by the University of
+    California, Berkeley and its contributors.
+
+    IN THE FUTURE, SEND UPDATES AND PATCHES TO: util-linux@math.uio.no
+
+
+
+HIGHLIGHTS for version 2.5:
+
+0) Nicolai Langfeldt is taking over maintenance of util-linux, with the
+   help of a few others (Michael K. Johnson, Andries Brouwer, and Rik
+   Faith).
+
+   PLEASE SEND PATCHES AND UPDATES TO: util-linux@math.uio.no
+
+1) The following packages have been removed.  Please use the up-to-date,
+   canonical versions of these packages from the listed places:
+
+    timezone support (/usr/lib/zoneinfo, libz.a, zic, zdump):
+        elsie.nci.nih.gov:/pub/tzcode95d.tar.gz
+        elsie.nci.nih.gov:/pub/tzdata95h.tar.gz
+    MAKEDEV-C:
+        sunsite.unc.edu:/pub/Linux/system/Admin/MAKEDEV-C-1.5.tar.gz
+    MAKEDEV:
+        sunsite.unc.edu:/pub/Linux/system/Admin/MAKEDEV-2.2.tar.gz
+    md5sum:
+        prep.ai.mit.edu:/pub/gnu/textutils-1.3.tar.gz
+        [The GNU version is now compatible with the Plumb/Lankester
+        version.]
+    ksymoops:
+        Now bundled with the kernel in linux/scripts.
+
+2) update_state has been removed
+3) fdisk now supports NetBSD disklabels courtesy of Bernhard Fastenrath
+   <fasten@athene.informatik.uni-bonn.de> (and > 8GB disks, courtesy of
+   Andries Brouwer)
+4) mount improved -- many patches from Andries Brouwer for greatly improved
+   error reporting
+5) ddate, chkdupexe, and other programs have been improved and bug fixed
+6) util-linux is now a source-only distribution
+7) mcookie generates better random numbers and will use /dev/random or
+   /dev/audio if available
+8) chfn, chsh, passwd, and vipw have been updated with security patches
+   from Zefram <A.Main@dcs.warwick.ac.uk>.  Now, they all use the same
+   locking, and several security holes have been patched.  Further, chsh
+   and chfn can be configured at compile time to require a password before
+   updates and chsh can be configured to only use shells from /etc/shells.
diff --git a/LSM b/LSM
index 3b0a1cb3e8624ee267a3df92c1728021b76b01aa..0a64cfe3d14c1c7e5080cdfc439a9d33389b9921 100644 (file)
--- a/LSM
+++ b/LSM
@@ -1,23 +1,23 @@
 Begin3
 Title:          util-linux: Miscellaneous utilities for Linux
-Version:        2.2
-Entered-date:   Sun Feb 26 16:05:47 1995
-Description:    reboot shutdown simpleinit sln swapoff swapon cal chfn chsh
-                clear col colcrt colrm column dnsdomainname domainname
-                dsplit fdformat getopt hexdump hostid hostname ipcrm ipcs
-                last logger look lpcntl mcookie md5sum mesg namei newgrp
-                passwd ramsize rdev readprofile renice reset rev rootflags
-                script selection setfdprm setsid setterm strings swapdev
-                tsort tunelp ul vidmode wall whereis write chroot
-                ctrlaltdel frag syslogd update_state vipw zdump zic
+Version:        2.5
+Entered-date:   Thu Oct 12 15:20:00 1995
+Description:    agetty arch cal cat cfdisk chfn chkdupexe chroot chsh clear
+                clock col colcrt colrm column ctrlaltdel cytune ddate dmesg
+                dnsdomainname domainname dsplit fastboot fasthalt fdformat
+                fdisk fsck.minix getopt halt hexdump hostid hostname ipcrm
+                ipcs kbdrate kill last logger login look mcookie mesg mkfs
+                mkfs.minix mkswap more mount namei passwd ramsize rdev
+                readprofile reboot renice reset rev rootflags script
+                setfdprm setserial setsid setterm shutdown simpleinit sln
+                strings swapdev swapoff swapon sync syslogd tsort tunelp ul
+                umount vidmode vipw wall whereis write
 Keywords:       essential utilities
 Author:         several
-Maintained-by:  faith@cs.unc.edu (Rik Faith)
-Primary-site:   ftp.cs.unc.edu /pub/users/faith/linux
-                592k util-linux-2.2.tar.gz
-                571k util-linux-2.2.bin.tar.gz
-Alternate-site: tsx-11.mit.edu /pub/linux/packages/utils
+Maintained-by:  Nicolai Langfeldt <util-linux@math.uio.no>
+Primary-site:   tsx-11.mit.edu /pub/linux/packages/utils
+                487k util-linux-2.5.tar.gz
 Alternate-site: sunsite.unc.edu /pub/Linux/system/Misc
-Platforms:      Linux 1.1.9x, GNU tar
+Platforms:      Linux 1.2.x/1.3.x
 Copying-policy: GPL, BSD, others
 End
diff --git a/MCONFIG b/MCONFIG
index ee661cfe6330caae1191ee70d2aab70ff0d20db5..12fef1363262d49d15a0b20519bddc2675e9ac36 100644 (file)
--- a/MCONFIG
+++ b/MCONFIG
@@ -1,29 +1,87 @@
 # MCONFIG -- Configuration stuff for util-linux
 # Created: Sat Feb  4 15:50:30 1995
-# Revised: Sun Feb 26 21:33:32 1995 by faith@cs.unc.edu
+# Revised: Thu Oct 12 10:11:33 1995 by r.faith@ieee.org
 # Copyright 1995 Rickard E. Faith (faith@cs.unc.edu)
 #
 
-# If HAVE_SHADOW is set to "yes", then login, chfn, chsh, newgrp, passwd, and
-# vipw will not be built or installed from the login-utils subdirectory.
+# If HAVE_SHADOW is set to "yes", then login, chfn, chsh, newgrp, passwd,
+# and vipw will not be built or installed from the login-utils
+# subdirectory.
 HAVE_SHADOW=no
 #HAVE_SHADOW=yes
 
-# If HAVE_SYSVINIT is set to "yes", then agetty, simpleinit, shutdown,
-# last, mesg, and wall will not be built or installed from the login-utils
-# subdirectory.
+# If you use chfn and chsh from this package, REQUIRE_PASSWORD will require
+# non-root users to enter the account password before updating /etc/passwd.
+REQUIRE_PASSWORD=yes
+#REQUIRE_PASSWORD=no
+
+# If you use chsh from this package, ONLY_LISTED_SHELLS will require that
+# the selected shell be listed in /etc/shells -- otherwise only a warning is
+# printed.  This prevents someone from setting their shell to /bin/false.
+ONLY_LISTED_SHELLS=yes
+#ONLY_LISTED_SHELLS=no
+
+
+# If HAVE_PASSWD is set to "yes", then passwd will not be built or
+# installed from the login-utils subdirectory (but login, chfn, chsh,
+# newgrp, and vipw *will* be installed).
+HAVE_PASSWD=no
+#HAVE_PASSWD=yes
+
+# If HAVE_SYSVINIT is set to "yes", then simpleinit and shutdown will not
+# be built or installed from the login-utils subdirectory.  (The shutdown
+# and halt that come with the SysVinit package should be used with the init
+# found in that package.)
 HAVE_SYSVINIT=no
 #HAVE_SYSVINIT=yes
 
+# If HAVE_SYSVINIT_UTILS is set to "yes", then last, mesg, and wall will
+# not be built or installed from the login-utils subdirectory.  (The
+# shutdown and init from the SysVinit package do not depend on the last,
+# mesg, and wall from that package.)
+HAVE_SYSVINIT_UTILS=no
+#HAVE_SYSVINIT_UTILS=yes
+
+# If HAVE_ANOTHER_GETTY is set to "yes", then agetty will not be built or
+# installed from the login-utils subdirectory.  Note that agetty can
+# co-exist with other gettys, so this option should never be used.
+HAVE_GETTY=no
+#HAVE_GETTY=yes
+
+# If USE_TTY_GROUP is set to "yes", then wall and write will be installed
+# setgid to the "tty" group, and mesg will only set the group write bit.
+# Note that this is only useful if login/xterm/etc. change the group of the
+# user's tty to "tty" [The login in util-linux does this correctly, and
+# xterm will do it correctly if X is compiled with USE_TTY_GROUP set
+# properly.]
+USE_TTY_GROUP=yes
+#USE_TTY_GROUP=no
+
 # If HAVE_STRINGS is set to "yes", then strings won't be installed.  This
 # is the quick fix until the strings in GNU binutils is in wide use and has
-# international support.
+# internationalization support.
 HAVE_STRINGS=no
 #HAVE_STRINGS=yes
 
+# If HAVE_CLEAR is set to "yes", then clear won't be installed, since a
+# version of clear comes with the ncurses package.
+HAVE_CLEAR=no
+#HAVE_CLEAR=yes
+
+# If HAVE_SYSLOGD is set to "yes", then syslogd will not be built or
+# installed from the syslogd subdirectory.
+HAVE_SYSLOGD=no
+#HAVE_SYSLOGD=yes
+
+# If HAVE_ANOTHER_FDISK is set to "yes", then fdisk will not be built or
+# installed from the disk-utils subdirectory.  This anticipates the
+# replacement of fdisk 2.x by fdisk 3.x, which will be distributed
+# separately. 
+HAVE_FDISK=no
+#HAVE_FDISK=yes
+
 CC=            gcc
 OPT=           -pipe -O2 -m486 -fomit-frame-pointer
-WFLAGS=                -Wall
 LDFLAGS=       -s -N
 CFLAGS=                $(OPT) -I. -I$(BSD) \
                        -DSBINDIR=\"$(SBINDIR)\" \
@@ -35,11 +93,12 @@ DEVDIR=             $(DESTDIR)/dev
 ETCDIR=                $(DESTDIR)/etc
 SBINDIR=       $(DESTDIR)/sbin
 USRSBINDIR=    $(DESTDIR)/usr/sbin
+USRLIBDIR=      $(DESTDIR)/usr/lib
 USRBINDIR=      $(DESTDIR)/usr/bin
 USRGAMESDIR=    $(DESTDIR)/usr/games
 BINDIR=         $(DESTDIR)/bin
 VARPATH=       $(DESTDIR)/var
-LOGDIR=                $(DESTDIR)/var/adm
+LOGDIR=                $(DESTDIR)/var/log
 MANDIR=                $(DESTDIR)/usr/man
 MAN1DIR=       $(DESTDIR)/usr/man/man1
 MAN3DIR=       $(DESTDIR)/usr/man/man3
@@ -54,9 +113,6 @@ SHUTDOWNDIR= $(SBINDIR)
 # Directory for fsck
 FSCKDIR=       $(SBINDIR)
 
-# Directory for rdev, vidmode, etc.
-RDEVDIR=       $(USRBINDIR)
-
 # Directory for passwd
 PASSWDDIR=     $(USRBINDIR)
 
@@ -77,3 +133,9 @@ INSTALLDAT=  $(INSTALL) -m $(DATMODE)
 INSTALLSUID=    $(INSTALL) -m $(SUIDMODE) -o root
 
 BSD=           ../bsd
+
+%.o: %.c
+       $(CC) -c $(CFLAGS) $< -o $@
+
+%: %.cc
+       $(CXX) $(CFLAGS) $< -o $@
index 9fb4052723a260d7fd4cf637ed18ed86868443e4..0cc45be2649fb0cabaa79e5f1de4dc63788ce990 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,24 +1,26 @@
 # Makefile -- Makefile for util-linux Linux utilities
 # Created: Sat Dec 26 20:09:40 1992
-# Revised: Sun Feb 26 17:29:25 1995 by faith@cs.unc.edu
+# Revised: Fri Oct  6 21:37:30 1995 by r.faith@ieee.org
 # Copyright 1992, 1993, 1994, 1995 Rickard E. Faith (faith@cs.unc.edu)
+# May be distributed under the terms of the GNU GPL.
 #
 
-VERSION=2.2
-include MCONFIG
+VERSION=2.5
+
+include ./MCONFIG
 
 SUBDIRS= bsd \
        disk-utils \
        games \
        login-utils \
-       makedev-1.4.1 \
        misc-utils \
        mount \
        sys-utils \
-       syslogd \
-       text-utils \
-       time
+       text-utils
 
+ifeq "$(HAVE_SYSLOGD)" "no"
+SUBDIRS:=$(SUBDIRS) syslogd
+endif
 
 .PHONEY: all install clean
 all:
@@ -43,12 +45,13 @@ dist:
        rm -rf /tmp/util-linux-$(VERSION); \
        cvs export -fNd util-linux-$(VERSION) -r HEAD util-linux; \
        cd util-linux-$(VERSION); \
-       ln -s README util-linux-$(VERSION).bin.Notes; \
        find -type d | xargs chmod 755; \
        find -type f | xargs chmod 644; \
        find -type d | xargs chown root:root; \
        find -type f | xargs chown root:root; \
        cd ..; \
-       tar zcvvf util-linux-$(VERSION).tar.gz util-linux-$(VERSION); \
-       cp -p util-linux-$(VERSION)/README util-linux-$(VERSION).bin.Notes; \
+       tar cvvf util-linux-$(VERSION).tar util-linux-$(VERSION); \
+       gzip -9 util-linux-$(VERSION).tar; \
+       cp -p util-linux-$(VERSION)/LSM util-linux-$(VERSION).lsm; \
+       cp -p util-linux-$(VERSION)/ANNOUNCE util-linux-$(VERSION).Announce; \
        echo Done.)
diff --git a/README b/README
index b82609988728c23ad7885f087487ccfb7f1c4b79..ff2a6e06065694b2064780dcaef9554e2b1c67f6 100644 (file)
--- a/README
+++ b/README
@@ -1,41 +1,4 @@
-util-linux: Miscellaneous utilities for Linux
-%n util-linux
-%v 2.2
-%c *
-%l *
-%b *
-%d *
-%f ftp.cs.unc.edu:/pub/users/faith/linux
-%t util-linux-2.2.tar.gz
-%w utils
-%%
-# These lines describe an automated build procedure, please ignore them.
-%setup
-make
-%doc ANNOUNCE LSM README
-%doc COPYING.GPL COPYING.UCB
-%doc ./time/README.time ./disk-utils/README.cfdisk
-%doc ./disk-utils/README.fdisk ./disk-utils/README.bootutils-0.1
-%doc ./sys-utils/README.setserial ./makedev-1.4.1/README.MAKEDEV-C
-%doc ./misc-utils/README.script ./misc-utils/README.hostname
-%doc ./misc-utils/README.namei ./misc-utils/README.cal
-%doc ./misc-utils/README1.namei ./text-utils/README.col
-%doc ./mount/README.mount
-%doc ./login-utils/README.getty ./login-utils/README.admutil
-%doc ./login-utils/README.poeigl
-cp -a $BUILDDIR/$NAME-$VERSION/example.files /usr/doc/$WHERE/$NAME-$VERSION
-* rm -rf /usr/lib/zoneinfo
-* make install
-%i set -x
-%i /usr/sbin/zic -l US/Eastern
-%i /usr/sbin/zic -p America/New_York
-%i set +x
-%i echo 'WARNING: Check time zone!  (If necessary, change with zic).'
-%i echo 'WARNING: Check /etc/rc for initalization of /var/adm/utmp'
-%i echo 'WARNING: /etc/rc should run /sbin/update, *NOT* /sbin/bdflush'
-exit
-# Please ignore the previous lines. . .
-# The informative part of the notes file starts here:
+util-linux 2.5
 
 WARNING: THE PROGRAMS IN THIS SUITE DO *NOT* SUPPORT SHADOW PASSWORD FILES!
 
@@ -45,9 +8,6 @@ WARNING: USE GNU TAR -- OTHER TARS WILL FAIL SILENTLY!
 
 WARNING: DO *NOT* INSTALL WITHOUT THINKING.
 
-WARNING: Read the util-linux-2.2.bin.Notes file *BEFORE* and *AFTER*
-         installation: there are a few links you must make by hand.
-
 WARNING: The agetty, simpleinit, login, passwd, and other programs in this
          package are *NOT* System V compliant.  These utilities are meant
          to be used by people who build their own systems.  If you are not
@@ -55,64 +15,115 @@ WARNING: The agetty, simpleinit, login, passwd, and other programs in this
          prevent you from logging into your system.  Have a boot floppy
          ready, especially if you don't know what you are doing.
 
-WARNING: The binary distribution was tarred using GNU TAR AND THE -S OPTION!
-         This means that holes will be preserved, but that ONLY GNU TAR
-         WILL WORK ON THE BINARY DISTRIBUTION (in fact, other, inferior,
-         tar programs will fail silently).  YOU HAVE BEEN WARNED!
-
-WARNING: localtime and posixtime default to US/Eastern -- change these now.
-
-
-
-To install from the binary distribution:
-
-1) Get binary distribution (see the .lsm file for locations)
-2) cd /
-3) gtar zpxvf util-linux-2.2.bin.tar.gz
-   (or: pms -i util-linux-2.2.bin.tar.gz)
-4) *IF* you want to use agetty and simpleinit, then make softlinks from
-   /sbin/init to simpleinit and from /sbin/getty to agetty, but make sure
-   that your /etc/inittab is set up right (this is *NOT* the System V
-   compatible init!), or you will be hosed.
-5) Run zic -l and/or zic -p to set your timezone.  The distribution is set
-   up to use /usr/lib/zoneinfo/US/Eastern as the default.  This was
-   installed with "zic -l US/Eastern"
-6) Remove all the old binaries from previous locations.
-
 
 
 To install from source:
 
 1) Get source distribution (see the .lsm file for locations)
-2) Untar util-linux-2.2.tar.gz in /usr/src
-3) cd util-linux-2.2
-4) Edit MCONFIG:
-
-   If you use the shadow password suite and do _not_ want to install
-   programs like login and passwd that do not support shadow passwords,
-   then set HAVE_SHADOW to yes
-
-   If you use the System V init suite and do _not_ want to install programs
-   like agetty, simpleinit, and shutdown, then set HAVE_SYSVINIT to yes
+2) Untar util-linux-2.5.tar.gz in /usr/src
+3) cd util-linux-2.5
+4) Edit MCONFIG
+5) make
 
-   If you don't like the compile-time options or the directories, then
-   change them.  Note that you also can say something like "make OPT=-g
-   LDFLAGS=" in order to make a complete debugging version without editing
-   the MCONFIG at all.
+   Note that libc 4.5.26 headers need a small patch to be used with
+   recent kernels.  See the file uio.h-diff for the patch, if necessary.
 
-5) make
 6) make install
 7) If you want to use simpleinit and agetty, then make softlinks from
    /sbin/init to simpleinit and from /sbin/getty to agetty, but make sure
    that your /etc/inittab is set up right (this is *NOT* the System V
    compatible init!), or you will be hosed.  If you are using the SysV
    init and/or some other getty, they you can keep using those.
-8) Run zic -l and/or zic -p to set your timezone.  The distribution is set
-   up to use /usr/lib/zoneinfo/US/Eastern as the default.  This was
-   installed with "zic -l US/Eastern"
-9) Remove all the old binaries from previous locations.
-
-
+8) Remove all the old binaries from previous locations.
+9) See the HIGHLIGHTS below for links you need to make for the new FSSTND
+   compliance. 
+
+
+HIGHLIGHTS for version 2.5:
+0) Nicolai Langfeldt is taking over maintenance of util-linux, with the
+   help of a few others (Michael K. Johnson, Andries Brouwer, and Rik
+   Faith).
+
+   PLEASE SEND PATCHES AND UPDATES TO: util-linux@math.uio.no
+
+1) The following packages have been removed.  Please use the up-to-date,
+   canonical versions of these packages from the listed places:
+
+    timezone support (/usr/lib/zoneinfo, libz.a, zic, zdump):
+        elsie.nci.nih.gov:/pub/tzcode95d.tar.gz
+        elsie.nci.nih.gov:/pub/tzdata95h.tar.gz
+    MAKEDEV-C:
+        sunsite.unc.edu:/pub/Linux/system/Admin/MAKEDEV-C-1.5.tar.gz
+    MAKEDEV:
+        sunsite.unc.edu:/pub/Linux/system/Admin/MAKEDEV-2.2.tar.gz
+    md5sum:
+        prep.ai.mit.edu:/pub/gnu/textutils-1.3.tar.gz
+        [The GNU version is now compatible with the Plumb/Lankester
+        version.]
+    ksymoops:
+        Now bundled with the kernel in linux/scripts.
+
+2) update_state has been removed
+3) fdisk now supports NetBSD disklabels courtesy of Bernhard Fastenrath
+   <fasten@athene.informatik.uni-bonn.de> (and > 8GB disks, courtesy of
+   Andries Brouwer)
+4) mount improved -- many patches from Andries Brouwer for greatly improved
+   error reporting
+5) ddate, chkdupexe, and other programs have been improved and bug fixed
+6) util-linux is now a source-only distribution
+7) mcookie generates better random numbers and will use /dev/random or
+   /dev/audio if available
+8) chfn, chsh, passwd, and vipw have been updated with security patches
+   from Zefram <A.Main@dcs.warwick.ac.uk>.  Now, they all use the same
+   locking, and several security holes have been patched.  Further, chsh
+   and chfn can be configured at compile time to require a password before
+   updates and chsh can be configured to only use shells from /etc/shells.
+        
+
+HIGHLIGHTS for version 2.4 (2.3 was never released):
+0) Michael K. Johnson <johnsonm@nigel.vnet.net> is the interim maintainer
+   while Rik Faith is working on PhD work.
+1) login now makes the login tty mode 600 and places it in group "tty"
+2) wall, and write will not write dangerous escape sequences
+3) wall and write can be run setgid "tty".  If util-linux is compiled for
+   this option, "mesg y" will only set group write instead of group/other
+   write.
+4) fdisk and cfdisk have been patched with the latest llseek.c.  Although I
+   had a lot of bug reports about fdisk from util-linux-2.2, I was unable
+   to reproduce any of the problems.  Some of the problems appeared to be
+   releated to a failure to reboot the machine after changing the partition
+   table, and some may have been due to a specific kernel revision problem.
+   However, this doesn't seem to account for all of the bug reports -- if
+   this version gives you problem, please send as complete a bug report as
+   possible.
+5) chkdupexe from Nicolai Langfeldt (janl@ifi.uio.no)
+6) ctrlaltdel now installs into /sbin instead of /usr/sbin
+7) mkfs replacement from Ron Sommeling (sommel@sci.kun.nl)
+8) lpcntl removed.  Use tunelp instead.
+9) ksymoops from Greg McGary <gkm@magilla.cichlid.com>
+10) mkfs.minix now clears the first 512 bytes of the file system so that
+    Minix disks won't be confused with MSDOS disks (Daniel Quinlan
+    (quinlan@yggdrasil.com))
+11) mkswap should now work on an Alpha running Linux
+12) frag removed.  See
+    sunsite.unc.edu:/pub/Linux/system/Filesystems/defrag-0.6.tar.gz for the
+    latest version.
+13) mount patches from Andries.Brouwer@cwi.nl and Dan Quinlan
+    (quinlan@yggdrasil.com).
+14) MAKEDEV and MAKEDEV-C updated to the latest versions.
+15) Paths updated for FSSTND 1.2.  This means that you may need to make
+    some links.  The links you need to make we system dependent.  The
+    ultimate goal is to rename /var/adm to /var/log and have a symbolic
+    link from /var/adm to /var/log during the transition period.  If you
+    are running an ELF system, you probably won't have to do anything.  The
+    bottom line is that the following files must exist or be pointers to
+    the old version (used internally by the a.out libraries):
+
+             New                 Old
+
+        /var/log/wtmp       /var/adm/wtmp
+        /var/log/lastlog    /var/adm/lastlog
+        /var/run/utmp       /var/adm/utmp
 
 HIGHLIGHTS for version 2.2:
 1) This is primarily a quick bug-fix release for version 2.1
@@ -168,74 +179,76 @@ disk-utils:
     fdisk: A. V. Le Blanc (LeBlanc@mcc.ac.uk) fdisk 1.5 release, with
            patched from Kevin Martin for DOS and OS/2 compatibility (1.5a);
            Rik Faith (1.5b, 2.0).
-    frag: Werner Almesberger (1.0), Steffen Zahn (1.1), Rob Hooft (1.2), 
-          Steffen Zahn (szahn%masterix@emndev.siemens.co.at) (1.3), Michael
-          Bischoff <mbi@mo.math.nat.tu-bs.de> (1.4).
     fsck.minix, mkfs.minix: Linus Torvalds, with modifications by: Rik
                             Faith (faith@cs.unc.edu), Scott Heavner
                             (sdh@po.cwru.edu), Dr. Wettstein
                             (greg%wind.uucp@plains.nodak.edu), Daniel
                             Quinlan (quinlan@yggdrasil.com).
+    mkfs: David Engel (david@ods.com) and Fred N. van Kempen
+          (waltje@uWalt.NL.Mugnet.ORG)
+          Version 1.9 from Ron Sommeling (sommel@sci.kun.nl)
     mkswap: Linus Torvalds, with modifications by Mike Jagdis
             (jaggy@purplet.demon.co.uk. )
+            Version for Alpha from
+            cage.cs.arizona.edu:/pub/davidm/linux/mkswap-axp-950503.tar.gz
     setfdprm: Werner Almesberger (almesber@nessie.cs.id.ethz.ch)
               Note that more floppy utilities are available from:
                 ftp.imag.fr:pub/Linux/ZLIBC/fdutils/fdutils-4.1.src.tar.gz
                 sunsite.unc.edu:/pub/Linux/system/Misc/fdutils-4.1.src.tar.gz
                 tsx-11.mit.edu:/pub/linux/sources/sbin/fdutils-4.1.src.tar.gz
-    llseek.c: from Remy Card's e2fsprogs-0.5b-WIP.tar.gz
+    llseek.c: from Remy Card's e2fsprogs-0.5b.tar.gz (21Mar95 version) from:
+                sunsite.unc.edu:/pub/Linux/system/Filesystems/ext2
 
 games:
     banner: (8.3 (Berkeley) 4/2/94)
-    ddate: Druel the Chaotic aka Jeremy Johnson aka mpython@gnu.ai.mit.edu,
-           with modifications by Lee Harvey Oswald Smith, K.S.C.
+            ftp.cdrom.com:/pub/bsd-sources/4.4BSD-Lite/usr/src/usr.bin
 
 login-utils:
     agetty: W. Z. Venema, ported by Peter Orbaek <poe@daimi.aau.dk>.
-            ftp.daimi.aau.dk:/pub/linux/poe/poeigl-1.32.tar.gz
+            ftp.daimi.aau.dk:/pub/linux/poe/poeigl-1.37.tar.gz
     chfn: Salvatore Valente <svalente@athena.mit.edu>
     chsh: Salvatore Valente <svalente@athena.mit.edu>
     last: 5.11 w/year (Berkeley) 6/29/88; Port by Michael Haardt with
           changes by Peter Orbaek.
-          ftp://ftp.daimi.aau.dk/pub/linux/poe/admutil-1.14.tar.gz
+          ftp://ftp.daimi.aau.dk/pub/linux/poe/admutil-1.16.tar.gz
     login: 5.40 (Berkeley) 5/9/89; with ports by Michael Glad and Peter Orbaek
-           ftp.daimi.aau.dk:/pub/linux/poe/poeigl-1.32.tar.gz
-    mesg: Miquel van Smoorenburg (miquels@htsa.aha.nl,
-          miquels@drinkel.nl.mugnet.org).  From his sysvinit.tar.Z package.
+           ftp.daimi.aau.dk:/pub/linux/poe/poeigl-1.37.tar.gz
+    mesg: 8.2 (Berkeley) 1/21/94
+          ftp.cdrom.com:/pub/bsd-sources/4.4BSD-Lite/usr/src/usr.bin
     newgrp: Michael Haardt, with modifications by Peter Orbaek.
-            ftp://ftp.daimi.aau.dk/pub/linux/poe/admutil-1.14.tar.gz
+            ftp://ftp.daimi.aau.dk/pub/linux/poe/admutil-1.16.tar.gz
     passwd: Peter Orbaek, with yp modifications by Alvaro Martinez
             Echevarria (alvaro@enano.etsit.upm.es)
-            ftp://ftp.daimi.aau.dk/pub/linux/poe/admutil-1.14.tar.gz
+            ftp://ftp.daimi.aau.dk/pub/linux/poe/admutil-1.16.tar.gz
     shutdown: Peter Orbaek, with new modifications by Stephen Tweedie, Rik
               Faith, and Dave (gentzel@nova.enet.dec.com).
-              ftp://ftp.daimi.aau.dk/pub/linux/poe/admutil-1.14.tar.gz
+              ftp://ftp.daimi.aau.dk/pub/linux/poe/admutil-1.16.tar.gz
     simpleinit: Peter Orbaek
-                ftp.daimi.aau.dk:/pub/linux/poe/poeigl-1.32.tar.gz
+                ftp.daimi.aau.dk:/pub/linux/poe/poeigl-1.37.tar.gz
     vipw: 5.16 (Berkeley) 3/3/91, with modifications by Mike Grupenhoff
           <kashmir@umiacs.UMD.EDU> 
-    wall: 5.14 (Berkeley) 3/2/91 [From the BSD NET-2 (4.3bsd-reno)
-          distribution at wuarchive.wustl.edu:/mirrors/4.3-reno]
-
-makedev-1.4:
-    MAKEDEV-C: David A. Holland (dholland@husc.harvard.edu)
-               This version MODIFIED by Rik Faith (faith@cs.unc.edu)
-               sunsite.unc.edu:/pub/Linux/system/Admin/MAKEDEV-C-1.4.tar.gz
+    wall: 8.2 (Berkeley) 11/16/93 (With changes so that damaging escape
+          sequences cannot be sent. 
+          ftp.cdrom.com:/pub/bsd-sources/4.4BSD-Lite/usr/src/usr.bin
 
 
 misc-utils:
     cal: 8.4 (Berkeley) 4/2/94, with modifications by Rik Faith and
          Hein@student.tu-clausthal.de (Jochen Hein).
          ftp.cdrom.com:/pub/bsd-sources/4.4BSD-Lite/usr/src/usr.bin
+    chkdupexe: Version 1.2 from "Nicolai Langfeldt" <janl@ifi.uio.no>
     clear: Rik Faith
+    ddate: Druel the Chaotic aka Jeremy Johnson aka mpython@gnu.ai.mit.edu,
+           with modifications by Lee Harvey Oswald Smith, K.S.C. and
+           substantial updates from Rev. Bro. Lee H:. O:. Smith, KYTP
     domainname: Peter Orbaek
-            ftp.daimi.aau.dk:/pub/linux/poe/poeigl-1.32.tar.gz
+            ftp.daimi.aau.dk:/pub/linux/poe/poeigl-1.37.tar.gz
     dsplit: David Arnstein (arnstein@netcom.com)
             gatekeeper.dec.com:/pub/usenet/comp.sources.misc/volume40/dsplit
     getopt (getoptprog): jhunix.hcf.jhu.edu:
            /pub/public_domain_software/NetBSD/usr/src/usr.bin/getopt
     hostid: Mitch DSouza (m.dsouza@mrc-apu.cam.ac.uk)
-            ftp.daimi.aau.dk:/pub/linux/poe/poeigl-1.32.tar.gz
+            ftp.daimi.aau.dk:/pub/linux/poe/poeigl-1.37.tar.gz
     hostname/dnsdomainname: Peter Tobias <tobias@server.et-inf.fho-emden.de>
               This version (1.6) should also be available soon in:
               nic.funet.fi:/pub/OS/Linux/PEOPLE/Linus/net-source/base/NetKit-A*
@@ -262,9 +275,11 @@ misc-utils:
            wuarchive.wustl.edu:/mirrors/4.3-reno
     whereis: 5.5 (Berkeley) 4/18/91
              wuarchive.wustl.edu:/mirrors/4.3-reno
-    write: 4.22 (Berkeley) 6/1/90, with modifications by Mike Grupenhoff
-           (kashmir@umiacs.umd.edu) .
-           wuarchive.wustl.edu:/mirrors/4.3-reno
+    write: 8.1 (Berkeley) 6/6/93, with modifications by Mike Grupenhoff
+           (kashmir@umiacs.umd.edu).  With changes so that damaging escape
+           sequences cannot be sent.
+           ftp.cdrom.com:/pub/bsd-sources/4.4BSD-Lite/usr/src/usr.bin
+
 
 mount:
     mount, umount, swapon
@@ -294,6 +309,9 @@ mount:
     before /proc/filesystems is checked.  Andries.Brouwer@cwi.nl fixed up
     error reporting.
 
+    Updated with patches from Andries.Brouwer@cwi.nl and Dan Quinlan
+    (quinlan@yggdrasil.com).  And more patches from Andries and others.
+
 historic/selection: The complete selection-1.5 package, by Andrew Haylett
     <ajh@gec-mrc.co.uk>, 17th June 1993, is included in the historic tree.
     Kernel patches are no longer necessary for modern kernels, but these
@@ -301,7 +319,6 @@ historic/selection: The complete selection-1.5 package, by Andrew Haylett
     modified for this distribution.  With changes from Rick Sladkey.
 
 sys-utils:
-    MAKEDEV: Nick Holloway <Nick.Holloway@alfie.demon.co.uk>
     arch: Rik Faith <faith@cs.unc.edu>
     chroot: Rick Sladkey <jrs@world.std.com>
     clock: Originally from the timesrc-1.2.tar.Z package, Charles Hedrick,
@@ -311,7 +328,8 @@ sys-utils:
            (hamish@zot.apana.org.au) (V1.2a); Alan Modra
            (alan@spri.levels.unisa.edu.au (V1.3, V1.4).
     ctrlaltdel: Peter Orbaek <poe@daimi.aau.dk>
-                ftp://ftp.daimi.aau.dk/pub/linux/poe/admutil-1.14.tar.gz
+                ftp://ftp.daimi.aau.dk/pub/linux/poe/admutil-1.16.tar.gz
+    cytune: Nick Simicish (njs@scifi.emi.net) and Rik Faith (faith@cs.unc.edu)
     dmesg: Theodore Ts'o (tytso@athena.mit.edu); Rick Sladkey
            (jrs@world.std.com)
     ipcrm: From the ipcdelta.tar.z distribution by krishna
@@ -323,7 +341,7 @@ sys-utils:
     kbdrate: Rik Faith (faith@cs.unc.edu), with patches from
              Andries.Brouwer@cwi.nl and John Bowman
              (bowman@hagar.ph.utexas.edu)
-    lpcntl: Nigel Gamble (nigel@gate.net)
+    ksymoops: 1.7 from Greg McGary <gkm@magilla.cichlid.com>
     rdev: almesber@nessie.cs.id.ethz.ch (Werner Almesberger), with
           modifications from Peter MacDonald, Stephen Tweedie
           (sct@dcs.ed.ac.uk), and Dave (gentzel@nova.enet.dec.com)
@@ -341,7 +359,7 @@ sys-utils:
     sln: Mike Parker and David MacKenzie (from Linux's libc)
     sync: Nick Holloway, with thanks to James Bonfield
     tunelp: Michael K. Johnson (johnsonm@nigel.vnet.net)
-    update_state: Rik Faith (faith@cs.unc.edu)
+
 
 syslogd:
    5.45 (Berkeley) 3/2/91
@@ -373,194 +391,3 @@ text-utils:
     ul: 8.1 (Berkeley) 6/6/93
         ftp.cdrom.com:/pub/bsd-sources/4.4BSD-Lite/usr/src/usr.bin
 
-time:
-    elsie.nci.nih.gov:/pub/classictzcode.tar.gz
-    elsie.nci.nih.gov:/pub/classictzdata.tar.gz
-    (The zoneinfo database was updated Dec 1994.)
-
-%%
-* bin/arch
-* bin/dmesg
-* bin/dnsdomainname
-* bin/domainname
-* bin/hostname
-* bin/kill
-* bin/login
-* bin/more
-* bin/mount
-* bin/setserial
-* bin/sync
-* bin/umount
-* dev/MAKEDEV
-* dev/MAKEDEV-C
-* etc/devinfo
-* etc/makedev.cfg
-* etc/fdprm
-* sbin/agetty
-* sbin/cfdisk
-* sbin/clock
-* sbin/fastboot
-* sbin/fasthalt
-* sbin/fdisk
-* sbin/fsck.minix
-* sbin/halt
-* sbin/kbdrate
-* sbin/mkfs
-* sbin/mkfs.minix
-* sbin/mkswap
-* sbin/reboot
-* sbin/shutdown
-* sbin/simpleinit
-* sbin/sln
-* sbin/swapoff
-* sbin/swapon
-* usr/bin/cal
-* usr/bin/chfn
-* usr/bin/chsh
-* usr/bin/clear
-* usr/bin/col
-* usr/bin/colcrt
-* usr/bin/colrm
-* usr/bin/column
-* usr/bin/dsplit
-* usr/bin/fdformat
-* usr/bin/getopt
-* usr/bin/hexdump
-* usr/bin/hostid
-* usr/bin/ipcrm
-* usr/bin/ipcs
-* usr/bin/last
-* usr/bin/logger
-* usr/bin/look
-* usr/bin/lpcntl
-* usr/bin/mcookie
-* usr/bin/md5sum
-* usr/bin/mesg
-* usr/bin/namei
-* usr/bin/newgrp
-* usr/bin/passwd
-* usr/bin/ramsize
-* usr/bin/rdev
-* usr/bin/readprofile
-* usr/bin/renice
-* usr/bin/reset
-* usr/bin/rev
-* usr/bin/rootflags
-* usr/bin/script
-* usr/bin/setfdprm
-* usr/bin/setsid
-* usr/bin/setterm
-* usr/bin/strings
-* usr/bin/swapdev
-* usr/bin/tsort
-* usr/bin/tunelp
-* usr/bin/ul
-* usr/bin/vidmode
-* usr/bin/wall
-* usr/bin/whereis
-* usr/bin/write
-* usr/info/ipc.info
-* usr/lib/libz.a
-* usr/lib/more.help
-* usr/lib/zoneinfo
-* usr/man/man1/arch.1
-* usr/man/man1/cal.1
-* usr/man/man1/chfn.1
-* usr/man/man1/chsh.1
-* usr/man/man1/clear.1
-* usr/man/man1/col.1
-* usr/man/man1/colcrt.1
-* usr/man/man1/colrm.1
-* usr/man/man1/column.1
-* usr/man/man1/dnsdomainname.1
-* usr/man/man1/domainname.1
-* usr/man/man1/dsplit.1
-* usr/man/man1/getopt.1
-* usr/man/man1/hexdump.1
-* usr/man/man1/hostid.1
-* usr/man/man1/hostname.1
-* usr/man/man1/kill.1
-* usr/man/man1/last.1
-* usr/man/man1/logger.1
-* usr/man/man1/login.1
-* usr/man/man1/look.1
-* usr/man/man1/md5sum.1
-* usr/man/man1/mesg.1
-* usr/man/man1/more.1
-* usr/man/man1/namei.1
-* usr/man/man1/newgrp.1
-* usr/man/man1/passwd.1
-* usr/man/man1/readprofile.1
-* usr/man/man1/reset.1
-* usr/man/man1/rev.1
-* usr/man/man1/script.1
-* usr/man/man1/setterm.1
-* usr/man/man1/strings.1
-* usr/man/man1/tsort.1
-* usr/man/man1/ul.1
-* usr/man/man1/wall.1
-* usr/man/man1/whereis.1
-* usr/man/man1/write.1
-* usr/man/man3/newctime.3
-* usr/man/man3/newtzset.3
-* usr/man/man5/devinfo.5
-* usr/man/man5/fstab.5
-* usr/man/man5/makedev.cfg.5
-* usr/man/man5/nfs.5
-* usr/man/man5/syslog.conf.5
-* usr/man/man5/tzfile.5
-* usr/man/man6/banner.6
-* usr/man/man6/ddate.6
-* usr/man/man8/MAKEDEV-C.8
-* usr/man/man8/MAKEDEV.8
-* usr/man/man8/agetty.8
-* usr/man/man8/cfdisk.8
-* usr/man/man8/chroot.8
-* usr/man/man8/clock.8
-* usr/man/man8/ctrlaltdel.8
-* usr/man/man8/dmesg.8
-* usr/man/man8/fastboot.8
-* usr/man/man8/fasthalt.8
-* usr/man/man8/fdformat.8
-* usr/man/man8/fdisk.8
-* usr/man/man8/frag.8
-* usr/man/man8/fsck.minix.8
-* usr/man/man8/halt.8
-* usr/man/man8/ipcrm.8
-* usr/man/man8/ipcs.8
-* usr/man/man8/kbdrate.8
-* usr/man/man8/lpcntl.8
-* usr/man/man8/mkfs.8
-* usr/man/man8/mkfs.minix.8
-* usr/man/man8/mkswap.8
-* usr/man/man8/mount.8
-* usr/man/man8/ramsize.8
-* usr/man/man8/rdev.8
-* usr/man/man8/reboot.8
-* usr/man/man8/renice.8
-* usr/man/man8/rootflags.8
-* usr/man/man8/setfdprm.8
-* usr/man/man8/setserial.8
-* usr/man/man8/setsid.8
-* usr/man/man8/shutdown.8
-* usr/man/man8/simpleinit.8
-* usr/man/man8/swapdev.8
-* usr/man/man8/swapoff.8
-* usr/man/man8/swapon.8
-* usr/man/man8/sync.8
-* usr/man/man8/syslogd.8
-* usr/man/man8/tunelp.8
-* usr/man/man8/umount.8
-* usr/man/man8/update_state.8
-* usr/man/man8/vidmode.8
-* usr/man/man8/vipw.8
-* usr/man/man8/zdump.8
-* usr/man/man8/zic.8
-* usr/sbin/chroot
-* usr/sbin/ctrlaltdel
-* usr/sbin/frag
-* usr/sbin/syslogd
-* usr/sbin/update_state
-* usr/sbin/vipw
-* usr/sbin/zdump
-* usr/sbin/zic
index 6baf09d593b10043e5a25d26bf64c7a8abbde61d..8783c5b3022cfea6573edfb895fde9259294f429 100644 (file)
@@ -1,14 +1,11 @@
 # Makefile -- Makefile for util-linux Linux utilities
 # Created: Sat Dec 26 20:09:40 1992
-# Revised: Sat Feb  4 19:35:59 1995 by faith@cs.unc.edu
+# Revised: Fri Mar 10 21:20:41 1995 by faith@cs.unc.edu
 # Copyright 1992, 1993, 1994, 1995 Rickard E. Faith (faith@cs.unc.edu)
 #
 
 include ../MCONFIG
 
-%.o: %.c
-       $(CC) -c $(CFLAGS) $< -o $@
-
 all: err.o getopt.o
 err.o: err.c
 getopt.o: getopt.c
index 7dca388e0448c462bf2856fa9df60e5672406444..b37c6793d6e79d6549d0a4654c6eda2923a5c087 100644 (file)
 #undef _PATH_MAILDIR
 
 #ifndef SBINDIR
-#define SBINDIR                        "/etc"
+#define SBINDIR                        "/sbin"
 #endif
 
 #ifndef USRSBINDIR
-#define USRSBINDIR              "/etc"
+#define USRSBINDIR              "/usr/sbin"
 #endif
 
 #ifndef LOGDIR
-#define LOGDIR                  "/etc"
+#define LOGDIR                  "/var/log"
 #endif
 
 #ifndef VARPATH
-#define VARPATH                        "/usr"
+#define VARPATH                        "/var"
 #endif
 
 #define _PATH_BSHELL           "/bin/sh"
@@ -59,7 +59,7 @@
 #define _PATH_TTY              "/dev/tty"
 #define TTYTYPES               "/etc/ttytype"
 #define SECURETTY              "/etc/securetty"
-#define _PATH_UTMP             LOGDIR "/utmp"
+#define _PATH_UTMP             "/var/run/utmp"
 #define _PATH_WTMP             LOGDIR "/wtmp"
 
 #define        _PATH_DEFPATH           "/usr/local/bin:/bin:/usr/bin:."
@@ -81,6 +81,7 @@
 #define _PATH_MTAB             "/etc/mtab"
 #define _PATH_UMOUNT           "/bin/umount"
 #define UMOUNT_ARGS            "umount", "-a"
+#define SWAPOFF_ARGS            "swapoff", "-a"
 
 #define _PATH_PASSWD            "/etc/passwd"
 #define _PATH_PTMP              "/etc/ptmp"
index 854e1ec9d89cb1ca4934e09adde1c0c8edf0b27c..739d12834f3caa310133071cc3a2f5ac5d6e2efe 100644 (file)
@@ -1,6 +1,6 @@
 # Makefile -- Makefile for util-linux Linux utilities
 # Created: Sat Dec 26 20:09:40 1992
-# Revised: Wed Feb 22 16:09:35 1995 by faith@cs.unc.edu
+# Revised: Fri Oct  6 21:02:21 1995 by r.faith@ieee.org
 # Copyright 1992, 1993, 1994, 1995 Rickard E. Faith (faith@cs.unc.edu)
 #
 
@@ -8,15 +8,17 @@ include ../MCONFIG
 
 # Where to put man pages?
 
-MAN8=          cfdisk.8 fdformat.8 fdisk.8 frag.8 fsck.minix.8 \
-               mkfs.8 mkfs.minix.8 mkswap.8 setfdprm.8 
+MAN8=          cfdisk.8 fdformat.8 fsck.minix.8 \
+               mkfs.8 mkfs.minix.8 mkswap.8 setfdprm.8
+
+MAN8.FDISK=    fdisk.8
 
 # Where to put binaries?
 # See the "install" rule for the links. . .
 
-SBIN=          cfdisk fdisk fsck.minix mkfs mkfs.minix mkswap 
+SBIN=          cfdisk fsck.minix mkfs mkfs.minix mkswap
 
-USRSBIN=       frag
+SBIN.FDISK=    fdisk
 
 USRBIN=                fdformat setfdprm
 
@@ -24,29 +26,31 @@ USRBIN=             fdformat setfdprm
 
 ETC=           fdprm
 
-all: $(SBIN) $(USRSBIN) $(USRBIN)
+ifeq "$(HAVE_FDISK)" "no"
+SBIN:=$(SBIN) $(SBIN.FDISK)
+MAN8:=$(MAN8) $(MAN8.FDISK)
+endif
 
-cfdisk: cfdisk.c llseek.o
-       $(CC) $(CFLAGS) $(LDFLAGS) $< llseek.o -o $@ -lcurses -ltermcap -lm
+all: $(SBIN) $(USRBIN) 
 
-%.o: %.c
-       $(CC) -c $(CFLAGS) $< -o $@
+cfdisk: cfdisk.o llseek.o
+       $(CC) $(LDFLAGS) $^ -o $@ -lcurses -ltermcap -lm
 
 # Rules for everything else
 
 fdformat: fdformat.o
-fdisk: fdisk.o llseek.o
-frag: frag.o
+fdisk: fdisk.o fdisklabel.o llseek.o
 fsck.minix: fsck.minix.o
 mkfs: mkfs.o
 mkfs.minix: mkfs.minix.o
 mkswap: mkswap.o
 setfdprm: setfdprm.o
+fdisk.o: fdisk.c fdisk.h
+fdisklabel.o: fdisklabel.c fdisk.h
 
 install: all
-       $(INSTALLDIR) $(SBINDIR) $(USRSBINDIR) $(ETCDIR)
+       $(INSTALLDIR) $(SBINDIR) $(USRBINDIR) $(ETCDIR)
        $(INSTALLBIN) $(SBIN) $(SBINDIR)
-       $(INSTALLBIN) $(USRSBIN) $(USRSBINDIR)
        $(INSTALLBIN) $(USRBIN) $(USRBINDIR)
        $(INSTALLDAT) $(ETC) $(ETCDIR)
        $(INSTALLDIR) $(MAN8DIR)
@@ -54,4 +58,4 @@ install: all
 
 .PHONY:        clean
 clean:
-       -rm -f *.o *~ core $(SBIN) $(USRSBIN) $(USRBIN)
+       -rm -f *.o *~ core $(SBIN) $(USRBIN)
index 9e64508ed5ad600a427683ceed99c4c1369ed977..40f54b4b9fcdb606836767821a9be97946385d6a 100644 (file)
@@ -114,7 +114,7 @@ Dividing up your disk
 
 It is a good idea to plan ahead before you start creating partitions
 on your disk.  If you set aside a partition for some purpose, it is not
-easy to change its size: you must all the data from the partition,
+easy to change its size: you must backup all the data from the partition,
 whether to floppies, to another partition, to another hard disk, or
 somewhere else; then you must edit the table which describes this
 partition, so changing its size; then you must reboot and initialise
@@ -309,8 +309,8 @@ display/entry units are sectors.
 
 The Verify command is useful because
 
-  1. It warns you if anything is wrong.  *Always* give a Verify command
-     before writing any changes to disk.
+  1. It warns you if anything is wrong.  *Always* do a Verify command
+     to check your work before writing any changes to disk.
 
   2. It reports how many unallocated sectors there are on the disk.
 
@@ -369,20 +369,22 @@ unless there are sectors available inside the extended partition.
 
 If space is available, you are prompted for the first cylinder:
 
-     First sector (237-977): _
+     First sector ([237]-977): _
 
 The limits are the lowest and the highest cylinders in which sectors
-are available in the appropriate part of the disk.  Not all numbers in
+are available in the appropriate part of the disk.  The square-bracketed
+number is what you'll get if you simply press enter.  Not all numbers in
 this range are necessarily available: they may fall inside an existing
 partition.  If you select a cylinder which is already in use, you are
 told off and prompted again for the first cylinder.  After selecting the
 first cylinder, you are prompted again:
 
-     Last cylinder or +size or +sizeM or +sizeK (237-836): _
+     Last cylinder or +size or +sizeM or +sizeK (237-[836]): _
 
 The limits are the cylinder you have chosen as the first cylinder,
 and the highest cylinder which contains a legitimate upper boundary for
-the new partition.  In other words, all numbers in the given range are
+the new partition.  The square-bracketed number is what you'll get if
+you simply press enter. In other words, all numbers in the given range are
 legitimate, unlike those in the first range of cylinders.  You may also
 specify the size of a partition in megabytes, kilobytes, or in the
 current units (cylinders or sectors).  A plus sign `+' indicates that
@@ -395,7 +397,7 @@ possible answers to the last cylinder request above are
      Make cylinder 700 the last cylinder in the partition.
 
 +300
-     Make cylinder 537 the last cylinder in the partition.
+     Make cylinder 237 + 300 = 537 the last cylinder in the partition.
 
 +15m
      Make the partition at least 15 megabytes in size.
@@ -404,7 +406,7 @@ possible answers to the last cylinder request above are
      Make the partition at least 12,500 kilobytes in size.
 
 If you specify a size which is too large or an end which is out of
-range, the prompt is simply repeated.
+range, fdisk complains and repeats the prompt.
 
 Adding or deleting partitions has no effect unless you subsequently
 give the Write command.  Please remember to give the Verify command
@@ -544,7 +546,7 @@ Warnings for `fdisk' users
 
 In general, you should not use this `fdisk' program to create
 partitions for other operating systems, only for Linux.  Nor should you
-use `fdisk' commands from other operating systems do create partitions
+use `fdisk' commands from other operating systems to create partitions
 for Linux.
 
 DR-DOS 5.0 and 6.0 are reported to have difficulties with partition
diff --git a/disk-utils/README.fdisk.alpha b/disk-utils/README.fdisk.alpha
new file mode 100644 (file)
index 0000000..da6e873
--- /dev/null
@@ -0,0 +1,16 @@
+
+There are some things which have to be done for the alpha version:
+- LABELSECTOR, LABELOFFSET, BBSIZE & SBSIZE are undefined in fdisklabel.h
+  These values are different for different versions of NetBSD and I don't
+  have the alpha source tree for NetBSD yet (It's not in 1.0 but in current).
+  I guess Linux/Alpha uses the same values.
+- The alpha fdisklabel.c requires a few functions from fdisk.c.
+  ("make test" shows the undefined symbols when fdisk.c is missing)
+  All the other functions/variables shouldn't be declared. I didn't do
+  that because I didn't want to change much in fdisk.c.
+- The disklabel in fdisklabel.c is the NetBSD disklabel which might
+  differ from the Linux/Alpha disklabel in some parts.
+- bselect () should be called from main () immediately. Under Linux/Alpha
+  it's the main menu and not a submenu.
+
+fasten@informatik.uni-bonn.de
diff --git a/disk-utils/README.fdisk.bsd b/disk-utils/README.fdisk.bsd
new file mode 100644 (file)
index 0000000..705df90
--- /dev/null
@@ -0,0 +1,28 @@
+
+All changes in fdisk.c are marked with this comment: /* bf */
+
+I added some explanatory comments to make it easier to see what
+changed and why. You'll probably want to remove them.
+
+There's a function sync_disks() in fdisklabel.c which could be called
+from write_table() in fdisk.c (line 1216) (and be moved to fdisk.c)
+to save a few bytes.
+
+There's a function edit_int() in fdisklabel.c which I added because read_int()
+had no default value. In fdisk v2.0d it has so edit_int could be replaces by
+read_int(). The function which uses edit_int() (bsd_edit_disklabel ()) is a
+bit crufty anyhow:
+- The disklabel contains some values which are probably meaningless for IDE or
+  SCSI drives, I made them editable but I don't know any sensible range of
+  values (bad for read_int()). (interleave, trackskew, cylskew)
+- I made the values secsize/nsectors/ntracks/ncylinders editable for Linux/Alpha
+  but not for Linux/i386 because under Linux/i386 the disklabel is inside a
+  DOS partition so the disklabel was written by an OS which got along with the
+  disk and should have left the correct values there.
+
+I've put the BSD copyright (which applies to fdisklabel.h and
+alpha_bootblock_checksum, bsd_dkcksum, bsd_print_disklabel in fdisklabel.c)
+into a separate man page. This way all Linux versions of BSD programs can refer
+to ths bsd.<n> man page.
+
+fasten@informatik.uni-bonn.de
index cb23149fb07504e3e744511f93455c7589e5f552..010c370dda3e308deb9f11004a9ff3d7240f9eaf 100644 (file)
@@ -11,7 +11,7 @@
 .\" permission notice identical to this one.
 .\"
 .\" " for hilit mode
-.TH CFDISK 8 "25 April 1994" "The BOGUS Linux Release" "Linux Programmer's Manual"
+.TH CFDISK 8 "3 June 1995" "The BOGUS Linux Release" "Linux Programmer's Manual"
 .SH NAME
 cfdisk \- Curses based disk partition table manipulator for Linux
 .SH SYNOPSIS
diff --git a/disk-utils/cfdisk.8.bak b/disk-utils/cfdisk.8.bak
new file mode 100644 (file)
index 0000000..cb23149
--- /dev/null
@@ -0,0 +1,407 @@
+.\" cfdisk.8 -- man page for cfdisk
+.\" Copyright 1994 Kevin E. Martin (martin@cs.unc.edu)
+.\"
+.\" Permission is granted to make and distribute verbatim copies of this
+.\" manual provided the copyright notice and this permission notice are
+.\" preserved on all copies.
+.\"
+.\" Permission is granted to copy and distribute modified versions of this
+.\" manual under the conditions for verbatim copying, provided that the
+.\" entire resulting derived work is distributed under the terms of a
+.\" permission notice identical to this one.
+.\"
+.\" " for hilit mode
+.TH CFDISK 8 "25 April 1994" "The BOGUS Linux Release" "Linux Programmer's Manual"
+.SH NAME
+cfdisk \- Curses based disk partition table manipulator for Linux
+.SH SYNOPSIS
+.BI "cfdisk [ \-avz ] [ \-c " cylinders " ] [ \-h " heads " ]"
+.BI "[ \-s " sectors-per-track " ] [ -P " opt " ] [ " device " ]"
+.SH DESCRIPTION
+.B cfdisk
+is a curses based program for partitioning a hard disk drive.  The
+.I device
+can be any one of the following:
+.sp
+.nf
+.RS
+/dev/hda [default]
+/dev/hdb
+/dev/sda
+/dev/sdb
+/dev/sdc
+/dev/sdd
+.RE
+.fi
+
+.B cfdisk
+first tries to read the geometry of the hard disk.  If it fails, an
+error message is displayed and
+.B cfdisk
+exits.  This should only happen when partitioning a SCSI drive on an
+adapter without a BIOS.  To correct this problem, you can set the
+.IR cylinders ", " heads " and " sectors-per-track
+on the command line.  Next,
+.B cfdisk
+tries to read the current partition table from the disk drive.  If it
+is unable to figure out the partition table, an error is displayed and
+the program will exit.  This might also be caused by incorrect
+geometry information, and can be overridden on the command line.
+Another way around this problem is with the
+.B \-z
+option.  This will ignore the partition table on the disk.
+
+The main display is composed of four sections, from top to bottom: the
+header, the partitions, the command line and a warning line.  The
+header contains the program name and version number followed by the
+disk drive and its geometry.  The partitions section always displays
+the current partition table.  The command line is the place where
+commands and text are entered.  The available commands are usually
+displayed in brackets.  The warning line is usually empty except when
+there is important information to be displayed.  The current partition
+is highlighted with reverse video (or an arrow if the
+.B \-a
+option is given).  All partition specific commands apply to the
+current partition.
+
+The format of the partition table in the partitions section is, from
+left to right: Name, Flags, Partition Type, Filesystem Type and Size.
+The name is the partition device name.  The flags can be
+.IR Boot ,
+which designates a bootable partition or
+.IR NC ,
+which stands for "Not Compatible with DOS or OS/2".  DOS, OS/2 and
+possibly other operating systems require the first sector of the first
+partition on the disk and all logical partitions to begin on the
+second head.  This wastes the second through the last sector of the
+first track of the first head (the first sector is taken by the
+partition table itself).
+.B cfdisk
+allows you to recover these "lost" sectors with the maximize command
+.RB ( m ).
+.I Note:
+.BR fdisk (8)
+and some early versions of DOS create all partitions with the number
+of sectors already maximized.  For more information, see the maximize
+command below.  The partition type can be one of
+.IR Primary " or " Logical .
+For unallocated space on the drive, the partition type can also be
+.IR Pri/Log ,
+or empty (if the space is unusable).  The filesystem type section
+displays the name of the filesystem used on the partition, if known.
+If it is unknown, then
+.I Unknown
+and the hex value of the filesystem type are displayed.  A special
+case occurs when there are sections of the disk drive that cannot be
+used (because all of the primary partitions are used).  When this is
+detected, the filesystem type is displayed as
+.IR Unusable .
+The size field displays the size of the partition in megabytes (by
+default).  It can also display the size in sectors and cylinders (see
+the change units command below).  If an asterisks
+.RB ( * )
+appears after the size, this means that the partition is not aligned
+on cylinder boundaries.
+.SH "DOS 6.x WARNING"
+
+The DOS 6.x FORMAT command looks for some information in the first
+sector of the data area of the partition, and treats this information
+as more reliable than the information in the partition table.  DOS
+FORMAT expects DOS FDISK to clear the first 512 bytes of the data area
+of a partition whenever a size change occurs.  DOS FORMAT will look at
+this extra information even if the /U flag is given -- we consider
+this a bug in DOS FORMAT and DOS FDISK.
+
+The bottom line is that if you use cfdisk or fdisk to change the size of a
+DOS partition table entry, then you must also use
+.B dd
+to zero the first 512 bytes of that partition before using DOS FORMAT to
+format the partition.  For example, if you were using cfdisk to make a DOS
+partition table entry for /dev/hda1, then (after exiting fdisk or cfdisk
+and rebooting Linux so that the partition table information is valid) you
+would use the command "dd if=/dev/zero of=/dev/hda1 bs=512 count=1" to zero
+the first 512 bytes of the partition.
+.B BE EXTREMELY CAREFUL
+if you use the
+.B dd
+command, since a small typo can make all of the data on your disk useless.
+
+.B BE EXTREMELY CAREFUL
+if you use the
+.B dd
+command, since a small typo can make all of the data on your disk useless.
+
+For best resutls, you should always use an OS-specific partition table
+program.  For example, you should make DOS partitions with the DOS FDISK
+program and Linux partitions with the Linux fdisk or Linux cfdisk program.
+
+.SH COMMANDS
+.B cfdisk
+commands can be entered by pressing the desired key (pressing
+.I Enter
+after the command is not necessary).  Here is a list of the available
+commands:
+.TP
+.B b
+Toggle bootable flag of the current partition.  This allows you to
+select which primary partition is bootable on the drive.
+.TP
+.B d
+Delete the current partition.  This will convert the current partition
+into free space and merge it with any free space immediately
+surrounding the current partition.  A partition already marked as free
+space or marked as unusable cannot be deleted.
+.TP
+.B g
+Change the disk geometry (cylinders, heads, or sectors-per-track).
+.B WARNING:
+This option should only be used by people who know what they are
+doing.  A command line option is also available to change the disk
+geometry.  While at the change disk geometry command line, you can
+choose to change cylinders
+.RB ( c ),
+heads
+.RB ( h ),
+and sectors per track
+.RB ( s ).
+The default value will be printed at the prompt which you can accept
+by simply pressing the
+.I Enter
+key, or you can exit without changes by pressing the
+.I ESC
+key.  If you want to change the default value, simply enter the
+desired value and press
+.IR Enter .
+The altered disk parameter values do not take effect until you return
+the main menu (by pressing
+.IR Enter " or " ESC
+at the change disk geometry command line.  If you change the geometry
+such that the disk appears larger, the extra sectors are added at the
+end of the disk as free space.  If the disk appears smaller, the
+partitions that are beyond the new last sector are deleted and the
+last partition on the drive (or the free space at the end of the
+drive) is made to end at the new last sector.
+.TP
+.B h
+Print the help screen.
+.TP
+.B m
+Maximize disk usage of the current partition.  This command will
+recover the the unused space between the partition table and the
+beginning of the partition, but at the cost of making the partition
+incompatible with DOS, OS/2 and possibly other operating systems.
+This option will toggle between maximal disk usage and DOS, OS/2,
+etc. compatible disk usage.  The default when creating a partition is
+to create DOS, OS/2, etc. compatible partitions.
+.TP
+.B n
+Create new partition from free space.  If the partition type is
+.IR Primary " or " Logical ,
+a partition of that type will be created, but if the partition type is
+.IR Pri/Log ,
+you will be prompted for the type you want to create.  Be aware that
+(1) there are only four slots available for primary partitions and (2)
+since there can be only one extended partition, which contains all of
+the logical drives, all of the logical drives must be contiguous (with
+no intervening primary partition).
+.B cfdisk
+next prompts you for the size of the partition you want to create.
+The default size, equal to the entire free space of the current
+partition, is display in megabytes.  You can either press the
+.I Enter
+key to accept the default size or enter a different size at the
+prompt.
+.B cfdisk
+accepts size entries in megabytes
+.RB ( M )
+[default], kilobytes
+.RB ( K ),
+cylinders
+.RB ( C )
+and sectors
+.RB ( S )
+by entering the number immediately followed by one of
+.RB ( M ", " K ", " C " or " S ).
+If the partition fills the free space available, the partition is
+created and you are returned to the main command line.  Otherwise, the
+partition can be created at the beginning or the end of the free
+space, and
+.B cfdisk
+will ask you to choose where to place the partition.  After the
+partition is created,
+.B cfdisk
+automatically adjusts the other partition's partition types if all of
+the primary partitions are used.
+.TP
+.B p
+Print the partition table to the screen or to a file. There are
+several different formats for the partition that you can choose from:
+.sp
+.RS
+.TP
+.B r
+Raw data format (exactly what would be written to disk)
+.TP
+.B s
+Partition table in sector order format
+.TP
+.B t
+Partition table in raw format
+.RE
+
+.RS
+The
+.I raw data format
+will print the sectors that would be written to disk if a
+.BR w rite
+command is selected.  First, the primary partition table is printed,
+followed by the partition tables associated with each logical
+partition.  The data is printed in hex byte by byte with 16 bytes per
+line.
+
+The
+.I partition table in sector order format
+will print the partition table ordered by sector number.  The fields,
+from left to right, are the number of the partition, the partition
+type, the first sector, the last sector, the offset from the first
+sector of the partition to the start of the data, the length of the
+partition, the filesystem type (with the hex value in parenthesis),
+and the flags (with the hex value in parenthesis).  In addition to the
+primary and logical partitions, free and unusable space is printed and
+the extended partition is printed before the first logical partition.
+
+If a partition does not start or end on a cylinder boundary or if the
+partition length is not divisible by the cylinder size, an asterisks
+.RB ( * )
+is printed after the non-aligned sector number/count.  This usually
+indicates that a partition was created by an operating system that
+either does not align partitions to cylinder boundaries or that used
+different disk geometry information.  If you know the disk geometry of
+the other operating system, you could enter the geometry information
+with the change geometry command
+.RB ( g ).
+
+For the first partition on the disk and for all logical partitions, if
+the offset from the beginning of the partition is not equal to the
+number of sectors per track (i.e., the data does not start on the
+first head), a number sign
+.RB ( # )
+is printed after the offset.  For the remaining partitions, if the
+offset is not zero, a number sign will be printed after the offset.
+This corresponds to the
+.I NC
+flag in the partitions section of the main display.
+
+The
+.I partition table in raw format
+will print the partition table ordered by partition number.  It will
+leave out all free and unusable space.  The fields, from left to
+right, are the number of the partition, the flags (in hex), the
+starting head, sector and cylinder, the filesystem ID (in hex), the
+ending head, sector and cylinder, the starting sector in the partition
+and the number of sectors in the partition.  The information in this
+table can be directly translated to the
+.IR "raw data format" .
+
+The partition table entries only have 10 bits available to represent
+the starting and ending cylinders.  Thus, when the absolute starting
+(ending) sector number is on a cylinder greater than 1023, the maximal
+values for starting (ending) head, sector and cylinder are printed.
+This is the method used by OS/2, and thus fixes the problems
+associated with OS/2's fdisk rewriting the partition table when it is
+not in this format.  Since Linux and OS/2 use absolute sector counts,
+the values in the starting and ending head, sector and cylinder are
+not used.
+.RE
+.TP
+.B q
+Quit program.  This will exit the program without writing any data to
+disk.
+.TP
+.B t
+Change the filesystem type.  By default, new partitions are created as
+.I Linux
+partitions, but since
+.B cfdisk
+can create partitions for other operating systems, change partition
+type allows you to enter the hex value of the filesystem you desire.
+A list of the know filesystem types is displayed.  You can type in the
+filesystem type at the prompt or accept the default filesystem type
+.RI [ Linux ].
+.TP
+.B u
+Change units of the partition size display.  It will rotate through
+megabytes, sectors and cylinders.
+.TP
+.B W
+Write partition table to disk (must enter an upper case W).  Since
+this might destroy data on the disk, you must either confirm or deny
+the write by entering `yes' or `no'.  If you enter `yes',
+.B cfdisk
+will write the partition table to disk and the tell the kernel to
+re-read the partition table from the disk.  The re-reading of the
+partition table works is most cases, but I have seen it fail.  Don't
+panic.  It will be correct after you reboot the system.  In all cases,
+I still recommend rebooting the system--just to be safe.
+.TP
+.I Up Arrow
+.TP
+.I Down Arrow
+Move cursor to the previous or next partition.  If there are more
+partitions than can be displayed on a screen, you can display the next
+(previous) set of partitions by moving down (up) at the last (first)
+partition displayed on the screen.
+.TP
+.I CTRL-L
+Redraws the screen.  In case something goes wrong and you cannot read
+anything, you can refresh the screen from the main command line.
+.TP
+.B ?
+Print the help screen.
+
+.RE
+All of the commands can be entered with either upper or lower case
+letters (except for
+.BR W rites).
+When in a sub-menu or at a prompt to enter a filename, you can hit the
+.I ESC
+key to return to the main command line.
+.SH OPTIONS
+.TP
+.B \-a
+Use an arrow cursor instead of reverse video for highlighting the
+current partition.
+.TP
+.B \-v
+Print the version number and copyright.
+.TP
+.B \-z
+Start with zeroed partition table.  This option is useful when you
+want to repartition your entire disk.
+.I Note:
+this option does not zero the partition table on the disk; rather, it
+simply starts the program without reading the existing partition
+table.
+.TP
+.BI \-c " cylinders"
+.TP
+.BI \-h " heads"
+.TP
+.BI \-s " sectors-per-track"
+Override the number of cylinders, heads and sectors per track read
+from the BIOS.  If your BIOS or adapter does not supply this
+information or if it supplies incorrect information, use these options
+to set the disk geometry values.
+.TP
+.BI \-P " opt"
+Prints the partition table in specified formats.
+.I opt
+can be one or more of "r", "s" or "t".  See the
+.BR p rint
+command (above) for more information on the print formats.
+.SH "SEE ALSO"
+fdisk(8)
+.SH BUGS
+The current version does not support multiple disks (future addition).
+.SH AUTHOR
+Kevin E. Martin (martin@cs.unc.edu)
index 6c42f9c06a1afbaa47b2499a060b4bb447c24dd4..beb46e508d0f9d77e8851b3184022c9ca5d7378f 100644 (file)
@@ -43,6 +43,7 @@
 #include <curses.h>
 #include <signal.h>
 #include <math.h>
+#include <string.h>
 #include <sys/ioctl.h>
 #include <linux/genhd.h>
 #include <linux/hdreg.h>
@@ -59,7 +60,7 @@ extern ext2_loff_t ext2_llseek(unsigned int fd,
                               unsigned int origin);
 
 
-#define VERSION "0.8a BETA (>2GB)"
+#define VERSION "0.8d BETA (>2GB)"
 
 #define DEFAULT_DEVICE "/dev/hda"
 #define ALTERNATE_DEVICE "/dev/sda"
@@ -236,7 +237,7 @@ char *partition_type[NUM_PART_TYPES] = {
 
 /* The rest of these are taken from A. V. Le Blanc's (LeBlanc@mcc.ac.uk)
  * fdisk program.  I do not know where they came from, but I include
- * them for completeness.
+ * them for completeness.  (With additions.)
  */
 
     [0x02]        = "XENIX root",
@@ -247,7 +248,8 @@ char *partition_type[NUM_PART_TYPES] = {
     [0x51]        = "Novell?",
     [0x52]        = "Microport",
     [0x63]        = "GNU HURD",
-    [0x64]        = "Novell",
+    [0x64]        = "Novell Netware 286",
+    [0x65]        = "Novell Netware 386",
     [0x75]        = "PC/IX",
     [0x80]        = "Old MINIX",
     [0x93]        = "Amoeba",
diff --git a/disk-utils/cfdisk.c.bak b/disk-utils/cfdisk.c.bak
new file mode 100644 (file)
index 0000000..3b9f22f
--- /dev/null
@@ -0,0 +1,2066 @@
+/****************************************************************************
+ *
+ *     CFDISK
+ *
+ * cfdisk is a curses based disk drive partitioning program that can
+ * create partitions for a wide variety of operating systems including
+ * Linux, MS-DOS and OS/2.
+ *
+ * cfdisk was inspired by the fdisk program, by A. V. Le Blanc
+ * (LeBlanc@mcc.ac.uk).
+ *
+ *     Copyright (C) 1994 Kevin E. Martin (martin@cs.unc.edu)
+ *
+ * cfdisk is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * cfdisk is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with cfdisk; if not, write to the Free Software Foundation,
+ * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Created:    Fri Jan 28 22:46:58 1994, martin@cs.unc.edu
+ *
+ ****************************************************************************/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <unistd.h>
+#include <ctype.h>
+#include <errno.h>
+#include <getopt.h>
+#include <fcntl.h>
+#include <curses.h>
+#include <signal.h>
+#include <math.h>
+#include <sys/ioctl.h>
+#include <linux/genhd.h>
+#include <linux/hdreg.h>
+#include <linux/fs.h>          /* for BLKRRPART */
+
+typedef long ext2_loff_t;
+extern ext2_loff_t ext2_llseek(unsigned int fd,
+                              ext2_loff_t offset,
+                              unsigned int origin);
+
+#define VERSION "0.8 BETA (>2GB)"
+
+#define DEFAULT_DEVICE "/dev/hda"
+#define ALTERNATE_DEVICE "/dev/sda"
+
+#define LINE_LENGTH 80
+#define MAXIMUM_PARTS 60
+
+#define SECTOR_SIZE 512
+
+#define MAX_CYLINDERS 65535
+#define MAX_HEADS 255
+#define MAX_SECTORS 63
+
+#define ACTIVE_FLAG 0x80
+#define PART_TABLE_FLAG 0xAA55
+
+#define UNUSABLE -1
+#define FREE_SPACE 0x00
+#define EXTENDED 0x05
+#define LINUX_MINIX 0x81
+#define LINUX_SWAP 0x82
+#define LINUX 0x83
+
+#define ADD_EXISTS "This partition is already in use"
+#define ADD_UNUSABLE "This partition is unusable"
+#define DEL_EMPTY "Cannot delete an empty partition"
+#define ID_EMPTY "Cannot change FS Type to empty"
+#define ID_EXT "Cannot change FS Type to extended"
+#define NEED_EXT "No room to create the extended partition"
+#define NO_FLAGS "Cannot make this partition bootable"
+#define NO_MORE_PARTS "No more partitions"
+#define PRINT_OPEN_ERR "Cannot open file '%s'"
+#define TWO_EXTENDEDS "Cannot create logical drive here -- would create two extended partitions"
+#define TYPE_EMPTY "Cannot change the type of an empty partition"
+#define BAD_COMMAND "Illegal command"
+#define MAX_UNMAXABLE "Cannot maximize this partition"
+#define BAD_OPEN "Cannot open disk drive"
+#define BAD_SEEK "Cannot seek on disk drive"
+#define BAD_READ "Cannot read disk drive"
+#define BAD_WRITE "Cannot write disk drive"
+#define BAD_GEOMETRY "Cannot read disk drive geometry"
+#define BAD_PRIMARY "Bad primary partition"
+#define BAD_LOGICAL "Bad logical partition"
+#define BAD_CYLINDERS "Illegal cylinders value"
+#define BAD_HEADS "Illegal heads value"
+#define BAD_SECTORS "Illegal sectors value"
+#define WRITE_WARN "Warning!!  This may destroy data on your disk!"
+#define YES_NO "Please enter `yes' or `no'"
+#define WRITING_PART "Writing partition table to disk..."
+#define YES_WRITE "Wrote partition table to disk"
+#define NO_WRITE "Did not write partition table to disk"
+#define RRPART_FAILED "Wrote partition table, but re-read table failed.  Reboot to update table."
+
+#define PRI_OR_LOG -1
+#define PRIMARY -2
+#define LOGICAL -3
+
+#define COL_ID_WIDTH 20
+
+#define CR '\015'
+#define ESC '\033'
+#define DEL '\177'
+#define BELL '\007'
+/* '\014' == ^L */
+#define REDRAWKEY '\014'
+
+/* Display units */
+#define MEGABYTES 1
+#define SECTORS 2
+#define CYLINDERS 3
+
+#define GS_DEFAULT -1
+#define GS_ESCAPE -2
+
+#define PRINT_RAW_TABLE 1
+#define PRINT_SECTOR_TABLE 2
+#define PRINT_PARTITION_TABLE 4
+
+#define IS_PRIMARY(p) ((p) >= 0 && (p) < 4)
+#define IS_LOGICAL(p) ((p) > 3)
+
+#define round_int(d) ((double)((int)(d+0.5)))
+#define ceiling(d) ((double)(((d) != (int)(d)) ? (int)(d+1.0) : (int)(d)))
+
+#define set_hsc(h,s,c,sector) \
+{ \
+      s = sector % sectors + 1;        \
+      sector /= sectors;       \
+      h = sector % heads;      \
+      sector /= heads;         \
+      c = sector & 0xFF;       \
+      s |= (sector >> 2) & 0xC0;\
+}
+
+#define ALIGNMENT 2
+typedef union {
+    struct {
+       unsigned char align[ALIGNMENT];
+       unsigned char b[SECTOR_SIZE];
+    } c;
+    struct {
+       unsigned char align[ALIGNMENT];
+       unsigned char buffer[0x1BE];
+       struct partition part[4];
+       unsigned short flag;
+    } p;
+} partition_table;
+
+typedef struct {
+    int first_sector;  /* first sector in partition */
+    int last_sector;   /* last sector in partition */
+    int offset;                /* offset from first sector to start of data */
+    int flags;         /* active == 0x80 */
+    int id;            /* filesystem type */
+    int num;           /* number of partition -- primary vs. logical */
+} partition_info;
+
+char *disk_device = DEFAULT_DEVICE;
+int fd;
+int heads = 0;
+int sectors = 0;
+int cylinders = 0;
+int changed = FALSE;
+int opened = FALSE;
+
+partition_info p_info[MAXIMUM_PARTS];
+partition_info ext_info;
+int num_parts = 0;
+
+int logical = 0;
+int logical_sectors[MAXIMUM_PARTS];
+
+__sighandler_t old_SIGINT, old_SIGTERM;
+
+int arrow_cursor = FALSE;
+int display_units = MEGABYTES;
+int zero_table = FALSE;
+int print_only = 0;
+
+/* Curses screen information */
+int cur_part = 0;
+int warning_last_time = FALSE;
+int defined = FALSE;
+int COLUMNS = 80;
+int NUM_ON_SCREEN = 1;
+
+/* Y coordinates */
+int HEADER_START = 0;
+int DISK_TABLE_START = 5;
+int WARNING_START = 23;
+int COMMAND_LINE_Y = 21;
+
+/* X coordinates */
+int NAME_START = 4;
+int FLAGS_START = 16;
+int PTYPE_START = 30;
+int FSTYPE_START = 45;
+int SIZE_START = 70;
+int COMMAND_LINE_X = 5;
+
+#define NUM_PART_TYPES 256
+char *partition_type[NUM_PART_TYPES] = {
+    [LINUX_MINIX] = "Linux/MINIX",
+    [LINUX_SWAP]  = "Linux Swap",
+    [LINUX]       = "Linux",
+    [FREE_SPACE]  = "Free Space",
+    [EXTENDED]    = "Extended",
+    [0x01]        = "DOS 12-bit FAT",
+    [0x04]        = "DOS 16-bit < 32Mb",
+    [0x06]        = "DOS 16-bit >=32Mb",
+    [0x07]        = "OS/2 HPFS",
+    [0x0A]        = "OS/2 Boot Manager",
+    [0xA5]        = "BSD/386",
+
+/* The rest of these are taken from A. V. Le Blanc's (LeBlanc@mcc.ac.uk)
+ * fdisk program.  I do not know where they came from, but I include
+ * them for completeness.
+ */
+
+    [0x02]        = "XENIX root",
+    [0x03]        = "XENIX usr",
+    [0x08]        = "AIX",
+    [0x09]        = "AIX bootable",
+    [0x40]        = "Venix 80286",
+    [0x51]        = "Novell?",
+    [0x52]        = "Microport",
+    [0x63]        = "GNU HURD",
+    [0x64]        = "Novell",
+    [0x75]        = "PC/IX",
+    [0x80]        = "Old MINIX",
+    [0x93]        = "Amoeba",
+    [0x94]        = "Amoeba BBT",
+    [0xB7]        = "BSDI fs",
+    [0xB8]        = "BSDI swap",
+    [0xC7]        = "Syrinx",
+    [0xDB]        = "CP/M",
+    [0xE1]        = "DOS access",
+    [0xE3]        = "DOS R/O",
+    [0xF2]        = "DOS secondary",
+    [0xFF]        = "BBT"
+};
+
+void fdexit(int ret)
+{
+    if (opened)
+       close(fd);
+
+    if (changed) {
+       fprintf(stderr, "Disk has been changed.\n");
+       fprintf(stderr, "Reboot the system to ensure the partition "
+                       "table is correctly updated.\n");
+       
+       fprintf( stderr, "\nWARNING: If you have created or modified any\n"
+                        "DOS 6.x partitions, please see the cfdisk manual\n"
+                        "page for additional information.\n" );
+    }
+
+
+    exit(ret);
+}
+
+int get_string(char *str, int len, char *def)
+{
+    char c;
+    int i = 0;
+    int x, y;
+    int use_def = FALSE;
+
+    getyx(stdscr, y, x);
+    clrtoeol();
+
+    str[i] = 0;
+
+    if (def != NULL) {
+       mvaddstr(y, x, def);
+       move(y, x);
+       use_def = TRUE;
+    }
+
+    refresh();
+    while ((c = getch()) != '\n' && c != CR) {
+       switch (c) {
+       case ESC:
+           move(y, x);
+           clrtoeol();
+           refresh();
+           return GS_ESCAPE;
+       case DEL:
+       case '\b':
+           if (i > 0) {
+               str[--i] = 0;
+               mvaddch(y, x+i, ' ');
+               move(y, x+i);
+           } else if (use_def) {
+               clrtoeol();
+               use_def = FALSE;
+           } else
+               putchar(BELL);
+           break;
+       default:
+           if (i < len && isprint(c)) {
+               mvaddch(y, x+i, c);
+               if (use_def) {
+                   clrtoeol();
+                   use_def = FALSE;
+               }
+               str[i++] = c;
+               str[i] = 0;
+           } else
+               putchar(BELL);
+       }
+       refresh();
+    }
+
+    if (use_def)
+       return GS_DEFAULT;
+    else
+       return i;
+}
+
+void clear_warning(void)
+{
+    int i;
+
+    if (!warning_last_time)
+       return;
+
+    move(WARNING_START,0);
+    for (i = 0; i < COLS; i++)
+       addch(' ');
+
+    warning_last_time = FALSE;
+}
+
+void print_warning(char *s)
+{
+    mvaddstr(WARNING_START, (COLS-strlen(s))/2, s);
+    putchar(BELL); /* CTRL-G */
+
+    warning_last_time = TRUE;
+}
+
+void fatal(char *s)
+{
+    char str[LINE_LENGTH];
+
+    sprintf(str, "FATAL ERROR: %s", s);
+    mvaddstr(WARNING_START, (COLS-strlen(str))/2, str);
+    sprintf(str, "Press any key to exit fdisk");
+    mvaddstr(WARNING_START+1, (COLS-strlen(str))/2, str);
+    putchar(BELL); /* CTRL-G */
+
+    refresh();
+
+    (void)getch();
+
+    signal(SIGINT, old_SIGINT);
+    signal(SIGTERM, old_SIGTERM);
+    mvcur(0, COLS-1, LINES-1, 0);
+    nl();
+    endwin();
+    fdexit(1);
+}
+
+void read_sector(char *buffer, int sect_num)
+{
+    if (ext2_llseek(fd, sect_num*SECTOR_SIZE, SEEK_SET) < 0)
+       fatal(BAD_SEEK);
+    if (read(fd, buffer, SECTOR_SIZE) != SECTOR_SIZE)
+       fatal(BAD_READ);
+}
+
+void write_sector(char *buffer, int sect_num)
+{
+    if (ext2_llseek(fd, sect_num*SECTOR_SIZE, SEEK_SET) < 0)
+       fatal(BAD_SEEK);
+    if (write(fd, buffer, SECTOR_SIZE) != SECTOR_SIZE)
+       fatal(BAD_WRITE);
+}
+
+void check_part_info(void)
+{
+    int i, pri = 0, log = 0;
+
+    for (i = 0; i < num_parts; i++)
+       if (p_info[i].id > 0 && IS_PRIMARY(p_info[i].num))
+           pri++;
+       else if (p_info[i].id > 0 && IS_LOGICAL(p_info[i].num))
+           log++;
+    if (ext_info.id == EXTENDED)
+       if (log > 0)
+           pri++;
+       else {
+           ext_info.first_sector = 0;
+           ext_info.last_sector = 0;
+           ext_info.offset = 0;
+           ext_info.flags = 0;
+           ext_info.id = FREE_SPACE;
+           ext_info.num = PRIMARY;
+       }
+
+    if (pri >= 4)
+       for (i = 0; i < num_parts; i++)
+           if (p_info[i].id == FREE_SPACE || p_info[i].id == UNUSABLE)
+               if (ext_info.id == EXTENDED)
+                   if (p_info[i].first_sector >= ext_info.first_sector &&
+                       p_info[i].last_sector <= ext_info.last_sector) {
+                       p_info[i].id = FREE_SPACE;
+                       p_info[i].num = LOGICAL;
+                   } else if (i > 0 &&
+                              p_info[i-1].first_sector >=
+                              ext_info.first_sector &&
+                              p_info[i-1].last_sector <=
+                              ext_info.last_sector) {
+                       p_info[i].id = FREE_SPACE;
+                       p_info[i].num = LOGICAL;
+                   } else if (i < num_parts-1 &&
+                              p_info[i+1].first_sector >=
+                              ext_info.first_sector &&
+                              p_info[i+1].last_sector <=
+                              ext_info.last_sector) {
+                       p_info[i].id = FREE_SPACE;
+                       p_info[i].num = LOGICAL;
+                   } else
+                       p_info[i].id = UNUSABLE;
+               else /* if (ext_info.id != EXTENDED) */
+                   p_info[i].id = UNUSABLE;
+           else /* if (p_info[i].id > 0) */
+               while (0); /* Leave these alone */
+    else /* if (pri < 4) */
+       for (i = 0; i < num_parts; i++) {
+           if (p_info[i].id == UNUSABLE)
+               p_info[i].id = FREE_SPACE;
+           if (p_info[i].id == FREE_SPACE)
+               if (ext_info.id == EXTENDED)
+                   if (p_info[i].first_sector >= ext_info.first_sector &&
+                       p_info[i].last_sector <= ext_info.last_sector)
+                       p_info[i].num = LOGICAL;
+                   else if (i > 0 &&
+                            p_info[i-1].first_sector >=
+                            ext_info.first_sector &&
+                            p_info[i-1].last_sector <=
+                            ext_info.last_sector)
+                       p_info[i].num = PRI_OR_LOG;
+                   else if (i < num_parts-1 &&
+                            p_info[i+1].first_sector >=
+                            ext_info.first_sector &&
+                            p_info[i+1].last_sector <=
+                            ext_info.last_sector)
+                       p_info[i].num = PRI_OR_LOG;
+                   else
+                       p_info[i].num = PRIMARY;
+               else /* if (ext_info.id != EXTENDED) */
+                   p_info[i].num = PRI_OR_LOG;
+           else /* if (p_info[i].id > 0) */
+               while (0); /* Leave these alone */
+       }
+}
+
+void remove_part(int i)
+{
+    int p;
+
+    for (p = i; p < num_parts; p++)
+       p_info[p] = p_info[p+1];
+
+    num_parts--;
+}
+
+void insert_part(int i, int num, int id, int flags, int first, int last,
+                int offset)
+{
+    int p;
+
+    for (p = num_parts; p > i; p--)
+        p_info[p] = p_info[p-1];
+
+    p_info[i].first_sector = first;
+    p_info[i].last_sector = last;
+    p_info[i].offset = offset;
+    p_info[i].flags = flags;
+    p_info[i].id = id;
+    p_info[i].num = num;
+
+    num_parts++;
+}
+
+void del_part(int i)
+{
+    int num = p_info[i].num;
+
+    if (i > 0 && (p_info[i-1].id == FREE_SPACE ||
+                 p_info[i-1].id == UNUSABLE)) {
+       /* Merge with previous partition */
+       p_info[i-1].last_sector = p_info[i].last_sector;
+       remove_part(i--);
+    }
+
+    if (i < num_parts - 1 && (p_info[i+1].id == FREE_SPACE ||
+                             p_info[i+1].id == UNUSABLE)) {
+       /* Merge with next partition */
+       p_info[i+1].first_sector = p_info[i].first_sector;
+       remove_part(i);
+    }
+
+    if (i > 0)
+       p_info[i].first_sector = p_info[i-1].last_sector + 1;
+    else
+       p_info[i].first_sector = 0;
+
+    if (i < num_parts - 1)
+       p_info[i].last_sector = p_info[i+1].first_sector - 1;
+    else
+       p_info[i].last_sector = sectors*heads*cylinders - 1;
+
+    p_info[i].offset = 0;
+    p_info[i].flags = 0;
+    p_info[i].id = FREE_SPACE;
+    p_info[i].num = PRI_OR_LOG;
+
+    if (IS_LOGICAL(num)) {
+       /* We have a logical partition --> shrink the extended partition
+        * if (1) this is the first logical drive, or (2) this is the
+        * last logical drive; and if there are any other logical drives
+        * then renumber the ones after "num".
+        */
+       if (i == 0 || (i > 0 && IS_PRIMARY(p_info[i-1].num)))
+           ext_info.first_sector = p_info[i].last_sector + 1;
+       if (i == num_parts-1 ||
+           (i < num_parts-1 && IS_PRIMARY(p_info[i+1].num)))
+           ext_info.last_sector = p_info[i].first_sector - 1;
+       for (i = 0; i < num_parts; i++)
+           if (p_info[i].num > num)
+               p_info[i].num--;
+    }
+
+    /* Clean up the rest of the partitions */
+    check_part_info();
+}
+
+int add_part(int num, int id, int flags, int first, int last, int offset)
+{
+    int i, pri = 0, log = 0;
+
+    if (num_parts == MAXIMUM_PARTS ||
+       first < 0 ||
+       first >= cylinders*heads*sectors ||
+       last < 0 ||
+       last >= cylinders*heads*sectors)
+       return -1;
+
+    for (i = 0; i < num_parts; i++)
+       if (p_info[i].id > 0 && IS_PRIMARY(p_info[i].num))
+           pri++;
+       else if (p_info[i].id > 0 && IS_LOGICAL(p_info[i].num))
+           log++;
+    if (ext_info.id == EXTENDED && log > 0)
+       pri++;
+
+    if (IS_PRIMARY(num))
+       if (pri >= 4)
+           return -1;
+       else
+           pri++;
+
+    for (i = 0; p_info[i].last_sector < first; i++);
+
+    if (p_info[i].id != FREE_SPACE || last > p_info[i].last_sector)
+       return -1;
+
+    if (id == EXTENDED)
+       if (ext_info.id != FREE_SPACE)
+           return -1;
+       else if (IS_PRIMARY(num)) {
+           ext_info.first_sector = first;
+           ext_info.last_sector = last;
+           ext_info.offset = offset;
+           ext_info.flags = flags;
+           ext_info.id = EXTENDED;
+           ext_info.num = num;
+
+           return 0;
+       } else
+           return -1;
+
+    if (IS_LOGICAL(num)) {
+       if (ext_info.id != EXTENDED) {
+           print_warning("!!!! Internal error creating logical "
+                         "drive with no extended partition !!!!");
+       } else {
+           /* We might have a logical partition outside of the extended
+            * partition's range --> we have to extend the extended
+            * partition's range to encompass this new partition, but we
+            * must make sure that there are no primary partitions between
+            * it and the closest logical drive in extended partition.
+            */
+           if (first < ext_info.first_sector) {
+               if (i < num_parts-1 && IS_PRIMARY(p_info[i+1].num)) {
+                   print_warning(TWO_EXTENDEDS);
+                   return -1;
+               } else {
+                   if (first == 0) {
+                       ext_info.first_sector = 0;
+                       ext_info.offset = first = offset;
+                   } else
+                       ext_info.first_sector = first;
+               }
+           } else if (last > ext_info.last_sector) {
+               if (i > 0 && IS_PRIMARY(p_info[i-1].num)) {
+                   print_warning(TWO_EXTENDEDS);
+                   return -1;
+               } else
+                   ext_info.last_sector = last;
+           }
+       }
+    }
+
+    if (first != p_info[i].first_sector &&
+       !(IS_LOGICAL(num) && first == offset)) {
+       insert_part(i, PRI_OR_LOG, FREE_SPACE, 0,
+                   p_info[i].first_sector, first-1, 0);
+       i++;
+    }
+
+    if (last != p_info[i].last_sector)
+       insert_part(i+1, PRI_OR_LOG, FREE_SPACE, 0,
+                   last+1, p_info[i].last_sector, 0);
+
+    p_info[i].first_sector = first;
+    p_info[i].last_sector = last;
+    p_info[i].offset = offset;
+    p_info[i].flags = flags;
+    p_info[i].id = id;
+    p_info[i].num = num;
+
+    check_part_info();
+
+    return 0;
+}
+
+int find_primary(void)
+{
+    int num = 0, cur = 0;
+
+    while (cur < num_parts && IS_PRIMARY(num))
+       if ((p_info[cur].id > 0 && p_info[cur].num == num) ||
+           (ext_info.id == EXTENDED && ext_info.num == num)) {
+           num++;
+           cur = 0;
+       } else
+           cur++;
+
+    if (!IS_PRIMARY(num))
+       return -1;
+    else
+       return num;
+}
+
+int find_logical(int i)
+{
+    int num = -1;
+    int j;
+
+    for (j = i; j < num_parts && num == -1; j++)
+       if (p_info[j].id > 0 && IS_LOGICAL(p_info[j].num))
+           num = p_info[j].num;
+
+    if (num == -1) {
+       num = 4;
+       for (j = 0; j < num_parts; j++)
+           if (p_info[j].id > 0 && p_info[j].num == num)
+               num++;
+    }
+
+    return num;
+}
+
+void inc_logical(int i)
+{
+    int j;
+
+    for (j = i; j < num_parts; j++)
+       if (p_info[j].id > 0 && IS_LOGICAL(p_info[j].num))
+           p_info[j].num++;
+}
+
+void new_part(int i)
+{
+    char response[LINE_LENGTH], def[LINE_LENGTH];
+    char c;
+    int first = p_info[i].first_sector;
+    int last = p_info[i].last_sector;
+    int offset = 0;
+    int flags = 0;
+    int id = LINUX;
+    int num = -1;
+    int num_sects = last - first + 1;
+    int len, ext, j;
+
+    if (p_info[i].num == PRI_OR_LOG) {
+       mvaddstr(COMMAND_LINE_Y, COMMAND_LINE_X, "Primary or logical [pl]: ");
+       clrtoeol();
+       refresh();
+       while (toupper(c = getch()) != 'P' && toupper(c) != 'L' && c != ESC);
+       if (toupper(c) == 'P')
+           num = find_primary();
+       else if (toupper(c) == 'L')
+           num = find_logical(i);
+       else
+           return;
+    } else if (p_info[i].num == PRIMARY)
+       num = find_primary();
+    else if (p_info[i].num == LOGICAL)
+       num = find_logical(i);
+    else
+       print_warning("!!! Internal error !!!");
+
+    sprintf(def, "%.2f", ceiling(num_sects/20.48)/100);
+    mvaddstr(COMMAND_LINE_Y, COMMAND_LINE_X, "Size (in MB): ");
+    if ((len = get_string(response, LINE_LENGTH, def)) <= 0 &&
+       len != GS_DEFAULT)
+       return;
+    else if (len > 0) {
+#define num_cyls(bytes) (round_int(bytes/SECTOR_SIZE/(sectors*heads)))
+       for (j = 0;
+            j < len-1 && (isdigit(response[j]) || response[j] == '.');
+            j++);
+       if (toupper(response[j]) == 'K') {
+           num_sects = num_cyls(atof(response)*1024)*sectors*heads;
+       } else if (toupper(response[j]) == 'M') {
+           num_sects = num_cyls(atof(response)*1024*1024)*sectors*heads;
+       } else if (toupper(response[j]) == 'C') {
+           num_sects = round_int(atof(response))*sectors*heads;
+       } else if (toupper(response[j]) == 'S') {
+           num_sects = round_int(atof(response));
+       } else {
+           num_sects = num_cyls(atof(response)*1024*1024)*sectors*heads;
+       }
+    }
+
+    if (num_sects <= 0 ||
+       num_sects > p_info[i].last_sector - p_info[i].first_sector + 1)
+       return;
+
+    if (num_sects < p_info[i].last_sector - p_info[i].first_sector + 1) {
+       /* Determine where inside free space to put partition.
+        */
+       mvaddstr(COMMAND_LINE_Y, COMMAND_LINE_X,
+                "Add partition at beginning or end of free space [be]: ");
+       clrtoeol();
+       refresh();
+       while (toupper(c = getch()) != 'B' && toupper(c) != 'E' && c != ESC);
+       if (toupper(c) == 'B')
+           last = first + num_sects - 1;
+       else if (toupper(c) == 'E')
+           first = last - num_sects + 1;
+       else
+           return;
+    }
+
+    if (IS_LOGICAL(num) && ext_info.id != EXTENDED) {
+       /* We want to add a logical partition, but need to create an
+        * extended partition first.
+        */
+       if ((ext = find_primary()) < 0) {
+           print_warning(NEED_EXT);
+           return;
+       }
+       (void)add_part(ext, EXTENDED, 0, first, last,
+                      (first == 0 ? sectors : 0));
+    }
+
+    if (IS_LOGICAL(num))
+       inc_logical(i);
+
+    /* Now we have a complete partition to ourselves */
+    if (first == 0 || IS_LOGICAL(num))
+       offset = sectors;
+
+    (void)add_part(num, id, flags, first, last, offset);
+}
+
+void clear_p_info(void)
+{
+    num_parts = 1;
+    p_info[0].first_sector = 0;
+    p_info[0].last_sector = sectors*heads*cylinders - 1;
+    p_info[0].offset = 0;
+    p_info[0].flags = 0;
+    p_info[0].id = FREE_SPACE;
+    p_info[0].num = PRI_OR_LOG;
+
+    ext_info.first_sector = 0;
+    ext_info.last_sector = 0;
+    ext_info.offset = 0;
+    ext_info.flags = 0;
+    ext_info.id = FREE_SPACE;
+    ext_info.num = PRIMARY;
+}
+
+void fill_p_info(void)
+{
+    int p, i;
+    struct hd_geometry geometry;
+    partition_table buffer;
+    partition_info tmp_ext = { 0, 0, 0, 0, FREE_SPACE, PRIMARY };
+
+    if ((fd = open(disk_device, O_RDWR)) < 0)
+       fatal(BAD_OPEN);
+    read_sector(buffer.c.b, 0);
+
+    if (!ioctl(fd, HDIO_GETGEO, &geometry)) {
+       if (!heads)
+           heads = geometry.heads;
+       if (!sectors)
+           sectors = geometry.sectors;
+       if (!cylinders)
+           cylinders = geometry.cylinders;
+    }
+
+    if (!heads || !sectors || !cylinders)
+       fatal(BAD_GEOMETRY);
+
+    clear_p_info();
+
+    if (!zero_table) {
+       for (i = 0; i < 4; i++) {
+           if (buffer.p.part[i].sys_ind > 0 &&
+               add_part(i,
+                        buffer.p.part[i].sys_ind,
+                        buffer.p.part[i].boot_ind,
+                        ((buffer.p.part[i].start_sect <= sectors) ?
+                         0 : buffer.p.part[i].start_sect),
+                        buffer.p.part[i].start_sect +
+                        buffer.p.part[i].nr_sects - 1,
+                        ((buffer.p.part[i].start_sect <= sectors) ?
+                         buffer.p.part[i].start_sect : 0))) {
+               fatal(BAD_PRIMARY);
+           }
+           if (buffer.p.part[i].sys_ind == EXTENDED)
+               tmp_ext = ext_info;
+       }
+
+       if (tmp_ext.id == EXTENDED) {
+           ext_info = tmp_ext;
+           logical_sectors[logical] = ext_info.first_sector;
+           read_sector(buffer.c.b, logical_sectors[logical++]);
+           i = 4;
+           do {
+               for (p = 0;
+                    p < 4 && (!buffer.p.part[p].sys_ind ||
+                              buffer.p.part[p].sys_ind == 5);
+                    p++);
+               if (p > 3)
+                   fatal(BAD_LOGICAL);
+
+               if (add_part(i++,
+                            buffer.p.part[p].sys_ind,
+                            buffer.p.part[p].boot_ind,
+                            logical_sectors[logical-1],
+                            logical_sectors[logical-1] +
+                            buffer.p.part[p].start_sect +
+                            buffer.p.part[p].nr_sects - 1,
+                            buffer.p.part[p].start_sect)) {
+                   fatal(BAD_LOGICAL);
+               }
+
+               for (p = 0;
+                    p < 4 && buffer.p.part[p].sys_ind != 5;
+                    p++);
+               if (p < 4) {
+                   logical_sectors[logical] =
+                       ext_info.first_sector + buffer.p.part[p].start_sect;
+                   read_sector(buffer.c.b, logical_sectors[logical++]);
+               }
+           } while (p < 4 && logical < MAXIMUM_PARTS-4);
+       }
+    }
+}
+
+void fill_part_table(struct partition *p, partition_info *pi)
+{
+    int sects;
+
+    p->boot_ind = pi->flags;
+    p->sys_ind = pi->id;
+    if (IS_LOGICAL(pi->num))
+       p->start_sect = pi->offset;
+    else
+       p->start_sect = pi->first_sector + pi->offset;
+    p->nr_sects = pi->last_sector - (pi->first_sector+pi->offset) + 1;
+    sects = (((pi->first_sector+pi->offset)/(sectors*heads) > 1023) ?
+            heads*sectors*1024 - 1 : pi->first_sector+pi->offset);
+    set_hsc(p->head, p->sector, p->cyl, sects);
+    sects = ((pi->last_sector/(sectors*heads) > 1023) ?
+            heads*sectors*1024 - 1 : pi->last_sector);
+    set_hsc(p->end_head, p->end_sector, p->end_cyl, sects);
+}
+
+void fill_primary_table(partition_table *buffer)
+{
+    int i;
+
+    /* Zero out existing table */
+    for (i = 0x1BE; i < SECTOR_SIZE; i++)
+       buffer->c.b[i] = 0;
+
+    for (i = 0; i < num_parts; i++)
+       if (IS_PRIMARY(p_info[i].num))
+           fill_part_table(&(buffer->p.part[p_info[i].num]), &(p_info[i]));
+
+    if (ext_info.id == EXTENDED)
+       fill_part_table(&(buffer->p.part[ext_info.num]), &ext_info);
+
+    buffer->p.flag = PART_TABLE_FLAG;
+}
+
+void fill_logical_table(partition_table *buffer, partition_info *pi)
+{
+    struct partition *p;
+    int i, sects;
+
+    for (i = 0; i < logical && pi->first_sector != logical_sectors[i]; i++);
+    if (i == logical || buffer->p.flag != (unsigned short)PART_TABLE_FLAG)
+       for (i = 0; i < SECTOR_SIZE; i++)
+           buffer->c.b[i] = 0;
+
+    /* Zero out existing table */
+    for (i = 0x1BE; i < SECTOR_SIZE; i++)
+       buffer->c.b[i] = 0;
+
+    fill_part_table(&(buffer->p.part[0]), pi);
+
+    for (i = 0;
+        i < num_parts && pi->num != p_info[i].num - 1;
+        i++);
+
+    if (i < num_parts) {
+       p = &(buffer->p.part[1]);
+       pi = &(p_info[i]);
+
+       p->boot_ind = 0;
+       p->sys_ind = 5;
+       p->start_sect = pi->first_sector - ext_info.first_sector;
+       p->nr_sects = pi->last_sector - pi->first_sector + 1;
+       sects = ((pi->first_sector/(sectors*heads) > 1023) ?
+                heads*sectors*1024 - 1 : pi->first_sector);
+       set_hsc(p->head, p->sector, p->cyl, sects);
+       sects = ((pi->last_sector/(sectors*heads) > 1023) ?
+                heads*sectors*1024 - 1 : pi->last_sector);
+       set_hsc(p->end_head, p->end_sector, p->end_cyl, sects);
+    }
+
+    buffer->p.flag = PART_TABLE_FLAG;
+}
+
+void write_part_table(void)
+{
+    int i, done = FALSE, len;
+    partition_table buffer;
+    char response[LINE_LENGTH];
+
+    print_warning(WRITE_WARN);
+
+    while (!done) {
+       mvaddstr(COMMAND_LINE_Y, COMMAND_LINE_X,
+                "Are you sure you want write the partition table to disk? (yes or no): ");
+       
+       len = get_string(response, LINE_LENGTH, NULL);
+
+       clear_warning();
+
+       if (len == GS_ESCAPE)
+           return;
+       else if (len == 2 &&
+                toupper(response[0]) == 'N' &&
+                toupper(response[1]) == 'O') {
+           print_warning(NO_WRITE);
+           return;
+       } else if (len == 3 &&
+                  toupper(response[0]) == 'Y' &&
+                  toupper(response[1]) == 'E' &&
+                  toupper(response[2]) == 'S')
+           done = TRUE;
+       else
+           print_warning(YES_NO);
+    }
+
+    clear_warning();
+    print_warning(WRITING_PART);
+    refresh();
+    
+    read_sector(buffer.c.b, 0);
+    fill_primary_table(&buffer);
+    write_sector(buffer.c.b, 0);
+
+    for (i = 0; i < num_parts; i++)
+       if (IS_LOGICAL(p_info[i].num)) {
+           /* Read the extended partition table from disk ??? KEM */
+           read_sector(buffer.c.b, p_info[i].first_sector);
+           fill_logical_table(&buffer, &(p_info[i]));
+           write_sector(buffer.c.b, p_info[i].first_sector);
+       }
+
+    sync();
+    sleep(2);
+    if (!ioctl(fd,BLKRRPART))
+       changed = TRUE;
+    sync();
+    sleep(4);
+
+    clear_warning();
+    if (changed)
+       print_warning(YES_WRITE);
+    else
+       print_warning(RRPART_FAILED);
+}
+
+void fp_printf(FILE *fp, char *format, ...)
+{
+    va_list args;
+    char buf[1024];
+    int y, x;
+
+    va_start(args, format);
+    vsprintf(buf, format, args);
+    va_end(args);
+
+    if (fp == NULL) {
+       /* The following works best if the string to be printed has at
+           most only one newline. */
+       printw("%s", buf);
+       getyx(stdscr, y, x);
+       if (y >= COMMAND_LINE_Y-2) {
+           mvaddstr(COMMAND_LINE_Y, COMMAND_LINE_X,
+                    "Press any key to continue...");
+           clrtoeol();
+           refresh();
+           (void)getch();
+           erase();
+           move(0, 0);
+       }
+    } else
+       fprintf(fp, "%s", buf);
+}
+
+#define MAX_PER_LINE 16
+void print_file_buffer(FILE *fp, char *buffer)
+{
+    int i,l;
+
+    for (i = 0, l = 0; i < SECTOR_SIZE; i++, l++) {
+       if (l == 0)
+           fp_printf(fp, "0x%03X:", i);
+       fp_printf(fp, " %02X", (unsigned char) buffer[i]);
+       if (l == MAX_PER_LINE - 1) {
+           fp_printf(fp, "\n");
+           l = -1;
+       }
+    }
+    if (l > 0)
+       fp_printf(fp, "\n");
+    fp_printf(fp, "\n");
+}
+
+void print_raw_table(void)
+{
+    int i, to_file;
+    partition_table buffer;
+    char fname[LINE_LENGTH];
+    FILE *fp;
+
+    if (print_only) {
+       fp = stdout;
+       to_file = TRUE;
+    } else {
+       mvaddstr(COMMAND_LINE_Y, COMMAND_LINE_X,
+                "Enter filename or press RETURN to display on screen: ");
+
+       if ((to_file = get_string(fname, LINE_LENGTH, NULL)) < 0)
+           return;
+
+       if (to_file) {
+           if ((fp = fopen(fname, "w")) == NULL) {
+               char errstr[LINE_LENGTH];
+               sprintf(errstr, PRINT_OPEN_ERR, fname);
+               print_warning(errstr);
+               return;
+           }
+       } else {
+           fp = NULL;
+           erase();
+           move(0, 0);
+       }
+    }
+
+    fp_printf(fp, "Disk Drive: %s\n", disk_device);
+
+    read_sector(buffer.c.b, 0);
+    fill_primary_table(&buffer);
+    print_file_buffer(fp, buffer.c.b);
+
+    for (i = 0; i < num_parts; i++)
+       if (IS_LOGICAL(p_info[i].num)) {
+           read_sector(buffer.c.b, p_info[i].first_sector);
+           fill_logical_table(&buffer, &(p_info[i]));
+           print_file_buffer(fp, buffer.c.b);
+       }
+
+    if (to_file) {
+       if (!print_only)
+           fclose(fp);
+    } else {
+       mvaddstr(COMMAND_LINE_Y, COMMAND_LINE_X,
+                "Press any key to continue...");
+       clrtoeol();
+       refresh();
+       (void)getch();
+    }
+}
+
+void print_p_info_entry(FILE *fp, partition_info *p)
+{
+    int size;
+    char part_str[21];
+
+    if (p->id == UNUSABLE)
+       fp_printf(fp, "   None   ");
+    else if (p->id == FREE_SPACE && p->num == PRI_OR_LOG)
+       fp_printf(fp, "   Pri/Log");
+    else if (p->id == FREE_SPACE && p->num == PRIMARY)
+       fp_printf(fp, "   Primary");
+    else if (p->id == FREE_SPACE && p->num == LOGICAL)
+       fp_printf(fp, "   Logical");
+    else
+       fp_printf(fp, "%2d %-7.7s", p->num+1,
+                 IS_LOGICAL(p->num) ? "Logical" : "Primary");
+
+    fp_printf(fp, " ");
+
+    fp_printf(fp, "%7d%c", p->first_sector,
+             ((p->first_sector/(sectors*heads)) !=
+              ((float)p->first_sector/(sectors*heads)) ?
+              '*' : ' '));
+
+    fp_printf(fp, " ");
+
+    fp_printf(fp, "%7d%c", p->last_sector,
+             (((p->last_sector+1)/(sectors*heads)) !=
+              ((float)(p->last_sector+1)/(sectors*heads)) ?
+              '*' : ' '));
+
+    fp_printf(fp, " ");
+
+    fp_printf(fp, "%6d%c", p->offset,
+             ((((p->first_sector == 0 || IS_LOGICAL(p->num)) &&
+                (p->offset != sectors)) ||
+               (p->first_sector != 0 && IS_PRIMARY(p->num) &&
+                p->offset != 0)) ?
+              '#' : ' '));
+
+    fp_printf(fp, " ");
+
+    size = p->last_sector - p->first_sector + 1;
+    fp_printf(fp, "%7d%c", size,
+             ((size/(sectors*heads)) != ((float)size/(sectors*heads)) ?
+              '*' : ' '));
+
+    fp_printf(fp, " ");
+
+    if (p->id == UNUSABLE)
+       sprintf(part_str, "%.16s", "Unusable");
+    else if (p->id == FREE_SPACE)
+       sprintf(part_str, "%.16s", "Free Space");
+    else if (partition_type[p->id])
+       sprintf(part_str, "%.16s (%02X)", partition_type[p->id], p->id);
+    else
+       sprintf(part_str, "%.16s (%02X)", "Unknown", p->id);
+    fp_printf(fp, "%-21.21s", part_str);
+
+    fp_printf(fp, " ");
+
+    if (p->flags == ACTIVE_FLAG)
+       fp_printf(fp, "Boot (%02X)", p->flags);
+    else if (p->flags != 0)
+       fp_printf(fp, "Unknown (%02X)", p->flags);
+    else
+       fp_printf(fp, "None (%02X)", p->flags);
+
+    fp_printf(fp, "\n");
+}
+
+void print_p_info(void)
+{
+    char fname[LINE_LENGTH];
+    FILE *fp;
+    int i, to_file, pext = (ext_info.id == EXTENDED);
+
+    if (print_only) {
+       fp = stdout;
+       to_file = TRUE;
+    } else {
+       mvaddstr(COMMAND_LINE_Y, COMMAND_LINE_X,
+                "Enter filename or press RETURN to display on screen: ");
+
+       if ((to_file = get_string(fname, LINE_LENGTH, NULL)) < 0)
+           return;
+
+       if (to_file) {
+           if ((fp = fopen(fname, "w")) == NULL) {
+               char errstr[LINE_LENGTH];
+               sprintf(errstr, PRINT_OPEN_ERR, fname);
+               print_warning(errstr);
+               return;
+           }
+       } else {
+           fp = NULL;
+           erase();
+           move(0, 0);
+       }
+    }
+
+    fp_printf(fp, "Partition Table for %s\n", disk_device);
+    fp_printf(fp, "\n");
+    fp_printf(fp, "           First    Last\n");
+    fp_printf(fp, " # Type    Sector   Sector   Offset  Length   Filesystem Type (ID)  Flags\n");
+    fp_printf(fp, "-- ------- -------- -------- ------- -------- --------------------- ---------\n");
+
+    for (i = 0; i < num_parts; i++) {
+       if (pext && (p_info[i].first_sector >= ext_info.first_sector)) {
+           print_p_info_entry(fp,&ext_info);
+           pext = FALSE;
+       }
+       print_p_info_entry(fp, &(p_info[i]));
+    }
+
+    if (to_file) {
+       if (!print_only)
+           fclose(fp);
+    } else {
+       mvaddstr(COMMAND_LINE_Y, COMMAND_LINE_X,
+                "Press any key to continue...");
+       clrtoeol();
+       refresh();
+       (void)getch();
+    }
+}
+
+void print_part_entry(FILE *fp, int num, partition_info *pi)
+{
+    int first = 0, start = 0, end = 0, size = 0;
+    int ss = 0, sh = 0, sc = 0;
+    int es = 0, eh = 0, ec = 0;
+    int flags = 0, id = 0;
+
+    if (pi != NULL) {
+       flags = pi->flags;
+       id = pi->id;
+
+       if (IS_LOGICAL(num))
+           first = pi->offset;
+       else
+           first = pi->first_sector + pi->offset;
+
+       start = pi->first_sector + pi->offset;
+       end = pi->last_sector;
+       size = end - start + 1;
+       if ((start/(sectors*heads)) > 1023)
+           start = heads*sectors*1024 - 1;
+       if ((end/(sectors*heads)) > 1023)
+           end = heads*sectors*1024 - 1;
+
+       ss = start % sectors + 1;
+       start /= sectors;
+       sh = start % heads;
+       sc = start / heads;
+
+       es = end % sectors + 1;
+       end /= sectors;
+       eh = end % heads;
+       ec = end / heads;
+    }
+
+    fp_printf(fp, "%2d  0x%02X %4d %4d %4d 0x%02X %4d %4d %4d %7d %7d\n",
+             num+1, flags, sh, ss, sc, id, eh, es, ec, first, size);
+}
+
+
+void print_part_table(void)
+{
+    int i, j, to_file;
+    char fname[LINE_LENGTH];
+    FILE *fp;
+
+    if (print_only) {
+       fp = stdout;
+       to_file = TRUE;
+    } else {
+       mvaddstr(COMMAND_LINE_Y, COMMAND_LINE_X,
+                "Enter filename or press RETURN to display on screen: ");
+
+       if ((to_file = get_string(fname, LINE_LENGTH, NULL)) < 0)
+           return;
+
+       if (to_file) {
+           if ((fp = fopen(fname, "w")) == NULL) {
+               char errstr[LINE_LENGTH];
+               sprintf(errstr, PRINT_OPEN_ERR, fname);
+               print_warning(errstr);
+               return;
+           }
+       } else {
+           fp = NULL;
+           erase();
+           move(0, 0);
+       }
+    }
+
+    fp_printf(fp, "Partition Table for %s\n", disk_device);
+    fp_printf(fp, "\n");
+    fp_printf(fp, "         ---Starting---      ----Ending---- Start   Number\n");
+    fp_printf(fp, " # Flags Head Sect Cyl   ID  Head Sect Cyl  Sector  Sectors\n");
+    fp_printf(fp, "-- ----- ---- ---- ---- ---- ---- ---- ---- ------- -------\n");
+
+    for (i = 0; i < 4; i++) {
+       for (j = 0;
+            j < num_parts && (p_info[j].id <= 0 || p_info[j].num != i);
+            j++);
+       if (j < num_parts) {
+           print_part_entry(fp, i, &(p_info[j]));
+       } else if (ext_info.id == EXTENDED && ext_info.num == i) {
+           print_part_entry(fp, i, &ext_info);
+       } else {
+           print_part_entry(fp, i, NULL);
+       }
+    }
+
+    for (i = 0; i < num_parts; i++)
+       if (IS_LOGICAL(p_info[i].num))
+           print_part_entry(fp, p_info[i].num, &(p_info[i]));
+
+    if (to_file) {
+       if (!print_only)
+           fclose(fp);
+    } else {
+       mvaddstr(COMMAND_LINE_Y, COMMAND_LINE_X,
+                "Press any key to continue...");
+       clrtoeol();
+       refresh();
+       (void)getch();
+    }
+}
+
+void print_tables(void)
+{
+    int done = FALSE;
+
+    mvaddstr(COMMAND_LINE_Y, COMMAND_LINE_X, "Print format [rst]: ");
+    clrtoeol();
+    refresh();
+
+    while (!done)
+       switch (toupper(getch())) {
+       case 'R':
+           print_raw_table();
+           done = TRUE;
+           break;
+       case 'S':
+           print_p_info();
+           done = TRUE;
+           break;
+       case 'T':
+           print_part_table();
+           done = TRUE;
+           break;
+       case ESC:
+           done = TRUE;
+           break;
+       }
+}
+
+#define END_OF_HELP "EOHS!"
+#define NEW_HELP_SCREEN "SNHS!"
+void display_help()
+{
+    char *help_text[] = {
+       "Help Screen for cfdisk " VERSION,
+       "",
+       "This is cfdisk, a curses based disk partitioning programs, which",
+       "allows you to create, delete and modify partitions on your hard",
+       "disk drive.",
+       "",
+       "Copyright (C) 1994 Kevin E. Martin",
+       "",
+       "Command      Meaning",
+       "-------      -------",
+       "  b          Toggle bootable flag of the current partition",
+       "  d          Delete the current partition",
+       "  g          Change cylinders, heads, sectors-per-track parameters",
+       "             WARNING: This option should only be used by people who",
+       "             know what they are doing.",
+       "  h          Print this screen",
+       "  m          Maximize disk usage of the current partition",
+       "             Note: This may make the partition incompatible with",
+       "             DOS, OS/2, ...",
+       "  n          Create new partition from free space",
+       "  p          Print partition table to the screen or to a file",
+       "             There are several different formats for the partition",
+       "             that you can choose from:",
+       "                r - Raw data (exactly what would be written to disk)",
+       "                s - Table ordered by sectors",
+       "                t - Table in raw format",
+       "  q          Quit program without writing partition table",
+       "  t          Change the filesystem type",
+       "  u          Change units of the partition size display",
+       "             Rotates through Mb, sectors and cylinders",
+       "  W          Write partition table to disk (must enter upper case W)",
+        "             Since this might destroy data on the disk, you must",
+       "             either confirm or deny the write by entering `yes' or",
+       "             `no'",
+       "Up Arrow     Move cursor to the previous partition",
+       "Down Arrow   Move cursor to the next partition",
+       "CTRL-L       Redraws the screen",
+       "  ?          Print this screen",
+       "",
+       "Note: All of the commands can be entered with either upper or lower",
+       "case letters (except for Writes).",
+       END_OF_HELP
+    };
+
+    int cur_line = 0;
+    FILE *fp = NULL;
+
+    erase();
+    move(0, 0);
+    while (strcmp(help_text[cur_line], END_OF_HELP))
+       if (!strcmp(help_text[cur_line], NEW_HELP_SCREEN)) {
+           mvaddstr(COMMAND_LINE_Y, COMMAND_LINE_X,
+                    "Press any key to continue...");
+           clrtoeol();
+           refresh();
+           (void)getch();
+           erase();
+           move(0, 0);
+           cur_line++;
+       } else
+           fp_printf(fp, "%s\n", help_text[cur_line++]);
+
+    mvaddstr(COMMAND_LINE_Y, COMMAND_LINE_X,
+            "Press any key to continue...");
+    clrtoeol();
+    refresh();
+    (void)getch();
+}
+
+int change_geometry(void)
+{
+    int ret_val = FALSE;
+    int done = FALSE;
+    char def[LINE_LENGTH];
+    char response[LINE_LENGTH];
+    int tmp_val;
+
+    while (!done) {
+       mvaddstr(COMMAND_LINE_Y, COMMAND_LINE_X,
+                "Change disk geometry information [chs]: ");
+       clrtoeol();
+       refresh();
+
+       clear_warning();
+
+       switch (toupper(getch())) {
+       case 'C':
+           sprintf(def, "%d", cylinders);
+           mvaddstr(COMMAND_LINE_Y, COMMAND_LINE_X,
+                    "Enter the number of cylinders: ");
+           if (get_string(response, LINE_LENGTH, def) > 0) {
+               tmp_val = atoi(response);
+               if (tmp_val > 0 && tmp_val <= MAX_CYLINDERS) {
+                   cylinders = tmp_val;
+                   ret_val = TRUE;
+               } else
+                   print_warning(BAD_CYLINDERS);
+           }
+           break;
+       case 'H':
+           sprintf(def, "%d", heads);
+           mvaddstr(COMMAND_LINE_Y, COMMAND_LINE_X,
+                    "Enter the number of heads: ");
+           if (get_string(response, LINE_LENGTH, def) > 0) {
+               tmp_val = atoi(response);
+               if (tmp_val > 0 && tmp_val <= MAX_HEADS) {
+                   heads = tmp_val;
+                   ret_val = TRUE;
+               } else
+                   print_warning(BAD_HEADS);
+           }
+           break;
+       case 'S':
+           sprintf(def, "%d", sectors);
+           mvaddstr(COMMAND_LINE_Y, COMMAND_LINE_X,
+                    "Enter the number of sectors per track: ");
+           if (get_string(response, LINE_LENGTH, def) > 0) {
+               tmp_val = atoi(response);
+               if (tmp_val > 0 && tmp_val <= MAX_SECTORS) {
+                   sectors = tmp_val;
+                   ret_val = TRUE;
+               } else
+                   print_warning(BAD_SECTORS);
+           }
+           break;
+       case ESC:
+       case CR:
+           done = TRUE;
+           break;
+       default:
+           putchar(BELL);
+           break;
+       }
+    }
+
+    if (ret_val) {
+       if (p_info[num_parts-1].last_sector > heads*sectors*cylinders-1) {
+           while (p_info[num_parts-1].first_sector > heads*sectors*cylinders-1) {
+               if (p_info[num_parts-1].id == FREE_SPACE ||
+                   p_info[num_parts-1].id == UNUSABLE)
+                   remove_part(num_parts-1);
+               else
+                   del_part(num_parts-1);
+           }
+
+           p_info[num_parts-1].last_sector = heads*sectors*cylinders - 1;
+
+           if (ext_info.last_sector > heads*sectors*cylinders-1)
+               ext_info.last_sector = heads*sectors*cylinders - 1;
+       } else if (p_info[num_parts-1].last_sector < heads*sectors*cylinders-1) {
+           if (p_info[num_parts-1].id == FREE_SPACE ||
+               p_info[num_parts-1].id == UNUSABLE) {
+               p_info[num_parts-1].last_sector = heads*sectors*cylinders - 1;
+           } else {
+               insert_part(num_parts, PRI_OR_LOG, FREE_SPACE, 0,
+                           p_info[num_parts-1].last_sector+1,
+                           heads*sectors*cylinders-1, 0);
+           }
+       }
+
+       /* Make sure the partitions are correct */
+       check_part_info();
+    }
+
+    return ret_val;
+}
+
+void change_id(int i)
+{
+    char id[LINE_LENGTH], def[LINE_LENGTH];
+    int num_types = 0;
+    int num_across, num_down;
+    int len, new_id = LINUX;
+    int y_start, y_end;
+    int j, pos;
+
+    for (num_types = 0, j = 1; j < NUM_PART_TYPES; j++)
+       if (partition_type[j])
+           num_types++;
+
+    num_across = COLS/COL_ID_WIDTH;
+    num_down = (((float)num_types)/num_across + 1);
+    y_start = COMMAND_LINE_Y - 1 - num_down;
+    if (y_start > DISK_TABLE_START+cur_part+4)
+       y_start = DISK_TABLE_START+cur_part+4;
+    y_end = y_start + num_down - 1;
+
+    for (j = y_start - 1; j <= y_end + 1; j++) {
+       move(j, 0);
+       clrtoeol();
+    }
+
+    for (pos = 0, j = 1; j < NUM_PART_TYPES; j++)
+       if (partition_type[j]) {
+           move(y_start + pos % num_down, (pos/num_down)*COL_ID_WIDTH + 1);
+           printw("%02X %-16.16s", j, partition_type[j]);
+           pos++;
+       }
+
+    sprintf(def, "%02X", new_id);
+    mvaddstr(COMMAND_LINE_Y, COMMAND_LINE_X, "Enter filesystem type: ");
+    if ((len = get_string(id, 2, def)) <= 0 && len != GS_DEFAULT)
+       return;
+
+    if (len != GS_DEFAULT) {
+       if (!isxdigit(id[0]))
+           return;
+       new_id = (isdigit(id[0]) ? id[0] - '0' : tolower(id[0]) - 'a' + 10);
+       if (len == 2)
+           if (isxdigit(id[1]))
+               new_id = new_id*16 +
+                   (isdigit(id[1]) ? id[1] - '0' : tolower(id[1]) - 'a' + 10);
+           else
+               return;
+    }
+
+    if (new_id == 0)
+       print_warning(ID_EMPTY);
+    else if (new_id == EXTENDED)
+       print_warning(ID_EXT);
+    else
+       p_info[i].id = new_id;
+}
+
+void draw_partition(int i)
+{
+    int size, j;
+    int y = i + DISK_TABLE_START + 2 - (cur_part/NUM_ON_SCREEN)*NUM_ON_SCREEN;
+
+    if (!arrow_cursor) {
+       move(y, 0);
+       for (j = 0; j < COLS; j++)
+           addch(' ');
+    }
+
+    if (p_info[i].id > 0) {
+       mvprintw(y, NAME_START,
+                "%s%d", disk_device, p_info[i].num+1);
+       if (p_info[i].flags) {
+           if (p_info[i].flags == ACTIVE_FLAG)
+               mvaddstr(y, FLAGS_START, "Boot");
+           else
+               mvprintw(y, FLAGS_START, "Unk(%02X)", p_info[i].flags);
+           if (p_info[i].first_sector == 0 || IS_LOGICAL(p_info[i].num)) {
+               if (p_info[i].offset != sectors)
+                   addstr(", NC");
+           } else {
+               if (p_info[i].offset != 0)
+                   addstr(", NC");
+           }
+       } else {
+           if (p_info[i].first_sector == 0 || IS_LOGICAL(p_info[i].num)) {
+               if (p_info[i].offset != sectors)
+                   mvaddstr(y, FLAGS_START, "NC");
+           } else {
+               if (p_info[i].offset != 0)
+                   mvaddstr(y, FLAGS_START, "NC");
+           }
+       }
+    }
+    mvaddstr(y, PTYPE_START,
+            (p_info[i].id == UNUSABLE ? "" :
+             (IS_LOGICAL(p_info[i].num) ? "Logical" :
+              (p_info[i].num >= 0 ? "Primary" :
+               (p_info[i].num == PRI_OR_LOG ? "Pri/Log" :
+                (p_info[i].num == PRIMARY ? "Primary" : "Logical"))))));
+    if (p_info[i].id == UNUSABLE)
+       mvaddstr(y, FSTYPE_START, "Unusable");
+    else if (p_info[i].id == FREE_SPACE)
+       mvaddstr(y, FSTYPE_START, "Free Space");
+    else if (partition_type[p_info[i].id])
+       mvaddstr(y, FSTYPE_START, partition_type[p_info[i].id]);
+    else
+       mvprintw(y, FSTYPE_START, "Unknown (%02X)", p_info[i].id);
+
+    size = p_info[i].last_sector - p_info[i].first_sector + 1;
+    if (display_units == SECTORS)
+       mvprintw(y, SIZE_START, "%9d", size);
+    else if (display_units == CYLINDERS)
+       mvprintw(y, SIZE_START, "%9d", size/(sectors*heads));
+    else
+       mvprintw(y, SIZE_START, "%9.2f", ceiling(size/20.48)/100);
+    if (((size/(sectors*heads)) != ceiling(size/(sectors*(float)heads))) ||
+       ((p_info[i].first_sector/(sectors*heads)) !=
+        ceiling(p_info[i].first_sector/(sectors*heads))))
+       mvprintw(y, COLUMNS-1, "*");
+}
+
+void init_const(void)
+{
+    if (!defined) {
+       NAME_START = (((float)NAME_START)/COLUMNS)*COLS;
+       FLAGS_START = (((float)FLAGS_START)/COLUMNS)*COLS;
+       PTYPE_START = (((float)PTYPE_START)/COLUMNS)*COLS;
+       FSTYPE_START = (((float)FSTYPE_START)/COLUMNS)*COLS;
+       SIZE_START = (((float)SIZE_START)/COLUMNS)*COLS;
+       COMMAND_LINE_X = (((float)COMMAND_LINE_X)/COLUMNS)*COLS;
+
+       COMMAND_LINE_Y = LINES - 4;
+       WARNING_START = LINES - 2;
+
+       if ((NUM_ON_SCREEN = COMMAND_LINE_Y - DISK_TABLE_START - 3) <= 0)
+           NUM_ON_SCREEN = 1;
+
+       COLUMNS = COLS;
+       defined = TRUE;
+    }
+}
+
+void draw_screen(void)
+{
+    int i;
+    char *line;
+
+    line = (char *)malloc((COLS+1)*sizeof(char));
+
+    if (warning_last_time) {
+       for (i = 0; i < COLS; i++) {
+           move(WARNING_START, i);
+           line[i] = inch();
+       }
+       line[COLS] = 0;
+    }
+
+    erase();
+
+    if (warning_last_time)
+       mvaddstr(WARNING_START, 0, line);
+
+
+    sprintf(line, "cfdisk %s", VERSION);
+    mvaddstr(HEADER_START, (COLS-strlen(line))/2, line);
+    sprintf(line, "Disk Drive: %s", disk_device);
+    mvaddstr(HEADER_START+2, (COLS-strlen(line))/2, line);
+    sprintf(line, "Heads: %d   Sectors per Track: %d   Cylinders: %d",
+           heads, sectors, cylinders);
+    mvaddstr(HEADER_START+3, (COLS-strlen(line))/2, line);
+
+    mvaddstr(DISK_TABLE_START, NAME_START, "Name");
+    mvaddstr(DISK_TABLE_START, FLAGS_START, "Flags");
+    mvaddstr(DISK_TABLE_START, PTYPE_START, "Part Type");
+    mvaddstr(DISK_TABLE_START, FSTYPE_START, "FS Type");
+    if (display_units == SECTORS)
+       mvaddstr(DISK_TABLE_START, SIZE_START, "  Sectors");
+    else if (display_units == CYLINDERS)
+       mvaddstr(DISK_TABLE_START, SIZE_START, "Cylinders");
+    else
+       mvaddstr(DISK_TABLE_START, SIZE_START, "Size (MB)");
+
+    move(DISK_TABLE_START+1, 1);
+    for (i = 1; i < COLS-1; i++)
+       addch('-');
+
+    if (NUM_ON_SCREEN >= num_parts)
+       for (i = 0; i < num_parts; i++)
+           draw_partition(i);
+    else
+       for (i = (cur_part/NUM_ON_SCREEN)*NUM_ON_SCREEN;
+            i < NUM_ON_SCREEN + (cur_part/NUM_ON_SCREEN)*NUM_ON_SCREEN &&
+            i < num_parts;
+            i++)
+           draw_partition(i);
+
+    free(line);
+}
+
+int draw_cursor(int move)
+{
+    if (move != 0 && (cur_part + move < 0 || cur_part + move >= num_parts))
+       return -1;
+
+    if (arrow_cursor)
+       mvaddstr(DISK_TABLE_START + cur_part + 2
+                - (cur_part/NUM_ON_SCREEN)*NUM_ON_SCREEN, 0, "   ");
+    else
+       draw_partition(cur_part);
+
+    cur_part += move;
+
+    if (((cur_part - move)/NUM_ON_SCREEN)*NUM_ON_SCREEN !=
+       (cur_part/NUM_ON_SCREEN)*NUM_ON_SCREEN)
+       draw_screen();
+
+    if (arrow_cursor)
+       mvaddstr(DISK_TABLE_START + cur_part + 2
+                - (cur_part/NUM_ON_SCREEN)*NUM_ON_SCREEN, 0, "-->");
+    else {
+       standout();
+       draw_partition(cur_part);
+       standend();
+    }
+
+    return 0;
+}
+
+void die(int dummy)
+{
+    signal(SIGINT, old_SIGINT);
+    signal(SIGTERM, old_SIGTERM);
+    mvcur(0, COLS-1, LINES-1, 0);
+    nl();
+    endwin();
+    fdexit(0);
+}
+
+void do_curses_fdisk(void)
+{
+    int done = FALSE;
+    char command;
+
+    initscr();
+    old_SIGINT = signal(SIGINT, die);
+    old_SIGTERM = signal(SIGTERM, die);
+#ifdef DEBUG
+    signal(SIGINT, old_SIGINT);
+    signal(SIGTERM, old_SIGTERM);
+#endif
+
+    cbreak();
+    noecho();
+    nonl();
+
+    init_const();
+
+    fill_p_info();
+
+    draw_screen();
+
+    while (!done) {
+       (void)draw_cursor(0);
+
+       if (p_info[cur_part].id == FREE_SPACE)
+           mvaddstr(COMMAND_LINE_Y, COMMAND_LINE_X, "Command [hnpquW?]: ");
+       else if (p_info[cur_part].id > 0)
+           mvaddstr(COMMAND_LINE_Y, COMMAND_LINE_X, "Command [bdhmpqtuW?]: ");
+       else
+           mvaddstr(COMMAND_LINE_Y, COMMAND_LINE_X, "Command [hpquW?]: ");
+
+       clrtoeol();
+       refresh();
+
+       clear_warning();
+
+       switch (command = getch()) {
+       case 'B':
+       case 'b':
+           if (p_info[cur_part].id > 0)
+               p_info[cur_part].flags ^= 0x80;
+           else
+               print_warning(NO_FLAGS);
+           break;
+       case 'D':
+       case 'd':
+           if (p_info[cur_part].id > 0) {
+               del_part(cur_part);
+               if (cur_part >= num_parts)
+                   cur_part = num_parts - 1;
+               draw_screen();
+           } else
+               print_warning(DEL_EMPTY);
+           break;
+       case 'G':
+       case 'g':
+           if (change_geometry())
+               draw_screen();
+           break;
+       case 'M':
+       case 'm':
+           if (p_info[cur_part].id > 0) {
+               if (p_info[cur_part].first_sector == 0 ||
+                   IS_LOGICAL(p_info[cur_part].num)) {
+                   if (p_info[cur_part].offset == sectors)
+                       p_info[cur_part].offset = 1;
+                   else
+                       p_info[cur_part].offset = sectors;
+                   draw_screen();
+               } else if (p_info[cur_part].offset != 0)
+                   p_info[cur_part].offset = 0;
+               else
+                   print_warning(MAX_UNMAXABLE);
+           } else
+               print_warning(MAX_UNMAXABLE);
+           break;
+       case 'N':
+       case 'n':
+           if (p_info[cur_part].id == FREE_SPACE) {
+               new_part(cur_part);
+               draw_screen();
+           } else if (p_info[cur_part].id == UNUSABLE)
+               print_warning(ADD_UNUSABLE);
+           else
+               print_warning(ADD_EXISTS);
+           break;
+       case 'P':
+       case 'p':
+           print_tables();
+           draw_screen();
+           break;
+       case 'Q':
+       case 'q':
+           done = TRUE;
+           break;
+       case 'T':
+       case 't':
+           if (p_info[cur_part].id > 0) {
+               change_id(cur_part);
+               draw_screen();
+           } else
+               print_warning(TYPE_EMPTY);
+           break;
+       case 'U':
+       case 'u':
+           if (display_units == MEGABYTES)
+               display_units = SECTORS;
+           else if (display_units == SECTORS)
+               display_units = CYLINDERS;
+           else if (display_units == CYLINDERS)
+               display_units = MEGABYTES;
+           draw_screen();
+           break;
+       case 'W':
+           write_part_table();
+           break;
+       case 'H':
+       case 'h':
+       case '?':
+           display_help();
+           draw_screen();
+           break;
+       case ESC:
+           if ((command = getch()) == '[') {
+               command = getch();
+               switch (command) {
+               case 'A' : /* Up arrow */
+                   if (!draw_cursor(-1))
+                       command = 0;
+                   else
+                       print_warning(NO_MORE_PARTS);
+                   break;
+               case 'B' : /* Down arrow */
+                   if (!draw_cursor(1))
+                       command = 0;
+                   else
+                       print_warning(NO_MORE_PARTS);
+                   break;
+               case 'C' : /* Right arrow */
+               case 'D' : /* Left arrow */
+               }
+           }
+           if (command)
+               putchar(BELL); /* CTRL-G */
+           break;
+       case REDRAWKEY:
+           clear();
+           draw_screen();
+           break;
+       default:
+           print_warning(BAD_COMMAND);
+           putchar(BELL); /* CTRL-G */
+       }
+    }
+
+    signal(SIGINT, old_SIGINT);
+    signal(SIGTERM, old_SIGTERM);
+    mvcur(0, COLS-1, LINES-1, 0);
+    nl();
+    endwin();
+    fdexit(0);
+}
+
+void copyright(void)
+{
+    fprintf(stderr, "Copyright (C) 1994 Kevin E. Martin\n");
+}
+
+void usage(char *prog_name)
+{
+    fprintf(stderr,
+           "%s: [-avz] [-c # cylinders] [-h # heads] [-s # sectors/track]\n",
+           prog_name);
+    fprintf(stderr,
+           "[ -P opt ] device\n");
+    copyright();
+}
+
+void main(int argc, char **argv)
+{
+    char c;
+    int i, len;
+
+    while ((c = getopt(argc, argv, "ac:h:s:vzP:")) != EOF)
+       switch (c) {
+       case 'a':
+           arrow_cursor = TRUE;
+           break;
+       case 'c':
+           cylinders = atoi(optarg);
+           if (cylinders <= 0 || cylinders > MAX_CYLINDERS) {
+               fprintf(stderr, "%s: %s\n", argv[0], BAD_CYLINDERS);
+               exit(1);
+           }
+           break;
+       case 'h':
+           heads = atoi(optarg);
+           if (heads <= 0 || heads > MAX_HEADS) {
+               fprintf(stderr, "%s: %s\n", argv[0], BAD_HEADS);
+               exit(1);
+           }
+           break;
+       case 's':
+           sectors = atoi(optarg);
+           if (sectors <= 0 || sectors > MAX_SECTORS) {
+               fprintf(stderr, "%s: %s\n", argv[0], BAD_SECTORS);
+               exit(1);
+           }
+           break;
+       case 'v':
+           fprintf(stderr, "cfdisk %s\n", VERSION);
+           copyright();
+           exit(0);
+       case 'z':
+           zero_table = TRUE;
+           break;
+       case 'P':
+           len = strlen(optarg);
+           for (i = 0; i < len; i++) {
+               switch (optarg[i]) {
+               case 'r':
+                   print_only |= PRINT_RAW_TABLE;
+                   break;
+               case 's':
+                   print_only |= PRINT_SECTOR_TABLE;
+                   break;
+               case 't':
+                   print_only |= PRINT_PARTITION_TABLE;
+                   break;
+               default:
+                   usage(argv[0]);
+                   break;
+               }
+           }
+           break;
+       default:
+           usage(argv[0]);
+           exit(1);
+       }
+
+    if (argc-optind == 1)
+       disk_device = argv[optind];
+    else if (argc-optind != 0) {
+       usage(argv[0]);
+       exit(1);
+    } else if ((fd = open(DEFAULT_DEVICE, O_RDWR)) < 0)
+       disk_device = ALTERNATE_DEVICE;
+    else close(fd);
+
+    if (print_only) {
+       fill_p_info();
+       if (print_only & PRINT_RAW_TABLE)
+           print_raw_table();
+       if (print_only & PRINT_SECTOR_TABLE)
+           print_p_info();
+       if (print_only & PRINT_PARTITION_TABLE)
+           print_part_table();
+    } else
+       do_curses_fdisk();
+}
diff --git a/disk-utils/cfdisk.c.orig b/disk-utils/cfdisk.c.orig
new file mode 100644 (file)
index 0000000..3b9f22f
--- /dev/null
@@ -0,0 +1,2066 @@
+/****************************************************************************
+ *
+ *     CFDISK
+ *
+ * cfdisk is a curses based disk drive partitioning program that can
+ * create partitions for a wide variety of operating systems including
+ * Linux, MS-DOS and OS/2.
+ *
+ * cfdisk was inspired by the fdisk program, by A. V. Le Blanc
+ * (LeBlanc@mcc.ac.uk).
+ *
+ *     Copyright (C) 1994 Kevin E. Martin (martin@cs.unc.edu)
+ *
+ * cfdisk is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * cfdisk is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with cfdisk; if not, write to the Free Software Foundation,
+ * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Created:    Fri Jan 28 22:46:58 1994, martin@cs.unc.edu
+ *
+ ****************************************************************************/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <unistd.h>
+#include <ctype.h>
+#include <errno.h>
+#include <getopt.h>
+#include <fcntl.h>
+#include <curses.h>
+#include <signal.h>
+#include <math.h>
+#include <sys/ioctl.h>
+#include <linux/genhd.h>
+#include <linux/hdreg.h>
+#include <linux/fs.h>          /* for BLKRRPART */
+
+typedef long ext2_loff_t;
+extern ext2_loff_t ext2_llseek(unsigned int fd,
+                              ext2_loff_t offset,
+                              unsigned int origin);
+
+#define VERSION "0.8 BETA (>2GB)"
+
+#define DEFAULT_DEVICE "/dev/hda"
+#define ALTERNATE_DEVICE "/dev/sda"
+
+#define LINE_LENGTH 80
+#define MAXIMUM_PARTS 60
+
+#define SECTOR_SIZE 512
+
+#define MAX_CYLINDERS 65535
+#define MAX_HEADS 255
+#define MAX_SECTORS 63
+
+#define ACTIVE_FLAG 0x80
+#define PART_TABLE_FLAG 0xAA55
+
+#define UNUSABLE -1
+#define FREE_SPACE 0x00
+#define EXTENDED 0x05
+#define LINUX_MINIX 0x81
+#define LINUX_SWAP 0x82
+#define LINUX 0x83
+
+#define ADD_EXISTS "This partition is already in use"
+#define ADD_UNUSABLE "This partition is unusable"
+#define DEL_EMPTY "Cannot delete an empty partition"
+#define ID_EMPTY "Cannot change FS Type to empty"
+#define ID_EXT "Cannot change FS Type to extended"
+#define NEED_EXT "No room to create the extended partition"
+#define NO_FLAGS "Cannot make this partition bootable"
+#define NO_MORE_PARTS "No more partitions"
+#define PRINT_OPEN_ERR "Cannot open file '%s'"
+#define TWO_EXTENDEDS "Cannot create logical drive here -- would create two extended partitions"
+#define TYPE_EMPTY "Cannot change the type of an empty partition"
+#define BAD_COMMAND "Illegal command"
+#define MAX_UNMAXABLE "Cannot maximize this partition"
+#define BAD_OPEN "Cannot open disk drive"
+#define BAD_SEEK "Cannot seek on disk drive"
+#define BAD_READ "Cannot read disk drive"
+#define BAD_WRITE "Cannot write disk drive"
+#define BAD_GEOMETRY "Cannot read disk drive geometry"
+#define BAD_PRIMARY "Bad primary partition"
+#define BAD_LOGICAL "Bad logical partition"
+#define BAD_CYLINDERS "Illegal cylinders value"
+#define BAD_HEADS "Illegal heads value"
+#define BAD_SECTORS "Illegal sectors value"
+#define WRITE_WARN "Warning!!  This may destroy data on your disk!"
+#define YES_NO "Please enter `yes' or `no'"
+#define WRITING_PART "Writing partition table to disk..."
+#define YES_WRITE "Wrote partition table to disk"
+#define NO_WRITE "Did not write partition table to disk"
+#define RRPART_FAILED "Wrote partition table, but re-read table failed.  Reboot to update table."
+
+#define PRI_OR_LOG -1
+#define PRIMARY -2
+#define LOGICAL -3
+
+#define COL_ID_WIDTH 20
+
+#define CR '\015'
+#define ESC '\033'
+#define DEL '\177'
+#define BELL '\007'
+/* '\014' == ^L */
+#define REDRAWKEY '\014'
+
+/* Display units */
+#define MEGABYTES 1
+#define SECTORS 2
+#define CYLINDERS 3
+
+#define GS_DEFAULT -1
+#define GS_ESCAPE -2
+
+#define PRINT_RAW_TABLE 1
+#define PRINT_SECTOR_TABLE 2
+#define PRINT_PARTITION_TABLE 4
+
+#define IS_PRIMARY(p) ((p) >= 0 && (p) < 4)
+#define IS_LOGICAL(p) ((p) > 3)
+
+#define round_int(d) ((double)((int)(d+0.5)))
+#define ceiling(d) ((double)(((d) != (int)(d)) ? (int)(d+1.0) : (int)(d)))
+
+#define set_hsc(h,s,c,sector) \
+{ \
+      s = sector % sectors + 1;        \
+      sector /= sectors;       \
+      h = sector % heads;      \
+      sector /= heads;         \
+      c = sector & 0xFF;       \
+      s |= (sector >> 2) & 0xC0;\
+}
+
+#define ALIGNMENT 2
+typedef union {
+    struct {
+       unsigned char align[ALIGNMENT];
+       unsigned char b[SECTOR_SIZE];
+    } c;
+    struct {
+       unsigned char align[ALIGNMENT];
+       unsigned char buffer[0x1BE];
+       struct partition part[4];
+       unsigned short flag;
+    } p;
+} partition_table;
+
+typedef struct {
+    int first_sector;  /* first sector in partition */
+    int last_sector;   /* last sector in partition */
+    int offset;                /* offset from first sector to start of data */
+    int flags;         /* active == 0x80 */
+    int id;            /* filesystem type */
+    int num;           /* number of partition -- primary vs. logical */
+} partition_info;
+
+char *disk_device = DEFAULT_DEVICE;
+int fd;
+int heads = 0;
+int sectors = 0;
+int cylinders = 0;
+int changed = FALSE;
+int opened = FALSE;
+
+partition_info p_info[MAXIMUM_PARTS];
+partition_info ext_info;
+int num_parts = 0;
+
+int logical = 0;
+int logical_sectors[MAXIMUM_PARTS];
+
+__sighandler_t old_SIGINT, old_SIGTERM;
+
+int arrow_cursor = FALSE;
+int display_units = MEGABYTES;
+int zero_table = FALSE;
+int print_only = 0;
+
+/* Curses screen information */
+int cur_part = 0;
+int warning_last_time = FALSE;
+int defined = FALSE;
+int COLUMNS = 80;
+int NUM_ON_SCREEN = 1;
+
+/* Y coordinates */
+int HEADER_START = 0;
+int DISK_TABLE_START = 5;
+int WARNING_START = 23;
+int COMMAND_LINE_Y = 21;
+
+/* X coordinates */
+int NAME_START = 4;
+int FLAGS_START = 16;
+int PTYPE_START = 30;
+int FSTYPE_START = 45;
+int SIZE_START = 70;
+int COMMAND_LINE_X = 5;
+
+#define NUM_PART_TYPES 256
+char *partition_type[NUM_PART_TYPES] = {
+    [LINUX_MINIX] = "Linux/MINIX",
+    [LINUX_SWAP]  = "Linux Swap",
+    [LINUX]       = "Linux",
+    [FREE_SPACE]  = "Free Space",
+    [EXTENDED]    = "Extended",
+    [0x01]        = "DOS 12-bit FAT",
+    [0x04]        = "DOS 16-bit < 32Mb",
+    [0x06]        = "DOS 16-bit >=32Mb",
+    [0x07]        = "OS/2 HPFS",
+    [0x0A]        = "OS/2 Boot Manager",
+    [0xA5]        = "BSD/386",
+
+/* The rest of these are taken from A. V. Le Blanc's (LeBlanc@mcc.ac.uk)
+ * fdisk program.  I do not know where they came from, but I include
+ * them for completeness.
+ */
+
+    [0x02]        = "XENIX root",
+    [0x03]        = "XENIX usr",
+    [0x08]        = "AIX",
+    [0x09]        = "AIX bootable",
+    [0x40]        = "Venix 80286",
+    [0x51]        = "Novell?",
+    [0x52]        = "Microport",
+    [0x63]        = "GNU HURD",
+    [0x64]        = "Novell",
+    [0x75]        = "PC/IX",
+    [0x80]        = "Old MINIX",
+    [0x93]        = "Amoeba",
+    [0x94]        = "Amoeba BBT",
+    [0xB7]        = "BSDI fs",
+    [0xB8]        = "BSDI swap",
+    [0xC7]        = "Syrinx",
+    [0xDB]        = "CP/M",
+    [0xE1]        = "DOS access",
+    [0xE3]        = "DOS R/O",
+    [0xF2]        = "DOS secondary",
+    [0xFF]        = "BBT"
+};
+
+void fdexit(int ret)
+{
+    if (opened)
+       close(fd);
+
+    if (changed) {
+       fprintf(stderr, "Disk has been changed.\n");
+       fprintf(stderr, "Reboot the system to ensure the partition "
+                       "table is correctly updated.\n");
+       
+       fprintf( stderr, "\nWARNING: If you have created or modified any\n"
+                        "DOS 6.x partitions, please see the cfdisk manual\n"
+                        "page for additional information.\n" );
+    }
+
+
+    exit(ret);
+}
+
+int get_string(char *str, int len, char *def)
+{
+    char c;
+    int i = 0;
+    int x, y;
+    int use_def = FALSE;
+
+    getyx(stdscr, y, x);
+    clrtoeol();
+
+    str[i] = 0;
+
+    if (def != NULL) {
+       mvaddstr(y, x, def);
+       move(y, x);
+       use_def = TRUE;
+    }
+
+    refresh();
+    while ((c = getch()) != '\n' && c != CR) {
+       switch (c) {
+       case ESC:
+           move(y, x);
+           clrtoeol();
+           refresh();
+           return GS_ESCAPE;
+       case DEL:
+       case '\b':
+           if (i > 0) {
+               str[--i] = 0;
+               mvaddch(y, x+i, ' ');
+               move(y, x+i);
+           } else if (use_def) {
+               clrtoeol();
+               use_def = FALSE;
+           } else
+               putchar(BELL);
+           break;
+       default:
+           if (i < len && isprint(c)) {
+               mvaddch(y, x+i, c);
+               if (use_def) {
+                   clrtoeol();
+                   use_def = FALSE;
+               }
+               str[i++] = c;
+               str[i] = 0;
+           } else
+               putchar(BELL);
+       }
+       refresh();
+    }
+
+    if (use_def)
+       return GS_DEFAULT;
+    else
+       return i;
+}
+
+void clear_warning(void)
+{
+    int i;
+
+    if (!warning_last_time)
+       return;
+
+    move(WARNING_START,0);
+    for (i = 0; i < COLS; i++)
+       addch(' ');
+
+    warning_last_time = FALSE;
+}
+
+void print_warning(char *s)
+{
+    mvaddstr(WARNING_START, (COLS-strlen(s))/2, s);
+    putchar(BELL); /* CTRL-G */
+
+    warning_last_time = TRUE;
+}
+
+void fatal(char *s)
+{
+    char str[LINE_LENGTH];
+
+    sprintf(str, "FATAL ERROR: %s", s);
+    mvaddstr(WARNING_START, (COLS-strlen(str))/2, str);
+    sprintf(str, "Press any key to exit fdisk");
+    mvaddstr(WARNING_START+1, (COLS-strlen(str))/2, str);
+    putchar(BELL); /* CTRL-G */
+
+    refresh();
+
+    (void)getch();
+
+    signal(SIGINT, old_SIGINT);
+    signal(SIGTERM, old_SIGTERM);
+    mvcur(0, COLS-1, LINES-1, 0);
+    nl();
+    endwin();
+    fdexit(1);
+}
+
+void read_sector(char *buffer, int sect_num)
+{
+    if (ext2_llseek(fd, sect_num*SECTOR_SIZE, SEEK_SET) < 0)
+       fatal(BAD_SEEK);
+    if (read(fd, buffer, SECTOR_SIZE) != SECTOR_SIZE)
+       fatal(BAD_READ);
+}
+
+void write_sector(char *buffer, int sect_num)
+{
+    if (ext2_llseek(fd, sect_num*SECTOR_SIZE, SEEK_SET) < 0)
+       fatal(BAD_SEEK);
+    if (write(fd, buffer, SECTOR_SIZE) != SECTOR_SIZE)
+       fatal(BAD_WRITE);
+}
+
+void check_part_info(void)
+{
+    int i, pri = 0, log = 0;
+
+    for (i = 0; i < num_parts; i++)
+       if (p_info[i].id > 0 && IS_PRIMARY(p_info[i].num))
+           pri++;
+       else if (p_info[i].id > 0 && IS_LOGICAL(p_info[i].num))
+           log++;
+    if (ext_info.id == EXTENDED)
+       if (log > 0)
+           pri++;
+       else {
+           ext_info.first_sector = 0;
+           ext_info.last_sector = 0;
+           ext_info.offset = 0;
+           ext_info.flags = 0;
+           ext_info.id = FREE_SPACE;
+           ext_info.num = PRIMARY;
+       }
+
+    if (pri >= 4)
+       for (i = 0; i < num_parts; i++)
+           if (p_info[i].id == FREE_SPACE || p_info[i].id == UNUSABLE)
+               if (ext_info.id == EXTENDED)
+                   if (p_info[i].first_sector >= ext_info.first_sector &&
+                       p_info[i].last_sector <= ext_info.last_sector) {
+                       p_info[i].id = FREE_SPACE;
+                       p_info[i].num = LOGICAL;
+                   } else if (i > 0 &&
+                              p_info[i-1].first_sector >=
+                              ext_info.first_sector &&
+                              p_info[i-1].last_sector <=
+                              ext_info.last_sector) {
+                       p_info[i].id = FREE_SPACE;
+                       p_info[i].num = LOGICAL;
+                   } else if (i < num_parts-1 &&
+                              p_info[i+1].first_sector >=
+                              ext_info.first_sector &&
+                              p_info[i+1].last_sector <=
+                              ext_info.last_sector) {
+                       p_info[i].id = FREE_SPACE;
+                       p_info[i].num = LOGICAL;
+                   } else
+                       p_info[i].id = UNUSABLE;
+               else /* if (ext_info.id != EXTENDED) */
+                   p_info[i].id = UNUSABLE;
+           else /* if (p_info[i].id > 0) */
+               while (0); /* Leave these alone */
+    else /* if (pri < 4) */
+       for (i = 0; i < num_parts; i++) {
+           if (p_info[i].id == UNUSABLE)
+               p_info[i].id = FREE_SPACE;
+           if (p_info[i].id == FREE_SPACE)
+               if (ext_info.id == EXTENDED)
+                   if (p_info[i].first_sector >= ext_info.first_sector &&
+                       p_info[i].last_sector <= ext_info.last_sector)
+                       p_info[i].num = LOGICAL;
+                   else if (i > 0 &&
+                            p_info[i-1].first_sector >=
+                            ext_info.first_sector &&
+                            p_info[i-1].last_sector <=
+                            ext_info.last_sector)
+                       p_info[i].num = PRI_OR_LOG;
+                   else if (i < num_parts-1 &&
+                            p_info[i+1].first_sector >=
+                            ext_info.first_sector &&
+                            p_info[i+1].last_sector <=
+                            ext_info.last_sector)
+                       p_info[i].num = PRI_OR_LOG;
+                   else
+                       p_info[i].num = PRIMARY;
+               else /* if (ext_info.id != EXTENDED) */
+                   p_info[i].num = PRI_OR_LOG;
+           else /* if (p_info[i].id > 0) */
+               while (0); /* Leave these alone */
+       }
+}
+
+void remove_part(int i)
+{
+    int p;
+
+    for (p = i; p < num_parts; p++)
+       p_info[p] = p_info[p+1];
+
+    num_parts--;
+}
+
+void insert_part(int i, int num, int id, int flags, int first, int last,
+                int offset)
+{
+    int p;
+
+    for (p = num_parts; p > i; p--)
+        p_info[p] = p_info[p-1];
+
+    p_info[i].first_sector = first;
+    p_info[i].last_sector = last;
+    p_info[i].offset = offset;
+    p_info[i].flags = flags;
+    p_info[i].id = id;
+    p_info[i].num = num;
+
+    num_parts++;
+}
+
+void del_part(int i)
+{
+    int num = p_info[i].num;
+
+    if (i > 0 && (p_info[i-1].id == FREE_SPACE ||
+                 p_info[i-1].id == UNUSABLE)) {
+       /* Merge with previous partition */
+       p_info[i-1].last_sector = p_info[i].last_sector;
+       remove_part(i--);
+    }
+
+    if (i < num_parts - 1 && (p_info[i+1].id == FREE_SPACE ||
+                             p_info[i+1].id == UNUSABLE)) {
+       /* Merge with next partition */
+       p_info[i+1].first_sector = p_info[i].first_sector;
+       remove_part(i);
+    }
+
+    if (i > 0)
+       p_info[i].first_sector = p_info[i-1].last_sector + 1;
+    else
+       p_info[i].first_sector = 0;
+
+    if (i < num_parts - 1)
+       p_info[i].last_sector = p_info[i+1].first_sector - 1;
+    else
+       p_info[i].last_sector = sectors*heads*cylinders - 1;
+
+    p_info[i].offset = 0;
+    p_info[i].flags = 0;
+    p_info[i].id = FREE_SPACE;
+    p_info[i].num = PRI_OR_LOG;
+
+    if (IS_LOGICAL(num)) {
+       /* We have a logical partition --> shrink the extended partition
+        * if (1) this is the first logical drive, or (2) this is the
+        * last logical drive; and if there are any other logical drives
+        * then renumber the ones after "num".
+        */
+       if (i == 0 || (i > 0 && IS_PRIMARY(p_info[i-1].num)))
+           ext_info.first_sector = p_info[i].last_sector + 1;
+       if (i == num_parts-1 ||
+           (i < num_parts-1 && IS_PRIMARY(p_info[i+1].num)))
+           ext_info.last_sector = p_info[i].first_sector - 1;
+       for (i = 0; i < num_parts; i++)
+           if (p_info[i].num > num)
+               p_info[i].num--;
+    }
+
+    /* Clean up the rest of the partitions */
+    check_part_info();
+}
+
+int add_part(int num, int id, int flags, int first, int last, int offset)
+{
+    int i, pri = 0, log = 0;
+
+    if (num_parts == MAXIMUM_PARTS ||
+       first < 0 ||
+       first >= cylinders*heads*sectors ||
+       last < 0 ||
+       last >= cylinders*heads*sectors)
+       return -1;
+
+    for (i = 0; i < num_parts; i++)
+       if (p_info[i].id > 0 && IS_PRIMARY(p_info[i].num))
+           pri++;
+       else if (p_info[i].id > 0 && IS_LOGICAL(p_info[i].num))
+           log++;
+    if (ext_info.id == EXTENDED && log > 0)
+       pri++;
+
+    if (IS_PRIMARY(num))
+       if (pri >= 4)
+           return -1;
+       else
+           pri++;
+
+    for (i = 0; p_info[i].last_sector < first; i++);
+
+    if (p_info[i].id != FREE_SPACE || last > p_info[i].last_sector)
+       return -1;
+
+    if (id == EXTENDED)
+       if (ext_info.id != FREE_SPACE)
+           return -1;
+       else if (IS_PRIMARY(num)) {
+           ext_info.first_sector = first;
+           ext_info.last_sector = last;
+           ext_info.offset = offset;
+           ext_info.flags = flags;
+           ext_info.id = EXTENDED;
+           ext_info.num = num;
+
+           return 0;
+       } else
+           return -1;
+
+    if (IS_LOGICAL(num)) {
+       if (ext_info.id != EXTENDED) {
+           print_warning("!!!! Internal error creating logical "
+                         "drive with no extended partition !!!!");
+       } else {
+           /* We might have a logical partition outside of the extended
+            * partition's range --> we have to extend the extended
+            * partition's range to encompass this new partition, but we
+            * must make sure that there are no primary partitions between
+            * it and the closest logical drive in extended partition.
+            */
+           if (first < ext_info.first_sector) {
+               if (i < num_parts-1 && IS_PRIMARY(p_info[i+1].num)) {
+                   print_warning(TWO_EXTENDEDS);
+                   return -1;
+               } else {
+                   if (first == 0) {
+                       ext_info.first_sector = 0;
+                       ext_info.offset = first = offset;
+                   } else
+                       ext_info.first_sector = first;
+               }
+           } else if (last > ext_info.last_sector) {
+               if (i > 0 && IS_PRIMARY(p_info[i-1].num)) {
+                   print_warning(TWO_EXTENDEDS);
+                   return -1;
+               } else
+                   ext_info.last_sector = last;
+           }
+       }
+    }
+
+    if (first != p_info[i].first_sector &&
+       !(IS_LOGICAL(num) && first == offset)) {
+       insert_part(i, PRI_OR_LOG, FREE_SPACE, 0,
+                   p_info[i].first_sector, first-1, 0);
+       i++;
+    }
+
+    if (last != p_info[i].last_sector)
+       insert_part(i+1, PRI_OR_LOG, FREE_SPACE, 0,
+                   last+1, p_info[i].last_sector, 0);
+
+    p_info[i].first_sector = first;
+    p_info[i].last_sector = last;
+    p_info[i].offset = offset;
+    p_info[i].flags = flags;
+    p_info[i].id = id;
+    p_info[i].num = num;
+
+    check_part_info();
+
+    return 0;
+}
+
+int find_primary(void)
+{
+    int num = 0, cur = 0;
+
+    while (cur < num_parts && IS_PRIMARY(num))
+       if ((p_info[cur].id > 0 && p_info[cur].num == num) ||
+           (ext_info.id == EXTENDED && ext_info.num == num)) {
+           num++;
+           cur = 0;
+       } else
+           cur++;
+
+    if (!IS_PRIMARY(num))
+       return -1;
+    else
+       return num;
+}
+
+int find_logical(int i)
+{
+    int num = -1;
+    int j;
+
+    for (j = i; j < num_parts && num == -1; j++)
+       if (p_info[j].id > 0 && IS_LOGICAL(p_info[j].num))
+           num = p_info[j].num;
+
+    if (num == -1) {
+       num = 4;
+       for (j = 0; j < num_parts; j++)
+           if (p_info[j].id > 0 && p_info[j].num == num)
+               num++;
+    }
+
+    return num;
+}
+
+void inc_logical(int i)
+{
+    int j;
+
+    for (j = i; j < num_parts; j++)
+       if (p_info[j].id > 0 && IS_LOGICAL(p_info[j].num))
+           p_info[j].num++;
+}
+
+void new_part(int i)
+{
+    char response[LINE_LENGTH], def[LINE_LENGTH];
+    char c;
+    int first = p_info[i].first_sector;
+    int last = p_info[i].last_sector;
+    int offset = 0;
+    int flags = 0;
+    int id = LINUX;
+    int num = -1;
+    int num_sects = last - first + 1;
+    int len, ext, j;
+
+    if (p_info[i].num == PRI_OR_LOG) {
+       mvaddstr(COMMAND_LINE_Y, COMMAND_LINE_X, "Primary or logical [pl]: ");
+       clrtoeol();
+       refresh();
+       while (toupper(c = getch()) != 'P' && toupper(c) != 'L' && c != ESC);
+       if (toupper(c) == 'P')
+           num = find_primary();
+       else if (toupper(c) == 'L')
+           num = find_logical(i);
+       else
+           return;
+    } else if (p_info[i].num == PRIMARY)
+       num = find_primary();
+    else if (p_info[i].num == LOGICAL)
+       num = find_logical(i);
+    else
+       print_warning("!!! Internal error !!!");
+
+    sprintf(def, "%.2f", ceiling(num_sects/20.48)/100);
+    mvaddstr(COMMAND_LINE_Y, COMMAND_LINE_X, "Size (in MB): ");
+    if ((len = get_string(response, LINE_LENGTH, def)) <= 0 &&
+       len != GS_DEFAULT)
+       return;
+    else if (len > 0) {
+#define num_cyls(bytes) (round_int(bytes/SECTOR_SIZE/(sectors*heads)))
+       for (j = 0;
+            j < len-1 && (isdigit(response[j]) || response[j] == '.');
+            j++);
+       if (toupper(response[j]) == 'K') {
+           num_sects = num_cyls(atof(response)*1024)*sectors*heads;
+       } else if (toupper(response[j]) == 'M') {
+           num_sects = num_cyls(atof(response)*1024*1024)*sectors*heads;
+       } else if (toupper(response[j]) == 'C') {
+           num_sects = round_int(atof(response))*sectors*heads;
+       } else if (toupper(response[j]) == 'S') {
+           num_sects = round_int(atof(response));
+       } else {
+           num_sects = num_cyls(atof(response)*1024*1024)*sectors*heads;
+       }
+    }
+
+    if (num_sects <= 0 ||
+       num_sects > p_info[i].last_sector - p_info[i].first_sector + 1)
+       return;
+
+    if (num_sects < p_info[i].last_sector - p_info[i].first_sector + 1) {
+       /* Determine where inside free space to put partition.
+        */
+       mvaddstr(COMMAND_LINE_Y, COMMAND_LINE_X,
+                "Add partition at beginning or end of free space [be]: ");
+       clrtoeol();
+       refresh();
+       while (toupper(c = getch()) != 'B' && toupper(c) != 'E' && c != ESC);
+       if (toupper(c) == 'B')
+           last = first + num_sects - 1;
+       else if (toupper(c) == 'E')
+           first = last - num_sects + 1;
+       else
+           return;
+    }
+
+    if (IS_LOGICAL(num) && ext_info.id != EXTENDED) {
+       /* We want to add a logical partition, but need to create an
+        * extended partition first.
+        */
+       if ((ext = find_primary()) < 0) {
+           print_warning(NEED_EXT);
+           return;
+       }
+       (void)add_part(ext, EXTENDED, 0, first, last,
+                      (first == 0 ? sectors : 0));
+    }
+
+    if (IS_LOGICAL(num))
+       inc_logical(i);
+
+    /* Now we have a complete partition to ourselves */
+    if (first == 0 || IS_LOGICAL(num))
+       offset = sectors;
+
+    (void)add_part(num, id, flags, first, last, offset);
+}
+
+void clear_p_info(void)
+{
+    num_parts = 1;
+    p_info[0].first_sector = 0;
+    p_info[0].last_sector = sectors*heads*cylinders - 1;
+    p_info[0].offset = 0;
+    p_info[0].flags = 0;
+    p_info[0].id = FREE_SPACE;
+    p_info[0].num = PRI_OR_LOG;
+
+    ext_info.first_sector = 0;
+    ext_info.last_sector = 0;
+    ext_info.offset = 0;
+    ext_info.flags = 0;
+    ext_info.id = FREE_SPACE;
+    ext_info.num = PRIMARY;
+}
+
+void fill_p_info(void)
+{
+    int p, i;
+    struct hd_geometry geometry;
+    partition_table buffer;
+    partition_info tmp_ext = { 0, 0, 0, 0, FREE_SPACE, PRIMARY };
+
+    if ((fd = open(disk_device, O_RDWR)) < 0)
+       fatal(BAD_OPEN);
+    read_sector(buffer.c.b, 0);
+
+    if (!ioctl(fd, HDIO_GETGEO, &geometry)) {
+       if (!heads)
+           heads = geometry.heads;
+       if (!sectors)
+           sectors = geometry.sectors;
+       if (!cylinders)
+           cylinders = geometry.cylinders;
+    }
+
+    if (!heads || !sectors || !cylinders)
+       fatal(BAD_GEOMETRY);
+
+    clear_p_info();
+
+    if (!zero_table) {
+       for (i = 0; i < 4; i++) {
+           if (buffer.p.part[i].sys_ind > 0 &&
+               add_part(i,
+                        buffer.p.part[i].sys_ind,
+                        buffer.p.part[i].boot_ind,
+                        ((buffer.p.part[i].start_sect <= sectors) ?
+                         0 : buffer.p.part[i].start_sect),
+                        buffer.p.part[i].start_sect +
+                        buffer.p.part[i].nr_sects - 1,
+                        ((buffer.p.part[i].start_sect <= sectors) ?
+                         buffer.p.part[i].start_sect : 0))) {
+               fatal(BAD_PRIMARY);
+           }
+           if (buffer.p.part[i].sys_ind == EXTENDED)
+               tmp_ext = ext_info;
+       }
+
+       if (tmp_ext.id == EXTENDED) {
+           ext_info = tmp_ext;
+           logical_sectors[logical] = ext_info.first_sector;
+           read_sector(buffer.c.b, logical_sectors[logical++]);
+           i = 4;
+           do {
+               for (p = 0;
+                    p < 4 && (!buffer.p.part[p].sys_ind ||
+                              buffer.p.part[p].sys_ind == 5);
+                    p++);
+               if (p > 3)
+                   fatal(BAD_LOGICAL);
+
+               if (add_part(i++,
+                            buffer.p.part[p].sys_ind,
+                            buffer.p.part[p].boot_ind,
+                            logical_sectors[logical-1],
+                            logical_sectors[logical-1] +
+                            buffer.p.part[p].start_sect +
+                            buffer.p.part[p].nr_sects - 1,
+                            buffer.p.part[p].start_sect)) {
+                   fatal(BAD_LOGICAL);
+               }
+
+               for (p = 0;
+                    p < 4 && buffer.p.part[p].sys_ind != 5;
+                    p++);
+               if (p < 4) {
+                   logical_sectors[logical] =
+                       ext_info.first_sector + buffer.p.part[p].start_sect;
+                   read_sector(buffer.c.b, logical_sectors[logical++]);
+               }
+           } while (p < 4 && logical < MAXIMUM_PARTS-4);
+       }
+    }
+}
+
+void fill_part_table(struct partition *p, partition_info *pi)
+{
+    int sects;
+
+    p->boot_ind = pi->flags;
+    p->sys_ind = pi->id;
+    if (IS_LOGICAL(pi->num))
+       p->start_sect = pi->offset;
+    else
+       p->start_sect = pi->first_sector + pi->offset;
+    p->nr_sects = pi->last_sector - (pi->first_sector+pi->offset) + 1;
+    sects = (((pi->first_sector+pi->offset)/(sectors*heads) > 1023) ?
+            heads*sectors*1024 - 1 : pi->first_sector+pi->offset);
+    set_hsc(p->head, p->sector, p->cyl, sects);
+    sects = ((pi->last_sector/(sectors*heads) > 1023) ?
+            heads*sectors*1024 - 1 : pi->last_sector);
+    set_hsc(p->end_head, p->end_sector, p->end_cyl, sects);
+}
+
+void fill_primary_table(partition_table *buffer)
+{
+    int i;
+
+    /* Zero out existing table */
+    for (i = 0x1BE; i < SECTOR_SIZE; i++)
+       buffer->c.b[i] = 0;
+
+    for (i = 0; i < num_parts; i++)
+       if (IS_PRIMARY(p_info[i].num))
+           fill_part_table(&(buffer->p.part[p_info[i].num]), &(p_info[i]));
+
+    if (ext_info.id == EXTENDED)
+       fill_part_table(&(buffer->p.part[ext_info.num]), &ext_info);
+
+    buffer->p.flag = PART_TABLE_FLAG;
+}
+
+void fill_logical_table(partition_table *buffer, partition_info *pi)
+{
+    struct partition *p;
+    int i, sects;
+
+    for (i = 0; i < logical && pi->first_sector != logical_sectors[i]; i++);
+    if (i == logical || buffer->p.flag != (unsigned short)PART_TABLE_FLAG)
+       for (i = 0; i < SECTOR_SIZE; i++)
+           buffer->c.b[i] = 0;
+
+    /* Zero out existing table */
+    for (i = 0x1BE; i < SECTOR_SIZE; i++)
+       buffer->c.b[i] = 0;
+
+    fill_part_table(&(buffer->p.part[0]), pi);
+
+    for (i = 0;
+        i < num_parts && pi->num != p_info[i].num - 1;
+        i++);
+
+    if (i < num_parts) {
+       p = &(buffer->p.part[1]);
+       pi = &(p_info[i]);
+
+       p->boot_ind = 0;
+       p->sys_ind = 5;
+       p->start_sect = pi->first_sector - ext_info.first_sector;
+       p->nr_sects = pi->last_sector - pi->first_sector + 1;
+       sects = ((pi->first_sector/(sectors*heads) > 1023) ?
+                heads*sectors*1024 - 1 : pi->first_sector);
+       set_hsc(p->head, p->sector, p->cyl, sects);
+       sects = ((pi->last_sector/(sectors*heads) > 1023) ?
+                heads*sectors*1024 - 1 : pi->last_sector);
+       set_hsc(p->end_head, p->end_sector, p->end_cyl, sects);
+    }
+
+    buffer->p.flag = PART_TABLE_FLAG;
+}
+
+void write_part_table(void)
+{
+    int i, done = FALSE, len;
+    partition_table buffer;
+    char response[LINE_LENGTH];
+
+    print_warning(WRITE_WARN);
+
+    while (!done) {
+       mvaddstr(COMMAND_LINE_Y, COMMAND_LINE_X,
+                "Are you sure you want write the partition table to disk? (yes or no): ");
+       
+       len = get_string(response, LINE_LENGTH, NULL);
+
+       clear_warning();
+
+       if (len == GS_ESCAPE)
+           return;
+       else if (len == 2 &&
+                toupper(response[0]) == 'N' &&
+                toupper(response[1]) == 'O') {
+           print_warning(NO_WRITE);
+           return;
+       } else if (len == 3 &&
+                  toupper(response[0]) == 'Y' &&
+                  toupper(response[1]) == 'E' &&
+                  toupper(response[2]) == 'S')
+           done = TRUE;
+       else
+           print_warning(YES_NO);
+    }
+
+    clear_warning();
+    print_warning(WRITING_PART);
+    refresh();
+    
+    read_sector(buffer.c.b, 0);
+    fill_primary_table(&buffer);
+    write_sector(buffer.c.b, 0);
+
+    for (i = 0; i < num_parts; i++)
+       if (IS_LOGICAL(p_info[i].num)) {
+           /* Read the extended partition table from disk ??? KEM */
+           read_sector(buffer.c.b, p_info[i].first_sector);
+           fill_logical_table(&buffer, &(p_info[i]));
+           write_sector(buffer.c.b, p_info[i].first_sector);
+       }
+
+    sync();
+    sleep(2);
+    if (!ioctl(fd,BLKRRPART))
+       changed = TRUE;
+    sync();
+    sleep(4);
+
+    clear_warning();
+    if (changed)
+       print_warning(YES_WRITE);
+    else
+       print_warning(RRPART_FAILED);
+}
+
+void fp_printf(FILE *fp, char *format, ...)
+{
+    va_list args;
+    char buf[1024];
+    int y, x;
+
+    va_start(args, format);
+    vsprintf(buf, format, args);
+    va_end(args);
+
+    if (fp == NULL) {
+       /* The following works best if the string to be printed has at
+           most only one newline. */
+       printw("%s", buf);
+       getyx(stdscr, y, x);
+       if (y >= COMMAND_LINE_Y-2) {
+           mvaddstr(COMMAND_LINE_Y, COMMAND_LINE_X,
+                    "Press any key to continue...");
+           clrtoeol();
+           refresh();
+           (void)getch();
+           erase();
+           move(0, 0);
+       }
+    } else
+       fprintf(fp, "%s", buf);
+}
+
+#define MAX_PER_LINE 16
+void print_file_buffer(FILE *fp, char *buffer)
+{
+    int i,l;
+
+    for (i = 0, l = 0; i < SECTOR_SIZE; i++, l++) {
+       if (l == 0)
+           fp_printf(fp, "0x%03X:", i);
+       fp_printf(fp, " %02X", (unsigned char) buffer[i]);
+       if (l == MAX_PER_LINE - 1) {
+           fp_printf(fp, "\n");
+           l = -1;
+       }
+    }
+    if (l > 0)
+       fp_printf(fp, "\n");
+    fp_printf(fp, "\n");
+}
+
+void print_raw_table(void)
+{
+    int i, to_file;
+    partition_table buffer;
+    char fname[LINE_LENGTH];
+    FILE *fp;
+
+    if (print_only) {
+       fp = stdout;
+       to_file = TRUE;
+    } else {
+       mvaddstr(COMMAND_LINE_Y, COMMAND_LINE_X,
+                "Enter filename or press RETURN to display on screen: ");
+
+       if ((to_file = get_string(fname, LINE_LENGTH, NULL)) < 0)
+           return;
+
+       if (to_file) {
+           if ((fp = fopen(fname, "w")) == NULL) {
+               char errstr[LINE_LENGTH];
+               sprintf(errstr, PRINT_OPEN_ERR, fname);
+               print_warning(errstr);
+               return;
+           }
+       } else {
+           fp = NULL;
+           erase();
+           move(0, 0);
+       }
+    }
+
+    fp_printf(fp, "Disk Drive: %s\n", disk_device);
+
+    read_sector(buffer.c.b, 0);
+    fill_primary_table(&buffer);
+    print_file_buffer(fp, buffer.c.b);
+
+    for (i = 0; i < num_parts; i++)
+       if (IS_LOGICAL(p_info[i].num)) {
+           read_sector(buffer.c.b, p_info[i].first_sector);
+           fill_logical_table(&buffer, &(p_info[i]));
+           print_file_buffer(fp, buffer.c.b);
+       }
+
+    if (to_file) {
+       if (!print_only)
+           fclose(fp);
+    } else {
+       mvaddstr(COMMAND_LINE_Y, COMMAND_LINE_X,
+                "Press any key to continue...");
+       clrtoeol();
+       refresh();
+       (void)getch();
+    }
+}
+
+void print_p_info_entry(FILE *fp, partition_info *p)
+{
+    int size;
+    char part_str[21];
+
+    if (p->id == UNUSABLE)
+       fp_printf(fp, "   None   ");
+    else if (p->id == FREE_SPACE && p->num == PRI_OR_LOG)
+       fp_printf(fp, "   Pri/Log");
+    else if (p->id == FREE_SPACE && p->num == PRIMARY)
+       fp_printf(fp, "   Primary");
+    else if (p->id == FREE_SPACE && p->num == LOGICAL)
+       fp_printf(fp, "   Logical");
+    else
+       fp_printf(fp, "%2d %-7.7s", p->num+1,
+                 IS_LOGICAL(p->num) ? "Logical" : "Primary");
+
+    fp_printf(fp, " ");
+
+    fp_printf(fp, "%7d%c", p->first_sector,
+             ((p->first_sector/(sectors*heads)) !=
+              ((float)p->first_sector/(sectors*heads)) ?
+              '*' : ' '));
+
+    fp_printf(fp, " ");
+
+    fp_printf(fp, "%7d%c", p->last_sector,
+             (((p->last_sector+1)/(sectors*heads)) !=
+              ((float)(p->last_sector+1)/(sectors*heads)) ?
+              '*' : ' '));
+
+    fp_printf(fp, " ");
+
+    fp_printf(fp, "%6d%c", p->offset,
+             ((((p->first_sector == 0 || IS_LOGICAL(p->num)) &&
+                (p->offset != sectors)) ||
+               (p->first_sector != 0 && IS_PRIMARY(p->num) &&
+                p->offset != 0)) ?
+              '#' : ' '));
+
+    fp_printf(fp, " ");
+
+    size = p->last_sector - p->first_sector + 1;
+    fp_printf(fp, "%7d%c", size,
+             ((size/(sectors*heads)) != ((float)size/(sectors*heads)) ?
+              '*' : ' '));
+
+    fp_printf(fp, " ");
+
+    if (p->id == UNUSABLE)
+       sprintf(part_str, "%.16s", "Unusable");
+    else if (p->id == FREE_SPACE)
+       sprintf(part_str, "%.16s", "Free Space");
+    else if (partition_type[p->id])
+       sprintf(part_str, "%.16s (%02X)", partition_type[p->id], p->id);
+    else
+       sprintf(part_str, "%.16s (%02X)", "Unknown", p->id);
+    fp_printf(fp, "%-21.21s", part_str);
+
+    fp_printf(fp, " ");
+
+    if (p->flags == ACTIVE_FLAG)
+       fp_printf(fp, "Boot (%02X)", p->flags);
+    else if (p->flags != 0)
+       fp_printf(fp, "Unknown (%02X)", p->flags);
+    else
+       fp_printf(fp, "None (%02X)", p->flags);
+
+    fp_printf(fp, "\n");
+}
+
+void print_p_info(void)
+{
+    char fname[LINE_LENGTH];
+    FILE *fp;
+    int i, to_file, pext = (ext_info.id == EXTENDED);
+
+    if (print_only) {
+       fp = stdout;
+       to_file = TRUE;
+    } else {
+       mvaddstr(COMMAND_LINE_Y, COMMAND_LINE_X,
+                "Enter filename or press RETURN to display on screen: ");
+
+       if ((to_file = get_string(fname, LINE_LENGTH, NULL)) < 0)
+           return;
+
+       if (to_file) {
+           if ((fp = fopen(fname, "w")) == NULL) {
+               char errstr[LINE_LENGTH];
+               sprintf(errstr, PRINT_OPEN_ERR, fname);
+               print_warning(errstr);
+               return;
+           }
+       } else {
+           fp = NULL;
+           erase();
+           move(0, 0);
+       }
+    }
+
+    fp_printf(fp, "Partition Table for %s\n", disk_device);
+    fp_printf(fp, "\n");
+    fp_printf(fp, "           First    Last\n");
+    fp_printf(fp, " # Type    Sector   Sector   Offset  Length   Filesystem Type (ID)  Flags\n");
+    fp_printf(fp, "-- ------- -------- -------- ------- -------- --------------------- ---------\n");
+
+    for (i = 0; i < num_parts; i++) {
+       if (pext && (p_info[i].first_sector >= ext_info.first_sector)) {
+           print_p_info_entry(fp,&ext_info);
+           pext = FALSE;
+       }
+       print_p_info_entry(fp, &(p_info[i]));
+    }
+
+    if (to_file) {
+       if (!print_only)
+           fclose(fp);
+    } else {
+       mvaddstr(COMMAND_LINE_Y, COMMAND_LINE_X,
+                "Press any key to continue...");
+       clrtoeol();
+       refresh();
+       (void)getch();
+    }
+}
+
+void print_part_entry(FILE *fp, int num, partition_info *pi)
+{
+    int first = 0, start = 0, end = 0, size = 0;
+    int ss = 0, sh = 0, sc = 0;
+    int es = 0, eh = 0, ec = 0;
+    int flags = 0, id = 0;
+
+    if (pi != NULL) {
+       flags = pi->flags;
+       id = pi->id;
+
+       if (IS_LOGICAL(num))
+           first = pi->offset;
+       else
+           first = pi->first_sector + pi->offset;
+
+       start = pi->first_sector + pi->offset;
+       end = pi->last_sector;
+       size = end - start + 1;
+       if ((start/(sectors*heads)) > 1023)
+           start = heads*sectors*1024 - 1;
+       if ((end/(sectors*heads)) > 1023)
+           end = heads*sectors*1024 - 1;
+
+       ss = start % sectors + 1;
+       start /= sectors;
+       sh = start % heads;
+       sc = start / heads;
+
+       es = end % sectors + 1;
+       end /= sectors;
+       eh = end % heads;
+       ec = end / heads;
+    }
+
+    fp_printf(fp, "%2d  0x%02X %4d %4d %4d 0x%02X %4d %4d %4d %7d %7d\n",
+             num+1, flags, sh, ss, sc, id, eh, es, ec, first, size);
+}
+
+
+void print_part_table(void)
+{
+    int i, j, to_file;
+    char fname[LINE_LENGTH];
+    FILE *fp;
+
+    if (print_only) {
+       fp = stdout;
+       to_file = TRUE;
+    } else {
+       mvaddstr(COMMAND_LINE_Y, COMMAND_LINE_X,
+                "Enter filename or press RETURN to display on screen: ");
+
+       if ((to_file = get_string(fname, LINE_LENGTH, NULL)) < 0)
+           return;
+
+       if (to_file) {
+           if ((fp = fopen(fname, "w")) == NULL) {
+               char errstr[LINE_LENGTH];
+               sprintf(errstr, PRINT_OPEN_ERR, fname);
+               print_warning(errstr);
+               return;
+           }
+       } else {
+           fp = NULL;
+           erase();
+           move(0, 0);
+       }
+    }
+
+    fp_printf(fp, "Partition Table for %s\n", disk_device);
+    fp_printf(fp, "\n");
+    fp_printf(fp, "         ---Starting---      ----Ending---- Start   Number\n");
+    fp_printf(fp, " # Flags Head Sect Cyl   ID  Head Sect Cyl  Sector  Sectors\n");
+    fp_printf(fp, "-- ----- ---- ---- ---- ---- ---- ---- ---- ------- -------\n");
+
+    for (i = 0; i < 4; i++) {
+       for (j = 0;
+            j < num_parts && (p_info[j].id <= 0 || p_info[j].num != i);
+            j++);
+       if (j < num_parts) {
+           print_part_entry(fp, i, &(p_info[j]));
+       } else if (ext_info.id == EXTENDED && ext_info.num == i) {
+           print_part_entry(fp, i, &ext_info);
+       } else {
+           print_part_entry(fp, i, NULL);
+       }
+    }
+
+    for (i = 0; i < num_parts; i++)
+       if (IS_LOGICAL(p_info[i].num))
+           print_part_entry(fp, p_info[i].num, &(p_info[i]));
+
+    if (to_file) {
+       if (!print_only)
+           fclose(fp);
+    } else {
+       mvaddstr(COMMAND_LINE_Y, COMMAND_LINE_X,
+                "Press any key to continue...");
+       clrtoeol();
+       refresh();
+       (void)getch();
+    }
+}
+
+void print_tables(void)
+{
+    int done = FALSE;
+
+    mvaddstr(COMMAND_LINE_Y, COMMAND_LINE_X, "Print format [rst]: ");
+    clrtoeol();
+    refresh();
+
+    while (!done)
+       switch (toupper(getch())) {
+       case 'R':
+           print_raw_table();
+           done = TRUE;
+           break;
+       case 'S':
+           print_p_info();
+           done = TRUE;
+           break;
+       case 'T':
+           print_part_table();
+           done = TRUE;
+           break;
+       case ESC:
+           done = TRUE;
+           break;
+       }
+}
+
+#define END_OF_HELP "EOHS!"
+#define NEW_HELP_SCREEN "SNHS!"
+void display_help()
+{
+    char *help_text[] = {
+       "Help Screen for cfdisk " VERSION,
+       "",
+       "This is cfdisk, a curses based disk partitioning programs, which",
+       "allows you to create, delete and modify partitions on your hard",
+       "disk drive.",
+       "",
+       "Copyright (C) 1994 Kevin E. Martin",
+       "",
+       "Command      Meaning",
+       "-------      -------",
+       "  b          Toggle bootable flag of the current partition",
+       "  d          Delete the current partition",
+       "  g          Change cylinders, heads, sectors-per-track parameters",
+       "             WARNING: This option should only be used by people who",
+       "             know what they are doing.",
+       "  h          Print this screen",
+       "  m          Maximize disk usage of the current partition",
+       "             Note: This may make the partition incompatible with",
+       "             DOS, OS/2, ...",
+       "  n          Create new partition from free space",
+       "  p          Print partition table to the screen or to a file",
+       "             There are several different formats for the partition",
+       "             that you can choose from:",
+       "                r - Raw data (exactly what would be written to disk)",
+       "                s - Table ordered by sectors",
+       "                t - Table in raw format",
+       "  q          Quit program without writing partition table",
+       "  t          Change the filesystem type",
+       "  u          Change units of the partition size display",
+       "             Rotates through Mb, sectors and cylinders",
+       "  W          Write partition table to disk (must enter upper case W)",
+        "             Since this might destroy data on the disk, you must",
+       "             either confirm or deny the write by entering `yes' or",
+       "             `no'",
+       "Up Arrow     Move cursor to the previous partition",
+       "Down Arrow   Move cursor to the next partition",
+       "CTRL-L       Redraws the screen",
+       "  ?          Print this screen",
+       "",
+       "Note: All of the commands can be entered with either upper or lower",
+       "case letters (except for Writes).",
+       END_OF_HELP
+    };
+
+    int cur_line = 0;
+    FILE *fp = NULL;
+
+    erase();
+    move(0, 0);
+    while (strcmp(help_text[cur_line], END_OF_HELP))
+       if (!strcmp(help_text[cur_line], NEW_HELP_SCREEN)) {
+           mvaddstr(COMMAND_LINE_Y, COMMAND_LINE_X,
+                    "Press any key to continue...");
+           clrtoeol();
+           refresh();
+           (void)getch();
+           erase();
+           move(0, 0);
+           cur_line++;
+       } else
+           fp_printf(fp, "%s\n", help_text[cur_line++]);
+
+    mvaddstr(COMMAND_LINE_Y, COMMAND_LINE_X,
+            "Press any key to continue...");
+    clrtoeol();
+    refresh();
+    (void)getch();
+}
+
+int change_geometry(void)
+{
+    int ret_val = FALSE;
+    int done = FALSE;
+    char def[LINE_LENGTH];
+    char response[LINE_LENGTH];
+    int tmp_val;
+
+    while (!done) {
+       mvaddstr(COMMAND_LINE_Y, COMMAND_LINE_X,
+                "Change disk geometry information [chs]: ");
+       clrtoeol();
+       refresh();
+
+       clear_warning();
+
+       switch (toupper(getch())) {
+       case 'C':
+           sprintf(def, "%d", cylinders);
+           mvaddstr(COMMAND_LINE_Y, COMMAND_LINE_X,
+                    "Enter the number of cylinders: ");
+           if (get_string(response, LINE_LENGTH, def) > 0) {
+               tmp_val = atoi(response);
+               if (tmp_val > 0 && tmp_val <= MAX_CYLINDERS) {
+                   cylinders = tmp_val;
+                   ret_val = TRUE;
+               } else
+                   print_warning(BAD_CYLINDERS);
+           }
+           break;
+       case 'H':
+           sprintf(def, "%d", heads);
+           mvaddstr(COMMAND_LINE_Y, COMMAND_LINE_X,
+                    "Enter the number of heads: ");
+           if (get_string(response, LINE_LENGTH, def) > 0) {
+               tmp_val = atoi(response);
+               if (tmp_val > 0 && tmp_val <= MAX_HEADS) {
+                   heads = tmp_val;
+                   ret_val = TRUE;
+               } else
+                   print_warning(BAD_HEADS);
+           }
+           break;
+       case 'S':
+           sprintf(def, "%d", sectors);
+           mvaddstr(COMMAND_LINE_Y, COMMAND_LINE_X,
+                    "Enter the number of sectors per track: ");
+           if (get_string(response, LINE_LENGTH, def) > 0) {
+               tmp_val = atoi(response);
+               if (tmp_val > 0 && tmp_val <= MAX_SECTORS) {
+                   sectors = tmp_val;
+                   ret_val = TRUE;
+               } else
+                   print_warning(BAD_SECTORS);
+           }
+           break;
+       case ESC:
+       case CR:
+           done = TRUE;
+           break;
+       default:
+           putchar(BELL);
+           break;
+       }
+    }
+
+    if (ret_val) {
+       if (p_info[num_parts-1].last_sector > heads*sectors*cylinders-1) {
+           while (p_info[num_parts-1].first_sector > heads*sectors*cylinders-1) {
+               if (p_info[num_parts-1].id == FREE_SPACE ||
+                   p_info[num_parts-1].id == UNUSABLE)
+                   remove_part(num_parts-1);
+               else
+                   del_part(num_parts-1);
+           }
+
+           p_info[num_parts-1].last_sector = heads*sectors*cylinders - 1;
+
+           if (ext_info.last_sector > heads*sectors*cylinders-1)
+               ext_info.last_sector = heads*sectors*cylinders - 1;
+       } else if (p_info[num_parts-1].last_sector < heads*sectors*cylinders-1) {
+           if (p_info[num_parts-1].id == FREE_SPACE ||
+               p_info[num_parts-1].id == UNUSABLE) {
+               p_info[num_parts-1].last_sector = heads*sectors*cylinders - 1;
+           } else {
+               insert_part(num_parts, PRI_OR_LOG, FREE_SPACE, 0,
+                           p_info[num_parts-1].last_sector+1,
+                           heads*sectors*cylinders-1, 0);
+           }
+       }
+
+       /* Make sure the partitions are correct */
+       check_part_info();
+    }
+
+    return ret_val;
+}
+
+void change_id(int i)
+{
+    char id[LINE_LENGTH], def[LINE_LENGTH];
+    int num_types = 0;
+    int num_across, num_down;
+    int len, new_id = LINUX;
+    int y_start, y_end;
+    int j, pos;
+
+    for (num_types = 0, j = 1; j < NUM_PART_TYPES; j++)
+       if (partition_type[j])
+           num_types++;
+
+    num_across = COLS/COL_ID_WIDTH;
+    num_down = (((float)num_types)/num_across + 1);
+    y_start = COMMAND_LINE_Y - 1 - num_down;
+    if (y_start > DISK_TABLE_START+cur_part+4)
+       y_start = DISK_TABLE_START+cur_part+4;
+    y_end = y_start + num_down - 1;
+
+    for (j = y_start - 1; j <= y_end + 1; j++) {
+       move(j, 0);
+       clrtoeol();
+    }
+
+    for (pos = 0, j = 1; j < NUM_PART_TYPES; j++)
+       if (partition_type[j]) {
+           move(y_start + pos % num_down, (pos/num_down)*COL_ID_WIDTH + 1);
+           printw("%02X %-16.16s", j, partition_type[j]);
+           pos++;
+       }
+
+    sprintf(def, "%02X", new_id);
+    mvaddstr(COMMAND_LINE_Y, COMMAND_LINE_X, "Enter filesystem type: ");
+    if ((len = get_string(id, 2, def)) <= 0 && len != GS_DEFAULT)
+       return;
+
+    if (len != GS_DEFAULT) {
+       if (!isxdigit(id[0]))
+           return;
+       new_id = (isdigit(id[0]) ? id[0] - '0' : tolower(id[0]) - 'a' + 10);
+       if (len == 2)
+           if (isxdigit(id[1]))
+               new_id = new_id*16 +
+                   (isdigit(id[1]) ? id[1] - '0' : tolower(id[1]) - 'a' + 10);
+           else
+               return;
+    }
+
+    if (new_id == 0)
+       print_warning(ID_EMPTY);
+    else if (new_id == EXTENDED)
+       print_warning(ID_EXT);
+    else
+       p_info[i].id = new_id;
+}
+
+void draw_partition(int i)
+{
+    int size, j;
+    int y = i + DISK_TABLE_START + 2 - (cur_part/NUM_ON_SCREEN)*NUM_ON_SCREEN;
+
+    if (!arrow_cursor) {
+       move(y, 0);
+       for (j = 0; j < COLS; j++)
+           addch(' ');
+    }
+
+    if (p_info[i].id > 0) {
+       mvprintw(y, NAME_START,
+                "%s%d", disk_device, p_info[i].num+1);
+       if (p_info[i].flags) {
+           if (p_info[i].flags == ACTIVE_FLAG)
+               mvaddstr(y, FLAGS_START, "Boot");
+           else
+               mvprintw(y, FLAGS_START, "Unk(%02X)", p_info[i].flags);
+           if (p_info[i].first_sector == 0 || IS_LOGICAL(p_info[i].num)) {
+               if (p_info[i].offset != sectors)
+                   addstr(", NC");
+           } else {
+               if (p_info[i].offset != 0)
+                   addstr(", NC");
+           }
+       } else {
+           if (p_info[i].first_sector == 0 || IS_LOGICAL(p_info[i].num)) {
+               if (p_info[i].offset != sectors)
+                   mvaddstr(y, FLAGS_START, "NC");
+           } else {
+               if (p_info[i].offset != 0)
+                   mvaddstr(y, FLAGS_START, "NC");
+           }
+       }
+    }
+    mvaddstr(y, PTYPE_START,
+            (p_info[i].id == UNUSABLE ? "" :
+             (IS_LOGICAL(p_info[i].num) ? "Logical" :
+              (p_info[i].num >= 0 ? "Primary" :
+               (p_info[i].num == PRI_OR_LOG ? "Pri/Log" :
+                (p_info[i].num == PRIMARY ? "Primary" : "Logical"))))));
+    if (p_info[i].id == UNUSABLE)
+       mvaddstr(y, FSTYPE_START, "Unusable");
+    else if (p_info[i].id == FREE_SPACE)
+       mvaddstr(y, FSTYPE_START, "Free Space");
+    else if (partition_type[p_info[i].id])
+       mvaddstr(y, FSTYPE_START, partition_type[p_info[i].id]);
+    else
+       mvprintw(y, FSTYPE_START, "Unknown (%02X)", p_info[i].id);
+
+    size = p_info[i].last_sector - p_info[i].first_sector + 1;
+    if (display_units == SECTORS)
+       mvprintw(y, SIZE_START, "%9d", size);
+    else if (display_units == CYLINDERS)
+       mvprintw(y, SIZE_START, "%9d", size/(sectors*heads));
+    else
+       mvprintw(y, SIZE_START, "%9.2f", ceiling(size/20.48)/100);
+    if (((size/(sectors*heads)) != ceiling(size/(sectors*(float)heads))) ||
+       ((p_info[i].first_sector/(sectors*heads)) !=
+        ceiling(p_info[i].first_sector/(sectors*heads))))
+       mvprintw(y, COLUMNS-1, "*");
+}
+
+void init_const(void)
+{
+    if (!defined) {
+       NAME_START = (((float)NAME_START)/COLUMNS)*COLS;
+       FLAGS_START = (((float)FLAGS_START)/COLUMNS)*COLS;
+       PTYPE_START = (((float)PTYPE_START)/COLUMNS)*COLS;
+       FSTYPE_START = (((float)FSTYPE_START)/COLUMNS)*COLS;
+       SIZE_START = (((float)SIZE_START)/COLUMNS)*COLS;
+       COMMAND_LINE_X = (((float)COMMAND_LINE_X)/COLUMNS)*COLS;
+
+       COMMAND_LINE_Y = LINES - 4;
+       WARNING_START = LINES - 2;
+
+       if ((NUM_ON_SCREEN = COMMAND_LINE_Y - DISK_TABLE_START - 3) <= 0)
+           NUM_ON_SCREEN = 1;
+
+       COLUMNS = COLS;
+       defined = TRUE;
+    }
+}
+
+void draw_screen(void)
+{
+    int i;
+    char *line;
+
+    line = (char *)malloc((COLS+1)*sizeof(char));
+
+    if (warning_last_time) {
+       for (i = 0; i < COLS; i++) {
+           move(WARNING_START, i);
+           line[i] = inch();
+       }
+       line[COLS] = 0;
+    }
+
+    erase();
+
+    if (warning_last_time)
+       mvaddstr(WARNING_START, 0, line);
+
+
+    sprintf(line, "cfdisk %s", VERSION);
+    mvaddstr(HEADER_START, (COLS-strlen(line))/2, line);
+    sprintf(line, "Disk Drive: %s", disk_device);
+    mvaddstr(HEADER_START+2, (COLS-strlen(line))/2, line);
+    sprintf(line, "Heads: %d   Sectors per Track: %d   Cylinders: %d",
+           heads, sectors, cylinders);
+    mvaddstr(HEADER_START+3, (COLS-strlen(line))/2, line);
+
+    mvaddstr(DISK_TABLE_START, NAME_START, "Name");
+    mvaddstr(DISK_TABLE_START, FLAGS_START, "Flags");
+    mvaddstr(DISK_TABLE_START, PTYPE_START, "Part Type");
+    mvaddstr(DISK_TABLE_START, FSTYPE_START, "FS Type");
+    if (display_units == SECTORS)
+       mvaddstr(DISK_TABLE_START, SIZE_START, "  Sectors");
+    else if (display_units == CYLINDERS)
+       mvaddstr(DISK_TABLE_START, SIZE_START, "Cylinders");
+    else
+       mvaddstr(DISK_TABLE_START, SIZE_START, "Size (MB)");
+
+    move(DISK_TABLE_START+1, 1);
+    for (i = 1; i < COLS-1; i++)
+       addch('-');
+
+    if (NUM_ON_SCREEN >= num_parts)
+       for (i = 0; i < num_parts; i++)
+           draw_partition(i);
+    else
+       for (i = (cur_part/NUM_ON_SCREEN)*NUM_ON_SCREEN;
+            i < NUM_ON_SCREEN + (cur_part/NUM_ON_SCREEN)*NUM_ON_SCREEN &&
+            i < num_parts;
+            i++)
+           draw_partition(i);
+
+    free(line);
+}
+
+int draw_cursor(int move)
+{
+    if (move != 0 && (cur_part + move < 0 || cur_part + move >= num_parts))
+       return -1;
+
+    if (arrow_cursor)
+       mvaddstr(DISK_TABLE_START + cur_part + 2
+                - (cur_part/NUM_ON_SCREEN)*NUM_ON_SCREEN, 0, "   ");
+    else
+       draw_partition(cur_part);
+
+    cur_part += move;
+
+    if (((cur_part - move)/NUM_ON_SCREEN)*NUM_ON_SCREEN !=
+       (cur_part/NUM_ON_SCREEN)*NUM_ON_SCREEN)
+       draw_screen();
+
+    if (arrow_cursor)
+       mvaddstr(DISK_TABLE_START + cur_part + 2
+                - (cur_part/NUM_ON_SCREEN)*NUM_ON_SCREEN, 0, "-->");
+    else {
+       standout();
+       draw_partition(cur_part);
+       standend();
+    }
+
+    return 0;
+}
+
+void die(int dummy)
+{
+    signal(SIGINT, old_SIGINT);
+    signal(SIGTERM, old_SIGTERM);
+    mvcur(0, COLS-1, LINES-1, 0);
+    nl();
+    endwin();
+    fdexit(0);
+}
+
+void do_curses_fdisk(void)
+{
+    int done = FALSE;
+    char command;
+
+    initscr();
+    old_SIGINT = signal(SIGINT, die);
+    old_SIGTERM = signal(SIGTERM, die);
+#ifdef DEBUG
+    signal(SIGINT, old_SIGINT);
+    signal(SIGTERM, old_SIGTERM);
+#endif
+
+    cbreak();
+    noecho();
+    nonl();
+
+    init_const();
+
+    fill_p_info();
+
+    draw_screen();
+
+    while (!done) {
+       (void)draw_cursor(0);
+
+       if (p_info[cur_part].id == FREE_SPACE)
+           mvaddstr(COMMAND_LINE_Y, COMMAND_LINE_X, "Command [hnpquW?]: ");
+       else if (p_info[cur_part].id > 0)
+           mvaddstr(COMMAND_LINE_Y, COMMAND_LINE_X, "Command [bdhmpqtuW?]: ");
+       else
+           mvaddstr(COMMAND_LINE_Y, COMMAND_LINE_X, "Command [hpquW?]: ");
+
+       clrtoeol();
+       refresh();
+
+       clear_warning();
+
+       switch (command = getch()) {
+       case 'B':
+       case 'b':
+           if (p_info[cur_part].id > 0)
+               p_info[cur_part].flags ^= 0x80;
+           else
+               print_warning(NO_FLAGS);
+           break;
+       case 'D':
+       case 'd':
+           if (p_info[cur_part].id > 0) {
+               del_part(cur_part);
+               if (cur_part >= num_parts)
+                   cur_part = num_parts - 1;
+               draw_screen();
+           } else
+               print_warning(DEL_EMPTY);
+           break;
+       case 'G':
+       case 'g':
+           if (change_geometry())
+               draw_screen();
+           break;
+       case 'M':
+       case 'm':
+           if (p_info[cur_part].id > 0) {
+               if (p_info[cur_part].first_sector == 0 ||
+                   IS_LOGICAL(p_info[cur_part].num)) {
+                   if (p_info[cur_part].offset == sectors)
+                       p_info[cur_part].offset = 1;
+                   else
+                       p_info[cur_part].offset = sectors;
+                   draw_screen();
+               } else if (p_info[cur_part].offset != 0)
+                   p_info[cur_part].offset = 0;
+               else
+                   print_warning(MAX_UNMAXABLE);
+           } else
+               print_warning(MAX_UNMAXABLE);
+           break;
+       case 'N':
+       case 'n':
+           if (p_info[cur_part].id == FREE_SPACE) {
+               new_part(cur_part);
+               draw_screen();
+           } else if (p_info[cur_part].id == UNUSABLE)
+               print_warning(ADD_UNUSABLE);
+           else
+               print_warning(ADD_EXISTS);
+           break;
+       case 'P':
+       case 'p':
+           print_tables();
+           draw_screen();
+           break;
+       case 'Q':
+       case 'q':
+           done = TRUE;
+           break;
+       case 'T':
+       case 't':
+           if (p_info[cur_part].id > 0) {
+               change_id(cur_part);
+               draw_screen();
+           } else
+               print_warning(TYPE_EMPTY);
+           break;
+       case 'U':
+       case 'u':
+           if (display_units == MEGABYTES)
+               display_units = SECTORS;
+           else if (display_units == SECTORS)
+               display_units = CYLINDERS;
+           else if (display_units == CYLINDERS)
+               display_units = MEGABYTES;
+           draw_screen();
+           break;
+       case 'W':
+           write_part_table();
+           break;
+       case 'H':
+       case 'h':
+       case '?':
+           display_help();
+           draw_screen();
+           break;
+       case ESC:
+           if ((command = getch()) == '[') {
+               command = getch();
+               switch (command) {
+               case 'A' : /* Up arrow */
+                   if (!draw_cursor(-1))
+                       command = 0;
+                   else
+                       print_warning(NO_MORE_PARTS);
+                   break;
+               case 'B' : /* Down arrow */
+                   if (!draw_cursor(1))
+                       command = 0;
+                   else
+                       print_warning(NO_MORE_PARTS);
+                   break;
+               case 'C' : /* Right arrow */
+               case 'D' : /* Left arrow */
+               }
+           }
+           if (command)
+               putchar(BELL); /* CTRL-G */
+           break;
+       case REDRAWKEY:
+           clear();
+           draw_screen();
+           break;
+       default:
+           print_warning(BAD_COMMAND);
+           putchar(BELL); /* CTRL-G */
+       }
+    }
+
+    signal(SIGINT, old_SIGINT);
+    signal(SIGTERM, old_SIGTERM);
+    mvcur(0, COLS-1, LINES-1, 0);
+    nl();
+    endwin();
+    fdexit(0);
+}
+
+void copyright(void)
+{
+    fprintf(stderr, "Copyright (C) 1994 Kevin E. Martin\n");
+}
+
+void usage(char *prog_name)
+{
+    fprintf(stderr,
+           "%s: [-avz] [-c # cylinders] [-h # heads] [-s # sectors/track]\n",
+           prog_name);
+    fprintf(stderr,
+           "[ -P opt ] device\n");
+    copyright();
+}
+
+void main(int argc, char **argv)
+{
+    char c;
+    int i, len;
+
+    while ((c = getopt(argc, argv, "ac:h:s:vzP:")) != EOF)
+       switch (c) {
+       case 'a':
+           arrow_cursor = TRUE;
+           break;
+       case 'c':
+           cylinders = atoi(optarg);
+           if (cylinders <= 0 || cylinders > MAX_CYLINDERS) {
+               fprintf(stderr, "%s: %s\n", argv[0], BAD_CYLINDERS);
+               exit(1);
+           }
+           break;
+       case 'h':
+           heads = atoi(optarg);
+           if (heads <= 0 || heads > MAX_HEADS) {
+               fprintf(stderr, "%s: %s\n", argv[0], BAD_HEADS);
+               exit(1);
+           }
+           break;
+       case 's':
+           sectors = atoi(optarg);
+           if (sectors <= 0 || sectors > MAX_SECTORS) {
+               fprintf(stderr, "%s: %s\n", argv[0], BAD_SECTORS);
+               exit(1);
+           }
+           break;
+       case 'v':
+           fprintf(stderr, "cfdisk %s\n", VERSION);
+           copyright();
+           exit(0);
+       case 'z':
+           zero_table = TRUE;
+           break;
+       case 'P':
+           len = strlen(optarg);
+           for (i = 0; i < len; i++) {
+               switch (optarg[i]) {
+               case 'r':
+                   print_only |= PRINT_RAW_TABLE;
+                   break;
+               case 's':
+                   print_only |= PRINT_SECTOR_TABLE;
+                   break;
+               case 't':
+                   print_only |= PRINT_PARTITION_TABLE;
+                   break;
+               default:
+                   usage(argv[0]);
+                   break;
+               }
+           }
+           break;
+       default:
+           usage(argv[0]);
+           exit(1);
+       }
+
+    if (argc-optind == 1)
+       disk_device = argv[optind];
+    else if (argc-optind != 0) {
+       usage(argv[0]);
+       exit(1);
+    } else if ((fd = open(DEFAULT_DEVICE, O_RDWR)) < 0)
+       disk_device = ALTERNATE_DEVICE;
+    else close(fd);
+
+    if (print_only) {
+       fill_p_info();
+       if (print_only & PRINT_RAW_TABLE)
+           print_raw_table();
+       if (print_only & PRINT_SECTOR_TABLE)
+           print_p_info();
+       if (print_only & PRINT_PARTITION_TABLE)
+           print_part_table();
+    } else
+       do_curses_fdisk();
+}
index 7fb78af6a8cebf2529b6f0317661e4031e8c7bb3..8b08535a6019b94202b6843cb7397704230c9666 100644 (file)
@@ -93,7 +93,7 @@ int main(int argc,char **argv)
        argv++;
     }
     if (argc != 2) usage(name);
-    if (lstat(argv[1],&st) < 0) PERROR(argv[1]);
+    if (stat(argv[1],&st) < 0) PERROR(argv[1]);
     if (!S_ISBLK(st.st_mode) || MAJOR(st.st_rdev) != FLOPPY_MAJOR) {
        fprintf(stderr,"%s: not a floppy device\n",argv[1]);
        exit(1);
index d1891bb2452d8b47321456479dcbcb84a169117d..395e9c71dcdb8aa54a5df912c84111768363eae6 100644 (file)
@@ -1,6 +1,6 @@
 .\" Copyright 1992, 1993 Rickard E. Faith (faith@cs.unc.edu)
 .\" May be distributed under the GNU General Public License
-.TH FDISK 8 "Tue Mar 22 01:00:00 1994" "Linux 1.0" "Linux Programmer's Manual"
+.TH FDISK 8 "3 June 1995" "Linux 1.0" "Linux Programmer's Manual"
 .SH NAME
 fdisk \- Partition table manipulator for Linux
 .SH SYNOPSIS
index 3c0a328d5e3221be8846413e6ca0b41f2d5ffcf9..f3455fa5fae57829f7d35cb79cde36a1e0ebdde7 100644 (file)
  * Modified, Wed Jun 22 21:05:30 1994, faith@cs.unc.edu:
  *    Added/changed a few partition type names to conform to cfdisk.
  *    (suggested by Sujal, smpatel@wam.umd.edu)
+ * Modified 3/5/95 leisner@sdsp.mc.xerox.com -- on -l only open
+ *    devices RDONLY (instead of RDWR).  This allows you to
+ *    have the disks as rw-r----- with group disk (and if you
+ *    want is safe to setguid fdisk to disk).
+ * Modified Sat Mar 11 10:02 1995 with more partition types, faith@cs.unc.edu
+ * Modified, Thu May  4 01:11:45 1995, esr@snark.thyrsus.com:
+ *     It's user-interface cleanup time.
+ *     Actual error messages for out-of-bounds values (what a concept!).
+ *     Enable read-only access to partition table for learners.
+ *     Smart defaults for most numeric prompts.
+ * Fixed a bug preventing a partition from crossing cylinder 8064, aeb, 950801.
+ * Read partition table twice to avoid kernel bug
+ *     (from Daniel Quinlan <quinlan@yggdrasil.com>), Tue Sep 26 10:25:28 1995
+ * Modified, Sat Jul  1 23:43:16 MET DST 1995, fasten@cs.bonn.edu:
+ *      editor for NetBSD/i386 (and Linux/Alpha?) disklabels.
+ * Tue Sep 26 17:07:54 1995: More patches from aeb.  Fix segfaults, all >4GB.
+ *   Don't destroy random data if extd partition starts past 4GB, aeb, 950818.
+ *   Don't segfault on bad partition created by previous fdisk.
+ *
  */
 
 
 #include <linux/hdreg.h>
 #include <linux/fs.h>
 
-#if defined(__GNUC__) || defined(HAS_LONG_LONG)
-typedef long long ext2_loff_t;
-#else
-typedef long      ext2_loff_t;
-#endif
-
-extern ext2_loff_t ext2_llseek(unsigned int fd,
-                              ext2_loff_t offset,
-                              unsigned int origin);
+#include "fdisk.h"
 
 #define hex_val(c)     ({ \
                                char _c = (c); \
@@ -66,13 +77,12 @@ extern ext2_loff_t ext2_llseek(unsigned int fd,
                        })
 
 
-#define VERSION        "2.0a (>2GB)"
+#define VERSION        "2.1 (>4GB)"
 
 #define DEFAULT_DEVICE "/dev/hda"
 #define ALTERNATE_DEVICE "/dev/sda"
 #define LINE_LENGTH    80
 #define MAXIMUM_PARTS  60
-#define SECTOR_SIZE    512
 #define PART_TABLE_FLAG        0xaa55
 #define table_check(b) ((unsigned short *)((b) + 0x1fe))
 #define offset(b, n)   ((struct partition *)((b) + 0x1be + \
@@ -91,7 +101,6 @@ extern ext2_loff_t ext2_llseek(unsigned int fd,
                                s |= (sector >> 2) & 0xc0;      \
                        }
 
-#define cround(n)      (((n) + display_factor * unit_flag) / display_factor)
 #define ACTIVE_FLAG    0x80
 #define EXTENDED       5
 
@@ -99,8 +108,8 @@ extern ext2_loff_t ext2_llseek(unsigned int fd,
 #define LINUX_SWAP     0x82
 #define LINUX_NATIVE   0x83
 
-enum failure {usage, unable_to_open, unable_to_read, unable_to_seek,
-       unable_to_write, out_of_memory};
+/* normally O_RDWR, -l option gives O_RDONLY */
+static int type_open = O_RDWR;
 
 char   *disk_device = DEFAULT_DEVICE,  /* hda, unless specified */
        *line_ptr,                      /* interactive input */
@@ -113,7 +122,6 @@ char        *disk_device = DEFAULT_DEVICE,  /* hda, unless specified */
 int    fd,                             /* the disk */
        ext_index,                      /* the prime extended partition */
        listing = 0,                    /* no aborts for fdisk -l */
-       size_flag = 0,
        dos_compatible_flag = ~0,
        partitions = 4;                 /* maximum partition + 1 */
 
@@ -133,11 +141,8 @@ struct     partition *part_table[MAXIMUM_PARTS]    /* partitions */
        *ext_pointers[MAXIMUM_PARTS]            /* link pointers */
                = {NULL, NULL, NULL, NULL};
 
-struct systypes {
-       unsigned char index;
-       char *name;
-       } sys_types[] = {
-               {0, "Empty"},
+struct systypes sys_types[] = { /* struct systypes in fdisk.h *//* bf */
+                {0, "Empty"},
                {1, "DOS 12-bit FAT"},
                {2, "XENIX root"},
                {3, "XENIX usr"},
@@ -152,7 +157,8 @@ struct systypes {
                {0x51, "Novell?"},
                {0x52, "Microport"},            /* or CPM? */
                {0x63, "GNU HURD"},             /* or System V/386? */
-               {0x64, "Novell"},
+               {0x64, "Novell Netware 286"},
+               {0x65, "Novell Netware 386"},
                {0x75, "PC/IX"},
                {0x80, "Old MINIX"},            /* Minix 1.4a and earlier */
 
@@ -173,6 +179,8 @@ struct systypes {
                {0xff, "BBT"}                   /* (bad track table) */
        };
 
+int nsys_types = sizeof (sys_types) / sizeof (struct systypes); /* bf */
+
 jmp_buf listingbuf;
 
 void fatal(enum failure why)
@@ -216,6 +224,7 @@ void menu(void)
 {
        puts("Command action\n"
                "   a   toggle a bootable flag\n"
+                "   b   edit bsd disklabel\n" /* bf */
                "   c   toggle the dos compatiblity flag\n"
                "   d   delete a partition\n"
                "   l   list known partition types\n"
@@ -244,6 +253,7 @@ void xmenu(void)
                "   q   quit without saving changes\n"
                "   r   return to main menu\n"
                "   s   change number of sectors\n"
+               "   v   verify the partition table\n"
                "   w   write table to disk and exit"
        );
 }
@@ -265,10 +275,12 @@ char *partition_type(unsigned char type)
        return NULL;
 }
 
-void list_types(void)
+/* added parameters to list_types() so fdisklabel
+   can pass another list of types.
+*//* bf */
+void list_types(struct systypes *sys, int size)
 {
-       uint last[4], done = 0, next = 0,
-               size = sizeof(sys_types) / sizeof(struct systypes);
+       uint last[4], done = 0, next = 0;
        int i;
 
        for (i = 3; i >= 0; i--)
@@ -277,8 +289,8 @@ void list_types(void)
 
        do {
                printf("%c%2x  %-15.15s", i ? ' ' : '\n',
-                       sys_types[next].index, sys_types[next].name);
-               next = last[i++] + done;
+                       sys[next].index, sys[next].name);
+               next = last[i++] + done;
                if (i > 3 || next >= last[i]) {
                        i = 0;
                        next = ++done;
@@ -399,7 +411,7 @@ void read_extended(struct partition *p)
                offsets[partitions] = extended_offset + p->start_sect;
                if (!extended_offset)
                        extended_offset = p->start_sect;
-               if (ext2_llseek(fd, offsets[partitions]
+               if (ext2_llseek(fd, (ext2_loff_t)offsets[partitions]
                               * SECTOR_SIZE, SEEK_SET) < 0)
                        fatal(unable_to_seek);
                if (!(buffers[partitions] = (char *) malloc(SECTOR_SIZE)))
@@ -443,11 +455,20 @@ void get_boot(void)
        struct hd_geometry geometry;
 
        partitions = 4;
-       if ((fd = open(disk_device, O_RDWR)) < 0)
+       if ((fd = open(disk_device, type_open)) < 0)
+       {
+           if ((fd = open(disk_device, O_RDONLY)) < 0)
                fatal(unable_to_open);
+           else
+               printf("You will not be able to write the partition table.\n");
+       }
        if (SECTOR_SIZE != read(fd, buffer, SECTOR_SIZE))
                fatal(unable_to_read);
+#ifdef HDIO_REQ
        if (!ioctl(fd, HDIO_REQ, &geometry)) {
+#else
+       if (!ioctl(fd, HDIO_GETGEO, &geometry)) {
+#endif
                heads = geometry.heads;
                sectors = geometry.sectors;
                cylinders = geometry.cylinders;
@@ -492,19 +513,61 @@ char read_char(char *mesg)
        return *line_ptr;
 }
 
-uint read_int(uint low, uint high, char *mesg)
+/* new function *//* bf */
+int read_hex(struct systypes *sys, int size)
 {
-       uint i;
+        int hex;
+
+        while (1)
+        {
+           read_char("Hex code (type L to list codes): ");
+           if (tolower(*line_ptr) == 'l')
+               list_types(sys, size);
+          else if (isxdigit (*line_ptr))
+          {
+             hex = 0;
+             do
+                hex = hex << 4 | hex_val(*line_ptr++);
+             while (isxdigit(*line_ptr));
+             return hex;
+          }
+        }
+}
+
+
+uint read_int(uint low, uint dflt, uint high, enum offset base, char *mesg)
+{
+       uint i, use_default = 1;
        char ms[70];
-       sprintf(ms, "%s (%d-%d): ", mesg, low, high);
+
+       switch(base) {
+       case lower:
+           sprintf(ms, "%s ([%d]-%d): ", mesg, low, high);
+           break;
+       case upper:
+           sprintf(ms, "%s (%d-[%d]): ", mesg, low, high);
+           break;
+       case deflt:
+           sprintf(ms, "%s (%d-[%d]-%d): ", mesg, low, dflt, high);
+           break;
+       default:
+           sprintf(ms, "%s (%d-%d): ", mesg, low, high);
+           break;
+       }
 
        while (1) {
-               while (!isdigit(read_char(ms)) &&
-                       (!size_flag || *line_ptr != '+'));
-               if (*line_ptr == '+') {
-                       i = atoi(++line_ptr);
-                       while (isdigit(*line_ptr))
-                               line_ptr++;
+               while (!isdigit(read_char(ms))
+                               && (*line_ptr != '-' && *line_ptr != '+'))
+                       continue;
+               if (*line_ptr == '+' || *line_ptr == '-') {
+                       if (*line_ptr == '+')
+                           ++line_ptr;
+                       i = atoi(line_ptr);
+                       while (isdigit(*line_ptr))
+                       {
+                               line_ptr++;
+                               use_default = 0;
+                       }
                        switch (*line_ptr) {
                                case 'c':
                                case 'C': if (!unit_flag)
@@ -520,19 +583,38 @@ uint read_int(uint low, uint high, char *mesg)
                                        break;
                                default: break;
                        }
-                       i += low;
+                       switch(base) {
+                       case lower: i += low; break;
+                       case upper: i += high; break;
+                       case deflt: i += dflt; break;
+                       }
                }
-               else i = atoi(line_ptr);
+               else
+               {
+                       i = atoi(line_ptr);
+                       while (isdigit(*line_ptr))
+                       {
+                               line_ptr++;
+                               use_default = 0;
+                       }
+               }
+               if (use_default)
+                   printf("Using default value %d\n", i = dflt);
                if (i >= low && i <= high)
                        break;
+               else
+                       printf("Value out of range.\n");
        }
-       size_flag = 0;
        return i;
 }
 
 int get_partition(int warn, int max)
 {
-       int i = read_int(1, max, "Partition number") - 1;
+       /*
+        * try to pick a default least likely to do damage,
+        * in case luser just types a newline
+        */
+       int i = read_int(1, max, max, ignore, "Partition number") - 1;
 
        if (warn && !part_table[i]->sys_ind)
                fprintf(stderr, "Warning: partition %d has empty type\n",
@@ -547,7 +629,7 @@ char *const str_units(void)
 
 void change_units(void)
 {
-       if (unit_flag = !unit_flag)
+       if ((unit_flag = !unit_flag))
                display_factor = 1;
        else display_factor = heads * sectors;
        update_units();
@@ -622,7 +704,8 @@ void delete_partition(int i)
                        changed[i - 1] = 1;
                }
                else {
-                       part_table[5]->start_sect +=
+                   if(part_table[5]) /* prevent SEGFAULT */
+                       part_table[5]->start_sect +=
                                offsets[5] - extended_offset;
                        offsets[5] = extended_offset;
                        changed[5] = 1;
@@ -655,6 +738,7 @@ void change_sysid(void)
        else if (!sys)
                printf("Partition %d does not exist yet!\n", i + 1);
        else while (1) {
+#if 0
                read_char("Hex code (type L to list codes): ");
                if (tolower(*line_ptr) == 'l')
                        list_types();
@@ -663,6 +747,12 @@ void change_sysid(void)
                        do
                                sys = sys << 4 | hex_val(*line_ptr++);
                        while (isxdigit(*line_ptr));
+#endif
+                       /* The above code has been moved to read_hex ()
+                          to avoid having the same code in fdisklabel.
+                        *//* bf */
+                        sys = read_hex (sys_types, nsys_types); /* bf */
+
                        if (!sys) {
                                delete_partition(i);
                                break;
@@ -683,7 +773,9 @@ void change_sysid(void)
                                changed[i] = 1;
                                break;
                        }
+#if 0 /* see above *//* bf */
                }
+#endif
        }
 }
 
@@ -744,6 +836,7 @@ static void check_consistency(struct partition *p, int partition)
                printf("logical=(%d, %d, %d)\n",lec, leh, les);
        }
 
+#if 0
 /* Beginning on cylinder boundary? */
        if (pbh != !pbc || pbs != 1) {
                printf("Partition %i does not start on cylinder "
@@ -751,6 +844,7 @@ static void check_consistency(struct partition *p, int partition)
                printf("     phys=(%d, %d, %d) ", pbc, pbh, pbs);
                printf("should be (%d, %d, 1)\n", pbc, !pbc);
        }
+#endif
 
 /* Ending on cylinder boundary? */
        if (peh != (heads - 1) || pes != sectors) {
@@ -773,22 +867,22 @@ void list_table(void)
                cylinders, str_units(), display_factor);
        if (w < 5)
                w = 5;
-       printf("%*s Boot  Begin   Start     End  Blocks   Id  System\n",
+        printf("%*s Boot   Begin    Start      End   Blocks   Id  System\n",
                w + 1, "Device");
        for (i = 0 ; i < partitions; i++)
                if ((p = part_table[i])->sys_ind) {
-                       printf("%*s%-2d  %c%8d%8d%8d%8d%c  %2x  %s\n", w,
-                       disk_device, i + 1,
-                       !p->boot_ind ? ' ' : p->boot_ind == ACTIVE_FLAG
+                        printf("%*s%-2d  %c%9d%9d%9d%9d%c  %2x  %s\n", w,
+/* device */           disk_device, i + 1,
+/* boot flag */                !p->boot_ind ? ' ' : p->boot_ind == ACTIVE_FLAG
                        ? '*' : '?',
-                       cround(rounded( calculate(p->head, p->sector, p->cyl),
+/* begin */            cround(rounded( calculate(p->head, p->sector, p->cyl),
                                p->start_sect + offsets[i])),
-                       cround(p->start_sect + offsets[i]),
-                       cround(p->start_sect + offsets[i] + p->nr_sects
+/* start */            cround(p->start_sect + offsets[i]),
+/* end */              cround(p->start_sect + offsets[i] + p->nr_sects
                                - (p->nr_sects ? 1: 0)),
-                       p->nr_sects / 2, p->nr_sects & 1 ? '+' : ' ',
-                       p->sys_ind,
-                       (type = partition_type(p->sys_ind)) ?
+/* odd flag on end */  p->nr_sects / 2, p->nr_sects & 1 ? '+' : ' ',
+/* type id */          p->sys_ind,
+/* type name */                (type = partition_type(p->sys_ind)) ?
                        type : "Unknown");
                        check_consistency(p, i);
                }
@@ -824,7 +918,9 @@ void x_list_table(int extend)
 void check_bounds(uint *first, uint *last)
 {
        int i;
-       uint max = 256 * 63 * 1024;
+       uint max = 0xffffffff;          /* used to be 256 * 63 * 1024
+                                          but that made it impossible to add a
+                                          partition crossing cylinder 8064 */
        struct partition *p = part_table[0];
 
        for (i = 0; i < partitions; p = part_table[++i])
@@ -863,7 +959,7 @@ void check(int n, uint h, uint s, uint c, uint start)
        if (real_c >= cylinders)
                fprintf(stderr, "Partitions %d: cylinder %d greater than "
                        "maximum %d\n", n, real_c + 1, cylinders);
-       if (start != total)
+       if (cylinders <= 1024 && start != total)
                fprintf(stderr,
                        "Partition %d: previous sectors %d disagrees with "
                        "total %d\n", n, start, total);
@@ -980,9 +1076,9 @@ void add_partition(int n, int sys)
                }
                if (!read && start == temp) {
                        uint i;
-                       temp = 0;
-                       start = read_int(cround(i = (stop = start) + (n > 4)),
-                               cround(limit), mesg);
+                       i = (stop = start) + (n > 4);
+                       start = read_int(cround(i), cround(i), cround(limit),
+                                        ignore, mesg);
                        if (unit_flag) {
                                start = (start - 1) * display_factor;
                                if (start < i) start = i;
@@ -1012,8 +1108,8 @@ void add_partition(int n, int sys)
        else {
                sprintf(mesg, "Last %s or +size or +sizeM or +sizeK",
                        str_units());
-               size_flag = 1;
-               stop = read_int(cround(start), cround(limit), mesg);
+               stop = read_int(cround(start), cround(limit), cround(limit),
+                               lower, mesg);
                if (unit_flag) {
                        stop = stop * display_factor - 1;
                        if (stop >limit)
@@ -1099,6 +1195,10 @@ void new_partition(void)
                                        EXTENDED);
                                return;
                        }
+                       else
+                               printf("Invalid partition number "
+                                      "for type `%c'\n", c);
+               
        }
 }
 
@@ -1110,7 +1210,7 @@ void write_table(void)
        for (i = 3; i < partitions; i++)
                if (changed[i]) {
                        *table_check(buffers[i]) = PART_TABLE_FLAG;
-                       if (ext2_llseek(fd, offsets[i]
+                       if (ext2_llseek(fd, (ext2_loff_t)offsets[i]
                                       * SECTOR_SIZE, SEEK_SET) < 0)
                                fatal(unable_to_seek);
                        if (write(fd, buffers[i], SECTOR_SIZE) != SECTOR_SIZE)
@@ -1123,15 +1223,25 @@ void write_table(void)
               "(Reboot to ensure the partition table has been updated.)\n");
        sync();
        sleep(2);
-       if (i = ioctl(fd, BLKRRPART))
-               error = errno;
+       if (i = ioctl(fd, BLKRRPART)) {
+                error = errno;
+        } else {
+                /* some kernel versions (1.2.x) seem to have trouble
+                   rereading the partition table, but if asked to do it
+                  twice, the second time works. - biro@yggdrasil.com */
+                sync();
+                sleep(2);
+                if(i = ioctl(fd, BLKRRPART))
+                        error = errno;
+        }
+
        close(fd);
 
        printf("Syncing disks.\n");
        sync();
        sleep(4);               /* for sync() */
 
-       if (i)
+       if (i < 0)
                printf("Re-read table failed with error %d: %s.\nReboot your "
                        "system to ensure the partition table is updated.\n",
                        error, strerror(error));
@@ -1185,8 +1295,9 @@ void move_begin(int i)
        }
        first = rounded(calculate(p->head, p->sector, p->cyl), p->start_sect +
                offsets[i]);
-       new = read_int(first, p->start_sect + p->nr_sects + offsets[i] - 1,
-               "New beginning of data") - offsets[i];
+       new = read_int(first, first, 
+                      p->start_sect + p->nr_sects + offsets[i] - 1,
+                      lower, "New beginning of data") - offsets[i];
 
        if (new != p->nr_sects) {
                first = p->nr_sects + p->start_sect - new;
@@ -1203,15 +1314,16 @@ void xselect(void)
                switch (tolower(read_char("Expert command (m for help): "))) {
                        case 'b': move_begin(get_partition(0, partitions));
                                break;
-                       case 'c': cylinders = read_int(1, 65535,
-                                       "Number of cylinders");
-                               warn_cylinders();
+                       case 'c': cylinders = read_int(1, cylinders, 65535,
+                                       deflt, "Number of cylinders");
+                               warn_cylinders();
                                break;
                        case 'd': print_raw();
                                break;
                        case 'e': x_list_table(1);
                                break;
-                       case 'h': heads = read_int(1, 256, "Number of heads");
+                       case 'h': heads = read_int(1, heads, 256, deflt,
+                                                  "Number of heads");
                                update_units();
                                break;
                        case 'p': x_list_table(0);
@@ -1219,7 +1331,7 @@ void xselect(void)
                        case 'q': close(fd);
                                exit(0);
                        case 'r': return;
-                       case 's': sectors = read_int(1, 63,
+                       case 's': sectors = read_int(1, sectors, 63, deflt,
                                        "Number of sectors");
                                if (dos_compatible_flag) {
                                        sector_offset = sectors;
@@ -1229,6 +1341,8 @@ void xselect(void)
                                }
                                update_units();
                                break;
+                       case 'v': verify();
+                               break;
                        case 'w': write_table();
                        default: xmenu();
                }
@@ -1239,13 +1353,21 @@ void try(char *device)
 {
        disk_device = device;
        if (!setjmp(listingbuf))
-               if ((fd = open(disk_device, O_RDWR)) >= 0) {
+               if ((fd = open(disk_device, type_open)) >= 0) {
                        close(fd);
                        get_boot();
                        list_table();
                        if (partitions > 4)
                                delete_partition(ext_index);
-               }
+              } else {
+                               /* Ignore other errors, since we try IDE
+                                  and SCSI hard disks which may not be
+                                  installed on the system. */
+                if(errno == EACCES) {
+                   fprintf(stderr, "Cannot open %s\n", device);
+                   exit(1);
+                }
+             }
 }
 
 void main(int argc, char **argv)
@@ -1259,6 +1381,7 @@ void main(int argc, char **argv)
                                exit(0);
                        case 'l':
                                listing = 1;
+                               type_open = O_RDONLY;
                                try("/dev/hda");
                                try("/dev/hdb");
                                try("/dev/hdc");
@@ -1301,22 +1424,29 @@ void main(int argc, char **argv)
                disk_device = ALTERNATE_DEVICE;
        else close(fd);
 
-       get_boot();
        if (argc == 1)
                printf("Using %s as default device!\n", disk_device);
+       get_boot();
 
        while (1) {
                putchar('\n');
                switch (tolower(read_char("Command (m for help): "))) {
                        case 'a': toggle_active(get_partition(1, partitions));
                                break;
+/* There should be a define which allows to turn off disklabel support so as
+   not to make fdisk larger than necessary on installation boot disks.
+*/
+#if 1 /* #ifndef NO_DISKLABEL_SUPPORT */
+                        case 'b': bselect(); /* bf */
+                                break;
+#endif
                        case 'c':
                                toggle_dos();
                                break;
                        case 'd': delete_partition(
                                        get_partition(1, partitions));
                                break;
-                       case 'l': list_types();
+                        case 'l': list_types(sys_types, nsys_types); /* bf */
                                break;
                        case 'n': new_partition();
                                break;
diff --git a/disk-utils/fdisk.h b/disk-utils/fdisk.h
new file mode 100644 (file)
index 0000000..4f23fd8
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+   fdisk.h
+*/
+
+#define SECTOR_SIZE    512
+#define NETBSD_PARTITION 0xa5
+#define cround(n)      (((n) + display_factor * unit_flag) / display_factor)
+
+#if defined(__GNUC__) || defined(HAS_LONG_LONG)
+typedef long long ext2_loff_t;
+#else
+typedef long      ext2_loff_t;
+#endif
+
+extern ext2_loff_t ext2_llseek(unsigned int fd,
+                              ext2_loff_t offset,
+                              unsigned int origin);
+
+enum failure {usage, unable_to_open, unable_to_read, unable_to_seek,
+       unable_to_write, out_of_memory};
+
+enum offset {ignore, lower, deflt, upper};
+
+struct systypes {
+  unsigned char index;
+  char *name;
+};
+
+/* prototypes for fdisk.c */
+extern char *disk_device,
+            *line_ptr;
+extern int fd,
+           partitions;
+extern uint unit_flag,
+            display_factor;
+extern struct partition *part_table[];
+extern void fatal(enum failure why);
+extern int  get_partition(int warn, int max);
+extern void list_types(struct systypes *sys, int size);
+extern int read_line (void);
+extern char read_char(char *mesg);
+extern int read_hex(struct systypes *sys, int size);
+uint read_int(uint low, uint dflt, uint high, enum offset base, char *mesg);
+extern char *const str_units(void);
+
+/* prototypes for fdisklabel.c */
+extern void bselect(void);
diff --git a/disk-utils/fdisklabel.c b/disk-utils/fdisklabel.c
new file mode 100644 (file)
index 0000000..5fbf67a
--- /dev/null
@@ -0,0 +1,801 @@
+/*
+   NetBSD disklabel editor for Linux fdisk
+   Written by Bernhard Fastenrath (fasten@informatik.uni-bonn.de)
+   with code from the NetBSD disklabel command:
+  
+   Copyright (c) 1987, 1988 Regents of the University of California.
+   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 the University of
+       California, Berkeley and its contributors.
+   4. Neither the name of the University nor the names of its contributors
+      may be used to endorse or promote products derived from this software
+      without specific prior written permission.
+  
+   THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+   ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+   ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS 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.
+*/
+
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <ctype.h>
+#include <setjmp.h>
+#include <errno.h>
+
+#include <sys/ioctl.h>
+#include <sys/param.h>
+
+#include <linux/genhd.h>
+#include <linux/hdreg.h>
+#include <linux/fs.h>
+
+#include "fdisk.h"
+#define DKTYPENAMES
+#include "fdisklabel.h"
+
+static void bsd_delete_part (void);
+static void bsd_new_part (void);
+static void bsd_print_disklabel (int show_all);
+static void bsd_write_disklabel (void);
+static int bsd_create_disklabel (void);
+static void bsd_edit_disklabel (void);
+static void bsd_write_bootstrap (void);
+static void bsd_change_fstype (void);
+static int bsd_get_part_index (int max);
+static int bsd_check_new_partition (int *i);
+static void bsd_list_types (void);
+static u_short bsd_dkcksum (struct disklabel *lp);
+static int bsd_initlabel  (struct partition *p, struct disklabel *d, int pindex);
+static int bsd_readlabel  (struct partition *p, struct disklabel *d);
+static int bsd_writelabel (struct partition *p, struct disklabel *d);
+static void sync_disks (void);
+#if defined (i386)
+static int bsd_translate_fstype (int linux_type);
+static void bsd_link_part (void);
+#endif
+#if defined (__alpha__)
+void alpha_bootblock_checksum (char *boot);
+#endif
+
+static struct disklabel bsd_dlabel;
+static char buffer[BSD_BBSIZE];
+#if defined (i386)
+static struct partition *bsd_part;
+static int bsd_part_index;
+#endif
+
+void
+bmenu (void)
+{
+  puts ("Command action\n"
+       "   d   delete a BSD partition\n"
+       "   e   edit drive data\n"
+       "   i   install bootstrap\n"
+       "   l   list known filesystem types\n"
+       "   m   print this menu\n"
+       "   n   add a new BSD partition\n"
+       "   p   print BSD partition table\n"
+       "   q   quit without saving changes\n"
+#if defined (i386)
+       "   r   return to main menu\n"
+#endif
+       "   s   show complete disklabel\n"
+       "   t   change a partition's filesystem id\n"
+       "   w   write disklabel to disk\n"
+#if defined (i386)
+       "   x   link BSD partition to non-BSD partition"
+#endif
+       );
+}
+
+void
+bselect (void)
+{
+#if defined (i386)
+  int t;
+
+  for (t=0; t<4; t++)
+    if (part_table[t] -> sys_ind == NETBSD_PARTITION)
+    {
+      bsd_part = part_table[t];
+      bsd_part_index = t;
+      if (bsd_part -> start_sect == 0)
+      {
+        fprintf (stderr, "Partition %s%d has invalid starting sector 0.\n",
+                disk_device, t+1);
+        return;
+      }
+      printf ("Reading disklabel of %s%d at sector %d.\n",
+             disk_device, t+1, bsd_part -> start_sect + BSD_LABELSECTOR);
+      if (bsd_readlabel (bsd_part, &bsd_dlabel) == 0)
+        if (bsd_create_disklabel () == 0)
+         return;
+      break;
+    }
+
+  if (t == 4)
+  {
+    printf ("There is no NetBSD partition on %s.\n", disk_device);
+    return;
+  }
+
+#elif defined (__alpha__)
+
+  if (bsd_readlabel (NULL, &bsd_dlabel) == 0)
+    if (bsd_create_disklabel () == 0)
+      exit ( EXIT_SUCCESS );
+
+#endif
+
+  while (1)
+  {
+    putchar ('\n');
+    switch (tolower (read_char ("BSD disklabel command (m for help): ")))
+    {
+      case 'd':
+        bsd_delete_part ();
+       break;
+      case 'e':
+        bsd_edit_disklabel ();
+       break;
+      case 'i':
+        bsd_write_bootstrap ();
+       break;
+      case 'l':
+        bsd_list_types ();
+       break;
+      case 'n':
+       bsd_new_part ();
+       break;
+      case 'p':
+       bsd_print_disklabel (0);
+       break;
+      case 'q':
+       close (fd);
+       exit ( EXIT_SUCCESS );
+      case 's':
+       bsd_print_disklabel (1);
+       break;
+      case 't':
+        bsd_change_fstype ();
+       break;
+      case 'w':
+       bsd_write_disklabel ();
+       break;
+#if defined (i386)
+      case 'r':
+       return;
+      case 'x':
+       bsd_link_part ();
+       break;
+#endif
+      default:
+       bmenu ();
+       break;
+    }
+  }
+}
+
+static void
+bsd_delete_part (void)
+{
+  int i;
+
+  i = bsd_get_part_index (bsd_dlabel.d_npartitions);
+  bsd_dlabel.d_partitions[i].p_size   = 0;
+  bsd_dlabel.d_partitions[i].p_offset = 0;
+  bsd_dlabel.d_partitions[i].p_fstype = BSD_FS_UNUSED;  
+  if (bsd_dlabel.d_npartitions == i + 1)
+    while (bsd_dlabel.d_partitions[bsd_dlabel.d_npartitions-1].p_size == 0)
+      bsd_dlabel.d_npartitions--;
+}
+
+static void
+bsd_new_part (void)
+{
+  uint begin, end;
+  char mesg[48];
+  int i;
+
+  if (!bsd_check_new_partition (&i))
+    return;
+
+#if defined (i386)
+  begin = bsd_part -> start_sect;
+  end = begin + bsd_part -> nr_sects - 1;
+#elif defined (__alpha__)
+  begin = 0;
+  end = bsd_dlabel.d_secperunit;
+#endif
+
+  sprintf (mesg, "First %s", str_units());
+  begin = read_int (cround (begin), cround (begin), cround (end), ignore, mesg);
+
+  sprintf (mesg, "Last %s or +size or +sizeM or +sizeK", str_units());
+  end = read_int (cround (begin), cround (end), cround (end), ignore, mesg);
+
+  if (unit_flag)
+  {
+    begin = (begin - 1) * display_factor;
+    end = end * display_factor - 1;
+  }
+  bsd_dlabel.d_partitions[i].p_size   = end - begin + 1;
+  bsd_dlabel.d_partitions[i].p_offset = begin;
+  bsd_dlabel.d_partitions[i].p_fstype = BSD_FS_UNUSED; 
+}
+
+static void
+bsd_print_disklabel (int show_all)
+{
+  struct disklabel *lp = &bsd_dlabel;
+  struct bsd_partition *pp;
+  FILE *f = stdout;
+  int i, j;
+
+  if (show_all)
+  {
+#if defined (i386)
+    fprintf(f, "# %s%d:\n", disk_device, bsd_part_index+1);
+#elif defined (__alpha__)
+    fprintf(f, "# %s:\n", disk_device);
+#endif
+    if ((unsigned) lp->d_type < BSD_DKMAXTYPES)
+      fprintf(f, "type: %s\n", bsd_dktypenames[lp->d_type]);
+    else
+      fprintf(f, "type: %d\n", lp->d_type);
+    fprintf(f, "disk: %.*s\n", sizeof(lp->d_typename), lp->d_typename);
+    fprintf(f, "label: %.*s\n", sizeof(lp->d_packname), lp->d_packname);
+    fprintf(f, "flags:");
+    if (lp->d_flags & BSD_D_REMOVABLE)
+      fprintf(f, " removable");
+    if (lp->d_flags & BSD_D_ECC)
+      fprintf(f, " ecc");
+    if (lp->d_flags & BSD_D_BADSECT)
+      fprintf(f, " badsect");
+    fprintf(f, "\n");
+    fprintf(f, "bytes/sector: %d\n", lp->d_secsize);
+    fprintf(f, "sectors/track: %d\n", lp->d_nsectors);
+    fprintf(f, "tracks/cylinder: %d\n", lp->d_ntracks);
+    fprintf(f, "sectors/cylinder: %d\n", lp->d_secpercyl);
+    fprintf(f, "cylinders: %d\n", lp->d_ncylinders);
+    fprintf(f, "rpm: %d\n", lp->d_rpm);
+    fprintf(f, "interleave: %d\n", lp->d_interleave);
+    fprintf(f, "trackskew: %d\n", lp->d_trackskew);
+    fprintf(f, "cylinderskew: %d\n", lp->d_cylskew);
+    fprintf(f, "headswitch: %d\t\t# milliseconds\n", lp->d_headswitch);
+    fprintf(f, "track-to-track seek: %d\t# milliseconds\n", lp->d_trkseek);
+    fprintf(f, "drivedata: ");
+    for (i = NDDATA - 1; i >= 0; i--)
+      if (lp->d_drivedata[i])
+       break;
+    if (i < 0)
+      i = 0;
+    for (j = 0; j <= i; j++)
+      fprintf(f, "%d ", lp->d_drivedata[j]);
+  }
+  fprintf (f, "\n%d partitions:\n", lp->d_npartitions);
+  fprintf (f, "#        size   offset    fstype   [fsize bsize   cpg]\n");
+  pp = lp->d_partitions;
+  for (i = 0; i < lp->d_npartitions; i++, pp++) {
+    if (pp->p_size) {
+      fprintf(f, "  %c: %8d %8d  ", 'a' + i,
+             pp->p_size, pp->p_offset);
+      if ((unsigned) pp->p_fstype < BSD_FSMAXTYPES)
+       fprintf(f, "%8.8s", bsd_fstypes[pp->p_fstype].name);
+      else
+       fprintf(f, "%8x", pp->p_fstype);
+      switch (pp->p_fstype)
+      {
+        case BSD_FS_UNUSED:
+         fprintf(f, "    %5d %5d %5.5s ",
+                 pp->p_fsize, pp->p_fsize * pp->p_frag, "");
+         break;
+         
+       case BSD_FS_BSDFFS:
+         fprintf(f, "    %5d %5d %5d ",
+                 pp->p_fsize, pp->p_fsize * pp->p_frag,
+                 pp->p_cpg);
+         break;
+         
+       default:
+         fprintf(f, "%20.20s", "");
+         break;
+      }
+      fprintf(f, "\t# (Cyl. %4d",
+#if 0
+             pp->p_offset / lp->d_secpercyl); /* differs from Linux fdisk */
+#else
+             pp->p_offset / lp->d_secpercyl + 1);
+#endif
+      if (pp->p_offset % lp->d_secpercyl)
+       putc('*', f);
+      else
+       putc(' ', f);
+      fprintf(f, "- %d",
+             (pp->p_offset + 
+              pp->p_size + lp->d_secpercyl - 1) /
+#if 0
+             lp->d_secpercyl - 1); /* differs from Linux fdisk */
+#else
+             lp->d_secpercyl);
+#endif
+      if (pp->p_size % lp->d_secpercyl)
+       putc('*', f);
+      fprintf(f, ")\n");
+    }
+  }
+}
+
+static void
+bsd_write_disklabel (void)
+{
+#if defined (i386)
+  printf ("Writing disklabel to %s%d.\n", disk_device, bsd_part_index+1);
+  bsd_writelabel (bsd_part, &bsd_dlabel);
+#elif defined (__alpha__)
+  printf ("Writing disklabel to %s.\n", disk_device);
+  bsd_writelabel (NULL, &bsd_dlabel);
+#endif
+}
+
+static int
+bsd_create_disklabel (void)
+{
+  char c;
+
+#if defined (i386)
+  fprintf (stderr, "%s%d contains no disklabel.\n",
+          disk_device, bsd_part_index+1);
+#elif defined (__alpha__)
+  fprintf (stderr, "%s contains no disklabel.\n", disk_device);
+#endif
+
+  while (1)
+    if ((c = tolower (read_char ("Do you want to create a disklabel? (y/n) "))) == 'y')
+    {
+#if defined (i386)
+      if (bsd_initlabel (bsd_part, &bsd_dlabel, bsd_part_index) == 1)
+#elif defined (__alpha__)
+      if (bsd_initlabel (NULL, &bsd_dlabel, 0) == 1)
+#endif
+      {
+        bsd_print_disklabel (1);
+       return 1;
+      }
+      else
+       return 0;
+    }
+    else if (c == 'n')
+      return 0;
+}
+
+static int
+edit_int (int def, char *mesg)
+{
+  do {
+    fputs (mesg, stdout);
+    printf (" (%d): ", def);
+    if (!read_line ())
+      return def;
+  }
+  while (!isdigit (*line_ptr));
+  return atoi (line_ptr);
+} 
+
+static void
+bsd_edit_disklabel (void)
+{
+  struct disklabel *d;
+
+  d = &bsd_dlabel;
+
+#ifdef __alpha__
+  d -> d_secsize    = (u_long) edit_int ((u_long) d -> d_secsize     ,"bytes/sector");
+  d -> d_nsectors   = (u_long) edit_int ((u_long) d -> d_nsectors    ,"sectors/track");
+  d -> d_ntracks    = (u_long) edit_int ((u_long) d -> d_ntracks     ,"tracks/cylinder");
+  d -> d_ncylinders = (u_long) edit_int ((u_long) d -> d_ncylinders  ,"cylinders");
+#endif
+
+  /* d -> d_secpercyl can be != d -> d_nsectors * d -> d_ntracks */
+  while (1)
+  {
+    d -> d_secpercyl = (u_long) edit_int ((u_long) d -> d_nsectors * d -> d_ntracks,
+                                         "sectors/cylinder");
+    if (d -> d_secpercyl <= d -> d_nsectors * d -> d_ntracks)
+      break;
+
+    printf ("Must be <= sectors/track * tracks/cylinder (default).\n");
+  }
+  d -> d_rpm        = (u_short) edit_int ((u_short) d -> d_rpm       ,"rpm");
+  d -> d_interleave = (u_short) edit_int ((u_short) d -> d_interleave,"interleave");
+  d -> d_trackskew  = (u_short) edit_int ((u_short) d -> d_trackskew ,"trackskew");
+  d -> d_cylskew    = (u_short) edit_int ((u_short) d -> d_cylskew   ,"cylinderskew");
+  d -> d_headswitch = (u_long) edit_int ((u_long) d -> d_headswitch  ,"headswitch");
+  d -> d_trkseek    = (u_long) edit_int ((u_long) d -> d_trkseek     ,"track-to-track seek");
+
+  d -> d_secperunit = d -> d_secpercyl * d -> d_ncylinders;
+}
+
+static int
+bsd_get_bootstrap (char *path, void *ptr, int size)
+{
+  int fd;
+
+  if ((fd = open (path, O_RDONLY)) < 0)
+  {
+    perror (path);
+    return 0;
+  }
+  if (read (fd, ptr, size) < 0)
+  {
+    perror (path);
+    close (fd);
+    return 0;
+  }
+  printf (" ... %s\n", path);
+  close (fd);
+  return 1;
+}
+
+static void
+bsd_write_bootstrap (void)
+{
+  char *bootdir = BSD_LINUX_BOOTDIR;
+  char path[MAXPATHLEN];
+  char *dkbasename;
+  struct disklabel dl;
+  char *d, *p, *e;
+  int sector;
+
+  if (bsd_dlabel.d_type == BSD_DTYPE_SCSI)
+    dkbasename = "sd";
+  else
+    dkbasename = "wd";
+
+  printf ("Bootstrap: %sboot -> boot%s (%s): ", dkbasename, dkbasename, dkbasename);
+  if (read_line ())
+  {
+    line_ptr[strlen (line_ptr)-1] = '\0';
+    dkbasename = line_ptr;
+  }
+  sprintf (path, "%s/%sboot", bootdir, dkbasename);
+  if (!bsd_get_bootstrap (path, buffer, (int) bsd_dlabel.d_secsize))
+    return;
+
+  /* We need a backup of the disklabel (bsd_dlabel might have changed). */
+  d = &buffer[BSD_LABELSECTOR * SECTOR_SIZE];
+  bcopy (d, &dl, sizeof (struct disklabel));
+
+  /* The disklabel will be overwritten by 0's from bootxx anyway */
+  bzero (d, sizeof (struct disklabel));
+
+  sprintf (path, "%s/boot%s", bootdir, dkbasename);
+  if (!bsd_get_bootstrap (path, &buffer[bsd_dlabel.d_secsize],
+                         (int) bsd_dlabel.d_bbsize - bsd_dlabel.d_secsize))
+    return;
+
+  e = d + sizeof (struct disklabel);
+  for (p=d; p < e; p++)
+    if (*p)
+    {
+      fprintf (stderr, "Bootstrap overlaps with disk label!\n");
+      exit ( EXIT_FAILURE );
+    }
+
+  bcopy (&dl, d, sizeof (struct disklabel));
+
+#if defined (i386)
+  sector = bsd_part -> start_sect;
+#elif defined (__alpha__)
+  sector = 0;
+  alpha_bootblock_checksum (buffer);
+#endif
+
+  if (ext2_llseek (fd, sector * SECTOR_SIZE, SEEK_SET) == -1)
+    fatal (unable_to_seek);
+  if (BSD_BBSIZE != write (fd, buffer, BSD_BBSIZE))
+    fatal (unable_to_write);
+
+#if defined (i386)
+  printf ("Bootstrap installed on %s%d.\n", disk_device, bsd_part_index+1);
+#elif defined (__alpha__)
+  printf ("Bootstrap installed on %s.\n", disk_device);
+#endif
+
+  sync_disks ();
+}
+
+static void
+bsd_change_fstype (void)
+{
+  int i;
+
+  i = bsd_get_part_index (bsd_dlabel.d_npartitions);
+  bsd_dlabel.d_partitions[i].p_fstype = read_hex (bsd_fstypes, BSD_FSMAXTYPES);
+}
+
+static int
+bsd_get_part_index (int max)
+{
+  char prompt[40];
+  char l;
+
+  sprintf (prompt, "Partition (a-%c): ", 'a' + max - 1);
+  do
+     l = tolower (read_char (prompt));
+  while (l < 'a' || l > 'a' + max - 1);
+  return l - 'a';
+}
+
+static int
+bsd_check_new_partition (int *i)
+{
+  int t;
+
+  if (bsd_dlabel.d_npartitions == BSD_MAXPARTITIONS)
+  {
+    for (t=0; t < BSD_MAXPARTITIONS; t++)
+      if (bsd_dlabel.d_partitions[t].p_size == 0)
+       break;
+
+    if (t == BSD_MAXPARTITIONS)
+    {
+      fprintf (stderr, "The maximum number of partitions has been created\n");
+      return 0;
+    }
+  }
+  *i = bsd_get_part_index (BSD_MAXPARTITIONS);
+
+  if (*i >= bsd_dlabel.d_npartitions)
+    bsd_dlabel.d_npartitions = (*i) + 1;
+
+  if (bsd_dlabel.d_partitions[*i].p_size != 0)
+  {
+    fprintf (stderr, "This partition already exists.\n");
+    return 0;
+  }
+  return 1;
+}
+
+static void
+bsd_list_types (void)
+{
+  list_types (bsd_fstypes, BSD_FSMAXTYPES);
+}
+
+static u_short
+bsd_dkcksum (struct disklabel *lp)
+{
+  register u_short *start, *end;
+  register u_short sum = 0;
+  
+  start = (u_short *)lp;
+  end = (u_short *)&lp->d_partitions[lp->d_npartitions];
+  while (start < end)
+    sum ^= *start++;
+  return (sum);
+}
+
+static int
+bsd_initlabel (struct partition *p, struct disklabel *d, int pindex)
+{
+  struct hd_geometry geometry;
+  struct bsd_partition *pp;
+
+  if (ioctl (fd, HDIO_GETGEO, &geometry) == -1)
+  {
+    perror ("ioctl");
+    return 0;
+  }
+  bzero (d, sizeof (struct disklabel));
+
+  d -> d_magic = BSD_DISKMAGIC;
+
+  if (strncmp (disk_device, "/dev/sd", 7) == 0)
+    d -> d_type = BSD_DTYPE_SCSI;
+  else
+    d -> d_type = BSD_DTYPE_ST506;
+
+#if 0 /* not used (at least not written to disk) by NetBSD/i386 1.0 */
+  d -> d_subtype = BSD_DSTYPE_INDOSPART & pindex;
+#endif
+
+#if defined (i386)
+  d -> d_flags = BSD_D_DOSPART;
+#else
+  d -> d_flags = 0;
+#endif
+  d -> d_secsize = SECTOR_SIZE;       /* bytes/sector  */
+  d -> d_nsectors = geometry.sectors; /* sectors/track */
+  d -> d_ntracks = geometry.heads;    /* tracks/cylinder (heads) */
+  d -> d_ncylinders = geometry.cylinders;
+  d -> d_secpercyl  = geometry.sectors * geometry.heads; /* sectors/cylinder */
+  d -> d_secperunit = d -> d_secpercyl * d -> d_ncylinders;
+
+  d -> d_rpm = 3600;
+  d -> d_interleave = 1;
+  d -> d_trackskew = 0;
+  d -> d_cylskew = 0;
+  d -> d_headswitch = 0;
+  d -> d_trkseek = 0;
+
+  d -> d_magic2 = BSD_DISKMAGIC;
+  d -> d_bbsize = BSD_BBSIZE;
+  d -> d_sbsize = BSD_SBSIZE;
+
+#if defined (i386)
+  d -> d_npartitions = 4;
+  pp = &d -> d_partitions[2]; /* Partition C should be the NetBSD partition */
+  pp -> p_offset = p -> start_sect;
+  pp -> p_size   = p -> nr_sects;
+  pp -> p_fstype = BSD_FS_UNUSED;
+  pp = &d -> d_partitions[3]; /* Partition D should be the whole disk */
+  pp -> p_offset = 0;
+  pp -> p_size   = d -> d_secperunit;
+  pp -> p_fstype = BSD_FS_UNUSED;
+#elif defined (__alpha__)
+  d -> d_npartitions = 3;
+  pp = &d -> d_partitions[2]; /* Partition C should be the whole disk */
+  pp -> p_offset = 0;
+  pp -> p_size   = d -> d_secperunit;
+  pp -> p_fstype = BSD_FS_UNUSED;  
+#endif
+
+  return 1;
+}
+
+static int
+bsd_readlabel (struct partition *p, struct disklabel *d)
+{
+  int t, sector;
+
+#if defined (i386)
+  sector = p -> start_sect;
+#elif defined (__alpha__)
+  sector = 0;
+#endif
+
+  if (ext2_llseek (fd, sector * SECTOR_SIZE, SEEK_SET) == -1)
+    fatal (unable_to_seek);
+  if (BSD_BBSIZE != read (fd, buffer, BSD_BBSIZE))
+    fatal (unable_to_read);
+
+  bcopy (&buffer[BSD_LABELSECTOR * SECTOR_SIZE + BSD_LABELOFFSET],
+        d, sizeof (struct disklabel));
+
+  for (t = d -> d_npartitions; t < BSD_MAXPARTITIONS; t++)
+  {
+    d -> d_partitions[t].p_size   = 0;
+    d -> d_partitions[t].p_offset = 0;
+    d -> d_partitions[t].p_fstype = BSD_FS_UNUSED;  
+  }
+  if (d -> d_magic != BSD_DISKMAGIC || d -> d_magic2 != BSD_DISKMAGIC)
+    return 0;
+
+  if (d -> d_npartitions > BSD_MAXPARTITIONS)
+    fprintf (stderr, "Warning: too many partitions (%d, maximum is %d).\n",
+            d -> d_npartitions, BSD_MAXPARTITIONS);
+  return 1;
+}
+
+static int
+bsd_writelabel (struct partition *p, struct disklabel *d)
+{
+  int sector;
+
+#if defined (i386)
+  sector = p -> start_sect + BSD_LABELSECTOR;
+#elif defined (__alpha__)
+  sector = BSD_LABELSECTOR;
+#endif
+
+  d -> d_checksum = 0;
+  d -> d_checksum = bsd_dkcksum (d);
+
+  /* This is necessary if we want to write the bootstrap later,
+     otherwise we'd write the old disklabel with the bootstrap.
+  */
+  bcopy (d, &buffer[BSD_LABELSECTOR * SECTOR_SIZE + BSD_LABELOFFSET],
+        sizeof (struct disklabel));
+
+#if defined (__alpha__) && BSD_LABELSECTOR == 0
+  alpha_bootblock_checksum (buffer);
+  if (ext2_llseek (fd, 0, SEEK_SET) == -1)
+    fatal (unable_to_seek);
+  if (BSD_BBSIZE != write (fd, buffer, BSD_BBSIZE))
+    fatal (unable_to_write);
+#else
+  if (ext2_llseek (fd, sector * SECTOR_SIZE + BSD_LABELOFFSET, SEEK_SET) == -1)
+    fatal (unable_to_seek);
+  if (sizeof (struct disklabel) != write (fd, d, sizeof (struct disklabel)))
+    fatal (unable_to_write);
+#endif
+
+  sync_disks ();
+
+  return 1;
+}
+
+static void
+sync_disks (void)
+{
+  printf ("\nSyncing disks.\n");
+  sync ();
+  sleep (4);
+}
+
+#if defined (i386)
+static int
+bsd_translate_fstype (int linux_type)
+{
+  switch (linux_type)
+  {
+    case 0x01: /* DOS 12-bit FAT   */
+    case 0x04: /* DOS 16-bit <32M  */
+    case 0x06: /* DOS 16-bit >=32M */
+    case 0xe1: /* DOS access       */
+    case 0xe3: /* DOS R/O          */
+    case 0xf2: /* DOS secondary    */
+      return BSD_FS_MSDOS;
+    case 0x07: /* OS/2 HPFS        */
+      return BSD_FS_HPFS;
+    default:
+      return BSD_FS_OTHER;
+  }
+}
+
+static void
+bsd_link_part (void)
+{
+  int k, i;
+
+  k = get_partition (1, partitions);
+
+  if (!bsd_check_new_partition (&i))
+    return;
+
+  bsd_dlabel.d_partitions[i].p_size   = part_table[k] -> nr_sects;
+  bsd_dlabel.d_partitions[i].p_offset = part_table[k] -> start_sect;
+  bsd_dlabel.d_partitions[i].p_fstype =
+    bsd_translate_fstype (part_table[k] -> sys_ind);
+}
+#endif
+
+#if defined (__alpha__)
+typedef unsigned long long u_int64_t;
+
+void
+alpha_bootblock_checksum (char *boot)
+{
+  u_int64_t *dp, sum;
+  int i;
+  
+  dp = (u_int64_t *)boot;
+  sum = 0;
+  for (i = 0; i < 63; i++)
+    sum += dp[i];
+  dp[63] = sum;
+}
+#endif /* __alpha__ */
diff --git a/disk-utils/fdisklabel.h b/disk-utils/fdisklabel.h
new file mode 100644 (file)
index 0000000..841046b
--- /dev/null
@@ -0,0 +1,233 @@
+/*
+ * Copyright (c) 1987, 1988 Regents of the University of California.
+ * 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 the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS 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.
+ */
+
+#define BSD_DISKMAGIC     ((u_long) 0x82564557)
+#define        BSD_MAXPARTITIONS 8
+#define BSD_LINUX_BOOTDIR "/usr/ucb/mdec"
+
+#if defined (i386)
+#define BSD_LABELSECTOR   1
+#define BSD_LABELOFFSET   0
+#define        BSD_BBSIZE        8192          /* size of boot area, with label */
+#define        BSD_SBSIZE        8192          /* max size of fs superblock */
+#elif defined (__alpha__)
+#error LABELSECTOR, LABELOFFSET, BBSIZE & SBSIZE are undefined for __alpha__
+#define BSD_LABELSECTOR   0
+#define BSD_LABELOFFSET   0
+#define        BSD_BBSIZE        0
+#define        BSD_SBSIZE        0
+#else
+#error unknown architecture
+#endif
+
+struct disklabel {
+       u_long  d_magic;                /* the magic number */
+       short   d_type;                 /* drive type */
+       short   d_subtype;              /* controller/d_type specific */
+       char    d_typename[16];         /* type name, e.g. "eagle" */
+       /* 
+        * d_packname contains the pack identifier and is returned when
+        * the disklabel is read off the disk or in-core copy.
+        * d_boot0 and d_boot1 are the (optional) names of the
+        * primary (block 0) and secondary (block 1-15) bootstraps
+        * as found in /usr/mdec.  These are returned when using
+        * getdiskbyname(3) to retrieve the values from /etc/disktab.
+        */
+#if defined(KERNEL) || defined(STANDALONE)
+       char    d_packname[16];                 /* pack identifier */ 
+#else
+       union {
+               char    un_d_packname[16];      /* pack identifier */ 
+               struct {
+                       char *un_d_boot0;       /* primary bootstrap name */
+                       char *un_d_boot1;       /* secondary bootstrap name */
+               } un_b; 
+       } d_un; 
+#define d_packname     d_un.un_d_packname
+#define d_boot0                d_un.un_b.un_d_boot0
+#define d_boot1                d_un.un_b.un_d_boot1
+#endif /* ! KERNEL or STANDALONE */
+                       /* disk geometry: */
+       u_long  d_secsize;              /* # of bytes per sector */
+       u_long  d_nsectors;             /* # of data sectors per track */
+       u_long  d_ntracks;              /* # of tracks per cylinder */
+       u_long  d_ncylinders;           /* # of data cylinders per unit */
+       u_long  d_secpercyl;            /* # of data sectors per cylinder */
+       u_long  d_secperunit;           /* # of data sectors per unit */
+       /*
+        * Spares (bad sector replacements) below
+        * are not counted in d_nsectors or d_secpercyl.
+        * Spare sectors are assumed to be physical sectors
+        * which occupy space at the end of each track and/or cylinder.
+        */
+       u_short d_sparespertrack;       /* # of spare sectors per track */
+       u_short d_sparespercyl;         /* # of spare sectors per cylinder */
+       /*
+        * Alternate cylinders include maintenance, replacement,
+        * configuration description areas, etc.
+        */
+       u_long  d_acylinders;           /* # of alt. cylinders per unit */
+
+                       /* hardware characteristics: */
+       /*
+        * d_interleave, d_trackskew and d_cylskew describe perturbations
+        * in the media format used to compensate for a slow controller.
+        * Interleave is physical sector interleave, set up by the formatter
+        * or controller when formatting.  When interleaving is in use,
+        * logically adjacent sectors are not physically contiguous,
+        * but instead are separated by some number of sectors.
+        * It is specified as the ratio of physical sectors traversed
+        * per logical sector.  Thus an interleave of 1:1 implies contiguous
+        * layout, while 2:1 implies that logical sector 0 is separated
+        * by one sector from logical sector 1.
+        * d_trackskew is the offset of sector 0 on track N
+        * relative to sector 0 on track N-1 on the same cylinder.
+        * Finally, d_cylskew is the offset of sector 0 on cylinder N
+        * relative to sector 0 on cylinder N-1.
+        */
+       u_short d_rpm;                  /* rotational speed */
+       u_short d_interleave;           /* hardware sector interleave */
+       u_short d_trackskew;            /* sector 0 skew, per track */
+       u_short d_cylskew;              /* sector 0 skew, per cylinder */
+       u_long  d_headswitch;           /* head switch time, usec */
+       u_long  d_trkseek;              /* track-to-track seek, usec */
+       u_long  d_flags;                /* generic flags */
+#define NDDATA 5
+       u_long  d_drivedata[NDDATA];    /* drive-type specific information */
+#define NSPARE 5
+       u_long  d_spare[NSPARE];        /* reserved for future use */
+       u_long  d_magic2;               /* the magic number (again) */
+       u_short d_checksum;             /* xor of data incl. partitions */
+                       /* filesystem and partition information: */
+       u_short d_npartitions;          /* number of partitions in following */
+       u_long  d_bbsize;               /* size of boot area at sn0, bytes */
+       u_long  d_sbsize;               /* max size of fs superblock, bytes */
+       struct bsd_partition {          /* the partition table */
+               u_long  p_size;         /* number of sectors in partition */
+               u_long  p_offset;       /* starting sector */
+               u_long  p_fsize;        /* filesystem basic fragment size */
+               u_char  p_fstype;       /* filesystem type, see below */
+               u_char  p_frag;         /* filesystem fragments per block */
+               u_short p_cpg;          /* filesystem cylinders per group */
+       } d_partitions[BSD_MAXPARTITIONS]; /* actually may be more */
+};
+
+/* d_type values: */
+#define        BSD_DTYPE_SMD           1               /* SMD, XSMD; VAX hp/up */
+#define        BSD_DTYPE_MSCP          2               /* MSCP */
+#define        BSD_DTYPE_DEC           3               /* other DEC (rk, rl) */
+#define        BSD_DTYPE_SCSI          4               /* SCSI */
+#define        BSD_DTYPE_ESDI          5               /* ESDI interface */
+#define        BSD_DTYPE_ST506         6               /* ST506 etc. */
+#define        BSD_DTYPE_HPIB          7               /* CS/80 on HP-IB */
+#define BSD_DTYPE_HPFL         8               /* HP Fiber-link */
+#define        BSD_DTYPE_FLOPPY        10              /* floppy */
+
+/* d_subtype values: */
+#define BSD_DSTYPE_INDOSPART   0x8             /* is inside dos partition */
+#define BSD_DSTYPE_DOSPART(s)  ((s) & 3)       /* dos partition number */
+#define BSD_DSTYPE_GEOMETRY    0x10            /* drive params in label */
+
+#ifdef DKTYPENAMES
+static char *bsd_dktypenames[] = {
+       "unknown",
+       "SMD",
+       "MSCP",
+       "old DEC",
+       "SCSI",
+       "ESDI",
+       "ST506",
+       "HP-IB",
+       "HP-FL",
+       "type 9",
+       "floppy",
+       0
+};
+#define BSD_DKMAXTYPES (sizeof(bsd_dktypenames) / sizeof(bsd_dktypenames[0]) - 1)
+#endif
+
+/*
+ * Filesystem type and version.
+ * Used to interpret other filesystem-specific
+ * per-partition information.
+ */
+#define        BSD_FS_UNUSED   0               /* unused */
+#define        BSD_FS_SWAP     1               /* swap */
+#define        BSD_FS_V6       2               /* Sixth Edition */
+#define        BSD_FS_V7       3               /* Seventh Edition */
+#define        BSD_FS_SYSV     4               /* System V */
+#define        BSD_FS_V71K     5               /* V7 with 1K blocks (4.1, 2.9) */
+#define        BSD_FS_V8       6               /* Eighth Edition, 4K blocks */
+#define        BSD_FS_BSDFFS   7               /* 4.2BSD fast file system */
+#define        BSD_FS_MSDOS    8               /* MS-DOS file system */
+#define        BSD_FS_BSDLFS   9               /* 4.4BSD log-structured file system */
+#define        BSD_FS_OTHER    10              /* in use, but unknown/unsupported */
+#define        BSD_FS_HPFS     11              /* OS/2 high-performance file system */
+#define        BSD_FS_ISO9660  12              /* ISO-9660 filesystem (cdrom) */
+#define BSD_FS_ISOFS   BSD_FS_ISO9660
+#define        BSD_FS_BOOT     13              /* partition contains bootstrap */
+#define BSD_FS_ADOS    14              /* AmigaDOS fast file system */
+#define BSD_FS_HFS     15              /* Macintosh HFS */
+
+#ifdef DKTYPENAMES
+static struct systypes bsd_fstypes[] = {
+        {BSD_FS_UNUSED, "unused"},
+       {BSD_FS_SWAP,   "swap"},
+       {BSD_FS_V6,     "Version 6"},
+       {BSD_FS_V7,     "Version 7"},
+       {BSD_FS_SYSV,   "System V"},
+       {BSD_FS_V71K,   "4.1BSD"},
+       {BSD_FS_V8,     "Eighth Edition"},
+       {BSD_FS_BSDFFS, "4.2BSD"},
+       {BSD_FS_MSDOS,  "MS-DOS"},
+       {BSD_FS_BSDLFS, "4.4LFS"},
+       {BSD_FS_OTHER,  "unknown"},
+       {BSD_FS_HPFS,   "HPFS"},
+       {BSD_FS_ISO9660,"ISO-9660"},
+       {BSD_FS_BOOT,   "boot"},
+       {BSD_FS_ADOS,   "ADOS"},
+       {BSD_FS_HFS,    "HFS"}
+};
+
+#define BSD_FSMAXTYPES (sizeof(bsd_fstypes) / sizeof(struct systypes))
+#endif
+
+/*
+ * flags shared by various drives:
+ */
+#define        BSD_D_REMOVABLE 0x01            /* removable media */
+#define        BSD_D_ECC       0x02            /* supports ECC */
+#define        BSD_D_BADSECT   0x04            /* supports bad sector forw. */
+#define        BSD_D_RAMDISK   0x08            /* disk emulator */
+#define        BSD_D_CHAIN     0x10            /* can do back-back transfers */
+#define        BSD_D_DOSPART   0x20            /* within MSDOS partition */
index 32bbe48817e502cfa4d41b583cfd33a18c1b3689..024e1b7a3ab7d21c1f0a59518384fafd61f62193 100644 (file)
@@ -123,3 +123,6 @@ Error code values by Rik Faith (faith@cs.unc.edu)
 .br
 Added support for file system valid flag: Dr. Wettstein
 (greg%wind.uucp@plains.nodak.edu)
+.br
+Check to prevent fsck of mounted filesystem added by Daniel Quinlan
+(quinlan@yggdrasil.com)
index 66166d3a898fbc0b8ca467bf490fd2c57eb95aa6..3e59ec953ee361ad9a32cd602c68e07f677abb21 100644 (file)
@@ -5,16 +5,19 @@
  * under the terms of the GNU Public License.
  */
 
+#define FOR_UTIL_LINUX
+
 #include <sys/types.h>
 
 #include <errno.h>
 #include <unistd.h>
 #include <linux/unistd.h>
-#if 0
+#ifndef FOR_UTIL_LINUX
 #include "et/com_err.h"
 #include "ext2fs/io.h"
 #endif
 
+#ifdef FOR_UTIL_LINUX
 #if defined(__GNUC__) || defined(HAS_LONG_LONG)
 typedef long long ext2_loff_t;
 #else
@@ -24,6 +27,7 @@ typedef long      ext2_loff_t;
 extern ext2_loff_t ext2_llseek(unsigned int fd,
                               ext2_loff_t offset,
                               unsigned int origin);
+#endif
 
 #ifdef __linux__
 
@@ -47,8 +51,15 @@ ext2_loff_t ext2_llseek (unsigned int fd, ext2_loff_t offset,
        int retval;
        static int do_compat = 0;
 
-       if (do_compat)
+       if (do_compat) {
+       compat_lseek:
+               if ((sizeof(off_t) < sizeof(ext2_loff_t)) &&
+                   (offset >= ((ext2_loff_t) 1 << ((sizeof(off_t)*8) -1)))) {
+                       errno = -EINVAL;
+                       return -1;
+               }
                return lseek (fd, (off_t) offset, origin);
+       }
        
        offset_high = ((unsigned long long) offset) >> 32;
        offset_low = ((unsigned long long) offset) & 0xffffffff;
@@ -59,7 +70,7 @@ ext2_loff_t ext2_llseek (unsigned int fd, ext2_loff_t offset,
                 * which does not support the llseek system call
                 */
                do_compat++;
-               return lseek (fd, (off_t) offset, origin);
+               goto compat_lseek;
        }
        if (retval == -1)
                result = -1;
index 48b223425dc8b32ebdaf293a4e2a336e259a923d..e391f7141b9ed28710504b347d9d7d987aad9b09 100644 (file)
@@ -1,12 +1,9 @@
 .\" -*- nroff -*-
-.TH FSCK 8 "Jul 1993" "Version 1.8"
+.TH MKFS 8 "Jun 1995" "Version 1.9"
 .SH NAME
-fsck \- check and repair a Linux file system
+mkfs \- build a Linux file system
 .SH SYNOPSIS
-.B fsck
-[
-.B \-A
-]
+.B mkfs
 [
 .B \-V
 ]
@@ -18,62 +15,35 @@ fsck \- check and repair a Linux file system
 .B fs-options
 ]
 .I filesys
+[
+.I blocks
+]
 .SH DESCRIPTION
-.B fsck
-is used to check and optionally repair a Linux file system.
+.B mkfs
+is used to build a Linux file system on a device, usually
+a hard disk partition.
 .I filesys
 is either the device name (e.g. /dev/hda1, /dev/sdb2) or
 the mount point (e.g. /, /usr, /home) for the file system.
+.I blocks
+is the number of blocks to be used for the file system.
 .PP
 The exit code returned by
-.B fsck
-is the sum of the following conditions:
-.br
-\      0\      \-\ No errors
-.br
-\      1\      \-\ File system errors corrected
-.br
-\      2\      \-\ File system errors corrected, system should
-.br
-\      \       \ \ be rebooted if file system was mounted
-.br
-\      4\      \-\ File system errors left uncorrected
-.br
-\      8\      \-\ Operational error
-.br
-\      16\     \-\ Usage or syntax error
-.br
-\      128\    \-\ Shared library error
-.br
-The exit code returned when all file systems are checked using the
-.B -A
-option is the bit-wise OR of the exit codes for each
-file system that is checked.
+.B mkfs
+is 0 on success and 1 on failure.
 .PP
 In actuality,
-.B fsck
-is simply a front-end for the various file system checkers
-(\fBfsck\fR.\fIfstype\fR)
+.B mkfs
+is simply a front-end for the various file system builders
+(\fBmkfs\fR.\fIfstype\fR)
 available under Linux.
-The file system-specific checker is searched for in /etc/fs first,
+The file system-specific builder is searched for in /etc/fs first,
 then in /etc and finally in the directories listed in the PATH
-environment variable.
-Please see the file system-specific checker manual pages for
+enviroment variable.
+Please see the file system-specific builder manual pages for
 further details.
 .SH OPTIONS
 .TP
-.B -A
-Walk through the
-.I /etc/fstab
-file and try to check all file systems in one run.  This option is
-typically used from the
-.I /etc/rc
-system initalization file, instead of multiple commands for checking
-a single file system.  Note, that with this option, you cannot give
-the
-.I filesys
-argument as well.
-.TP
 .B -V
 Produce verbose output, including all file system-specific commands
 that are executed.
@@ -82,7 +52,7 @@ file system-specific commands.
 This is really only useful for testing.
 .TP
 .BI -t \ fstype
-Specifies the type of file system to be checked.
+Specifies the type of file system to be built.
 If not specified, the type is deduced by searching for
 .I filesys
 in
@@ -93,24 +63,18 @@ If the type can not be deduced, the default file system type
 .TP
 .B fs-options
 File system-specific options to be passed to the real file 
-system checker.
+system builder.
 Although not guaranteed, the following options are supported
-by most file system checkers.
-.TP
-.I -a
-Automatically repair the file system without any questions (use
-this option with caution).
-.TP
-.I -l
-List all the file names in the file system.
+by most file system builders.
 .TP
-.I -r
-Interactively repair the file system (ask for confirmations).
+.B -c
+Check the device for bad blocks before building the file system.
 .TP
-.I -s
-List the super block before checking the file system.
+.BI -l \ filename
+Read the bad blocks list from
+.I filename
 .TP
-.I -v
+.B -v
 Produce verbose output.
 .SH BUGS
 All generic options must precede and not be combined with
@@ -118,16 +82,22 @@ file system-specific options.
 Some file system-specific programs do not support the
 .I -v
 (verbose) option, nor return meaningful exit codes.
+Also, some file system-specific programs do not automatically
+detect the device size and require the
+.I blocks
+parameter to be specified.
 .SH AUTHORS
 David Engel (david@ods.com)
 .br
 Fred N. van Kempen (waltje@uwalt.nl.mugnet.org)
 .br
+Ron Sommeling (sommel@sci.kun.nl)
+.br
 The manual page was shamelessly adapted from Remy Card's version
 for the ext2 file system.
 .SH SEE ALSO
-.BR mkfs (8),
-.BR fsck.minix (8),
-.BR fsck.ext (8),
-.BR fsck.ext2 (8),
-.BR fsck.xiafs (8).
+.BR fsck (8),
+.BR mkfs.minix (8),
+.BR mkfs.ext (8),
+.BR mkfs.ext2 (8),
+.BR mkfs.xiafs (8).
index 018a538491507756679f92b3e15b34c0559dadfd..78a3a0c2f9a46bfd2b95a2e3702271df19acbe1e 100644 (file)
 /*
- * fs-util     A simple generic frontend for the for the fsck and mkfs
- *             programs under Linux.  See the manual pages for details.
+ * mkfs                A simple generic frontend for the for the mkfs program
+ *             under Linux.  See the manual page for details.
  *
- * Usage:      fsck [-AV] [-t fstype] [fs-options] device
- *             mkfs [-V] [-t fstype] [fs-options] device< [size]
+ * Usage:      mkfs [-V] [-t fstype] [fs-options] device [size]
  *
  * Authors:    David Engel, <david@ods.com>
  *             Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
+ *             Ron Sommeling, <sommel@sci.kun.nl>
  */
 
 
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <errno.h>
-#include <limits.h>
 #include <stdio.h>
 #include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <mntent.h>
 #include <unistd.h>
 #include <getopt.h>
+#include <limits.h>
 
 
+#define VERSION                "1.9"
+
 #ifndef DEFAULT_FSTYPE
-#   define DEFAULT_FSTYPE      "minix"
+# define DEFAULT_FSTYPE                "minix"
 #endif
 
-#define _PATH_PROG     "%s.%s"
-#define _PROG_FSCK     "fsck"
-
-#define EXIT_OK          0
-#define EXIT_NONDESTRUCT 1
-#define EXIT_DESTRUCT    2
-#define EXIT_UNCORRECTED 4
-#define EXIT_ERROR       8
-#define EXIT_USAGE       16
-#define EXIT_LIBRARY     128
-
-static char *Version = "1.8";
-static char *ignored_types[] = {
-  "ignore",
-  "iso9660",
-  "msdos",
-  "nfs",
-  "proc",
-  "sw",
-  "swap",
-  NULL
-};
-
-
-/* Execute a program. */
-int do_exec(char *prog, char **argv, int verbose)
-{
-    char *args[33];
-    register int i;
-    int pid, status;
-
-    /* Build the vector. */
-    i = 0;
-    args[i++] = prog;
-    while(*argv != NULL && i < 32)
-        args[i++] = *argv++;
-    args[i] = NULL;
-
-    if (verbose) {
-       i = 0;
-       while(args[i] != NULL) {
-           printf("%s ", args[i]);
-           i++;
-       }
-       printf("\n");
-       if (verbose > 1)
-           return EXIT_OK;
-    }
-
-    /* Fork and execute the correct program. */
-    if ((pid = fork()) < 0) {
-        perror("fork");
-       status = EXIT_ERROR;
-    } else if (pid == 0) {
-       (void) execvp(args[0], args);
-       perror(args[0]);
-       exit(EXIT_ERROR);
-    } else {
-        while(wait(&status) != pid)
-           ;
-       status = WEXITSTATUS(status);
-    }
-
-    return status;
-}
-
-
-/* Check if we have to ignore a file system type. */
-int ignore(char *type, char *opts)
-{
-    char *cp;
-    char **ip;
-
-    ip = ignored_types;
-    while (*ip != NULL) {
-       if (!strcmp(type, *ip))
-           return 1;
-       ip++;
-    }
-
-    for (cp = strtok(opts, ","); cp != NULL; cp = strtok(NULL, ",")) {
-       if (!strcmp(cp, "noauto"))
-           return 1;
-    }
-
-    return 0;
-}
-
-
-/* Check all file systems, using the /etc/fstab table. */
-int check_all(int verbose, char **argv)
-{
-    char path[PATH_MAX];
-    char *args[33];
-    FILE *mntfile;
-    struct mntent *mp;
-    register int i;
-    int status = EXIT_OK;
-
-    if (verbose)
-        printf("Checking all file systems.\n");
-
-    /* Create an array of arguments. */
-    i = 0;
-    while (*argv != NULL && i < 32)
-       args[i++] = *argv++;
-    args[i] = NULL;
-    args[i + 1] = NULL;
-
-    /* Open the mount table. */
-    if ((mntfile = setmntent(MNTTAB, "r")) == NULL) {
-       perror(MNTTAB);
-       exit(EXIT_ERROR);
-    }
-
-    /* Walk through the /etc/fstab file. */
-    while ((mp = getmntent(mntfile)) != NULL) {
-       if (verbose)
-           printf("%-7s %-15s %-15s ", mp->mnt_type,
-                  mp->mnt_fsname, mp->mnt_dir);
-       if (ignore(mp->mnt_type, mp->mnt_opts)) {
-           if (verbose)
-               printf("(ignored)\n");
-           continue;
-       }
-
-       /* Build program name. */
-       sprintf(path, _PATH_PROG, _PROG_FSCK, mp->mnt_type);
-       args[i] = mp->mnt_fsname;
-       status |= do_exec(path, args, verbose);
-    }
-
-    (void) endmntent(mntfile);
-
-    return status;
-}
-
-
-/* Lookup filesys in /etc/fstab and return the corresponding entry. */
-struct mntent *lookup(char *filesys)
-{
-    FILE *mntfile;
-    struct mntent *mp;
-
-    /* No filesys name given. */
-    if (filesys == NULL)
-        return NULL;
-
-    /* Open the mount table. */
-    if ((mntfile = setmntent(MNTTAB, "r")) == NULL) {
-       perror(MNTTAB);
-       exit(EXIT_ERROR);
-    }
-
-    while ((mp = getmntent(mntfile)) != NULL) {
-       if (!strcmp(filesys, mp->mnt_fsname) ||
-           !strcmp(filesys, mp->mnt_dir))
-           break;
-    }
+#define SEARCH_PATH    "PATH=/sbin:/sbin/fs.d:/sbin/fs:/etc/fs:/etc"
+#define PROGNAME       "mkfs.%s"
 
-    (void) endmntent(mntfile);
 
-    return mp;
-}
-
-
-void usage(int fsck, char *prog)
+int main(int argc, char *argv[])
 {
-    if (fsck) {
-       fprintf(stderr, "Usage: fsck [-AV] [-t fstype] [fs-options] filesys\n");
-    } else {
-       fprintf(stderr, "Usage: mkfs [-V] [-t fstype] [fs-options] filesys [size]\n");
-    }
-
-    exit(EXIT_USAGE);
-}
-
-
-void main(int argc, char *argv[])
-{
-    char path[PATH_MAX];
-    char *oldpath, newpath[PATH_MAX];
-    register char *sp;
-    struct mntent *fsent;
-    char *fstype = NULL;
-    int verbose = 0;
-    int doall = 0;
-    int i, fsck, more;
-
-    /* Must be 1 for "fsck" and 0 for "mkfs". */
-    if ((sp = strrchr(argv[0], '/')) != NULL)
-        sp++;
-    else
-        sp = argv[0];
-    if (!strcmp(sp, _PROG_FSCK))
-        fsck = 1;
-    else
-        fsck = 0;
-
-    /* Check commandline options. */
-    opterr = 0;
-    more = 0;
-    while ((more == 0) && ((i = getopt(argc, argv, "AVt:")) != EOF))
-       switch(i) {
-         case 'A':
-           doall++;
-           break;
-         case 'V':
-           verbose++;
-           break;
-         case 't':
-           if (optarg == NULL)
-               usage(fsck, sp);
-           fstype = optarg;
-           break;
-         default:
-           more = 1;
-           break;              /* start of specific arguments */
-       }
-
-    /* Did we get any specific arguments? */
-    if (more)
-        optind--;
-
-    /* Print our version number if requested. */
-    if (verbose)
-        printf("%s (fsutil) version %s (%s)\n", argv[0],
-              Version, __DATE__);
-
-    /* Update our PATH to include /etc/fs and /etc. */
-    strcpy(newpath, "PATH=/etc/fs:/etc:");
-    if ((oldpath = getenv("PATH")) != NULL)
-        strcat(newpath, oldpath);
-    putenv(newpath);
-    
-    /* If -A was specified ("check all"), double-check. */
-    if (doall) {
-       if (!fsck || (fstype != NULL))
-           usage(fsck, sp);
-       exit(check_all(verbose, &argv[optind]));
-    } else {
-       /* If -t wasn't specified, we must deduce fstype. */
-       if (fstype == NULL) {
-           /* make sure that "filesys" was specified */
-           if (optind >= argc)
-               usage(fsck, sp);
-           /* then try looking for it in /etc/fstab */
-           if ((fsent = lookup(argv[argc - 1])) != NULL) {
-               argv[argc - 1] = fsent->mnt_fsname;
-               fstype = fsent->mnt_type;
-           } else {
-               if (!fsck && optind < argc-1) {
-                   if ((fsent = lookup(argv[argc - 2])) != NULL) {
-                       argv[argc - 2] = fsent->mnt_fsname;
-                       fstype = fsent->mnt_type;
-                   }
-               }
-           }
-           /* if we still don't know, use the default */
-           if (fstype == NULL) fstype = DEFAULT_FSTYPE;
-       }
-
-       /* Build program name. */
-       sprintf(path, _PATH_PROG, sp, fstype);
-       exit(do_exec(path, &argv[optind], verbose));
+  char progname[NAME_MAX];
+  char *fstype = NULL;
+  int i, more = 0, verbose = 0;
+
+  /* Check commandline options. */
+  opterr = 0;
+  while ((more == 0) && ((i = getopt(argc, argv, "Vt:")) != EOF))
+    switch (i) {
+    case 'V':
+      verbose++;
+      break;
+    case 't':
+      fstype = optarg;
+      break;
+    default:
+      more = 1;
+      break;           /* start of specific arguments */
     }
-    /*NOTREACHED*/
+  if (optind == argc) {
+    fprintf(stderr,
+      "Usage: mkfs [-V] [-t fstype] [fs-options] device [size]\n");
+    return -1;
+  }
+  
+  /* If -t wasn't specified, use the default */
+  if (fstype == NULL)
+    fstype = DEFAULT_FSTYPE;
+
+  /* Set PATH and program name */
+  putenv(SEARCH_PATH);
+  sprintf(progname, PROGNAME, fstype);
+  argv[--optind] = progname;
+
+  if (verbose) {
+    puts("mkfs version " VERSION " (" __DATE__ ")");
+    i = optind;
+    while (argv[i])
+      printf("%s ", argv[i++]);
+    printf("\n");
+    if (verbose > 1)
+      return 0;
+  }
+
+  /* Execute the program */
+  execvp(progname, argv+optind);
+  perror(progname);
+  return 1;
 }
index cbfb1cf4ca015501dade0570e24660cba39124f9..3c59bb073a290289820ce8be1d04ce0343d3f4e5 100644 (file)
@@ -86,3 +86,6 @@ Inode request feature by Scott Heavner (sdh@po.cwru.edu)
 .br
 Support for the file system valid flag by Dr. Wettstein
 (greg%wind.uucp@plains.nodak.edu)
+.br
+Check to prevent mkfs of mounted filesystem and boot sector clearing
+by Daniel Quinlan (quinlan@yggdrasil.com)
index b2dcf78963d97b0307a5380d222bdada729d39e5..87c7c1270c6fa96b4ac116944cd4ea807f0ca124 100644 (file)
@@ -6,33 +6,39 @@
  */
 
 /*
- * 24.11.91  - time began. Used the fsck sources to get started.
+ * DD.MM.YY
  *
- * 25.11.91  - corrected some bugs. Added support for ".badblocks"
+ * 24.11.91  - Time began. Used the fsck sources to get started.
+ *
+ * 25.11.91  - Corrected some bugs. Added support for ".badblocks"
  *             The algorithm for ".badblocks" is a bit weird, but
  *             it should work. Oh, well.
  *
- * 25.01.92  -  Added the -l option for getting the list of bad blocks
- *              out of a named file. (Dave Rivers, rivers@ponds.uucp)
+ * 25.01.92  - Added the -l option for getting the list of bad blocks
+ *             out of a named file. (Dave Rivers, rivers@ponds.uucp)
  *
- * 28.02.92  - added %-information when using -c.
+ * 28.02.92  - Added %-information when using -c.
  *
- * 28.02.93  -  added support for other namelengths than the original
+ * 28.02.93  - Added support for other namelengths than the original
  *             14 characters so that I can test the new kernel routines..
  *
- * Sat Oct  9 11:48:31 1993, faith@cs.unc.edu: make exit status conform
- *                           to that required by fsutil
+ * 09.10.93  - Make exit status conform to that required by fsutil
+ *             (Rik Faith, faith@cs.unc.edu)
  *
- * 31.10.93  -  added inode request feature, for backup floppies: use
- *              32 inodes, for a news partition use more.
- *              (Scott Heavner, sdh@po.cwru.edu)
+ * 31.10.93  - Added inode request feature, for backup floppies: use
+ *             32 inodes, for a news partition use more.
+ *             (Scott Heavner, sdh@po.cwru.edu)
  *
- * Mon Jan  3 11:08:49 1994, Dr. Wettstein (greg%wind.uucp@plains.nodak.edu).
- *                          Added support for file system valid flag.
+ * 03.01.94  - Added support for file system valid flag.
+ *             (Dr. Wettstein, greg%wind.uucp@plains.nodak.edu)
  * 
- * 9.11.94   -  added test to prevent overwrite of mounted fs adapted
- *              from Theodore Ts'o's (tytso@athena.mit.edu) mke2fs
- *              program.  (Daniel Quinlan, quinlan@yggdrasil.com)
+ * 09.11.94  - Added test to prevent overwrite of mounted fs adapted
+ *             from Theodore Ts'o's (tytso@athena.mit.edu) mke2fs
+ *             program.  (Daniel Quinlan, quinlan@yggdrasil.com)
+ *
+ * 03.20.95  - Clear first 512 bytes of filesystem to make certain that
+ *             the filesystem is not misidentified as a MS-DOS FAT filesystem.
+ *             (Daniel Quinlan, quinlan@yggdrasil.com)
  *
  * Usage:  mkfs [-c] [-nXX] [-iXX] device size-in-blocks
  *         mkfs [-l filename ] device size-in-blocks
@@ -98,6 +104,7 @@ static char root_block[BLOCK_SIZE] = "\0";
 static char * inode_buffer = NULL;
 #define Inode (((struct minix_inode *) inode_buffer)-1)
 static char super_block_buffer[BLOCK_SIZE];
+static char boot_block_buffer[512];
 #define Super (*(struct minix_super_block *)super_block_buffer)
 #define INODES ((unsigned long)Super.s_ninodes)
 #define ZONES ((unsigned long)Super.s_nzones)
@@ -181,16 +188,21 @@ void write_tables(void)
        Super.s_state |= MINIX_VALID_FS;
        Super.s_state &= ~MINIX_ERROR_FS;
 
+       if (lseek(DEV, 0, SEEK_SET))
+               die("seek to boot block failed in write_tables");
+       if (512 != write(DEV, boot_block_buffer, 512))
+               die("unable to clear boot sector");
        if (BLOCK_SIZE != lseek(DEV, BLOCK_SIZE, SEEK_SET))
                die("seek failed in write_tables");
        if (BLOCK_SIZE != write(DEV, super_block_buffer, BLOCK_SIZE))
                die("unable to write super-block");
        if (IMAPS*BLOCK_SIZE != write(DEV,inode_map,IMAPS*BLOCK_SIZE))
-               die("Unable to write inode map");
+               die("unable to write inode map");
        if (ZMAPS*BLOCK_SIZE != write(DEV,zone_map,ZMAPS*BLOCK_SIZE))
-               die("Unable to write zone map");
+               die("unable to write zone map");
        if (INODE_BUFFER_SIZE != write(DEV,inode_buffer,INODE_BUFFER_SIZE))
-               die("Unable to write inodes");
+               die("unable to write inodes");
+       
 }
 
 void write_block(int blk, char * buffer)
@@ -314,6 +326,7 @@ void setup_tables(void)
        memset(inode_map,0xff,sizeof(inode_map));
        memset(zone_map,0xff,sizeof(zone_map));
        memset(super_block_buffer,0,BLOCK_SIZE);
+       memset(boot_block_buffer,0,512);
        MAGIC = magic;
        ZONESIZE = 0;
        MAXSIZE = (7+512+512*512)*1024;
@@ -339,7 +352,7 @@ void setup_tables(void)
                unmark_inode(i);
        inode_buffer = malloc(INODE_BUFFER_SIZE);
        if (!inode_buffer)
-               die("Unable to allocate buffer for inodes");
+               die("unable to allocate buffer for inodes");
        memset(inode_buffer,0,INODE_BUFFER_SIZE);
        printf("%d inodes\n",INODES);
        printf("%d blocks\n",ZONES);
@@ -424,7 +437,7 @@ char *filename;
 
        listfile=fopen(filename,"r");
        if(listfile == (FILE *)NULL) {
-               die("Can't open file of bad blocks");
+               die("can't open file of bad blocks");
        }
        while(!feof(listfile)) {
                fscanf(listfile,"%d\n", &blockno);
@@ -519,7 +532,7 @@ int main(int argc, char ** argv)
        if (!S_ISBLK(statbuf.st_mode))
                check=0;
        else if (statbuf.st_rdev == 0x0300 || statbuf.st_rdev == 0x0340)
-               die("Will not try to make filesystem on '%s'");
+               die("will not try to make filesystem on '%s'");
        setup_tables();
        if (check)
                check_blocks();
index 2c02fbbe063f72adc2bc92f9ca5b3269fcd8c9a4..643d7ba0447f0b424adc6364d6661845fb2756eb 100644 (file)
@@ -7,13 +7,13 @@
 .\" "
 .TH MKSWAP 8 "8 February 1995" "Linux 1.0" "Linux Programmer's Manual"
 .SH NAME
-mkswap \- set up a Linux swap device
+mkswap \- set up a Linux swap area
 .SH SYNOPSIS
 .B "mkswap [ \-c ]"
 .IB device  " [" size-in-blocks "]"
 .SH DESCRIPTION
 .B mkswap
-sets up a Linux swap area on a device (usually a disk partition).
+sets up a Linux swap area on a device or in a file.
 
 The
 .I device
@@ -31,23 +31,45 @@ is usually of the following form:
 The
 .I size-in-blocks
 parameter is the desired size of the file system, in blocks.  This
-information is determined automatically by mkswap if it is omitted.  Block
-counts are rounded down to pages of 4 kB each.  Only block counts equal to
-or greater than 40 and equal to or less than 131072 are allowed.  Block
-counts greater than 130752 are (silently) rounded down to 130752.
+information is determined automatically by
+.B mkswap
+if it is omitted.  Block counts are rounded down so that the total
+size is an integer multiple of the machine's page size.  Only block
+counts in the range MINCOUNT..MAXCOUNT are allowed.  If the block count
+exceeds the MAXCOUNT, it is truncated to that value and a warning
+message is issued.
+
+The MINCOUNT and MAXCOUNT values for a swap area are:
 
-As Nick Holloway explains, the actual maximum for each swap file/partition
-is:
 .RS
-(4096 - 10) * 8 * 4096 = 133890048 bytes = 130752 blocks =  127.6875 Mb
+MINCOUNT = 10 * PAGE_SIZE / 1024
+.br
+MAXCOUNT = (PAGE_SIZE - 10) * 8 * PAGE_SIZE / 1024
 .RE
-This is because a single page is used to hold the swap bitmap at the
-start of the partition, where each bit is a single 4K page.  The reason
-for the -10, is that the signature is "SWAP-SPACE" -- 10 characters.
 
-.B mkswap
-can also set up swap files, although the file has to be created first.  A
-sequence of commands similar to the following is reasonable for this
+For example, on a machine with 4kB pages (e.g., x86), we get:
+
+.RS
+MINCOUNT = 10 * 4096 / 1024 = 40
+.br
+MAXCOUNT = (4096 - 10) * 8 * 4096 / 1024 = 130752
+.RE
+
+As each block is 1kB large, the swap area in this example could have a
+size that is anywhere in the range from 40kB up to 127.6875MB.
+
+If you don't know the page size that your machine uses, you may be
+able to look it up with "cat /proc/cpuinfo".
+
+The reason for the limit on MAXCOUNT is that a single page is used to
+hold the swap bitmap at the start of the swap area, where each bit
+represents a single page.  The reason for the -10, is that the
+signature is "SWAP-SPACE" -- 10 characters.
+
+To setup a swap file, it is necessary to create that file before
+running
+.B mkswap .
+A sequence of commands similar to the following is reasonable for this
 purpose:
 
 .nf
@@ -59,9 +81,7 @@ purpose:
 .RE
 .fi
 
-Note that the regular file has to be created before running
-.B mkswap
-on the file, and that the file must not contain any holes (so, using
+Note that a swap file must not contain any holes (so, using
 .BR cp (1)
 to create the file is not acceptable).
 
index bb4e2249e93f2e3b9dd84e98cce6999ba11fb78d..fe3f04c11edc730fbffa51d607109e42f35ff94c 100644 (file)
 
 #include <linux/mm.h>
 
-#ifndef __GNUC__
-#error "needs gcc for the bitop-__asm__'s"
-#endif
-
 #ifndef __linux__
-#define volatile
+# define volatile
 #endif
 
 #define TEST_BUFFER_PAGES 8
@@ -45,21 +41,29 @@ static long PAGES = 0;
 static int check = 0;
 static int badpages = 0;
 
-static char signature_page[PAGE_SIZE];
+static int signature_page[PAGE_SIZE/sizeof(int)];
 
-#define bitop(name,op) \
-static inline int name(char * addr,unsigned int nr) \
-{ \
-int __res; \
-__asm__ __volatile__("bt" op " %1,%2; adcl $0,%0" \
-:"=g" (__res) \
-:"r" (nr),"m" (*(addr)),"0" (0)); \
-return __res; \
+static long bit_test_and_set (unsigned int *addr, unsigned int nr)
+{
+       unsigned int r, m;
+
+       addr += nr / (8 * sizeof(int));
+       r = *addr;
+       m = 1 << (nr & (8 * sizeof(int) - 1));
+       *addr = r | m;
+       return (r & m) != 0;
 }
 
-bitop(bit,"")
-bitop(setbit,"s")
-bitop(clrbit,"r")
+static bit_test_and_clear (unsigned int *addr, unsigned int nr)
+{
+       unsigned int r, m;
+
+       addr += nr / (8 * sizeof(int));
+       r = *addr;
+       m = 1 << (nr & (8 * sizeof(int) - 1));
+       *addr = r & ~m;
+       return (r & m) != 0;
+}
 
 /*
  * Volatile to let gcc know that this doesn't return. When trying
@@ -84,18 +88,18 @@ void check_blocks(void)
        current_page = 0;
        while (current_page < PAGES) {
                if (!check) {
-                       setbit(signature_page,current_page++);
+                       bit_test_and_set(signature_page,current_page++);
                        continue;
                }
                if (do_seek && lseek(DEV,current_page*PAGE_SIZE,SEEK_SET) !=
                current_page*PAGE_SIZE)
                        die("seek failed in check_blocks");
                if (do_seek = (PAGE_SIZE != read(DEV, buffer, PAGE_SIZE))) {
-                       clrbit(signature_page,current_page++);
+                       bit_test_and_clear(signature_page,current_page++);
                        badpages++;
                        continue;
                }
-               setbit(signature_page,current_page++);
+               bit_test_and_set(signature_page,current_page++);
        }
        if (badpages)
                printf("%d bad page%s\n",badpages,(badpages>1)?"s":"");
@@ -165,7 +169,7 @@ int main(int argc, char ** argv)
                argv++;
                if (argv[0][0] != '-')
                        if (device_name) {
-                               PAGES = strtol(argv[0],&tmp,0)>>2;
+                               PAGES = strtol(argv[0],&tmp,0)>>(PAGE_SHIFT-10);
                                if (*tmp)
                                        usage();
                        } else
@@ -179,14 +183,17 @@ int main(int argc, char ** argv)
        if (device_name && !PAGES) {
                PAGES = get_size(device_name) / PAGE_SIZE;
        }
-       if (!device_name || PAGES<10)
+       if (!device_name || PAGES<10) {
+               fprintf(stderr,
+                       "%s: error: swap area needs to be at least %ldkB\n",
+                       program_name, 10 * PAGE_SIZE / 1024);
                usage();
-       if (PAGES > 32688) /* 130752 blocks */
-               PAGES=32688;
-#if 0
-       if (PAGES > 32768)
-               PAGES=32768;
-#endif
+       }
+       if (PAGES > 8 * (PAGE_SIZE - 10)) {
+               PAGES = 8 * (PAGE_SIZE - 10);
+               fprintf(stderr, "%s: warning: truncating swap area to %ldkB\n",
+                       program_name, PAGES * PAGE_SIZE / 1024);
+       }
        DEV = open(device_name,O_RDWR);
        if (DEV < 0 || fstat(DEV, &statbuf) < 0) {
                perror(device_name);
@@ -197,13 +204,13 @@ int main(int argc, char ** argv)
        else if (statbuf.st_rdev == 0x0300 || statbuf.st_rdev == 0x0340)
                die("Will not try to make swapdevice on '%s'");
        check_blocks();
-       if (!clrbit(signature_page,0))
+       if (!bit_test_and_clear(signature_page,0))
                die("fatal: first page unreadable");
        goodpages = PAGES - badpages - 1;
-       if (!goodpages)
+       if (goodpages <= 0)
                die("Unable to set up swap-space: unreadable");
        printf("Setting up swapspace, size = %d bytes\n",goodpages*PAGE_SIZE);
-       strncpy(signature_page+PAGE_SIZE-10,"SWAP-SPACE",10);
+       strncpy((char*)signature_page+PAGE_SIZE-10,"SWAP-SPACE",10);
        if (lseek(DEV, 0, SEEK_SET))
                die("unable to rewind swap-device");
        if (PAGE_SIZE != write(DEV, signature_page, PAGE_SIZE))
index 0f7bc6e787eec0fad0a8a59c5118c54cf4274aae..49b9f981f24196f51d18b5937aaa2a5e862ccc58 100644 (file)
@@ -1,25 +1,23 @@
 # Makefile -- Makefile for util-linux Linux utilities
 # Created: Sat Dec 26 20:09:40 1992
-# Revised: Wed Feb  8 20:30:16 1995 by faith@cs.unc.edu
+# Revised: Fri Oct  6 20:27:05 1995 by r.faith@ieee.org
 # Copyright 1992, 1993, 1994, 1995 Rickard E. Faith (faith@cs.unc.edu)
+# May be distributed under the GPL
 #
 
 include ../MCONFIG
 
 # Where to put man pages?
 
-MAN6=          banner.6 ddate.6
+MAN6=          banner.6
 
 # Where to put binaries?
 # See the "install" rule for the links. . .
 
-USRGAMES=       banner ddate
+USRGAMES=       banner
 
 all: $(USRGAMES)
 
-%.o: %.c
-       $(CC) -c $(CFLAGS) $< -o $@
-
 # Rules for everything else
 
 banner: banner.o $(BSD)/getopt.o $(BSD)/err.o
diff --git a/games/ddate.6 b/games/ddate.6
deleted file mode 100644 (file)
index 6499c62..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-.\" All Rites Reversed.  This file is in the PUBLIC DOMAIN.
-.\" Kallisti.
-.TH DDATE 6 "55 Confusion 3160" "" "Linux Programmer's Manual"
-.SH NAME
-ddate \- converts boring normal dates to fun Discordian Dates
-.SH SYNOPSIS
-.B ddate
-.SH DESCRIPTION
-.B ddate
-prints the date in Discordian Date format.
-.SH AUTHOR
-.nf
-Druel the Chaotic aka Jeremy Johnson (mpython@gnu.ai.mit.edu)
-.br
-Modifications for Unix by Lee Harvey Oswald Smith, K.S.C.
-.br
-Five tons of flax.
diff --git a/games/ddate.c b/games/ddate.c
deleted file mode 100644 (file)
index 33ce386..0000000
+++ /dev/null
@@ -1,171 +0,0 @@
-/* ddate.c .. converts boring normal dates to fun Discordian Date -><-
-   written  the 65th day of The Aftermath in the Year of Our Lady of 
-   Discord 3157 by Druel the Chaotic aka Jeremy Johnson aka
-   mpython@gnu.ai.mit.edu  
-
-   and I'm not responsible if this program messes anything up (except your 
-   mind, I'm responsible for that)
-
-   Modifications for Unix by Lee Harvey Oswald Smith, K.S.C.
-   Five tons of flax.
-*/
-
-#include <time.h>
-#include <string.h>
-#include <stdio.h>
-
-struct disc_time
-{int season; /* 0-4 */
- int day; /* 0-72 */
- int yday; /* 0-365 */
- int year; /* 3066- */
-};
-
-char *ending(int);
-void print(struct disc_time,char **);
-struct disc_time convert(int,int);
-struct disc_time makeday(int,int,int);
-
-main (int argc,char **argv) 
-{long t;
- struct tm *eris;
- int bob,raw;
- struct disc_time hastur;
- if (argc==4)
-    { int moe,larry,curly;
-      moe=atoi(argv[1]);
-      larry=atoi(argv[2]);
-      curly=atoi(argv[3]);
-      hastur=makeday(moe,larry,curly);
-    }
-  else if (argc!=1)
-    { fprintf(stderr,"Syntax: DiscDate [month day year]");
-      exit(1);
-    }
-  else
-    {
-      t= time(NULL);
-      eris=localtime(&t);
-      bob=eris->tm_yday; /* days since Jan 1. */
-      raw=eris->tm_year; /* years since 1980 */
-      hastur=convert(bob,raw);
-    }
-      print(hastur,argv);
-}
-
-struct disc_time makeday(int imonth,int iday,int iyear) /*i for input */
-{ struct disc_time funkychickens;
-  
-  int cal[12] = 
-    {
-       31,28,31,30,31,30,31,31,30,31,30,31
-    };
-  int dayspast=0;
-
-  imonth--;
-  funkychickens.year= iyear+1166;
-  while(imonth>0)
-     {
-       dayspast+=cal[--imonth];
-     }
-  funkychickens.day=dayspast+iday-1;
-  funkychickens.season=0;
-   if((funkychickens.year%4)==2)
-     {
-       if (funkychickens.day==59)
-         funkychickens.day=-1;
-     }
-  funkychickens.yday=funkychickens.day;
-/*               note: EQUAL SIGN...hopefully that fixes it */
-  while(funkychickens.day>=73)
-      {
-       funkychickens.season++;
-       funkychickens.day-=73;
-      }
-  return funkychickens;
-}
-
-char *ending(int num)
-{  
- int temp;
- char *funkychickens;
- funkychickens=(char *)malloc(sizeof(char)*3);
-  temp=num%10; /* get 0-9 */  
-  switch (temp)
-  { case 1:
-      strcpy(funkychickens,"st");
-      break;
-    case 2:
-      strcpy(funkychickens,"nd");
-      break;
-    case 3:
-      strcpy(funkychickens,"rd");
-      break;
-    default:
-      strcpy(funkychickens,"th");
-    }
- return funkychickens;
-}
-
-struct disc_time convert(int nday, int nyear)
-{  struct disc_time funkychickens;
-   
-   funkychickens.year = nyear+3066;
-   funkychickens.day=nday;
-   funkychickens.season=0;
-   if ((funkychickens.year%4)==2)
-     {if (funkychickens.day==59)
-       funkychickens.day=-1;
-     else if (funkychickens.day >59)
-       funkychickens.day-=1;
-    }
-   funkychickens.yday=funkychickens.day;
-   while (funkychickens.day>=73)
-     { funkychickens.season++;
-       funkychickens.day-=73;
-     }
-   return funkychickens;
-  
- }
-
-void print(struct disc_time tick, char **args)
-{ char *days[5] = { "Sweetmorn",
-                   "Boomtime",
-                   "Pungenday",
-                   "Prickle-Prickle",
-                   "Setting Orange"
-                 };
-  char *seasons[5] = { "Chaos",
-                      "Discord",
-                      "Confusion",
-                      "Bureaucracy",
-                      "The Aftermath"
-                     };
-  char *holidays[5][2] = { "Mungday", "Chaoflux",
-                          "Mojoday", "Discoflux",
-                          "Syaday",  "Confuflux",
-                          "Zaraday", "Bureflux",
-                          "Maladay", "Afflux"
-                        };
-  if (args[1]==NULL)
-    printf("Today is ");
-  else
-    printf("%s-%s-%s is ",args[1],args[2],args[3]);
-  if (tick.day==-1) printf("St. Tib's Day!");
-  else
-    { tick.day++;
-      printf("%s",days[tick.yday%5]);
-      printf(", the %d", tick.day);
-      printf("%s day of %s",ending(tick.day),seasons[tick.season]) ;
-    }
-  printf(" in the YOLD %d\n",tick.year);
-  if ((tick.day==5)||(tick.day==50))
-    { printf("Celebrate ");
-      if (tick.day==5)
-       printf("%s\n",holidays[tick.season][0]);
-      else
-       printf("%s\n",holidays[tick.season][1]);
-    }
-}
diff --git a/historic/frag.8 b/historic/frag.8
new file mode 100644 (file)
index 0000000..c2f67b5
--- /dev/null
@@ -0,0 +1,47 @@
+.\" Copyright 1992,1993,1994 Rickard E. Faith (faith@cs.unc.edu)
+.\" May be distributed under the GNU General Public License
+.TH FRAG 8 "8 January 1994" "Linux 0.99" "Linux Programmer's Manual"
+.SH NAME
+frag \- simple fragmentation checker
+.SH SYNOPSIS
+.B /usr/sbin/frag
+.B "[ \-s [ \-s ]]"
+filename ...
+.SH DESCRIPTION
+.B frag
+will report the file system fragmentation on a specified
+.IR filename .
+If the
+.I filename
+is a directory,
+.B frag
+will recursively descend the directory.
+.SH OPTIONS
+.TP
+.B \-s
+Silent (may be set to 1 or 2).  The first
+.B \-s
+eliminates the file by file statistics, and just prints the 
+examined directories and a summary.  The second
+.B \-s
+eliminates the printing of the directories, and just prints a
+summary.  This option is useful when
+.B frag
+is used on a directory.
+.SH "SEE ALSO"
+.BR mkfs (8),
+.BR fsck (8),
+.BR mkefs (8),
+.BR efsck (8)
+.SH BUGS
+.B frag
+will get caught in an infinite loop in the /proc filesystem.
+.SH AUTHORS
+V1.0 by Werner Almesberger
+.br
+V1.1 by Steffen Zahn, adding directory recursion
+.br
+V1.2 by Rob Hooft, adding hole counts
+.br
+V1.3 by Steffen Zahn, ignore symlinks,
+don't cross filesys borders, get filesystem block size at runtime
diff --git a/historic/frag.c b/historic/frag.c
new file mode 100644 (file)
index 0000000..0098e02
--- /dev/null
@@ -0,0 +1,311 @@
+/* frag.c - simple fragmentation checker
+            V1.0 by Werner Almesberger
+            V1.1 by Steffen Zahn, adding directory recursion
+            V1.2 by Rob Hooft, adding hole counts
+            V1.3 by Steffen Zahn, email: szahn%masterix@emndev.siemens.co.at
+                    14 Nov 93
+                    - ignore symlinks,
+                    - don't cross filesys borders
+                    - get filesystem block size at runtime
+           V1.4 by Michael Bischoff <mbi@mo.math.nat.tu-bs.de> to handle
+                   indirect blocks better, but only for ext2fs
+                   (applied by faith@cs.unc.edu, Sat Feb  4 22:06:27 1995)
+
+            TODO: - handle hard links
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <string.h>
+#include <dirent.h>
+#include <sys/stat.h>
+#include <sys/vfs.h>
+#include <linux/fs.h>                      /* for FIBMAP */
+
+typedef struct StackElem {
+    struct StackElem *backref, *next;
+    char name[NAME_MAX];
+    char dir_seen;
+    char from_cmd_line;
+} StackElem;
+
+StackElem *top = NULL;
+
+
+void discard( void )
+{
+    StackElem *se = top;
+    if( se == NULL )
+        return ;
+    top = se->next;
+    free(se);
+}
+
+void push( StackElem * se )
+{
+    se -> next = top;
+    top = se;
+}
+
+char *p2s( StackElem *se, char *path )
+{
+    char *s;
+    if( se->backref!=NULL ) {
+        path = p2s( se->backref, path );
+        if( path[-1]!='/' )
+            *path++ = '/';
+    }
+    s = se->name;
+    while( *s )
+        *path++ = *s++;
+    return path;
+}
+
+char *path2str( StackElem *se, char *path )
+{
+    *(p2s( se, path ))=0;
+    return path;
+}
+              
+void *xmalloc( size_t size )
+{
+    void *p;
+    if( (p=malloc(size))==NULL ) {
+        fprintf(stderr,"\nvirtual memory exhausted.\n");
+        exit(1);
+    }
+    return p;
+}
+
+int main(int argc,char **argv)
+{
+    int fd,last_phys_block,
+        fragments_in_file, blocks_in_file,
+        blocks,current_phys_block,
+        this_fragment, largest_fragment, i;
+    long sum_blocks=0, sum_frag_blocks=0, sum_files=0, sum_frag_files=0;
+    long num_hole=0, sum_hole=0, hole;
+    struct stat st;
+    struct statfs stfs;
+    StackElem *se, *se1;
+    char path[PATH_MAX], pathlink[PATH_MAX], *p;
+    DIR *dir;
+    struct dirent *de;
+    char silent_flag=0;
+    dev_t local_fs;
+    int block_size;
+    
+    if (argc < 2)
+    {
+        fprintf(stderr,"usage: %s [-s [-s]] filename ...\n",argv[0]);
+        exit(1);
+    }
+    argc--; argv++;
+    while (argc>0)
+    {
+        p = *argv;
+        if( *p=='-' )
+            while( *++p )
+                switch( *p )
+                {
+                case 's':
+                    silent_flag++; /* may be 1 or 2 */
+                    break;
+                default:
+                    fprintf(stderr,"\nunknown flag %c\n", *p );
+                    exit(1);
+                }
+        else
+        {
+            se = xmalloc( sizeof(StackElem) );
+            se->backref=NULL; se->dir_seen=0; se->from_cmd_line=1;
+            strcpy( se->name, p );
+            push(se);
+        }
+        argc--; argv++;
+    }
+    while ( top != NULL)
+    {
+        se = top;
+        if( se->dir_seen )
+            discard();
+        else
+        {
+            path2str( se, path );
+            if( readlink( path, pathlink, sizeof(pathlink) )>=0 )
+            {                   /* ignore symlinks */
+                if(silent_flag<1)
+                {
+                    printf("symlink %s\n", path );
+                }
+                discard();
+            }
+            else if( stat( path,&st) < 0)
+            {
+                perror( path );
+                discard();
+            }
+            else if( !se->from_cmd_line && (local_fs!=st.st_dev) )
+            {                   /* do not cross filesystem borders */
+                if(silent_flag<2)
+                {
+                    printf("different filesystem %s\n", path );
+                }
+                discard();
+            }
+            else
+            {
+                if( se->from_cmd_line )
+                {
+                    local_fs = st.st_dev;
+                    if ( statfs( path, &stfs )<0 )
+                    {
+                        perror( path );
+                        block_size = 1024;
+                    }
+                    else
+                        block_size = stfs.f_bsize;
+                }
+                if( S_ISREG(st.st_mode))   /* regular file */
+                {
+                    if ( (fd = open( path ,O_RDONLY)) < 0 )
+                    {
+                        perror( path );
+                        discard();
+                    }
+                    else
+                    {
+                        last_phys_block = -1;
+                        fragments_in_file = 0;
+                        hole = 0; this_fragment=0;
+                        largest_fragment=0;
+                        blocks_in_file = (st.st_size+block_size-1)/block_size;
+                        for (blocks = 0; blocks < blocks_in_file; blocks++)
+                        {
+                            current_phys_block = blocks;
+                            if (ioctl(fd,FIBMAP,&current_phys_block) < 0)
+                            {
+                                perror(path);
+                                break;
+                            }
+                            if (current_phys_block) { /* no hole here */
+                               int indirect;
+                               /* indirect is the number of indirection */
+                               /* blocks which must be skipped */
+                               indirect = 0;
+                               /* every 256 blocks there is an indirect block,
+                                  the first of these is before block 12 */
+                               if (blocks >= 12 && (blocks-12) % 256 == 0)
+                                   ++indirect;
+                               /* there is a block pointing to the indirect
+                                  blocks every 64K blocks */
+                               if (blocks >= 256+12 && (blocks-256-12) % 65536 == 0)
+                                   ++indirect; /* 2nd indirect block */
+                               /* there is a single triple indirect block */
+                               if (blocks == 65536 + 256 + 12)
+                                   ++indirect;
+                                if (last_phys_block == current_phys_block-1-indirect)
+                                    this_fragment++;
+                               else { /* start of first or new fragment */
+                                    if( largest_fragment<this_fragment )
+                                        largest_fragment=this_fragment;
+                                    this_fragment=1;
+                                    fragments_in_file++;
+                                }
+                                last_phys_block = current_phys_block;
+                            }
+                            else
+                            {
+                                hole++;
+                            }
+                        }
+                        if( largest_fragment<this_fragment )
+                            largest_fragment=this_fragment;
+                        blocks_in_file-=hole;
+                                /* number of allocated blocks in file */
+                        if( !silent_flag )
+                        {
+                            if( fragments_in_file < 2
+                                || blocks_in_file < 2 )
+                                i = 0; /* fragmentation 0 % */
+                            else
+                                i = (fragments_in_file - 1) * 100 /
+                                    (blocks_in_file-1);
+                                /* maximum fragmentation 100%
+                                   means every block is an fragment */
+                            printf(" %3d%%  %s  (%d block(s), %d fragment(s), largest %d",
+                                   i, path, blocks_in_file,
+                                   fragments_in_file,largest_fragment);
+                            if (hole)
+                            {
+                                printf(", %d hole(s))\n",hole);
+                            }
+                            else
+                            {
+                                printf(")\n");
+                            }
+                        }
+                        sum_blocks+=blocks_in_file;
+                        if (hole)
+                            num_hole++;
+                        sum_hole+=hole;
+                        sum_files++;
+                        if( fragments_in_file>1 )
+                        {
+                            sum_frag_blocks+=blocks_in_file-largest_fragment;
+                            sum_frag_files++;
+                        }
+                        discard();
+                        close(fd);
+                    }
+                }
+                else if( S_ISDIR( st.st_mode ) ) /* push dir contents */
+                {
+                    if( (dir=opendir( path ))==NULL )
+                    {
+                        perror(path);
+                        discard();
+                    }
+                    else
+                    {
+                        if( silent_flag<2 )
+                            printf("reading %s\n", path);
+                        while( (de=readdir(dir))!=NULL )
+                        {
+                            if( (strcmp(de->d_name,".")!=0)
+                                && (strcmp(de->d_name,"..")!=0) )
+                            {
+                                se1 = xmalloc( sizeof(StackElem) );
+                                se1->backref=se; se1->dir_seen=0;
+                                se1->from_cmd_line=0;
+                                strcpy( se1->name, de->d_name );
+                                push(se1);
+                            }
+                        }
+                        closedir( dir );
+                        se->dir_seen=1;
+                    }
+                }
+                else /* if( S_ISREG(st.st_mode)) */
+                    discard();
+            }
+        } /* if( se->dir_seen ) */
+    } /* while ( top != NULL) */
+    if (sum_files>1)
+    {
+        printf("\nsummary:\n");
+        printf(" %3ld%% file  fragmentation (%ld of %ld files contain fragments)\n",
+               sum_files<1 ? 0L : sum_frag_files*100/sum_files,
+               sum_frag_files, sum_files);
+        printf(" %3ld%% block fragmentation (%ld of %ld blocks are in fragments)\n",
+               sum_blocks<1 ? 0L : sum_frag_blocks*100/sum_blocks,
+               sum_frag_blocks, sum_blocks);
+        if (num_hole>1)
+            printf("  %ld files contain %ld blocks in holes\n",
+                   num_hole,sum_hole);
+    }
+    exit(0);
+}
diff --git a/historic/lpcntl.8 b/historic/lpcntl.8
new file mode 100644 (file)
index 0000000..87bcd03
--- /dev/null
@@ -0,0 +1,30 @@
+.\" Public Domain 1994 Rik Faith (faith@cs.unc.edu)
+.\" "
+.TH LPCNTL 8 "18 July 1994" "Linux 1.1" "Linux Programmer's Manual"
+.SH NAME
+lpcntl \- interface to line printer ioctl
+.SH SYNOPSIS
+.BI "lpcntl " device " [ " irq " ]"
+.SH DESCRIPTION
+.B lpcntl
+is used to manipulate the line printer driver.
+.PP
+.I device
+specifies a line printer device (e.g.,
+.IR /dev/lp1 ).
+.PP
+If
+.I irq
+is specified, then the line printer driver is set to use that IRQ.  If the
+.I irq
+is zero, then the polling driver is selected.  Only the super user may
+change the IRQ.
+.PP
+If no
+.I irq
+is specified, then
+.B lpcntl
+will report the interrupt number currently in use, or will report that the
+polling driver is currently being used.
+.SH AUTHOR
+Nigel Gamble (nigel@gate.net)
diff --git a/historic/lpcntl.c b/historic/lpcntl.c
new file mode 100644 (file)
index 0000000..bf164a6
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * Simple command interface to ioctl(fd, LPSETIRQ, irq).
+ * Nigel Gamble (nigel@gate.net)
+ * e.g.
+ *     lpcntl /dev/lp1 7
+ */
+
+#include <stdio.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <linux/lp.h>
+
+int
+main(int argc, char **argv)
+{
+       unsigned int irq;
+       int fd;
+       int ret;
+
+       if (argc < 2) {
+               fprintf(stderr, "usage: %s <lp device> [<irq>]\n", argv[0]);
+               exit(1);
+       }
+
+       fd = open(argv[1], O_RDONLY);
+       if (fd == -1) {
+               perror(argv[1]);
+               exit(1);
+       }
+
+       if (argc == 2) {
+               irq = ioctl(fd, LPGETIRQ);
+               if (irq == -1) {
+                       perror(argv[1]);
+                       exit(1);
+               }
+               if (irq)
+                       printf("%s using IRQ %d\n", argv[1], irq);
+               else
+                       printf("%s using polling\n", argv[1]);
+       } else {
+               irq = atoi(argv[2]);
+               ret = ioctl(fd, LPSETIRQ, irq);
+               if (ret == -1) {
+                       if (errno == EPERM)
+                               fprintf(stderr, "%s: only super-user can change the IRQ\n", argv[0]);
+                       else
+                               perror(argv[1]);
+                       exit(1);
+               }
+       }
+
+       return 0;
+}
diff --git a/historic/mesg.1 b/historic/mesg.1
new file mode 100644 (file)
index 0000000..81932df
--- /dev/null
@@ -0,0 +1,24 @@
+.\" Original author: Miquel van Smoorenburg, miquels@drinkel.nl.mugnet.org
+.\" Updated by faith@cs.unc.edu, Fri Oct 29 23:22:16 1993
+.TH MESG 1 "29 October 1993" "Linux 0.99" "Linux Programmer's Manual"
+.SH NAME
+mesg \- control write access to your terminal
+.SH SYNOPSIS
+.B mesg
+.RB [y|n]
+.br
+.SH DESCRIPTION
+.B Mesg
+controls the access to your terminal by others. It's typically used
+to allow/disallow others users to \fBwrite(1)\fP to your terminal.
+.SH FLAGS
+.IP y
+Allow write access to your terminal.
+.IP n
+Disallow write access to your terminal.
+.IP [none]
+Prints out the current access state of your terminal.
+.SH SEE ALSO
+.BR write (1), wall (1)
+.SH AUTHOR
+Miquel van Smoorenburg, miquels@drinkel.nl.mugnet.org
diff --git a/historic/mesg.c b/historic/mesg.c
new file mode 100644 (file)
index 0000000..07c5fad
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * mesg.c      The "mesg" utility. Gives / restrict access to
+ *             your terminal by others.
+ *
+ * Usage:      mesg [y|n].
+ *             Without arguments prints out the current settings.
+ */
+#include <stdio.h>
+#include <sys/stat.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <unistd.h>
+
+char *Version = "@(#) mesg 1.0 08-12-92 MvS";
+
+int main(int argc, char **argv)
+{
+  struct stat st;
+
+  if (!isatty(0)) {
+       /* Or should we look in /etc/utmp? */
+       fprintf(stderr, "stdin: is not a tty");
+       return(1);
+  }
+
+  if (fstat(0, &st) < 0) {
+       perror("fstat");
+       return(1);
+  }
+  if (argc < 2) {
+       printf("Is %s\n", ((st.st_mode & 022) == 022) ? "y" : "n");
+       return(0);
+  }
+  if (argc > 2 || (argv[1][0] != 'y' && argv[1][0] != 'n')) {
+       fprintf(stderr, "Usage: mesg [y|n]\n");
+       return(1);
+  }
+  if (argv[1][0] == 'y')
+       st.st_mode |= 022;
+  else
+       st.st_mode &= ~022;
+  fchmod(0, st.st_mode);
+  return(0);
+}
diff --git a/historic/mkfs.c b/historic/mkfs.c
new file mode 100644 (file)
index 0000000..018a538
--- /dev/null
@@ -0,0 +1,297 @@
+/*
+ * fs-util     A simple generic frontend for the for the fsck and mkfs
+ *             programs under Linux.  See the manual pages for details.
+ *
+ * Usage:      fsck [-AV] [-t fstype] [fs-options] device
+ *             mkfs [-V] [-t fstype] [fs-options] device< [size]
+ *
+ * Authors:    David Engel, <david@ods.com>
+ *             Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
+ */
+
+
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <errno.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <mntent.h>
+#include <unistd.h>
+#include <getopt.h>
+
+
+#ifndef DEFAULT_FSTYPE
+#   define DEFAULT_FSTYPE      "minix"
+#endif
+
+#define _PATH_PROG     "%s.%s"
+#define _PROG_FSCK     "fsck"
+
+#define EXIT_OK          0
+#define EXIT_NONDESTRUCT 1
+#define EXIT_DESTRUCT    2
+#define EXIT_UNCORRECTED 4
+#define EXIT_ERROR       8
+#define EXIT_USAGE       16
+#define EXIT_LIBRARY     128
+
+static char *Version = "1.8";
+static char *ignored_types[] = {
+  "ignore",
+  "iso9660",
+  "msdos",
+  "nfs",
+  "proc",
+  "sw",
+  "swap",
+  NULL
+};
+
+
+/* Execute a program. */
+int do_exec(char *prog, char **argv, int verbose)
+{
+    char *args[33];
+    register int i;
+    int pid, status;
+
+    /* Build the vector. */
+    i = 0;
+    args[i++] = prog;
+    while(*argv != NULL && i < 32)
+        args[i++] = *argv++;
+    args[i] = NULL;
+
+    if (verbose) {
+       i = 0;
+       while(args[i] != NULL) {
+           printf("%s ", args[i]);
+           i++;
+       }
+       printf("\n");
+       if (verbose > 1)
+           return EXIT_OK;
+    }
+
+    /* Fork and execute the correct program. */
+    if ((pid = fork()) < 0) {
+        perror("fork");
+       status = EXIT_ERROR;
+    } else if (pid == 0) {
+       (void) execvp(args[0], args);
+       perror(args[0]);
+       exit(EXIT_ERROR);
+    } else {
+        while(wait(&status) != pid)
+           ;
+       status = WEXITSTATUS(status);
+    }
+
+    return status;
+}
+
+
+/* Check if we have to ignore a file system type. */
+int ignore(char *type, char *opts)
+{
+    char *cp;
+    char **ip;
+
+    ip = ignored_types;
+    while (*ip != NULL) {
+       if (!strcmp(type, *ip))
+           return 1;
+       ip++;
+    }
+
+    for (cp = strtok(opts, ","); cp != NULL; cp = strtok(NULL, ",")) {
+       if (!strcmp(cp, "noauto"))
+           return 1;
+    }
+
+    return 0;
+}
+
+
+/* Check all file systems, using the /etc/fstab table. */
+int check_all(int verbose, char **argv)
+{
+    char path[PATH_MAX];
+    char *args[33];
+    FILE *mntfile;
+    struct mntent *mp;
+    register int i;
+    int status = EXIT_OK;
+
+    if (verbose)
+        printf("Checking all file systems.\n");
+
+    /* Create an array of arguments. */
+    i = 0;
+    while (*argv != NULL && i < 32)
+       args[i++] = *argv++;
+    args[i] = NULL;
+    args[i + 1] = NULL;
+
+    /* Open the mount table. */
+    if ((mntfile = setmntent(MNTTAB, "r")) == NULL) {
+       perror(MNTTAB);
+       exit(EXIT_ERROR);
+    }
+
+    /* Walk through the /etc/fstab file. */
+    while ((mp = getmntent(mntfile)) != NULL) {
+       if (verbose)
+           printf("%-7s %-15s %-15s ", mp->mnt_type,
+                  mp->mnt_fsname, mp->mnt_dir);
+       if (ignore(mp->mnt_type, mp->mnt_opts)) {
+           if (verbose)
+               printf("(ignored)\n");
+           continue;
+       }
+
+       /* Build program name. */
+       sprintf(path, _PATH_PROG, _PROG_FSCK, mp->mnt_type);
+       args[i] = mp->mnt_fsname;
+       status |= do_exec(path, args, verbose);
+    }
+
+    (void) endmntent(mntfile);
+
+    return status;
+}
+
+
+/* Lookup filesys in /etc/fstab and return the corresponding entry. */
+struct mntent *lookup(char *filesys)
+{
+    FILE *mntfile;
+    struct mntent *mp;
+
+    /* No filesys name given. */
+    if (filesys == NULL)
+        return NULL;
+
+    /* Open the mount table. */
+    if ((mntfile = setmntent(MNTTAB, "r")) == NULL) {
+       perror(MNTTAB);
+       exit(EXIT_ERROR);
+    }
+
+    while ((mp = getmntent(mntfile)) != NULL) {
+       if (!strcmp(filesys, mp->mnt_fsname) ||
+           !strcmp(filesys, mp->mnt_dir))
+           break;
+    }
+
+    (void) endmntent(mntfile);
+
+    return mp;
+}
+
+
+void usage(int fsck, char *prog)
+{
+    if (fsck) {
+       fprintf(stderr, "Usage: fsck [-AV] [-t fstype] [fs-options] filesys\n");
+    } else {
+       fprintf(stderr, "Usage: mkfs [-V] [-t fstype] [fs-options] filesys [size]\n");
+    }
+
+    exit(EXIT_USAGE);
+}
+
+
+void main(int argc, char *argv[])
+{
+    char path[PATH_MAX];
+    char *oldpath, newpath[PATH_MAX];
+    register char *sp;
+    struct mntent *fsent;
+    char *fstype = NULL;
+    int verbose = 0;
+    int doall = 0;
+    int i, fsck, more;
+
+    /* Must be 1 for "fsck" and 0 for "mkfs". */
+    if ((sp = strrchr(argv[0], '/')) != NULL)
+        sp++;
+    else
+        sp = argv[0];
+    if (!strcmp(sp, _PROG_FSCK))
+        fsck = 1;
+    else
+        fsck = 0;
+
+    /* Check commandline options. */
+    opterr = 0;
+    more = 0;
+    while ((more == 0) && ((i = getopt(argc, argv, "AVt:")) != EOF))
+       switch(i) {
+         case 'A':
+           doall++;
+           break;
+         case 'V':
+           verbose++;
+           break;
+         case 't':
+           if (optarg == NULL)
+               usage(fsck, sp);
+           fstype = optarg;
+           break;
+         default:
+           more = 1;
+           break;              /* start of specific arguments */
+       }
+
+    /* Did we get any specific arguments? */
+    if (more)
+        optind--;
+
+    /* Print our version number if requested. */
+    if (verbose)
+        printf("%s (fsutil) version %s (%s)\n", argv[0],
+              Version, __DATE__);
+
+    /* Update our PATH to include /etc/fs and /etc. */
+    strcpy(newpath, "PATH=/etc/fs:/etc:");
+    if ((oldpath = getenv("PATH")) != NULL)
+        strcat(newpath, oldpath);
+    putenv(newpath);
+    
+    /* If -A was specified ("check all"), double-check. */
+    if (doall) {
+       if (!fsck || (fstype != NULL))
+           usage(fsck, sp);
+       exit(check_all(verbose, &argv[optind]));
+    } else {
+       /* If -t wasn't specified, we must deduce fstype. */
+       if (fstype == NULL) {
+           /* make sure that "filesys" was specified */
+           if (optind >= argc)
+               usage(fsck, sp);
+           /* then try looking for it in /etc/fstab */
+           if ((fsent = lookup(argv[argc - 1])) != NULL) {
+               argv[argc - 1] = fsent->mnt_fsname;
+               fstype = fsent->mnt_type;
+           } else {
+               if (!fsck && optind < argc-1) {
+                   if ((fsent = lookup(argv[argc - 2])) != NULL) {
+                       argv[argc - 2] = fsent->mnt_fsname;
+                       fstype = fsent->mnt_type;
+                   }
+               }
+           }
+           /* if we still don't know, use the default */
+           if (fstype == NULL) fstype = DEFAULT_FSTYPE;
+       }
+
+       /* Build program name. */
+       sprintf(path, _PATH_PROG, sp, fstype);
+       exit(do_exec(path, &argv[optind], verbose));
+    }
+    /*NOTREACHED*/
+}
diff --git a/historic/mkswap.8 b/historic/mkswap.8
new file mode 100644 (file)
index 0000000..2c02fbb
--- /dev/null
@@ -0,0 +1,86 @@
+.\" Copyright 1992, 1993 Rickard E. Faith (faith@cs.unc.edu)
+.\" May be distributed under the GNU General Public License
+.\" Modified with suggestions from Linus, Mon Feb  1 21:40:49 1993
+.\" Modified with patches from Kai, Wed Jun 22 21:54:56 1994
+.\" Patches from jaggy@purplet.demon.co.uk (Mike Jagdis), Wed Feb 8 1995
+.\" Added comments from Nick Holloway, Sat Feb 11 1995, faith@cs.unc.edu
+.\" "
+.TH MKSWAP 8 "8 February 1995" "Linux 1.0" "Linux Programmer's Manual"
+.SH NAME
+mkswap \- set up a Linux swap device
+.SH SYNOPSIS
+.B "mkswap [ \-c ]"
+.IB device  " [" size-in-blocks "]"
+.SH DESCRIPTION
+.B mkswap
+sets up a Linux swap area on a device (usually a disk partition).
+
+The
+.I device
+is usually of the following form:
+
+.nf
+.RS
+/dev/hda[1-8]
+/dev/hdb[1-8]
+/dev/sda[1-8]
+/dev/sdb[1-8]
+.RE
+.fi
+
+The
+.I size-in-blocks
+parameter is the desired size of the file system, in blocks.  This
+information is determined automatically by mkswap if it is omitted.  Block
+counts are rounded down to pages of 4 kB each.  Only block counts equal to
+or greater than 40 and equal to or less than 131072 are allowed.  Block
+counts greater than 130752 are (silently) rounded down to 130752.
+
+As Nick Holloway explains, the actual maximum for each swap file/partition
+is:
+.RS
+(4096 - 10) * 8 * 4096 = 133890048 bytes = 130752 blocks =  127.6875 Mb
+.RE
+This is because a single page is used to hold the swap bitmap at the
+start of the partition, where each bit is a single 4K page.  The reason
+for the -10, is that the signature is "SWAP-SPACE" -- 10 characters.
+
+.B mkswap
+can also set up swap files, although the file has to be created first.  A
+sequence of commands similar to the following is reasonable for this
+purpose:
+
+.nf
+.RS
+# dd if=/dev/zero of=swapfile bs=1024 count=8192
+# mkswap swapfile 8192
+# sync
+# swapon swapfile
+.RE
+.fi
+
+Note that the regular file has to be created before running
+.B mkswap
+on the file, and that the file must not contain any holes (so, using
+.BR cp (1)
+to create the file is not acceptable).
+
+.SH OPTIONS
+.TP
+.B \-c
+Check the device for bad blocks before creating the file system.  If any
+are found, the count is printed.  This option is meant to be used for swap
+partitions
+.BR only ,
+and should
+.B not
+be used for regular files!  To make sure that regular files do not contain
+bad blocks, the partition that contains the regular file should have been
+created with
+.BR "mkfs -c" .
+.SH "SEE ALSO"
+.BR fsck (8),
+.BR mkfs (8),
+.BR fdisk (8)
+.SH AUTHOR
+Linus Torvalds (torvalds@cs.helsinki.fi)
diff --git a/historic/mkswap.c b/historic/mkswap.c
new file mode 100644 (file)
index 0000000..bb4e224
--- /dev/null
@@ -0,0 +1,212 @@
+/*
+ * mkswap.c - set up a linux swap device
+ *
+ * (C) 1991 Linus Torvalds. This file may be redistributed as per
+ * the Linux copyright.
+ */
+
+/*
+ * 20.12.91  - time began. Got VM working yesterday by doing this by hand.
+ *
+ * Usuage: mkswap [-c] device [size-in-blocks]
+ *
+ *     -c for readablility checking (use it unless you are SURE!)
+ *
+ * The device may be a block device or a image of one, but this isn't
+ * enforced (but it's not much fun on a character device :-).
+ *
+ * Patches from jaggy@purplet.demon.co.uk (Mike Jagdis) to make the
+ * size-in-blocks parameter optional added Wed Feb  8 10:33:43 1995.
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+
+#include <linux/mm.h>
+
+#ifndef __GNUC__
+#error "needs gcc for the bitop-__asm__'s"
+#endif
+
+#ifndef __linux__
+#define volatile
+#endif
+
+#define TEST_BUFFER_PAGES 8
+
+static char * program_name = "mkswap";
+static char * device_name = NULL;
+static int DEV = -1;
+static long PAGES = 0;
+static int check = 0;
+static int badpages = 0;
+
+static char signature_page[PAGE_SIZE];
+
+#define bitop(name,op) \
+static inline int name(char * addr,unsigned int nr) \
+{ \
+int __res; \
+__asm__ __volatile__("bt" op " %1,%2; adcl $0,%0" \
+:"=g" (__res) \
+:"r" (nr),"m" (*(addr)),"0" (0)); \
+return __res; \
+}
+
+bitop(bit,"")
+bitop(setbit,"s")
+bitop(clrbit,"r")
+
+/*
+ * Volatile to let gcc know that this doesn't return. When trying
+ * to compile this under minix, volatile gives a warning, as
+ * exit() isn't defined as volatile under minix.
+ */
+volatile void fatal_error(const char * fmt_string)
+{
+       fprintf(stderr,fmt_string,program_name,device_name);
+       exit(1);
+}
+
+#define usage() fatal_error("Usage: %s [-c] /dev/name [blocks]\n")
+#define die(str) fatal_error("%s: " str "\n")
+
+void check_blocks(void)
+{
+       unsigned int current_page;
+       int do_seek = 1;
+       static char buffer[PAGE_SIZE];
+
+       current_page = 0;
+       while (current_page < PAGES) {
+               if (!check) {
+                       setbit(signature_page,current_page++);
+                       continue;
+               }
+               if (do_seek && lseek(DEV,current_page*PAGE_SIZE,SEEK_SET) !=
+               current_page*PAGE_SIZE)
+                       die("seek failed in check_blocks");
+               if (do_seek = (PAGE_SIZE != read(DEV, buffer, PAGE_SIZE))) {
+                       clrbit(signature_page,current_page++);
+                       badpages++;
+                       continue;
+               }
+               setbit(signature_page,current_page++);
+       }
+       if (badpages)
+               printf("%d bad page%s\n",badpages,(badpages>1)?"s":"");
+}
+
+static long valid_offset (int fd, int offset)
+{
+       char ch;
+
+       if (lseek (fd, offset, 0) < 0)
+               return 0;
+       if (read (fd, &ch, 1) < 1)
+               return 0;
+       return 1;
+}
+
+static int count_blocks (int fd)
+{
+       int high, low;
+
+       low = 0;
+       for (high = 1; valid_offset (fd, high); high *= 2)
+               low = high;
+       while (low < high - 1)
+       {
+               const int mid = (low + high) / 2;
+
+               if (valid_offset (fd, mid))
+                       low = mid;
+               else
+                       high = mid;
+       }
+       valid_offset (fd, 0);
+       return (low + 1);
+}
+
+static int get_size(const char  *file)
+{
+       int     fd;
+       int     size;
+
+       fd = open(file, O_RDWR);
+       if (fd < 0) {
+               perror(file);
+               exit(1);
+       }
+       if (ioctl(fd, BLKGETSIZE, &size) >= 0) {
+               close(fd);
+               return (size * 512);
+       }
+               
+       size = count_blocks(fd);
+       close(fd);
+       return size;
+}
+
+int main(int argc, char ** argv)
+{
+       char * tmp;
+       struct stat statbuf;
+       int goodpages;
+
+       memset(signature_page,0,PAGE_SIZE);
+       if (argc && *argv)
+               program_name = *argv;
+       while (argc-- > 1) {
+               argv++;
+               if (argv[0][0] != '-')
+                       if (device_name) {
+                               PAGES = strtol(argv[0],&tmp,0)>>2;
+                               if (*tmp)
+                                       usage();
+                       } else
+                               device_name = argv[0];
+               else while (*++argv[0])
+                       switch (argv[0][0]) {
+                               case 'c': check=1; break;
+                               default: usage();
+                       }
+       }
+       if (device_name && !PAGES) {
+               PAGES = get_size(device_name) / PAGE_SIZE;
+       }
+       if (!device_name || PAGES<10)
+               usage();
+       if (PAGES > 32688) /* 130752 blocks */
+               PAGES=32688;
+#if 0
+       if (PAGES > 32768)
+               PAGES=32768;
+#endif
+       DEV = open(device_name,O_RDWR);
+       if (DEV < 0 || fstat(DEV, &statbuf) < 0) {
+               perror(device_name);
+               exit(1);
+       }
+       if (!S_ISBLK(statbuf.st_mode))
+               check=0;
+       else if (statbuf.st_rdev == 0x0300 || statbuf.st_rdev == 0x0340)
+               die("Will not try to make swapdevice on '%s'");
+       check_blocks();
+       if (!clrbit(signature_page,0))
+               die("fatal: first page unreadable");
+       goodpages = PAGES - badpages - 1;
+       if (!goodpages)
+               die("Unable to set up swap-space: unreadable");
+       printf("Setting up swapspace, size = %d bytes\n",goodpages*PAGE_SIZE);
+       strncpy(signature_page+PAGE_SIZE-10,"SWAP-SPACE",10);
+       if (lseek(DEV, 0, SEEK_SET))
+               die("unable to rewind swap-device");
+       if (PAGE_SIZE != write(DEV, signature_page, PAGE_SIZE))
+               die("unable to write signature page");
+       return 0;
+}
index ec78fbcd281c17951fc80bd1b5a85f8d8a6d8075..4195d79d38fb03659066b8fed5a96d75cb6e0f95 100644 (file)
@@ -25,8 +25,9 @@ selection.man:        selection.1
                nroff -man selection.1 > selection.man
 
 install:       selection # selection.man
-       install -m 755 selection $(BINDIR)/selection
-       install -m 644 selection.1 $(MANDIR)/man$(MANEXT)/selection.$(MANEXT)
+       $(INSTALLDIR) $(USRBINDIR) $(MAN1DIR)
+       $(INSTALLBIN) selection $(USRBINDIR)
+       $(INSTALLMAN) selection.1 $(MAN1DIR)
 
 DIST = selection-1.5
 DATE = 17th June 1993
diff --git a/historic/selection/mouse.c.old b/historic/selection/mouse.c.old
new file mode 100644 (file)
index 0000000..e5e474e
--- /dev/null
@@ -0,0 +1,356 @@
+/* simple driver for serial mouse */
+/* Andrew Haylett, 17th June 1993 */
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <termios.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "mouse.h"
+
+#define DEF_MDEV       "/dev/mouse"
+#define DEF_MTYPE      P_MS
+#define DEF_MBAUD      1200
+#define DEF_MSAMPLE    100
+#define DEF_MDELTA     25
+#define DEF_MACCEL     2
+
+/* thse settings may be altered by the user */
+static char *mdev = DEF_MDEV;          /* mouse device */
+static mouse_type mtype = DEF_MTYPE;   /* mouse type */
+static int mbaud = DEF_MBAUD;          /* mouse device baud rate */
+static int msample = DEF_MSAMPLE;      /* sample rate for Logitech mice */
+static int mdelta = DEF_MDELTA;                /* x+y movements more than mdelta pixels..*/
+static int maccel = DEF_MACCEL;                /* ..are multiplied by maccel. */
+int ms_copy_button = MS_BUTLEFT,
+    ms_paste_button = MS_BUTRIGHT;
+
+static char *progname;
+
+static void
+ms_usage()
+{
+    printf(
+       "Selection version 1.5, 17th June 1993\n"
+       "Usage: %s [-a accel] [-b baud-rate] [-c l|m|r] [-d delta]\n"
+       "       [-m mouse-device] [-p l|m|r] [-s sample-rate] [-t mouse-type]\n\n", progname);
+    printf(
+       "    -a accel         sets the acceleration (default %d)\n"
+       "    -b baud-rate     sets the baud rate (default %d)\n"
+       "    -c l|m|r         sets the copy button (default `l')\n"
+       "    -d delta         sets the delta value (default %d)\n"
+       "    -m mouse-device  sets mouse device (default `%s')\n"
+       "    -p l|m|r         sets the paste button (default `r')\n"
+       "    -s sample-rate   sets the sample rate (default %d)\n"
+       "    -t mouse-type    sets mouse type (default `ms')\n"
+       "                     Microsoft = `ms', Mouse Systems Corp = `msc',\n"
+       "                     MM Series = `mm', Logitech = `logi', BusMouse = `bm',\n"
+       "                     MSC 3-bytes = `sun', PS/2 = `ps2')\n",
+       DEF_MACCEL, DEF_MBAUD, DEF_MDELTA, DEF_MDEV, DEF_MSAMPLE);
+    exit(1);
+}
+
+extern int optind;
+extern char *optarg;
+
+void
+ms_params(int argc, char *argv[])
+{
+    int opt;
+
+    progname = (rindex(argv[0], '/')) ? rindex(argv[0], '/') + 1 : argv[0];
+    while ((opt = getopt(argc, argv, "a:b:c:d:m:p:s:t:")) != -1)
+    {
+       switch (opt)
+       {
+           case 'a':
+               maccel = atoi(optarg);
+               if (maccel < 2)
+                   ms_usage();
+               break;
+           case 'b':
+               mbaud = atoi(optarg);
+               break;
+           case 'c':
+               switch (*optarg)
+               {
+                   case 'l':   ms_copy_button = MS_BUTLEFT; break;
+                   case 'm':   ms_copy_button = MS_BUTMIDDLE; break;
+                   case 'r':   ms_copy_button = MS_BUTRIGHT; break;
+                   default:    ms_usage(); break;
+               }
+               break;
+           case 'd':
+               mdelta = atoi(optarg);
+               if (mdelta < 2)
+                   ms_usage();
+               break;
+           case 'm':
+               mdev = optarg;
+               break;
+           case 'p':
+               switch (*optarg)
+               {
+                   case 'l':   ms_paste_button = MS_BUTLEFT; break;
+                   case 'm':   ms_paste_button = MS_BUTMIDDLE; break;
+                   case 'r':   ms_paste_button = MS_BUTRIGHT; break;
+                   default:    ms_usage(); break;
+               }
+               break;
+           case 's':
+               msample = atoi(optarg);
+               break;
+           case 't':
+               if (!strcmp(optarg, "ms"))
+                   mtype = P_MS;
+               else if (!strcmp(optarg, "sun"))
+                   mtype = P_SUN;
+               else if (!strcmp(optarg, "msc"))
+                   mtype = P_MSC;
+               else if (!strcmp(optarg, "mm"))
+                   mtype = P_MM;
+               else if (!strcmp(optarg, "logi"))
+                   mtype = P_LOGI;
+               else if (!strcmp(optarg, "bm"))
+                   mtype = P_BM;
+               else if (!strcmp(optarg, "ps2"))
+                   mtype = P_PS2;
+               else
+                   ms_usage();
+               break;
+           default:
+               ms_usage();
+               break;
+       }
+    }
+}
+
+#define limit(n,l,u)   n = ((n) < (l) ? (l) : ((n) > (u) ? (u) : (n)))
+
+static int mx = 32767;
+static int my = 32767;
+static int x, y;
+static int mfd = -1;
+
+static const unsigned short cflag[NR_TYPES] =
+{
+      (CS7                   | CREAD | CLOCAL | HUPCL ),   /* MicroSoft */
+      (CS8 | CSTOPB          | CREAD | CLOCAL | HUPCL ),   /* MouseSystems 3 */
+      (CS8 | CSTOPB          | CREAD | CLOCAL | HUPCL ),   /* MouseSystems 5 */
+      (CS8 | PARENB | PARODD | CREAD | CLOCAL | HUPCL ),   /* MMSeries */
+      (CS8 | CSTOPB          | CREAD | CLOCAL | HUPCL ),   /* Logitech */
+      0,                                                   /* BusMouse */
+      0                                                    /* PS/2 */
+};
+
+static const unsigned char proto[NR_TYPES][5] =
+{
+    /*  hd_mask hd_id   dp_mask dp_id   nobytes */
+    {  0x40,   0x40,   0x40,   0x00,   3       },  /* MicroSoft */
+    {  0xf8,   0x80,   0x00,   0x00,   3       },  /* MouseSystems 3 (Sun) */
+    {  0xf8,   0x80,   0x00,   0x00,   5       },  /* MouseSystems 5 */
+    {  0xe0,   0x80,   0x80,   0x00,   3       },  /* MMSeries */
+    {  0xe0,   0x80,   0x80,   0x00,   3       },  /* Logitech */
+    {  0xf8,   0x80,   0x00,   0x00,   5       },  /* BusMouse */
+    {   0xcc,  0x00,   0x00,   0x00,   3       }   /* PS/2 */
+};
+
+static void
+ms_setspeed(const int old, const int new,
+            const unsigned short c_cflag)
+{
+    struct termios tty;
+    char *c;
+
+    tcgetattr(mfd, &tty);
+    
+    tty.c_iflag = IGNBRK | IGNPAR;
+    tty.c_oflag = 0;
+    tty.c_lflag = 0;
+    tty.c_line = 0;
+    tty.c_cc[VTIME] = 0;
+    tty.c_cc[VMIN] = 1;
+
+    switch (old)
+    {
+       case 9600:      tty.c_cflag = c_cflag | B9600; break;
+       case 4800:      tty.c_cflag = c_cflag | B4800; break;
+       case 2400:      tty.c_cflag = c_cflag | B2400; break;
+       case 1200:
+       default:        tty.c_cflag = c_cflag | B1200; break;
+    }
+
+    tcsetattr(mfd, TCSAFLUSH, &tty);
+
+    switch (new)
+    {
+       case 9600:      c = "*q";  tty.c_cflag = c_cflag | B9600; break;
+       case 4800:      c = "*p";  tty.c_cflag = c_cflag | B4800; break;
+       case 2400:      c = "*o";  tty.c_cflag = c_cflag | B2400; break;
+       case 1200:
+       default:        c = "*n";  tty.c_cflag = c_cflag | B1200; break;
+    }
+
+    write(mfd, c, 2);
+    usleep(100000);
+    tcsetattr(mfd, TCSAFLUSH, &tty);
+}
+
+int
+ms_init(const int maxx, const int maxy)
+{
+    if ((mfd = open(mdev, O_RDWR)) < 0)
+    {
+       char buf[32];
+       sprintf(buf, "ms_init: %s", mdev);
+       perror(buf);
+       return -1;
+    }
+
+    if (mtype != P_BM && mtype != P_PS2)
+    {
+       ms_setspeed(9600, mbaud, cflag[mtype]);
+       ms_setspeed(4800, mbaud, cflag[mtype]);
+       ms_setspeed(2400, mbaud, cflag[mtype]);
+       ms_setspeed(1200, mbaud, cflag[mtype]);
+
+       if (mtype == P_LOGI)
+       {
+           write(mfd, "S", 1);
+           ms_setspeed(mbaud, mbaud, cflag[P_MM]);
+       }
+
+       if      (msample <= 0)          write(mfd, "O", 1);
+       else if (msample <= 15)         write(mfd, "J", 1);
+       else if (msample <= 27)         write(mfd, "K", 1);
+       else if (msample <= 42)         write(mfd, "L", 1);
+       else if (msample <= 60)         write(mfd, "R", 1);
+       else if (msample <= 85)         write(mfd, "M", 1);
+       else if (msample <= 125)        write(mfd, "Q", 1);
+       else                            write(mfd, "N", 1);
+    }
+
+    mx = maxx;
+    my = maxy;
+    x = mx / 2;
+    y = my / 2;
+    return 0;
+}
+
+int
+get_ms_event(struct ms_event *ev)
+{
+    unsigned char buf[5];
+    char dx, dy;
+    int i, acc;
+
+    if (mfd == -1)
+       return -1;
+    if (mtype != P_BM)
+    {
+       if (read(mfd, &buf[0], 1) != 1)
+           return -1;
+restart:
+       /* find a header packet */
+       while ((buf[0] & proto[mtype][0]) != proto[mtype][1])
+       {
+           if (read(mfd, &buf[0], 1) != 1)
+           {
+               perror("get_ms_event: read");
+               return -1;
+           }
+       }
+
+       /* read in the rest of the packet */
+       for (i = 1; i < proto[mtype][4]; ++i)
+       {
+           if (read(mfd, &buf[i], 1) != 1)
+           {
+               perror("get_ms_event: read");
+               return -1;
+           }
+       /* check whether it's a data packet */
+           if (mtype != P_PS2 && ((buf[i] & proto[mtype][2]) != proto[mtype][3]
+                   || buf[i] == 0x80))
+               goto restart;
+       }
+    }
+    else       /* bus mouse */
+    {
+       while ((i = read(mfd, buf, 3)) != 3 && errno == EAGAIN)
+           usleep(40000);
+       if (i != 3)
+       {
+           perror("get_ms_event: read");
+           return -1;
+       }
+    }
+
+/* construct the event */
+    switch (mtype)
+    {
+       case P_MS:              /* Microsoft */
+       default:
+           ev->ev_butstate = ((buf[0] & 0x20) >> 3) | ((buf[0] & 0x10) >> 4);
+           dx = (char)(((buf[0] & 0x03) << 6) | (buf[1] & 0x3F));
+           dy = (char)(((buf[0] & 0x0C) << 4) | (buf[2] & 0x3F));
+           break;
+        case P_SUN:            /* Mouse Systems 3 byte as used in Sun workstations */
+           ev->ev_butstate = (~buf[0]) & 0x07;
+           dx =  (char)(buf[1]);
+           dy = -(char)(buf[2]);
+           break;
+       case P_MSC:             /* Mouse Systems Corp (5 bytes, PC) */
+           ev->ev_butstate = (~buf[0]) & 0x07;
+           dx =    (char)(buf[1]) + (char)(buf[3]);
+           dy = - ((char)(buf[2]) + (char)(buf[4]));
+           break;
+       case P_MM:              /* MM Series */
+       case P_LOGI:            /* Logitech */
+           ev->ev_butstate = buf[0] & 0x07;
+           dx = (buf[0] & 0x10) ?   buf[1] : - buf[1];
+           dy = (buf[0] & 0x08) ? - buf[2] :   buf[2];
+           break;
+       case P_BM:              /* BusMouse */
+           ev->ev_butstate = (~buf[0]) & 0x07;
+           dx =   (char)buf[1];
+           dy = - (char)buf[2];
+           break;
+       case P_PS2:            /* PS/2 Mouse */
+           ev->ev_butstate = 0;
+           if (buf[0] & 0x01)
+               ev->ev_butstate |= MS_BUTLEFT;
+           if (buf[0] & 0x02)
+               ev->ev_butstate |= MS_BUTRIGHT;
+           dx =    (buf[0] & 0x10) ? buf[1]-256 : buf[1];
+           dy = - ((buf[0] & 0x20) ? buf[2]-256 : buf[2]);
+           break;
+    }
+
+    acc = (abs(ev->ev_dx) + abs(ev->ev_dy) > mdelta) ? maccel : 1;
+    ev->ev_dx = dx * acc;
+    ev->ev_dy = dy * acc;
+    x += ev->ev_dx;
+    y += ev->ev_dy;
+    limit(x, 0, mx);
+    limit(y, 0, my);
+    ev->ev_x = x;
+    ev->ev_y = y;
+    if (dx || dy)
+    {
+       if (ev->ev_butstate)
+           ev->ev_code = MS_DRAG;
+       else
+           ev->ev_code = MS_MOVE;
+    }
+    else
+    {
+       if (ev->ev_butstate)
+           ev->ev_code = MS_BUTDOWN;
+       else
+           ev->ev_code = MS_BUTUP;
+    }
+    return 0;
+}
diff --git a/historic/selection/selection.1.old b/historic/selection/selection.1.old
new file mode 100644 (file)
index 0000000..fdc76af
--- /dev/null
@@ -0,0 +1,139 @@
+.\"
+.\" selection.1 - the cut and paste utility for Linux virtual consoles
+.\"
+.\" Modified by faith@cs.unc.edu
+.\"
+.TH SELECTION 1 "20 November 1993" "Linux 0.99" "Linux Programmer's Manual"
+.SH NAME
+selection - the cut and paste utility for Linux virtual consoles
+.SH SYNTAX
+\fBselection [-a accel] [-b baud-rate] [-c l|m|r] [-d delta] [-m mouse-device] [-p l|m|r] [-s sample-rate] [-t mouse-type]\fR
+.SH DESCRIPTION
+\fBselection\fR is a utility that allows characters to be selected from the
+current Linux virtual console using the mouse and pasted into the current
+console. \fBselection\fR is normally invoked at boot time from /etc/rc.local,
+and runs as a background process.
+.SH OPTIONS
+.IP \fB\-a\fP\fIaccel\fP
+movements of more than \fIdelta\fP pixels are multiplied by \fIaccel\fP (default 2)
+.IP \fB\-b\fP\fIbaud-rate\fP
+set the baud rate of the mouse (default 1200 baud)
+.IP \fB\-c\fP\fIl|m|r\fP
+set the copy button to be the left, middle or right button (default left)
+.IP \fB\-d\fP\fIdelta\fP
+movements of more than \fIdelta\fP pixels are multiplied by \fIaccel\fP
+(default 25)
+.IP \fB\-m\fP\fImouse-device\fP
+specify the mouse device (default /dev/mouse)
+.IP \fB\-p\fP\fIl|m|r\fP
+set the paste button to be the left, middle or right button (default right)
+.IP \fB\-s\fP\fIsample-rate\fP
+set the sample rate of the mouse (default 100)
+.IP \fB\-t\fP\fImouse-type\fP
+specify the mouse type (Microsoft = `ms', Mouse Systems Corp = `msc',
+MM Series = `mm', Logitech = `logi', BusMouse = `bm',
+MSC 3-bytes = `sun', PS/2 = `ps2'; default = ms)
+.SH OPERATION
+To invoke the selection mechanism, press and release the copy button
+(the meaning of the buttons may be set at startup as above). A highlighted
+block will start moving around the screen, correlated with the movement of the
+mouse.
+.PP
+Move the block to the first character of the selection, then press and hold
+down the copy button.
+.PP
+Drag out the selection; the selected text will be highlighted. Then release
+the copy button. You can take the end of the selection to before the start of
+the selection if necessary.
+.PP
+Double-clicking the copy button while the highlighted block is on the
+screen selects text by word boundaries; treble-clicking selects by entire
+lines. If the button is held down after double- or treble-clicking, multiple
+words or lines may be selected. A word consists of a set of alphanumeric
+characters and underscores.
+.PP
+If a trailing space after the contents of a line is highlighted, and if there
+is no other text on the remainder of the line, the rest of the line will be
+selected automatically. If a number of lines are selected, highlighted
+trailing spaces on each line will be removed from the selection buffer.
+.PP
+Pressing the paste button in any virtual console pastes the
+selected text into the read queue of the associated tty.
+.PP
+Any output on the virtual console holding the selection will clear the
+highlighted selection from the screen, to maintain integrity of the display,
+although the contents of the paste buffer will be unaffected.
+.PP
+The selection mechanism is disabled if the controlling virtual console is
+placed in graphics mode, for example when running X11, and is re-enabled when
+text mode is resumed. (But see BUGS section below.)
+.SH FILES
+/dev/mouse - default mouse device
+.br
+/dev/tty0 - current VC device
+.SH DIAGNOSTICS
+\fBselection\fR complains if any of the devices it requires cannot be located.
+.SH BUGS
+The size of the paste buffer is set at 2048 bytes by default. This may be
+changed at compile time; consult the installation notes.
+.PP
+The selection mechanism doesn't work very well with graphics characters, or
+indeed with any characters where a mapping between the typed character and
+the displayed character is performed by the console driver. The selection
+mechanism pastes into the input buffer the character codes as they are
+displayed on the screen, not those originally typed in by the user.
+.PP
+Because of the way that the kernel bus mouse drivers work, allowing only one
+process to have the mouse device open at once, \fBselection\fR cannot
+co-exist with X11 using ATI XL, Logitech and Microsoft bus mice or with a
+PS/2 mouse. The X server will not start while \fBselection\fR is running.
+This problem is not present with serial mice.
+.SH AUTHOR
+.nf
+Andrew Haylett <ajh@gec-mrc.co.uk>
+.SH ACKNOWLEDGEMENTS
+.nf
+Lefty patches originally suggested by:
+.ti +4
+Sotiris C. Vassilopoulos <scv2f@edu.Virginia.acc.honi4>
+.br
+Logitech patches from:
+.ti +4
+Jim Winstead Jr <jwinstea@jarthur.Claremont.EDU>
+.br
+Command line options based on those from:
+.ti +4
+Peter Macdonald <pmacdona@sanjuan>
+.br
+Patches for bus mouse from:
+.br
+.ti +4
+Erik Troan <ewtroan@eos.ncsu.edu>
+.br
+.ti +4
+Christoph Niemann <niemann@rubdv15.etdv.ruhr-uni-bochum.de>
+.br
+.ti +4
+Koen Gadeyne <kmg@barco.be>
+.br
+Patches for PS/2 mouse from:
+.br
+.ti +4
+Hans D. Fink
+.br
+Patches for Sun mouse from:
+.br
+.ti +4
+Michael Haardt <michael@gandalf.moria>
+.br
+Run-time configurable mouse buttons suggested by:
+.br
+.ti +4
+Charlie Brady <charlieb@au.oz.tpl.tplrd>
+.br
+Setsid patches by:
+.bt
+.ti +4
+Rick Sladkey <jrs@world.std.com>
+.sp
+Apologies to any contributors whose names I have omitted.
diff --git a/install-sh b/install-sh
new file mode 100644 (file)
index 0000000..ab74c88
--- /dev/null
@@ -0,0 +1,238 @@
+#!/bin/sh
+#
+# install - install a program, script, or datafile
+# This comes from X11R5.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# `make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch.
+#
+
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit="${DOITPROG-}"
+
+
+# put in absolute paths if you don't have them in your path; or use env. vars.
+
+mvprog="${MVPROG-mv}"
+cpprog="${CPPROG-cp}"
+chmodprog="${CHMODPROG-chmod}"
+chownprog="${CHOWNPROG-chown}"
+chgrpprog="${CHGRPPROG-chgrp}"
+stripprog="${STRIPPROG-strip}"
+rmprog="${RMPROG-rm}"
+mkdirprog="${MKDIRPROG-mkdir}"
+
+tranformbasename=""
+transform_arg=""
+instcmd="$mvprog"
+chmodcmd="$chmodprog 0755"
+chowncmd=""
+chgrpcmd=""
+stripcmd=""
+rmcmd="$rmprog -f"
+mvcmd="$mvprog"
+src=""
+dst=""
+dir_arg=""
+
+while [ x"$1" != x ]; do
+    case $1 in
+       -c) instcmd="$cpprog"
+           shift
+           continue;;
+
+       -d) dir_arg=true
+           shift
+           continue;;
+
+       -m) chmodcmd="$chmodprog $2"
+           shift
+           shift
+           continue;;
+
+       -o) chowncmd="$chownprog $2"
+           shift
+           shift
+           continue;;
+
+       -g) chgrpcmd="$chgrpprog $2"
+           shift
+           shift
+           continue;;
+
+       -s) stripcmd="$stripprog"
+           shift
+           continue;;
+
+       -t=*) transformarg=`echo $1 | sed 's/-t=//'`
+           shift
+           continue;;
+
+       -b=*) transformbasename=`echo $1 | sed 's/-b=//'`
+           shift
+           continue;;
+
+       *)  if [ x"$src" = x ]
+           then
+               src=$1
+           else
+               # this colon is to work around a 386BSD /bin/sh bug
+               :
+               dst=$1
+           fi
+           shift
+           continue;;
+    esac
+done
+
+if [ x"$src" = x ]
+then
+       echo "install:  no input file specified"
+       exit 1
+else
+       true
+fi
+
+if [ x"$dir_arg" != x ]; then
+       dst=$src
+       src=""
+       
+       if [ -d $dst ]; then
+               instcmd=:
+       else
+               instcmd=mkdir
+       fi
+else
+
+# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
+# might cause directories to be created, which would be especially bad 
+# if $src (and thus $dsttmp) contains '*'.
+
+       if [ -f $src -o -d $src ]
+       then
+               true
+       else
+               echo "install:  $src does not exist"
+               exit 1
+       fi
+       
+       if [ x"$dst" = x ]
+       then
+               echo "install:  no destination specified"
+               exit 1
+       else
+               true
+       fi
+
+# If destination is a directory, append the input filename; if your system
+# does not like double slashes in filenames, you may need to add some logic
+
+       if [ -d $dst ]
+       then
+               dst="$dst"/`basename $src`
+       else
+               true
+       fi
+fi
+
+## this sed command emulates the dirname command
+dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
+
+# Make sure that the destination directory exists.
+#  this part is taken from Noah Friedman's mkinstalldirs script
+
+# Skip lots of stat calls in the usual case.
+if [ ! -d "$dstdir" ]; then
+defaultIFS='   
+'
+IFS="${IFS-${defaultIFS}}"
+
+oIFS="${IFS}"
+# Some sh's can't handle IFS=/ for some reason.
+IFS='%'
+set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
+IFS="${oIFS}"
+
+pathcomp=''
+
+while [ $# -ne 0 ] ; do
+       pathcomp="${pathcomp}${1}"
+       shift
+
+       if [ ! -d "${pathcomp}" ] ;
+        then
+               $mkdirprog "${pathcomp}"
+       else
+               true
+       fi
+
+       pathcomp="${pathcomp}/"
+done
+fi
+
+if [ x"$dir_arg" != x ]
+then
+       $doit $instcmd $dst &&
+
+       if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
+       if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
+       if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
+       if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
+else
+
+# If we're going to rename the final executable, determine the name now.
+
+       if [ x"$transformarg" = x ] 
+       then
+               dstfile=`basename $dst`
+       else
+               dstfile=`basename $dst $transformbasename | 
+                       sed $transformarg`$transformbasename
+       fi
+
+# don't allow the sed command to completely eliminate the filename
+
+       if [ x"$dstfile" = x ] 
+       then
+               dstfile=`basename $dst`
+       else
+               true
+       fi
+
+# Make a temp file name in the proper directory.
+
+       dsttmp=$dstdir/#inst.$$#
+
+# Move or copy the file name to the temp name
+
+       $doit $instcmd $src $dsttmp &&
+
+       trap "rm -f ${dsttmp}" 0 &&
+
+# and set any options; do chmod last to preserve setuid bits
+
+# If any of these fail, we abort the whole thing.  If we want to
+# ignore errors from any of these, just make sure not to ignore
+# errors from the above "$doit $instcmd $src $dsttmp" command.
+
+       if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
+       if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
+       if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
+       if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
+
+# Now rename the file to the real destination.
+
+       $doit $rmcmd -f $dstdir/$dstfile &&
+       $doit $mvcmd $dsttmp $dstdir/$dstfile 
+
+fi &&
+
+
+exit 0
index 88e0b82209c0169bf6afe2b905b0f6331cc05517..35c8125a2d5a88182c745fe4f3dbf542595112f0 100644 (file)
@@ -1,6 +1,6 @@
 # Makefile -- Makefile for util-linux Linux utilities
 # Created: Sat Dec 26 20:09:40 1992
-# Revised: Wed Feb 22 16:09:31 1995 by faith@cs.unc.edu
+# Revised: Thu Oct 12 10:10:32 1995 by r.faith@ieee.org
 # Copyright 1992, 1993, 1994, 1995 Rickard E. Faith (faith@cs.unc.edu)
 #
 # Suggested changed from Bauke Jan Douma <bjdouma@xs4all.nl> have been
@@ -10,46 +10,64 @@ include ../MCONFIG
 
 # Where to put man pages?
 
-MAN1=          last.1 mesg.1 wall.1
+MAN1.MISC=     last.1 mesg.1 wall.1
 
-MAN1.NONSHADOW= chfn.1 chsh.1 login.1 newgrp.1 passwd.1
+MAN1.PUTILS=   chfn.1 chsh.1 login.1 newgrp.1
+MAN1.PASSWD=    passwd.1
 
-MAN8=          agetty.8 fastboot.8 fasthalt.8 halt.8 reboot.8 simpleinit.8 \
-               shutdown.8
+MAN8.GETTY=    agetty.8
 
-MAN8.NONSHADOW= vipw.8
+MAN8.INIT=     fastboot.8 fasthalt.8 halt.8 reboot.8 simpleinit.8 shutdown.8
+
+MAN8.PUTILS=   vipw.8
 
 # Where to put binaries?
 # See the "install" rule for the links. . .
 
-SBIN=          agetty simpleinit shutdown
+SBIN.GETTY=    agetty
 
-BIN.NONSHADOW=  login
+SBIN.INIT=     simpleinit shutdown
 
-USRBIN=                last mesg wall
+BIN.PUTILS=    login
 
-USRBIN.NONSHADOW= chfn chsh newgrp passwd
+USRBIN.MISC=   last mesg wall
 
-USRSBIN.NONSHADOW= vipw
+USRBIN.PUTILS= chfn chsh newgrp
+USRBIN.PASSWD= passwd
 
-PASSWDDIR=     /usr/bin
+USRSBIN.PUTILS=        vipw
 
 ifeq "$(HAVE_SHADOW)" "no"
-WHAT_TO_BUILD:=$(WHAT_TO_BUILD) all-nonshadow
-WHAT_TO_INSTALL:=$(WHAT_TO_INSTALL) install-nonshadow
+ifeq "$(HAVE_PASSWD)" "no"
+WHAT_TO_BUILD:=$(WHAT_TO_BUILD) all-passwd all-putils
+WHAT_TO_INSTALL:=$(WHAT_TO_INSTALL) install-passwd install-putils
+else
+WHAT_TO_BUILD:=$(WHAT_TO_BUILD) all-putils
+WHAT_TO_INSTALL:=$(WHAT_TO_INSTALL) install-putils
+endif
 endif
 
 ifeq "$(HAVE_SYSVINIT)" "no"
-WHAT_TO_BUILD:=$(WHAT_TO_BUILD) all-nonsysvinit
-WHAT_TO_INSTALL:=$(WHAT_TO_INSTALL) install-nonsysvinit
+WHAT_TO_BUILD:=$(WHAT_TO_BUILD) all-init
+WHAT_TO_INSTALL:=$(WHAT_TO_INSTALL) install-init
 endif
 
-all: $(WHAT_TO_BUILD)
-all-nonshadow: $(BIN.NONSHADOW) $(USRBIN.NONSHADOW) $(USRSBIN.NONSHADOW)
-all-nonsysvinit: $(USRBIN) $(SBIN)
+ifeq "$(HAVE_SYSVINIT_UTILS)" "no"
+WHAT_TO_BUILD:=$(WHAT_TO_BUILD) all-misc
+WHAT_TO_INSTALL:=$(WHAT_TO_INSTALL) install-misc
+endif
 
-%.o: %.c
-       $(CC) -c $(CFLAGS) $< -o $@
+ifeq "$(HAVE_GETTY)" "no"
+WHAT_TO_BUILD:=$(WHAT_TO_BUILD) all-getty
+WHAT_TO_INSTALL:=$(WHAT_TO_INSTALL) install-getty
+endif
+
+all: $(WHAT_TO_BUILD)
+all-passwd: $(USRBIN.PASSWD)
+all-putils: $(BIN.PUTILS) $(USRBIN.PUTILS) $(USRSBIN.PUTILS)
+all-init: $(SBIN.INIT)
+all-getty: $(SBIN.GETTY)
+all-misc: $(USRBIN.MISC)
 
 # Rules for everything else
 
@@ -59,12 +77,11 @@ chfn: chfn.o setpwnam.o
 chsh: chsh.o setpwnam.o
 last.o: $(BSD)/pathnames.h
 last: last.o $(BSD)/getopt.o
-login.o: $(BSD)/pathnames.h
-login: login.o
-mesg: mesg.o
+login: login.o checktty.o
+mesg: mesg.o $(BSD)/getopt.o $(BSD)/err.o
 newgrp.o: $(BSD)/pathnames.h
 newgrp: newgrp.o
-passwd: passwd.o islocal.o
+setpwnam.o: $(BSD)/pathnames.h
 shutdown.o: $(BSD)/pathnames.h
 shutdown: shutdown.o
 simpleinit.o: $(BSD)/pathnames.h
@@ -73,40 +90,81 @@ vipw.o: $(BSD)/pathnames.h
 vipw: vipw.o
 wall: wall.o ttymsg.o
 
+ifeq "$(USE_TTY_GROUP)" "yes"
+login.o: login.c $(BSD)/pathnames.h
+       $(CC) -c $(CFLAGS) -DUSE_TTY_GROUP login.c
+mesg.o: mesg.c $(BSD)/err.h
+       $(CC) -c $(CFLAGS) -DUSE_TTY_GROUP mesg.c
+else
+login.o: $(BSD)/pathnames.h
+mesg.o: $(BSD)/err.h
+endif
+
+passwd: passwd.o islocal.o setpwnam.o
+passwd.o: passwd.c
+       $(CC) -c $(CFLAGS) -DUSE_SETPWNAM passwd.c
+
+ifeq "$(REQUIRE_PASSWORD)" "yes"
+CHSH_FLAGS:=$(CHSH_FLAGS) -DREQUIRE_PASSWORD
+endif
+
+ifeq "$(ONLY_LISTED_SHELLS)" "yes"
+CHSH_FLAGS:=$(CHSH_FLAGS) -DONLY_LISTED_SHELLS
+endif
+
+chsh.o: chsh.c
+       $(CC) -c $(CFLAGS) $(CHSH_FLAGS) chsh.c
+
+chfn.o: chfn.c
+       $(CC) -c $(CFLAGS) $(CHSH_FLAGS) chfn.c
+
 install: all $(WHAT_TO_INSTALL)
 
-install-nonshadow:
-       $(INSTALLDIR) $(SBINDIR) $(BINDIR) $(USRBINDIR)
-       $(INSTALLBIN) $(BIN.NONSHADOW) $(BINDIR)
-       $(INSTALLBIN) $(USRBIN.NONSHADOW) $(USRBINDIR)
-       $(INSTALLBIN) $(USRSBIN.NONSHADOW) $(USRSBINDIR)
+install-putils: $(BIN.PUTILS) $(USRBIN.PUTILS) $(USRSBIN.PUTILS)
+       $(INSTALLDIR) $(BINDIR) $(USRBINDIR) $(USRSBINDIR)
+       $(INSTALLSUID) $(BIN.PUTILS) $(BINDIR)
+       $(INSTALLSUID) $(USRBIN.PUTILS) $(USRBINDIR)
+       $(INSTALLBIN) $(USRSBIN.PUTILS) $(USRSBINDIR)
        $(INSTALLDIR) $(MAN1DIR) $(MAN8DIR)
-       $(INSTALLMAN) $(MAN1.NONSHADOW) $(MAN1DIR)
-       $(INSTALLMAN) $(MAN8.NONSHADOW) $(MAN8DIR)
-       chown root $(USRBINDIR)/chsh
-       chmod u+s $(USRBINDIR)/chsh
-       chown root $(USRBINDIR)/chfn
-       chmod u+s $(USRBINDIR)/chfn
-       chown root $(USRBINDIR)/newgrp
-       chmod u+s $(USRBINDIR)/newgrp
-       chown root $(PASSWDDIR)/passwd
-       chmod u+s $(PASSWDDIR)/passwd
-       chown root $(BINDIR)/login
-       chmod u+s $(BINDIR)/login
-
-install-nonsysvinit:
-       $(INSTALLDIR) $(SBINDIR) $(BINDIR) $(USRBINDIR)
-       $(INSTALLBIN) $(SBIN) $(SBINDIR)
+       $(INSTALLMAN) $(MAN1.PUTILS) $(MAN1DIR)
+       $(INSTALLMAN) $(MAN8.PUTILS) $(MAN8DIR)
+
+install-passwd: $(USRBIN.PASSWD)
+       $(INSTALLDIR) $(USRBINDIR)
+       $(INSTALLSUID) $(USRBIN.PASSWD) $(USRBINDIR)
+       $(INSTALLDIR) $(MAN1DIR)
+       $(INSTALLMAN) $(MAN1.PASSWD) $(MAN1DIR)
+
+install-init: $(SBIN.INIT)
+       $(INSTALLDIR) $(SBINDIR)
+       $(INSTALLBIN) $(SBIN.INIT) $(SBINDIR)
+       $(INSTALLDIR) $(MAN8DIR)
+       $(INSTALLMAN) $(MAN8.INIT) $(MAN8DIR)
+       # Make *relative* links for these
        (cd $(SHUTDOWNDIR); ln -sf shutdown reboot)
        (cd $(SHUTDOWNDIR); ln -sf shutdown fastboot)
        (cd $(SHUTDOWNDIR); ln -sf shutdown halt)
        (cd $(SHUTDOWNDIR); ln -sf shutdown fasthalt)
-       $(INSTALLBIN) $(USRBIN) $(USRBINDIR)
-       $(INSTALLDIR) $(MAN1DIR) $(MAN8DIR)
-       $(INSTALLMAN) $(MAN1) $(MAN1DIR)
-       $(INSTALLMAN) $(MAN8) $(MAN8DIR)
+
+
+install-getty: $(SBIN.GETTY)
+       $(INSTALLDIR) $(SBINDIR)
+       $(INSTALLBIN) $(SBIN.GETTY) $(SBINDIR)
+       $(INSTALLDIR) $(MAN8DIR)
+       $(INSTALLMAN) $(MAN8.GETTY) $(MAN8DIR)
+
+install-misc: $(USRBIN.MISC)
+       $(INSTALLDIR) $(USRBINDIR)
+       $(INSTALLBIN) $(USRBIN.MISC) $(USRBINDIR)
+       $(INSTALLDIR) $(MAN1DIR)
+       $(INSTALLMAN) $(MAN1.MISC) $(MAN1DIR)
+ifeq "$(USE_TTY_GROUP)" "yes"
+       chgrp tty $(USRBINDIR)/wall
+       chmod g+s $(USRBINDIR)/wall
+endif
 
 .PHONY: clean
 clean:
-       -rm -f *.o *~ core $(SBIN) $(BIN) $(BIN.NONSHADOW) $(USRBIN) \
-               $(USRBIN.NONSHADOW) $(USRSBIN.NONSHADOW)
+       -rm -f *.o *~ core $(BIN.PASSWD) $(SBIN.GETTY) $(SBIN.INIT) \
+               $(USRBIN.MISC) $(USRBIN.PASSWD) $(USRBIN.PUTILS) \
+               $(USRSBIN.PUTILS) $(BIN.PUTILS)
index 789252d107459c3682e37b8d0f0b2d1a2857353a..3e25e84e722a8be72caa2b794b4e55eb445926b6 100644 (file)
@@ -1,4 +1,4 @@
-README file for the admutils V1.14 for Linux.
+README file for the admutils V1.16 for Linux.
 
 See installation instructions at the bottom. Currently the latest versions
 of this software is maintained at ftp://ftp.daimi.aau.dk/pub/linux/poe/
@@ -7,6 +7,54 @@ LICENSE:
 This software is distributed as is without any warranty what so ever.
 With respect to copyrights it is covered by the GNU Public License.
 
+Version 1.17 (7-Oct-95):
+       Added setrlimit() calls to passwd.c and chsh.c to fix security hole
+       caused by resource limitations. Inspired by Zefram 
+       <A.Main@dcs.warwick.ac.uk>. Also beefed up the ptmp locking in
+       chsh.c. 
+       Added swap_off() function to shutdown.c by baekgrd@ibm.net
+       (Anders Baekgaard).
+       Bugfix in shutdown.c that makes sure wtmp gets closed. By
+       Alexandre Julliard <julliard@sunsite.unc.edu>.
+       Fixed bug in passwd.c that made it impossible to change from having
+       no password into having one.
+
+Version 1.16 (18-Sep-95):
+       Added feature to passwd.c by Arpad Magossanyi (mag@tas.vein.hu),
+       so root can give a password for a user on the command line. This
+       might be useful in a shell script autogenerating passwords for
+       new users.
+
+       Added and updated manual pages for all commands by Rick Faith.
+
+Version 1.15d (21-Aug-95):
+       Fixed minor nit with salt generation in passwd.c
+       By Steven Reisman <sar@beehive.mn.org>.
+
+Version 1.15c (5-Jul-95):
+       passwd does not allow reuse of the old password when changing.
+       passwd returns 1 if the password is not changed. This was
+       suggested by Anibal Jodorcovsky <anibal@ee.mcgill.ca> who
+       also fixed my initial bug in this feature.
+
+       passwd uses O_EXCL for opening /etc/ptmp instead of access/fopen.
+       This was suggested by jorge@un1.satlink.com (Jorge).
+
+Version 1.15a (12-Jun-95):
+       Fix in last.c so it does not print wtmp entries marked DEAD_PROCESS.
+       By Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+Version 1.15 (5-Jun-95):
+       Man-page fixes, fixes in pathnames.h to adhere to the FSSTND.
+       Fix by Rickard Faith <faith@cs.unc.edu> to passwd.c, so sanity
+       checks come before the second entry of the new password.
+       This is for Linux 1.2, GCC 2.6.2 or later.
+
+Version 1.14a (12-Mar-95):
+       Fixed passwd and chsh so a username that is a prefix of another
+       doesn't affect the other's password. After suggested patch
+       by Valtteri J. Karu <vatekaru@tuug.utu.fi>, but differently!
+
 Version 1.14 (12-Feb-95):
        Added options -l, -y, -i to last.c. See last.man
 
index f6f8933c4a21b5ee02ea7d493ba1657f92f3316e..5b6fac3f407bcd1cb70a9e67cefe6f7319c0ad5b 100644 (file)
@@ -1,6 +1,6 @@
 README for init/getty/login, by poe@daimi.aau.dk
 
-This package contains init, getty, and login programs for Linux.
+This package contains simpleinit, agetty, and login programs for Linux.
 Additional utilities included are: hostname, who, write, wall, users
 domainname, hostid, cage and mesg.
 
@@ -9,12 +9,81 @@ ported the things to Linux.
 
 About installation: See the bottom of this file. Check the Makefile!
 Be sure you know what you are doing! You may well be able to lock
-yourself out from your machine.
+yourself out from your machine. Especially: The init provided here
+(simpleinit) is NOT a SYSV compatible init and the inittab format
+is different.
 
 If you are uncertain whether you got the latest version, check out
 
        ftp://ftp.daimi.aau.dk:/pub/linux/poe/
 
+Version 1.37 (15-Sep-95):
+       Added -I <initstring> and -w options to agetty.c for those that
+       use agetty with modems.
+
+Version 1.36 (25-Aug-95): 
+       Enhanced /etc/usertty features with group support. Moved this part
+       of login.c to checktty.c. One can now define classes of hosts and
+       ttys and do access checking based on unix-group membership. See
+       login.1. Also time ranges for logins can be specified, for example
+       writing the line
+
+       joe     [mon:tue:wed:thu:fri:8-16]@barracuda [mon:tue:wed:thu:fri:0-7:17-23]@joes.pc.at.home [sat:sun:0-23]@joes.pc.at.home
+
+       says that during working hours, Joe may rlogin from the host
+       barracuda, whereas outside working hours and in weekends Joe may
+       rlogin from his networked PC at home.
+
+       login.c: failures was not properly initialized, it now is. Also
+       made sure ALL failures are really logged to syslog.
+
+Version 1.35 (7-Aug-95):
+       login.c: Much improved features for the usertty file, allows
+       access control based on both hostnames/addresses and line. See the 
+       about.usertty file and the man-page.
+
+       Fixed agetty so it doesn't fiddle with the ut_id field in the
+       utmp record, this should prevent growing utmps on systems with
+       more than 10 login lines. Fix suggested and checked by Alan Wendt 
+       <alan@ezlink.com> in his agetty.1.9.1a.
+
+       Agetty now installs as agetty again, not as getty.
+       Updated man-page for login(1) to document /etc/usertty changes.
+
+       This has been tested on Linux 1.2.5 with GCC 2.5.8 and libc 4.5.26.
+
+Version 1.33a (20-Jun-95):
+       rchatfie@cavern.nmsu.edu ("rc.") suggested that I should remove
+       the #ifndef linux around the special logging of dial-up 
+       logins. This is now done, so each login via a serial port 
+       generates a separate DIALUP syslog entry.
+
+Version 1.33 (5-Jun-95):
+       Patch by Ron Sommeling <sommel@sci.kun.nl> and
+       jlaiho@ichaos.nullnet.fi (Juha Laiho) for agetty.c, used
+       to return a pointer to an automatic variable in get_logname().
+       Many patches from or via Rickard Faith <faith@cs.unc.edu>, fixing
+       man-pages etc, now defaults to using /var/log/wtmp and /var/run/utmp
+       according to the new FSSTND.
+
+       Fix in login.c for CPU eating bug when a remote telnet client dies
+       while logging in.
+
+       This is for Linux 1.2, GCC 2.6.2 or later.
+
+Version 1.32b (12-Mar-95):
+       Login now sets the tty group to "tty" instead of "other". Depending
+       on compile-time define USE_TTY_GROUP the tty mode is set to 0620 or
+       0600 instead of 0622. All as per suggestion by Rik Faith and the
+       linux-security list.
+       Write/wall now strips control chars except BEL (\007). Again after
+       suggestion by Rik Faith.
+
+Version 1.32a
+       Urgent security patch from Alvaro M. Echevarria incorporated into
+       login.c. This is really needed on machines running YP until
+       the libraries are fixed.
+
 Version 1.32
        Login now logs the ip-address of the connecting host to utmp as it
        should.
index 3f3cf6adaacfc4e1206eca9b2650ab8f67d0c805..f6a59909ce90705e51ec54c070276e826f2ad952 100644 (file)
@@ -6,8 +6,8 @@ agetty \- alternative Linux getty
 .SH SYNOPSIS
 .na
 .nf
-agetty [-ihL] [-l login_program] [-m] [-t timeout] port baud_rate,... [term]
-agetty [-ihL] [-l login_program] [-m] [-t timeout] baud_rate,...  port [term]
+agetty [-ihLmw] [-l login_program] [-I init] [-t timeout] port baud_rate,... [term]
+agetty [-ihLmw] [-l login_program] [-I init] [-t timeout] baud_rate,... port [term]
 .SH DESCRIPTION
 .ad
 .fi
@@ -85,6 +85,14 @@ login prompt. Terminals or communications hardware may become confused
 when receiving lots of text at the wrong baud rate; dial-up scripts
 may fail if the login prompt is preceded by too much text.
 .TP
+-I initstring
+Set an initial string to be sent to the tty or modem before sending
+anything else. This may be used to initialize a modem.  Non printable
+characters may be sent by writing their octal code preceded by a
+backslash (\\). For example to send a linefeed character (ASCII 10,
+octal 012) write \\012.
+.PP
+.TP
 -l login_program
 Invoke the specified \fIlogin_program\fP instead of /bin/login.
 This allows the use of a non-standard login program (for example,
@@ -112,7 +120,11 @@ lines.
 Force the line to be local line with no need for carrier detect. This can
 be useful when you have locally attached terminal where the serial line
 does not set the carrier detect signal.
-
+.TP
+-w
+Wait for the user or the modem to send a carriage-return or a linefeed 
+character before sending the /etc/issue file and the login prompt.
+.PP
 .SH EXAMPLES
 .na
 .nf
@@ -190,7 +202,7 @@ This is thingol.orcan.dk (Linux i386 1.1.9) 18:29:30
 .SH FILES
 .na
 .nf
-/etc/utmp, the system status file (System V only).
+/var/run/utmp, the system status file.
 /etc/issue, printed before the login prompt (System V only).
 /dev/console, problem reports (if syslog(3) is not used).
 /etc/inittab (Linux simpleinit(8) configuration file).
@@ -214,7 +226,7 @@ the modem emits its status message \fIafter\fP raising the DCD line.
 Depending on how the program was configured, all diagnostics are
 written to the console device or reported via the syslog(3) facility.
 Error messages are produced if the \fIport\fP argument does not
-specify a terminal device; if there is no /etc/utmp entry for the
+specify a terminal device; if there is no utmp entry for the
 current process (System V only); and so on.
 .SH AUTHOR(S)
 .na
index a8cd45db854210553d6fb9376a6e1350db000af5..c7595bf372eb47ecbb2b6c51890c5216f57180ca 100644 (file)
@@ -132,12 +132,15 @@ struct options {
     int     numspeed;                  /* number of baud rates to try */
     int     speeds[MAX_SPEED];         /* baud rates to be tried */
     char   *tty;                       /* name of tty */
+    char   *initstring;                        /* modem init string */
 };
 
 #define        F_PARSE         (1<<0)          /* process modem status messages */
 #define        F_ISSUE         (1<<1)          /* display /etc/issue */
 #define        F_RTSCTS        (1<<2)          /* enable RTS/CTS flow control */
 #define F_LOCAL                (1<<3)          /* force local */
+#define F_INITSTRING    (1<<4)         /* initstring is set */
+#define F_WAITCRLF     (1<<5)          /* wait for CR or LF */
 
 /* Storage for things detected while the login name was read. */
 
@@ -194,7 +197,6 @@ main(argc, argv)
      char  **argv;
 {
     char   *logname;                   /* login name, given to /bin/login */
-    char   *get_logname();
     struct chardata chardata;          /* set by get_logname() */
     struct termio termio;              /* terminal mode bits */
     static struct options options = {
@@ -251,7 +253,13 @@ main(argc, argv)
     /* Initialize the termio settings (raw mode, eight-bit, blocking i/o). */
 
     termio_init(&termio, options.speeds[FIRST_SPEED], options.flags & F_LOCAL);
-       
+
+    /* write the modem init string and flush the buffers */
+    if (options.flags & F_INITSTRING) {
+       write(1, options.initstring, strlen(options.initstring));
+       ioctl(1, TCFLSH, 2);
+    }
+
     /* Optionally detect the baud rate from the modem status message. */
 
     if (options.flags & F_PARSE)
@@ -262,6 +270,16 @@ main(argc, argv)
     if (options.timeout)
        (void) alarm((unsigned) options.timeout);
  
+    /* optionally wait for CR or LF before writing /etc/issue */
+    if (options.flags & F_WAITCRLF) {
+       char ch;
+
+       while(read(0, &ch, 1) == 1) {
+           ch &= 0x7f;   /* strip "parity bit" */
+           if (ch == '\n' || ch == '\r') break;
+       }
+    }
+
     /* Read the login name. */
 
     while ((logname = get_logname(&options, &chardata, &termio)) == 0)
@@ -299,8 +317,48 @@ parse_args(argc, argv, op)
     extern int optind;                 /* getopt */
     int     c;
 
-    while (isascii(c = getopt(argc, argv, "Lhil:mt:"))) {
+    while (isascii(c = getopt(argc, argv, "I:Lhil:mt:w"))) {
        switch (c) {
+       case 'I':
+           if (!(op->initstring = malloc(strlen(optarg)))) {
+               error("can't malloc initstring");
+               break;
+           }
+           {
+               char ch, *p, *q;
+               int i;
+
+               /* copy optarg into op->initstring decoding \ddd
+                  octal codes into chars */
+               q = op->initstring;
+               p = optarg;
+               while (*p) {
+                   if (*p == '\\') {           /* know \\ means \ */
+                       p++;
+                       if (*p == '\\') {
+                           ch = '\\';
+                           p++;
+                       } else {                /* handle \000 - \177 */
+                           ch = 0;
+                           for (i = 1; i <= 3; i++) {
+                               if (*p >= '0' && *p <= '7') {
+                                   ch <<= 3;
+                                   ch += *p - '0';
+                                   p++;
+                               } else 
+                                 break;
+                           }
+                       }
+                       *q++ = ch;
+                   } else {
+                       *q++ = *p++;
+                   }
+               }
+               *q = '\0';
+           }
+           op->flags |= F_INITSTRING;
+           break;
+
        case 'L':                               /* force local */
            op->flags |= F_LOCAL;
            break;
@@ -320,6 +378,9 @@ parse_args(argc, argv, op)
            if ((op->timeout = atoi(optarg)) <= 0)
                error("bad timeout value: %s", optarg);
            break;
+       case 'w':
+           op->flags |= F_WAITCRLF;
+           break;
        default:
            usage();
        }
@@ -379,10 +440,11 @@ update_utmp(line)
     long    time();
     long    lseek();
     char   *strncpy();
+    struct  utmp *utp;
 
     /*
      * The utmp file holds miscellaneous information about things started by
-     * /etc/init and other system-related events. Our purpose is to update
+     * /sbin/init and other system-related events. Our purpose is to update
      * the utmp entry for the current process, in particular the process type
      * and the tty line we are listening to. Return successfully only if the
      * utmp file can be opened for update, and if we are able to find our
@@ -390,24 +452,36 @@ update_utmp(line)
      */
 
 #ifdef linux
-       utmpname(_PATH_UTMP);
-        memset(&ut, 0, sizeof(ut));
-       (void) strncpy(ut.ut_user, "LOGIN", sizeof(ut.ut_user));
-       (void) strncpy(ut.ut_line, line, sizeof(ut.ut_line));
-       (void) strncpy(ut.ut_id, line + 3, sizeof(ut.ut_id));
-       (void) time(&ut.ut_time);
-       ut.ut_type = LOGIN_PROCESS;
-       ut.ut_pid = mypid;
-
-       pututline(&ut);
-       endutent();
-
-        if((ut_fd = open(_PATH_WTMP, O_APPEND|O_WRONLY)) >= 0) {
-           flock(ut_fd, LOCK_EX);
-           write(ut_fd, &ut, sizeof(ut));
-           flock(ut_fd, LOCK_UN);
-           close(ut_fd);
-       }
+    utmpname(_PATH_UTMP);
+    setutent();
+    while ((utp = getutent()) 
+          && !(utp->ut_type == INIT_PROCESS
+               && utp->ut_pid == mypid)) /* nothing */;
+
+    if (utp) {
+       memcpy(&ut, utp, sizeof(ut));
+    } else {
+       /* some inits don't initialize utmp... */
+       memset(&ut, 0, sizeof(ut));
+       strncpy(ut.ut_id, line + 3, sizeof(ut.ut_id));
+    }
+    endutent();
+       
+    strncpy(ut.ut_user, "LOGIN", sizeof(ut.ut_user));
+    strncpy(ut.ut_line, line, sizeof(ut.ut_line));
+    time(&ut.ut_time);
+    ut.ut_type = LOGIN_PROCESS;
+    ut.ut_pid = mypid;
+
+    pututline(&ut);
+    endutent();
+
+    if((ut_fd = open(_PATH_WTMP, O_APPEND|O_WRONLY)) >= 0) {
+       flock(ut_fd, LOCK_EX);
+       write(ut_fd, &ut, sizeof(ut));
+       flock(ut_fd, LOCK_UN);
+       close(ut_fd);
+    }
 #else
     if ((ut_fd = open(UTMP_FILE, 2)) < 0) {
        error("%s: open for update: %m", UTMP_FILE);
@@ -592,7 +666,7 @@ auto_baud(tp)
        buf[nread] = '\0';
        for (bp = buf; bp < buf + nread; bp++) {
            if (isascii(*bp) && isdigit(*bp)) {
-               if (speed = bcode(bp)) {
+               if ((speed = bcode(bp))) {
                    tp->c_cflag &= ~CBAUD;
                    tp->c_cflag |= speed;
                }
@@ -709,7 +783,7 @@ do_prompt(op, tp)
                      int users = 0;
                      struct utmp *ut;
                      setutent();
-                     while (ut = getutent())
+                     while ((ut = getutent()))
                        if (ut->ut_type == USER_PROCESS)
                          users++;
                      endutent();
@@ -764,7 +838,7 @@ char   *get_logname(op, cp, tp)
      struct chardata *cp;
      struct termio *tp;
 {
-    char    logname[BUFSIZ];
+    static char logname[BUFSIZ];
     char   *bp;
     char    c;                         /* input character, full eight bits */
     char    ascval;                    /* low 7 bits of input character */
@@ -860,7 +934,7 @@ char   *get_logname(op, cp, tp)
     }
     /* Handle names with upper case and no lower case. */
 
-    if (cp->capslock = caps_lock(logname)) {
+    if ((cp->capslock = caps_lock(logname))) {
        for (bp = logname; *bp; bp++)
            if (isupper(*bp))
                *bp = tolower(*bp);             /* map name to lower case */
diff --git a/login-utils/checktty.c b/login-utils/checktty.c
new file mode 100644 (file)
index 0000000..8daa172
--- /dev/null
@@ -0,0 +1,423 @@
+/* checktty.c - linked into login, checks user against /etc/usertty
+   Created 25-Aug-95 by Peter Orbaek <poe@daimi.aau.dk>
+*/
+
+#include <pwd.h>
+#include <grp.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <time.h>
+#include <sys/stat.h>
+#include <malloc.h>
+#include <netdb.h>
+#include <sys/syslog.h>
+
+#ifdef linux
+#  include <sys/sysmacros.h>
+#  include <linux/major.h>
+#endif
+
+#include "pathnames.h"
+
+/* functions in login.c */
+void badlogin(char *s);
+void sleepexit(int);
+extern struct hostent hostaddress;
+extern char *hostname;
+
+#ifdef TESTING
+struct hostent hostaddress;
+char *hostname;
+
+void 
+badlogin(char *s)
+{
+    printf("badlogin: %s\n", s);
+}
+
+void
+sleepexit(int x)
+{
+    printf("sleepexit %d\n", x);
+    exit(1);
+}
+#endif
+
+#define NAMELEN 128
+
+/* linked list of names */
+struct grplist {
+    struct grplist *next;
+    char name[NAMELEN];
+};
+
+struct grplist *mygroups = NULL;
+
+enum State { StateUsers, StateGroups, StateClasses };
+
+#define CLASSNAMELEN 32
+
+struct ttyclass {
+    struct grplist *first;
+    struct ttyclass *next;
+    char classname[CLASSNAMELEN];
+};
+
+struct ttyclass *ttyclasses = NULL;
+
+static void
+add_group(char *group)
+{
+    struct grplist *ge;
+
+    ge = (struct grplist *)malloc(sizeof(struct grplist));
+
+    /* we can't just bail out at this stage! */
+    if (!ge) {
+       printf("login: memory low, login may fail\n");
+       syslog(LOG_WARNING, "can't malloc grplist");
+       return;
+    }
+
+    ge->next = mygroups;
+    strncpy(ge->name, group, NAMELEN);
+    mygroups = ge;
+}
+
+static int
+am_in_group(char *group)
+{
+    struct grplist *ge;
+
+    for (ge = mygroups; ge; ge = ge->next) {
+       if (strcmp(ge->name, group) == 0) return 1;
+    }
+    return 0;
+}
+
+static void
+find_groups(gid_t defgrp, char *user)
+{
+    struct group *gp;
+    char **p;
+
+    setgrent();
+    while ((gp = getgrent())) {
+       if (gp->gr_gid == defgrp) {
+           add_group(gp->gr_name);
+       } else {
+           for(p = gp->gr_mem; *p; p++) {
+               if (strcmp(user, *p) == 0) {
+                   add_group(gp->gr_name);
+                   break;
+               }
+           }
+       }
+           
+    }
+    endgrent();
+}
+
+static struct ttyclass *
+new_class(char *class)
+{
+    struct ttyclass *tc;
+
+    tc = (struct ttyclass *)malloc(sizeof(struct ttyclass));
+    if (tc == NULL) {
+       printf("login: memory low, login may fail\n");
+       syslog(LOG_WARNING, "can't malloc for ttyclass");
+       return NULL;
+    }
+
+    tc->next = ttyclasses;
+    tc->first = NULL;
+    strncpy(tc->classname, class, CLASSNAMELEN);
+    ttyclasses = tc;
+    return tc;
+}
+
+static void
+add_to_class(struct ttyclass *tc, char *tty)
+{
+    struct grplist *ge;
+
+    if (tc == NULL) return;
+
+    ge = (struct grplist *)malloc(sizeof(struct grplist));
+    if (ge == NULL) {
+       printf("login: memory low, login may fail\n");
+       syslog(LOG_WARNING, "can't malloc for grplist");
+       return;
+    }
+
+    ge->next = tc->first;
+    strncpy(ge->name, tty, NAMELEN);
+    tc->first = ge;
+}
+
+
+/* return true if tty is a pty. Very linux dependent */
+static int
+isapty(tty)
+     char *tty;
+{
+    char devname[100];
+    struct stat stb;
+
+#ifdef linux
+    strcpy(devname, "/dev/");
+    strncat(devname, tty, 80);
+    if((stat(devname, &stb) >= 0)
+       && major(stb.st_rdev) == TTY_MAJOR
+       && minor(stb.st_rdev) >= 192) {
+       return 1;
+    }
+#endif
+    return 0;
+}
+
+/* match the hostname hn against the pattern pat */
+static int
+hnmatch(hn, pat)
+     char *hn;
+     char *pat;
+{
+    int x1, x2, x3, x4, y1, y2, y3, y4;
+    unsigned long p, mask, a;
+    unsigned char *ha;
+    int n, m;
+
+    if ((hn == NULL) && (strcmp(pat, "localhost") == 0)) return 1;
+    if ((hn == NULL) || hn[0] == 0) return 0;
+
+    if (pat[0] >= '0' && pat[0] <= '9') {
+       /* pattern is an IP QUAD address and a mask x.x.x.x/y.y.y.y */
+       sscanf(pat, "%d.%d.%d.%d/%d.%d.%d.%d", &x1, &x2, &x3, &x4,
+              &y1, &y2, &y3, &y4);
+       p = (((unsigned long)x1<<24)+((unsigned long)x2<<16)
+            +((unsigned long)x3<<8)+((unsigned long)x4));
+       mask = (((unsigned long)y1<<24)+((unsigned long)y2<<16)
+               +((unsigned long)y3<<8)+((unsigned long)y4));
+
+       if (!hostaddress.h_addr_list || !hostaddress.h_addr_list[0])
+         return 0;
+
+       ha = (unsigned char *)hostaddress.h_addr_list[0];
+       a = (((unsigned long)ha[0]<<24)+((unsigned long)ha[1]<<16)
+            +((unsigned long)ha[2]<<8)+((unsigned long)ha[3]));
+       return ((p & mask) == (a & mask));
+    } else {
+       /* pattern is a suffix of a FQDN */
+       n = strlen(pat);
+       m = strlen(hn);
+       if (n > m) return 0;
+       return (strcasecmp(pat, hn + m - n) == 0);
+    }
+}
+
+static char *wdays[] = { "sun", "mon", "tue", "wed", "thu", "fri", "sat" };
+
+/* example timespecs:
+
+   mon:tue:wed:8-17
+
+   meaning monday, tuesday or wednesday between 8:00 and 17:59
+
+   4:5:13:fri
+
+   meaning fridays from 4:00 to 5:59 and from 13:00 to 13:59
+*/
+static int
+timeok(struct tm *t, char *spec)
+{
+    char *p, *q;
+    int dayok = 0;
+    int hourok = 0;
+    int h, h2;
+    char *sp;
+
+    sp = spec;
+    while ((p = strsep(&sp, ":"))) {
+       if (*p >= '0' && *p <= '9') {
+           h = atoi(p);
+           if (h == t->tm_hour) hourok = 1;
+           if ((q = strchr(p, '-')) && (q[1] >= '0' && q[1] <= '9')) {
+               h2 = atoi(q+1);
+               if (h <= t->tm_hour && t->tm_hour <= h2) hourok = 1;
+           }
+       } else if (strcasecmp(wdays[t->tm_wday], p) == 0) {
+           dayok = 1;
+       }
+    }
+
+    return (dayok && hourok);
+}
+
+/* return true if tty equals class or is in the class defined by class.
+   Also return true if hostname matches the hostname pattern, class
+   or a pattern in the class named by class. */
+static int
+in_class(char *tty, char *class)
+{
+    struct ttyclass *tc;
+    struct grplist *ge;
+    time_t t;
+    char *p;
+    char timespec[256];
+    struct tm *tm;
+    char *n;
+
+    time(&t);
+    tm = localtime(&t);
+
+    if (class[0] == '[') {
+       if ((p = strchr(class, ']'))) {
+           *p = 0;
+           strcpy(timespec, class+1);
+           *p = ']';
+           if(!timeok(tm, timespec)) return 0;
+           class = p+1;
+       }
+       /* really ought to warn about syntax error */
+    }
+
+    if (strcmp(tty, class) == 0) return 1;
+
+    if ((class[0] == '@') && isapty(tty)
+       && hnmatch(hostname, class+1)) return 1;
+
+    for (tc = ttyclasses; tc; tc = tc->next) {
+       if (strcmp(tc->classname, class) == 0) {
+           for (ge = tc->first; ge; ge = ge->next) {
+
+               n = ge->name;
+               if (n[0] == '[') {
+                   if ((p = strchr(n, ']'))) {
+                       *p = 0;
+                       strcpy(timespec, n+1);
+                       *p = ']';
+                       if(!timeok(tm, timespec)) continue;
+                       n = p+1;
+                   }
+                   /* really ought to warn about syntax error */
+               }
+
+               if (strcmp(n, tty) == 0) return 1;
+
+               if ((n[0] == '@') && isapty(tty)
+                   && hnmatch(hostname, n+1)) return 1;
+           }
+           return 0;
+       }
+    }
+    return 0;
+}
+
+void
+checktty(user, tty, pwd)
+     char *user;
+     char *tty;
+     struct passwd *pwd;
+{
+    FILE *f;
+    char buf[256], defaultbuf[256];
+    char *ptr;
+    enum State state = StateUsers;
+    int found_match = 0;
+
+    /* no /etc/usertty, default to allow access */
+#ifdef TESTING
+    if (!(f = fopen("usertty", "r"))) return;
+#else
+    if (!(f = fopen(_PATH_USERTTY, "r"))) return;
+#endif
+
+    if (pwd == NULL) return;  /* misspelled username handled elsewhere */
+
+    find_groups(pwd->pw_gid, user);
+
+    defaultbuf[0] = 0;
+    while(fgets(buf, 255, f)) {
+
+       /* strip comments */
+       for(ptr = buf; ptr < buf + 256; ptr++) 
+         if(*ptr == '#') *ptr = 0;
+
+       if (buf[0] == '*') {
+           strncpy(defaultbuf, buf, 256);
+           continue;
+       }
+
+       if (strncmp("GROUPS", buf, 6) == 0) {
+           state = StateGroups;
+           continue;
+       } else if (strncmp("USERS", buf, 5) == 0) {
+           state = StateUsers;
+           continue;
+       } else if (strncmp("CLASSES", buf, 7) == 0) {
+           state = StateClasses;
+           continue;
+       }
+
+       strtok(buf, " \t");
+       if((state == StateUsers && (strncmp(user, buf, 8) == 0))
+          || (state == StateGroups && am_in_group(buf))) {
+           found_match = 1;  /* we found a line matching the user */
+           while((ptr = strtok(NULL, "\t\n "))) {
+               if (in_class(tty, ptr)) {
+                   fclose(f);
+                   return;
+               }
+           }
+       } else if (state == StateClasses) {
+           /* define a new tty/host class */
+           struct ttyclass *tc = new_class(buf);
+
+           while ((ptr = strtok(NULL, "\t\n "))) {
+               add_to_class(tc, ptr);
+           }
+       }
+    }
+    fclose(f);
+
+    /* user is not explicitly mentioned in /etc/usertty, if there was
+       a default rule, use that */
+    if (defaultbuf[0]) {
+       strtok(defaultbuf, " \t");
+       while((ptr = strtok(NULL, "\t\n "))) {
+           if (in_class(tty, ptr)) return;
+       }
+
+       /* there was a default rule, but user didn't match, reject! */
+       printf("Login on %s from %s denied by default.\n", tty, hostname);
+       badlogin(user);
+       sleepexit(1);
+    }
+
+    if (found_match) {
+       /* if we get here, /etc/usertty exists, there's a line
+          matching our username, but it doesn't contain the
+          name of the tty where the user is trying to log in.
+          So deny access! */
+
+       printf("Login on %s from %s denied.\n", tty, hostname);
+       badlogin(user);
+       sleepexit(1);
+    }
+
+    /* users not matched in /etc/usertty are by default allowed access
+       on all tty's */
+}
+
+#ifdef TESTING
+main(int argc, char *argv[]) 
+{
+    struct passwd *pw;
+
+    pw = getpwnam(argv[1]);
+    checktty(argv[1], argv[2], pw);
+}
+#endif
index 9be9fff0a9c1496c136d9932c4762ca074873a27..5e8369ba678d83a0649250d591612794d838a050 100644 (file)
@@ -6,9 +6,9 @@
 .\"  modify it under the terms of the gnu general public license.
 .\"  there is no warranty.
 .\"
-.\"  faith
-.\"  1.1.1.1
-.\"  1995/02/22 19:09:24
+.\"  $Author: faith $
+.\"  $Revision: 1.1 $
+.\"  $Date: 1995/03/12 01:29:16 $
 .\"
 .TH CHFN 1 "October 13 1994" "chfn" "Linux Reference Manual"
 .SH NAME
index 2effa85d222713f06f34dc081a40a08e8288762d..207bcb254716371511fa04ff299b9c1952edcedb 100644 (file)
@@ -6,13 +6,16 @@
  *   modify it under the terms of the gnu general public license.
  *   there is no warranty.
  *
- *   faith
- *   1.1.1.1
- *   1995/02/22 19:09:24
+ *   $Author: faith $
+ *   $Revision: 1.8 $
+ *   $Date: 1995/10/12 14:46:35 $
+ *
+ * Updated Thu Oct 12 09:19:26 1995 by faith@cs.unc.edu with security
+ * patches from Zefram <A.Main@dcs.warwick.ac.uk>
  *
  */
 
-#define _POSIX_SOURCE 1
+static char rcsId[] = "$Version: $Id: chfn.c,v 1.8 1995/10/12 14:46:35 faith Exp $ $";
 
 #include <sys/types.h>
 #include <stdio.h>
@@ -35,7 +38,7 @@ typedef unsigned char boolean;
 #define false 0
 #define true 1
 
-static char *version_string = "chfn 0.9 beta";
+static char *version_string = "chfn 0.9a beta";
 static char *whoami;
 
 static char buf[1024];
@@ -59,15 +62,17 @@ static int check_gecos_string P((char *msg, char *gecos));
 static boolean set_changed_data P((struct finfo *oldfp, struct finfo *newfp));
 static int save_new_data P((struct finfo *pinfo));
 static void *xmalloc P((int bytes));
+#if 0
 extern int strcasecmp P((char *, char *));
 extern int setpwnam P((struct passwd *pwd));
+#endif
 #define memzero(ptr, size) memset((char *) ptr, 0, size)
 
 int main (argc, argv)
     int argc;
     char *argv[];
 {
-    char *cp;
+    char *cp, *pwdstr;
     uid_t uid;
     struct finfo oldf, newf;
     boolean interactive;
@@ -80,8 +85,6 @@ int main (argc, argv)
     for (cp = whoami; *cp; cp++)
        if (*cp == '/') whoami = cp + 1;
 
-    umask (022);
-
     /*
      * "oldf" contains the users original finger information.
      * "newf" contains the changed finger information, and contains NULL
@@ -117,7 +120,22 @@ int main (argc, argv)
        perror (whoami);
        return (-1);
     }
-    
+
+    printf ("Changing finger information for %s.\n", oldf.username);
+
+#if REQUIRE_PASSWORD
+    /* require password, unless root */
+    if(uid != 0 && oldf.pw->pw_passwd && oldf.pw->pw_passwd[0]) {
+       pwdstr = getpass("Password: ");
+       if(strncmp(oldf.pw->pw_passwd,
+                  crypt(pwdstr, oldf.pw->pw_passwd), 13)) {
+           puts("Incorrect password.");
+           exit(1);
+       }
+    }
+#endif
+
+
     if (interactive) ask_info (&oldf, &newf);
 
     if (! set_changed_data (&oldf, &newf)) {
@@ -268,7 +286,6 @@ static void ask_info (oldfp, newfp)
     struct finfo *oldfp;
     struct finfo *newfp;
 {
-    printf ("Changing finger information for %s.\n", oldfp->username);
     newfp->full_name = prompt ("Name", oldfp->full_name);
     newfp->office = prompt ("Office", oldfp->office);
     newfp->office_phone        = prompt ("Office Phone", oldfp->office_phone);
@@ -391,6 +408,7 @@ static int save_new_data (pinfo)
     pinfo->pw->pw_gecos = gecos;
     if (setpwnam (pinfo->pw) < 0) {
        perror ("setpwnam");
+       printf( "Finger information *NOT* changed.  Try again later.\n" );
        return (-1);
     }
     printf ("Finger information changed.\n");
index ec278fb4f23aa078def98288fdcf29e3422e8d20..57ded290246156dd53922d07d068197c84ae7fee 100644 (file)
@@ -6,9 +6,9 @@
 .\"  modify it under the terms of the gnu general public license.
 .\"  there is no warranty.
 .\"
-.\"  faith
-.\"  1.1.1.1
-.\"  1995/02/22 19:09:23
+.\"  $Author: faith $
+.\"  $Revision: 1.1 $
+.\"  $Date: 1995/03/12 01:28:58 $
 .\"
 .TH CHSH 1 "October 13 1994" "chsh" "Linux Reference Manual"
 .SH NAME
index 9a9a52e854df938a9257e1dfef78a49845f20e27..9ffd81b2fbaa6eb35db924182e99f518a377527a 100644 (file)
@@ -6,13 +6,20 @@
  *   modify it under the terms of the gnu general public license.
  *   there is no warranty.
  *
- *   faith
- *   1.1.1.1
- *   1995/02/22 19:09:23
+ *   $Author: faith $
+ *   $Revision: 1.8 $
+ *   $Date: 1995/10/12 14:46:35 $
+ *
+ * Updated Thu Oct 12 09:33:15 1995 by faith@cs.unc.edu with security
+ * patches from Zefram <A.Main@dcs.warwick.ac.uk>
  *
  */
 
+static char rcsId[] = "$Version: $Id: chsh.c,v 1.8 1995/10/12 14:46:35 faith Exp $ $";
+
+#if 0
 #define _POSIX_SOURCE 1
+#endif
 
 #include <sys/types.h>
 #include <stdio.h>
@@ -35,7 +42,7 @@ typedef unsigned char boolean;
 #define false 0
 #define true 1
 
-static char *version_string = "chsh 0.9 beta";
+static char *version_string = "chsh 0.9a beta";
 static char *whoami;
 
 static char buf[FILENAME_MAX];
@@ -58,7 +65,7 @@ int main (argc, argv)
     int argc;
     char *argv[];
 {
-    char *cp, *shell;
+    char *cp, *shell, *oldshell, *pwdstr;
     uid_t uid;
     struct sinfo info;
     struct passwd *pw;
@@ -70,8 +77,6 @@ int main (argc, argv)
     for (cp = whoami; *cp; cp++)
        if (*cp == '/') whoami = cp + 1;
 
-    umask (022);
-
     uid = getuid ();
     memzero (&info, sizeof (info));
 
@@ -91,28 +96,55 @@ int main (argc, argv)
            return (-1); }
     }
 
+    oldshell = pw->pw_shell;
+    if (!oldshell[0]) oldshell = "/bin/sh";
+
     /* reality check */
+#if 0
+                               /* Require current shell to be in list.
+                                   This is not a reasonable expectation on
+                                   most Linux systems, and the error is
+                                   confusing.  */
+    if (uid != 0 && (uid != pw->pw_uid || !get_shell_list(oldshell))) {
+#else
     if (uid != 0 && uid != pw->pw_uid) {
+#endif
        errno = EACCES;
        perror (whoami);
        return (-1);
     }
     
     shell = info.shell;
+
+    printf( "Changing shell for %s.\n", pw->pw_name );
+
+#ifdef REQUIRE_PASSWORD
+    /* require password, unless root */
+    if(uid != 0 && pw->pw_passwd && pw->pw_passwd[0]) {
+       pwdstr = getpass("Password: ");
+       if(strncmp(pw->pw_passwd, crypt(pwdstr, pw->pw_passwd), 13)) {
+           puts("Incorrect password.");
+           exit(1);
+       }
+    }
+#endif
+
     if (! shell) {
-       printf ("Changing shell for %s.\n", pw->pw_name);
-       shell = prompt ("New shell", pw->pw_shell);
+       shell = prompt ("New shell", oldshell);
        if (! shell) return 0;
     }
+    
     if (check_shell (shell) < 0) return (-1);
 
     if (! strcmp (pw->pw_shell, shell)) {
        printf ("Shell not changed.\n");
        return 0;
     }
+    if (!strcmp(shell, "/bin/sh")) shell = "";
     pw->pw_shell = shell;
     if (setpwnam (pw) < 0) {
        perror ("setpwnam");
+       printf( "Shell *NOT* changed.  Try again later.\n" );
        return (-1);
     }
     printf ("Shell changed.\n");
@@ -252,8 +284,23 @@ static int check_shell (shell)
            return (-1);
        }
     }
-    if (! get_shell_list (shell))
-       printf ("warning: \"%s\" is not listed as a valid shell.\n", shell);
+#if ONLY_LISTED_SHELLS
+    if (! get_shell_list (shell)) {
+       if (!getuid())
+         printf ("Warning: \"%s\" is not listed as a valid shell.\n", shell);
+       else {
+         printf ("%s: \"%s\" is not listed as a valid shell.\n",
+                 whoami, shell);
+         printf( "%s: use -l option to see list\n" );
+         exit(1);
+       }
+    }
+#else
+    if (! get_shell_list (shell)) {
+       printf ("Warning: \"%s\" is not listed as a valid shell.\n", shell);
+       printf( "Use %s -l to see list.\n", whoami );
+    }
+#endif
     return 0;
 }
 
index 44e6b827048f792e4a4dea1f2b46b2bfe61e4f3e..f2c1d1d2b3ffd1cb138d7e31cc8dc736af2cef13 100644 (file)
@@ -44,7 +44,7 @@ continues.
 limit the number of entries displayed to that specified by \fInumber\fP.
 .IP "\fB\-f\fP \fIfilename\fP"
 Use \fIfilename\fP as the name of the accounting file instead of
-.BR /etc/wtmp .
+.BR /var/log/wtmp .
 .IP "\fB\-h\fP \fIhostname\fP"
 List only logins from \fIhostname\fP.
 .IP "\fB\-i\fP \fIIP address\fP""
@@ -56,4 +56,4 @@ List only logins on \fItty\fP.
 .IP "\fB\-y\fP"
 Also report year of dates.
 .SH FILES
-/usr/adm/wtmp \(em login data base
+/var/log/wtmp \(em login data base
diff --git a/login-utils/last.1.orig b/login-utils/last.1.orig
new file mode 100644 (file)
index 0000000..4d0deb8
--- /dev/null
@@ -0,0 +1,49 @@
+.TH LAST 1 "20 March 1992"
+.SH NAME
+last \(em indicate last logins by user or terminal
+.SH SYNOPSIS
+.ad l
+.B last
+.RB [ \-\fP\fInumber\fP ]
+.RB [ \-f
+.IR filename ]
+.RB [ \-t
+.IR tty ]
+.RB [ \-h
+.IR hostname ]
+.RI [ name ...]
+.ad b
+.SH DESCRIPTION
+\fBLast\fP looks back in the \fBwtmp\fP file which records all logins
+and logouts for information about a user, a teletype or any group of
+users and teletypes.  Arguments specify names of users or teletypes of
+interest.  If multiple arguments are given, the information which
+applies to any of the arguments is printed.  For example ``\fBlast root
+console\fP'' would list all of root's sessions as well as all sessions
+on the console terminal.  \fBLast\fP displays the sessions of the
+specified users and teletypes, most recent first, indicating the times
+at which the session began, the duration of the session, and the
+teletype which the session took place on.  If the session is still
+continuing or was cut short by a reboot, \fBlast\fP so indicates.
+.LP
+The pseudo-user \fBreboot\fP logs in at reboots of the system.
+.LP
+\fBLast\fP with no arguments displays a record of all logins and
+logouts, in reverse order.
+.LP
+If \fBlast\fP is interrupted, it indicates how far the search has
+progressed in \fBwtmp\fP.  If interrupted with a quit signal \fBlast\fP
+indicates how far the search has progressed so far, and the search
+continues.
+.SH OPTIONS
+.IP \fB\-\fP\fInumber\fP
+limit the number of entries displayed to that specified by \fInumber\fP.
+.IP "\fB\-\fP \fIfilename\fP"
+Use \fIfilename\fP as the name of the accounting file instead of
+.BR /etc/wtmp .
+.IP "\fB\-t\fP \fItty\fP"
+List only logins on \fItty\fP.
+.IP "\fB\-h\fP \fIhostname\fP"
+List only logins from \fhostname\fP.
+.SH FILES
+/etc/wtmp \(em login data base
index c00808c2ed302536c4e475dcd1817bf35cace4b3..bc8294978eff32f770dbc12b0d1bf0a7572def94 100644 (file)
@@ -242,6 +242,7 @@ wtmp()
                                        break;
                        }
                        if (bp->ut_name[0] && bp->ut_type != LOGIN_PROCESS
+                           && bp->ut_type != DEAD_PROCESS
                            && want(bp, YES)) {
 
                               print_partial_line(bp);
diff --git a/login-utils/last.c.orig b/login-utils/last.c.orig
new file mode 100644 (file)
index 0000000..788aa66
--- /dev/null
@@ -0,0 +1,381 @@
+/*
+ * Copyright (c) 1987 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the above copyright notice and this paragraph are
+ * duplicated in all such forms and that any documentation,
+ * advertising materials, and other materials related to such
+ * distribution and use acknowledge that the software was developed
+ * by the University of California, 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'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef lint
+char copyright[] =
+"@(#) Copyright (c) 1987 Regents of the University of California.\n\
+ All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)last.c     5.11 (Berkeley) 6/29/88";
+#endif /* not lint */
+
+/*
+ * last
+ */
+#include <sys/param.h>
+#include <sys/stat.h>
+#include <sys/file.h>
+#include <signal.h>
+#include <string.h>
+#include <time.h>
+#include <utmp.h>
+#include <stdio.h>
+#include <getopt.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include "pathnames.h"
+
+#define        SECDAY  (24*60*60)                      /* seconds in a day */
+#define        NO      0                               /* false/no */
+#define        YES     1                               /* true/yes */
+
+static struct utmp     buf[1024];              /* utmp read buffer */
+
+#define        HMAX    (int)sizeof(buf[0].ut_host)     /* size of utmp host field */
+#define        LMAX    (int)sizeof(buf[0].ut_line)     /* size of utmp tty field */
+#define        NMAX    (int)sizeof(buf[0].ut_name)     /* size of utmp name field */
+
+typedef struct arg {
+       char    *name;                          /* argument */
+#define        HOST_TYPE       -2
+#define        TTY_TYPE        -3
+#define        USER_TYPE       -4
+       int     type;                           /* type of arg */
+       struct arg      *next;                  /* linked list pointer */
+} ARG;
+ARG    *arglist;                               /* head of linked list */
+
+typedef struct ttytab {
+       long    logout;                         /* log out time */
+       char    tty[LMAX + 1];                  /* terminal name */
+       struct ttytab   *next;                  /* linked list pointer */
+} TTY;
+TTY    *ttylist;                               /* head of linked list */
+
+static long    currentout,                     /* current logout value */
+               maxrec;                         /* records to display */
+static char    *file = _PATH_WTMP;             /* wtmp file */
+
+static void wtmp(), addarg(), hostconv();
+static int want();
+TTY *addtty();
+static char *ttyconv();
+
+int
+main(argc, argv)
+       int     argc;
+       char    **argv;
+{
+       extern int      optind;
+       extern char     *optarg;
+       int     ch;
+
+       while ((ch = getopt(argc, argv, "0123456789f:h:t:")) != EOF)
+               switch((char)ch) {
+               case '0': case '1': case '2': case '3': case '4':
+               case '5': case '6': case '7': case '8': case '9':
+                       /*
+                        * kludge: last was originally designed to take
+                        * a number after a dash.
+                        */
+                       if (!maxrec)
+                               maxrec = atol(argv[optind - 1] + 1);
+                       break;
+               case 'f':
+                       file = optarg;
+                       break;
+               case 'h':
+                       hostconv(optarg);
+                       addarg(HOST_TYPE, optarg);
+                       break;
+               case 't':
+                       addarg(TTY_TYPE, ttyconv(optarg));
+                       break;
+               case '?':
+               default:
+                       fputs("usage: last [-#] [-f file] [-t tty] [-h hostname] [user ...]\n", stderr);
+                       exit(1);
+               }
+       for (argv += optind; *argv; ++argv) {
+#define        COMPATIBILITY
+#ifdef COMPATIBILITY
+               /* code to allow "last p5" to work */
+               addarg(TTY_TYPE, ttyconv(*argv));
+#endif
+               addarg(USER_TYPE, *argv);
+       }
+       wtmp();
+       exit(0);
+}
+
+/*
+ * wtmp --
+ *     read through the wtmp file
+ */
+static void
+wtmp()
+{
+       register struct utmp    *bp;            /* current structure */
+       register TTY    *T;                     /* tty list entry */
+       struct stat     stb;                    /* stat of file for size */
+       long    bl, delta,                      /* time difference */
+               lseek(), time();
+       int     bytes, wfd;
+       void    onintr();
+       char    *ct, *crmsg;
+
+       if ((wfd = open(file, O_RDONLY, 0)) < 0 || fstat(wfd, &stb) == -1) {
+               perror(file);
+               exit(1);
+       }
+       bl = (stb.st_size + sizeof(buf) - 1) / sizeof(buf);
+
+       (void)time(&buf[0].ut_time);
+       (void)signal(SIGINT, onintr);
+       (void)signal(SIGQUIT, onintr);
+
+       while (--bl >= 0) {
+               if (lseek(wfd, (long)(bl * sizeof(buf)), L_SET) == -1 ||
+                   (bytes = read(wfd, (char *)buf, sizeof(buf))) == -1) {
+                       fprintf(stderr, "last: %s: ", file);
+                       perror((char *)NULL);
+                       exit(1);
+               }
+               for (bp = &buf[bytes / sizeof(buf[0]) - 1]; bp >= buf; --bp) {
+                       /*
+                        * if the terminal line is '~', the machine stopped.
+                        * see utmp(5) for more info.
+                        */
+                       if (!strncmp(bp->ut_line, "~", LMAX)) {
+                               /* everybody just logged out */
+                               for (T = ttylist; T; T = T->next)
+                                       T->logout = -bp->ut_time;
+                               currentout = -bp->ut_time;
+                               crmsg = strncmp(bp->ut_name, "shutdown", NMAX) ? "crash" : "down ";
+                               if (!bp->ut_name[0])
+                                       (void)strcpy(bp->ut_name, "reboot");
+                               if (want(bp, NO)) {
+                                       ct = ctime(&bp->ut_time);
+                                       if(bp->ut_type != LOGIN_PROCESS)
+                                         printf("%-*.*s  %-*.*s %-*.*s %10.10s %5.5s \n", NMAX, NMAX, bp->ut_name, LMAX, LMAX, bp->ut_line, HMAX, HMAX, bp->ut_host, ct, ct + 11);
+                                       if (maxrec && !--maxrec)
+                                               return;
+                               }
+                               continue;
+                       }
+                       /* find associated tty */
+                       for (T = ttylist;; T = T->next) {
+                               if (!T) {
+                                       /* add new one */
+                                       T = addtty(bp->ut_line);
+                                       break;
+                               }
+                               if (!strncmp(T->tty, bp->ut_line, LMAX))
+                                       break;
+                       }
+                       if (bp->ut_name[0] && bp->ut_type != LOGIN_PROCESS
+                           && want(bp, YES)) {
+                               ct = ctime(&bp->ut_time);
+                               printf("%-*.*s  %-*.*s %-*.*s %10.10s %5.5s ", NMAX, NMAX, bp->ut_name, LMAX, LMAX, bp->ut_line, HMAX, HMAX, bp->ut_host, ct, ct + 11);
+                               if (!T->logout)
+                                       puts("  still logged in");
+                               else {
+                                       if (T->logout < 0) {
+                                               T->logout = -T->logout;
+                                               printf("- %s", crmsg);
+                                       }
+                                       else
+                                               printf("- %5.5s", ctime(&T->logout)+11);
+                                       delta = T->logout - bp->ut_time;
+                                       if (delta < SECDAY)
+                                               printf("  (%5.5s)\n", asctime(gmtime(&delta))+11);
+                                       else
+                                               printf(" (%ld+%5.5s)\n", delta / SECDAY, asctime(gmtime(&delta))+11);
+                               }
+                               if (maxrec != -1 && !--maxrec)
+                                       return;
+                       }
+                       T->logout = bp->ut_time;
+               }
+       }
+       ct = ctime(&buf[0].ut_time);
+       printf("\nwtmp begins %10.10s %5.5s \n", ct, ct + 11);
+}
+
+/*
+ * want --
+ *     see if want this entry
+ */
+static int
+want(bp, check)
+       register struct utmp    *bp;
+       int     check;
+{
+       register ARG    *step;
+
+       if (check)
+               /*
+                * when uucp and ftp log in over a network, the entry in
+                * the utmp file is the name plus their process id.  See
+                * etc/ftpd.c and usr.bin/uucp/uucpd.c for more information.
+                */
+               if (!strncmp(bp->ut_line, "ftp", sizeof("ftp") - 1))
+                       bp->ut_line[3] = '\0';
+               else if (!strncmp(bp->ut_line, "uucp", sizeof("uucp") - 1))
+                       bp->ut_line[4] = '\0';
+       if (!arglist)
+               return(YES);
+
+       for (step = arglist; step; step = step->next)
+               switch(step->type) {
+               case HOST_TYPE:
+                       if (!strncmp(step->name, bp->ut_host, HMAX))
+                               return(YES);
+                       break;
+               case TTY_TYPE:
+                       if (!strncmp(step->name, bp->ut_line, LMAX))
+                               return(YES);
+                       break;
+               case USER_TYPE:
+                       if (!strncmp(step->name, bp->ut_name, NMAX))
+                               return(YES);
+                       break;
+       }
+       return(NO);
+}
+
+/*
+ * addarg --
+ *     add an entry to a linked list of arguments
+ */
+static void
+addarg(type, arg)
+       int     type;
+       char    *arg;
+{
+       register ARG    *cur;
+
+       if (!(cur = (ARG *)malloc((unsigned int)sizeof(ARG)))) {
+               fputs("last: malloc failure.\n", stderr);
+               exit(1);
+       }
+       cur->next = arglist;
+       cur->type = type;
+       cur->name = arg;
+       arglist = cur;
+}
+
+/*
+ * addtty --
+ *     add an entry to a linked list of ttys
+ */
+TTY *
+addtty(ttyname)
+       char    *ttyname;
+{
+       register TTY    *cur;
+
+       if (!(cur = (TTY *)malloc((unsigned int)sizeof(TTY)))) {
+               fputs("last: malloc failure.\n", stderr);
+               exit(1);
+       }
+       cur->next = ttylist;
+       cur->logout = currentout;
+       memcpy(cur->tty, ttyname, LMAX);
+       return(ttylist = cur);
+}
+
+/*
+ * hostconv --
+ *     convert the hostname to search pattern; if the supplied host name
+ *     has a domain attached that is the same as the current domain, rip
+ *     off the domain suffix since that's what login(1) does.
+ */
+static void
+hostconv(arg)
+       char    *arg;
+{
+       static int      first = 1;
+       static char     *hostdot,
+                       name[MAXHOSTNAMELEN];
+       char    *argdot;
+
+       if (!(argdot = strchr(arg, '.')))
+               return;
+       if (first) {
+               first = 0;
+               if (gethostname(name, sizeof(name))) {
+                       perror("last: gethostname");
+                       exit(1);
+               }
+               hostdot = strchr(name, '.');
+       }
+       if (hostdot && !strcmp(hostdot, argdot))
+               *argdot = '\0';
+}
+
+/*
+ * ttyconv --
+ *     convert tty to correct name.
+ */
+static char *
+ttyconv(arg)
+       char    *arg;
+{
+       char    *mval;
+
+       /*
+        * kludge -- we assume that all tty's end with
+        * a two character suffix.
+        */
+       if (strlen(arg) == 2) {
+               /* either 6 for "ttyxx" or 8 for "console" */
+               if (!(mval = malloc((unsigned int)8))) {
+                       fputs("last: malloc failure.\n", stderr);
+                       exit(1);
+               }
+               if (!strcmp(arg, "co"))
+                       (void)strcpy(mval, "console");
+               else {
+                       (void)strcpy(mval, "tty");
+                       (void)strcpy(mval + 3, arg);
+               }
+               return(mval);
+       }
+       if (!strncmp(arg, "/dev/", sizeof("/dev/") - 1))
+               return(arg + 5);
+       return(arg);
+}
+
+/*
+ * onintr --
+ *     on interrupt, we inform the user how far we've gotten
+ */
+void
+onintr(signo)
+       int     signo;
+{
+       char    *ct;
+
+       ct = ctime(&buf[0].ut_time);
+       printf("\ninterrupted %10.10s %5.5s \n", ct, ct + 11);
+       if (signo == SIGINT)
+               exit(1);
+       (void)fflush(stdout);                   /* fix required for rsh */
+}
index e6e30d82a05e7ae65b4470acd791d32be86775ea..0e1f5eff80efa4ee66221c93155b058660119c9f 100644 (file)
@@ -29,6 +29,12 @@ exists, the contents of of this file are printed to the screen, and the
 login is terminated.  This is typically used to prevent logins when the
 system is being taken down.
 
+If special access restrictions are specified for the user in
+.IR /etc/usertty ,
+these must be met, or the log in attempt will be denied and a 
+.B syslog
+message will be generated. See the section on "Special Access Restrictions".
+
 If the user is root, then the login must be occuring on a tty listed in
 .IR /etc/securetty .
 Failures will be logged with the
@@ -49,7 +55,7 @@ If the file
 exists, then a "quiet" login is performed (this disables the checking of
 the checking of mail and the printing of the last login time and message of
 the day).  Otherwise, if
-.I /var/adm/lastlog
+.I /var/log/lastlog
 exists, the last login time is printed (and the current login is recorded).
 
 Random administrative things, such as setting the UID and GID of the tty
@@ -98,14 +104,183 @@ to pass the name of the remote host to
 .B login
 so that it may be placed in utmp and wtmp.  Only the superuser may use this
 option.
+
+.SH "SPECIAL ACCESS RESTRICTIONS"
+The file
+.I /etc/securetty
+lists the names of the ttys where root is allowed to log in. One name of
+a tty device without the /dev/ prefix must be specified on each line.
+If the file does not exist, root is allowed to log in on any tty.
+.PP
+The file
+.I /etc/usertty
+specifies additional access restrictions for specific users. If this file
+does not exist, no additional access restrictions are imposed. The file
+consists of a sequence of sections. There are three possible section 
+types: CLASSES, GROUPS and USERS. A CLASSES section defines classes of
+ttys and hostname patterns, A GROUPS section defines allowed ttys and
+hosts on a per group basis, and a USERS section defines allowed ttys
+and hosts on a per user basis.
+.PP
+Each line in this file in may be no longer than 255 characters. Comments
+start with # character and extend to the end of the line.
+.PP
+.SS "The CLASSES Section"
+A CLASSES section begins with the word CLASSES at the start of a line in all
+upper case. Each following line until the start of a new section or the
+end of the file consists of a sequence of words separated by tabs or
+spaces. Each line defines a class of ttys and host patterns. 
+.PP
+The word at
+the beginning of a line becomes defined as a collective name for the
+ttys and host patterns specified at the rest of the line. This collective
+name can be used in any subsequent GROUPS or USERS section. No such class
+name must occur as part of the definition of a class in order to avoid
+problems with recursive classes.
+.PP
+An example CLASSES section:
+.PP
+.nf
+.in +.5
+CLASSES
+myclass1               tty1 tty2
+myclass2               tty3 @.foo.com
+.in -.5
+.fi
+.PP
+This defines the classes 
+.I myclass1
+and
+.I myclass2
+as the corresponding right hand sides.
+.PP
+
+.SS "The GROUPS Section
+A GROUPS section defines allowed ttys and hosts on a per Unix group basis. If
+a user is a member of a Unix group according to 
+.I /etc/passwd
+and
+.I /etc/group
+and such a group is mentioned in a GROUPS section in 
+.I /etc/usertty
+then the user is granted access if the group is.
+.PP
+A GROUPS section starts with the word GROUPS in all upper case at the start of
+a line, and each following line is a sequence of words separated by spaces
+or tabs. The first word on a line is the name of the group and the rest
+of the words on the line specifies the ttys and hosts where members of that
+group are allowed access. These specifications may involve the use of
+classes defined in previous CLASSES sections.
+.PP
+An example GROUPS section.
+.PP
+.nf
+.in +0.5
+GROUPS
+sys            tty1 @.bar.edu
+stud           myclass1 tty4
+.in -0.5
+.fi
+.PP
+This example specifies that members of group 
+.I sys
+may log in on tty1 and from hosts in the bar.edu domain. Users in group
+.I stud
+may log in from hosts/ttys specified in the class myclass1 or from tty4.
+.PP
+
+.SS "The USERS Section"
+A USERS section starts with the word USERS in all upper case at the
+start of a line, and each following line is a sequence of words
+separated by spaces or tabs. The first word on a line is a username
+and that user is allowed to log in on the ttys and from the hosts
+mentioned on the rest of the line. These specifications may involve
+classes defined in previous CLASSES sections.  If no section header is
+specified at the top of the file, the first section defaults to be a
+USERS section.
+.PP
+An example USERS section:
+.PP
+.nf
+.in +0.5
+USERS
+zacho          tty1 @130.225.16.0/255.255.255.0
+blue           tty3 myclass2
+.in -0.5
+.fi
+.PP
+This lets the user zacho login only on tty1 and from hosts with IP addreses
+in the range 130.225.16.0 \- 130.225.16.255, and user blue is allowed to
+log in from tty3 and whatever is specified in the class myclass2.
+.PP
+There may be a line in a USERS section starting with a username of *. This
+is a default rule and it will be applied to any user not matching any other
+line.
+.PP
+If both a USERS line and GROUPS line match a user then the user is allowed
+access from the union of all the ttys/hosts mentioned in these specifications.
+
+.SS Origins
+The tty and host pattern specifications used in the specification of classes,
+group and user access are called origins. An origin string may have 
+one of these formats:
+.IP o 
+The name of a tty device without the /dev/ prefix, for example tty1 or
+ttyS0.
+.PP
+.IP o
+The string @localhost, meaning that the user is allowed to telnet/rlogin
+from the local host to the same host. This also allows the user to for
+example run the command: xterm -e /bin/login.
+.PP
+.IP o
+A domain name suffix such as @.some.dom, meaning that the user may
+rlogin/telnet from any host whose domain name has the suffix .some.dom.
+.PP
+.IP o
+A range of IPv4 addresses, written @x.x.x.x/y.y.y.y where x.x.x.x
+is the IP address in the usual dotted quad decimal notation, and
+y.y.y.y is a bitmask in the same notation specifying which bits in the
+address to compare with the IP address of the remote host. For example
+@130.225.16.0/255.255.254.0 means that the user may rlogin/telnet from
+any host whose IP address is in the range 130.225.16.0 \- 130.225.17.255.
+.PP
+Any of the above origins may be prefixed by a time specification according
+to the syntax:
+.PP
+.nf
+timespec    ::= '[' <day-or-hour> [':' <day-or-hour>]* ']'
+day         ::= 'mon' | 'tue' | 'wed' | 'thu' | 'fri' | 'sat' | 'sun'
+hour        ::= '0' | '1' | ... | '23'
+hourspec    ::= <hour> | <hour> '\-' <hour>
+day-or-hour ::= <day> | <hourspec>
+.fi
+.PP
+For example, the origin [mon:tue:wed:thu:fri:8\-17]tty3 means that log in is
+allowed on mondays through fridays between 8:00 and 17:59 (5:59 pm) on tty3.
+This also shows that an hour range a\-b includes all moments between a:00 and
+b:59. A single hour specification (such as 10) means the time span between 
+10:00 and 10:59.
+.PP
+Not specifying any time prefix for a tty or host means log in from that origin
+is allowed any time. If you give a time prefix be sure to specify both a set
+of days and one or more hours or hour ranges. A time specification may
+not include any white space.
+.PP
+If no default rule is given then users not matching any line
+.I /etc/usertty
+are allowed to log in from anywhere as is standard behavior.
+.PP
 .SH FILES
 .nf
-.I /etc/utmp
-.I /etc/wtmp
+.I /var/run/utmp
+.I /var/log/wtmp
+.I /var/log/lastlog
 .I /usr/spool/mail/*
 .I /etc/motd
 .I /etc/passwd
 .I /etc/nologin
+.I /etc/usertty
 .I .hushlogin
 .fi
 .SH "SEE ALSO"
index f0130f8ed0dda0b8a1098825b8fb194aaf75d0b1..33a0b03e739a37208c1d3a4b56c2ff56504df433 100644 (file)
@@ -130,8 +130,11 @@ static char sccsid[] = "@(#)login.c        5.40 (Berkeley) 5/9/89";
 
 #ifndef linux
 #include <tzfile.h>
+#endif
 #include <lastlog.h>
-#else
+
+#if 0
+/* from before we had a lastlog.h file in linux */
 struct  lastlog
   { long ll_time;
     char ll_line[12];
@@ -152,7 +155,7 @@ void checknologin P_((void));
 void dolastlog P_((int quiet));
 void badlogin P_((char *name));
 char *stypeof P_((char *ttyid));
-void checktty P_((char *user, char *tty));
+void checktty P_((char *user, char *tty, struct passwd *pwd));
 void getstr P_((char *buf, int cnt, char *err));
 void sleepexit P_((int eval));
 #undef P_
@@ -164,13 +167,11 @@ char      realm[REALM_SZ];
 int    kerror = KSUCCESS, notickets = 1;
 #endif
 
-#ifndef linux
 #define        TTYGRPNAME      "tty"           /* name of group to own ttys */
-#else
-#  define TTYGRPNAME      "other"
-#  ifndef MAXPATHLEN
-#    define MAXPATHLEN 1024
-#  endif
+/**#  define TTYGRPNAME      "other" **/
+
+#ifndef MAXPATHLEN
+#  define MAXPATHLEN 1024
 #endif
 
 /*
@@ -184,9 +185,9 @@ int     timeout = 60;
 #endif
 
 struct passwd *pwd;
-int    failures;
+int    failures = 1;
 char   term[64], *hostname, *username, *tty;
-
+struct  hostent hostaddress;
 char   thishost[100];
 
 #ifndef linux
@@ -265,6 +266,7 @@ main(argc, argv)
        (void)strncpy(thishost, tbuf, sizeof(thishost)-1);
        domain = index(tbuf, '.');
 
+       hostname = NULL;
        fflag = hflag = pflag = 0;
        passwd_req = 1;
        while ((ch = getopt(argc, argv, "fh:p")) != EOF)
@@ -284,6 +286,14 @@ main(argc, argv)
                            strcasecmp(p, domain) == 0)
                                *p = 0;
                        hostname = optarg;
+                       { 
+                           struct hostent *he = gethostbyname(hostname);
+                           if (he) {
+                               memcpy(&hostaddress, he, sizeof(hostaddress));
+                           } else {
+                               memset(&hostaddress, 0, sizeof(hostaddress));
+                           }
+                       }
                        break;
 
                case 'p':
@@ -357,7 +367,7 @@ main(argc, argv)
            tcsetattr(0,TCSAFLUSH,&tt);
        }
 
-       if (tty = rindex(ttyn, '/'))
+       if ((tty = rindex(ttyn, '/')))
                ++tty;
        else
                tty = ttyn;
@@ -375,14 +385,27 @@ main(argc, argv)
                        getloginname();
                }
 
-               checktty(username, tty);
+               /* Dirty patch to fix a gigantic security hole when using 
+                  yellow pages. This problem should be solved by the
+                  libraries, and not by programs, but this must be fixed
+                  urgently! If the first char of the username is '+', we 
+                  avoid login success.
+                  Feb 95 <alvaro@etsit.upm.es> */
+
+               if (username[0] == '+') {
+                   puts("Illegal username");
+                   badlogin(username);
+                   sleepexit(1);
+               }
 
                (void)strcpy(tbuf, username);
-               if (pwd = getpwnam(username))
+               if ((pwd = getpwnam(username)))
                        salt = pwd->pw_passwd;
                else
                        salt = "xx";
 
+               checktty(username, tty, pwd); /* in checktty.c */
+
                /* if user not super-user, check for disabled logins */
                if (pwd == NULL || pwd->pw_uid)
                        checknologin();
@@ -566,30 +589,38 @@ main(argc, argv)
        /* for linux, write entries in utmp and wtmp */
        {
                struct utmp ut;
-               char *ttyabbrev;
                int wtmp;
-               
-               memset((char *)&ut, 0, sizeof(ut));
-               ut.ut_type = USER_PROCESS;
-               ut.ut_pid = getpid();
-               strncpy(ut.ut_line, ttyn + sizeof("/dev/")-1, sizeof(ut.ut_line));
-               ttyabbrev = ttyn + sizeof("/dev/tty") - 1;
-               strncpy(ut.ut_id, ttyabbrev, sizeof(ut.ut_id));
-               (void)time(&ut.ut_time);
+               struct utmp *utp;
+               pid_t mypid = getpid();
+
+               utmpname(_PATH_UTMP);
+               setutent();
+               while ((utp = getutent()) 
+                      && !(utp->ut_pid == mypid)) /* nothing */;
+
+               if (utp) {
+                   memcpy(&ut, utp, sizeof(ut));
+               } else {
+                   /* some gettys/telnetds don't initialize utmp... */
+                   memset(&ut, 0, sizeof(ut));
+               }
+               endutent();
+
+               if (ut.ut_id[0] == 0)
+                 strncpy(ut.ut_id, ttyn + 8, sizeof(ut.ut_id));
+       
                strncpy(ut.ut_user, username, sizeof(ut.ut_user));
-               
-               /* fill in host and ip-addr fields when we get networking */
+               strncpy(ut.ut_line, ttyn + 5, sizeof(ut.ut_line));
+               time(&ut.ut_time);
+               ut.ut_type = USER_PROCESS;
+               ut.ut_pid = mypid;
                if (hostname) {
-                   struct hostent *he;
-
                    strncpy(ut.ut_host, hostname, sizeof(ut.ut_host));
-                   if ((he = gethostbyname(hostname)))
-                     memcpy(&ut.ut_addr, he->h_addr_list[0],
+                   if (hostaddress.h_addr_list)
+                     memcpy(&ut.ut_addr, hostaddress.h_addr_list[0],
                             sizeof(ut.ut_addr));
                }
-               
-               utmpname(_PATH_UTMP);
-               setutent();
+
                pututline(&ut);
                endutent();
                
@@ -600,7 +631,6 @@ main(argc, argv)
                        close(wtmp);
                }
        }
-        /* fix_utmp_type_and_user(username, ttyn, LOGIN_PROCESS); */
 #endif
 
        dolastlog(quietlog);
@@ -615,9 +645,13 @@ main(argc, argv)
        (void)chown(ttyn, pwd->pw_uid,
            (gr = getgrnam(TTYGRPNAME)) ? gr->gr_gid : pwd->pw_gid);
 
-       (void)chmod(ttyn, 0622);
-       (void)setgid(pwd->pw_gid);
+#ifdef USE_TTY_GROUP
+       chmod(ttyn, 0620);
+#else
+       chmod(ttyn, 0600);
+#endif
 
+       setgid(pwd->pw_gid);
        initgroups(username, pwd->pw_gid);
 
 #ifdef HAVE_QUOTA
@@ -676,10 +710,9 @@ main(argc, argv)
        (void)setenv("LOGNAME", pwd->pw_name, 1);
 #endif
 
-#ifndef linux
-       if (tty[sizeof("tty")-1] == 'd')
+       if (tty[sizeof("tty")-1] == 'S')
                syslog(LOG_INFO, "DIALUP %s, %s", tty, pwd->pw_name);
-#endif
+
        if (pwd->pw_uid == 0)
                if (hostname)
                        syslog(LOG_NOTICE, "ROOT LOGIN ON %s FROM %s",
@@ -748,16 +781,26 @@ getloginname()
        register int ch;
        register char *p;
        static char nbuf[UT_NAMESIZE + 1];
+       int cnt, cnt2;
 
+       cnt2 = 0;
        for (;;) {
+               cnt = 0;
                (void)printf("\n%s login: ", thishost); fflush(stdout);
                for (p = nbuf; (ch = getchar()) != '\n'; ) {
                        if (ch == EOF) {
-                               badlogin(username);
+                               badlogin("EOF");
                                exit(0);
                        }
                        if (p < nbuf + UT_NAMESIZE)
                                *p++ = ch;
+
+                       cnt++;
+                       if (cnt > UT_NAMESIZE + 20) {
+                               fprintf(stderr, "login name much too long.\n");
+                               badlogin("NAME too long");
+                               exit(0);
+                       }
                }
                if (p > nbuf)
                        if (nbuf[0] == '-')
@@ -768,6 +811,13 @@ getloginname()
                                username = nbuf;
                                break;
                        }
+
+               cnt2++;
+               if (cnt2 > 50) {
+                       fprintf(stderr, "too many bare linefeeds.\n");
+                       badlogin("EXCESSIVE linefeeds");
+                       exit(0);
+               }
        }
 }
 
@@ -898,9 +948,6 @@ void
 badlogin(name)
        char *name;
 {
-       if (failures == 0)
-               return;
-
        if (hostname)
                syslog(LOG_NOTICE, "%d LOGIN FAILURE%s FROM %s, %s",
                    failures, failures > 1 ? "S" : "", hostname, name);
@@ -923,62 +970,6 @@ stypeof(ttyid)
 }
 #endif 
 
-void
-checktty(user, tty)
-     char *user;
-     char *tty;
-{
-    FILE *f;
-    char buf[256];
-    char *ptr;
-    char devname[50];
-    struct stat stb;
-
-    /* no /etc/usertty, default to allow access */
-    if(!(f = fopen(_PATH_USERTTY, "r"))) return;
-
-    while(fgets(buf, 255, f)) {
-
-       /* strip comments */
-       for(ptr = buf; ptr < buf + 256; ptr++) 
-         if(*ptr == '#') *ptr = 0;
-
-       strtok(buf, " \t");
-       if(strncmp(user, buf, 8) == 0) {
-           while((ptr = strtok(NULL, "\t\n "))) {
-               if(strncmp(tty, ptr, 10) == 0) {
-                   fclose(f);
-                   return;
-               }
-               if(strcmp("PTY", ptr) == 0) {
-#ifdef linux
-                   sprintf(devname, "/dev/%s", ptr);
-                   /* VERY linux dependent, recognize PTY as alias
-                      for all pseudo tty's */
-                   if((stat(devname, &stb) >= 0)
-                      && major(stb.st_rdev) == 4 
-                      && minor(stb.st_rdev) >= 192) {
-                       fclose(f);
-                       return;
-                   }
-#endif
-               }
-           }
-           /* if we get here, /etc/usertty exists, there's a line
-              beginning with our username, but it doesn't contain the
-              name of the tty where the user is trying to log in.
-              So deny access! */
-           fclose(f);
-           printf("Login on %s denied.\n", tty);
-           badlogin(user);
-           sleepexit(1);
-       }
-    }
-    fclose(f);
-    /* users not mentioned in /etc/usertty are by default allowed access
-       on all tty's */
-}
-
 void
 getstr(buf, cnt, err)
        char *buf, *err;
index 81932dfd94effc763ba03cd2ddec9396f94b4cfd..4a9f3c9b1656abb95b2c5573b07339809baed85d 100644 (file)
@@ -1,24 +1,98 @@
-.\" Original author: Miquel van Smoorenburg, miquels@drinkel.nl.mugnet.org
-.\" Updated by faith@cs.unc.edu, Fri Oct 29 23:22:16 1993
-.TH MESG 1 "29 October 1993" "Linux 0.99" "Linux Programmer's Manual"
+.\" Copyright (c) 1987, 1990, 1993
+.\"    The Regents of the University of California.  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 the University of
+.\"    California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\"    may be used to endorse or promote products derived from this software
+.\"    without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS 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.
+.\"
+.\"    @(#)mesg.1      8.1 (Berkeley) 6/6/93
+.\"
+.\" Fri Mar 10 20:31:02 1995, modified for standard man macros,
+.\" faith@cs.unc.edu
+.\"
+.\"
+.\" "
+.TH MESG 1 "10 March 1995" "Linux 1.2" "Linux Programmer's Manual"
 .SH NAME
-mesg \- control write access to your terminal
+mesg \- display (do not display) messages from other users
 .SH SYNOPSIS
-.B mesg
-.RB [y|n]
-.br
+.B mesg [ n ] [ y ]
 .SH DESCRIPTION
-.B Mesg
-controls the access to your terminal by others. It's typically used
-to allow/disallow others users to \fBwrite(1)\fP to your terminal.
-.SH FLAGS
-.IP y
-Allow write access to your terminal.
-.IP n
-Disallow write access to your terminal.
-.IP [none]
-Prints out the current access state of your terminal.
-.SH SEE ALSO
-.BR write (1), wall (1)
-.SH AUTHOR
-Miquel van Smoorenburg, miquels@drinkel.nl.mugnet.org
+The
+.B mesg
+utility is invoked by a users to control write access others have to the
+terminal device associated with the standard error output.  If write access
+is allowed, then programs such as
+.BR talk (1)
+and
+.BR write (1)
+may display messages on the terminal.
+.PP
+Traditionally, write access is allowed by default.  However, as users
+become more conscious of various security risks, there is a trend to remove
+write access by default, at least for the primary login shell.  To make
+sure your ttys are set the way you want them to be set,
+.B mesg
+should be executed in your login scripts.
+.PP
+Options available:
+.TP
+.B n
+Disallows messages.
+.TP
+.B y
+Permits messages to be displayed.
+.PP
+If no arguments are given,
+.B mesg
+displays the present message status to the standard error output.
+.PP
+The
+.B mesg
+utility exits with one of the following values:
+.TP
+.I "\ 0"
+Messages are allowed.
+.TP
+.I "\ 1"
+Messages are not allowed.
+.TP
+.I "\>1"
+An error has occurred.
+.SH FILES
+.I /dev/[pt]ty[pq]?
+.SH "SEE ALSO"
+.BR biff (1),
+.BR talk (1),
+.BR write (1),
+.BR wall (1),
+.BR login (1),
+.BR xterm (1)
+.SH HISTORY
+A
+.B mesg
+command appeared in Version 6 AT&T UNIX.
index 07c5fad1f327a5e87a19af5d158cc527272f262c..79d3ef21ebaacb280d85b264c28260ea74104415 100644 (file)
 /*
- * mesg.c      The "mesg" utility. Gives / restrict access to
- *             your terminal by others.
+ * Copyright (c) 1987, 1993
+ *     The Regents of the University of California.  All rights reserved.
+ * (c) UNIX System Laboratories, Inc.
+ * All or some portions of this file are derived from material licensed
+ * to the University of California by American Telephone and Telegraph
+ * Co. or Unix System Laboratories, Inc. and are reproduced herein with
+ * the permission of UNIX System Laboratories, Inc.
  *
- * Usage:      mesg [y|n].
- *             Without arguments prints out the current settings.
+ * 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 the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS 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.
+ *
+ * Modified Fri Mar 10 20:27:19 1995, faith@cs.unc.edu, for Linux
+ * 
  */
-#include <stdio.h>
+
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1987, 1993\n\
+       The Regents of the University of California.  All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)mesg.c     8.2 (Berkeley) 1/21/94";
+#endif /* not lint */
+
+#include <sys/types.h>
 #include <sys/stat.h>
-#include <stdlib.h>
+
+#include <err.h>
 #include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
 #include <unistd.h>
 
-char *Version = "@(#) mesg 1.0 08-12-92 MvS";
-
-int main(int argc, char **argv)
+int
+main(argc, argv)
+       int argc;
+       char *argv[];
 {
-  struct stat st;
-
-  if (!isatty(0)) {
-       /* Or should we look in /etc/utmp? */
-       fprintf(stderr, "stdin: is not a tty");
-       return(1);
-  }
-
-  if (fstat(0, &st) < 0) {
-       perror("fstat");
-       return(1);
-  }
-  if (argc < 2) {
-       printf("Is %s\n", ((st.st_mode & 022) == 022) ? "y" : "n");
-       return(0);
-  }
-  if (argc > 2 || (argv[1][0] != 'y' && argv[1][0] != 'n')) {
-       fprintf(stderr, "Usage: mesg [y|n]\n");
-       return(1);
-  }
-  if (argv[1][0] == 'y')
-       st.st_mode |= 022;
-  else
-       st.st_mode &= ~022;
-  fchmod(0, st.st_mode);
-  return(0);
+       struct stat sb;
+       char *tty;
+       int ch;
+
+       while ((ch = getopt(argc, argv, "")) != EOF)
+               switch (ch) {
+               case '?':
+               default:
+                       goto usage;
+               }
+       argc -= optind;
+       argv += optind;
+
+       if ((tty = ttyname(STDERR_FILENO)) == NULL)
+               err(1, "ttyname");
+       if (stat(tty, &sb) < 0)
+               err(1, "%s", tty);
+
+       if (*argv == NULL) {
+               if (sb.st_mode & (S_IWGRP | S_IWOTH)) {
+                       (void)fprintf(stderr, "is y\n");
+                       exit(0);
+               }
+               (void)fprintf(stderr, "is n\n");
+               exit(1);
+       }
+
+       switch (*argv[0]) {
+       case 'y':
+#ifdef USE_TTY_GROUP
+               if (chmod(tty, sb.st_mode | S_IWGRP) < 0)
+                       err(1, "%s", tty);
+#else
+               if (chmod(tty, sb.st_mode | S_IWGRP | S_IWOTH) < 0)
+                       err(1, "%s", tty);
+#endif
+               exit(0);
+       case 'n':
+               if (chmod(tty, sb.st_mode & ~(S_IWGRP|S_IWOTH)) < 0)
+                       err(1, "%s", tty);
+               exit(1);
+       }
+
+usage: (void)fprintf(stderr, "usage: mesg [y | n]\n");
+       exit(2);
 }
index 032a5d5aaed05cb68c40fb8ec74233fb1e7e2d74..de420ecfb10738c9489d44fd7e41c4e189270fb9 100644 (file)
@@ -1,6 +1,6 @@
 .\" Original author unknown.  This man page is in the public domain.
 .\" Modified Sat Oct  9 17:46:48 1993 by faith@cs.unc.edu
-.TH NEWGRP 1 "9 October 1993" "Linux 0.99" "Linux Programmer's Manual"
+.TH NEWGRP 1 "9 October 1993" "Linux 1.2" "Linux Programmer's Manual"
 .SH NAME
 newgrp \- log in to a new group
 .SH SYNOPSIS
@@ -22,3 +22,7 @@ If no group is specified, the GID is changed to the login GID.
 
 .SH "SEE ALSO"
 .BR login "(1), " group (5)
+
+.SH AUTHOR
+Originally by Michael Haardt. Currently maintained by 
+Peter Orbaek (poe@daimi.aau.dk).
index d22c458fad2b93db8efa884c4b7516e0b420dc57..f2bf9de90af280a0a7fdcaa509e44950b59d38f0 100644 (file)
@@ -1,20 +1,33 @@
 .\" Copyright 1992 Rickard E. Faith (faith@cs.unc.edu)
 .\" May be distributed under the GNU General Public License
-.TH PASSWD 1 "22 June 1994" "Linux 1.0" "Linux Programmer's Manual"
+.TH PASSWD 1 "22 June 1994" "Linux 1.2" "Linux Programmer's Manual"
 .SH NAME
 passwd \- change password
 .SH SYNOPSIS
-.BR "passwd [ " name " ]"
+.BR "passwd [ " name " [ " password " ] ]"
 .SH DESCRIPTION
+Without arguments
 .B passwd
-will change the specified user's password.  Only the superuser is allowed
-to change other user's passwords.  If the user is not root, then the old
-password is prompted for and verified.
+will change the password for the current user. First the user is asked for
+the old password, then prompted twice for the new password in order to
+catch typing errors. The new password must be at least six characters long,
+and have both upper and lower case letters or non-letters. The new password
+must not be equal to the old password, and it must not match the username.
+
+The one and two argument forms may only be used by the superuser. Using the
+one argument form, the superuser may change the password for that user.
+The superuser is not asked for the users old password, and the rules 
+for proper passwords are not applied since the superuser may have legitimate
+reasons to choose a non-conformant password.
+
+The two argument form gives the 
+.I user
+the password stated as the second argument. This may be useful when
+giving many users an initial generated password.
+
+Giving an empty string as the second argument erases the password for the
+user.
 
-A new password is prompted for twice, to avoid typing mistakes.  Unless the
-user is the superuser, the new password must have more than six characters,
-and must have either both upper and lower case letters, or non-letters.
-Some passwords which are similar to the user's name are not allowed.
 .SH FILES
 .I /etc/passwd
 .br
index 5bd6d3abd998ac9c5873b496dc8ad492a203cc1e..1c786e94e5f7f46aa9c38ec483f41339db7a3477 100644 (file)
@@ -5,16 +5,26 @@
 
 /* Hacked by Alvaro Martinez Echevarria, alvaro@enano.etsit.upm.es,
    to allow peaceful coexistence with yp. Nov 94. */
+/* Hacked to allow root to set passwd from command line.
+   by Arpad Magossanyi (mag@tas.vein.hu) */
 
+/*
+ * Usage: passwd [username [password]]
+ * Only root may use the one and two argument forms. 
+ */
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <stdio.h>
 #include <unistd.h>
 #include <termios.h>
+#include <fcntl.h>
 #include <pwd.h>
 #include <ctype.h>
 #include <time.h>
 #include <string.h>
+#include <errno.h>
+#include <sys/resource.h>
 
 extern int is_local(char *);
 
@@ -23,171 +33,225 @@ extern int is_local(char *);
 
 #define MAX_LENGTH     1024
 
+static void
+pexit(str)
+     char *str;
+{
+    perror(str);
+    exit(1);
+}
+
 int
 main(argc, argv)
-       int argc;
-       char *argv[];
+     int argc;
+     char *argv[];
 {
-       struct passwd *pe;
-       uid_t gotuid = getuid();
-       char *pwdstr, *cryptstr;
-       char pwdstr1[10];
-       int ucase, lcase, other;
-       char *p, *q, *user;
-       time_t tm;
-       char salt[2];
-       FILE *fd_in, *fd_out;
-       char line[MAX_LENGTH];
-       int error=0;
-       int r;
-
-       umask(022);
+    struct passwd *pe;
+    uid_t gotuid = getuid();
+    char *pwdstr = NULL, *cryptstr, *oldstr;
+    char pwdstr1[10];
+    int ucase, lcase, other;
+    char *p, *q, *user;
+    time_t tm;
+    char salt[2];
+    FILE *fd_in, *fd_out;
+    char line[MAX_LENGTH];
+    char colonuser[16];
+    int error=0;
+    int r;
+    int ptmp;
+#ifndef USE_SETPWNAM
+    struct rlimit rlim;
+#endif
 
-       if(argc > 2) {
-               puts("Too many arguments");
-               exit(1);
-       } else if(argc == 2) {
-               if(gotuid) {
-                       puts("Only root can change the password for others");
-                       exit(1);
-               }
-               user = argv[1];
-       } else {
-               if (!(user = getlogin())) {
-                  if (!(pe = getpwuid( getuid() ))) {
-                     puts("Cannot find login name");
-                     exit(1);
-                  } else
-                        user = pe->pw_name;
-                }
+    if(argc > 3) {
+       puts("Too many arguments");
+       exit(1);
+    } else if(argc >= 2) {
+       if(gotuid) {
+           puts("Only root can change the password for others");
+           exit(1);
        }
-
-       if(!(pe = getpwnam(user))) {
-               puts("Can't find username anywhere. Are you really a user?");
-               exit(1);
+       user = argv[1];
+       
+       if (argc == 3) pwdstr = argv[2];
+       
+    } else {
+       if (!(user = getlogin())) {
+           if (!(pe = getpwuid( getuid() ))) {
+               pexit("Cannot find login name");
+           } else
+             user = pe->pw_name;
        }
+    }
 
-        if (!(is_local(user))) {
-               puts("Sorry, I can only change local passwords. Use yppasswd instead.");
-               exit(1);
-       }
+#ifndef USE_SETPWNAM
+    umask(022);
 
-       /* if somebody got into changing utmp... */
-       if(gotuid && gotuid != pe->pw_uid) {
-           puts("UID and username does not match, imposter!");
+    rlim.rlim_cur = rlim.rlim_max = RLIM_INFINITY;
+    setrlimit(RLIMIT_CPU, &rlim);
+    setrlimit(RLIMIT_FSIZE, &rlim);
+    setrlimit(RLIMIT_STACK, &rlim);
+    setrlimit(RLIMIT_DATA, &rlim);
+    setrlimit(RLIMIT_RSS, &rlim);
+    rlim.rlim_cur = rlim.rlim_max = 0;
+    setrlimit(RLIMIT_CORE, &rlim);
+#endif
+    
+    if(!(pe = getpwnam(user))) {
+       pexit("Can't find username anywhere. Are you really a user?");
+    }
+    
+    if (!(is_local(user))) {
+       puts("Sorry, I can only change local passwords. Use yppasswd instead.");
+       exit(1);
+    }
+    
+    /* if somebody got into changing utmp... */
+    if(gotuid && gotuid != pe->pw_uid) {
+       puts("UID and username does not match, imposter!");
+       exit(1);
+    }
+    
+    printf( "Changing password for %s\n", user );
+    
+    if(gotuid && pe->pw_passwd && pe->pw_passwd[0]) {
+       oldstr = getpass("Enter old password: ");
+       if(strncmp(pe->pw_passwd, crypt(oldstr, pe->pw_passwd), 13)) {
+           puts("Illegal password, imposter.");
            exit(1);
        }
+    }
 
-       printf( "Changing password for %s\n", user );
-
-       if(gotuid && pe->pw_passwd && pe->pw_passwd[0]) {
-               pwdstr = getpass("Enter old password: ");
-               if(strncmp(pe->pw_passwd, crypt(pwdstr, pe->pw_passwd), 13)) {
-                       puts("Illegal password, imposter.");
-                       exit(1);
-               }
-       }
+    if (!pwdstr) {
+       /* password not set on command line by root, ask for it ... */
        
-redo_it:
+      redo_it:
        pwdstr = getpass("Enter new password: ");
-       strncpy(pwdstr1, pwdstr, 9);
-       pwdstr = getpass("Re-type new password: ");
-
-       if(strncmp(pwdstr, pwdstr1, 8)) {
-               puts("You misspelled it. Password not changed.");
-               exit(0);
+       if (pwdstr[0] == '\0') {
+           puts("Password not changed.");
+           exit(1);
        }
        
        if((strlen(pwdstr) < 6) && gotuid) {
-               puts("The password must have at least 6 characters, try again.");
-               goto redo_it;
+           puts("The password must have at least 6 characters, try again.");
+           goto redo_it;
        }
        
        other = ucase = lcase = 0;
        for(p = pwdstr; *p; p++) {
-               ucase = ucase || isupper(*p);
-               lcase = lcase || islower(*p);
-               other = other || !isalpha(*p);
+           ucase = ucase || isupper(*p);
+           lcase = lcase || islower(*p);
+           other = other || !isalpha(*p);
        }
        
        if((!ucase || !lcase) && !other && gotuid) {
-               puts("The password must have both upper- and lowercase");
-               puts("letters, or non-letters; try again.");
-               goto redo_it;
+           puts("The password must have both upper- and lowercase");
+           puts("letters, or non-letters; try again.");
+           goto redo_it;
+       }
+       
+       if (pe->pw_passwd[0] 
+           && !strncmp(pe->pw_passwd, crypt(pwdstr, pe->pw_passwd), 13)
+           && gotuid) {
+           puts("You cannot reuse the old password.");
+           goto redo_it;
        }
        
        r = 0;
        for(p = pwdstr, q = pe->pw_name; *q && *p; q++, p++) {
-         if(tolower(*p) != tolower(*q)) {
-           r = 1;
-           break;
-         }
+           if(tolower(*p) != tolower(*q)) {
+               r = 1;
+               break;
+           }
        }
-
+       
        for(p = pwdstr + strlen(pwdstr)-1, q = pe->pw_name;
            *q && p >= pwdstr; q++, p--) {
-         if(tolower(*p) != tolower(*q)) {
-           r += 2;
-           break;
-         }
+           if(tolower(*p) != tolower(*q)) {
+               r += 2;
+               break;
+           }
        }
-
+       
        if(gotuid && r != 3) {
-         puts("Please don't use something like your username as password!");
-         goto redo_it;
+           puts("Please don't use something like your username as password!");
+           goto redo_it;
        }
-
+       
        /* do various other checks for stupid passwords here... */
-
-       time(&tm);
-       salt[0] = bin_to_ascii(tm & 0x3f);
-       salt[1] = bin_to_ascii((tm >> 5) & 0x3f);
-       cryptstr = crypt(pwdstr, salt);
        
-       if(access("/etc/ptmp", F_OK) == 0) {
-               puts("/etc/ptmp exists, can't change password");
-               exit(1);
-       }
+       strncpy(pwdstr1, pwdstr, 9);
+       pwdstr = getpass("Re-type new password: ");
        
-       if(!(fd_out = fopen("/etc/ptmp", "w"))) {
-               puts("Can't open /etc/ptmp, can't update password");
-               exit(1);
+       if(strncmp(pwdstr, pwdstr1, 8)) {
+           puts("You misspelled it. Password not changed.");
+           exit(1);
        }
+    } /* pwdstr != argv[2] i.e. password set on command line */
+    
+    time(&tm);
+    salt[0] = bin_to_ascii(tm & 0x3f);
+    salt[1] = bin_to_ascii((tm >> 6) & 0x3f);
+    cryptstr = crypt(pwdstr, salt);
+
+    if (pwdstr[0] == 0) cryptstr = "";
 
-       if(!(fd_in = fopen("/etc/passwd", "r"))) {
-               puts("Can't read /etc/passwd, can't update password");
-               exit(1);
+#ifdef USE_SETPWNAM
+    pe->pw_passwd = cryptstr;
+    if (setpwnam( pe ) < 0) {
+       perror( "setpwnam" );
+       printf( "Password *NOT* changed.  Try again later.\n" );
+       exit( 1 );
+    }
+#else
+    if ((ptmp = open("/etc/ptmp", O_CREAT|O_EXCL|O_WRONLY, 0600)) < 0) {
+       pexit("Can't exclusively open /etc/ptmp, can't update password");
+    }
+    fd_out = fdopen(ptmp, "w");
+    
+    if(!(fd_in = fopen("/etc/passwd", "r"))) {
+       pexit("Can't read /etc/passwd, can't update password");
+    }
+    
+    strcpy(colonuser, user);
+    strcat(colonuser, ":");
+    while(fgets(line, sizeof(line), fd_in)) {
+       if(!strncmp(line,colonuser,strlen(colonuser))) {
+           pe->pw_passwd = cryptstr;
+           if(putpwent(pe, fd_out) < 0) {
+               error = 1;
+           }
+       } else {
+           if(fputs(line,fd_out) < 0) {
+               error = 1;
+           }
        }
-       while(fgets(line, sizeof(line), fd_in)) {
-               if(!strncmp(line,user,strlen(user))) {
-                       pe->pw_passwd = cryptstr;
-                       if(putpwent(pe, fd_out) < 0) {
-                               error = 1;
-                       }
-               } else {
-                       if(fputs(line,fd_out) < 0) {
-                               error = 1;
-                       }
-               }
-               if(error) {
-                       puts("Error while writing new password file, password not changed.");
-                       fclose(fd_out);
-                       endpwent();
-                       unlink("/etc/ptmp");
-                       exit(1);
-               }
+       if(error) {
+           puts("Error while writing new password file, password not changed.");
+           fclose(fd_out);
+           endpwent();
+           unlink("/etc/ptmp");
+           exit(1);
        }
-       fclose(fd_in);
-       fclose(fd_out);
-
-       unlink("/etc/passwd.OLD");
-       link("/etc/passwd", "/etc/passwd.OLD");
-       unlink("/etc/passwd");
-       link("/etc/ptmp", "/etc/passwd");
-       unlink("/etc/ptmp");
-       chmod("/etc/passwd", 0644);
-       chown("/etc/passwd", 0, 0);
-
-       puts("Password changed.");      
-       exit(0);
+    }
+    fclose(fd_in);
+    fclose(fd_out);
+    
+    unlink("/etc/passwd.OLD"); /* passwd.OLD not required */
+    if (link("/etc/passwd", "/etc/passwd.OLD")) 
+      pexit("link(/etc/passwd, /etc/passwd.OLD) failed: no change");
+    if (unlink("/etc/passwd") < 0)
+      pexit("unlink(/etc/passwd) failed: no change");
+    if (link("/etc/ptmp", "/etc/passwd") < 0)
+      pexit("link(/etc/ptmp, /etc/passwd) failed: PASSWD file DROPPED!!");
+    if (unlink("/etc/ptmp") < 0) 
+      pexit("unlink(/etc/ptmp) failed: /etc/ptmp still exists");
+    
+    chmod("/etc/passwd", 0644);
+    chown("/etc/passwd", 0, 0);
+#endif
+    
+    puts("Password changed."); 
+    exit(0);
 }
index f7e6eb312a64d76c2b7ab61965eadadae7de23b9..8a01c6ec538da034f134e53ee384bb48bebcd9b8 100644 (file)
  *
  *  Thanks to "two guys named Ian".
  */
-/*   faith
- *   1.1.1.1
- *   1995/02/22 19:09:24
+/*   $Author: faith $
+ *   $Revision: 1.5 $
+ *   $Date: 1995/10/12 14:46:36 $
  */
 
-#define DEBUG 0
+#undef DEBUG
 
 /*  because I use getpwent(), putpwent(), etc... */
 #define _SVID_SOURCE
 #include <fcntl.h>
 #include <pwd.h>
 #include <errno.h>
+#include <signal.h>
+#include <sys/resource.h>
 #ifdef BSD43
 #include <sys/file.h>
 #endif
+#include <paths.h>
+
+#include "pathnames.h"
 
 extern int errno;
 
@@ -52,15 +57,18 @@ typedef int boolean;
 #define true 1
 
 #ifndef DEBUG
-#define PASSWD_FILE    "/etc/passwd"
-#define PTMP_FILE      "/etc/ptmp"
+#define PASSWD_FILE    _PATH_PASSWD
+#define PTMP_FILE      _PATH_PTMP
+#define PTMPTMP_FILE   _PATH_PTMPTMP
 #else
 #define PASSWD_FILE    "/tmp/passwd"
 #define PTMP_FILE      "/tmp/ptmp"
+#define PTMPTMP_FILE   "/tmp/ptmptmp"
 #endif
 
 static int copy_pwd (struct passwd *src, struct passwd *dest);
 static char *xstrdup (char *str);
+static void pw_init(void);
 
 /*
  *  setpwnam () --
@@ -70,14 +78,12 @@ static char *xstrdup (char *str);
  */
 int setpwnam (struct passwd *pwd)
 {
-    char *passwd = PASSWD_FILE;
-    char *ptmp = PTMP_FILE;
     FILE *fp;
-    int x, save_errno, fd;
+    int x, save_errno, fd, ret;
     struct passwd *entry;
     boolean found;
-    char buf[50];
     struct passwd spwd;
+    int oldumask;
 
     /*  getpwent() returns a pointer to a static buffer.
      *  "pwd" might have some from getpwent(), so we have to copy it to
@@ -86,16 +92,31 @@ int setpwnam (struct passwd *pwd)
     if (copy_pwd (pwd, &spwd) < 0)
        return (-1);
 
+    oldumask = umask(0);   /* Create with exact permissions */
+    pw_init();
+
     /* sanity check */
     for (x = 0; x < 3; x++) {
         if (x > 0) sleep (1);
-       fd = open (ptmp, O_WRONLY|O_CREAT|O_EXCL, 00644);
-        if (fd >= 0) break;
+       fd = open (PTMPTMP_FILE, O_WRONLY|O_CREAT, 0644);
+       if(fd == -1) {
+           perror(PTMPTMP_FILE);
+           umask(oldumask);
+           return (-1);
+       }
+       ret = link(PTMPTMP_FILE, PTMP_FILE);
+       unlink(PTMPTMP_FILE);
+       if(ret == -1)
+           close(fd);
+       else
+           break;
     }
-    if (fd < 0) return (-1);
+
+    umask(oldumask);
+    if (ret == -1) return (-1);
 
     /* ptmp should be owned by root.root or root.wheel */
-    if (chown (ptmp, (uid_t) 0, (gid_t) 0) < 0)
+    if (chown (PTMP_FILE, (uid_t) 0, (gid_t) 0) < 0)
        perror ("chown");
 
     /* open ptmp for writing and passwd for reading */
@@ -122,25 +143,13 @@ int setpwnam (struct passwd *pwd)
        goto fail;
     }
 
-    strcpy (buf, passwd);
-    strcat (buf, "~");
     /* we don't care if we can't remove the backup file */
-    remove (buf);
+    unlink (PASSWD_FILE".OLD");
     /* we don't care if we can't create the backup file */
-    link (passwd, buf);
-    /* we DO care if we can't erase the passwd file */
-    if (remove (passwd) < 0) {
-       /* if the file is still there, fail */
-       if (access (passwd, F_OK) == 0) goto fail;
-    }
-    /* if we can't link ptmp to passwd, all is lost */
-    if (link (ptmp, passwd) < 0) {
-       /* reinstall_system (); */
-       return (-1);
-    }
-    /* if we can't erase the ptmp file, we simply lose */
-    if (remove (ptmp) < 0)
-       return (-1);
+    link (PASSWD_FILE, PASSWD_FILE".OLD");
+    /* we DO care if we can't rename to the passwd file */
+    if (rename (PTMP_FILE, PASSWD_FILE) < 0)
+       goto fail;
     /* finally:  success */
     return 0;
 
@@ -149,7 +158,7 @@ int setpwnam (struct passwd *pwd)
     if (fp) fclose (fp);
     if (fd >= 0) close (fd);
     endpwent ();
-    remove (ptmp);
+    unlink (PTMP_FILE);
     errno = save_errno;
     return (-1);
 }
@@ -207,3 +216,34 @@ int putpwent (const struct passwd *p, FILE *stream)
 }
 
 #endif
+
+static void
+pw_init()
+{
+       struct rlimit rlim;
+
+       /* Unlimited resource limits. */
+       rlim.rlim_cur = rlim.rlim_max = RLIM_INFINITY;
+       (void)setrlimit(RLIMIT_CPU, &rlim);
+       (void)setrlimit(RLIMIT_FSIZE, &rlim);
+       (void)setrlimit(RLIMIT_STACK, &rlim);
+       (void)setrlimit(RLIMIT_DATA, &rlim);
+       (void)setrlimit(RLIMIT_RSS, &rlim);
+
+       /* Don't drop core (not really necessary, but GP's). */
+       rlim.rlim_cur = rlim.rlim_max = 0;
+       (void)setrlimit(RLIMIT_CORE, &rlim);
+
+       /* Turn off signals. */
+       (void)signal(SIGALRM, SIG_IGN);
+       (void)signal(SIGHUP, SIG_IGN);
+       (void)signal(SIGINT, SIG_IGN);
+       (void)signal(SIGPIPE, SIG_IGN);
+       (void)signal(SIGQUIT, SIG_IGN);
+       (void)signal(SIGTERM, SIG_IGN);
+       (void)signal(SIGTSTP, SIG_IGN);
+       (void)signal(SIGTTOU, SIG_IGN);
+
+       /* Create with exact permissions. */
+       (void)umask(0);
+}
index 78eb984b0b31f6efe966b6183ccba8e965f684e3..21b384124529c6d15a62cea078004e9c0889bea6 100644 (file)
@@ -1,6 +1,6 @@
 .\" Copyright 1992 Rickard E. Faith (faith@cs.unc.edu)
 .\" May be distributed under the GNU General Public License
-.TH SHUTDOWN 8 "20 November 1993" "Linux 0.99" "Linux Programmer's Manual"
+.TH SHUTDOWN 8 "20 November 1993" "Linux 1.2" "Linux Programmer's Manual"
 .SH NAME
 shutdown \- close down the system
 .SH SYNOPSIS
@@ -53,7 +53,7 @@ notifies all users, tells
 not to spawn more
 .BR getty (8)'s,
 writes the shutdown time into the
-.I /var/adm/wtmp
+.I /var/log/wtmp
 file, kills all other processes on the system,
 .BR sync (2)'s,
 unmounts all the disks,
@@ -93,7 +93,7 @@ detects (and deletes).
 .I /fastboot
 .I /etc/singleboot
 .I /etc/nologin
-.I /var/adm/wtmp
+.I /var/log/wtmp
 .fi
 .SH "SEE ALSO"
 .BR umount (8),
@@ -106,7 +106,8 @@ Unlike the BSD
 .BR shutdown ,
 users are notified of shutdown only once or twice, instead of many times,
 and at shorter and shorter intervals as "apocalypse approaches."
+Some would construe this as a feature.
 .SH AUTHOR
-poe@daimi.aau.dk
+Peter Orbaek (poe@daimi.aau.dk)
 .br
 Modified by jrs@world.std.com
index 0ca303988db5196266ecc35c5566d42bf3782768..155154c21722e158e856db4bc82ce7e84a42c2b3 100644 (file)
@@ -46,6 +46,7 @@
 
 void usage(), int_handler(), write_user(struct utmp *);
 void wall(), write_wtmp(), unmount_disks(), unmount_disks_ourselves();
+void swap_off();
 
 char   *prog;          /* name of the program */
 int    opt_reboot;     /* true if -r option or reboot command */
@@ -88,14 +89,14 @@ main(argc, argv)
        
 #ifndef DEBUGGING
        if(geteuid()) {
-               fprintf(stderr, "Only root can shut a system down.\n");
+               fprintf(stderr, "%s: Only root can shut a system down.\n", argv[0]);
                exit(1);
        }
 #endif
 
        if(*argv[0] == '-') argv[0]++;  /* allow shutdown as login shell */
        prog = argv[0];
-       if(ptr = strrchr(argv[0], '/')) prog = ++ptr;
+       if((ptr = strrchr(argv[0], '/'))) prog = ++ptr;
        
        if(!strcmp("halt", prog)) {
                opt_reboot = 0;
@@ -163,7 +164,7 @@ main(argc, argv)
                                struct tm *tt;
                                int now, then;
                                
-                               if(colon = strchr(argv[c], ':')) {
+                               if((colon = strchr(argv[c], ':'))) {
                                        *colon = '\0';
                                        hour = atoi(argv[c]);
                                        minute = atoi(++colon);
@@ -276,6 +277,9 @@ main(argc, argv)
        sync();
        sleep(2);
 
+       /* remove swap files and partitions using swapoff */
+       swap_off();
+
        /* unmount disks... */
        unmount_disks();
        sync();
@@ -339,7 +343,7 @@ wall()
        utmpname(_PATH_UTMP);
        setutent();
        
-       while(ut = getutent()) {
+       while((ut = getutent())) {
                if(ut->ut_type == USER_PROCESS)
                        write_user(ut);
        }
@@ -360,12 +364,41 @@ write_wtmp()
        time(&ut.ut_time);
        ut.ut_type = BOOT_TIME;
        
-       if((fd = open(_PATH_WTMP, O_WRONLY|O_APPEND)) > 0) {
+       if((fd = open(_PATH_WTMP, O_WRONLY|O_APPEND)) >= 0) {
                write(fd, (char *)&ut, sizeof(ut));
                close(fd);
        }
 }
 
+void
+swap_off()
+{
+       /* swapoff esp. swap FILES so the underlying partition can be
+          unmounted. It you don't have swapoff(1) or use mount to
+          add swapspace, this may not be necessary, but I guess it
+          won't hurt */
+
+       int pid;
+       int result;
+       int status;
+
+       sync();
+       if ((pid = fork()) < 0) {
+               printf("Cannot fork for swapoff. Shrug!\n");
+               return;
+       }
+       if (!pid) {
+               execl("/sbin/swapoff", SWAPOFF_ARGS, NULL);
+               execl("/etc/swapoff", SWAPOFF_ARGS, NULL);
+               execl("/bin/swapoff", SWAPOFF_ARGS, NULL);
+               execlp("swapoff", SWAPOFF_ARGS, NULL);
+               puts("Cannot exec swapoff, hoping umount will do the trick.");
+               exit(0);
+       }
+       while ((result = wait(&status)) != -1 && result != pid)
+               ;
+}
+
 void
 unmount_disks()
 {
@@ -385,16 +418,13 @@ unmount_disks()
                execl(_PATH_UMOUNT, UMOUNT_ARGS, NULL);
                printf("Cannot exec %s, trying umount.\n", _PATH_UMOUNT);
                execlp("umount", UMOUNT_ARGS, NULL);
-               printf("Cannot exec umount, trying manually.\n");
-               unmount_disks_ourselves();
+               puts("Cannot exec umount, giving up on umount.");
                exit(0);
        }
        while ((result = wait(&status)) != -1 && result != pid)
                ;
-       if (result == -1 || status) {
-               printf("Running umount failed, trying manually.\n");
-               unmount_disks_ourselves();
-       }
+       puts("Unmounting any remaining filesystems...");
+       unmount_disks_ourselves();
 }
 
 void
@@ -411,7 +441,7 @@ unmount_disks_ourselves()
        
        sync();
        if (!(mtab = setmntent(_PATH_MTAB, "r"))) {
-               printf("Cannot open %s.\n", _PATH_MTAB);
+               printf("shutdown: Cannot open %s.\n", _PATH_MTAB);
                return;
        }
        n = 0;
@@ -429,7 +459,7 @@ unmount_disks_ourselves()
                printf("umount %s\n", filesys);
 #else
                if (umount(mntlist[i]) < 0)
-                       printf("Couldn't umount %s\n", filesys);
+                       printf("shutdown: Couldn't umount %s\n", filesys);
 #endif
        }
 }
index 9b31c15e49f7b4dd97fe86f1b463d8dfb9014edf..3a39dcd4518f03ff7fa5015e95fe05b5c941459b 100644 (file)
@@ -144,7 +144,7 @@ int main(int argc, char *argv[])
 
                    utmpname(_PATH_UTMP);
                    setutent();
-                   while(ut = getutent()) {
+                   while((ut = getutent())) {
                        if(ut->ut_pid == pid) {
                            time(&ut->ut_time);
                            memset(&ut->ut_user, 0, UT_NAMESIZE);
@@ -265,7 +265,9 @@ void spawn(int i)
        } else {
                /* this is the child */
                char term[40];
+#ifdef SET_TZ
                char tz[CMDSIZ];
+#endif
                char *env[3];
                
                setsid();
@@ -294,8 +296,10 @@ void read_inittab()
        char buf[CMDSIZ];
        int i,j,k;
        char *ptr, *getty;
+#ifdef SPECIAL_CONSOLE_TERM
        char tty[50];
        struct stat stb;
+#endif
        char *termenv, *getenv();
        
        termenv = getenv("TERM");       /* set by kernel */
@@ -332,7 +336,7 @@ void read_inittab()
                (void) strtok(getty, " \t\n");
                inittab[i].toks[0] = getty;
                j = 1;
-               while(ptr = strtok((char *)0, " \t\n"))
+               while((ptr = strtok((char *)0, " \t\n")))
                        inittab[i].toks[j++] = ptr;
                inittab[i].toks[j] = (char *)0;
 
index 40c178df2de26c4dd9a854a07c46d51e94760d15..e6aa39615b5c1ffa2302de835ffbeef210ac5df4 100644 (file)
@@ -1,6 +1,6 @@
 /*
- * Copyright (c) 1989 The Regents of the University of California.
- * All rights reserved.
+ * Copyright (c) 1989, 1993
+ *     The Regents of the University of California.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * Modified for Linux (which doesn\'t have snprintf()) by faith@cs.unc.edu
- * on Sun Mar  7 16:14:18 1993.
+ * Modified Sun Mar 12 10:39:22 1995, faith@cs.unc.edu for Linux
  *
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)ttymsg.c   5.8 (Berkeley) 7/1/91";
+static char sccsid[] = "@(#)ttymsg.c   8.2 (Berkeley) 11/16/93";
 #endif /* not lint */
 
 #include <sys/types.h>
@@ -51,18 +50,23 @@ static char sccsid[] = "@(#)ttymsg.c        5.8 (Berkeley) 7/1/91";
 #include <string.h>
 #include <stdlib.h>
 
+#ifdef __linux__
+#include "pathnames.h"
+#endif
+
 /*
- * Display the contents of a uio structure on a terminal.  Used by wall(1)
- * and syslogd(8).  Forks and finishes in child if write would block, waiting
- * at most five minutes.  Returns pointer to error string on unexpected error;
- * string is not newline-terminated.  Various "normal" errors are ignored
- * (exclusive-use, lack of permission, etc.).
+ * Display the contents of a uio structure on a terminal.  Used by wall(1),
+ * syslogd(8), and talkd(8).  Forks and finishes in child if write would block,
+ * waiting up to tmout seconds.  Returns pointer to error string on unexpected
+ * error; string is not newline-terminated.  Various "normal" errors are
+ * ignored (exclusive-use, lack of permission, etc.).
  */
 char *
-ttymsg(iov, iovcnt, line)
+ttymsg(iov, iovcnt, line, tmout)
        struct iovec *iov;
        int iovcnt;
        char *line;
+       int tmout;
 {
        static char device[MAXNAMLEN] = _PATH_DEV;
        static char errbuf[1024];
@@ -70,13 +74,25 @@ ttymsg(iov, iovcnt, line)
        struct iovec localiov[6];
        int forked = 0;
 
-       if (iovcnt > 6)
+       if (iovcnt > sizeof(localiov) / sizeof(localiov[0]))
                return ("too many iov's (change code in wall/ttymsg.c)");
+
+       (void) strcpy(device + sizeof(_PATH_DEV) - 1, line);
+       if (strchr(device + sizeof(_PATH_DEV) - 1, '/')) {
+               /* A slash is an attempt to break security... */
+#ifdef __linux__
+               (void) sprintf(errbuf, "'/' in \"%s\"", device);
+#else
+               (void) snprintf(errbuf, sizeof(errbuf), "'/' in \"%s\"",
+                   device);
+#endif
+               return (errbuf);
+       }
+
        /*
         * open will fail on slip lines or exclusive-use lines
         * if not running as root; not an error.
         */
-       (void) strcpy(device + sizeof(_PATH_DEV) - 1, line);
        if ((fd = open(device, O_WRONLY|O_NONBLOCK, 0)) < 0) {
                if (errno == EBUSY || errno == EACCES)
                        return (NULL);
@@ -100,7 +116,7 @@ ttymsg(iov, iovcnt, line)
                if (wret >= 0) {
                        left -= wret;
                        if (iov != localiov) {
-                               bcopy(iov, localiov, 
+                               bcopy(iov, localiov,
                                    iovcnt * sizeof(struct iovec));
                                iov = localiov;
                        }
@@ -139,14 +155,14 @@ ttymsg(iov, iovcnt, line)
                                return (NULL);
                        }
                        forked++;
-                       /* wait at most 5 minutes */
+                       /* wait at most tmout seconds */
                        (void) signal(SIGALRM, SIG_DFL);
                        (void) signal(SIGTERM, SIG_DFL); /* XXX */
                        (void) sigsetmask(0);
-                       (void) alarm((u_int)(60 * 5));
+                       (void) alarm((u_int)tmout);
                        (void) fcntl(fd, O_NONBLOCK, &off);
                        continue;
-               } 
+               }
                /*
                 * We get ENODEV on a slip line if we're running as root,
                 * and EIO if the line just went away.
index 23d84ad69dea72c5cfc8810353dc4240e0590cb1..b2786d0e5ee9b890b7b52062a9ebda35c69a1b7c 100644 (file)
@@ -30,7 +30,7 @@
 .\" SUCH DAMAGE.
 .\"
 .\"     from: @(#)vipw.8       6.7 (Berkeley) 3/16/91
-.\"    vipw.8,v 1.1.1.1 1995/02/22 19:09:25 faith Exp
+.\"    $Id: vipw.8,v 1.2 1995/03/12 01:33:13 faith Exp $
 .\"
 .Dd March 16, 1991
 .Dt VIPW 8
index f36df5f2e84d81f3756171b37d7e8e1fcbf51f6d..681d9a658d1ddf966ed328a87aa104feefd69d53 100644 (file)
  * 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.
+ *
+ * Updated Thu Oct 12 09:56:55 1995 by faith@cs.unc.edu with security
+ * patches from Zefram <A.Main@dcs.warwick.ac.uk>
+ *
  */
 
 #ifndef lint
@@ -39,7 +43,7 @@ char copyright[] =
 
 #ifndef lint
 /*static char sccsid[] = "from: @(#)vipw.c     5.16 (Berkeley) 3/3/91";*/
-static char rcsid[] = "vipw.c,v 1.1.1.1 1995/02/22 19:09:25 faith Exp";
+static char rcsid[] = "$Id: vipw.c,v 1.4 1995/10/12 14:46:36 faith Exp $";
 #endif /* not lint */
 
 #include <sys/types.h>
@@ -115,7 +119,6 @@ pw_init()
 int
 pw_lock()
 {
-       static char path[MAXPATHLEN] = _PATH_PTMP;
        int lockfd, fd, ret;
        char *p;
 
@@ -131,11 +134,13 @@ pw_lock()
                    progname, _PATH_PASSWD, strerror(errno));
                exit(1);
        }
+#if 0 /* flock()ing is superfluous here, with the ptmp/ptmptmp system. */
        if (flock(lockfd, LOCK_EX|LOCK_NB)) {
                (void)fprintf(stderr,
                    "%s: the password file is busy.\n", progname);
                exit(1);
        }
+#endif
 
        if ((fd = open(_PATH_PTMPTMP, O_WRONLY|O_CREAT, 0644)) == -1) {
                (void)fprintf(stderr,
@@ -162,8 +167,9 @@ pw_lock()
 void
 pw_unlock()
 {
-       (void)unlink(_PATH_PASSWD);
-       if (link(_PATH_PTMP, _PATH_PASSWD) == -1) {
+       unlink(_PATH_PASSWD ".OLD");
+       link(_PATH_PASSWD, _PATH_PASSWD ".OLD" );
+       if (rename(_PATH_PTMP, _PATH_PASSWD) == -1) {
            (void)fprintf(stderr, 
            "%s: can't unlock %s: %s (your changes are still in %s)\n", 
            progname, _PATH_PASSWD, strerror(errno), _PATH_PTMP);
@@ -183,7 +189,7 @@ pw_edit(notsetuid)
 
        if (!(editor = getenv("EDITOR")))
                editor = _PATH_VI;
-       if ((p = strrchr(editor, '/')) != NULL)
+       if ((p = strrchr(strtok(editor," \t"), '/')) != NULL)
                ++p;
        else 
                p = editor;
index b10badbac8f2103c1a767f6f1fa5ae47c3c6e002..7f3e6123553ea26ba23ae5da29d72fb5f4d20077 100644 (file)
@@ -1,6 +1,6 @@
 /*
- * Copyright (c) 1988, 1990 Regents of the University of California.
- * All rights reserved.
+ * Copyright (c) 1988, 1990, 1993
+ *     The Regents of the University of California.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * Modified for Linux, Mon Mar  8 18:08:30 1993, faith@cs.unc.edu
+ * Modified Sun Mar 12 10:34:34 1995, faith@cs.unc.edu, for Linux
  */
 
 #ifndef lint
-char copyright[] =
-"@(#) Copyright (c) 1988 Regents of the University of California.\n\
- All rights reserved.\n";
+static char copyright[] =
+"@(#) Copyright (c) 1988, 1990, 1993\n\
      The Regents of the University of California.  All rights reserved.\n";
 #endif /* not lint */
 
 #ifndef lint
-static char sccsid[] = "@(#)wall.c     5.14 (Berkeley) 3/2/91";
+static char sccsid[] = "@(#)wall.c     8.2 (Berkeley) 11/16/93";
 #endif /* not lint */
 
 /*
@@ -52,11 +52,20 @@ static char sccsid[] = "@(#)wall.c  5.14 (Berkeley) 3/2/91";
 #include <sys/stat.h>
 #include <sys/time.h>
 #include <sys/uio.h>
-#include <utmp.h>
+
+#include <paths.h>
 #include <pwd.h>
 #include <stdio.h>
 #include <stdlib.h>
-#include <paths.h>
+#include <string.h>
+#include <unistd.h>
+#include <utmp.h>
+#ifdef __linux__
+#include <locale.h>
+#include "pathnames.h"
+#endif
+
+void   makemsg __P((char *));
 
 #define        IGNOREUSER      "sleeper"
 
@@ -65,6 +74,7 @@ int mbufsize;
 char *mbuf;
 
 /* ARGSUSED */
+int
 main(argc, argv)
        int argc;
        char **argv;
@@ -75,7 +85,12 @@ main(argc, argv)
        struct utmp utmp;
        FILE *fp;
        char *p, *ttymsg();
+       char line[sizeof(utmp.ut_line) + 1];
 
+#ifdef __linux__
+       setlocale(LC_CTYPE,"");
+#endif
+       
        while ((ch = getopt(argc, argv, "n")) != EOF)
                switch (ch) {
                case 'n':
@@ -94,11 +109,6 @@ usage:
        if (argc > 1)
                goto usage;
 
-#ifdef __linux__
-       if (argc != 1)
-             makemsg("");
-       else
-#endif
        makemsg(*argv);
 
        if (!(fp = fopen(_PATH_UTMP, "r"))) {
@@ -114,14 +124,17 @@ usage:
                        continue;
 #ifdef __linux__
                if (utmp.ut_type != USER_PROCESS)
-                     continue;
+                  continue;
 #endif
-               if (p = ttymsg(&iov, 1, utmp.ut_line))
+               strncpy(line, utmp.ut_line, sizeof(utmp.ut_line));
+               line[sizeof(utmp.ut_line)] = '\0';
+               if ((p = ttymsg(&iov, 1, line, 60*5)) != NULL)
                        (void)fprintf(stderr, "wall: %s\n", p);
        }
        exit(0);
 }
 
+void
 makemsg(fname)
        char *fname;
 {
@@ -167,20 +180,27 @@ makemsg(fname)
        }
        (void)fprintf(fp, "%79s\r\n", " ");
 
-       if (*fname && !(freopen(fname, "r", stdin))) {
+       if (fname && !(freopen(fname, "r", stdin))) {
                (void)fprintf(stderr, "wall: can't read %s.\n", fname);
                exit(1);
        }
        while (fgets(lbuf, sizeof(lbuf), stdin))
-               for (cnt = 0, p = lbuf; ch = *p; ++p, ++cnt) {
+               for (cnt = 0, p = lbuf; (ch = *p) != '\0'; ++p, ++cnt) {
                        if (cnt == 79 || ch == '\n') {
                                for (; cnt < 79; ++cnt)
                                        putc(' ', fp);
                                putc('\r', fp);
                                putc('\n', fp);
                                cnt = 0;
-                       } else
-                               putc(ch, fp);
+                       } else {
+                          /* Test for control chars added Fri Mar 10
+                             19:49:30 1995, faith@cs.unc.edu */
+                          if (!isprint(ch) && !isspace(ch) && ch != '\007') {
+                             putc('^', fp);
+                             putc(ch^0x40,fp); /* DEL to ?, others to alpha */
+                          } else
+                             putc(ch, fp);
+                       }
                }
        (void)fprintf(fp, "%79s\r\n", " ");
        rewind(fp);
diff --git a/makedev-1.4.1/LEGAL.NOTICE b/makedev-1.4.1/LEGAL.NOTICE
deleted file mode 100644 (file)
index 51ff410..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-(This license is based on one written by Ian F. Darwin.)
-
-This software is not subject to any export provision of the United
-States Department of Commerce, and may be exported to any country,
-planet, or star system.
-
-Permission is granted to any sentient being to use this software for
-any purpose on any computer system, and to alter it and redistribute
-it freely, subject to the following restrictions:
-
-1. The author is not responsible for the consequences of use of this
-   software, no matter how awful, even if they arise from flaws in it.
-
-2. The origin of this software must not be misrepresented, either by
-   explicit claim or by omission. Since few users ever read sources,
-   credits must appear in the documentation.
-
-3. Altered versions must be plainly marked as such, and must not be
-   misrepresented as being the original software. Since few users
-   ever read sources, credits must appear in the documentation.
-
-4. This notice may not be removed or altered.
diff --git a/makedev-1.4.1/MAKEDEV-C.8 b/makedev-1.4.1/MAKEDEV-C.8
deleted file mode 100644 (file)
index 6144278..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-.\" -*- nroff -*-
-.TH MAKEDEV 8 "January 1995" "Version 1.4"
-.SH NAME
-MAKEDEV \- create and maintain filesystem device entries
-.SH SYNOPSIS
-.B MAKEDEV
-[
-.I \-vcdnhV
-]
-device or device-group name(s)
-.SH DESCRIPTION
-.B MAKEDEV
-is used to maintain the special filesystem entries found in /dev. It
-creates, or optionally removes, one or more device entries. The names 
-and device numbers are defined in the DEVINFO file (q.v.);
-site-specific configuration is found in the file MAKEDEV.cfg. 
-.B MAKEDEV
-itself has no knowledge of device information.
-.SH OPTIONS
-.TP
-.I -v 
-Verbose mode; print out exactly what's being done.
-.TP
-.I -c
-Create; create the specified devices. [default]
-.TP
-.I -d
-Delete; remove the specified devices instead of creating them.
-.TP
-.I -n
-Do nothing; only print what would be done. Implies -v as well.
-.TP
-.I -h
-Print a usage message.
-.TP
-.I -V
-Print the version string.
-.SS " "
-The following targets are special:
-.TP
-.I update
-Run MAKEDEV in update mode. This reads the list of devices currently
-available from /proc/devices, and updates all entries in /dev to match
-the device numbers found there.
-.TP
-.I local
-Run MAKEDEV to create local devices. This option is obsolete and just
-prints a warning message. Use DEVINFO.local and MAKEDEV.cfg to achieve
-the same results.
-.SH FILES
-.TP 20
-.I /etc/devinfo
-If ./DEVINFO is not found
-.TP
-.I /etc/devinfo.local
-Alternate location for local info
-.TP
-.I /etc/makedev.cfg
-If ./MAKEDEV.cfg is not found
-.TP
-.I MAKEDEV.cache
-Cached data for `update'
-.TP
-.I /proc/devices
-The kernel's list of current devices
-.SH AUTHOR
-David A. Holland (dholland@husc.harvard.edu)
-.br
-.br
-Based on the older
-.B MAKEDEV
-shell script written by Nick Holloway.
-Additional ideas were contributed by Rik Faith.
-.SH NOTES
-The LALR(1) parser generator used to build makedev.c from makedev.syn
-is a commercial product. You won't be able to do a complete rebuild 
-unless you have it.
-.SH SEE ALSO
-.BR DEVINFO (5),
-.BR MAKEDEV.cfg (5)
diff --git a/makedev-1.4.1/Makefile b/makedev-1.4.1/Makefile
deleted file mode 100644 (file)
index 2902786..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-# Makefile -- Makefile for util-linux Linux utilities
-# Created: Sat Feb 11 13:47:13 1995
-# Revised: Wed Feb 22 16:09:38 1995 by faith@cs.unc.edu
-# Copyright 1992, 1993, 1994, 1995 Rickard E. Faith (faith@cs.unc.edu)
-#
-
-include ../MCONFIG
-
-# Where to put man pages?
-
-MAN5=          devinfo.5 makedev.cfg.5
-MAN8=          MAKEDEV-C.8
-
-# Where to put binaries?
-# See the "install" rule for the links. . .
-
-DEV=           MAKEDEV-C
-
-# Where to put data?
-
-FILES=         devinfo makedev.cfg
-
-all: $(DEV)
-
-%.o: %.c
-       $(CC) -c $(CFLAGS) $< -o $@
-
-# Rules for everything else
-
-MAKEDEV-C: makedev.o
-       $(CC) $(LDFLAGS) $< -o $@
-
-install: all
-       $(INSTALLDIR) $(DEVDIR) $(ETCDIR)
-       $(INSTALLDAT) $(FILES) $(ETCDIR)
-       $(INSTALLBIN) $(DEV) $(DEVDIR)
-       $(INSTALLDIR) $(MAN5DIR) $(MAN8DIR)
-       $(INSTALLMAN) $(MAN5) $(MAN5DIR)
-       $(INSTALLMAN) $(MAN8) $(MAN8DIR)
-
-.PHONY:        clean
-clean:
-       -rm -f *.o *~ core $(DEV)
diff --git a/makedev-1.4.1/README.MAKEDEV-C b/makedev-1.4.1/README.MAKEDEV-C
deleted file mode 100644 (file)
index 9ecb72b..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-
-Readme file for MAKEDEV-C:
-
-MAKEDEV is a program to create the special file entries found in /dev.
-MAKEDEV-C is a compiled binary that runs from a config file, called
-DEVINFO. The config file is intended to be fairly human-readable, as
-well as machine-readable.
-
-New in release 1.4.1:
-
-Substantial updates to DEVINFO. Most notably:
-       - hdc and hdd are now the drives on the 2nd IDE controller. 
-         This is NOT how it used to be, nor is it how the shell MAKEDEV
-         does it, but it's what the kernel source indicates is right.
-       - SCSI tapes were totally messed up in the last release.
-       - New and more appropriate QIC device names.
-       - Assorted fixes. (See DEVINFO itself for more details.)
-
-Some changes to the sample MAKEDEV.cfg:
-       - added a class "system" (root.system, mode 660)
-       - do not omit hdc and hdd by default, as they now mean
-         something more useful than they used to.
-
-    ----------------
-New in release 1.4:
-
-First general public release. 
-Wrote man pages.
-
-    ----------------
-
-Release 1.3:
-
-First tentative limited-distribution release.
-
diff --git a/makedev-1.4.1/THIS_VERSION_IS_ALTERED b/makedev-1.4.1/THIS_VERSION_IS_ALTERED
deleted file mode 100644 (file)
index 3c6d31d..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-This version of makedev-1.4 has been altered by Rik Faith
-(faith@cs.unc.edu) to fit in with the util-linux suite of programs.
-
-The Makefile was re-written, a few programs were re-named, and the group
-for printer was changed to daemon, to conform with the original MAKEDEV
-script.
diff --git a/makedev-1.4.1/devinfo b/makedev-1.4.1/devinfo
deleted file mode 100644 (file)
index a50458c..0000000
+++ /dev/null
@@ -1,343 +0,0 @@
-/*
- * DEVINFO: device information for MAKEDEV
- *
- * MANY THANKS to those who have sent in corrections - I don't have most
- * of the hardware listed in here, so it won't get fixed if nobody tells me.
- * Mail to: David A. Holland <dholland@husc.harvard.edu>
- *
- * Version 1.4: 21-Feb-94  Corrected proc entry for ibcs2.
- *              27-Feb-94  Make 12 VCs by default.
- * Version 1.3: 14-Feb-94  Corrections from perusing the 1.1.91 source tree.
- *    hd1[a-b] becomes hd[c-d]; see comments below.
- *    Corrected idecd entry. Added entry for Aztech cdrom.
- *    Corrected sbpcd entries. 
- *    Invented new [and better] names for the QIC tape entries.
- *    There appear to be up to 32 cyclades devices supported in 1.1.91.
- * Version 1.2: 14-Feb-94  Revisions snarfed from shell MAKEDEV 2.1.
- *    Added cyclades, idecd, apm, dcf, /proc entry for joysticks, 
- *    scanner becomes logiscan/m105scan/ac4096, some new audio devices,
- *    high-number floppy entries, scsi tapes+cds now go 0-7, 
- *    corrected a comment erroneously indicating fd4 was possible,
- *    removed default major numbers for cdu31a, pcaudio, ibcs2.
- * Version 1.1: 13-Feb-94  Corrected scsi tapes (which were totally wrong)
- * Version 1.0: 11-Dec-94  Initial version
- */
-
-/* ignore when /proc/devices mentions these: */
-/* (this is how it was before; couldn't we use mem? */
-ignore { mem, tty, pcmcia }
-
-/* make a batch called generic, standard set of stuff */
-batch generic {
-      std, fd0, fd1, hda, hdb, xda, xdb, sda, sdb,
-      ptyp, ptyq, ptyr, ptys, console, vts, serial,
-      busmice, printers, fd
-}
-
-// The "std" group - basic devices */
-char (std, 1) {
-       mem (kmem): 1
-       kmem (kmem): 2
-       null (public) : 3
-       port (kmem) : 4
-               zero (public) : 5
-       core -> "/proc/kcore"
-       full (public) : 7
-}
-block (std, 1) {
-       ram (disk) : 1
-}
-char (std, 5) {
-       tty (public) : 0
-}
-
-/* the "console" group - system console */
-char (consoles,4) {
-       console (cons) : 0       # /dev/console
-       tty0 (cons) : 0          # tty0 == console
-}
-
-/* VTs tty1-tty63 (tty0 is special) */
-/* group "vts" is tty1-8; "vts2" is the rest */
-char (vts, 4) tty[1-12] (tty) : 1
-char (vts2, 4) tty [13-63] (tty) : 9
-
-
-/* serial ports, ttyS0-ttyS63 and cua0-cua63 */
-/* group "serial" is just ttyS0-3 and cua0-3; "serial2" is the rest */
-char (serial, 4) ttyS[0-3]  (tty)     : 64
-char (serial2,4) ttyS[4-63] (tty)     : 64+4
-char (serial, 5) cua[0-3]   (dialout) : 64
-char (serial2,5) cua[4-63]  (dialout) : 64 + 4
-
-/* ptys: pty[pqrs][0-9a-f] and tty[pqrs][0-9][a-f] */
-/* grouped as ptyp, ptyq, ptyr, and ptys */
-char (ptyp, 4) {
-        ptyp[0x0-f] (pty) : 128+0*16
-        ttyp[0x0-f] (tty) : 192+0*16
-}
-char (ptyq, 4) {
-        ptyq[0x0-f] (pty) : 128+1*16
-        ttyq[0x0-f] (tty) : 192+1*16
-}
-char (ptyr, 4) {
-        ptyr[0x0-f] (pty) : 128+2*16
-        ttyr[0x0-f] (tty) : 192+2*16
-}
-char (ptys, 4) {
-        ptys[0x0-f] (pty) : 128+3*16
-        ttys[0x0-f] (tty) : 192+3*16
-}
-
-/* cyclades serial multiplexer */
-char (cyclades=ttyC, 19) {
-       ttyC[0-31] (tty) : 32
-}
-char (cyclades=cub, 20) {
-       cub[0-31] (dialout) : 32
-}
-
-/* parallel ports par0-3 and printers lp0-3 (which are merely aliases) */
-/* group is "printers" */
-char (printers=lp, 6) {
-       par[0-3] (printer) : 0
-       lp[0-3] (printer) : 0
-}
-
-/* busmice: logibm, psaux, inportbm, atibm */
-char (busmice=mouse, 10) {
-       logibm   (mouse) : 0
-       psaux    (mouse) : 1
-       inportbm (mouse) : 2
-       atibm    (mouse) : 3
-       # sejin  (mouse) : 4
-}
-
-/* joysticks: js0, js1; group "js" */
-char (js=Joystick) js[0-1] (mouse) : 0
-
-/* floppies: fd0-3, with lots of modes */
-block (floppies=fd, 2) {
-       fd[0-3]       (floppy) : 0
-       fd[0-3]d360   (floppy) : 4
-       fd[0-3]h1200  (floppy) : 8
-       fd[0-3]D360   (floppy) : 12
-       fd[0-3]H360   (floppy) : 12
-       fd[0-3]D720   (floppy) : 16
-       fd[0-3]H720   (floppy) : 16
-       fd[0-3]h360   (floppy) : 20
-       fd[0-3]h720   (floppy) : 24
-       fd[0-3]H1440  (floppy) : 28
-       fd[0-3]H2880  (floppy) : 32
-       fd[0-3]CompaQ (floppy) : 36
-       fd[0-3]h1440  (floppy) : 40
-       fd[0-3]H1680  (floppy) : 44
-       fd[0-3]h410   (floppy) : 48
-       fd[0-3]H820   (floppy) : 52
-       fd[0-3]H1476  (floppy) : 56
-       fd[0-3]H1722  (floppy) : 60
-       fd[0-3]h420   (floppy) : 64
-       fd[0-3]h830   (floppy) : 68
-       fd[0-3]h1494  (floppy) : 72
-       fd[0-3]h1743  (floppy) : 76
-}
-
-// There is a controversy regarding whether these should be either
-//  (1) hda-hdd are major number 3, hda1-hd1d are major number 22
-//  (2) hda-hdb are major number 3, hdc-hdd are major number 22
-//
-// Case (1) is commented out, as case (2) seems to be more popular.
-// Case (2) also appears to make more sense in terms of the way
-// the drivers are actually implemented.
-
-// /* AT hard disks hda-hdd (partitions 1-8 and main) */
-// block(hd=hd,3) hd[a-d] 8/64
-// /* AT hard disks on second controller */
-// block(hd1,22) hd1[a-d] 8/64
-
-/* AT hard disks hda-b (partitions 1-8 and main) */
-block(hd=hd,3) hd[a-b] 8/64
-/* and 2nd controller */
-block(hd1,22) hd[c-d] 8/64
-
-// Ordinarily, the use of the syntax above would automatically create
-// this batch. Because of the way it's done (this is a bug, and hopefully
-// will be fixed in a future release) the batch for the hd1 devices is
-// also created as "hd". This cannot be accessed, but does no harm as
-// long as the order of the above two declarations isn't reversed. sigh.
-// Anyway, this line works around the problem.
-batch hd1 { hdc hdd }
-
-
-/* XT hard drives */
-block(xd=xd,13) xd[a-d] 8/64
-
-/* scsi hard disks sda-sdh */
-block(sd=sd,8) sd[a-h] 8/16
-
-/* loopback disk devices; group "loop" */
-block(loop=loop) loop[0-7] (disk) : 0
-
-/* scsi tapes st0-7 */
-char(st=st, 9) {
-       st[0-7] (tape) : 0
-       nst[0-7] (tape) : 128
-}
-
-/* qic tapes - group "qic" */
-// The following is what came with the shell MAKEDEV.
-//char (qic=tpqic02, 12) {
-//     rmt8       (tape) : 6
-//     rmt16      (tape) : 8
-//     tape-d     (tape) : 136
-//     tape-reset (tape) : 255
-//}
-// This, on the other hand, appears to be more correct.
-
-/*
- *  By the authority vested in me as the maintainer of this file, 
- *  I have made up the device names. The "n" versions don't rewind,
- *  as with other tape devices. The number specifies the model/capacity.
- *  There's not really room left for unit numbers, but I suppose there
- *  probably aren't many people with multiple QIC drives either...
- */
-char (qic=tpqic02, 12) {
-       nqt11   (tape) : 2
-       qt11    (tape) : 3
-       nqt24   (tape) : 4
-       qt24    (tape) : 5
-       nqt120  (tape) : 6
-       qt120   (tape) : 7
-       nqt150  (tape) : 8
-       qt150   (tape) : 9
-       qt-reset (tape) : 255
-}
-
-/* ftapes - group ftape */
-char (ftape=mt, 27) {
-       rft[0-3]  (tape) : 0
-       nrft[0-3] (tape) : 4
-       ftape -> rft0
-       nftape -> nrft0
-}
-
-/* scsi cd */
-block(sr=sr, 11) scd[0-7] (cdrom) : 0
-
-/* sony cd */
-block(sonycd=cdu31a) sonycd (cdrom) : 0
-
-/* mitsumi cd */
-block(mcd=mcd, 23) mcd (cdrom) : 0
-
-/* Sony cdu535 */
-block(cdu535="cdu-535", 24) cdu535 (cdrom) : 0
-
-/* LMS/Philips CD player (needs new major number) */
-block(lmscd, 24) lmscd (cdrom) : 0
-
-/* Aztech CDROM */
-block(aztcd, 29) aztcd0 (cdrom) : 0
-
-/* soundblaster CD, 1st controller */
-block(sbpcd=sbpcd, 25) {
-       sbpcd      (cdrom) : 0
-       sbpcd[0-3] (cdrom) : 0
-}
-/* 2nd, 3rd, 4th */
-block(sbpcd=sbpcd2, 26) sbpcd[4-7] (cdrom) : 0
-block(sbpcd=sbpcd3, 27) sbpcd[8-11] (cdrom) : 0
-block(sbpcd=sbpcd4, 28) sbpcd[12-15] (cdrom) : 0
-
-/* ide cd */
-block (idecd=idecd) {
-       idecd   (cdrom) : 0
-}
-
-/* Logitech scanner */
-char (logiscan=logiscan) {
-       logiscan (scanner) : 0
-}
-
-char (m105scan=m105) {
-       m105scan (scanner) : 0
-}
-
-char (ac4096=ac4096) {
-       ac4096 (scanner) : 0
-}
-
-// this is apparently obsolete?
-//char (scan=Scanner) {
-//     scan  (scanner) : 0
-//     scand (scanner) : 1
-//}
-
-/* audio */
-char (audio=sound, 14) {
-       mixer     (audio) : 0
-       sequencer (audio) : 1
-       midi00    (audio) : 2
-       midi -> midi00
-       dsp       (audio) : 3
-       audio     (audio) : 4
-       sndstat   (audio) : 6
-#      sequencer2(audio) : 8
-       mixer1    (audio) : 16
-#      patmgr0   (audio) : 17
-       midi01    (audio) : 18
-       dsp1      (audio) : 19
-       audio1    (audio) : 20
-#      patmgr1   (audio) : 33
-       midi02    (audio) : 34
-       midi03    (audio) : 50
-}
-
-/* pcaudio */
-char (pcaudio=pcsp) {
-       pcmixer (audio) : 0
-       pcsp    (audio) : 3
-       pcaudio (audio) : 4
-}
-
-/* sg: generic scsi devices */
-char (sg=sg, 21) {
-       sga (scsi) : 0
-       sgb (scsi) : 1
-       sgc (scsi) : 2
-       sgd (scsi) : 3
-       sge (scsi) : 4
-       sgf (scsi) : 5
-       sgg (scsi) : 6
-       sgh (scsi) : 7
-}
-
-/* fd: file descriptors */
-char (fd, 0) {  // the 0 is not used - there are only links in here!
-       fd     -> "/proc/self/fd"
-       stdin  -> "fd/0"
-       stdout -> "fd/1"
-       stderr -> "fd/2"
-}
-
-/* ibcs2: coff emulation stuff */
-char (ibcs2=socksys, 30) {
-       socksys (ibcs2) : 0
-       spx     (ibcs2) : 2
-       nfsd -> socksys
-       XOR -> null
-}
-
-char (apm=apm_bios) {
-       apm (system) : 0
-}
-
-char (dcf=dcf) {
-       dcf (system) : 0
-}
-
-/* demo device for module stuff */
-char (hw=hw) {
-       helloworld (public) : 0
-}
-
diff --git a/makedev-1.4.1/devinfo.5 b/makedev-1.4.1/devinfo.5
deleted file mode 100644 (file)
index 4818631..0000000
+++ /dev/null
@@ -1,122 +0,0 @@
-.\" -*- nroff -*-
-.TH DEVINFO 5 "January 1995" "Version 1.4"
-.SH NAME
-DEVINFO \- device entry database
-.SH DESCRIPTION
-.B DEVINFO 
-is a text file that describes all the possible devices for a system.
-It is used by
-.BR MAKEDEV (8)
-to create special file entries in 
-.BR /dev .
-It may be named either
-.BR /dev/DEVINFO " or " /etc/devinfo .
-Information about custom local devices, if any, should be placed in
-.BR DEVINFO.local " or " /etc/devinfo.local ,
-which has the same syntax.
-.LP
-The file format is free-form. Both C, C++, and shell comments are
-understood. There are basically four statements:
-.TP
-.RI "ignore { " proc-device... " }"
-This causes the specified names to be ignored if found in
-.BR /proc/devices .
-.TP
-.RI "batch { " device... " }"
-This creates a "batch" \- a collection of devices which will all be
-created when the batch is invoked. For example, in the standard 
-.BR DEVINFO ,
-"generic" is a batch.
-.TP
-.RI "block " device-spec
-This defines one or more block devices.
-.TP
-.RI "char " device-spec
-This defines one or more character devices.
-.LP
-Here is a sample
-.IR device-spec :
-.RS
-.nf
-(std, 1) {
-    mem (kmem) : 1
-    null (public) : 3
-    core -> "/proc/kcore"
-}
-.fi
-.RE
-.LP
-This example defines a group of devices called "std", with major
-number 1. Running
-.B "\"MAKEDEV std\""
-will create all the devices in the group; running, for example,
-.B "\"MAKEDEV null\""
-would make just the one device "null".
-.LP
-It is possible to specify, instead of just "std", something like
-"std=foo". In this case, the stuff on the right-hand side of the
-equals sign specifies a name from 
-.BR /proc/devices ,
-and the major number will be retrieved from there if present. If an
-entry from 
-.BR /proc/devices
-is specified, the explicit major number may be omitted. In this case,
-if the number is not found in /proc/devices, attempts to create the
-device will be rejected.
-.LP
-Inside the braces is a list of specific devices. The name in
-parenthesis is the "class" - this is something specified in 
-.B MAKEDEV.cfg
-(q.v.) that determines the ownership and permissions of the special
-file created. In the above example, the device "mem" was set to have
-the class "kmem", but "null" was set to be "public". Ordinarily you'd
-define "public" to be mode 666, but "kmem" to be mode 660 and owned by
-group kmem. The number after the colon is the minor number for this
-particular device \- for instance, 3 for "null".
-.LP
-You may also specify a symbolic link with "->". For instance, above,
-"core" was made a link to 
-.BR /proc/kcore .
-Note that names may contain any characters, but names that contain
-things other than alphanumerics, dash, and underscore should be put in
-double quotes.
-.LP
-An entire range of devices can be created: you may specify a range of
-numbers in brackets, like this:
-.RS
-.nf
-
-tty[1-8] (tty) : 1
-
-.fi
-.RE
-This creates tty1\-tty8 with minor device numbers starting with 1.
-If you specify the range in hex (prefixed by 0x) the device names will
-be created numbered in hex, as is normal for ptys. The range may
-appear inside the name string, but there may only be one range.
-.LP
-There is a special syntax for creating the entire banks of devices for
-a hard drive:
-.RS
-.nf
-
-    hd[a-d] 8/64
-
-.fi
-.RE
-What this means is as follows: create hda, and 8 partitions on hda
-(hda1 through hda8), starting with minor number 0. Then create hdb,
-and 8 partitions, starting with minor number 64. Then hdc, etc., with
-minor number 64*2 = 128. And so forth. These are automatically placed
-in the class "disk". The necessary groups and batches are created so
-you can ask 
-.B MAKEDEV
-to create "hd" or "hda" or "hda1" and expect it to do the correct
-thing. 
-.LP
-Note that simple arithmetic is permitted for specifying the minor
-device number, as this often makes things much clearer and less likely
-to be accidentally broken.
-.SH "SEE ALSO"
-.BR MAKEDEV (8),
-.BR MAKEDEV.cfg (5)
diff --git a/makedev-1.4.1/makedev.c b/makedev-1.4.1/makedev.c
deleted file mode 100644 (file)
index 59f16e0..0000000
+++ /dev/null
@@ -1,2296 +0,0 @@
-/*
- * makedev.c: Generate /dev entries
- *
- * Based on the MAKEDEV shell script, version 2.0, distributed with
- * util-linux 1.10 and written by Nick Holloway. 
- *
- * A number of bugs were fixed, and some additional features added.
- * Written 10-Dec-94 by David A. Holland, dholland@husc.harvard.edu
- *
- * Copyright 1994, 1995. All rights reserved. 
- * See the file LEGAL.NOTICE for conditions of redistribution.
- *
- * Bugs:
- *    None known right now.
- *
- * History:
- *
- * Version 1.4a: Sun Feb 26 18:08:45 1995, faith@cs.unc.edu
- *               Forced devinfo and makedev to be in /etc
- * Version 1.4: 15-Jan-95  Wrote man pages. Now reads DEVINFO.local.
- * Version 1.3: 31-Dec-94  Bug fixes. Added batches. Added omits.
- * Version 1.2: 11-Dec-94  Add configuration file parsing.
- * Version 1.1: 11-Dec-94  Distinguish block and character devices in the
- *    table of major device numbers. Changed the name and format of the
- *    update cache file to include the type. It appears that the old script
- *    was broken in this regard.
- * Version 1.0: 10-Dec-94  Initial version.
- */
-
-static const char *version = "MAKEDEV-C version 1.4a";
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdarg.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <pwd.h>
-#include <grp.h>
-#include <sys/stat.h>
-
-#define YES 1
-#define NO 0
-
-static int isverbose=NO;  /* flag: print out what we do? */
-static int deletion=NO;   /* flag: delete instead of create */
-static int donothing=NO;  /* flag: don't actually do anything */
-
-/*
- * Proto for main operative function.
- */
-typedef enum { M_CREATE, M_OMIT } makeopts;
-static void make(const char *batch_or_grp_or_devname, makeopts);
-
-/*
- * Roll over and die.
- */
-static void crash(const char *msg) {
-  fprintf(stderr, "MAKEDEV: %s\n", msg);
-  exit(1);
-}
-
-/*
- * Print a warning.
- */
-static void warn(const char *format, ...) {
-  va_list ap;
-  va_start(ap, format);
-  fprintf(stderr, "MAKEDEV: ");
-  vfprintf(stderr, format, ap);
-  fprintf(stderr, "\n");
-  va_end(ap);
-}
-
-/*
- * Translate string name to uid.
- */
-static uid_t name2uid(const char *name) {
-  struct passwd *p = getpwnam(name);
-  if (!p) warn("undefined user: %s, using uid 0", name);
-  return p ? p->pw_uid : 0;  /* make things owned by root by default */
-}
-
-/*
- * Translate string name to gid.
- */
-static gid_t name2gid(const char *name) {
-  struct group *g = getgrnam(name);
-  if (!g) warn("undefined group: %s, using gid 0", name);
-  return g ? g->gr_gid : 0;  /* group 0 is a good default too */
-}
-
-/*
- * Proto for parser.
- */
-static void doparse(FILE *f, int filetype, const char *filename);
-
-/************************* device classes *************************/
-
-/*
- * A device class is a string attached to the device which tells us
- * what set of permissions and ownership should be used. This is the
- * table of classes.
- */
-
-typedef struct {
-    const char *classname;
-    const char *owner;
-    const char *group;
-    int mode;
-} devclass;
-
-#define MAXCLASSES 32
-static devclass classes[MAXCLASSES];
-static int nclasses=0;
-
-static void addclass(const char *name, const char *o, const char *g, int m) {
-  if (nclasses>=MAXCLASSES) crash("out of space for device classes");
-  classes[nclasses].classname = name;
-  classes[nclasses].owner = o;
-  classes[nclasses].group = g;
-  classes[nclasses].mode = m;
-  nclasses++;
-  name2uid(o);  /* check for undefined users/groups */
-  name2gid(g);
-}
-
-static void loadclasses(void) {
-  FILE *f = fopen("/etc/makedev.cfg", "r");
-  if (!f) crash("can't find makedev.cfg");
-  doparse(f, 4, "makedev.cfg");
-  fclose(f);
-}
-
-/*
- * Return the index into the above table for a particular class name.
- */
-static int which_class(const char *name) {
-  int i;
-  for (i=0; i<nclasses; i++)
-    if (!strcmp(classes[i].classname, name)) return i;
-  return 0;
-}
-
-/*
- * Produce an "ls -l"-ish mode string.
- */
-static const char *modestring(int mode) {
-  static char rv[12];
-  int i,z;
-  strcpy(rv, "rwxrwxrwx");
-  for (i=8,z=1; i>=0; i--, z<<=1) if (!(mode&z)) rv[i]='-';
-  return rv;
-}
-
-/*
- * Create (or delete, or update) a block or character device.
- */
-static void class_makedev(const char *name, const char *class,
-                         int major, int minor, char type) {
-  int x = which_class(class), mode = classes[x].mode;
-  const char *owner = classes[x].owner, *group = classes[x].group;
-  if (isverbose) {
-    if (deletion) printf("rm -f %s\n", name);
-    else printf("%c%s   1 %-8s %-8s %3d, %3d for %s\n", type,
-               modestring(mode), owner, group, major, minor, name);
-  }
-  if (donothing) return;
-  if (unlink(name) && deletion) warn("Couldn't remove %s\n", name);
-  if (!deletion) {
-    dev_t q = (major<<8) | minor;
-    if (mknod(name, type=='c' ? S_IFCHR : S_IFBLK,  q) ||
-       chown(name, name2uid(owner), name2gid(group)) ||
-       chmod(name, mode)) {
-      warn("couldn't create %s: %s", name, strerror(errno));
-    }
-  }
-}
-
-/************************* major number list *************************/
-
-/*
- * In Linux device major numbers can be allocated dynamically, so we go
- * look in /proc/devices to see what they are. This keeps track of things.
- */
-
-typedef struct {
-    const char *procname;
-    int flag;
-} majorentry;
-
-#define MAXMAJORS 256
-static majorentry cmajors[MAXMAJORS];  /* initialized to 0 */
-static majorentry bmajors[MAXMAJORS];  /* initialized to 0 */
-static int no_proc=0;   /* true if we didn't find /proc/devices */
-
-/*
- * Store the name associated with a particular major device number.
- */
-static void set_major(const char *procname, int ischar, int num) {
-  if (num<0 || num>255) {
-    warn("warning: got bogus major number %d for %s", num, procname);
-    return;
-  }
-  if (ischar) cmajors[num].procname=procname;
-  else bmajors[num].procname=procname;
-}
-
-/*
- * Look up a major device number by name; return the default value
- * if provided. A default value of -1 implies the device is only
- * dynamic, and so if there's no entry we shouldn't even note its
- * existence.
- */
-static int get_major(const char *procname, int ischar, int defaalt) {
-  int i;
-  if (!procname) return defaalt;
-  if (ischar) {
-    for (i=0; i<MAXMAJORS; i++)
-      if (cmajors[i].procname && !strcmp(cmajors[i].procname, procname))
-       return i;
-  }
-  else {
-    for (i=0; i<MAXMAJORS; i++)
-      if (bmajors[i].procname && !strcmp(bmajors[i].procname, procname))
-       return i;
-  }
-  return defaalt;
-}
-
-/*
- * Read /proc/devices.
- */
-static void setup_majors(void) {
-  FILE *f = fopen("/proc/devices", "r");
-  if (!f) {
-    fprintf(stderr, "MAKEDEV: warning: can't read /proc/devices\n");
-    no_proc = 1;
-    return;
-  }
-  doparse(f, 1, "/proc/devices");
-  fclose(f);
-}
-
-/************************** procname list *************************/
-
-/*
- * The names found in /proc/devices aren't usually quite the same
- * as the names we use. This is a mapping between the two namespaces.
- */
-typedef struct {
-    const char *procname;
-    const char *groupname;
-} namealias;
-
-#define MAXALIASES 100
-static namealias aliases[MAXALIASES];
-static int naliases=0;
-
-static void addalias(const char *procname, const char *groupname) {
-  if (naliases>=MAXALIASES) crash("out of space for aliases");
-  aliases[naliases].procname = procname;
-  aliases[naliases].groupname = groupname;
-  naliases++;
-}
-
-static void ignore_procname(const char *procname) {
-  addalias(procname, NULL);
-}
-
-static const char *procnameof(const char *groupname) {
-  int i;
-  for (i=0; i<naliases; i++) if (!strcmp(groupname, aliases[i].groupname))
-    return aliases[i].procname;
-  return NULL;
-}
-
-static const char *groupnameof(const char *procname) {
-  int i;
-  for (i=0; i<naliases; i++) if (!strcmp(procname, aliases[i].procname))
-    return aliases[i].groupname;
-  return NULL;
-}
-
-/************************* batch list *************************/
-/*
- * Create a device "batch" - a bunch of devices or groups.
- * This is used for "generic" and automatically for disk entries.
- * (Disk entries for "hd" come up with groups hda, hdb, etc., but
- * "hd" itself needs to run these too.)
- */
-#define MAXTARGETS 32
-#define MAXBATCHES 16
-
-typedef struct {
-    const char *name;  /* name of batch */
-    const char *targets[MAXTARGETS];
-    int ntargets;
-    int busy;
-} batch;
-
-static batch batches[MAXBATCHES];
-static int nbatches=0;
-
-/*
- * Start a new batch.
- */
-static batch *addbatch(const char *name) {
-  batch *b;
-  if (nbatches>=MAXBATCHES) crash("Out of space for batches");
-  b = &batches[nbatches++];
-  b->name = name;
-  b->busy = NO;
-  return b;
-}
-
-/*
- * Add something to a batch.
- */
-static batch *add2batch(batch *b, const char *target) {
-  if (b->ntargets>=MAXTARGETS) {
-    warn("Too many targets for batch %s (max %d)", b->name, MAXTARGETS);
-    return b;
-  }
-  b->targets[b->ntargets++] = target;
-  return b;
-}
-
-/*
- * Run a batch.
- */
-static void run_batch(const batch *b, makeopts m) {
-  int i;
-  for (i=0; i<b->ntargets; i++) make(b->targets[i], m);
-}
-
-/*
- * Try to run a batch; returns YES if it found one.
- */
-static int try_run_batch(const char *name, makeopts m) {
-  int i;
-  for (i=0; i<nbatches; i++) {
-    if (!strcmp(name, batches[i].name)) {
-      if (batches[i].busy) {
-       warn("Found recursive batch definition for %s", batches[i].name);
-       continue;
-      }
-      batches[i].busy=YES;
-      run_batch(&batches[i], m);
-      batches[i].busy=NO;
-      return YES;
-    }
-  }
-  return NO;
-}
-
-/************************* device list *************************/
-
-/*
- * Structure to remember the properties of an individual device.
- * NOTE: if the device is actually a symbolic link, the "class"
- * member is used to store the thing it should be linked to.
- */
-typedef struct {
-    const char *name;   /* file name to create */
-    const char *grp;    /* device "group" name (e.g. "busmice") */
-    const char *class;  /* device class ( -> owner and permissions) */
-    int major, minor;   /* device number */
-    char type;          /* 'c', 'b', or 'l' for symbolic link */
-    int omit;           /* don't make me if this is nonzero */
-} device;
-
-/*
- * Create a device (link or actual "special file") - special files are
- * passed on to class_makedev().
- */
-void makedev(device *d, makeopts m) {
-  if (m==M_OMIT) {
-    d->omit=1;
-  }
-  if (d->omit==1) return;
-  if (d->type=='l') {
-    if (isverbose) {
-      if (deletion) printf("rm -f %s\n", d->name);
-      else printf("lrwxrwxrwx   %s -> %s\n", d->name, d->class);
-    }
-    if (donothing) return;
-    if (unlink(d->name) && deletion) warn("Couldn't remove %s\n", d->name);
-    if (!deletion) {
-      if (symlink(d->class, d->name)) /* class holds thing pointed to */
-       warn("couldn't link %s -> %s: %s", d->name, d->class, strerror(errno));
-    }
-  }
-  else class_makedev(d->name, d->class, d->major, d->minor, d->type);
-}
-
-/*
- * Array of devices. We allocate it once from main(); it doesn't grow.
- * Should maybe make it growable sometime. This keeps track of all possible
- * devices. We build this thing first, and then create devices from it as
- * requested.
- */
-static device *devices = NULL;
-static int maxdevices, ndevices;
-
-/*
- * Allocate space for the device array.
- */
-static void allocate_devs(int nd) {
-  devices = malloc(nd * sizeof(device));
-  if (!devices) crash("Out of memory");
-  ndevices = 0;
-  maxdevices = nd;
-}
-
-/*
- * Check all the devices for having valid device classes.
- */
-static void check_classes(void) {
-  int i;
-  const char *q=NULL;
-  for (i=0; i<ndevices; i++) 
-    if (devices[i].type!='l' && !devices[i].omit &&
-       which_class(devices[i].class)<0) {
-      if (!q || strcmp(q, devices[i].class)) {
-       warn("Invalid device class %s for %s", 
-            devices[i].class, devices[i].name);
-       q = devices[i].class;
-      }
-      devices[i].class = "default";
-    }
-}
-
-/*
- * Create an entry in the device table for a single device.
- */
-static void init(const char *name, const char *grp, const char *class,
-                int major, int minor, int type) {
-  if (major < 0) return;
-  if (!strchr("bcl", type)) {
-    warn("invalid device type %c for %s (skipping)", type, name);
-    return;
-  }
-  if (ndevices>=maxdevices) crash("out of space for devices");
-  devices[ndevices].name = name;
-  devices[ndevices].grp = grp;
-  devices[ndevices].class = class;
-  devices[ndevices].major = major;
-  devices[ndevices].minor = minor;
-  devices[ndevices].type = type;
-  devices[ndevices].omit = 0;
-  ndevices++;
-}
-
-/*
- * Create an entry for a symbolic link "device", such as /dev/fd
- * (which is a symbolic link to /proc/self/fd)
- */
-static void initlink(const char *name, const char *grp, const char *target) {
-  init(name, grp, target, 0, 0, 'l');
-}
-
-/*
- * Init lots of devices. This creates a number of devices, numbered between
- * lo and hi. The idea is that "base" contains a %d or %x (or something like
- * that) in it which pulls in the number. The device group can also do this,
- * though this will in most cases not be useful. "baseminor" is the minor
- * number of the first device created.
- */
-static void initlots(const char *base, int lo, int hi, const char *grp,
-                    const char *class,
-                    int maj, int baseminor, int type) {
-  char buf[32], gbuf[32];
-  int i;
-  if (maj<0) return;
-  for (i=lo; i<hi; i++) {
-    sprintf(buf, base, i);
-    if (grp) sprintf(gbuf, grp, i);  /* grp is permitted to contain a %d */
-    init(strdup(buf), grp ? strdup(gbuf) : NULL, class, 
-        maj, baseminor+i-lo, type);
-  }
-}
-
-/*
- * Init a whole (hard) disk's worth of devices - given `hd', it makes
- * hda1...hda8 through hdd1...hdd8 in one fell swoop. "low" and "high"
- * are the letters to use ('a' and 'd' for the previous example).
- * "nparts" is the number of partitions to create, ordinarily 8.
- * "maj" is the major device number; minmult is the multiplier for the
- * minor number. That is, if hda starts at 0, and hdb starts at 64, minmult
- * is 64.
- *
- * Note that it creates "hda", "hdb", etc. too, and puts things in the
- * groups "hda", "hdb", etc. as appropriate. The class is set to "disk".
- */
-static void initdisk(const char *base, int low, int high, int nparts,
-             int maj, int minmult) {
-  char buf[16], buf2[16];
-  int i;
-  batch *b;
-  if (maj<0) return;
-  if (low>=high) return;
-  b = addbatch(base);
-  for (i=low; i<=high; i++) {
-    char *q;
-    sprintf(buf, "%s%c", base, i);
-    q = strdup(buf);
-    init(q, q, "disk", maj, (i-low)*minmult,   'b');
-    strcpy(buf2, buf);
-    strcat(buf2, "%d");
-    initlots(buf2, 1, nparts, buf, "disk", maj, (i-low)*minmult+1, 'b');
-    add2batch(b, q);
-  }
-}
-
-static void initdevs(void) {
-  FILE *f = fopen("/etc/devinfo", "r");
-  if (!f) crash("Can't find devinfo");
-  doparse(f,3, "devinfo");
-  fclose(f);
-  f = fopen("/etc/devinfo.local", "r");
-  if (!f) f = fopen("/usr/local/etc/devinfo.local", "r");
-  if (f) {
-    doparse(f,3, "devinfo.local");
-    fclose(f);
-  }
-}
-
-/************************** update *************************/
-
-/*
- * Call make() with our names for something that appeared in /proc/devices.
- */
-
-static void transmake(const char *procname, makeopts m) {
-  const char *gname = groupnameof(procname);
-  if (gname) make(gname, m);
-}
-
-/*
- * Update a device that appeared in MAKEDEV.cache. Whenever we update,
- * we save what we did into MAKEDEV.cache; this lets us avoid doing
- * them over the next time. We only do something if the device has
- * disappeared or the major number has changed.
- *
- * Note that this caching made the shell version go much faster (it took
- * around 15 seconds with the cache, vs. over a minute if the cache was
- * blown away.) For us, it still does, but it hardly matters: it shaves
- * one second off a two-second execution.
- *
- * Also note the old script used DEVICES instead of MAKEDEV.cache. We
- * changed because the old file didn't record whether something was
- * a block or character device; since the sets of numbers are independent,
- * this was bound to break.
- */
-static void update2(const char *name, int ischar, int major) {
-  int now = get_major(name, ischar, -1);
-  if (now<0) {
-    deletion = 1;   /* must have been zero if we're doing an update */
-    transmake(name, M_CREATE);
-    deletion = 0;
-  }
-  else if (now!=major) { /* oops, it moved; remake it */
-    transmake(name, M_CREATE);
-    if (ischar) cmajors[now].flag=1;
-    else bmajors[now].flag=1;
-  }
-  else {
-    if (ischar) cmajors[now].flag=1; /* unchanged; inhibit remaking it */
-    else bmajors[now].flag=1; /* unchanged; inhibit remaking it */
-  }
-}
-
-static void updatefromcache(const char *name, int major, int type) {
-  update2(name, type=='c', major);
-}
-
-
-/*
- * Update. Read the information stored in MAKEDEV.cache from the last
- * update; fix anything that changed; then create any new devices that
- * weren't listed the last time. (We use the "flag" field in the
- * majors array to check this.) At that point, write out a new
- * cache file.
- */
-#define CACHEFILE "MAKEDEV.cache"
-
-static void update(void) {
-  FILE *f;
-  int i;
-  if (no_proc) { warn("Couldn't read anything from /proc/devices"); return; }
-  if (deletion) { warn("update and -d are incompatible"); return; }
-  f = fopen(CACHEFILE, "r");
-  if (f) {
-    doparse(f, 2, CACHEFILE);
-    fclose(f);
-  }
-  for (i=0; i<MAXMAJORS; i++) {
-    if (cmajors[i].procname && !cmajors[i].flag) {
-      transmake(cmajors[i].procname, M_CREATE);
-      cmajors[i].flag=1;
-    }
-    if (bmajors[i].procname && !bmajors[i].flag) {
-      transmake(bmajors[i].procname, M_CREATE);
-      bmajors[i].flag=1;
-    }
-  }
-  if (donothing) return;
-  f = fopen(CACHEFILE, "w");
-  if (f) {
-    for (i=0; i<MAXMAJORS; i++)  {
-      if (cmajors[i].procname) fprintf(f, "%s %d char\n", cmajors[i].procname, i);
-      if (bmajors[i].procname) fprintf(f, "%s %d block\n", bmajors[i].procname, i);
-    }
-    fclose(f);
-  }
-  else warn("warning: can't write MAKEDEV.cache");
-}
-
-/************************* work *************************/
-
-/*
- * Create (or delete, etc. according to flags) a device or device group.
- * The "generic" group is handled specially by recursing once.
- * "update" is handled specially; see update() below.
- * "local" issues a warning; people should use DEVINFO.local instead.
- */
-static void make(const char *what, makeopts m) {
-  int i;
-  if (!strcmp(what, "update")) {
-    if (m!=M_CREATE) warn("update not compatible with those options");
-    else update();
-  }
-  else if (!strcmp(what, "local")) {
-    warn("The local target is obsolete.");
-  }
-  else if (!try_run_batch(what, m)) {
-    int found=0;
-    for (i=0; i<ndevices; i++) {
-      if ((devices[i].grp && !strcmp(what, devices[i].grp)) ||
-          !strcmp(what, devices[i].name)) {
-        makedev(&devices[i], m);
-        found = 1;
-      }
-    }
-    if (!found) warn("unknown device or device group %s", what);
-  }
-}
-
-/*
- * A major improvement over the shell version...
- */
-static void usage(void) {
-  printf("MAKEDEV-C usage:\n");
-  printf("    MAKEDEV-C [-vdcn] device [device...]\n");
-  printf("      -v                 Verbose output\n");
-  printf("      -d                 Remove specified devices\n");
-  printf("      -c                 Create devices (default)\n");
-  printf("      -n                 Don't actually do anything (implies -v)\n");
-  printf("      -V                 Print version information\n");
-  printf("\n");
-}
-
-/*
- * We should use getopt one of these days.
- */
-int main(int argc, char **argv) {
-  int i,j, done=0;
-  for (i=1; i<argc && argv[i][0]=='-' && !done; i++)
-    for (j=1; argv[i][j] && !done; j++) switch(argv[i][j]) {
-        case '-': done=1; break;
-       case 'v': isverbose = 1; break;
-       case 'd': deletion = 1; break;
-       case 'c': deletion = 0; break;
-       case 'n': donothing = 1; isverbose = 1; break;
-       case 'h': usage(); exit(0);
-       case 'V': printf("MAKEDEV-C: %s\n", version); exit(0);
-       default: fprintf(stderr, "MAKEDEV-C: unknown flag %c\n", argv[i][j]);
-         exit(1);
-    }
-  setup_majors();      /* read major device numbers from /proc */
-  allocate_devs(1500); /* make space to hold devices */
-  initdevs();          /* set up device structures */
-  loadclasses();       /* load device classes from config file */
-  check_classes();     /* make sure no devices have bogus classes */
-  if (i==argc) warn("didn't do anything; try -h for help.");
-  else for (; i<argc; i++) make(argv[i], M_CREATE);
-  return 0;
-}
-
-
-
-/*
-
- AnaGram Parsing Engine
- Copyright (c) 1993, Parsifal Software.
- All Rights Reserved.
- This module may be copied and/or distributed at the discretion of the
- AnaGram licensee.
-
-*/
-
-
-
-#ifndef MAKEDEV_H
-#include "makedev.h"
-#endif
-
-#include <ctype.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-#define RULE_CONTEXT (&((PCB).cs[(PCB).ssx]))
-#define ERROR_CONTEXT ((PCB).cs[(PCB).error_frame_ssx])
-#define CONTEXT ((PCB).cs[(PCB).ssx])
-
-
-
-parse_pcb_type parse_pcb;
-#define PCB parse_pcb
-
-#line 698 "/usr/local/src/makedev/makedev.syn"
-/************************* parsing support *************************/
-
-/*
- * Don't use the built-in error printing.
- */
-#define SYNTAX_ERROR
-#define PARSER_STACK_OVERFLOW
-#define REDUCTION_TOKEN_ERROR
-
-static void doparse(FILE *f, int filetype, const char *filename) {
-  char *x;
-  int i=0, len;
-  if (filetype<1 || filetype>4) crash("tried to parse a bad file type");
-  if (filetype!=1) { /* /proc/devices won't stat intelligently */
-    struct stat buf;
-    if (fstat(fileno(f), &buf)) crash("fstat failed?!?");
-    len = buf.st_size;
-  }
-  else len=1023;
-  x = malloc(len+1);
-  if (!x) crash("Out of memory");
-
-  len = fread(x, 1, len, f);  /* it shouldn't return a short count... */
-  if (len<0) crash("fread failed?!?");
-  x[len]=0;
-
-  init_parse();
-  PCB.input_code = filetype+'0';
-  parse();
-  PCB.column--; /* correct for the filetype token */
-  while (!PCB.exit_flag) {
-    PCB.input_code = x[i++];
-    parse();
-  }
-  if (PCB.exit_flag == AG_SYNTAX_ERROR_CODE) {
-    warn("syntax error: %s, line %d, column %d in file %s",
-         PCB.error_message, PCB.line, PCB.column, filename);
-    crash("Sorry, can't continue.");
-  }
-  else if (PCB.exit_flag != AG_SUCCESS_CODE) {
-    crash("parser stack overflow!");
-  }
-}
-
-#define STRINGSIZE 8192
-static char string_space[STRINGSIZE];
-static int stringptr=0;
-
-static const char *string_start(int c) {
-  if (stringptr>=STRINGSIZE) crash("out of string space");
-  return string_space[stringptr]=c, string_space+stringptr++;
-}
-
-static void string_push(int c) {
-  if (stringptr>=STRINGSIZE) crash("out of string space");
-  string_space[stringptr++] = c;
-}
-
-static void string_finish(void) {
-  string_push(0);
-}
-
-
-#line 790 "makedev.c"
-#line 840 "/usr/local/src/makedev/makedev.syn"
-  static const char *cur_group=NULL, *cur_class=NULL;
-  static int cur_type;
-  static int cur_maj=0, cur_min=0, cur_bot=0, cur_top=0, ishex=0;
-
-  static void dhsproc(const char *g, const char *p, int t, int m) {
-    cur_group = g;
-    cur_type = t;
-    cur_maj = get_major(p, (t=='c'), m);
-    cur_min = 0;
-    cur_bot = cur_top = ishex = 0;
-    if (p) addalias(p,g);
-  }
-
-  static void newdev(const char *n) {
-    if (cur_maj<0) return;
-    init(n, cur_group, cur_class, cur_maj, cur_min, cur_type);
-  }
-  static void devrange(const char *n, const char *n1) {
-    char temp[32];
-    if (cur_maj<0) return;
-    sprintf(temp, "%s%%d%s", n, n1 ? n1 : "");
-    initlots(temp, cur_bot, cur_top, cur_group, cur_class,
-            cur_maj, cur_min, cur_type);
-  }
-  static void doinitlink(const char *src, const char *tg) {
-    if (cur_maj>=0) initlink(src, cur_group, tg);
-  }
-
-#line 820 "makedev.c"
-#ifndef CONVERT_CASE
-#define CONVERT_CASE(c) (c)
-#endif
-#ifndef TAB_SPACING
-#define TAB_SPACING 8
-#endif
-
-#define ag_rp_1(n, s) (set_major(s,YES,n))
-
-#define ag_rp_2(n, s) (set_major(s,NO,n))
-
-#define ag_rp_3(n, maj, t) (updatefromcache(n,maj,t))
-
-#define ag_rp_4() ('b')
-
-#define ag_rp_5() ('c')
-
-#define ag_rp_8(n, i) (add2batch(addbatch(n), i))
-
-#define ag_rp_9(b, i) (add2batch(b,i))
-
-#define ag_rp_10(n) (n)
-
-#define ag_rp_11(n) (ignore_procname(n))
-
-#define ag_rp_12(t, g, p) (dhsproc(g,p,t,-1))
-
-#define ag_rp_13(t, g, p, m) (dhsproc(g,p,t,m))
-
-#define ag_rp_14(t, g, m) (dhsproc(g,NULL,t,m))
-
-#define ag_rp_15(classname) (classname)
-
-#define ag_rp_16(c, min) ((cur_class=c, cur_min=min))
-
-#define ag_rp_17(a, b) (cur_bot=a, cur_top=b, ishex=0)
-
-#define ag_rp_18(a, b) (cur_bot=a, cur_top=b, ishex=1)
-
-#define ag_rp_19(n) (newdev(n))
-
-#define ag_rp_20(n, n1) (devrange(n,n1))
-
-#define ag_rp_21(n) (devrange(n,NULL))
-
-#define ag_rp_22(n, a, b, p, m) (initdisk(n, a, b, p, cur_maj, m))
-
-#define ag_rp_23(n, tg) (doinitlink(n, tg))
-
-#define ag_rp_24(n) (n)
-
-#define ag_rp_25(n) (n)
-
-#define ag_rp_26(n) (n)
-
-#define ag_rp_27(n, o, g, m) (addclass(n,o,g,m))
-
-#define ag_rp_28(n) (make(n, M_OMIT))
-
-#define ag_rp_29(n) (make(n, M_OMIT))
-
-#define ag_rp_30(n) (n)
-
-#define ag_rp_31(s) (string_finish(), s)
-
-#define ag_rp_32(s) (s)
-
-#define ag_rp_33(c) (string_start(c))
-
-#define ag_rp_34(s, c) (string_push(c), s)
-
-#define ag_rp_35(s) (string_finish(), s)
-
-#define ag_rp_36(c) (string_start(c))
-
-#define ag_rp_37(s, c) (string_push(c), s)
-
-#define ag_rp_38(c) (c)
-
-#define ag_rp_39() ('\\')
-
-#define ag_rp_40() ('"')
-
-#define ag_rp_41(d) (d-'0')
-
-#define ag_rp_42(n, d) (n*10 + d-'0')
-
-#define ag_rp_43(d) (d)
-
-#define ag_rp_44(n, d) (16*n+d)
-
-#define ag_rp_45(d) (d)
-
-#define ag_rp_46(n, d) (16*n+d)
-
-#define ag_rp_47(d) (d-'0')
-
-#define ag_rp_48(d) (10 + (d&7))
-
-#define ag_rp_49(d) (d-'0')
-
-#define ag_rp_50(n, d) (n*8+d-'0')
-
-#define ag_rp_51(x, t) (x+t)
-
-#define ag_rp_52(x, t) (x-t)
-
-#define ag_rp_53(t, f) (t*f)
-
-#define ag_rp_54(f) (-f)
-
-#define ag_rp_55(x) (x)
-
-
-#define READ_COUNTS 
-#define WRITE_COUNTS 
-static parse_vs_type ag_null_value;
-#define V(i,t) (*(t *) (&(PCB).vs[(PCB).ssx + i]))
-#define VS(i) (PCB).vs[(PCB).ssx + i]
-
-#ifndef GET_CONTEXT
-#define GET_CONTEXT CONTEXT = (PCB).input_context
-#endif
-
-typedef enum {
-  ag_action_1,
-  ag_action_2,
-  ag_action_3,
-  ag_action_4,
-  ag_action_5,
-  ag_action_6,
-  ag_action_7,
-  ag_action_8,
-  ag_action_9,
-  ag_action_10,
-  ag_action_11,
-  ag_action_12
-} ag_parser_action;
-
-static int ag_ap;
-
-
-
-static const unsigned char ag_rpx[] = {
-    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  2,
-    0,  0,  0,  3,  4,  5,  4,  5,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  6,  0,  0,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
-   19, 20, 21, 22, 23, 24,  0,  0,  0,  0,  0, 25, 26,  0,  0,  0, 27, 28,
-    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-   29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,  0,  0, 41, 42, 43, 44,
-   45, 46, 47, 48,  0, 49, 50,  0, 51,  0,  0, 52, 53
-};
-
-static unsigned char ag_key_itt[] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0,
- 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0
-};
-
-static unsigned short ag_key_pt[] = {
-  1,121,  1,122,  1,125,  1,126,  1,138,  1,139,0
-};
-
-static unsigned char ag_key_ch[] = {
-    0, 47,255, 42,255, 42, 47,255, 88,120,255, 97,108,255,104,108,255, 45,
-   47, 48, 66, 67, 98, 99,105,111,255, 42, 47,255, 47, 99,111,255, 42, 47,
-  255, 97,108,255, 47, 98, 99,105,255, 42, 47,255, 47,255, 42, 47,255, 47,
-   66, 67,255, 47, 99,111,255, 97,108,255, 47, 98, 99,105,255, 47,255, 47,
-   66, 67,255, 42, 47,255, 97,108,255,104,108,255, 47, 66, 67, 98, 99,105,
-  111,255, 97,108,255,104,108,255, 47, 66, 67, 98, 99,105,111,255, 99,111,
-  255, 97,108,255, 98, 99,105,255, 66, 67,255, 42, 47,255, 45, 47,255, 88,
-  120,255, 47, 48,255, 42, 47,255, 47, 98, 99,255, 98, 99,255, 42, 47,255,
-   97,108,255,104,108,255, 47, 98, 99,105,111,255, 45,255, 88,120,255, 48,
-  255
-};
-
-static unsigned char ag_key_act[] = {
-  0,3,4,3,4,0,0,4,0,0,4,7,7,4,7,7,4,3,2,2,3,3,2,2,7,7,4,0,0,4,2,7,7,4,0,
-  0,4,7,7,4,2,2,7,7,4,0,0,4,2,4,0,0,4,2,3,3,4,3,7,7,4,7,7,4,3,2,7,7,4,3,
-  4,3,3,3,4,0,0,4,7,7,4,7,7,4,2,3,3,2,2,7,7,4,7,7,4,7,7,4,3,3,3,2,2,7,7,
-  4,7,7,4,7,7,4,2,7,7,4,3,3,4,0,0,4,3,2,4,0,0,4,3,2,4,0,0,4,2,7,7,4,7,7,
-  4,0,0,4,7,7,4,7,7,4,2,2,2,7,7,4,3,4,0,0,4,2,4
-};
-
-static unsigned char ag_key_parm[] = {
-    0, 80,  0, 84,  0, 80, 86,  0,145,144,  0,  6,  0,  0,  2,  8,  0,137,
-    0,  0,118,117,  0,  0,  4, 10,  0, 80, 86,  0,  0,  8, 10,  0, 80, 86,
-    0,  6,  0,  0,  0,  0,  2,  4,  0, 80, 86,  0,  0,  0, 80, 86,  0,  0,
-  118,117,  0, 86,  8, 10,  0,  6,  0,  0, 86,  0,  2,  4,  0, 86,  0, 86,
-  118,117,  0, 80, 86,  0,  6,  0,  0,  2,  8,  0,  0,118,117,  0,  0,  4,
-   10,  0,  6,  0,  0,  2,  8,  0, 86,118,117,  0,  0,  4, 10,  0,  8, 10,
-    0,  6,  0,  0,  0,  2,  4,  0,118,117,  0, 80, 86,  0,137,  0,  0,145,
-  144,  0, 80,  0,  0, 80, 86,  0,  0,  0,  2,  0,  0,  2,  0, 80, 86,  0,
-    6,  0,  0,  2,  8,  0,  0,  0,  0,  4, 10,  0,137,  0,145,144,  0,  0,
-    0
-};
-
-static unsigned short ag_key_jmp[] = {
-    0,  0,  0,  2,  0,  0,  0,  0,  0,  0,  0, 38, 42,  0, 46, 49,  0,  4,
-    5,  8,  6, 20, 11, 14, 53, 59,  0,  0,  0,  0, 27, 63, 68,  0,  0,  0,
-    0, 72, 76,  0, 34, 37, 80, 84,  0,  0,  0,  0, 45,  0,  0,  0,  0, 50,
-   90,104,  0,122,124,129,  0,135,139,  0,133, 61,143,147,  0,153,  0,155,
-  157,171,  0,  0,  0,  0,221,225,  0,229,232,  0, 75,189,203, 78, 81,236,
-  242,  0,280,284,  0,288,291,  0,246,248,262, 92, 95,295,301,  0,305,310,
-    0,314,318,  0,109,322,326,  0,332,346,  0,  0,  0,  0,364,119,  0,  0,
-    0,  0,366,125,  0,  0,  0,  0,131,368,373,  0,377,382,  0,  0,  0,  0,
-  386,390,  0,394,397,  0,141,144,147,401,407,  0,411,  0,  0,  0,  0,158,
-    0
-};
-
-static unsigned short ag_key_index[] = {
-    1,  3, 17,  0,  3,  3, 30, 40, 48, 53, 57, 64, 69, 71,  0,  0, 84, 98,
-  106,112,  0,116,  0,  1,  1,  0,  0,106, 48, 48, 48, 48,  1,  1,  0,  0,
-    0, 69,112,  0,122, 48,  0,  0, 48, 48, 69, 69,116, 48, 69, 69,  0,128,
-    0,  0,  0, 69,  0, 69,  0,  0,134,138,  0,  0,  0,128,  0,  0, 69, 48,
-   69,  0,150, 64,  0,156,  0, 69,  0,116,  0,116, 69,  0,  0,  0,  1,  0,
-    0, 69, 69,  0,  1,  0,128,161,  0,  0,  0,  0,  0, 69, 69,  0, 57,  0,
-    0,  0, 69,  0, 64, 69,  1,  0,  1,  1,  0,  0,  0,  0,  0,161, 64, 48,
-   69, 69, 48,  0,128,  0, 48,  0,  0,161,161, 69, 69, 69, 69,  0,  0,  0,
-    0,  0,128,161,161,128,161,  1,  0, 69, 69,  0,  1,  0, 69,  0
-};
-
-static unsigned char ag_key_ends[] = {
-42,0, 47,0, 62,0, 108,111,99,107,32,100,101,118,105,99,101,115,58,0, 
-104,97,114,97,99,116,101,114,32,100,101,118,105,99,101,115,58,0, 
-116,99,104,0, 111,99,107,0, 97,114,0, 97,115,115,0, 
-103,110,111,114,101,0, 109,105,116,0, 108,97,115,115,0, 
-109,105,116,0, 116,99,104,0, 111,99,107,0, 104,97,114,0, 
-103,110,111,114,101,0, 108,111,99,107,32,100,101,118,105,99,101,115,58,0, 
-104,97,114,97,99,116,101,114,32,100,101,118,105,99,101,115,58,0, 
-47,0, 108,97,115,115,0, 109,105,116,0, 47,0, 116,99,104,0, 
-111,99,107,0, 104,97,114,0, 103,110,111,114,101,0, 47,0, 47,0, 
-108,111,99,107,32,100,101,118,105,99,101,115,58,0, 
-104,97,114,97,99,116,101,114,32,100,101,118,105,99,101,115,58,0, 
-108,111,99,107,32,100,101,118,105,99,101,115,58,0, 
-104,97,114,97,99,116,101,114,32,100,101,118,105,99,101,115,58,0, 
-116,99,104,0, 111,99,107,0, 97,114,0, 97,115,115,0, 
-103,110,111,114,101,0, 109,105,116,0, 47,0, 
-108,111,99,107,32,100,101,118,105,99,101,115,58,0, 
-104,97,114,97,99,116,101,114,32,100,101,118,105,99,101,115,58,0, 
-116,99,104,0, 111,99,107,0, 97,114,0, 97,115,115,0, 
-103,110,111,114,101,0, 109,105,116,0, 108,97,115,115,0, 
-109,105,116,0, 116,99,104,0, 111,99,107,0, 104,97,114,0, 
-103,110,111,114,101,0, 108,111,99,107,32,100,101,118,105,99,101,115,58,0, 
-104,97,114,97,99,116,101,114,32,100,101,118,105,99,101,115,58,0, 
-62,0, 42,0, 108,111,99,107,0, 104,97,114,0, 108,111,99,107,0, 
-104,97,114,0, 116,99,104,0, 111,99,107,0, 97,114,0, 97,115,115,0, 
-103,110,111,114,101,0, 109,105,116,0, 62,0, 
-};
-#define AG_TCV(x) (((int)(x) >= -1 && (int)(x) <= 255) ? ag_tcv[(x) + 1] : 0)
-
-static const unsigned char ag_tcv[] = {
-   18, 18,152,152,152,152,152,152,152,152,150, 93,152,152,150,152,152,152,
-  152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,151,153, 95,
-   87,153,153,153,153,130,128,149,148,127,133,153,135,154,113,114,115,116,
-  154,154,154,155,155,131,153,153,129,153,153,153,156,156,156,156,156,156,
-  157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,
-  157,157,134, 99,132,153,157,153,156,119,120,156,156,156,157,157,157,157,
-  157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,124,153,
-  123,153,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,
-  152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,
-  152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,
-  152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,
-  152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,
-  152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,
-  152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,
-  152,152,152,152,152
-};
-
-#ifndef SYNTAX_ERROR
-#define SYNTAX_ERROR fprintf(stderr,"%s, line %d, column %d\n", \
-  (PCB).error_message, (PCB).line, (PCB).column)
-#endif
-
-#ifndef FIRST_LINE
-#define FIRST_LINE 1
-#endif
-
-#ifndef FIRST_COLUMN
-#define FIRST_COLUMN 1
-#endif
-
-
-#ifndef PARSER_STACK_OVERFLOW
-#define PARSER_STACK_OVERFLOW {fprintf(stderr, \
-   "\nParser stack overflow, line %d, column %d\n",\
-   (PCB).line, (PCB).column);}
-#endif
-
-#ifndef REDUCTION_TOKEN_ERROR
-#define REDUCTION_TOKEN_ERROR {fprintf(stderr, \
-    "\nReduction token error, line %d, column %d\n", \
-    (PCB).line, (PCB).column);}
-#endif
-
-
-typedef enum
-  {ag_accept_key, ag_set_key, ag_jmp_key, ag_end_key, ag_no_match_key,
-   ag_cf_accept_key, ag_cf_set_key, ag_cf_end_key} key_words;
-
-
-static void ag_track(void) {
-  int ag_k = 0;
-  while (ag_k < (PCB).rx) {
-    int ag_ch = (PCB).lab[ag_k++];
-    switch (ag_ch) {
-    case '\n':
-      (PCB).column = 1, (PCB).line++;
-    case '\r':
-    case '\f':
-      break;
-    case '\t':
-      (PCB).column += (TAB_SPACING) - ((PCB).column - 1) % (TAB_SPACING);
-      break;
-    default:
-      (PCB).column++;
-    }
-  }
-  ag_k = 0;
-  while ((PCB).rx < (PCB).fx) (PCB).lab[ag_k++] = (PCB).lab[(PCB).rx++];
-  (PCB).fx = ag_k;
-  (PCB).rx = 0;
-}
-
-
-static void ag_prot(void) {
-  int ag_k = 38 - ++(PCB).btsx;
-  if (ag_k <= (PCB).ssx) {
-    (PCB).exit_flag = AG_STACK_ERROR_CODE;
-    PARSER_STACK_OVERFLOW;
-    return;
-  }
-  (PCB).bts[(PCB).btsx] = (PCB).sn;
-  (PCB).bts[ag_k] = (PCB).ssx;
-  (PCB).vs[ag_k] = (PCB).vs[(PCB).ssx];
-  (PCB).ss[ag_k] = (PCB).ss[(PCB).ssx];
-}
-
-static void ag_undo(void) {
-  if ((PCB).drt == -1) return;
-  while ((PCB).btsx) {
-    int ag_k = 38 - (PCB).btsx;
-    (PCB).sn = (PCB).bts[(PCB).btsx--];
-    (PCB).ssx = (PCB).bts[ag_k];
-    (PCB).vs[(PCB).ssx] = (PCB).vs[ag_k];
-    (PCB).ss[(PCB).ssx] = (PCB).ss[ag_k];
-  }
-  (PCB).token_number = (parse_token_type) (PCB).drt;
-  (PCB).ssx = (PCB).dssx;
-  (PCB).sn = (PCB).dsn;
-  (PCB).drt = -1;
-}
-
-
-static const unsigned char ag_tstt[] = {
-151,150,80,0,2,111,112,
-157,156,155,154,153,152,151,150,149,148,135,134,133,132,131,130,129,128,127,
-  124,123,120,119,116,115,114,113,99,95,93,87,0,82,83,
-151,150,80,0,2,
-116,115,114,113,0,5,6,8,10,12,
-157,156,155,154,153,152,151,150,149,148,135,134,133,132,131,130,129,128,127,
-  124,123,120,119,116,115,114,113,99,95,93,87,0,
-84,0,
-151,150,80,0,2,111,112,
-151,150,80,0,2,111,112,
-151,150,80,0,2,111,112,
-151,150,80,0,2,111,112,
-139,138,93,87,86,0,3,13,14,15,85,88,92,140,
-126,125,122,121,120,119,93,87,86,0,3,11,14,15,85,88,92,140,
-157,156,133,120,119,95,93,87,86,0,3,9,14,15,85,88,92,140,
-118,117,93,87,86,0,3,7,14,15,85,88,92,140,
-157,156,155,154,153,152,151,150,149,148,135,134,133,132,131,130,129,128,127,
-  124,123,120,119,116,115,114,113,99,95,87,18,0,90,91,
-93,0,
-151,150,80,0,2,111,112,
-157,156,155,154,139,138,133,127,126,125,123,122,121,120,119,118,117,116,115,
-  114,113,95,93,87,86,18,0,3,88,92,140,
-139,138,0,69,70,71,72,73,75,
-126,125,122,121,120,119,0,29,30,31,32,33,34,35,36,42,45,
-157,156,133,120,119,95,0,1,4,26,27,28,141,142,
-118,117,0,16,17,19,22,
-157,156,155,154,153,152,151,150,149,148,135,134,133,132,131,130,129,128,127,
-  124,123,120,119,116,115,114,113,99,95,87,18,0,
-151,150,80,0,2,111,112,
-151,150,80,0,2,111,112,
-157,156,133,124,120,119,95,0,1,4,26,37,141,142,
-157,156,133,120,119,95,0,1,4,26,141,142,
-139,138,18,0,69,71,72,73,75,
-151,150,80,0,2,111,112,
-151,150,80,0,2,111,112,
-151,150,80,0,2,111,112,
-151,150,80,0,2,111,112,
-151,150,80,0,2,111,112,
-151,150,80,0,2,111,112,
-130,0,50,
-157,156,133,120,119,95,0,1,4,26,46,141,142,
-124,0,37,
-157,156,133,124,120,119,95,93,87,86,0,3,14,15,37,85,88,92,140,
-126,125,122,121,120,119,18,0,29,30,31,32,33,34,36,42,45,
-157,156,155,154,153,151,149,148,135,134,133,132,131,130,129,128,127,124,123,
-  120,119,116,115,114,113,99,87,0,96,97,
-151,150,80,0,2,111,112,
-157,156,155,154,151,150,133,120,119,116,115,114,113,80,0,2,111,112,
-155,154,116,115,114,113,0,25,100,
-157,156,133,120,119,95,18,0,1,4,26,27,141,142,
-151,150,80,0,2,111,112,
-151,150,80,0,2,111,112,
-87,86,0,3,14,85,88,92,140,
-87,86,0,3,14,85,88,92,140,
-118,117,18,0,16,19,22,
-151,150,80,0,2,111,112,
-157,156,133,120,119,95,93,87,86,0,3,14,15,85,88,92,140,
-87,86,0,3,14,85,88,92,140,
-131,0,57,
-151,150,80,0,2,111,112,
-157,156,133,120,119,95,0,1,4,26,51,141,142,
-124,0,37,
-127,123,0,41,48,49,
-157,156,133,120,119,95,93,87,86,0,3,14,15,85,88,92,140,
-157,156,133,120,119,95,0,1,4,26,38,65,141,142,
-157,156,133,123,120,119,95,93,87,86,0,3,14,15,85,88,92,140,
-99,95,0,
-157,156,155,154,153,151,149,148,135,134,133,132,131,130,129,128,127,124,123,
-  120,119,116,115,114,113,99,95,87,0,97,
-151,150,80,0,2,111,112,
-155,154,122,121,120,119,116,115,114,113,0,29,30,31,32,33,100,
-155,154,116,115,114,113,0,23,24,25,100,
-155,154,116,115,114,113,0,20,21,25,100,
-157,156,133,120,119,95,0,1,4,26,76,77,141,142,
-151,150,80,0,2,111,112,
-157,156,133,120,119,95,0,1,4,26,141,142,
-129,127,0,48,52,
-157,156,133,120,119,95,93,87,86,0,3,14,15,85,88,92,140,
-151,150,80,0,2,111,112,
-157,156,133,123,120,119,95,93,87,86,0,3,14,15,85,88,92,140,
-157,156,133,120,119,95,0,1,4,26,47,141,142,
-151,150,80,0,2,111,112,
-126,125,122,121,120,119,93,87,86,18,0,3,14,15,85,88,92,140,
-157,156,133,120,119,95,0,1,4,26,43,44,141,142,
-137,134,130,0,50,55,56,59,60,68,
-157,156,133,120,119,95,0,1,4,26,38,39,40,65,141,142,
-87,86,0,3,14,85,88,92,140,
-157,156,155,154,133,120,119,116,115,114,113,95,0,1,4,26,100,141,142,
-155,154,116,115,114,113,0,23,25,100,
-157,156,155,154,133,120,119,116,115,114,113,95,0,1,4,26,100,141,142,
-155,154,116,115,114,113,0,20,25,100,
-157,156,133,127,123,120,119,95,93,87,86,0,3,14,15,85,88,92,140,
-157,156,133,123,120,119,95,0,1,4,26,41,76,141,142,
-157,156,133,120,119,95,0,1,4,26,141,142,
-155,154,116,115,114,113,0,25,100,
-151,150,80,0,2,111,112,
-157,156,133,120,119,95,0,1,4,26,53,141,142,
-157,156,133,120,119,95,0,1,4,26,47,141,142,
-157,156,133,127,123,120,119,95,93,87,86,0,3,14,15,85,88,92,140,
-157,156,133,127,123,120,119,95,93,87,86,0,3,14,15,85,88,92,140,
-157,156,133,123,120,119,95,0,1,4,26,41,43,141,142,
-151,150,80,0,2,111,112,
-157,156,133,120,119,95,0,1,4,26,141,142,
-151,150,80,0,2,111,112,
-157,156,155,154,145,144,133,120,119,116,115,114,113,0,25,63,66,100,101,102,
-  103,
-157,156,133,130,120,119,95,0,1,4,26,50,55,56,65,141,142,
-157,156,133,120,119,95,0,1,4,26,141,142,
-131,0,57,
-157,156,133,120,119,95,0,1,4,26,38,65,141,142,
-123,0,41,
-87,86,0,3,14,85,88,92,140,
-87,86,0,3,14,85,88,92,140,
-127,0,48,49,
-139,138,93,87,86,18,0,3,14,15,85,88,92,140,
-154,116,115,114,113,0,74,78,106,
-155,154,128,116,115,114,113,0,54,100,
-128,127,0,48,54,
-157,156,133,127,123,120,119,95,93,87,86,0,3,14,15,85,88,92,140,
-127,0,48,49,
-126,125,122,121,120,119,93,87,86,18,0,3,14,15,85,88,92,140,
-87,86,0,3,14,85,88,92,140,
-151,150,80,0,2,111,112,
-133,0,61,
-151,150,80,0,2,111,112,
-151,150,80,0,2,111,112,
-156,155,154,120,119,116,115,114,113,0,100,104,105,
-156,155,154,133,120,119,116,115,114,113,0,61,100,104,105,
-155,154,133,116,115,114,113,0,61,100,
-130,0,50,55,56,
-128,0,54,
-155,154,145,144,133,130,116,115,114,113,0,25,50,58,61,63,100,101,102,103,
-  107,109,
-126,125,122,121,120,119,93,87,86,18,0,3,14,15,85,88,92,140,
-151,150,80,0,2,111,112,
-154,116,115,114,113,0,106,
-87,86,0,3,14,85,88,92,140,
-151,150,80,0,2,111,112,
-155,154,116,115,114,113,0,25,100,
-151,150,80,0,2,111,112,
-157,156,133,120,119,0,66,
-151,150,80,0,2,111,112,
-156,155,154,120,119,116,115,114,113,0,64,100,104,105,
-155,154,116,115,114,113,0,25,100,
-155,154,145,144,133,130,116,115,114,113,0,25,50,58,61,63,100,101,102,103,
-  107,109,
-155,154,145,144,133,130,116,115,114,113,0,25,50,61,63,100,101,102,103,109,
-156,155,154,120,119,116,115,114,113,0,100,104,105,
-155,154,116,115,114,113,0,100,
-149,0,110,
-148,133,87,86,0,3,14,61,85,88,92,108,140,
-155,154,128,116,115,114,113,0,54,100,
-132,0,62,
-156,155,154,132,120,119,116,115,114,113,0,62,100,104,105,
-155,154,132,116,115,114,113,0,62,100,
-148,133,128,0,54,61,108,
-151,150,80,0,2,111,112,
-155,154,145,144,133,130,116,115,114,113,0,25,50,61,63,100,101,102,103,109,
-155,154,145,144,133,130,116,115,114,113,0,25,50,61,63,100,101,102,103,107,
-  109,
-151,150,80,0,2,111,112,
-155,154,145,144,133,130,116,115,114,113,0,25,50,61,63,100,101,102,103,107,
-  109,
-151,150,80,0,2,111,112,
-155,154,116,115,114,113,0,25,100,
-149,0,110,
-149,0,110,
-155,154,135,116,115,114,113,0,67,100,
-151,150,80,0,2,111,112,
-155,154,116,115,114,113,0,25,100,
-155,154,116,115,114,113,87,86,0,3,14,85,88,92,100,140,
-  0
-};
-
-
-static unsigned char ag_astt[1821] = {
-  1,1,1,8,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
-  1,8,1,1,9,9,1,5,3,1,1,1,1,7,0,1,1,1,1,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
-  9,9,9,9,9,9,9,9,9,9,9,9,9,5,3,7,1,1,1,5,1,1,3,1,1,1,5,1,1,3,1,1,1,5,1,1,3,
-  1,1,1,5,1,1,3,8,8,8,1,1,7,1,3,1,1,1,1,1,1,8,8,8,8,8,8,8,1,1,7,1,3,1,1,1,1,
-  1,1,8,8,8,8,8,8,8,1,1,7,1,3,1,1,1,1,1,1,8,8,8,1,1,7,1,3,1,1,1,1,1,1,1,1,1,
-  1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,5,1,3,3,7,1,1,1,5,
-  1,1,3,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,8,1,1,5,7,3,1,1,1,1,1,7,
-  1,1,1,1,1,1,1,1,1,1,1,1,7,1,2,2,2,2,1,1,1,1,1,2,2,2,2,2,1,7,2,2,1,1,1,1,1,
-  1,1,7,1,1,1,1,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
-  9,5,1,1,1,5,1,1,3,1,1,1,5,1,1,3,2,2,2,1,2,2,1,7,2,2,1,1,1,1,2,2,2,2,2,1,7,
-  2,2,1,1,1,1,1,3,7,3,3,3,1,1,1,1,1,5,1,1,3,1,1,1,5,1,1,3,1,1,1,5,1,1,3,1,1,
-  1,5,1,1,3,1,1,1,5,1,1,3,1,1,1,5,1,1,3,1,7,1,2,2,2,2,2,1,7,2,2,1,1,1,1,1,7,
-  1,8,8,8,1,8,8,8,8,1,1,7,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,7,1,2,2,2,2,3,1,1,1,
-  2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,7,1,2,1,1,1,5,1,1,3,
-  10,10,10,10,1,1,10,10,10,10,10,10,10,1,5,1,1,3,1,1,1,1,1,1,7,1,2,2,2,2,2,2,
-  1,3,7,2,2,1,3,1,1,1,1,1,5,1,1,3,1,1,1,5,1,1,3,1,1,8,1,1,1,1,1,1,1,1,8,1,1,
-  1,1,1,1,1,1,3,7,3,1,1,1,1,1,5,1,1,3,8,8,8,8,8,8,8,1,1,7,1,1,1,1,1,1,1,1,1,
-  8,1,2,1,1,1,1,1,7,1,1,1,1,5,1,1,3,2,2,2,2,2,1,7,2,2,2,1,1,1,1,7,1,1,1,8,1,
-  1,1,8,8,8,8,8,8,8,1,1,7,1,1,1,1,1,1,1,2,2,2,2,2,1,7,2,2,2,3,1,1,1,8,8,8,8,
-  8,8,8,8,1,1,7,1,1,1,1,1,1,1,2,2,7,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
-  2,2,2,2,2,1,2,2,7,2,1,1,1,5,1,1,3,1,1,1,1,1,1,1,1,1,1,7,1,2,2,2,2,2,1,1,1,
-  1,1,1,7,1,1,1,2,1,1,1,1,1,1,7,1,1,1,2,2,2,2,2,2,1,7,2,2,1,1,1,1,1,1,1,1,5,
-  1,1,3,2,2,2,2,2,1,7,2,2,1,1,1,1,1,7,1,1,8,8,8,8,8,8,8,1,1,7,1,1,1,1,1,1,1,
-  1,1,1,5,1,1,3,5,5,5,5,5,5,5,8,1,1,7,1,3,3,1,1,1,1,2,2,2,2,2,1,7,2,2,2,1,1,
-  1,1,1,1,5,1,1,3,5,5,5,5,5,5,8,1,1,5,7,1,3,3,1,1,1,1,2,2,2,2,2,1,7,2,2,1,1,
-  1,1,1,1,1,1,7,1,1,2,1,1,1,2,2,2,2,2,1,8,2,2,2,1,1,1,1,1,1,1,1,8,1,2,1,1,1,
-  1,2,2,1,1,2,2,2,1,1,1,1,1,7,2,2,1,2,1,1,1,1,1,1,1,1,5,3,1,2,2,2,1,1,2,2,2,
-  1,1,1,1,1,7,2,2,1,2,1,1,1,1,1,1,1,1,5,3,1,2,8,8,8,8,8,8,8,8,8,1,1,7,1,1,1,
-  1,1,1,1,2,2,2,1,2,2,1,7,2,2,1,1,3,1,1,2,2,2,2,2,1,7,2,2,1,1,1,1,1,1,1,1,1,
-  7,1,2,1,1,1,5,1,1,3,2,2,2,2,2,1,7,2,2,2,1,1,1,2,2,2,2,2,1,7,2,2,2,1,1,1,5,
-  5,5,5,5,5,5,5,8,1,1,7,1,2,2,1,1,1,1,8,8,8,8,8,8,8,8,8,1,1,7,1,1,1,1,1,1,1,
-  2,2,2,1,2,2,1,7,2,2,1,1,3,1,1,1,1,1,5,1,1,3,2,2,2,2,2,1,7,2,2,1,1,1,1,1,1,
-  5,1,1,3,1,1,1,1,1,1,1,1,1,1,1,1,1,7,1,1,1,2,1,1,1,2,2,2,1,2,2,1,7,2,2,2,1,
-  1,2,1,1,1,2,2,2,2,2,1,7,2,2,1,1,1,1,7,1,2,2,2,2,2,1,5,2,2,2,3,1,1,1,1,7,1,
-  1,1,8,1,2,1,1,1,1,1,1,8,1,2,1,1,1,1,1,5,1,2,5,5,8,1,1,5,7,1,3,3,1,1,1,1,1,
-  1,1,1,1,7,1,1,2,1,1,1,1,1,1,1,7,2,2,1,1,7,1,2,5,5,5,5,5,5,5,5,8,1,1,7,1,2,
-  2,1,1,1,1,1,5,1,2,5,5,5,5,5,5,8,1,1,5,7,1,3,3,1,1,1,1,1,1,8,1,2,1,1,1,1,1,
-  1,1,5,1,1,3,1,7,1,1,1,1,5,1,1,3,1,1,1,5,1,1,3,1,1,1,1,1,1,1,1,1,7,2,2,2,1,
-  1,1,1,1,1,1,1,1,1,7,1,2,2,2,1,1,1,1,1,1,1,7,1,2,1,7,1,1,2,1,7,2,1,1,1,1,1,
-  1,1,1,1,1,7,1,1,1,1,1,2,1,1,1,1,1,5,5,5,5,5,5,8,1,1,5,7,1,3,3,1,1,1,1,1,1,
-  1,5,1,1,3,1,1,1,1,1,4,2,1,1,8,1,2,1,1,1,1,1,1,1,5,1,1,3,1,1,1,1,1,1,7,1,2,
-  1,1,1,5,1,1,3,1,1,1,1,1,7,1,1,1,1,5,1,1,3,1,1,1,1,1,1,1,1,1,7,1,2,2,2,1,1,
-  1,1,1,1,7,1,2,1,1,1,1,1,1,1,1,1,1,7,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,
-  1,1,7,1,1,1,1,2,1,1,1,2,1,1,1,1,1,1,1,1,1,5,2,2,2,1,1,1,1,1,1,5,2,1,5,1,1,
-  1,1,1,8,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,7,2,2,1,7,1,1,1,1,1,1,1,1,1,1,1,7,2,
-  2,2,2,1,1,1,1,1,1,1,7,2,2,1,1,1,7,2,1,1,1,1,1,5,1,1,3,1,1,1,1,1,1,1,1,1,1,
-  7,1,1,1,1,2,1,1,1,2,1,1,1,1,1,1,1,1,1,1,7,1,1,1,1,2,1,1,1,1,1,1,1,1,5,1,1,
-  3,1,1,1,1,1,1,1,1,1,1,7,1,1,1,1,2,1,1,1,1,1,1,1,1,5,1,1,3,1,1,1,1,1,1,7,1,
-  2,1,4,1,1,4,1,1,1,1,1,1,1,1,7,1,2,1,1,1,5,1,1,3,1,1,1,1,1,1,7,1,2,1,1,1,1,
-  1,1,1,1,8,1,2,1,1,1,2,1,11
-};
-
-
-static unsigned char ag_pstt[] = {
-2,2,1,3,2,2,3,
-4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,4,5,
-122,122,1,124,122,
-6,7,8,9,3,0,13,12,11,10,
-74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,
-  74,74,74,74,74,74,76,
-77,5,
-2,2,1,123,2,2,128,
-2,2,1,123,2,2,127,
-2,2,1,123,2,2,126,
-2,2,1,123,2,2,125,
-18,18,15,14,14,10,17,4,18,18,17,14,15,16,
-19,19,19,19,19,19,15,14,14,11,17,3,19,19,17,14,15,16,
-20,20,20,20,20,20,15,14,14,12,17,2,20,20,17,14,15,16,
-21,21,15,14,14,13,17,1,21,21,17,14,15,16,
-22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,
-  22,22,22,22,22,22,85,22,88,
-89,15,
-2,2,1,123,2,2,152,
-80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,15,14,14,
-  80,17,79,14,15,16,
-23,24,18,27,27,27,27,26,25,
-32,33,28,29,30,31,19,34,22,23,24,25,38,38,37,36,35,
-92,92,92,92,92,39,20,90,91,42,43,43,41,40,
-44,45,21,48,48,47,46,
-84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
-  84,84,84,84,84,84,86,
-2,2,1,123,2,2,151,
-2,2,1,123,2,2,150,
-92,92,92,49,92,92,39,25,90,91,51,50,41,40,
-92,92,92,92,92,39,26,90,91,52,41,40,
-23,24,62,27,61,61,61,26,25,
-2,2,1,123,2,2,134,
-2,2,1,123,2,2,133,
-2,2,1,123,2,2,132,
-2,2,1,123,2,2,131,
-2,2,1,123,2,2,138,
-2,2,1,123,2,2,137,
-53,34,54,
-92,92,92,92,92,39,35,90,91,55,56,41,40,
-49,36,57,
-58,58,58,49,58,58,58,15,14,14,37,17,58,58,59,17,14,15,16,
-32,33,28,29,30,31,28,38,34,22,23,24,25,27,37,36,35,
-97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,
-  60,97,39,61,95,
-2,2,1,123,2,2,154,
-93,93,93,93,2,2,93,93,93,93,93,93,93,1,123,2,2,153,
-62,62,62,62,62,62,42,63,100,
-92,92,92,92,92,39,20,43,90,91,42,19,41,40,
-2,2,1,123,2,2,130,
-2,2,1,123,2,2,129,
-14,14,15,17,64,17,14,15,16,
-14,14,15,17,65,17,14,15,16,
-44,45,9,48,8,47,46,
-2,2,1,123,2,2,136,
-66,66,66,66,66,66,15,14,14,50,17,66,66,17,14,15,16,
-14,14,15,17,66,17,14,15,16,
-67,52,68,
-2,2,1,123,2,2,142,
-92,92,92,92,92,39,54,90,91,58,69,41,40,
-49,55,70,
-71,74,73,75,72,73,
-76,76,76,76,76,76,15,14,14,57,17,76,76,17,14,15,16,
-92,92,92,92,92,39,58,90,91,57,34,77,41,40,
-78,78,78,78,78,78,78,15,14,14,59,17,78,78,17,14,15,16,
-98,99,60,
-97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,
-  60,94,97,61,96,
-2,2,1,123,2,2,155,
-62,62,28,29,30,31,62,62,62,62,63,79,22,23,24,25,101,
-62,62,62,62,62,62,64,81,81,80,100,
-62,62,62,62,62,62,65,83,83,82,100,
-92,92,92,92,92,39,66,90,91,84,85,85,41,40,
-2,2,1,123,2,2,143,
-92,92,92,92,92,39,68,90,91,86,41,40,
-88,71,69,87,89,
-90,90,90,90,90,90,15,14,14,70,17,90,90,17,14,15,16,
-2,2,1,123,2,2,139,
-5,5,5,5,5,5,5,15,14,14,72,17,41,41,17,14,15,16,
-92,92,92,92,92,39,73,90,91,43,91,41,40,
-2,2,1,123,2,2,135,
-5,5,5,5,5,5,15,14,14,5,75,17,38,38,17,14,15,16,
-92,92,92,92,92,39,76,90,91,92,93,93,41,40,
-94,96,53,77,99,100,52,98,97,95,
-92,92,92,92,92,39,102,90,91,57,101,101,102,77,41,40,
-14,14,15,17,21,17,14,15,16,
-92,92,62,62,92,92,92,62,62,62,62,39,80,90,91,103,101,41,40,
-62,62,62,62,62,62,15,14,80,100,
-92,92,62,62,92,92,92,62,62,62,62,39,82,90,91,104,101,41,40,
-62,62,62,62,62,62,12,11,82,100,
-105,105,105,105,105,105,105,105,15,14,14,84,17,105,105,17,14,15,16,
-92,92,92,74,92,92,39,85,90,91,84,106,68,41,40,
-92,92,92,92,92,39,86,90,91,107,41,40,
-62,62,62,62,62,62,87,108,100,
-2,2,1,123,2,2,141,
-92,92,92,92,92,39,89,90,91,59,109,41,40,
-92,92,92,92,92,39,90,90,91,43,110,41,40,
-5,5,5,5,5,5,5,5,15,14,14,91,17,42,42,17,14,15,16,
-111,111,111,111,111,111,111,111,15,14,14,92,17,111,111,17,14,15,16,
-92,92,92,74,92,92,39,93,90,91,92,112,36,41,40,
-2,2,1,123,2,2,149,
-92,92,92,92,92,39,95,90,91,113,41,40,
-2,2,1,123,2,2,146,
-114,114,62,62,116,117,114,114,114,62,62,62,62,97,120,119,115,100,118,118,
-  118,
-92,92,92,53,92,92,39,98,90,91,57,99,100,54,121,41,40,
-92,92,92,92,92,39,99,90,91,122,41,40,
-67,100,123,
-92,92,92,92,92,39,32,90,91,57,30,77,41,40,
-74,102,124,
-14,14,15,17,17,17,14,15,16,
-14,14,15,17,16,17,14,15,16,
-71,40,72,70,
-5,5,15,14,14,5,106,17,69,69,17,14,15,16,
-125,125,125,125,125,107,127,126,110,
-62,62,128,62,62,62,62,108,47,101,
-128,71,109,129,45,
-5,5,5,5,5,5,5,5,15,14,14,110,17,39,39,17,14,15,16,
-71,40,72,44,
-5,5,5,5,5,5,15,14,14,5,112,17,37,37,17,14,15,16,
-14,14,15,17,56,17,14,15,16,
-2,2,1,123,2,2,148,
-130,115,131,
-2,2,1,123,2,2,157,
-2,2,1,123,2,2,156,
-132,62,62,132,132,62,62,62,62,118,108,104,109,
-132,62,62,130,132,132,62,62,62,62,119,133,108,105,109,
-62,62,130,62,62,62,62,120,134,101,
-53,121,99,100,53,
-128,122,48,
-62,62,116,117,130,53,62,62,62,62,123,138,135,140,136,137,100,118,118,118,
-  139,139,
-5,5,5,5,5,5,15,14,14,5,124,17,33,33,17,14,15,16,
-2,2,1,123,2,2,159,
-125,125,125,125,125,71,111,
-14,14,15,17,65,17,14,15,16,
-2,2,1,123,2,2,140,
-62,62,62,62,62,62,129,141,100,
-2,2,1,123,2,2,145,
-114,114,114,114,114,131,142,
-2,2,1,123,2,2,158,
-132,62,62,132,132,62,62,62,62,133,143,108,106,109,
-62,62,62,62,62,62,134,144,100,
-62,62,116,117,130,53,62,62,62,62,135,138,135,145,136,137,100,118,118,118,
-  139,139,
-62,62,116,117,130,53,62,62,62,62,136,138,135,136,137,100,118,118,118,119,
-132,62,62,132,132,62,62,62,62,118,108,105,109,
-62,62,62,62,62,62,117,101,
-146,112,147,
-149,130,14,14,15,17,49,148,17,14,15,150,16,
-62,62,128,62,62,62,62,141,46,101,
-151,142,152,
-132,62,62,151,132,132,62,62,62,62,143,51,108,107,109,
-62,62,151,62,62,62,62,144,50,101,
-149,130,128,145,120,148,150,
-2,2,1,123,2,2,161,
-62,62,116,117,130,53,62,62,62,62,147,138,135,136,137,100,118,118,118,116,
-62,62,116,117,130,53,62,62,62,62,148,138,135,136,137,100,118,118,118,153,
-  153,
-2,2,1,123,2,2,160,
-62,62,116,117,130,53,62,62,62,62,150,138,135,136,137,100,118,118,118,154,
-  154,
-2,2,1,123,2,2,144,
-62,62,62,62,62,62,152,155,100,
-146,114,147,
-146,113,147,
-62,62,156,62,62,62,62,155,157,101,
-2,2,1,123,2,2,147,
-62,62,62,62,62,62,157,158,100,
-62,62,62,62,62,62,14,14,15,17,55,17,14,15,101,16,
-  0
-};
-
-
-static const unsigned short ag_sbt[] = {
-     0,   7,  41,  46,  56,  88,  90,  97, 104, 111, 118, 132, 150, 168,
-   182, 216, 218, 225, 256, 265, 282, 296, 303, 335, 342, 349, 363, 375,
-   384, 391, 398, 405, 412, 419, 426, 429, 442, 445, 464, 481, 511, 518,
-   536, 545, 559, 566, 573, 582, 591, 598, 605, 622, 631, 634, 641, 654,
-   657, 663, 680, 694, 712, 715, 745, 752, 769, 780, 791, 805, 812, 824,
-   829, 846, 853, 871, 884, 891, 909, 923, 933, 949, 958, 977, 987,1006,
-  1016,1035,1050,1062,1071,1078,1091,1104,1123,1142,1157,1164,1176,1183,
-  1204,1221,1233,1236,1250,1253,1262,1271,1275,1289,1298,1308,1313,1332,
-  1336,1354,1363,1370,1373,1380,1387,1400,1415,1425,1430,1433,1455,1473,
-  1480,1487,1496,1503,1512,1519,1526,1533,1547,1556,1578,1598,1611,1619,
-  1622,1635,1645,1648,1663,1673,1680,1687,1707,1728,1735,1756,1763,1772,
-  1775,1778,1788,1795,1804,1820
-};
-
-
-static const unsigned short ag_sbe[] = {
-     3,  38,  44,  50,  87,  89,  93, 100, 107, 114, 123, 141, 159, 173,
-   213, 217, 221, 251, 258, 271, 288, 298, 334, 338, 345, 356, 369, 378,
-   387, 394, 401, 408, 415, 422, 427, 435, 443, 455, 471, 508, 514, 532,
-   542, 552, 562, 569, 575, 584, 594, 601, 614, 624, 632, 637, 647, 655,
-   659, 672, 686, 704, 714, 743, 748, 762, 775, 786, 797, 808, 818, 826,
-   838, 849, 863, 877, 887, 901, 915, 926, 939, 951, 970, 983, 999,1012,
-  1027,1042,1056,1068,1074,1084,1097,1115,1134,1149,1160,1170,1179,1196,
-  1211,1227,1234,1242,1251,1255,1264,1272,1281,1294,1305,1310,1324,1333,
-  1346,1356,1366,1371,1376,1383,1396,1410,1422,1426,1431,1443,1465,1476,
-  1485,1489,1499,1509,1515,1524,1529,1542,1553,1566,1588,1607,1617,1620,
-  1626,1642,1646,1658,1670,1676,1683,1697,1717,1731,1745,1759,1769,1773,
-  1776,1785,1791,1801,1812,1820
-};
-
-
-static const unsigned char ag_fl[] = {
-  2,2,2,2,2,0,1,1,2,3,1,2,3,1,2,3,3,3,1,2,3,4,1,1,1,1,1,2,3,1,2,0,1,6,3,
-  1,2,6,4,5,0,2,4,1,3,6,8,6,3,4,5,5,2,4,3,10,4,1,1,1,1,2,3,1,1,7,3,1,2,6,
-  3,1,1,1,2,0,1,3,1,2,1,1,1,1,2,0,1,0,2,2,1,1,1,2,3,1,2,1,2,2,1,2,1,1,2,
-  2,1,2,1,1,1,2,1,3,3,1,3,1,1,2,3,1,2,0,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
-  2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2
-};
-
-static const unsigned char ag_ptt[] = {
-    0,  5,  5,  5,  5, 15, 15, 17, 17,  7, 21, 21, 16, 24, 24, 16, 20, 23,
-   28, 28,  9, 27, 29, 29, 29, 29, 35, 35, 11, 39, 39, 40, 40, 34, 34, 44,
-   44, 34, 34, 46, 49, 49, 46, 47, 43, 36, 36, 36, 55, 56, 59, 59, 38, 38,
-   38, 38, 38, 65, 51, 53, 70, 70, 13, 69, 69, 71, 72, 77, 77, 72, 76, 74,
-    2, 82, 82, 83, 83,  2, 85, 85, 14, 88, 88, 90, 90, 91, 91, 92, 92,140,
-   26, 26,141,141,142, 96, 96, 97, 97, 97, 25, 25,103,103, 63, 63, 64, 64,
-  104,104, 78, 78, 58, 58, 58,107,107,109,109,109,109,111,111,112,112,  6,
-    8, 10, 12, 19, 22, 30, 31, 32, 33, 41, 37, 42, 45, 48, 54, 52, 50, 57,
-   62, 61, 60, 67, 66, 68, 73, 75,  3,  1,  4,100,101,102,105,106,108,110
-};
-
-
-
-
-static void ag_ra(void)
-{
-  switch(ag_rpx[ag_ap]) {
-  case   1: ag_rp_1(V(0,int), V(1,const char *)); break;
-  case   2: ag_rp_2(V(0,int), V(1,const char *)); break;
-  case   3: ag_rp_3(V(0,const char *), V(1,int), V(2,char)); break;
-  case   4: V(0,char) = ag_rp_4(); break;
-  case   5: V(0,char) = ag_rp_5(); break;
-  case   6: V(0,batch *) = ag_rp_8(V(0,const char *), V(3,const char *)); break;
-  case   7: V(0,batch *) = ag_rp_9(V(0,batch *), V(2,const char *)); break;
-  case   8: V(0,const char *) = ag_rp_10(V(0,const char *)); break;
-  case   9: ag_rp_11(V(0,const char *)); break;
-  case  10: ag_rp_12(V(0,char), V(2,const char *), V(4,const char *)); break;
-  case  11: ag_rp_13(V(0,char), V(2,const char *), V(4,const char *), V(6,int)); break;
-  case  12: ag_rp_14(V(0,char), V(2,const char *), V(4,int)); break;
-  case  13: V(0,const char *) = ag_rp_15(V(1,const char *)); break;
-  case  14: ag_rp_16(V(0,const char *), V(2,int)); break;
-  case  15: ag_rp_17(V(1,int), V(3,int)); break;
-  case  16: ag_rp_18(V(1,int), V(3,int)); break;
-  case  17: ag_rp_19(V(0,const char *)); break;
-  case  18: ag_rp_20(V(0,const char *), V(2,const char *)); break;
-  case  19: ag_rp_21(V(0,const char *)); break;
-  case  20: ag_rp_22(V(0,const char *), V(2,int), V(4,int), V(6,int), V(8,int)); break;
-  case  21: ag_rp_23(V(0,const char *), V(2,const char *)); break;
-  case  22: V(0,const char *) = ag_rp_24(V(0,const char *)); break;
-  case  23: V(0,const char *) = ag_rp_25(V(0,const char *)); break;
-  case  24: V(0,const char *) = ag_rp_26(V(0,const char *)); break;
-  case  25: ag_rp_27(V(1,const char *), V(3,const char *), V(4,const char *), V(5,int)); break;
-  case  26: ag_rp_28(V(1,const char *)); break;
-  case  27: ag_rp_29(V(0,const char *)); break;
-  case  28: V(0,int) = ag_rp_30(V(0,int)); break;
-  case  29: V(0,const char *) = ag_rp_31(V(0,const char *)); break;
-  case  30: V(0,const char *) = ag_rp_32(V(0,const char *)); break;
-  case  31: V(0,const char *) = ag_rp_33(V(0,int)); break;
-  case  32: V(0,const char *) = ag_rp_34(V(0,const char *), V(1,int)); break;
-  case  33: V(0,const char *) = ag_rp_35(V(1,const char *)); break;
-  case  34: V(0,const char *) = ag_rp_36(V(0,char)); break;
-  case  35: V(0,const char *) = ag_rp_37(V(0,const char *), V(1,char)); break;
-  case  36: V(0,char) = ag_rp_38(V(0,int)); break;
-  case  37: V(0,char) = ag_rp_39(); break;
-  case  38: V(0,char) = ag_rp_40(); break;
-  case  39: V(0,int) = ag_rp_41(V(0,int)); break;
-  case  40: V(0,int) = ag_rp_42(V(0,int), V(1,int)); break;
-  case  41: V(0,int) = ag_rp_43(V(1,int)); break;
-  case  42: V(0,int) = ag_rp_44(V(0,int), V(1,int)); break;
-  case  43: V(0,int) = ag_rp_45(V(0,int)); break;
-  case  44: V(0,int) = ag_rp_46(V(0,int), V(1,int)); break;
-  case  45: V(0,int) = ag_rp_47(V(0,int)); break;
-  case  46: V(0,int) = ag_rp_48(V(0,int)); break;
-  case  47: V(0,int) = ag_rp_49(V(0,int)); break;
-  case  48: V(0,int) = ag_rp_50(V(0,int), V(1,int)); break;
-  case  49: V(0,int) = ag_rp_51(V(0,int), V(2,int)); break;
-  case  50: V(0,int) = ag_rp_52(V(0,int), V(2,int)); break;
-  case  51: V(0,int) = ag_rp_53(V(0,int), V(2,int)); break;
-  case  52: V(0,int) = ag_rp_54(V(1,int)); break;
-  case  53: V(0,int) = ag_rp_55(V(1,int)); break;
-  }
-}
-
-#define TOKEN_NAMES parse_token_names
-const char *parse_token_names[158] = {
-  "file format",
-  "identifier",
-  "white space",
-  "simple eol",
-  "quoted string",
-  "file format",
-  "",
-  "devices",
-  "",
-  "cache",
-  "",
-  "devinfo",
-  "",
-  "config",
-  "eol",
-  "",
-  "device list",
-  "",
-  "eof",
-  "",
-  "character device",
-  "",
-  "",
-  "block device",
-  "",
-  "number",
-  "name",
-  "cachedevice",
-  "",
-  "devicetype",
-  "",
-  "",
-  "",
-  "",
-  "device block",
-  "",
-  "device header spec",
-  "",
-  "device decl",
-  "",
-  "",
-  "",
-  "",
-  "ignoramus",
-  "",
-  "",
-  "batch list",
-  "batch item",
-  "",
-  "",
-  "",
-  "groupname",
-  "",
-  "procname",
-  "",
-  "class",
-  "device tail",
-  "",
-  "expr",
-  "device range",
-  "",
-  "",
-  "",
-  "hex number",
-  "auto hex",
-  "devname",
-  "letter",
-  "",
-  "",
-  "config decl",
-  "",
-  "class decl",
-  "omit decl",
-  "",
-  "mode",
-  "",
-  "single omit",
-  "",
-  "octal number",
-  "",
-  "",
-  "",
-  "",
-  "",
-  "",
-  "",
-  "",
-  "",
-  "",
-  "",
-  "",
-  "",
-  "",
-  "",
-  "",
-  "",
-  "qstring",
-  "qstring char",
-  "qchar",
-  "",
-  "digit",
-  "",
-  "",
-  "",
-  "hex digit",
-  "",
-  "octal digit",
-  "term",
-  "",
-  "factor",
-  "",
-  "",
-  "",
-  "",
-  "",
-  "",
-  "",
-  "",
-  "",
-  "",
-  "",
-  "",
-  "",
-  "",
-  "",
-  "",
-  "",
-  "",
-  "",
-  "",
-  "",
-  "",
-  "",
-  "",
-  "",
-  "",
-  "letter",
-  "",
-  "",
-  "",
-  "simple eol",
-  "identifier",
-  "quoted string",
-  "digit",
-  "",
-  "",
-  "",
-  "octal digit",
-  "",
-  "",
-  "",
-  "",
-  "",
-  "",
-  "",
-  "",
-  "",
-  "",
-
-};
-
-static char ag_msg[82];
-static char ag_mst[] = "Missing %s";
-static char ag_uet[] = "Unexpected %s";
-static char ag_ac[4] = "' '";
-
-static void ag_diagnose(void) {
-  int ag_snd = (PCB).sn, ag_k;
-  const char *ag_p;
-  const char *ag_fmt = ag_uet;
-
-  ag_k = ag_sbt[ag_snd];
-  if (*TOKEN_NAMES[ag_tstt[ag_k]] && ag_astt[ag_k + 1] == ag_action_8) {
-    ag_p = TOKEN_NAMES[ag_tstt[ag_k]];
-    ag_fmt = ag_mst;
-  }
-  else if ((PCB).token_number && *TOKEN_NAMES[(PCB).token_number]) {
-    ag_p = TOKEN_NAMES[(PCB).token_number];
-  }
-  else if (isprint((*(PCB).lab)) && (*(PCB).lab) != '\\') {
-    ag_ac[1] = (*(PCB).lab);
-    ag_p = ag_ac;
-  }
-  else ag_p = "input";
-  sprintf(ag_msg, ag_fmt, ag_p);
-  (PCB).error_message = ag_msg;
-
-
-}
-static int ag_action_1_r_proc(void);
-static int ag_action_2_r_proc(void);
-static int ag_action_3_r_proc(void);
-static int ag_action_4_r_proc(void);
-static int ag_action_1_s_proc(void);
-static int ag_action_3_s_proc(void);
-static int ag_action_1_proc(void);
-static int ag_action_2_proc(void);
-static int ag_action_3_proc(void);
-static int ag_action_4_proc(void);
-static int ag_action_5_proc(void);
-static int ag_action_6_proc(void);
-static int ag_action_7_proc(void);
-static int ag_action_8_proc(void);
-static int ag_action_9_proc(void);
-static int ag_action_10_proc(void);
-static int ag_action_11_proc(void);
-static int ag_action_8_proc(void);
-
-
-static int (*ag_r_procs_scan[])(void) = {
-  ag_action_1_r_proc,
-  ag_action_2_r_proc,
-  ag_action_3_r_proc,
-  ag_action_4_r_proc
-};
-
-static int (*ag_s_procs_scan[])(void) = {
-  ag_action_1_s_proc,
-  ag_action_2_r_proc,
-  ag_action_3_s_proc,
-  ag_action_4_r_proc
-};
-
-static int (*ag_gt_procs_scan[])(void) = {
-  ag_action_1_proc,
-  ag_action_2_proc,
-  ag_action_3_proc,
-  ag_action_4_proc,
-  ag_action_5_proc,
-  ag_action_6_proc,
-  ag_action_7_proc,
-  ag_action_8_proc,
-  ag_action_9_proc,
-  ag_action_10_proc,
-  ag_action_11_proc,
-  ag_action_8_proc
-};
-
-
-static int ag_action_10_proc(void) {
-  (PCB).btsx = 0, (PCB).drt = -1;
-  ag_track();
-  return 0;
-}
-
-static int ag_action_11_proc(void) {
-  (PCB).btsx = 0, (PCB).drt = -1;
-  (*(int *) &(PCB).vs[(PCB).ssx]) = *(PCB).lab;
-  (PCB).ssx--;
-  ag_ra();
-  (PCB).ssx++;
-  ag_track();
-  return 0;
-}
-
-static int ag_action_3_r_proc(void) {
-  int ag_sd = ag_fl[ag_ap] - 1;
-  if (ag_sd) (PCB).sn = (PCB).ss[(PCB).ssx -= ag_sd];
-  (PCB).btsx = 0, (PCB).drt = -1;
-  (PCB).reduction_token = (parse_token_type) ag_ptt[ag_ap];
-  ag_ra();
-  return 1;
-}
-
-static int ag_action_3_s_proc(void) {
-  int ag_sd = ag_fl[ag_ap] - 1;
-  if (ag_sd) (PCB).sn = (PCB).ss[(PCB).ssx -= ag_sd];
-  (PCB).btsx = 0, (PCB).drt = -1;
-  (PCB).reduction_token = (parse_token_type) ag_ptt[ag_ap];
-  ag_ra();
-  return 1;
-}
-
-static int ag_action_4_r_proc(void) {
-  int ag_sd = ag_fl[ag_ap] - 1;
-  if (ag_sd) (PCB).sn = (PCB).ss[(PCB).ssx -= ag_sd];
-  (PCB).reduction_token = (parse_token_type) ag_ptt[ag_ap];
-  return 1;
-}
-
-static int ag_action_2_proc(void) {
-  (PCB).btsx = 0, (PCB).drt = -1;
-  if ((PCB).ssx >= 38) {
-    (PCB).exit_flag = AG_STACK_ERROR_CODE;
-    PARSER_STACK_OVERFLOW;
-  }
-  (*(int *) &(PCB).vs[(PCB).ssx]) = *(PCB).lab;
-  (PCB).ss[(PCB).ssx] = (PCB).sn;
-  (PCB).ssx++;
-  (PCB).sn = ag_ap;
-  ag_track();
-  return 0;
-}
-
-static int ag_action_9_proc(void) {
-  if((PCB).drt == -1) {
-    (PCB).drt=(PCB).token_number;
-    (PCB).dssx=(PCB).ssx;
-    (PCB).dsn=(PCB).sn;
-  }
-  ag_prot();
-  (PCB).ss[(PCB).ssx] = (PCB).sn;
-  (PCB).ssx++;
-  (PCB).sn = ag_ap;
-  (PCB).rx = 0;
-  return (PCB).exit_flag == AG_RUNNING_CODE;
-}
-
-static int ag_action_2_r_proc(void) {
-  (PCB).ssx++;
-  (PCB).sn = ag_ap;
-  return 0;
-}
-
-static int ag_action_7_proc(void) {
-  --(PCB).ssx;
-  (PCB).exit_flag = AG_SUCCESS_CODE;
-  (PCB).rx = 0;
-  return 0;
-}
-
-static int ag_action_1_proc(void) {
-  (PCB).exit_flag = AG_SUCCESS_CODE;
-  ag_track();
-  return 0;
-}
-
-static int ag_action_1_r_proc(void) {
-  (PCB).exit_flag = AG_SUCCESS_CODE;
-  return 0;
-}
-
-static int ag_action_1_s_proc(void) {
-  (PCB).exit_flag = AG_SUCCESS_CODE;
-  return 0;
-}
-
-static int ag_action_4_proc(void) {
-  int ag_sd = ag_fl[ag_ap] - 1;
-  (PCB).reduction_token = (parse_token_type) ag_ptt[ag_ap];
-  (PCB).btsx = 0, (PCB).drt = -1;
-  (*(int *) &(PCB).vs[(PCB).ssx]) = *(PCB).lab;
-  if (ag_sd) (PCB).sn = (PCB).ss[(PCB).ssx -= ag_sd];
-  else (PCB).ss[(PCB).ssx] = (PCB).sn;
-  ag_track();
-  while ((PCB).exit_flag == AG_RUNNING_CODE) {
-    unsigned ag_t1 = ag_sbe[(PCB).sn] + 1;
-    unsigned ag_t2 = ag_sbt[(PCB).sn+1] - 1;
-    do {
-      unsigned ag_tx = (ag_t1 + ag_t2)/2;
-      if (ag_tstt[ag_tx] < (const unsigned char)(PCB).reduction_token) ag_t1 = ag_tx + 1;
-      else ag_t2 = ag_tx;
-    } while (ag_t1 < ag_t2);
-    ag_ap = ag_pstt[ag_t1];
-    if ((ag_s_procs_scan[ag_astt[ag_t1]])() == 0) break;
-  }
-  return 0;
-}
-
-static int ag_action_3_proc(void) {
-  int ag_sd = ag_fl[ag_ap] - 1;
-  (PCB).btsx = 0, (PCB).drt = -1;
-  (*(int *) &(PCB).vs[(PCB).ssx]) = *(PCB).lab;
-  if (ag_sd) (PCB).sn = (PCB).ss[(PCB).ssx -= ag_sd];
-  else (PCB).ss[(PCB).ssx] = (PCB).sn;
-  ag_track();
-  (PCB).reduction_token = (parse_token_type) ag_ptt[ag_ap];
-  ag_ra();
-  while ((PCB).exit_flag == AG_RUNNING_CODE) {
-    unsigned ag_t1 = ag_sbe[(PCB).sn] + 1;
-    unsigned ag_t2 = ag_sbt[(PCB).sn+1] - 1;
-    do {
-      unsigned ag_tx = (ag_t1 + ag_t2)/2;
-      if (ag_tstt[ag_tx] < (const unsigned char)(PCB).reduction_token) ag_t1 = ag_tx + 1;
-      else ag_t2 = ag_tx;
-    } while (ag_t1 < ag_t2);
-    ag_ap = ag_pstt[ag_t1];
-    if ((ag_s_procs_scan[ag_astt[ag_t1]])() == 0) break;
-  }
-  return 0;
-}
-
-static int ag_action_8_proc(void) {
-  ag_undo();
-  (PCB).rx = 0;
-  (PCB).exit_flag = AG_SYNTAX_ERROR_CODE;
-  ag_diagnose();
-  SYNTAX_ERROR;
-  {(PCB).rx = 1; ag_track();}
-  return (PCB).exit_flag == AG_RUNNING_CODE;
-}
-
-static int ag_action_5_proc(void) {
-  int ag_sd = ag_fl[ag_ap];
-  if((PCB).drt == -1) {
-    (PCB).drt=(PCB).token_number;
-    (PCB).dssx=(PCB).ssx;
-    (PCB).dsn=(PCB).sn;
-  }
-  if (ag_sd) (PCB).sn = (PCB).ss[(PCB).ssx -= ag_sd];
-  else {
-    ag_prot();
-    (PCB).ss[(PCB).ssx] = (PCB).sn;
-  }
-  (PCB).rx = 0;
-  (PCB).reduction_token = (parse_token_type) ag_ptt[ag_ap];
-  ag_ra();
-  while ((PCB).exit_flag == AG_RUNNING_CODE) {
-    unsigned ag_t1 = ag_sbe[(PCB).sn] + 1;
-    unsigned ag_t2 = ag_sbt[(PCB).sn+1] - 1;
-    do {
-      unsigned ag_tx = (ag_t1 + ag_t2)/2;
-      if (ag_tstt[ag_tx] < (const unsigned char)(PCB).reduction_token) ag_t1 = ag_tx + 1;
-      else ag_t2 = ag_tx;
-    } while (ag_t1 < ag_t2);
-    ag_ap = ag_pstt[ag_t1];
-    if ((ag_r_procs_scan[ag_astt[ag_t1]])() == 0) break;
-  }
-  return (PCB).exit_flag == AG_RUNNING_CODE;
-}
-
-static int ag_action_6_proc(void) {
-  int ag_sd = ag_fl[ag_ap];
-  (PCB).reduction_token = (parse_token_type) ag_ptt[ag_ap];
-  if((PCB).drt == -1) {
-    (PCB).drt=(PCB).token_number;
-    (PCB).dssx=(PCB).ssx;
-    (PCB).dsn=(PCB).sn;
-  }
-  if (ag_sd) {
-    (PCB).sn = (PCB).ss[(PCB).ssx -= ag_sd];
-  }
-  else {
-    ag_prot();
-    (PCB).vs[(PCB).ssx] = ag_null_value;
-    (PCB).ss[(PCB).ssx] = (PCB).sn;
-  }
-  (PCB).rx = 0;
-  while ((PCB).exit_flag == AG_RUNNING_CODE) {
-    unsigned ag_t1 = ag_sbe[(PCB).sn] + 1;
-    unsigned ag_t2 = ag_sbt[(PCB).sn+1] - 1;
-    do {
-      unsigned ag_tx = (ag_t1 + ag_t2)/2;
-      if (ag_tstt[ag_tx] < (const unsigned char)(PCB).reduction_token) ag_t1 = ag_tx + 1;
-      else ag_t2 = ag_tx;
-    } while (ag_t1 < ag_t2);
-    ag_ap = ag_pstt[ag_t1];
-    if ((ag_r_procs_scan[ag_astt[ag_t1]])() == 0) break;
-  }
-  return (PCB).exit_flag == AG_RUNNING_CODE;
-}
-
-
-void init_parse(void) {
-  unsigned ag_t1 = 0;
-  (PCB).rx = (PCB).fx = 0;
-  (PCB).ss[0] = (PCB).sn = (PCB).ssx = 0;
-  (PCB).exit_flag = AG_RUNNING_CODE;
-  (PCB).key_sp = NULL;
-  (PCB).key_state = 0;
-  (PCB).line = FIRST_LINE;
-   (PCB).column = FIRST_COLUMN;
-  (PCB).btsx = 0, (PCB).drt = -1;
-  while (ag_tstt[ag_t1] == 0) {
-    ag_ap = ag_pstt[ag_t1];
-    (ag_gt_procs_scan[ag_astt[ag_t1]])();
-    ag_t1 = ag_sbt[(PCB).sn];
-  }
-}
-
-void parse(void) {
-  (PCB).lab[(PCB).fx++] = (PCB).input_code;
-  while ((PCB).exit_flag == AG_RUNNING_CODE) {
-    while (1) {
-      unsigned char *ag_p;
-      int ag_ch;
-      if ((PCB).rx >= (PCB).fx) return;
-      ag_ch = CONVERT_CASE((PCB).lab[(PCB).rx++]);
-      if ((PCB).key_sp) {
-        if (ag_ch != *(PCB).key_sp++) {
-          (PCB).rx = (PCB).save_index;
-          (PCB).key_sp = NULL;
-          (PCB).key_state = 0;
-          break;
-        } else if (*(PCB).key_sp) continue;
-        if (ag_key_act[(PCB).key_state] == ag_cf_end_key) {
-          int ag_k1;
-          int ag_k2;
-          if ((PCB).rx >= (PCB).fx) {
-            (PCB).rx--;
-            (PCB).key_sp--;
-            return;
-          }
-          (PCB).key_sp = NULL;
-          ag_k1 = ag_key_parm[(PCB).key_state];
-          ag_k2 = ag_key_pt[ag_k1];
-          if (ag_key_itt[ag_k2 + CONVERT_CASE((PCB).lab[(PCB).rx])])
-            (PCB).rx = (PCB).save_index;
-          else {
-            (PCB).token_number =  (parse_token_type) ag_key_pt[ag_k1+1];
-            (PCB).key_state = 0;
-          }
-          break;
-        }
-        else {
-          (PCB).token_number = (parse_token_type) ag_key_parm[(PCB).key_state];
-          (PCB).key_state = 0;
-          (PCB).key_sp = NULL;
-        }
-        break;
-      }
-      if ((PCB).key_state == 0) {
-        (PCB).token_number = (parse_token_type) AG_TCV(ag_ch);
-        if (((PCB).key_state = ag_key_index[(PCB).sn]) == 0) break;
-        (PCB).save_index = 1;
-      }
-      ag_p = &ag_key_ch[(PCB).key_state];
-      while (*ag_p < ag_ch) ag_p++;
-      if (*ag_p == ag_ch) {
-        (PCB).key_state = (int)(ag_p - ag_key_ch);
-        switch (ag_key_act[(PCB).key_state]) {
-        case ag_cf_set_key: {
-          int ag_k1;
-          int ag_k2;
-          if ((PCB).rx >= (PCB).fx) {
-            (PCB).rx--;
-            return;
-          }
-          ag_k1 = ag_key_parm[(PCB).key_state];
-          ag_k2 = ag_key_pt[ag_k1];
-          (PCB).key_state = ag_key_jmp[(PCB).key_state];
-          if (ag_key_itt[ag_k2 + CONVERT_CASE((PCB).lab[(PCB).rx])]) break;
-          (PCB).save_index = (PCB).rx;
-          (PCB).token_number = (parse_token_type) ag_key_pt[ag_k1+1];
-          break;
-        }
-        case ag_set_key:
-          (PCB).save_index = (PCB).rx;
-          (PCB).token_number = (parse_token_type) ag_key_parm[(PCB).key_state];
-        case ag_jmp_key:
-          (PCB).key_state = ag_key_jmp[(PCB).key_state];
-          continue;
-        case ag_cf_end_key:
-        case ag_end_key:
-          (PCB).key_sp = ag_key_ends + ag_key_jmp[(PCB).key_state];
-          continue;
-        case ag_accept_key:
-          (PCB).token_number = (parse_token_type) ag_key_parm[(PCB).key_state];
-          (PCB).key_state = 0;
-          break;
-        case ag_cf_accept_key: {
-          int ag_k1;
-          int ag_k2;
-          if ((PCB).rx >= (PCB).fx) {
-            (PCB).rx--;
-            return;
-          }
-          ag_k1 = ag_key_parm[(PCB).key_state];
-          ag_k2 = ag_key_pt[ag_k1];
-          if (ag_key_itt[ag_k2 + CONVERT_CASE((PCB).lab[(PCB).rx])])
-            (PCB).rx = (PCB).save_index;
-          else {
-            (PCB).rx--;
-            (PCB).token_number = (parse_token_type) ag_key_pt[ag_k1+1];
-            (PCB).key_state = 0;
-          }
-          break;
-        }
-        }
-        break;
-      } else {
-        (PCB).rx = (PCB).save_index;
-        (PCB).key_state = 0;
-        break;
-      }
-    }
-
-    {
-      unsigned ag_t1 = ag_sbt[(PCB).sn];
-      unsigned ag_t2 = ag_sbe[(PCB).sn] - 1;
-      do {
-        unsigned ag_tx = (ag_t1 + ag_t2)/2;
-        if (ag_tstt[ag_tx] > (const unsigned char)(PCB).token_number)
-          ag_t1 = ag_tx + 1;
-        else ag_t2 = ag_tx;
-      } while (ag_t1 < ag_t2);
-      if (ag_tstt[ag_t1] != (PCB).token_number)  ag_t1 = ag_sbe[(PCB).sn];
-      ag_ap = ag_pstt[ag_t1];
-      (ag_gt_procs_scan[ag_astt[ag_t1]])();
-    }
-  }
-
-}
-
-
diff --git a/makedev-1.4.1/makedev.cfg b/makedev-1.4.1/makedev.cfg
deleted file mode 100644 (file)
index 3f4696e..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * User and group ownerships, and permissions, for device classes.
- */
-
-class default: root    system  0640
-class public:  root    system  0666
-class system:   root   system  0660
-class kmem:    root    kmem    0640
-class tty:     root    tty     0620
-class pty:     root    root    0666
-class cons:    root    tty     0622 // 622 for console?
-class dialout: root    uucp    0660
-class mouse:   root    system  0666
-class printer: root    daemon  0660
-class floppy:  root    floppy  0660
-class disk:    root    disk    0640
-class scsi:    root    system  0600
-class cdrom:   root    disk    0660
-class tape:    root    disk    0660
-class audio:   root    system  0666
-class ibcs2:   root    system  0666
-class scanner: root    system  0666
-
-/*
- * Things marked as omit will not be created. Ever. Be sure to check
- * here if you try to make something and nothing happens.
- */
-
-omit {
-//     hdc hdd     // hdc and hdd are now the 2nd controller.
-                    // They're now made by "hd1", and *not* by "hd".
-       xdc xdd
-       sdc sdd sde sdf sdg sdh
-}
diff --git a/makedev-1.4.1/makedev.cfg.5 b/makedev-1.4.1/makedev.cfg.5
deleted file mode 100644 (file)
index 46a2642..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-.\" -*- nroff -*-
-.TH MAKEDEV.cfg 5 "January 1995" "Version 1.4"
-.SH NAME
-MAKEDEV.cfg \- configuration for MAKEDEV(8)
-.SH DESCRIPTION
-.B MAKEDEV.cfg
-is a text file that tells
-.BR MAKEDEV (8)
-what to do (and, equally importantly, what not to do.)
-Unlike
-.BR DEVINFO (5),
-which is meant to be centrally maintained, it contains all local
-configuration for a particular site and all customization.
-There are basically two kinds of declaration in this file: a "class"
-declaration and an "omit" declaration.
-.LP
-A class declaration has the form 
-.RS
-
-.RI class " name " : " owner group-owner permissions"
-
-.RE
-This says that any devices placed in the specified class by 
-.B DEVINFO 
-should be created with this ownership and these permissions. A sample
-entry might be
-.RS
-.nf
-
-class public:  root    system  0666
-
-.fi
-.RE
-This says that devices marked "public" should be owned by root.system
-and have mode 666.
-.LP
-An omit declaration has the form
-.RS
-
-.RI "omit { " device... " }"
-
-.RE
-This causes the specified devices to never be created, 
-.B "EVEN IF EXPLICITLY SPECIFIED."
-Use caution when setting this up.  The intent is to be able to run
-.B "\"MAKEDEV update\""
-and not have it create all sorts of useless devices you'd never use. 
-.SH "SEE ALSO"
-.BR MAKEDEV (8),
-.BR DEVINFO (5)
diff --git a/makedev-1.4.1/makedev.h b/makedev-1.4.1/makedev.h
deleted file mode 100644 (file)
index be620b4..0000000
+++ /dev/null
@@ -1,78 +0,0 @@
-#ifndef MAKEDEV_H
-#define MAKEDEV_H
-
-void init_parse(void);
-void parse(void);
-typedef union {
-  int alignment;
-  char ag_vt_2[sizeof(int)];
-  char ag_vt_3[sizeof(char)];
-  char ag_vt_4[sizeof(batch *)];
-  char ag_vt_5[sizeof(const char *)];
-} parse_vs_type;
-
-typedef enum {
-  parse_white_space_token = 2, parse_file_format_token = 5,
-  parse_devices_token = 7, parse_cache_token = 9, parse_devinfo_token = 11,
-  parse_config_token = 13, parse_eol_token, parse_device_list_token = 16,
-  parse_eof_token = 18, parse_character_device_token = 20,
-  parse_block_device_token = 23, parse_number_token = 25, parse_name_token,
-  parse_cachedevice_token, parse_devicetype_token = 29,
-  parse_device_block_token = 34, parse_device_header_spec_token = 36,
-  parse_device_decl_token = 38, parse_ignoramus_token = 43,
-  parse_batch_list_token = 46, parse_batch_item_token,
-  parse_groupname_token = 51, parse_procname_token = 53,
-  parse_class_token = 55, parse_device_tail_token, parse_expr_token = 58,
-  parse_device_range_token, parse_hex_number_token = 63,
-  parse_auto_hex_token, parse_devname_token, parse_config_decl_token = 69,
-  parse_class_decl_token = 71, parse_omit_decl_token, parse_mode_token = 74,
-  parse_single_omit_token = 76, parse_octal_number_token = 78,
-  parse_qstring_token = 96, parse_qstring_char_token, parse_qchar_token,
-  parse_hex_digit_token = 104, parse_term_token = 107,
-  parse_factor_token = 109, parse_letter_token = 136,
-  parse_simple_eol_token = 140, parse_identifier_token,
-  parse_quoted_string_token, parse_digit_token,
-  parse_octal_digit_token = 147
-} parse_token_type;
-
-typedef struct {
-  parse_token_type token_number, reduction_token, error_frame_token;
-  int input_code;
-  int input_value;
-  int line, column;
-  int ssx, sn, error_frame_ssx;
-  int drt, dssx, dsn;
-  int ss[38];
-  parse_vs_type vs[38];
-  int bts[38], btsx;
-  unsigned char * pointer;
-  unsigned char * la_ptr;
-  int lab[19], rx, fx;
-  unsigned char *key_sp;
-  int save_index, key_state;
-  char *error_message;
-  char read_flag;
-  char exit_flag;
-} parse_pcb_type;
-
-
-#ifndef PRULE_CONTEXT
-#define PRULE_CONTEXT(pcb)  (&((pcb).cs[(pcb).ssx]))
-#define PERROR_CONTEXT(pcb) ((pcb).cs[(pcb).error_frame_ssx])
-#define PCONTEXT(pcb)       ((pcb).cs[(pcb).ssx])
-#endif
-
-
-#ifndef AG_RUNNING_CODE_CODE
-/* PCB.exit_flag values */
-#define AG_RUNNING_CODE         0
-#define AG_SUCCESS_CODE         1
-#define AG_SYNTAX_ERROR_CODE    2
-#define AG_REDUCTION_ERROR_CODE 3
-#define AG_STACK_ERROR_CODE     4
-#define AG_SEMANTIC_ERROR_CODE  5
-#endif
-
-extern parse_pcb_type parse_pcb;
-#endif
-
diff --git a/makedev-1.4.1/makedev.syn b/makedev-1.4.1/makedev.syn
deleted file mode 100644 (file)
index 26ccef3..0000000
+++ /dev/null
@@ -1,994 +0,0 @@
-{
-/*
- * makedev.c: Generate /dev entries
- *
- * Based on the MAKEDEV shell script, version 2.0, distributed with
- * util-linux 1.10 and written by Nick Holloway. 
- *
- * A number of bugs were fixed, and some additional features added.
- * Written 10-Dec-94 by David A. Holland, dholland@husc.harvard.edu
- *
- * Copyright 1994, 1995. All rights reserved. 
- * See the file LEGAL.NOTICE for conditions of redistribution.
- *
- * Bugs:
- *    None known right now.
- *
- * History:
- *
- * Version 1.4: 15-Jan-95  Wrote man pages. Now reads DEVINFO.local.
- * Version 1.3: 31-Dec-94  Bug fixes. Added batches. Added omits.
- * Version 1.2: 11-Dec-94  Add configuration file parsing.
- * Version 1.1: 11-Dec-94  Distinguish block and character devices in the
- *    table of major device numbers. Changed the name and format of the
- *    update cache file to include the type. It appears that the old script
- *    was broken in this regard.
- * Version 1.0: 10-Dec-94  Initial version.
- */
-
-static const char *version = "MAKEDEV-C version 1.4";
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdarg.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <pwd.h>
-#include <grp.h>
-#include <sys/stat.h>
-
-#define YES 1
-#define NO 0
-
-static int isverbose=NO;  /* flag: print out what we do? */
-static int deletion=NO;   /* flag: delete instead of create */
-static int donothing=NO;  /* flag: don't actually do anything */
-
-/*
- * Proto for main operative function.
- */
-typedef enum { M_CREATE, M_OMIT } makeopts;
-static void make(const char *batch_or_grp_or_devname, makeopts);
-
-/*
- * Roll over and die.
- */
-static void crash(const char *msg) {
-  fprintf(stderr, "MAKEDEV: %s\n", msg);
-  exit(1);
-}
-
-/*
- * Print a warning.
- */
-static void warn(const char *format, ...) {
-  va_list ap;
-  va_start(ap, format);
-  fprintf(stderr, "MAKEDEV: ");
-  vfprintf(stderr, format, ap);
-  fprintf(stderr, "\n");
-  va_end(ap);
-}
-
-/*
- * Translate string name to uid.
- */
-static uid_t name2uid(const char *name) {
-  struct passwd *p = getpwnam(name);
-  if (!p) warn("undefined user: %s, using uid 0", name);
-  return p ? p->pw_uid : 0;  /* make things owned by root by default */
-}
-
-/*
- * Translate string name to gid.
- */
-static gid_t name2gid(const char *name) {
-  struct group *g = getgrnam(name);
-  if (!g) warn("undefined group: %s, using gid 0", name);
-  return g ? g->gr_gid : 0;  /* group 0 is a good default too */
-}
-
-/*
- * Proto for parser.
- */
-static void doparse(FILE *f, int filetype, const char *filename);
-
-/************************* device classes *************************/
-
-/*
- * A device class is a string attached to the device which tells us
- * what set of permissions and ownership should be used. This is the
- * table of classes.
- */
-
-typedef struct {
-    const char *classname;
-    const char *owner;
-    const char *group;
-    int mode;
-} devclass;
-
-#define MAXCLASSES 32
-static devclass classes[MAXCLASSES];
-static int nclasses=0;
-
-static void addclass(const char *name, const char *o, const char *g, int m) {
-  if (nclasses>=MAXCLASSES) crash("out of space for device classes");
-  classes[nclasses].classname = name;
-  classes[nclasses].owner = o;
-  classes[nclasses].group = g;
-  classes[nclasses].mode = m;
-  nclasses++;
-  name2uid(o);  /* check for undefined users/groups */
-  name2gid(g);
-}
-
-static void loadclasses(void) {
-  FILE *f = fopen("MAKEDEV.cfg", "r");
-  if (!f) f = fopen("../MAKEDEV.cfg", "r");
-  if (!f) f = fopen("/etc/makedev.cfg", "r");
-  if (!f) crash("can't find MAKEDEV.cfg");
-  doparse(f, 4, "MAKEDEV.cfg");
-  fclose(f);
-}
-
-/*
- * Return the index into the above table for a particular class name.
- */
-static int which_class(const char *name) {
-  int i;
-  for (i=0; i<nclasses; i++)
-    if (!strcmp(classes[i].classname, name)) return i;
-  return 0;
-}
-
-/*
- * Produce an "ls -l"-ish mode string.
- */
-static const char *modestring(int mode) {
-  static char rv[12];
-  int i,z;
-  strcpy(rv, "rwxrwxrwx");
-  for (i=8,z=1; i>=0; i--, z<<=1) if (!(mode&z)) rv[i]='-';
-  return rv;
-}
-
-/*
- * Create (or delete, or update) a block or character device.
- */
-static void class_makedev(const char *name, const char *class,
-                         int major, int minor, char type) {
-  int x = which_class(class), mode = classes[x].mode;
-  const char *owner = classes[x].owner, *group = classes[x].group;
-  if (isverbose) {
-    if (deletion) printf("rm -f %s\n", name);
-    else printf("%c%s   1 %-8s %-8s %3d, %3d for %s\n", type,
-               modestring(mode), owner, group, major, minor, name);
-  }
-  if (donothing) return;
-  if (unlink(name) && deletion) warn("Couldn't remove %s\n", name);
-  if (!deletion) {
-    dev_t q = (major<<8) | minor;
-    if (mknod(name, type=='c' ? S_IFCHR : S_IFBLK,  q) ||
-       chown(name, name2uid(owner), name2gid(group)) ||
-       chmod(name, mode)) {
-      warn("couldn't create %s: %s", name, strerror(errno));
-    }
-  }
-}
-
-/************************* major number list *************************/
-
-/*
- * In Linux device major numbers can be allocated dynamically, so we go
- * look in /proc/devices to see what they are. This keeps track of things.
- */
-
-typedef struct {
-    const char *procname;
-    int flag;
-} majorentry;
-
-#define MAXMAJORS 256
-static majorentry cmajors[MAXMAJORS];  /* initialized to 0 */
-static majorentry bmajors[MAXMAJORS];  /* initialized to 0 */
-static int no_proc=0;   /* true if we didn't find /proc/devices */
-
-/*
- * Store the name associated with a particular major device number.
- */
-static void set_major(const char *procname, int ischar, int num) {
-  if (num<0 || num>255) {
-    warn("warning: got bogus major number %d for %s", num, procname);
-    return;
-  }
-  if (ischar) cmajors[num].procname=procname;
-  else bmajors[num].procname=procname;
-}
-
-/*
- * Look up a major device number by name; return the default value
- * if provided. A default value of -1 implies the device is only
- * dynamic, and so if there's no entry we shouldn't even note its
- * existence.
- */
-static int get_major(const char *procname, int ischar, int defaalt) {
-  int i;
-  if (!procname) return defaalt;
-  if (ischar) {
-    for (i=0; i<MAXMAJORS; i++)
-      if (cmajors[i].procname && !strcmp(cmajors[i].procname, procname))
-       return i;
-  }
-  else {
-    for (i=0; i<MAXMAJORS; i++)
-      if (bmajors[i].procname && !strcmp(bmajors[i].procname, procname))
-       return i;
-  }
-  return defaalt;
-}
-
-/*
- * Read /proc/devices.
- */
-static void setup_majors(void) {
-  FILE *f = fopen("/proc/devices", "r");
-  if (!f) {
-    fprintf(stderr, "MAKEDEV: warning: can't read /proc/devices\n");
-    no_proc = 1;
-    return;
-  }
-  doparse(f, 1, "/proc/devices");
-  fclose(f);
-}
-
-/************************** procname list *************************/
-
-/*
- * The names found in /proc/devices aren't usually quite the same
- * as the names we use. This is a mapping between the two namespaces.
- */
-typedef struct {
-    const char *procname;
-    const char *groupname;
-} namealias;
-
-#define MAXALIASES 100
-static namealias aliases[MAXALIASES];
-static int naliases=0;
-
-static void addalias(const char *procname, const char *groupname) {
-  if (naliases>=MAXALIASES) crash("out of space for aliases");
-  aliases[naliases].procname = procname;
-  aliases[naliases].groupname = groupname;
-  naliases++;
-}
-
-static void ignore_procname(const char *procname) {
-  addalias(procname, NULL);
-}
-
-static const char *procnameof(const char *groupname) {
-  int i;
-  for (i=0; i<naliases; i++) if (!strcmp(groupname, aliases[i].groupname))
-    return aliases[i].procname;
-  return NULL;
-}
-
-static const char *groupnameof(const char *procname) {
-  int i;
-  for (i=0; i<naliases; i++) if (!strcmp(procname, aliases[i].procname))
-    return aliases[i].groupname;
-  return NULL;
-}
-
-/************************* batch list *************************/
-/*
- * Create a device "batch" - a bunch of devices or groups.
- * This is used for "generic" and automatically for disk entries.
- * (Disk entries for "hd" come up with groups hda, hdb, etc., but
- * "hd" itself needs to run these too.)
- */
-#define MAXTARGETS 32
-#define MAXBATCHES 16
-
-typedef struct {
-    const char *name;  /* name of batch */
-    const char *targets[MAXTARGETS];
-    int ntargets;
-    int busy;
-} batch;
-
-static batch batches[MAXBATCHES];
-static int nbatches=0;
-
-/*
- * Start a new batch.
- */
-static batch *addbatch(const char *name) {
-  batch *b;
-  if (nbatches>=MAXBATCHES) crash("Out of space for batches");
-  b = &batches[nbatches++];
-  b->name = name;
-  b->busy = NO;
-  return b;
-}
-
-/*
- * Add something to a batch.
- */
-static batch *add2batch(batch *b, const char *target) {
-  if (b->ntargets>=MAXTARGETS) {
-    warn("Too many targets for batch %s (max %d)", b->name, MAXTARGETS);
-    return b;
-  }
-  b->targets[b->ntargets++] = target;
-  return b;
-}
-
-/*
- * Run a batch.
- */
-static void run_batch(const batch *b, makeopts m) {
-  int i;
-  for (i=0; i<b->ntargets; i++) make(b->targets[i], m);
-}
-
-/*
- * Try to run a batch; returns YES if it found one.
- */
-static int try_run_batch(const char *name, makeopts m) {
-  int i;
-  for (i=0; i<nbatches; i++) {
-    if (!strcmp(name, batches[i].name)) {
-      if (batches[i].busy) {
-       warn("Found recursive batch definition for %s", batches[i].name);
-       continue;
-      }
-      batches[i].busy=YES;
-      run_batch(&batches[i], m);
-      batches[i].busy=NO;
-      return YES;
-    }
-  }
-  return NO;
-}
-
-/************************* device list *************************/
-
-/*
- * Structure to remember the properties of an individual device.
- * NOTE: if the device is actually a symbolic link, the "class"
- * member is used to store the thing it should be linked to.
- */
-typedef struct {
-    const char *name;   /* file name to create */
-    const char *grp;    /* device "group" name (e.g. "busmice") */
-    const char *class;  /* device class ( -> owner and permissions) */
-    int major, minor;   /* device number */
-    char type;          /* 'c', 'b', or 'l' for symbolic link */
-    int omit;           /* don't make me if this is nonzero */
-} device;
-
-/*
- * Create a device (link or actual "special file") - special files are
- * passed on to class_makedev().
- */
-void makedev(device *d, makeopts m) {
-  if (m==M_OMIT) {
-    d->omit=1;
-  }
-  if (d->omit==1) return;
-  if (d->type=='l') {
-    if (isverbose) {
-      if (deletion) printf("rm -f %s\n", d->name);
-      else printf("lrwxrwxrwx   %s -> %s\n", d->name, d->class);
-    }
-    if (donothing) return;
-    if (unlink(d->name) && deletion) warn("Couldn't remove %s\n", d->name);
-    if (!deletion) {
-      if (symlink(d->class, d->name)) /* class holds thing pointed to */
-       warn("couldn't link %s -> %s: %s", d->name, d->class, strerror(errno));
-    }
-  }
-  else class_makedev(d->name, d->class, d->major, d->minor, d->type);
-}
-
-/*
- * Array of devices. We allocate it once from main(); it doesn't grow.
- * Should maybe make it growable sometime. This keeps track of all possible
- * devices. We build this thing first, and then create devices from it as
- * requested.
- */
-static device *devices = NULL;
-static int maxdevices, ndevices;
-
-/*
- * Allocate space for the device array.
- */
-static void allocate_devs(int nd) {
-  devices = malloc(nd * sizeof(device));
-  if (!devices) crash("Out of memory");
-  ndevices = 0;
-  maxdevices = nd;
-}
-
-/*
- * Check all the devices for having valid device classes.
- */
-static void check_classes(void) {
-  int i;
-  const char *q=NULL;
-  for (i=0; i<ndevices; i++) 
-    if (devices[i].type!='l' && !devices[i].omit &&
-       which_class(devices[i].class)<0) {
-      if (!q || strcmp(q, devices[i].class)) {
-       warn("Invalid device class %s for %s", 
-            devices[i].class, devices[i].name);
-       q = devices[i].class;
-      }
-      devices[i].class = "default";
-    }
-}
-
-/*
- * Create an entry in the device table for a single device.
- */
-static void init(const char *name, const char *grp, const char *class,
-                int major, int minor, int type) {
-  if (major < 0) return;
-  if (!strchr("bcl", type)) {
-    warn("invalid device type %c for %s (skipping)", type, name);
-    return;
-  }
-  if (ndevices>=maxdevices) crash("out of space for devices");
-  devices[ndevices].name = name;
-  devices[ndevices].grp = grp;
-  devices[ndevices].class = class;
-  devices[ndevices].major = major;
-  devices[ndevices].minor = minor;
-  devices[ndevices].type = type;
-  devices[ndevices].omit = 0;
-  ndevices++;
-}
-
-/*
- * Create an entry for a symbolic link "device", such as /dev/fd
- * (which is a symbolic link to /proc/self/fd)
- */
-static void initlink(const char *name, const char *grp, const char *target) {
-  init(name, grp, target, 0, 0, 'l');
-}
-
-/*
- * Init lots of devices. This creates a number of devices, numbered between
- * lo and hi. The idea is that "base" contains a %d or %x (or something like
- * that) in it which pulls in the number. The device group can also do this,
- * though this will in most cases not be useful. "baseminor" is the minor
- * number of the first device created.
- */
-static void initlots(const char *base, int lo, int hi, const char *grp,
-                    const char *class,
-                    int maj, int baseminor, int type) {
-  char buf[32], gbuf[32];
-  int i;
-  if (maj<0) return;
-  for (i=lo; i<hi; i++) {
-    sprintf(buf, base, i);
-    if (grp) sprintf(gbuf, grp, i);  /* grp is permitted to contain a %d */
-    init(strdup(buf), grp ? strdup(gbuf) : NULL, class, 
-        maj, baseminor+i-lo, type);
-  }
-}
-
-/*
- * Init a whole (hard) disk's worth of devices - given `hd', it makes
- * hda1...hda8 through hdd1...hdd8 in one fell swoop. "low" and "high"
- * are the letters to use ('a' and 'd' for the previous example).
- * "nparts" is the number of partitions to create, ordinarily 8.
- * "maj" is the major device number; minmult is the multiplier for the
- * minor number. That is, if hda starts at 0, and hdb starts at 64, minmult
- * is 64.
- *
- * Note that it creates "hda", "hdb", etc. too, and puts things in the
- * groups "hda", "hdb", etc. as appropriate. The class is set to "disk".
- */
-static void initdisk(const char *base, int low, int high, int nparts,
-             int maj, int minmult) {
-  char buf[16], buf2[16];
-  int i;
-  batch *b;
-  if (maj<0) return;
-  if (low>=high) return;
-  b = addbatch(base);
-  for (i=low; i<=high; i++) {
-    char *q;
-    sprintf(buf, "%s%c", base, i);
-    q = strdup(buf);
-    init(q, q, "disk", maj, (i-low)*minmult,   'b');
-    strcpy(buf2, buf);
-    strcat(buf2, "%d");
-    initlots(buf2, 1, nparts, buf, "disk", maj, (i-low)*minmult+1, 'b');
-    add2batch(b, q);
-  }
-}
-
-static void initdevs(void) {
-  FILE *f = fopen("DEVINFO", "r");
-  if (!f) f = fopen("../DEVINFO", "r");
-  if (!f) f = fopen("/etc/devinfo", "r");
-  if (!f) crash("Can't find DEVINFO");
-  doparse(f,3, "DEVINFO");
-  fclose(f);
-  f = fopen("DEVINFO.local", "r");
-  if (!f) f = fopen("../DEVINFO.local", "r");
-  if (!f) f = fopen("/etc/devinfo.local", "r");
-  if (!f) f = fopen("/usr/local/etc/devinfo.local", "r");
-  if (f) {
-    doparse(f,3, "DEVINFO.local");
-    fclose(f);
-  }
-}
-
-/************************** update *************************/
-
-/*
- * Call make() with our names for something that appeared in /proc/devices.
- */
-
-static void transmake(const char *procname, makeopts m) {
-  const char *gname = groupnameof(procname);
-  if (gname) make(gname, m);
-}
-
-/*
- * Update a device that appeared in MAKEDEV.cache. Whenever we update,
- * we save what we did into MAKEDEV.cache; this lets us avoid doing
- * them over the next time. We only do something if the device has
- * disappeared or the major number has changed.
- *
- * Note that this caching made the shell version go much faster (it took
- * around 15 seconds with the cache, vs. over a minute if the cache was
- * blown away.) For us, it still does, but it hardly matters: it shaves
- * one second off a two-second execution.
- *
- * Also note the old script used DEVICES instead of MAKEDEV.cache. We
- * changed because the old file didn't record whether something was
- * a block or character device; since the sets of numbers are independent,
- * this was bound to break.
- */
-static void update2(const char *name, int ischar, int major) {
-  int now = get_major(name, ischar, -1);
-  if (now<0) {
-    deletion = 1;   /* must have been zero if we're doing an update */
-    transmake(name, M_CREATE);
-    deletion = 0;
-  }
-  else if (now!=major) { /* oops, it moved; remake it */
-    transmake(name, M_CREATE);
-    if (ischar) cmajors[now].flag=1;
-    else bmajors[now].flag=1;
-  }
-  else {
-    if (ischar) cmajors[now].flag=1; /* unchanged; inhibit remaking it */
-    else bmajors[now].flag=1; /* unchanged; inhibit remaking it */
-  }
-}
-
-static void updatefromcache(const char *name, int major, int type) {
-  update2(name, type=='c', major);
-}
-
-
-/*
- * Update. Read the information stored in MAKEDEV.cache from the last
- * update; fix anything that changed; then create any new devices that
- * weren't listed the last time. (We use the "flag" field in the
- * majors array to check this.) At that point, write out a new
- * cache file.
- */
-#define CACHEFILE "MAKEDEV.cache"
-
-static void update(void) {
-  FILE *f;
-  int i;
-  if (no_proc) { warn("Couldn't read anything from /proc/devices"); return; }
-  if (deletion) { warn("update and -d are incompatible"); return; }
-  f = fopen(CACHEFILE, "r");
-  if (f) {
-    doparse(f, 2, CACHEFILE);
-    fclose(f);
-  }
-  for (i=0; i<MAXMAJORS; i++) {
-    if (cmajors[i].procname && !cmajors[i].flag) {
-      transmake(cmajors[i].procname, M_CREATE);
-      cmajors[i].flag=1;
-    }
-    if (bmajors[i].procname && !bmajors[i].flag) {
-      transmake(bmajors[i].procname, M_CREATE);
-      bmajors[i].flag=1;
-    }
-  }
-  if (donothing) return;
-  f = fopen(CACHEFILE, "w");
-  if (f) {
-    for (i=0; i<MAXMAJORS; i++)  {
-      if (cmajors[i].procname) fprintf(f, "%s %d char\n", cmajors[i].procname, i);
-      if (bmajors[i].procname) fprintf(f, "%s %d block\n", bmajors[i].procname, i);
-    }
-    fclose(f);
-  }
-  else warn("warning: can't write MAKEDEV.cache");
-}
-
-/************************* work *************************/
-
-/*
- * Create (or delete, etc. according to flags) a device or device group.
- * The "generic" group is handled specially by recursing once.
- * "update" is handled specially; see update() below.
- * "local" issues a warning; people should use DEVINFO.local instead.
- */
-static void make(const char *what, makeopts m) {
-  int i;
-  if (!strcmp(what, "update")) {
-    if (m!=M_CREATE) warn("update not compatible with those options");
-    else update();
-  }
-  else if (!strcmp(what, "local")) {
-    warn("The local target is obsolete.");
-  }
-  else if (!try_run_batch(what, m)) {
-    int found=0;
-    for (i=0; i<ndevices; i++) {
-      if ((devices[i].grp && !strcmp(what, devices[i].grp)) ||
-          !strcmp(what, devices[i].name)) {
-        makedev(&devices[i], m);
-        found = 1;
-      }
-    }
-    if (!found) warn("unknown device or device group %s", what);
-  }
-}
-
-/*
- * A major improvement over the shell version...
- */
-static void usage(void) {
-  printf("MAKEDEV usage:\n");
-  printf("    MAKEDEV [-vdcn] device [device...]\n");
-  printf("      -v                 Verbose output\n");
-  printf("      -d                 Remove specified devices\n");
-  printf("      -c                 Create devices (default)\n");
-  printf("      -n                 Don't actually do anything (implies -v)\n");
-  printf("      -V                 Print version information\n");
-  printf("\n");
-}
-
-/*
- * We should use getopt one of these days.
- */
-int main(int argc, char **argv) {
-  int i,j, done=0;
-  for (i=1; i<argc && argv[i][0]=='-' && !done; i++)
-    for (j=1; argv[i][j] && !done; j++) switch(argv[i][j]) {
-        case '-': done=1; break;
-       case 'v': isverbose = 1; break;
-       case 'd': deletion = 1; break;
-       case 'c': deletion = 0; break;
-       case 'n': donothing = 1; isverbose = 1; break;
-       case 'h': usage(); exit(0);
-       case 'V': printf("MAKEDEV: %s\n", version); exit(0);
-       default: fprintf(stderr, "MAKEDEV: unknown flag %c\n", argv[i][j]);
-         exit(1);
-    }
-  setup_majors();      /* read major device numbers from /proc */
-  allocate_devs(1500); /* make space to hold devices */
-  initdevs();          /* set up device structures */
-  loadclasses();       /* load device classes from config file */
-  check_classes();     /* make sure no devices have bogus classes */
-  if (i==argc) warn("didn't do anything; try -h for help.");
-  else for (; i<argc; i++) make(argv[i], M_CREATE);
-  return 0;
-}
-
-}
-{
-/************************* parsing support *************************/
-
-/*
- * Don't use the built-in error printing.
- */
-#define SYNTAX_ERROR
-#define PARSER_STACK_OVERFLOW
-#define REDUCTION_TOKEN_ERROR
-
-static void doparse(FILE *f, int filetype, const char *filename) {
-  char *x;
-  int i=0, len;
-  if (filetype<1 || filetype>4) crash("tried to parse a bad file type");
-  if (filetype!=1) { /* /proc/devices won't stat intelligently */
-    struct stat buf;
-    if (fstat(fileno(f), &buf)) crash("fstat failed?!?");
-    len = buf.st_size;
-  }
-  else len=1023;
-  x = malloc(len+1);
-  if (!x) crash("Out of memory");
-
-  len = fread(x, 1, len, f);  /* it shouldn't return a short count... */
-  if (len<0) crash("fread failed?!?");
-  x[len]=0;
-
-  init_parse();
-  PCB.input_code = filetype+'0';
-  parse();
-  PCB.column--; /* correct for the filetype token */
-  while (!PCB.exit_flag) {
-    PCB.input_code = x[i++];
-    parse();
-  }
-  if (PCB.exit_flag == AG_SYNTAX_ERROR_CODE) {
-    warn("syntax error: %s, line %d, column %d in file %s",
-         PCB.error_message, PCB.line, PCB.column, filename);
-    crash("Sorry, can't continue.");
-  }
-  else if (PCB.exit_flag != AG_SUCCESS_CODE) {
-    crash("parser stack overflow!");
-  }
-}
-
-#define STRINGSIZE 8192
-static char string_space[STRINGSIZE];
-static int stringptr=0;
-
-static const char *string_start(int c) {
-  if (stringptr>=STRINGSIZE) crash("out of string space");
-  return string_space[stringptr]=c, string_space+stringptr++;
-}
-
-static void string_push(int c) {
-  if (stringptr>=STRINGSIZE) crash("out of string space");
-  string_space[stringptr++] = c;
-}
-
-static void string_finish(void) {
-  string_push(0);
-}
-
-}
-/************************* syntax begins here *************************/
-
-/*
- * We read four different file formats here:
- *     /proc/devices   1
- *     MAKEDEV.cache   2
- *     DEVINFO         3
- *     MAKEDEV.config  4
- */
-
-
-[
-  sticky {identifier}
-  disregard white space
-  lexeme {identifier, simple eol, quoted string}
-  distinguish keywords {'a-z' + 'A-Z'}
-  event driven
-  parser name = parse
-  line numbers
-]
-
-(void) file format $
-  -> '1', devices
-  -> '2', cache
-  -> '3', devinfo
-  -> '4', config
-
-
-/************************* /proc/devices *************************/
-
-(void) devices
-  -> eol?, device list..., eof
-
-(void) device list
-  -> "Character devices:", eol, character device...
-  -> "Block devices:", eol, block device...
-
-(void) character device
-  -> number:n, name:s, eol = set_major(s,YES,n);
-
-(void) block device
-  -> number:n, name:s, eol = set_major(s,NO,n);
-
-/************************* cache *************************/
-
-(void) cache
-  -> eol?, cachedevice..., eof
-
-(void) cachedevice
-  -> name:n, number:maj, devicetype:t, eol = updatefromcache(n,maj,t);
-
-(char) devicetype
-  -> 'b'       = 'b';
-  -> 'c'       = 'c';
-  -> "block"   = 'b';
-  -> "char"    = 'c';
-
-/************************* devinfo *************************/
-
-(void) devinfo
-  -> eol?, device block..., eof
-
-(void) device block
-  -> device header spec, '{', eol?, device decl?..., '}', eol?
-  -> device header spec, eol?, device decl
-  -> "ignore", '{', eol?, ignoramus..., '}', eol?
-  -> "batch", batch list, '}', eol?
-
-(batch *) batch list
-  -> name:n, '{', eol?, batch item:i, eol?  = add2batch(addbatch(n), i);
-  -> batch list:b, [',', eol?], batch item:i, eol? = add2batch(b,i);
-
-(const char *) batch item
-  -> name:n = n;
-
-(void) ignoramus
-  -> name:n, eol?, [',', eol?] = ignore_procname(n);
-
-{
-  static const char *cur_group=NULL, *cur_class=NULL;
-  static int cur_type;
-  static int cur_maj=0, cur_min=0, cur_bot=0, cur_top=0, ishex=0;
-
-  static void dhsproc(const char *g, const char *p, int t, int m) {
-    cur_group = g;
-    cur_type = t;
-    cur_maj = get_major(p, (t=='c'), m);
-    cur_min = 0;
-    cur_bot = cur_top = ishex = 0;
-    if (p) addalias(p,g);
-  }
-
-  static void newdev(const char *n) {
-    if (cur_maj<0) return;
-    init(n, cur_group, cur_class, cur_maj, cur_min, cur_type);
-  }
-  static void devrange(const char *n, const char *n1) {
-    char temp[32];
-    if (cur_maj<0) return;
-    sprintf(temp, "%s%%d%s", n, n1 ? n1 : "");
-    initlots(temp, cur_bot, cur_top, cur_group, cur_class,
-            cur_maj, cur_min, cur_type);
-  }
-  static void doinitlink(const char *src, const char *tg) {
-    if (cur_maj>=0) initlink(src, cur_group, tg);
-  }
-}
-
-(void) device header spec
-  -> devicetype:t, '(', groupname:g, '=', procname:p, ')' = dhsproc(g,p,t,-1);
-  -> devicetype:t, '(', groupname:g, '=', procname:p,
-                  ',', number:m, ')'                    = dhsproc(g,p,t,m);
-  -> devicetype:t, '(', groupname:g, ',', number:m, ')' = dhsproc(g,NULL,t,m);
-
-(const char *) class
-  -> '(', name:classname, ')' = classname;
-
-(void) device tail
-  -> class:c, ':', expr:min, eol = (cur_class=c, cur_min=min);
-
-(void) device range
-  -> '[', number:a, '-', number:b, ']'       = cur_bot=a, cur_top=b, ishex=0;
-  -> '[', hex number:a, '-', auto hex:b, ']' = cur_bot=a, cur_top=b, ishex=1;
-
-(void) device decl
-  -> devname:n,                           device tail = newdev(n);
-  -> devname:n, device range, devname:n1, device tail = devrange(n,n1);
-  -> devname:n, device range,             device tail = devrange(n,NULL);
-  -> devname:n, '[', letter:a, '-', letter:b,']', number:p,'/',number:m, eol =
-        initdisk(n, a, b, p, cur_maj, m);
-  -> devname:n, "->", name:tg, eol = doinitlink(n, tg);
-
-(const char *) devname -> name:n = n;
-(const char *) groupname -> name:n = n;
-(const char *) procname -> name:n = n;
-
-
-/************************* config *************************/
-
-(void) config
-  -> eol?, config decl..., eof
-
-(void) config decl
-  -> class decl
-  -> omit decl
-
-(void) class decl
-  -> "class", name:n, ':', name:o, name:g, mode:m, eol = addclass(n,o,g,m);
-
-(void) omit decl
-  -> "omit", name:n, eol = make(n, M_OMIT);
-  -> "omit", '{', eol?, single omit..., '}', eol?
-
-(void) single omit
-  -> name:n, eol?, [',', eol?] = make(n, M_OMIT);
-
-(int) mode
- -> octal number:n = n;
-
-/************************* support *************************/
-
-eof         = -1 + 0
-digit       = '0-9'
-letter      = 'a-z' + 'A-Z' + '-' + '_'
-octal digit = '0-7'
-qchar       = 32..126 - '\\' - '"'
-
-(void) white space
- -> ' ' + '\t' + '\r'
- -> "/*", ~eof?..., "*/"
-
-
-(void) eol
- -> simple eol...
-
-(void) simple eol
- -> [{"//" | '#'}, ~'\n'?...], '\n'
-
-(const char *) name
-  -> identifier:s = string_finish(), s;
-  -> quoted string:s = s;
-
-(const char *) identifier
-  -> letter:c                       = string_start(c);
-  -> identifier:s, letter+digit:c   = string_push(c), s;
-
-(const char *) quoted string
-  -> '"', qstring:s, '"' = string_finish(), s;
-
-(const char *) qstring
-  -> qstring char:c            = string_start(c);
-  -> qstring:s, qstring char:c = string_push(c), s;
-
-(char) qstring char
-  -> qchar:c     = c;
-  -> '\\', '\\'  = '\\';
-  -> '\\', '"'   = '"';
-
-(int) number
-  -> digit:d           = d-'0';
-  -> number:n, digit:d = n*10 + d-'0';
-
-(int) hex number
-  -> {"0x" | "0X"}, hex digit:d    =d;
-  -> hex number:n, hex digit:d     =16*n+d;
-
-(int) auto hex
-  -> hex digit:d    =d;
-  -> auto hex:n, hex digit:d     =16*n+d;
-
-
-(int) hex digit
-  -> digit:d                       =d-'0';
-  -> 'a-f' + 'A-F' :d              =10 + (d&7);
-
-(int) octal number
- -> octal digit:d                  = d-'0';
- -> octal number:n, octal digit:d  = n*8+d-'0';
-
-(int) expr
- -> term
- -> expr:x, '+', term:t         =x+t;
- -> expr:x, '-', term:t         =x-t;
-
-(int) term
- -> factor
- -> term:t, '*', factor:f       =t*f;
-// -> term:t, '/', factor:f       =t/f;
-
-(int) factor
- -> number
- -> hex number
- -> '-', factor:f               =-f;
- -> '(', expr:x, ')'            =x;
index e8e517fea11fd9a73e2b4aef7cba7f842114f3ee..f69f0c1ef9c7203a5dd60e18e8167affacd392ec 100644 (file)
@@ -1,45 +1,56 @@
 # Makefile -- Makefile for util-linux Linux utilities
 # Created: Sat Dec 26 20:09:40 1992
-# Revised: Thu Feb 16 10:00:24 1995 by faith@cs.unc.edu
+# Revised: Fri Oct  6 20:27:07 1995 by r.faith@ieee.org
 # Copyright 1992, 1993, 1994, 1995 Rickard E. Faith (faith@cs.unc.edu)
+# May be distirbuted under the GPL
 #
 
 include ../MCONFIG
 
 # Where to put man pages?
 
-MAN1=          cal.1 clear.1 dnsdomainname.1 domainname.1 dsplit.1 \
-               hostid.1 hostname.1 kill.1 logger.1 look.1 mcookie.1 \
-               md5sum.1 namei.1 reset.1 script.1 setterm.1 tsort.1 \
+MAN1=          cal.1 chkdupexe.1 ddate.1 dnsdomainname.1 domainname.1 \
+               dsplit.1 hostid.1 hostname.1 kill.1 logger.1 look.1 mcookie.1 \
+               namei.1 reset.1 script.1 setterm.1 tsort.1 \
                whereis.1 write.1
 
+ifeq "$(HAVE_CLEAR)" "no"
+MAN1:=$(MAN1) clear.1
+endif
+
 # Where to put binaries?
 # See the "install" rule for the links. . .
 
 BIN=            domainname hostname kill
 
-USRBIN=                cal clear dsplit hostid logger look mcookie md5sum namei \
-               reset script setterm tsort whereis write
+USRBIN=                cal chkdupexe ddate dsplit hostid logger look mcookie \
+               namei reset script setterm tsort whereis write
+
+ifeq "$(HAVE_CLEAR)" "no"
+USRBIN:=$(USRBIN) clear
+endif
 
 # Programs requiring special compilation
 
 NEEDS_TERMCAP=  setterm
-SCRIPTS=       clear reset
 
 all: $(BIN) $(USRBIN) $(USRBIN.NONSHADOW) $(USRGAMES) getoptprog
 
-%.o: %.c
-       $(CC) -c $(CFLAGS) $< -o $@
-
 $(NEEDS_TERMCAP):
        $(CC) $(LDFLAGS) $^ -o $@ -ltermcap
 
-$(SCRIPTS):
+%: %.sh
        cp $@.sh $@
+       chmod 755 $@
+
+%: %.pl
+       cp $@.pl $@
+       chmod 755 $@
 
 # Rules for everything else
 
 cal: cal.o $(BSD)/getopt.o $(BSD)/err.o
+chkdupexe: chkdupexe.pl
 clear: clear.sh
 domainname: domainname.o
 dsplit: dsplit.o
@@ -48,7 +59,8 @@ hostid: hostid.o
 hostname: hostname.o
 kill: kill.o procs.o
 logger: logger.o $(BSD)/getopt.o
-md5sum: md5.o
+mcookie: mcookie.o md5.o
+md5sum: md5sum.o md5.o
 md5.o: md5.h
 namei: namei.o
 reset: reset.sh
@@ -65,6 +77,10 @@ install: all
        $(INSTALLDIR) $(MAN1DIR) $(MAN8DIR)
        $(INSTALLMAN) $(MAN1) $(MAN1DIR)
        $(INSTALLMAN) getoptprog.1 $(MAN1DIR)/getopt.1
+ifeq "$(USE_TTY_GROUP)" "yes"
+       chgrp tty $(USRBINDIR)/write
+       chmod g+s $(USRBINDIR)/write
+endif
 
 .PHONY:        clean
 clean:
index 8004016d60ec1e40c5e1eae21ad43162a6cbdbf3..87ab71df637c07df91710aced0f9e56b13ce20e8 100644 (file)
@@ -54,7 +54,12 @@ static char sccsid[] = "@(#)cal.c    8.4 (Berkeley) 4/2/94";
 #include <time.h>
 #include <unistd.h>
 #include <locale.h>
-#include <localeinfo.h>
+
+#if defined(__linux__) && _LINUX_C_LIB_VERSION_MAJOR > 4
+# include <langinfo.h>
+#else
+# include <localeinfo.h>
+#endif
 
 #define        THURSDAY                4               /* for reformation */
 #define        SATURDAY                6               /* 1 Jan 1 was a Saturday */
@@ -93,13 +98,14 @@ int sep1752[MAXDAYS] = {
        SPACE,  SPACE,  SPACE,  SPACE,  SPACE,  SPACE,  SPACE,
 };
 
-char *day_headings = " S  M Tu  W Th  F  S ";
-char *j_day_headings = "  S   M  Tu   W  Th   F   S ";
+char day_headings[]   = " S  M Tu  W Th  F  S ";
+char j_day_headings[] = "  S   M  Tu   W  Th   F   S ";
+const char *full_month[12];
 
 /* leap year -- account for gregorian reformation in 1752 */
 #define        leap_year(yr) \
        ((yr) <= 1752 ? !((yr) % 4) : \
-       !((yr) % 4) && ((yr) % 100) || !((yr) % 400))
+       (!((yr) % 4) && ((yr) % 100)) || !((yr) % 400))
 
 /* number of centuries since 1700, not inclusive */
 #define        centuries_since_1700(yr) \
@@ -116,7 +122,7 @@ char *j_day_headings = "  S   M  Tu   W  Th   F   S ";
 int julian;
 
 void   ascii_day __P((char *, int));
-void   center __P((char *, int, int));
+void   center __P((const char *, int, int));
 void   day_array __P((int, int, int *));
 int    day_in_week __P((int, int, int));
 int    day_in_year __P((int, int, int));
@@ -201,17 +207,27 @@ void headers_init(void)
   int i;
 
   strcpy(day_headings,"");
-  for(i = 0 ; i < 7 ; i++ )
-    {
-      strncat(day_headings,_time_info->abbrev_wkday[i],2);
-      strcat(day_headings," ");
-    }
   strcpy(j_day_headings,"");
-  for(i = 0 ; i < 7 ; i++ )
-    {
-      strcat(j_day_headings,_time_info->abbrev_wkday[i]);
-      strcat(j_day_headings," ");
-    } 
+  
+  for(i = 0 ; i < 7 ; i++ ) {
+#if defined(__linux__) && _LINUX_C_LIB_VERSION_MAJOR > 4
+     strncat(day_headings,nl_langinfo(ABDAY_1+i),2);
+     strcat(j_day_headings,nl_langinfo(ABDAY_1+i));
+#else
+     strncat(day_headings,_time_info->abbrev_wkday[i],2);
+     strcat(j_day_headings,_time_info->abbrev_wkday[i]);
+#endif
+     strcat(day_headings," ");
+     strcat(j_day_headings," ");
+  }
+  
+  for (i = 0; i < 12; i++) {
+#if defined(__linux__) && _LINUX_C_LIB_VERSION_MAJOR > 4
+     full_month[i] = nl_langinfo(MON_1+i);
+#else
+     full_month[i] = _time_info->full_month[i];
+#endif
+  }
 }
 
 void
@@ -222,7 +238,7 @@ monthly(month, year)
        char *p, lineout[30];
 
        day_array(month, year, days);
-       len = sprintf(lineout, "%s %d", _time_info->full_month[month - 1], year);
+       len = sprintf(lineout, "%s %d", full_month[month - 1], year);
        (void)printf("%*s%s\n%s\n",
            ((julian ? J_WEEK_LEN : WEEK_LEN) - len) / 2, "",
            lineout, julian ? j_day_headings : day_headings);
@@ -252,8 +268,8 @@ j_yearly(year)
        (void)memset(lineout, ' ', sizeof(lineout) - 1);
        lineout[sizeof(lineout) - 1] = '\0';
        for (month = 0; month < 12; month += 2) {
-               center(_time_info->full_month[month], J_WEEK_LEN, J_HEAD_SEP);
-               center(_time_info->full_month[month + 1], J_WEEK_LEN, 0);
+               center(full_month[month], J_WEEK_LEN, J_HEAD_SEP);
+               center(full_month[month + 1], J_WEEK_LEN, 0);
                (void)printf("\n%s%*s%s\n", j_day_headings, J_HEAD_SEP, "",
                    j_day_headings);
                for (row = 0; row < 6; row++) {
@@ -287,9 +303,9 @@ yearly(year)
        (void)memset(lineout, ' ', sizeof(lineout) - 1);
        lineout[sizeof(lineout) - 1] = '\0';
        for (month = 0; month < 12; month += 3) {
-               center(_time_info->full_month[month], WEEK_LEN, HEAD_SEP);
-               center(_time_info->full_month[month + 1], WEEK_LEN, HEAD_SEP);
-               center(_time_info->full_month[month + 2], WEEK_LEN, 0);
+               center(full_month[month], WEEK_LEN, HEAD_SEP);
+               center(full_month[month + 1], WEEK_LEN, HEAD_SEP);
+               center(full_month[month + 2], WEEK_LEN, 0);
                (void)printf("\n%s%*s%s%*s%s\n", day_headings, HEAD_SEP,
                    "", day_headings, HEAD_SEP, "", day_headings);
                for (row = 0; row < 6; row++) {
@@ -392,7 +408,7 @@ ascii_day(p, day)
                return;
        }
        if (julian) {
-               if (val = day / 100) {
+               if ((val = day / 100)) {
                        day %= 100;
                        *p++ = val + '0';
                        display = 1;
@@ -430,7 +446,7 @@ trim_trailing_spaces(s)
 
 void
 center(str, len, separate)
-       char *str;
+       const char *str;
        int len;
        int separate;
 {
diff --git a/misc-utils/chkdupexe.1 b/misc-utils/chkdupexe.1
new file mode 100644 (file)
index 0000000..279562e
--- /dev/null
@@ -0,0 +1,38 @@
+.\" chkdupexe.1 -- 
+.\" Created: Sat Mar 11 18:19:44 1995 by faith@cs.unc.edu
+.\" Revised: Sat Mar 11 19:07:05 1995 by faith@cs.unc.edu
+.\" Revised: Wed Jul  5 01:56:26 1995 by shields@tembel.org
+.\" Copyright 1995 Rickard E. Faith (faith@cs.unc.edu)
+.\" 
+.\" Permission is granted to make and distribute verbatim copies of this
+.\" manual provided the copyright notice and this permission notice are
+.\" preserved on all copies.
+.\" 
+.\" Permission is granted to copy and distribute modified versions of this
+.\" manual under the conditions for verbatim copying, provided that the
+.\" entire resulting derived work is distributed under the terms of a
+.\" permission notice identical to this one
+.\" 
+.\" Since the Linux kernel and libraries are constantly changing, this
+.\" manual page may be incorrect or out-of-date.  The author(s) assume no
+.\" responsibility for errors or omissions, or for damages resulting from
+.\" the use of the information contained herein.  The author(s) may not
+.\" have taken the same level of care in the production of this manual,
+.\" which is licensed free of charge, as they might when working
+.\" professionally.
+.\" 
+.\" Formatted or processed versions of this manual, if unaccompanied by
+.\" the source, must acknowledge the copyright and authors of this work.
+.\" 
+.TH CHKDUPEXE 1 "11 Mar 1995" "" "Linux Programmer's Manual"
+.SH NAME
+chkdupexe \- find duplicate executables
+.SH SYNOPSIS
+.B chkdupexe
+.SH DESCRIPTION
+.B chkdupexe
+will scan the union of $PATH and a hardcoded list of common locations
+for binaries.  It will report dangling symlinks and duplicately-named
+binaries.
+.SH AUTHOR
+Nicolai Langfeldt, Michael Shields.
diff --git a/misc-utils/chkdupexe.pl b/misc-utils/chkdupexe.pl
new file mode 100644 (file)
index 0000000..117d20f
--- /dev/null
@@ -0,0 +1,56 @@
+#!/usr/bin/perl
+#
+# chkdupexe version 2.0
+#
+# Simple script to look for and list duplicate executables and dangling
+# symlinks in the system executable directories.
+#
+# Copyright 1993 Nicolai Langfeldt. Distribute under gnu copyleft
+#  (included in perl package)
+#
+# Modified 1995-07-04 Michael Shields <shields@tembel.org>
+#     Don't depend on GNU ls.
+#     Cleanups.
+#     Merge together $ENV{'PATH'} and $execdirs.
+#     Don't break if there are duplicates in $PATH.
+# 
+
+$execdirs='/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:/local/bin:/local/sbin:/usr/X11/bin:/usr/bin/X11:/usr/local/X11/bin:/local/X11/bin:/usr/TeX/bin:/usr/tex/bin:/usr/local/graph/bin:/usr/games:/usr/local/games:/usr/intervies/bin/LINUX';
+
+DIRECTORY:
+foreach $dir (split(/:/, "$execdirs:$ENV{'PATH'}")) {
+
+  # Follow symlinks and make sure we haven't scanned this directory already.
+  while (-l $dir) {
+    $newdir = readlink($dir);
+    print "Dangling symlink: $dir\n" unless $newdir;
+    $dir = $newdir;
+    next DIRECTORY if $seendir{$dir}++;
+  }
+
+  opendir(DIR,$dir) || (warn "Couldn't opendir($dir): $!\n", next);
+  foreach $_ (readdir(DIR)) {
+    lstat("$dir/$_");
+    if (-l _) {
+      ($dum)=stat("$dir/$_");
+      # Might as well report these since we discover them anyway
+      print "Dangling symlink: $dir/$_\n" unless $dum;
+      next;
+    }
+    next unless -f _ && -x _;  # Only handle regular executable files
+    if ($count{$_}) {
+      $progs{$_}.=" $dir/$_";
+      $count{$_}++;
+    } else {
+      $progs{$_}="$dir/$_";
+      $count{$_}=1;
+    }
+  }
+  closedir(DIR);
+}
+
+open(LS,"| xargs ls -ldU");
+while (($prog,$paths)=each %progs) {
+  print LS "$paths\n" if ($count{$prog}>1);
+}
+close(LS);
index 1d4a5df795df46069379eefba861edcd2fe8026e..9d20823048ed59d410a7055976fbc5c97e325566 100644 (file)
@@ -15,6 +15,12 @@ argument.  This causes
 .B tput
 to attempt to clear the screen checking the data in
 .I /etc/termcap
+(for the GNU or BSD
+.BR tput )
+or in the terminfo database
+(for the
+.B ncurses
+.BR tput )
 and sending the appropriate sequence to the terminal.  This command can be
 redirected to clear the screen of some other terminal.
 .SH "SEE ALSO"
diff --git a/misc-utils/ddate.1 b/misc-utils/ddate.1
new file mode 100644 (file)
index 0000000..1ccc201
--- /dev/null
@@ -0,0 +1,101 @@
+.\" All Rites Reversed.  This file is in the PUBLIC DOMAIN.
+.\" Kallisti.
+.TH DDATE 1 "59 Bureaucracy 3161" "" "Emperor Norton Utilities"
+.SH NAME
+ddate \- converts Gregorian dates to Discordian dates
+.SH SYNOPSIS
+.B ddate [+format] [date]
+.SH DESCRIPTION
+.B ddate
+prints the date in Discordian date format.
+.PP
+If called with no arguments,
+.B ddate 
+will get the current system date, convert this to the Discordian
+date format and print this on the standard output. Alternatively, a
+Gregorian date may be specified on the command line, in the form of a numerical
+day, month and year.
+.PP
+If a format string is specified, the Discordian date will be printed in 
+a format specified by the string. This mechanism works similarly to the 
+format string mechanism of
+.B date(1), 
+only almost completely differently. The fields are:
+.IP %A
+Full name of the day of the week (i.e., Sweetmorn)
+.IP %a 
+Abbreviated name of the day of the week (i.e., SM)
+.IP %B 
+Full name of the season (i.e., Chaos)
+.IP %b
+Abbreviated name of the season (i.e., Chs)
+.IP %d
+Ordinal number of day in season (i.e., 23)
+.IP %e
+Cardinal number of day in season (i.e., 23rd)
+.IP %H
+Name of current Holyday, if any
+.IP %N
+Magic code to prevent rest of format from being printed unless today is
+a Holyday.
+.IP %n 
+Newline
+.IP %t 
+Tab
+.IP %X
+Number of days remaining until X-Day. (Not valid if the SubGenius options are not
+compiled in.)
+.IP %{
+.IP %}
+Used to enclose the part of the string which is to be replaced with the
+words "St. Tib's Day" if the current day is St. Tib's Day.
+.IP %\.
+Try it and see.
+.bp
+.SH EXAMPLES
+.nf
+% ddate
+.br
+Sweetmorn, Bureaucracy 42, 3161 YOLD
+.PP
+% ddate +'Today is %{%A, the %e of %B%}, %Y. %N%nCelebrate %H'
+.br
+Today is Sweetmorn, the 42nd of Bureaucracy, 3161. 
+.PP
+% ddate +"It's %{%A, the %e of %B%}, %Y. %N%nCelebrate %H" 26 9 1995
+.br
+It's Prickle-Prickle, the 50th of Bureaucracy, 3161. 
+.br
+Celebrate Bureflux
+.PP
+% ddate +'Today's %{%A, the %e of %B%}, %Y. %N%nCelebrate %H' 29 2 1996
+.br
+Today's St. Tib's Day, 3162. 
+.br
+
+.SH BUGS
+
+.B ddate(1)
+will produce undefined behaviour if asked to produce the date for St. Tib's
+day and its format string does not contain the St. Tib's Day delimiters 
+%{ and %}.
+
+.SH AUTHOR
+.nh
+Original program by Druel the Chaotic aka Jeremy Johnson (mpython@gnu.ai.mit.edu)
+.br
+Major rewrite by Lee H:. O:. Smith, KYTP, aka Andrew Bulhak (acb@dev.null.org)
+.br
+Five tons of flax.
+
+.SH DISTRIBUTION POLICY
+
+Public domain. All rites reversed.
+
+.SH SEE ALSO
+
+date(1),
+.br
+Malaclypse the Younger, 
+.I "Principia Discordia, Or How I Found Goddess And What I Did To Her When I Found Her"
+
diff --git a/misc-utils/ddate.c b/misc-utils/ddate.c
new file mode 100644 (file)
index 0000000..96421d0
--- /dev/null
@@ -0,0 +1,313 @@
+/* $ DVCS ID: $jer|,523/lhos,KYTP!41023161\b"?" <<= DO NOT DELETE! */
+
+/* ddate.c .. converts boring normal dates to fun Discordian Date -><-
+   written  the 65th day of The Aftermath in the Year of Our Lady of 
+   Discord 3157 by Druel the Chaotic aka Jeremy Johnson aka
+   mpython@gnu.ai.mit.edu  
+      28 Sever St Apt #3
+      Worcester MA 01609
+
+   and I'm not responsible if this program messes anything up (except your 
+   mind, I'm responsible for that)
+
+   (k) YOLD 3161 and all time before and after.
+   Reprint, reuse, and recycle what you wish.
+   This program is in the public domain.  Distribute freely.  Or not.
+
+   Majorly hacked, extended and bogotified/debogotified on 
+   Sweetmorn, Bureaucracy 42, 3161 YOLD, by Lee H:. O:. Smith, KYTP, 
+   aka Andrew Bulhak, aka acb@dev.null.org
+
+   and I'm not responsible if this program messes anything up (except your 
+   mind, I'm responsible for that) (and that goes for me as well --lhos)
+
+   Version history:
+   Bureflux 3161:      First release of enhanced ddate with format strings
+   59 Bcy, 3161:       PRAISE_BOB and KILL_BOB options split, other minor
+                       changes.
+
+*/
+
+
+/* configuration options  VVVVV   READ THIS!!! */
+
+/* If you wish ddate(1) to print the date in the same format as Druel's 
+ * original ddate when called in immediate mode, define OLD_IMMEDIATE_FMT 
+ */
+
+#define OLD_IMMEDIATE_FMT
+
+/* If you wish to use the US format for aneristic dates (m-d-y), as opposed to
+ * the Commonwealth format, define US_FORMAT.
+ */
+
+/* #define US_FORMAT */
+
+/* If you are ideologically, theologically or otherwise opposed to the 
+ * Church of the SubGenius and do not wish your copy of ddate(1) to contain
+ * code for counting down to X-Day, undefine KILL_BOB */
+
+#define KILL_BOB 13013
+
+/* If you wish ddate(1) to contain SubGenius slogans, define PRAISE_BOB */
+
+/*#define PRAISE_BOB 13013*/
+
+#include <time.h>
+#include <string.h>
+#include <stdio.h>
+
+#ifndef __GNUC__
+#define inline /* foo */
+#endif
+
+/* string constants */
+
+char *day_long[5] = { 
+    "Sweetmorn", "Boomtime", "Pungenday", "Prickle-Prickle", "Setting Orange"
+};
+
+char *day_short[5] = {"SM","BT","PD","PP","SO"};
+
+char *season_long[5] = { 
+    "Chaos", "Discord", "Confusion", "Bureaucracy", "The Aftermath"
+};
+
+char *season_short[5] = {"Chs", "Dsc", "Cfn", "Bcy", "Afm"};
+
+char *holyday[5][2] = { 
+    "Mungday", "Chaoflux",
+    "Mojoday", "Discoflux",
+    "Syaday",  "Confuflux",
+    "Zaraday", "Bureflux",
+    "Maladay", "Afflux"
+};
+
+struct disc_time {
+    int season; /* 0-4 */
+    int day; /* 0-72 */
+    int yday; /* 0-365 */
+    int year; /* 3066- */
+};
+
+char *excl[] = {
+    "Hail Eris!", "All Hail Discordia!", "Kallisti!", "Fnord.", "Or not.",
+    "Wibble.", "Pzat!", "P'tang!", "Frink!", 
+#ifdef PRAISE_BOB
+    "Slack!", "Praise \"Bob\"!", "Or kill me.",
+#endif /* PRAISE_BOB */
+    /* randomness, from the Net and other places. Feel free to add (after
+       checking with the relevant authorities, of course). */
+    "Grudnuk demand sustenance!", "Keep the Lasagna flying!", 
+    "Umlaut Zebra Ã¼ber alles!", "You are what you see.",
+    "Or is it?", "This statement is false.",
+#if defined(linux) || defined (__linux__) || defined (__linux)
+    "Hail Eris, Hack Linux!",
+#endif
+    ""
+};
+
+char default_fmt[] = "%{%A, %B %d%}, %Y YOLD";
+char *default_immediate_fmt=
+#ifdef OLD_IMMEDIATE_FMT
+"Today is %{%A, the %e day of %B%} in the YOLD %Y%N%nCelebrate %H"
+#else
+default_fmt
+#endif
+;
+
+#define DY(y) (y+1166)
+
+inline char *ending(int i) { return (i%10==1)?"st":(i%10==2?"nd":(i%10==3?"rd":"th"));};
+inline int leapp(int i) { return (!(DY(i)%4))&&((DY(i)%100)||(!(DY(i)%400)));};
+
+void print(struct disc_time,char **); /* old */
+void format(char *buf, const char* fmt, struct disc_time dt);
+/* select a random string */
+inline char *sel(char **strings, int num) {return(strings[random()%num]); }; 
+/* read a fortune file */
+int load_fortunes(char *fn, char *delim, char** result);
+
+struct disc_time convert(int,int);
+struct disc_time makeday(int,int,int);
+
+main (int argc, char *argv[]) 
+{
+    long t;
+    struct tm *eris;
+    int bob,raw;
+    struct disc_time hastur;
+    char schwa[23*17], *fnord=0;
+    int pi;
+
+    srandom(time(NULL));
+    /* do args here */
+    for(pi=1; pi<argc; pi++) {
+       switch(argv[pi][0]) {
+       case '+': fnord=argv[pi]+1; break;
+       case '-': 
+           switch(argv[pi][1]) {
+           default: goto usage;
+           }
+       default: goto thud;
+       }
+    }
+
+  thud:
+    if (argc-pi==3){ 
+       int moe=atoi(argv[pi]), larry=atoi(argv[pi+1]), curly=atoi(argv[pi+2]);
+       hastur=makeday(
+#ifdef US_FORMAT
+           moe,larry,
+#else
+           larry,moe,
+#endif
+           curly);
+       fnord=fnord?fnord:default_fmt;
+    } else if (argc!=pi) { 
+      usage:
+       fprintf(stderr,"usage: %s [+format] [day month year]\n", argv[0]);
+       exit(1);
+    } else {
+       t= time(NULL);
+       eris=localtime(&t);
+       bob=eris->tm_yday; /* days since Jan 1. */
+       raw=eris->tm_year; /* years since 1980 */
+       hastur=convert(bob,raw);
+       fnord=fnord?fnord:default_immediate_fmt;
+    }
+    format(schwa, fnord, hastur);
+    printf("%s\n", schwa);
+    return 0;
+}
+
+void format(char *buf, const char* fmt, struct disc_time dt)
+{
+    int tib_start=-1, tib_end=0;
+    int i, fmtlen=strlen(fmt);
+    char *bufptr=buf;
+
+/*    fprintf(stderr, "format(%p, \"%s\", dt)\n", buf, fmt);*/
+
+    /* first, find extents of St. Tib's Day area, if defined */
+    for(i=0; i<fmtlen; i++) {
+       if(fmt[i]=='%') {
+           switch(fmt[i+1]) {
+           case 'A':
+           case 'a':
+           case 'd':
+           case 'e':
+               if(tib_start>0)     tib_end=i+1;
+               else                tib_start=i;
+               break;
+           case '{': tib_start=i; break;
+           case '}': tib_end=i+1; break;
+           }
+       }
+    }
+
+    /* now do the formatting */
+    buf[0]=0;
+
+    for(i=0; i<fmtlen; i++) {
+       if((i==tib_start) && (dt.day==-1)) {
+           /* handle St. Tib's Day */
+           strcpy(bufptr, "St. Tib's Day"); bufptr += 13;
+           i=tib_end;
+       } else {
+           if(fmt[i]=='%') {
+               char *wibble=0, snarf[23];
+               switch(fmt[++i]) {
+               case 'A': wibble=day_long[dt.yday%5]; break;
+               case 'a': wibble=day_short[dt.yday%5]; break;
+               case 'B': wibble=season_long[dt.season]; break;
+               case 'b': wibble=season_short[dt.season]; break;
+               case 'd': sprintf(snarf, "%d", dt.day+1); wibble=snarf; break;
+               case 'e': sprintf(snarf, "%d%s", dt.day+1, ending(dt.day+1)); 
+                   wibble=snarf; break;
+               case 'H': if(dt.day==4||dt.day==49)
+                   wibble=holyday[dt.season][dt.day==49]; break;
+               case 'N': if(dt.day!=4&&dt.day!=49) goto eschaton; break;
+               case 'n': *(bufptr++)='\n'; break;
+               case 't': *(bufptr++)='\t'; break;
+                   
+               case 'Y': sprintf(snarf, "%d", dt.year); wibble=snarf; break;
+               case '.': wibble=sel(excl, sizeof(excl)/sizeof(excl[0]));
+                   break;
+#ifdef KILL_BOB
+               case 'X': sprintf(snarf, "%d", 
+                                 xday_countdown(dt.yday, dt.year));
+                                 wibble = snarf; break;
+#endif /* KILL_BOB */
+               }
+               if(wibble) {
+/*                 fprintf(stderr, "wibble = (%s)\n", wibble);*/
+                   strcpy(bufptr, wibble); bufptr+=strlen(wibble);
+               }
+           } else {
+               *(bufptr++) = fmt[i];
+           }
+       }
+    }
+  eschaton:
+    *(bufptr)=0;
+}
+
+struct disc_time makeday(int imonth,int iday,int iyear) /*i for input */
+{ 
+    struct disc_time funkychickens;
+    
+    int cal[12] = { 31,28,31,30,31,30,31,31,30,31,30,31 };
+    int dayspast=0;
+    
+    imonth--;
+    funkychickens.year= iyear+1166;
+    while(imonth>0) { dayspast+=cal[--imonth]; }
+    funkychickens.day=dayspast+iday-1;
+    funkychickens.season=0;
+    if((funkychickens.year%4)==2) {
+       if (funkychickens.day==59)  funkychickens.day=-1;
+    }
+    funkychickens.yday=funkychickens.day;
+/*               note: EQUAL SIGN...hopefully that fixes it */
+    while(funkychickens.day>=73) {
+       funkychickens.season++;
+       funkychickens.day-=73;
+    }
+    return funkychickens;
+}
+
+struct disc_time convert(int nday, int nyear)
+{  struct disc_time funkychickens;
+   
+   funkychickens.year = nyear+3066;
+   funkychickens.day=nday;
+   funkychickens.season=0;
+   if ((funkychickens.year%4)==2)
+     {if (funkychickens.day==59)
+       funkychickens.day=-1;
+     else if (funkychickens.day >59)
+       funkychickens.day-=1;
+    }
+   funkychickens.yday=funkychickens.day;
+   while (funkychickens.day>=73)
+     { funkychickens.season++;
+       funkychickens.day-=73;
+     }
+   return funkychickens;
+  
+ }
+
+
+#ifdef KILL_BOB
+
+/* Code for counting down to X-Day, X-Day being Cfn 40, 3164 */
+
+int xday_countdown(int yday, int year) {
+    int r=(185-yday)+(((yday<59)&&(leapp(year)))?1:0);
+    while(year<3164) r+=(leapp(++year)?366:365);
+    while(year>3164) r-=(leapp(year--)?366:365);
+    return r;
+}
+
+#endif
index 447c71266b75c5a2b5e086f26d28a3e26aea723d..0a305ad1ea2c8c72c3cbca345ecb5be7045344c8 100644 (file)
@@ -1,43 +1,28 @@
-.\" Copyright 1992, 1995 Rickard E. Faith (faith@cs.unc.edu)
+.\" Copyright 1992 Rickard E. Faith (faith@cs.unc.edu)
 .\" May be distributed under the GNU General Public License
-.TH DOMAINNAME 1 "16 February 1995" "Linux 1.0" "Linux Programmer's Manual"
+.TH DOMAINNAME 1 "26 December 1992" "Linux 0.98" "Linux Programmer's Manual"
 .SH NAME
-domainname \- set or print NIS domain of current host
+domainname \- set or print domain of current host
 .SH SYNOPSIS
 .BR "domainname [ " name " ]"
 .SH DESCRIPTION
 .B domainname
-prints the NIS domainname of the current host, from the
+prints the domainname of the current host, from the
 .BR getdomainname (3)
 library call.  If an argument is present and the effective UID is 0,
 .B domainname
-changes the NIS domainname of the host, with the
+changes the name of the host, with the
 .BR setdomainname (2)
 system call.  This is usually done at boot time in the
 .I /etc/rc.local
 script.
-.PP
-.B Note:
-This command sets the NIS (Network Information Services) domain,
-.I not
-the DNS (Domain Name System) domain.  Unless you are running NIS
-(formerly known as Sun Yellow Pages (YP)), you should
-.I not
-use the
-.B domainname
-command to set your domain.  You probably want to set the DNS domain, which
-is used to map human-readable machine names into IP addresses on the
-InterNet.  See
-.BR dnsdomainname (1)
-for more information.
 .SH FILES
 .I /etc/rc.local
 .SH "SEE ALSO"
-.BR hostname (1),
-.BR dnsdomainname (1),
-.BR named (8),
-.BR sendmail (8),
-.bR ypinit (8)
+.BR getdomainname (3),
+.BR setdomainname (2),
+.BR uname (1),
+.BR uname (2)
 .SH AUTHOR
 Lars Wirzenius by substituting in hostname.c
 
index 14d8ffff1208e52610d56fc76a95f4ca62913112..c3c22a305a352489b4439e1560809d95f0254173 100644 (file)
@@ -1,5 +1,5 @@
 #ifdef lint
-   static char RCSid[] = "dsplit.c,v 1.1.1.1 1995/02/22 19:09:14";
+   static char RCSid[] = "$RCSfile: dsplit.c,v $ $Revision: 1.9 $ $Date: 1995/03/12 01:31:03 $";
 #endif
 /*
    Program dsplit:  Splits a large  file into pieces.
diff --git a/misc-utils/hostname.c.orig b/misc-utils/hostname.c.orig
new file mode 100644 (file)
index 0000000..b7e61d1
--- /dev/null
@@ -0,0 +1,187 @@
+/* hostname -- set the host name or show the host/domain name
+
+   Copyright (C) 1994 Peter Tobias
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+
+#include <stdio.h>
+#include <unistd.h>
+#include <getopt.h>
+#include <string.h>
+#include <netdb.h>
+#include <errno.h>
+#include <sys/param.h>
+
+#define NO_OPT -1
+
+static char *program_name;
+static const char *version_string = "hostname 1.5";
+
+static void sethname(char *);
+static void showhname(char *, int);
+static void usage(void);
+
+static void sethname(char *hname)
+{
+       if(sethostname(hname, strlen(hname))) {
+               switch(errno) {
+                       case EPERM:
+                               fprintf(stderr,"%s: you must be root to change the host name\n", program_name);
+                               break;
+                       case EINVAL:
+                               fprintf(stderr,"%s: name too long\n", program_name);
+                               break;
+                       default:
+               }
+               exit(1);
+       };
+}
+
+static void showhname(char *hname, int c)
+{
+       struct hostent *hp;
+       register char *p;
+
+       if (!(hp = gethostbyname(hname))) {
+               herror(program_name);
+               exit(1);
+       }
+
+       if (!(p = strchr(hp->h_name, '.'))) {
+               fprintf(stderr,"%s: can't find a FQDN for the host name `%s'\n", program_name, hname);
+               exit(1);
+       }
+
+       switch(c) {
+               case 'd':
+                       printf("%s\n", ++p);
+                       break;
+               case 'f':
+                       printf("%s\n", hp->h_name);
+                       break;
+               case 's':
+                       *p = '\0';
+                       printf("%s\n", hp->h_name);
+                       break;
+               default:
+       }
+}
+
+static void usage(void)
+{
+  printf("Usage: %s [OPTION]... [hostname]\n\n\
+  -d, --domain                 display the DNS domain name\n\
+  -F, --file filename          read the host name from file\n\
+  -f, --fqdn, --long           display the long host name (FQDN)\n\
+  -s, --short                  display the short host name\n\
+  -h, --help                   display this help and exit\n\
+  -v, --version                output version information and exit\n\
+\n\
+   When the program is called without any arguments, it displays the\n\
+   current host name as set by the hostname command. If an argument\n\
+   is given, the program will set the value of the host name to the\n\
+   value specified.\n\
+   Unless you are using bind or NIS for host lookups you can change the\n\
+   FQDN (Fully Qualified Domain Name) and the DNS domain name (which is\n\
+   part of the FQDN) in the /etc/hosts file.\n", program_name);
+}
+
+int main(int argc, char **argv)
+{
+       int c;
+       int option_index = 0;
+
+       char myname[MAXHOSTNAMELEN+1];
+
+       static const struct option long_options[] =
+       {
+               {"domain", no_argument, 0, 'd'},
+               {"file", required_argument, 0, 'F'},
+               {"fqdn", no_argument, 0, 'f'},
+               {"help", no_argument, 0, 'h'},
+               {"long", no_argument, 0, 'f'},
+               {"short", no_argument, 0, 's'},
+               {"version", no_argument, 0, 'v'},
+               {0, 0, 0, 0}
+       };
+
+       program_name = (rindex(argv[0], '/')) ? rindex(argv[0], '/') + 1 : argv[0];
+
+       if (strcmp(program_name, "dnsdomainname") == 0) {
+               if (argc > 1) {
+                       fprintf(stderr,"%s: You can't change the DNS domainname with this command\n", program_name);
+                       fprintf(stderr,"\nUnless you are using bind or NIS for host lookups you can change the DNS\n");
+                       fprintf(stderr,"domain name (which is part of the FQDN) in the /etc/hosts file.\n");
+                       exit(1);
+               }
+               c = 'd';
+       } else
+               c = getopt_long(argc, argv, "dfF:hsv", long_options, &option_index);
+
+       gethostname(myname, sizeof(myname));
+
+       switch(c)
+       {
+               case 'd':
+               case 'f':
+               case 's':
+                       showhname(myname, c);
+                       break;
+               case 'F':
+                       {
+                       register FILE *fd;
+                       register char *p;
+                       char fline[MAXHOSTNAMELEN];
+
+                       if ((fd = fopen(optarg, "r")) != NULL) {
+                               while (fgets(fline, sizeof(fline), fd) != NULL)
+                                       if ((p = index(fline, '\n')) != NULL) {
+                                               *p = '\0';
+                                               if (fline[0] == '#')
+                                                       continue;
+                                               sethname(fline);
+                                       }
+                               (void) fclose(fd);
+                       } else {
+                               fprintf(stderr,"%s: can't open `%s'\n",
+                                   program_name, optarg);
+                               exit(1);
+                       }
+                       }
+                       break;
+               case 'h':
+                       usage();
+                       break;
+               case 'v':
+                       printf("%s\n", version_string);
+                       break;
+               case '?':
+                       fprintf(stderr,"Try `%s --help' for more information.\n", program_name);
+                       exit(1);
+                       break;
+               case NO_OPT:
+                       if (optind < argc) {
+                               sethname(argv[optind]);
+                               exit(0);
+                       }
+               default:
+                       printf("%s\n", myname);
+
+       };
+       exit(0);
+}
index 395082548448ec9fcbb4d98779655c4dde2508af..6d3a11c3031ad44f0fcaca1ffa14d9555ad13427 100644 (file)
@@ -1,10 +1,10 @@
 .\" mcookie.1 -- 
 .\" Public Domain 1995 Rickard E. Faith (faith@cs.unc.edu)
-.TH MCOOKIE 1 "12 Feb 1995" "" "Linux Programmer's Manual"
+.TH MCOOKIE 1 "25 September 1995" "" "Linux Programmer's Manual"
 .SH NAME
 mcookie \- generate magic cookies for xauth
 .SH SYNOPSIS
-.B mcookie
+.BI "mcookie [\-v] [\-f " filename " ]"
 .SH DESCRIPTION
 .B mcookie
 generates a 128-bit random hexadecimal number for use with the X authority
@@ -12,6 +12,36 @@ system.  Typical usage:
 .RS
 xauth add :0 . `mcookie`
 .RE
+.PP
+The "random" number generated is actually the output of the MD5 message
+digest fed with various piece of random information: the current time, the
+process id, the parent process id, the contents of an input file (if
+.B \-f
+is specified), and several bytes of information from the first of the
+following devices which is present:
+.IR /dev/urandom ", " /dev/random ", " /dev/audio .
+Other files in
+.I /proc
+may be used as a last resort.
+.SH BUGS
+The entropy in the generated 128-bit is probably quite small (and,
+therefore, vulnerable to attack) unless a non-pseudorandom number generator
+is used (e.g.,
+.I /dev/random
+under Linux).
+.PP
+It is assumed that none of the devices opened will block.
+.SH FILES
+.I /dev/random
+.br
+.I /dev/urandom
+.br
+.I /dev/audio
+.br
+.I /proc/stat
+.br
+.I /proc/loadavg
 .SH "SEE ALSO"
 .BR X (1),
-.BR xauth (1)
+.BR xauth (1),
+.BR md5sum (1)
index d0730eddecaa70ef71c24ca2f0e5cd401270a808..a4c89607531569c09fc4863711fe29052530f45d 100644 (file)
 /* mcookie.c -- Generates random numbers for xauth
  * Created: Fri Feb  3 10:42:48 1995 by faith@cs.unc.edu
- * Revised: Sun Feb 12 20:29:58 1995 by faith@cs.unc.edu
+ * Revised: Mon Sep 25 23:44:43 1995 by r.faith@ieee.org
  * Public Domain 1995 Rickard E. Faith (faith@cs.unc.edu)
  * This program comes with ABSOLUTELY NO WARRANTY.
  * 
- * mcookie.c,v 1.1.1.1 1995/02/22 19:09:16 faith Exp
+ * $Id: mcookie.c,v 1.2 1995/10/07 01:32:00 faith Exp $
+ *
+ * This program gathers some random bits of data and used the MD5
+ * message-digest algorithm to generate a 128-bit hexadecimal number for
+ * use with xauth(1).
+ *
+ * NOTE: Unless /dev/random is available, this program does not actually
+ * gather 128 bits of random information, so the magic cookie generated
+ * will be considerably easier to guess than one might expect.
  */
 
-#define SECURE 1
+#ifdef __linux__
+#define HAVE_GETTIMEOFDAY 1
+#endif
 
 #include <stdio.h>
 #include <stdlib.h>
-#if SECURE
+#include <fcntl.h>
+#include "md5.h"
+#if HAVE_GETTIMEOFDAY
 #include <sys/time.h>
 #include <unistd.h>
 #endif
 
-int main( void )
+#define MAXBUFFERSIZE 512
+
+struct rngs {
+   const char *path;
+   int        length;
+} rngs[] = {
+   { "/dev/random",              16 },
+   { "/dev/urandom",            128 },
+   { "/proc/stat",    MAXBUFFERSIZE },
+   { "/proc/loadavg", MAXBUFFERSIZE },
+   { "/dev/audio",    MAXBUFFERSIZE },
+};
+#define RNGS (sizeof(rngs)/sizeof(struct rngs))
+
+int Verbose = 0;
+
+int main( int argc, char **argv )
 {
-   int      i;
-#if SECURE
-   struct timeval  tv;
-   struct timezone tz;
+   int               i;
+   struct MD5Context ctx;
+   unsigned char     digest[16];
+   unsigned char     buf[MAXBUFFERSIZE];
+   int               fd;
+   int               c;
+   pid_t             pid;
+   char              *file = NULL;
+   int               r;
+#if HAVE_GETTIMEOFDAY
+   struct timeval    tv;
+   struct timezone   tz;
+#else
+   long int          t;
+#endif
 
+   while ((c = getopt( argc, argv, "vf:" )) != EOF)
+      switch (c) {
+      case 'v': ++Verbose;     break;
+      case 'f': file = optarg; break;
+      }
+
+   MD5Init( &ctx );
+   
+#if HAVE_GETTIMEOFDAY
    gettimeofday( &tv, &tz );
-   srand( tv.tv_sec + tv.tv_usec );
+   MD5Update( &ctx, (unsigned char *)&tv, sizeof( tv ) );
 #else
-   long int t;
-   
    time( &t );
-   srand( t );
+   MD5Update( &ctx, (unsigned char *)&t, sizeof( t ) );
 #endif
+   pid = getppid();
+   MD5Update( &ctx, (unsigned char *)&pid, sizeof( pid ));
+   pid = getpid();
+   MD5Update( &ctx, (unsigned char *)&pid, sizeof( pid ));
 
-   for (i = 0; i < 32; i++) {
-      int r = (rand() & 0x0f0) >> 4;
+   if (file) {
+      int count = 0;
+      
+      if (file[0] == '-' && !file[1]) fd = fileno(stdin);
+      else if ((fd = open( file, O_RDONLY )) <0) {
+        fprintf( stderr, "Could not open %s\n" );
+      }
 
-      if (r < 10) putchar( '0' + r );
-      else        putchar( 'a' + r - 10 );
+      while ((r = read( fd, buf, sizeof( buf ) )) > 0) {
+        MD5Update( &ctx, buf, r );
+        count += r;
+      }
+      if (Verbose)
+        fprintf( stderr, "Got %d bytes from %s\n", count, file );
+      
+      if (file[0] != '-' || file[1]) close( fd );
    }
+
+   for (i = 0; i < RNGS; i++) {
+      if ((fd = open( rngs[i].path, O_RDONLY )) >= 0) {
+        r = read( fd, buf, sizeof( buf ) );
+        MD5Update( &ctx, buf, r );
+        close( fd );
+        if (Verbose)
+           fprintf( stderr, "Got %d bytes from %s\n", r, rngs[i].path );
+        if (r >= rngs[i].length) break;
+      } else if (Verbose)
+        fprintf( stderr, "Could not open %s\n", rngs[i].path );
+   }
+
+   MD5Final( digest, &ctx );
+   for (i = 0; i < 16; i++) printf( "%02x", digest[i] );
    putchar ( '\n' );
    
    return 0;
index 0424af0b8cf8001923b205b094c96d67e3b5602f..7505761875b6e751315b16eadd30eec6dcfbff3b 100644 (file)
@@ -42,7 +42,7 @@ chdir to /,  or if it encounters an unknown file type.
 -------------------------------------------------------------*/
 
 #ifndef lint
-static char *RCSid = "namei.c,v 1.1.1.1 1995/02/22 19:09:16 faith Exp";
+static char *RCSid = "$Id: namei.c,v 1.4 1995/03/12 01:35:45 faith Exp $";
 #endif
 
 #include <stdio.h>
index 1d232415c9eb09bc8ae56cfea0f02e848efef85d..4d0ea7aca7fcdec75b4f94c1e4f73e686ac1d16d 100644 (file)
@@ -6,9 +6,9 @@
  *   modify it under the terms of the gnu general public license.
  *   there is no warranty.
  *
- *   faith
- *   1.2
- *   1995/02/23 01:20:40
+ *   $Author: faith $
+ *   $Revision: 1.2 $
+ *   $Date: 1995/03/12 02:55:24 $
  *
  */
 
index 06ce4b2b7a541448f746aaaaf49fa2e290dd2ff0..46aea01ee587dcd05c580d12267140e0b84baac4 100644 (file)
@@ -14,7 +14,13 @@ with the
 arguments.  This causes
 .B tput
 to send appropriate reset strings to the terminal based on information in
-.IR /etc/termcap .
+.I /etc/termcap
+(for the GNU or BSD
+.BR tput )
+or in the terminfo database
+(for the
+.B ncurses
+.BR tput ).
 This sequence seems to be sufficient to reset the Linux VC's when they
 start printing "funny-looking" characters.  For good measure,
 .BR stty (1)
index 5125e156b04a135fb8ab01ed0146ad6a4b11e05f..9ff7aae619d08004230c9547deb515ff2bcacc8e 100644 (file)
@@ -1,5 +1,5 @@
-.\" Copyright (c) 1989 The Regents of the University of California.
-.\" All rights reserved.
+.\" Copyright (c) 1989, 1993
+.\"    The Regents of the University of California.  All rights reserved.
 .\"
 .\" This code is derived from software contributed to Berkeley by
 .\" Jef Poskanzer and Craig Leres of the Lawrence Berkeley Laboratory.
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.\"     @(#)write.1    6.5 (Berkeley) 4/24/91
+.\"     @(#)write.1    8.1 (Berkeley) 6/6/93
 .\"
-.\" Modified for Linux, Mon Mar  8 18:22:44 1993, faith@cs.unc.edu
+.\" Modified for Linux, Sun Mar 12 10:21:01 1995, faith@cs.unc.edu
 .\"
-.Dd March 8, 1993
-.Dt WRITE 1
-.Os "Linux 0.99"
-.Sh NAME
-.Nm write
-.Nd send a message to another user
-.Sh SYNOPSIS
-.Nm write
-.Ar user
-.Op Ar ttyname
-.Sh DESCRIPTION
-.Nm Write
+.TH WRITE 1 "12 March 1995" "" "Linux Programmer's Manual"
+.SH NAME
+write \- send a message to another user
+.SH SYNOPSIS
+.BI write " user " [ ttyname ]
+.SH DESCRIPTION
+.B Write
 allows you to communicate with other users, by copying lines from
 your terminal to theirs.
-.Pp
+.PP
 When you run the
-.Nm write
+.B write
 command, the user you are writing to gets a message of the form:
-.Pp
-.Dl Message from yourname@yourhost on yourtty at hh:mm ...
-.Pp
+.PP
+.RS
+Message from yourname@yourhost on yourtty at hh:mm ...
+.RE
+.PP
 Any further lines you enter will be copied to the specified user's
-terminal.
-If the other user wants to reply, they must run
-.Nm write
+terminal.  If the other user wants to reply, they must run
+.B write
 as well.
-.Pp
-When you are done, type an end-of-file or interrupt character.
-The other user will see the message
-.Ql EOF
-indicating that the
-conversation is over.
-.Pp
-You can prevent people (other than the super-user) from writing to you
-with the
-.Xr mesg 1
-command.
-Some commands, for example
-.Xr nroff 1
+.PP
+When you are done, type an end-of-file or interrupt character.  The other
+user will see the message
+.B EOF
+indicating that the conversation is over.
+.PP
+You can prevent people (other than the super-user) from writing to you with
+the
+.BR mesg (1)
+command.  Some commands, for example
+.BR nroff (1)
 and
-.Xr pr 1 ,
-disallow writing automatically, so that your output isn't overwritten.
-.Pp
+.BR pr (1),
+may disallow writing automatically, so that your output isn't overwritten.
+.PP
 If the user you want to write to is logged in on more than one terminal,
 you can specify which terminal to write to by specifying the terminal
 name as the second operand to the
-.Nm write
-command.
-Alternatively, you can let
-.Nm write
-select one of the terminals \- it will pick the one with the shortest
-idle time.
-This is so that if the user is logged in at work and also dialed up from
-home, the message will go to the right place.
-.Pp
-The traditional protocol for writing to someone is that the string
-.Ql \-o ,
+.B write
+command.  Alternatively, you can let
+.B write
+select one of the terminals \- it will pick the one with the shortest idle
+time.  This is so that if the user is logged in at work and also dialed up
+from home, the message will go to the right place.
+.PP
+The traditional protocol for writing to someone is that the string `\-o',
 either at the end of a line or on a line by itself, means that it's the
-other person's turn to talk.
-The string
-.Ql oo
-means that the person believes the conversation to be
-over.
-.Sh SEE ALSO
-.Xr mesg 1 ,
-.Xr talk 1 ,
-.Xr who 1
-.Sh HISTORY
+other person's turn to talk.  The string `oo' means that the person
+believes the conversation to be over.
+.SH "SEE ALSO"
+.BR mesg (1),
+.BR talk (1),
+.BR who (1)
+.SH HISTORY
 A
-.Nm
-command appeared in
-.At v6 .
+.B write
+command appeared in Version 6 AT&T UNIX.
index f2fe4a08621aea0b8068db38d9b89655d84335b4..a1865bd71aada89cd6ecd1b706c79f75cd0388c7 100644 (file)
@@ -1,6 +1,6 @@
 /*
- * Copyright (c) 1989 The Regents of the University of California.
- * All rights reserved.
+ * Copyright (c) 1989, 1993
+ *     The Regents of the University of California.  All rights reserved.
  *
  * This code is derived from software contributed to Berkeley by
  * Jef Poskanzer and Craig Leres of the Lawrence Berkeley Laboratory.
  */
 
 #ifndef lint
-char copyright[] =
-"@(#) Copyright (c) 1989 The Regents of the University of California.\n\
- All rights reserved.\n";
+static char copyright[] =
+"@(#) Copyright (c) 1989, 1993\n\
      The Regents of the University of California.  All rights reserved.\n";
 #endif /* not lint */
 
 #ifndef lint
-static char sccsid[] = "@(#)write.c    4.22 (Berkeley) 6/1/90";
+static char sccsid[] = "@(#)write.c    8.1 (Berkeley) 6/6/93";
 #endif /* not lint */
 
 #include <sys/param.h>
@@ -61,6 +61,8 @@ static char sccsid[] = "@(#)write.c   4.22 (Berkeley) 6/1/90";
 #include <string.h>
 #ifdef __linux__
 #include <paths.h>
+#include "pathnames.h"
+#include <locale.h>
 #endif
 
 extern int errno;
@@ -76,6 +78,10 @@ main(argc, argv)
        char tty[MAXPATHLEN], *mytty, *ttyname();
        void done();
 
+#ifdef __linux__
+       setlocale(LC_CTYPE,"");
+#endif
+
        /* check that sender has write enabled */
        if (isatty(fileno(stdin)))
                myttyfd = fileno(stdin);
@@ -329,7 +335,7 @@ wr_fputs(s)
 #define        PUTC(c) if (putchar(c) == EOF) goto err;
 
        for (; *s != '\0'; ++s) {
-               c = toascii(*s);
+               c = *s;
                if (c == '\n') {
                        PUTC('\r');
                        PUTC('\n');
index 737c716ab639c3a73b2420646bb405f379981481..22c146ce0530d958e0d0641a6f31d89ed087e9e7 100644 (file)
@@ -1,6 +1,7 @@
 # To make "ext" the default file system type for mount
 #  (used when no other type is specified), replace \"minix\" by \"ext2\".
-DEFAULT_FSTYPE=\"minix\"
+# Use iso9660 instead, since CDROMs are popular.
+DEFAULT_FSTYPE=\"iso9660\"
 
 # you need rpcgen and libc-4.2 or rpclib to compile in the NFS support
 DEFINES = -DHAVE_NFS -DFSTYPE_DEFAULT=$(DEFAULT_FSTYPE)
@@ -57,7 +58,7 @@ install: $(PROGS)
        $(INSTALLMAN) $(MAN5) $(MAN5DIR)
        $(INSTALLMAN) $(MAN8) $(MAN8DIR)
 
-.c.o:
+%.o: %.c
        $(COMPILE) $<
 
 mount: mount.o fstab.o sundries.o version.o $(NFS_OBJS) $(LO_OBJS)
index 8f96ee3b8e8294691491f7b368a7f6ed9499743d..82bf0f4c1deb69854434d05f045d2bb08988a4ba 100644 (file)
@@ -35,6 +35,7 @@
 .\" Sat Oct  9 10:07:10 1993: converted to man format by faith@cs.unc.edu
 .\" Sat Nov 20 20:47:38 1993: hpfs documentation added
 .\" Sat Nov 27 20:23:32 1993: Updated authorship information
+.\" Wed Jul 26 00:00:00 1995: Updated some nfs stuff, joey@infodrom.north.de
 .\"
 .TH FSTAB 5 "27 November 1993" "Linux 0.99" "Linux Programmer's Manual"
 .SH NAME
@@ -115,8 +116,11 @@ describes the mount options associated with the filesystem.
 
 It is formatted as a comma separated list of options.  It contains at least
 the type of mount plus any additional options appropriate to the filesystem
-type.  For documentation on all of the available options, see
+type.  For documentation on the available options for non-nfs file systems,
+see
 .BR mount (8).
+For documentation on all nfs-specific options have a look at
+.BR nfs (5).
 
 The fifth field,
 .RI ( fs_freq ),
@@ -154,14 +158,11 @@ The file
 resides in
 .IR /etc .
 .SH BUGS
-Linux does not, currently, support the special fields for
-.BR dump " and " fsck .
-
 The documentation in
 .BR mount (8)
 is often more up-to-date.
 .SH "SEE ALSO"
-.BR getmntent "(3), " mount "(8), " swapon (8)
+.BR getmntent "(3), " mount "(8), " swapon "(8), " nfs (5)
 .SH HISTORY
 The
 .B fstab
index 95b0879e0924b473bc4094f580570d52905c633e..d13280f8fc00b2df8e9db4aa6c8bf5f8177613f7 100644 (file)
@@ -1,11 +1,11 @@
-/* /home/faith/cvs/util-linux/mount/fstab.c,v 1.1.1.1 1995/02/22 19:09:21 faith Exp */
+/* $Header: /home/faith/cvs/util-linux/mount/fstab.c,v 1.2 1995/10/07 01:32:03 faith Exp $ */
 
 #include "fstab.h"
 #include <stdio.h>
 
 #define streq(s, t)    (strcmp ((s), (t)) == 0)
 
-/* These routines are superceded by mntent(3), but I use them for
+/* These routines are superseded by mntent(3), but I use them for
    convenience.  Mntent(3) is used in the implementation, so be
    very careful about the static buffers that are returned.  */
 
index c3c48b9e43269b74edbe471b74ba336bbbab7d04..825822591f15586641cdba61700001109ec53d0a 100644 (file)
@@ -1,7 +1,7 @@
 /* The fsent(3) routines are obsoleted by mntent(3).  I use them for
    convenience.  Since the implementation uses mntent(3), be very
    careful with the static buffers returned.
-   /home/faith/cvs/util-linux/mount/fstab.h,v 1.1.1.1 1995/02/22 19:09:21 faith Exp */
+   $Header: /home/faith/cvs/util-linux/mount/fstab.h,v 1.2 1995/09/25 20:57:42 faith Exp $ */
 
 #ifndef _FSTAB_H
 #include <stdio.h>
@@ -14,6 +14,7 @@
 #define fstab mntent
 #define fs_type mnt_type
 #define fs_spec mnt_fsname
+#define fs_mntopts mnt_opts
 #define FSTAB_SW MNTTYPE_SWAP
 
 struct fstab *getfsent (void);
index a47091dde4279b8f620c6d49e9ec1520a5626f34..4c197f467760b6f2d9968a83ca3d3490256b8cb4 100644 (file)
 .\"          Youngdale (eric@tantalus.nrl.navy.mil) and Remy Card
 .\"          (Remy.Card@masi.ibp.fr).
 .\" Sun Apr 24 19:25:59 1994: Updated per information supplied by Remy Card.
-.\" Thu Jul 14 07:44:36 1994: Updated absence of -t
-.\" option. (faith@cs.unc.edu)
+.\" Thu Jul 14 07:44:36 1994: Updated absence of -t option.
+.\"          (faith@cs.unc.edu)
 .\" Thu Jul 14 07:49:14 1994: Updated list of valid filesystems.
 .\" Wed Feb  8 09:25:48 1995: Updated man pages for Mike Grupenhoff's changes.
+.\" Sat Jul 22 01:45:58 1995: Updated list of binary extensions for
+.\"          msdos conversion. (sl14@cornell.edu)
+.\" Wed Jul 26 00:00:00 1995: Updated by Martin Schulze.
+.\"          (joey@infodrom.north.de)
+.\" Tue Sep 26 12:02:03 1995: Updated umount, nfs, proc parts of page.
+.\"          (aeb@cwi.nl)
 .\"
-.TH MOUNT 8 "8 February 1995" "Linux 1.1" "Linux Programmer's Manual"
+.TH MOUNT 8 "26 September 1995" "Linux 1.3" "Linux Programmer's Manual"
 .SH NAME
 mount, umount \- mount and dismount file systems
 .SH SYNOPSIS
@@ -62,9 +68,9 @@ mount, umount \- mount and dismount file systems
 .br
 .BI "mount [\-frwun] [\-t " vfstype "] [\-o " options "] " "special node"
 .br
-.BI "umount [\-an] [\-t " vfstype ]
+.BI "umount [\-ahvV] [\-t " vfstype ]
 .br
-.BI "umount " "special " | " node"
+.BI "umount [\-v] " "special " | " node " [...]
 .\" " for hilit19
 .SH DESCRIPTION
 The
@@ -79,13 +85,17 @@ If either
 .IR special " or " node
 are not provided, the appropriate information is taken from the
 .BR fstab (5)
-file.  The special keyword
-.I none
+file.  The
+.I proc
+file system is not associated with a special device, and when
+mounting it, an arbitrary keyword, such as
+.I proc
 can be used instead of a path or
 .I node
-specification.  This is useful when mounting the
-.I proc
-file system.
+specification. (The customary choice
+.I none
+is less fortunate: the error message `none busy' from umount
+can be confusing.)
 
 The system maintains a list of currently mounted file systems.  If no
 arguments are given to
@@ -196,7 +206,7 @@ or
 Tells the
 .I ext2
 file sysem kernel code to do some more checks while the file system is
-mounted.  Currently (0.99.15), the following values can be specified with
+mounted.  Currently (1.3.11), the following values can be specified with
 this option:
 .RS
 .TP
@@ -268,11 +278,12 @@ CRLF<-->NL translation is performed on all files that don't have a
 "well-known binary" extension. The list of known extensions can be found at
 the beginning of
 .I fs/msdos/misc.c
-(as of 09913r, the list is: exe, com, bin, app, sys, drv, ovl, ovr, obj,
+(as of 1.3.11, the list is: exe, com, bin, app, sys, drv, ovl, ovr, obj,
 lib, dll, pif, arc, zip, lha, lzh, zoo, tar, z, arj, tz, taz, tzp, tpz,
-gif, bmp, tif, gl, jpg, pcx, tfm, vf, gf, pk, pxl, dvi).
+gz, tgz, deb, gif, bmp, tif, gl, jpg, pcx, tfm, vf, gf, pk, pxl, dvi).
 .PP
 Programs that do computed lseeks won't like in-kernel text conversion.
+Several people have had their data ruined by this translation. Beware!
 
 For file systems mounted in
 .B binary
@@ -346,7 +357,7 @@ and
 file systems, give every file a gid equal to
 .IR value .
 .TP
-B grpid
+.B grpid
 Causes the
 .I ext2fs
 to use the BSD behavior when creating files: file are created with the
@@ -402,6 +413,19 @@ file system, turn on the
 flag.  Attempts to chown or chmod files do not yield errors, although they
 fail. Use with caution!
 .TP
+.B soft
+For the
+.IR nfs
+file system this allows the kernel to time out if the nfs server is not
+responding for some time, otherwise it will try forever. The time can be
+specified with
+.BR timeo=time .
+For more information look at
+.IR nfs (5).
+
+This option is useful if your nfs server sometimes doesn't respond or will
+be rebooted while some process tries to get a file from the server.
+.TP
 .BI sb= value
 For the
 .I ext2
@@ -459,8 +483,9 @@ The argument following the
 is used to indicate the file system type.  The file system types which are
 currently supported are listed in
 .IR linux/fs/filesystems.c :
-.IR minux ", " ext ", " ext2 ", " xiafs ", " msdos ", " hpfs ,
-.IR proc ", " nfs ", " iso9660 ", " sysv ", " xenix ", " coherent .
+.IR minix ", " ext ", " ext2 ", " xiafs ", " msdos ", " umsdos ,
+.IR hpfs ", " proc ", " nfs ", " iso9660 ", " smbfs ,
+.IR sysv ", " xenix ", " coherent .
 Note that that last three are equivalent and that "xenix" and "coherent"
 will be removed at some point in the future \(em use "sysv" instead.
 
@@ -468,13 +493,16 @@ The type
 .I minix
 is the default.  If no
 .B \-t
-option is given, the superblock is probed for the filesystem type (minix,
-ext, ext2, xia are supported).  If this probe fails and
+option is given, or if the "auto" type is specified, the superblock is
+probed for the filesystem type (minix, ext, ext2, xia are supported).  If
+this probe fails and
 .I /proc/filesystems
 exists, then all of the filesystems listed will be tried,
 .I except
 for those that are labeled "nodev" (e.g., "proc" and "nfs").
 
+Note that the "auto" type may be useful for user-mounted floppies.
+
 For example, the
 .B mount
 command:
@@ -503,9 +531,9 @@ Mount without writing in
 .B Umount
 removes the
 .I special
-device grafted at point
-.I node
-from file system tree.
+device, or the device grafted at point
+.IR node ,
+from the file system tree.
 
 Options for the
 .B umount
@@ -524,6 +552,15 @@ the file system types on which no action should be taken.  (See example
 above for the
 .B mount
 command.)
+.TP
+.B \-V
+Print version and exit.
+.TP
+.B \-h
+Print help message and exit.
+.TP
+.B \-v
+Verbose mode.
 
 .SH FILES
 .I /etc/fstab
@@ -535,7 +572,8 @@ lock file
 .I /etc/mtab.tmp
 temporary file
 .SH "SEE ALSO"
-.BR mount "(2), " umount "(2), " fstab "(5), " swapon (8)
+.BR mount "(2), " umount "(2), " fstab "(5), " swapon "(8), " nfs (5),
+.BR mountd "(8), " nfsd (8)
 .SH BUGS
 It is possible for a corrupted file system to cause a crash.
 .PP
index b6ffbcd67fadd05cb817c634ed3ac16c3c43c2fd..028848ac5f80a3aa898de854118fe4be5c3f568c 100644 (file)
@@ -2,7 +2,7 @@
  * A mount(8) for Linux 0.99.
  * mount.c,v 1.1.1.1 1993/11/18 08:40:51 jrs Exp
  *
- * Thu Jul 14 07:32:40 1994: faith@cs.unc.edu added changed from Adam
+ * Thu Jul 14 07:32:40 1994: faith@cs.unc.edu added changes from Adam
  * J. Richter (adam@adam.yggdrasil.com) so that /proc/filesystems is used
  * if no -t option is given.  I modified his patches so that, if
  * /proc/filesystems is not available, the behavior of mount is the same as
@@ -20,6 +20,8 @@
  * checked.
  *
  * Wed Feb  8 12:27:00 1995: Andries.Brouwer@cwi.nl fixed up error messages.
+ * Sat Jun  3 20:44:38 1995: Patches from Andries.Brouwer@cwi.nl applied.
+ * Tue Sep 26 22:38:20 1995: aeb@cwi.nl, many changes
  *
  */
 
@@ -33,6 +35,9 @@
 #include <sys/stat.h>
 #include <unistd.h>
 
+#define PROC_FILESYSTEMS       "/proc/filesystems"
+#define SIZE(a) (sizeof(a)/sizeof(a[0]))
+
 int del_loop (const char *);
 
 /* True for fake mount (-f).  */
@@ -99,15 +104,21 @@ const struct opt_map opt_map[] =
 #ifdef MS_NOSUB
   { "sub",     1, MS_NOSUB     },      /* allow submounts */
   { "nosub",   0, MS_NOSUB     },      /* don't allow submounts */
+#endif
+#ifdef  MS_SILENT
+  { "quiet",    0, MS_SILENT    },      /* be quiet  */
+  { "loud",     1, MS_SILENT    },      /* print out messages. */
 #endif
   { NULL,      0, 0            }
 };
 
+int mount_quiet=0;
 
 /* Report on a single mount.  */
 static void
 print_one (const struct mntent *mnt)
 {
+  if (mount_quiet) return;
   printf ("%s on %s", mnt->mnt_fsname, mnt->mnt_dir);
   if ((mnt->mnt_type != NULL) && *mnt->mnt_type != '\0')
     printf (" type %s", mnt->mnt_type);
@@ -151,6 +162,12 @@ parse_opt (const char *opt, int *mask, char *extra_opts)
          *mask |= om->mask;
        if (om->mask == MS_USER)
          *mask |= MS_SECURE;
+#ifdef MS_SILENT
+        if (om->mask == MS_SILENT && om->inv)  {
+          mount_quiet = 1;
+          verbose = 0;
+        }
+#endif
        return;
       }
   if (*extra_opts)
@@ -218,97 +235,192 @@ fix_opts_string (int flags, char *extra_opts)
 /*
     char *fstype(const char *device);
 
-    probes the device and attempts to determine the type of filesystem
+    Probes the device and attempts to determine the type of filesystem
     contained within.
 
     Original routine by <jmorriso@bogomips.ww.ubc.ca>; made into a function
     for mount(8) by Mike Grupenhoff <kashmir@umiacs.umd.edu>.
+    Read the superblock only once - aeb
+    Added a test for iso9660 - aeb
 
-    Currently supports: minix, ext, ext2, xia
+    Currently supports: minix, ext, ext2, xiafs, iso9660
 */
+char *magic_known[] = { "minix", "ext", "ext2", "xiafs", "iso9660" };
+
+static int
+tested(const char *device) {
+    char **m;
+
+    for (m = magic_known; m - magic_known < SIZE(magic_known); m++)
+        if (!strcmp(*m, device))
+           return 1;
+    return 0;
+}
 
 static char *
 fstype(const char *device)
 {
     int fd;
-
-    /* MINIX */
-    struct minix_super_block ms;
-    /* extended fs */
-    struct ext_super_block es;
-    /* 2nd extended fs */
-    struct ext2_super_block e2s;
-    /* xia fs */
-    struct xiafs_super_block xfs;
+    char ifs_magic[8];
+    union {
+       struct minix_super_block ms;
+       struct ext_super_block es;
+       struct ext2_super_block e2s;
+       struct xiafs_super_block xfs;
+    } sb;
+    struct stat statbuf;
+
+    /* opening and reading an arbitrary unknown path can have
+       undesired side effects - first check that `device' refers
+       to a block device */
+    if (stat (device, &statbuf))
+       error("mount: %s does not exist", device);
+    if (!S_ISBLK(statbuf.st_mode))
+       error("mount: %s is not a block device", device);
 
     fd = open(device, O_RDONLY);
-    if (fd < 0) {
+    if (fd < 0
+       || lseek(fd, BLOCK_SIZE, SEEK_SET) < 0
+       || read(fd, (char *) &sb, sizeof(sb)) < 0) {
        perror(device);
        return 0;
     }
-    lseek(fd, BLOCK_SIZE, SEEK_SET);
-    read(fd, (char *) &ms, sizeof(ms));
-    if (ms.s_magic == MINIX_SUPER_MAGIC || ms.s_magic == MINIX_SUPER_MAGIC2) {
-        close(fd);
+
+    if (sb.ms.s_magic == MINIX_SUPER_MAGIC
+       || sb.ms.s_magic == MINIX_SUPER_MAGIC2) {
+       close (fd);
        return("minix");
     }
 
-    lseek(fd, BLOCK_SIZE, SEEK_SET);
-    read(fd, (char *) &es, sizeof(es));
-    if (es.s_magic == EXT_SUPER_MAGIC) {
-        close(fd);
+    if (sb.es.s_magic == EXT_SUPER_MAGIC) {
+       close (fd);
        return("ext");
     }
 
-    lseek(fd, BLOCK_SIZE, SEEK_SET);
-    read(fd, (char *) &e2s, sizeof(e2s));
-    if (e2s.s_magic == EXT2_SUPER_MAGIC || e2s.s_magic == EXT2_PRE_02B_MAGIC) {
-        close(fd);
+#ifndef EXT2_PRE_02B_MAGIC
+#define EXT2_PRE_02B_MAGIC    0xEF51
+#endif
+    if (sb.e2s.s_magic == EXT2_SUPER_MAGIC
+       || sb.e2s.s_magic == EXT2_PRE_02B_MAGIC) {
+        close (fd);
        return("ext2");
     }
 
-    lseek(fd, 0, SEEK_SET);
-    read(fd, (char *) &xfs, sizeof(xfs));
-    if (xfs.s_magic == _XIAFS_SUPER_MAGIC) {
-        close(fd);
+    if (sb.xfs.s_magic == _XIAFS_SUPER_MAGIC) {
+        close (fd);
        return("xiafs");
     }
 
-    close(fd);
+    if (lseek (fd, 0100000, SEEK_SET) != -1
+        && read (fd, ifs_magic, 8) == 8
+        && !strncmp(ifs_magic, "\001CD001\001", 8)) { /* ECMA 119 */
+        close (fd);
+        return("iso9660");
+    }
 
+    close (fd);
     return(0);
+}
 
+FILE *procfs;
+
+static void
+procclose(void) {
+    if (procfs)
+        fclose (procfs);
+    procfs = 0;
+}
+
+static int
+procopen(void) {
+    return ((procfs = fopen(PROC_FILESYSTEMS, "r")) != NULL);
+}
+
+static char *
+procnext(void) {
+   char line[100];
+   static char fsname[50];
+
+   while (fgets(line, sizeof(line), procfs)) {
+      if (sscanf (line, "nodev %[^\n]\n", fsname) == 1) continue;
+      if (sscanf (line, " %[^ \n]\n", fsname) != 1) continue;
+      return fsname;
+   }
+   return 0;
 }
 
+static int
+is_in_proc(char *type) {
+    char *fsname;
+
+    if (procopen()) {
+       while ((fsname = procnext()) != NULL)
+         if (!strcmp(fsname, type))
+           return 1;
+    }
+    return 0;
+}
+
+static int
+already (char *spec, char *node) {
+    struct mntent *me;
+    int ret = 1;
+
+    if ((me = getmntfile(node)) != NULL)
+        error ("mount: according to mtab, %s is already mounted on %s",
+              me->mnt_fsname, node);
+    else if ((me = getmntfile(spec)) != NULL)
+        error ("mount: according to mtab, %s is mounted on %s",
+              spec, me->mnt_dir);
+    else
+        ret = 0;
+    return ret;
+}
 
 /* Mount a single file system.  Return status,
    so don't exit on non-fatal errors.  */
  
 static int
 try_mount5 (char *spec, char *node, char **type, int flags, char *mount_opts) {
-   FILE *procfs_file;
-   char line[100];
-   char fsname[50];
+   char *fsname;
    
-   if (*type) return mount5 (spec, node, *type, flags & ~MS_NOSYS, mount_opts);
-   if (( procfs_file = fopen("/proc/filesystems", "r")) == NULL) {
-                               /* If /proc/filesystems is not available,
-                                  preserve the old behavior of mount. */
-      return mount5 (spec,
-                    node,
-                    FSTYPE_DEFAULT,
-                    flags & ~MS_NOSYS, mount_opts);
+   if (strcasecmp (*type, "auto") == 0)
+      *type = NULL;
+
+   if (!*type) {
+      *type = fstype(spec);
+      if (!*type && !procopen())
+         *type = FSTYPE_DEFAULT;
+      if (verbose) {
+         printf ("mount: you didn't specify a filesystem type for %s\n",
+                 spec);
+         if (*type)
+           printf ("       I will try type %s\n", *type);
+         else
+           printf ("       I will try all types mentioned in %s\n",
+                   PROC_FILESYSTEMS);
+      }
    }
-   while (fgets(line, sizeof(line), procfs_file)) {
-      if (sscanf (line, "nodev %[^\n]\n", fsname) == 1) continue;
-      if (sscanf (line, " %[^ \n]\n", fsname) != 1) continue;
+
+   if (*type)
+      return mount5 (spec, node, *type, flags & ~MS_NOSYS, mount_opts);
+
+   while ((fsname = procnext()) != NULL) {
+      if (tested (fsname))
+        continue;
       if (mount5 (spec, node, fsname, flags & ~MS_NOSYS, mount_opts) == 0) {
-      *type=xstrdup(fsname);
-      fclose(procfs_file);
-      return 0;
+        *type = xstrdup(fsname);
+        procclose();
+        return 0;
+      } else if (errno != EINVAL) {
+         *type = "guess";
+        procclose();
+        return 1;
       }
    }
-   fclose(procfs_file);
+   procclose();
+   *type = NULL;
+
    return -1;
 }
 
@@ -321,7 +433,7 @@ mount_one (char *spec, char *node, char *type, char *opts, int freq, int pass)
   int flags;
   char *extra_opts;
   char *mount_opts;
-  int anti_recurse = 0;
+  static int added_ro = 0;
   int loop=0;
 
   if (type == NULL)
@@ -333,8 +445,12 @@ mount_one (char *spec, char *node, char *type, char *opts, int freq, int pass)
   parse_opts (xstrdup (opts), &flags, &extra_opts);
 
   /* root may allow certain types of mounts by ordinary users */
-  if (suid && !(flags & MS_USER))
-    die (3, "mount: only root can mount %s on %s", spec, node);
+  if (suid && !(flags & MS_USER)) {
+      if (already (spec, node))
+       die (3, "mount failed");
+      else
+        die (3, "mount: only root can mount %s on %s", spec, node);
+  }
 
   /* quietly succeed for fstab entries that don't get mounted automatically */
   if (all && (flags & MS_NOAUTO))
@@ -360,12 +476,9 @@ mount_one (char *spec, char *node, char *type, char *opts, int freq, int pass)
     if (nfsmount (spec, node, &flags, &extra_opts, &mount_opts) != 0)
       return 1;
 #else
-    die (1, "mount: this version doesn't support the type `nfs'");
+    die (1, "mount: this version was compiled without support for the type `nfs'");
 #endif
 
-  if (!type && !(type = fstype(spec)))
-       return 1;
-
   block_signals (SIG_BLOCK);
 
   if (fake
@@ -376,7 +489,7 @@ mount_one (char *spec, char *node, char *type, char *opts, int freq, int pass)
        {
          mnt.mnt_fsname = canonicalize (spec);
          mnt.mnt_dir = canonicalize (node);
-         mnt.mnt_type = loop?"loop":type;
+         mnt.mnt_type = loop ? "loop" : type;
          mnt.mnt_opts = fix_opts_string (flags & ~MS_NOMTAB, 
                                          loop?opts:extra_opts);
          mnt.mnt_freq = freq;
@@ -411,6 +524,10 @@ mount_one (char *spec, char *node, char *type, char *opts, int freq, int pass)
   block_signals (SIG_UNBLOCK);
 
   /* Mount failed, complain, but don't die.  */
+
+  if (type == 0)
+    error ("mount: you must specify the filesystem type");
+  else
   switch (mnt_err)
     {
     case EPERM:
@@ -421,11 +538,15 @@ mount_one (char *spec, char *node, char *type, char *opts, int freq, int pass)
       break;
     case EBUSY:
       error ("mount: %s already mounted or %s busy", spec, node);
+      already (spec, node);
       break;
     case ENOENT:
       { struct stat statbuf;
-       if (stat (node, &statbuf))
+       if (lstat (node, &statbuf))
              error ("mount: mount point %s does not exist", node);
+       else if (stat (node, &statbuf))
+             error ("mount: mount point %s is a symbolic link to nowhere",
+                    node);
        else if (stat (spec, &statbuf))
              error ("mount: special device %s does not exist", spec);
        else {
@@ -433,7 +554,7 @@ mount_one (char *spec, char *node, char *type, char *opts, int freq, int pass)
            perror("mount");
        }
        break;
-     }
+      }
     case ENOTDIR:
       error ("mount: mount point %s is not a directory", node); break;
     case EINVAL:
@@ -443,31 +564,37 @@ mount_one (char *spec, char *node, char *type, char *opts, int freq, int pass)
     case EIO:
       error ("mount: %s: can't read superblock", spec); break;
     case ENODEV:
-      error ("mount: fs type %s not supported by kernel", type); break;
+      if (is_in_proc(type))
+        error("mount: %s has wrong major or minor number", spec);
+      else if (procfs)
+       error ("mount: fs type %s not supported by kernel", type);
+      else
+       error ("mount: %s has wrong device number or fs type %s not supported",
+              spec, type);
+      break;
     case ENOTBLK:
       error ("mount: %s is not a block device", spec); break;
     case ENXIO:
       error ("mount: %s is not a valid block device", spec); break;
     case EACCES:  /* pre-linux 1.1.38 */
     case EROFS:   /* linux 1.1.38 and later */
-      if (anti_recurse)
-        {
-          error ("mount: block device %s is not permitted on its filesystem", spec);
+      if (added_ro) {
+          error ("mount: block device %s is not permitted on its filesystem",
+                spec);
           break;
-        }
-      else
-        {
-         anti_recurse++;
-         if (opts)
-           {
-             opts = realloc(xstrdup(opts), strlen(opts)+3);
+      } else {
+         added_ro = 1;
+         if (opts) {
+             opts = realloc(xstrdup(opts), strlen(opts)+4);
              strcat(opts, ",ro");
-           }
-         else
-           opts = "ro";
-          error ("mount: block device %s is write-protected, mounting read-only", spec);
-          return mount_one (spec, node, type, opts, freq, pass);
-        }
+         } else
+             opts = "ro";
+        if (type && !strcmp(type, "guess"))
+            type = 0;
+         error ("mount: block device %s is write-protected, "
+               "mounting read-only", spec);
+        return mount_one (spec, node, type, opts, freq, pass);
+      }
       break;
     default:
       error ("mount: %s", strerror (mnt_err)); break;
@@ -514,6 +641,7 @@ mount_all (string_list types)
       }
 
   status = 0;
+  if (!setfsent()) return 1;
   while ((fstab = getfsent ()) != NULL)
     if (matching_type (fstab->mnt_type, types)
         && !streq (fstab->mnt_dir, "/")
@@ -592,6 +720,7 @@ static void
 usage (FILE *fp, int n)
 {
   fprintf (fp, "%s", usage_string);
+  unlock_mtab();
   exit (n);
 }
 
@@ -629,7 +758,7 @@ main (int argc, char *argv[])
        ++verbose;
        break;
       case 'V':                        /* version */
-       printf ("%s\n", version);
+       printf ("mount: %s\n", version);
        exit (0);
       case 'w':                        /* mount read/write */
        ++readwrite;
index ee5203f5a5bdbb8325f69da4e78532d379e281bb..cdfba803d19e04cc69926d2a18e82d0dd80a392a 100644 (file)
@@ -195,7 +195,7 @@ interrupted.
 .SH FILES
 .I /etc/fstab
 .SH "SEE ALSO"
-.BR fstab "(5), " mount "(8), " umount (8)
+.BR fstab "(5), " mount "(8), " umount "(8), " exports (5)
 .SH AUTHOR
 "Rick Sladkey" <jrs@world.std.com>
 .SH BUGS
index 45e0e14d80fe6de0c9acd6345b62da564554c129..5ebf0195fdf451fe5399fed6d9b8690a7e8f371f 100644 (file)
@@ -1,9 +1,12 @@
 /*
  * Support functions.  Exported functions are prototyped in sundries.h.
  * sundries.c,v 1.1.1.1 1993/11/18 08:40:51 jrs Exp
+ *
+ * added fcntl locking by Kjetil T. (kjetilho@math.uio.no) - aeb, 950927
  */
 
 #include "sundries.h"
+#include "mount.h"
 
 /* File pointer for /etc/mtab.  */
 FILE *F_mtab = NULL;
@@ -14,6 +17,9 @@ FILE *F_temp = NULL;
 /* File descriptor for lock.  Value tested in unlock_mtab() to remove race.  */
 static int lock = -1;
 
+/* Flag for already existing lock file. */
+static int old_lockfile = 1;
+
 /* String list constructor.  (car() and cdr() are defined in "sundries.h").  */
 string_list
 cons (char *a, const string_list b)
@@ -75,6 +81,7 @@ error (const char *fmt, ...)
 {
   va_list args;
 
+  if (mount_quiet) return;
   va_start (args, fmt);
   vfprintf (stderr, fmt, args);
   fprintf (stderr, "\n");
@@ -103,6 +110,12 @@ handler (int sig)
   die (2, "%s", sys_siglist[sig]);
 }
 
+static void
+setlkw_timeout (int sig)
+{
+  /* nothing, fcntl will fail anyway */
+}
+
 /* Create the lock file.  The lock file will be removed if we catch a signal
    or when we exit.  The value of lock is tested to remove the race.  */
 void
@@ -110,20 +123,54 @@ lock_mtab (void)
 {
   int sig = 0;
   struct sigaction sa;
+  struct flock flock;
 
   /* If this is the first time, ensure that the lock will be removed.  */
   if (lock < 0)
     {
+      struct stat st;
       sa.sa_handler = handler;
       sa.sa_flags = 0;
       sigfillset (&sa.sa_mask);
   
       while (sigismember (&sa.sa_mask, ++sig) != -1)
-       sigaction (sig, &sa, (struct sigaction *) 0);
-
-      if ((lock = open (MOUNTED_LOCK, O_WRONLY|O_CREAT|O_EXCL, 0)) < 0)
-       die (2, "can't create lock file %s: %s",
-            MOUNTED_LOCK, strerror (errno));
+       {
+         if (sig == SIGALRM)
+           sa.sa_handler = setlkw_timeout;
+         else
+           sa.sa_handler = handler;
+         sigaction (sig, &sa, (struct sigaction *) 0);
+       }
+
+      /* This stat is performed so we know when not to be overly eager
+        when cleaning up after signals. The window between stat and
+        open is not significant. */
+      if (lstat (MOUNTED_LOCK, &st) < 0 && errno == ENOENT)
+       old_lockfile = 0;
+
+      lock = open (MOUNTED_LOCK, O_WRONLY|O_CREAT, 0);
+      if (lock < 0)
+        {
+          die (2, "can't create lock file %s: %s",
+              MOUNTED_LOCK, strerror (errno));
+        }
+
+      flock.l_type = F_WRLCK;
+      flock.l_whence = SEEK_SET;
+      flock.l_start = 0;
+      flock.l_len = 0;
+
+      alarm(LOCK_BUSY);
+      if (fcntl (lock, F_SETLKW, &flock) < 0)
+       {
+         close (lock);
+         /* The file should not be removed */
+         lock = -1;
+         die (2, "can't lock lock file %s: %s",
+              MOUNTED_LOCK, errno == EINTR ? "timed out" : strerror (errno));
+       }
+      /* We have now access to the lock, and it can always be removed */
+      old_lockfile = 0;
     }
 }
 
@@ -133,8 +180,9 @@ unlock_mtab (void)
 {
   if (lock != -1)
     {
-      close( lock );
-      unlink (MOUNTED_LOCK);
+      close (lock);
+      if (!old_lockfile)
+       unlink (MOUNTED_LOCK);
     }
 }
 
index ba878c9b4db4a69a7416b97dfb45d1ceac789732..77d8d32f40ee228b893e248a081554dde621c5ff 100644 (file)
 #include <string.h>
 #include <unistd.h>
 
+#if 0
+#include <linux/version.h>
+#if LINUX_VERSION_CODE >= 0x010302
+#define SUPPORT_PRIORITIES
+#endif
+#endif
+
+#ifdef SUPPORT_PRIORITIES
+#include <linux/swap.h>
+#endif
+
 #include "fstab.h"
 
+extern int mount_quiet;
 
 #define streq(s, t)    (strcmp ((s), (t)) == 0)
 
@@ -27,7 +39,7 @@
 #define MOUNTED_LOCK   "/etc/mtab~"
 #define MOUNTED_TEMP   "/etc/mtab.tmp"
 #define _PATH_FSTAB    "/etc/fstab"
-#define LOCK_BUSY      3
+#define LOCK_BUSY      10
 
 /* File pointer for /etc/mtab.  */
 extern FILE *F_mtab;
index 44c841681b3a2aae01165cc8a598ccc9671f61d9..911855dcff6a1674ba9784109095d6a71b73ebe0 100644 (file)
 .\" Sat Mar  6 20:46:02 1993: Modified by faith@cs.unc.edu
 .\" Sat Oct  9 09:35:30 1993: Converted to man format by faith@cs.unc.edu
 .\" Sat Nov 27 20:22:42 1993: Updated authorship information, faith@cs.unc.edu
+.\" Mon Sep 25 14:12:38 1995: Added -v and -p information
 .\"
-.TH SWAPON 8 "27 November 1993" "Linux 0.99" "Linux Programmer's Manual"
+.TH SWAPON 8 "25 September 1995" "Linux 1.x" "Linux Programmer's Manual"
 .SH NAME
 swapon, swapoff \- enable/disable devices and files for paging and swapping
 .SH SYNOPSIS
-.B /etc/swapon \-a
+.B /sbin/swapon [\-h \-V]
 .br
-.BI /etc/swapon " specialfile " ...
+.B /sbin/swapon \-a [\-v]
 .br
-.B /etc/swapoff \-a
+.BI "/sbin/swapon [\-v] [\-p " "priority" "] " " specialfile " ...
 .br
-.BI /etc/swapoff " specialfile " ...
+.B /sbin/swapoff [\-h \-V]
+.br
+.B /sbin/swapoff \-a
+.br
+.BI /sbin/swapoff " specialfile " ...
 .SH DESCRIPTION
 .B Swapon
 is used to specify devices on which paging and swapping are to take place.
@@ -59,10 +64,23 @@ is interleaved across several devices and files.
 
 Normally, the first form is used:
 .TP
+.B \-h
+Provide help
+.TP
+.B \-V
+Display version
+.TP
 .B \-a
 All devices marked as ``sw'' swap devices in
 .I /etc/fstab
 are made available.
+.TP
+.BI \-p " priority"
+Specify priority for
+.BR swapon .
+This option is only available if
+.B swapon
+was compiled under and is used under a 1.3.2 or later kernel.
 .PP
 .B Swapoff
 disables swapping on the specified devices and files, or on all swap
@@ -75,10 +93,10 @@ flag is given.
 .BR swapon "(2), " swapoff "(2), " fstab "(5), " init "(8), " mkswap (8),
 .BR rc "(8), " mount (8)
 .SH FILES
-.I /dev/hd[ab]?
+.I /dev/hd??
 standard paging devices
 .br
-.I /dev/sd[ab]?
+.I /dev/sd??
 standard (SCSI) paging devices
 .br
 .I /etc/fstab
index 584033021b92938d55f8b40655f532751d9d4824..331238f0be9c495228841f892583c457052601ed 100644 (file)
@@ -7,6 +7,9 @@
 
 /* Nonzero for chatty (-v).  This is a nonstandard flag (not in BSD).  */
 int verbose = 0;
+#ifdef SUPPORT_PRIORITIES
+int priority = -1;     /* non-prioritized swap by default */
+#endif
 
 extern char version[];
 static char *program_name;
@@ -14,16 +17,27 @@ static struct option longopts[] =
 {
   { "all", 0, 0, 'a' },
   { "help", 0, 0, 'h' },
+#ifdef SUPPORT_PRIORITIES
+  { "priority", required_argument, 0, 'p' },
+#endif
   { "verbose", 0, 0, 'v' },
   { "version", 0, 0, 'V' },
   { NULL, 0, 0, 0 }
 };
 
+#ifdef SUPPORT_PRIORITIES
 const char *usage_string = "\
 usage: %s [-hV]\n\
        %s -a [-v]\n\
-       %s [-v] special ...\n\
+       %s [-v] [-p priority] special ...\n\
 ";
+#else
+const char *usage_string = "\
+usage: %s [-hV]\n\
+       %s -a [-v]\n\
+       %s [-v] [-p priority] special ...\n\
+";
+#endif
 
 static void
 usage (FILE *fp, int n)
@@ -33,17 +47,33 @@ usage (FILE *fp, int n)
 }
 
 static int
+#ifdef SUPPORT_PRIORITIES
+swap (const char *special, int prio)
+#else
 swap (const char *special)
+#endif
 {
   int status;
+#ifdef SUPPORT_PRIORITIES
+  int flags;
+#endif
 
   if (verbose)
     printf("%s on device %s\n", program_name, special);
 
-  if (streq (program_name, "swapon"))
-    status = swapon (special);
-  else
-    status = swapoff (special);
+  if (streq (program_name, "swapon")) {
+#ifdef SUPPORT_PRIORITIES
+     flags = 0;
+     if (prio >= 0) {
+       flags = SWAP_FLAG_PREFER
+               | ((prio & SWAP_FLAG_PRIO_MASK) << SWAP_FLAG_PRIO_SHIFT);
+     }
+     status = swapon (special, flags);
+#else
+     status = swapon (special);
+#endif
+  } else
+     status = swapoff (special);
 
   if (status < 0)
     fprintf (stderr, "%s: %s: %s\n", program_name, special, strerror (errno));
@@ -64,7 +94,11 @@ main (int argc, char *argv[])
   else
     program_name = argv[0];
 
+#ifdef SUPPORT_PRIORITIES
+  while ((c = getopt_long (argc, argv, "ahp:vV", longopts, NULL)) != EOF)
+#else
   while ((c = getopt_long (argc, argv, "ahvV", longopts, NULL)) != EOF)
+#endif
     switch (c)
       {
       case 'a':                        /* all */
@@ -73,11 +107,16 @@ main (int argc, char *argv[])
       case 'h':                        /* help */
        usage (stdout, 0);
        break;
+#ifdef SUPPORT_PRIORITIES
+      case 'p':                        /* priority */
+       priority = atoi(optarg);
+       break;
+#endif
       case 'v':                        /* be chatty */
        ++verbose;
        break;
       case 'V':                        /* version */
-       printf ("%s\n", version);
+       printf ("swapon: %s\n", version);
        exit (0);
       case 0:
        break;
@@ -94,7 +133,25 @@ main (int argc, char *argv[])
     {
       while ((fstab = getfsent()) != NULL)
        if (streq (fstab->fs_type, FSTAB_SW))
-         status |= swap (fstab->fs_spec);
+       {
+#ifdef SUPPORT_PRIORITIES
+          /* parse mount options; */
+          char *opt, *opts = strdup(fstab->fs_mntopts);
+          
+          for (opt = strtok (opts, ",");
+               opt != NULL;
+               opt = strtok (NULL, ","))
+          {
+             if (strncmp(opt, "pri=", 4) == 0)
+             {
+                priority = atoi(opt+4);
+             }
+          }
+          status |= swap (fstab->fs_spec, priority);
+#else
+          status |= swap (fstab->fs_spec);
+#endif
+       }
     }
   else if (*argv == NULL)
     {
@@ -102,8 +159,13 @@ main (int argc, char *argv[])
     }
   else
     {
-      while (*argv != NULL)
-       status |= swap (*argv++);
+       while (*argv != NULL) {
+#ifdef SUPPORT_PRIORITIES
+         status |= swap (*argv++,priority);
+#else
+         status |= swap (*argv++);
+#endif
+       }
     }
   return status;
 }
index c3cfee71aa0c0072b67a128f0956be6a01f3d4ac..236f05241d3ee8914d2618e0e95c1eb4487ac2fa 100644 (file)
@@ -5,6 +5,9 @@
  * Wed Sep 14 22:43:54 1994: Sebastian Lederer
  * (lederer@next-pc.informatik.uni-bonn.de) added support for sending an
  * unmount RPC call to the server when an NFS-filesystem is unmounted.
+ *
+ * Tue Sep 26 16:33:09 1995: Added patches from Greg Page (greg@caldera.com)
+ * so that NetWare filesystems can be unmounted.
  */
 
 #include "sundries.h"
@@ -44,7 +47,7 @@ static int xdr_dir(XDR *xdrsp, char *dirp)
 /* Umount a single device.  Return a status code, so don't exit
    on a non-fatal error.  We lock/unlock around each umount.  */
 static int
-umount_one (const char *spec, const char *node)
+umount_one (const char *spec, const char *node, const char *type)
 {
   int umnt_err;
   int isroot;
@@ -75,7 +78,7 @@ umount_one (const char *spec, const char *node)
 #ifdef HAVE_NFS
       strcpy(buffer,spec);
               /* spec is constant so must use own buffer */
-      if((p=strchr(buffer,':')))
+      if(!strcasecmp(type, "nfs") && (p=strchr(buffer,':')))
       {
               *p='\0';
               strcpy(hostname,buffer);
@@ -174,7 +177,9 @@ fail:
     case EIO:
       error ("umount: %s: can't write superblock", spec); break;
     case EBUSY:
-      error ("umount: %s: device is busy", spec); break;
+     /* Let us hope fstab has a line "proc /proc ..."
+       and not "none /proc ..."*/
+     error ("umount: %s: device is busy", spec); break;
     case ENOENT:
       error ("umount: %s: not mounted", spec); break;
     case EPERM:
@@ -197,6 +202,7 @@ umount_all (string_list types)
 {
   string_list spec_list = NULL;
   string_list node_list = NULL;
+  string_list type_list = NULL;
   struct mntent *mnt;
   int errors;
 
@@ -207,6 +213,7 @@ umount_all (string_list types)
       {
        spec_list = cons (xstrdup (mnt->mnt_fsname), spec_list);
        node_list = cons (xstrdup (mnt->mnt_dir), node_list);
+        type_list = cons (xstrdup (mnt->mnt_type), type_list);
       }
 
   close_mtab ();
@@ -214,9 +221,10 @@ umount_all (string_list types)
   errors = 0;
   while (spec_list != NULL)
     {
-      errors |= umount_one (car (spec_list), car (node_list));
+      errors |= umount_one (car (spec_list), car (node_list), car (type_list));
       spec_list = cdr (spec_list);
       node_list = cdr (node_list);
+      type_list = cdr (type_list);
     }
 
   sync ();
@@ -238,7 +246,7 @@ static struct option longopts[] =
 char *usage_string = "\
 usage: umount [-hV]\n\
        umount -a [-v] [-t vfstypes]\n\
-       umount [-v] special | node\n\
+       umount [-v] special | node...\n\
 ";
 
 static void
@@ -248,6 +256,8 @@ usage (FILE *fp, int n)
   exit (n);
 }
 
+int mount_quiet = 0;
+
 int
 main (int argc, char *argv[])
 {
@@ -281,7 +291,7 @@ main (int argc, char *argv[])
        ++verbose;
        break;
       case 'V':                        /* version */
-       printf ("%s\n", version);
+       printf ("umount: %s\n", version);
        exit (0);
       case 't':                        /* specify file system type */
        types = parse_list (optarg);
@@ -305,9 +315,9 @@ main (int argc, char *argv[])
 
   if (all)
     result = umount_all (types);
-  else if (argc != 1)
+  else if (argc < 1)
     usage (stderr, 2);
-  else
+  else while (argc--)
     {
       file = canonicalize (*argv); /* mtab paths are canonicalized */
 
@@ -326,7 +336,7 @@ main (int argc, char *argv[])
       if (suid)
        {
          if (!mnt)
-           die (2, "umount: %s is not mounted", file);
+           die (2, "umount: %s is not mounted (according to mtab)", file);
          if (!(fs = getfsspec (file)) && !(fs = getfsfile (file)))
            die (2, "umount: %s is not in the fstab", file);
          if (!streq (mnt->mnt_fsname, fs->mnt_fsname)
@@ -345,9 +355,11 @@ main (int argc, char *argv[])
        }
 
       if (mnt)
-       result = umount_one (xstrdup (mnt->mnt_fsname), xstrdup(mnt->mnt_dir));
+        result = umount_one (xstrdup (mnt->mnt_fsname), xstrdup(mnt->mnt_dir),
+                             xstrdup(mnt->mnt_type));
       else
-       result = umount_one (*argv, *argv);
+        result = umount_one (*argv, *argv, *argv);
+
     }
   exit (result);
 }
index ece944d29e7062aacbe1660f0c268f61fae38055..47aed1dcddc6798de13036ae9eb7cf3bb9cc0ab6 100644 (file)
@@ -1 +1 @@
-char version[] = "(u)mount: version from util-linux-2.2";
+char version[] = "version from util-linux-2.5";
diff --git a/sys-utils/MAKEDEV b/sys-utils/MAKEDEV
deleted file mode 100644 (file)
index 6326edd..0000000
+++ /dev/null
@@ -1,486 +0,0 @@
-#! /bin/sh -
-
-RCSID='MAKEDEV,v 1.1.1.1 1995/02/22 19:09:11 faith Exp'
-
-#---#---#---#---#---#---#---#---#---#---#---#---#---#---#---#---#---#---#---#
-# Customisation:
-#   The devices fall into various classes.  This section contains the mapping
-# from a class name into a group name and permission.
-#   You will almost certainly need to edit the group name to match your
-# system, and you may change the permissions to suit your preference.  These
-# lines _must_ be of the format "user group perm".
-
- public="  root system 666"
- system="  root system 660"
-   kmem="  root kmem   660"
-    tty="  root tty    666"
-   cons="  root tty    622"    # 622 for console?
-dialout="  root uucp   660"
-  mouse="  root system 666"
-printer="  root daemon 660"
- floppy="  root floppy 660"
-   disk="  root disk   660"
-   scsi="  root system 600"
-  cdrom="  root disk   660"
-   tape="  root disk   660"
-  audio="  root system 666"
-  ibcs2="  root system 666"
-scanner="  root system 666"
-
-#---#---#---#---#---#---#---#---#---#---#---#---#---#---#---#---#---#---#---#
-
-procfs=/proc
-
-opt_v=
-opt_d=
-opt_n=
-
-while [ $# -ge 1 ]
-do
-       case $1 in
-               --)     shift; break ;;
-               -v)     shift; opt_v=1 ;;
-               -d)     shift; opt_d=1 ;;
-               -n)     shift; opt_n=1; opt_v=1 ;;
-               -V)     shift; opt_V=1 ;;
-               -*)     echo "$0: unknown flag \"$1\"" >&2; exit 1 ;;
-               *)      break ;;
-       esac
-done
-
-if [ "$opt_V" ]
-then
-       echo "$RCSID"
-       exit 0
-fi
-
-opts="${opt_n:+-n} ${opt_v:+-v} ${opt_d:+-d}"
-
-makedev () {   # usage: makedev name [bcu] major minor owner group mode
-       if [ "$opt_v" ]
-       then    if [ "$opt_d" ]
-               then    echo "delete $1"
-               else    echo "create $1 $2 $3 $4 $5:$6 $7" 
-               fi
-       fi
-       if [ ! "$opt_n" ]
-       then    if [ "$opt_d" ]
-               then
-                       rm -f $1
-               else
-                       mknod $1- $2 $3 $4 &&
-                       chown $5:$6 $1- &&
-                       chmod $7 $1- &&
-                       mv $1- $1
-               fi
-       fi
-}
-symlink () {   # usage: symlink name target
-       if [ "$opt_v" ]
-       then    if [ "$opt_d" ]
-               then    echo "delete $1"
-               else    echo "create $1 -> $2"
-               fi
-       fi
-       [ ! "$opt_n" ] && rm -f $1 &&
-       [ ! "$opt_d" ] && ln -s $2 $1
-}
-
-devices=
-if [ ! -f $procfs/devices ]
-then
-       echo "$0: warning: can't read $procfs/devices" >&2
-else
-       exec 3<$procfs/devices
-       while read major device <&3
-       do
-               case "$major" in
-                       Character|Block|'')
-                               ;;
-                       *)
-                               eval "major_$device=$major"
-                               devices="$devices $device"
-                               ;;
-               esac
-       done
-       exec 3<&-
-fi
-
-Major () {
-       device=$2
-       if [ "$opt_d" ]
-       then
-               echo -1 # don't care
-       else
-               eval echo \${major_$1:-\${device:?\"unknown major number for $1\"}}
-       fi
-}
-
-cvt () {
-       while [ $# -ne 0 ]
-       do
-               case "$1" in
-                       mem|tty|ttyp|cua|cub)   ;;
-                       hd)     echo hda hdb ;;
-                       xd)     echo xda xdb ;;
-                       fd)     echo fd0 fd1 ;;
-                       lp)     echo lp0 lp1 lp2 ;;
-                       mt)     echo ftape ;;
-                       loop)   echo loop ;;
-                       ibcs2)  echo ibcs2 ;;
-                       tpqic02)        echo qic ;;
-                       sound)          echo audio ;;
-                       logiscan)       echo logiscan ;;
-                       ac4096)         echo ac4096 ;;
-                       idecd)  echo idecd ;;
-                       hw)     echo helloworld ;;
-                       sbpcd | sbpcd[123])     echo $1 ;;
-                       Joystick)       echo js ;;
-                       apm_bios)       echo apm ;;
-                       dcf)            echo dcf ;;
-                       pcmcia) ;; # taken care of by its own driver
-                       ttyC)   echo cyclades ;;
-                       *)      echo "$0: don't know what \"$1\" is" >&2 ;;
-               esac
-               shift
-       done
-}
-
-for arg
-do
-       case $arg in
-       generic)
-               $0 $opts std
-               $0 $opts fd0 fd1
-               $0 $opts hda hdb
-               $0 $opts xda xdb
-               $0 $opts sda sdb
-               $0 $opts ptyp ptyq ptyr ptys
-               $0 $opts console tty1 tty2 tty3 tty4 tty5 tty6 tty7 tty8
-               $0 $opts ttyS0 ttyS1 ttyS2 ttyS3
-               $0 $opts busmice
-               $0 $opts lp0 lp1 lp2
-               $0 $opts par0 par1 par2
-               $0 $opts fd
-               ;;
-       local)
-               $0.local $opts
-               ;;
-       std)
-               makedev mem  c 1 1 $kmem
-               makedev kmem c 1 2 $kmem
-               makedev null c 1 3 $public
-               makedev port c 1 4 $kmem
-               makedev zero c 1 5 $public
-               symlink core $procfs/kcore
-               makedev full c 1 7 $public
-               makedev ram  b 1 1 $disk
-               makedev tty  c 5 0 $tty
-               ;;
-       console|tty0)
-               makedev $arg c 4 0 $cons
-               ;;
-       tty[1-9]|tty[1-5][0-9]|tty[6][0-3])
-               line=`expr $arg : "tty\(.*\)"`
-               makedev tty$line c 4 $line $tty
-               ;;
-       ttyS[0-9]|ttyS[1-5][0-9]|ttyS[6][0-3])
-               line=`expr $arg : "ttyS\(.*\)"`
-               minor=`expr 64 + $line`
-               makedev ttyS$line c 4 $minor $tty
-               makedev cua$line c 5 $minor $dialout
-               ;;
-       pty[p-s])
-               # Currently limited to 64 master/slave pairs.
-               bank=`expr $arg : "pty\(.\)"`
-               base=`expr \( pqrs : ".*$bank" - 1 \) \* 16`
-               for i in 0 1 2 3 4 5 6 7 8 9 a b c d e f
-               do
-                       j=`expr 0123456789abcdef : ".*$i" - 1`
-                       makedev pty$bank$i c 4 `expr 128 + $base + $j` $tty
-                       makedev tty$bank$i c 4 `expr 192 + $base + $j` $tty
-               done
-               ;;
-       cyclades)
-               major1=`Major ttyC` || continue
-               major2=`Major cub` || continue
-               for i in 0 1 2 3 4 5 6 7 # 8 9 10 11 12 13 14 15
-               do
-                       makedev ttyC$i c $major1 `expr 32 + $i` $tty
-                       makedev cub$i c $major2 `expr 32 + $i` $dialout
-               done
-               ;;
-       par[0-2])
-               major=`Major lp 6` || continue
-               port=`expr $arg : "par\(.\)"`
-               makedev $arg c $major $port $printer
-               ;;
-       lp[0-2])
-               major=`Major lp 6` || continue
-               port=`expr $arg : "lp\(.\)"`
-               makedev $arg c $major $port $printer
-               ;;
-       busmice)
-               major=`Major mouse 10` || continue
-               makedev logibm   c $major 0 $mouse
-               makedev psaux    c $major 1 $mouse
-               makedev inportbm c $major 2 $mouse
-               makedev atibm    c $major 3 $mouse
-               # makedev sejin    c $major 4 $mouse
-               ;;
-       js)
-               major=`Major Joystick` || continue
-               makedev js0 c $major 0 $mouse
-               makedev js1 c $major 1 $mouse
-               ;;
-       fd[0-4])
-               major=`Major fd 2` || continue
-               unit=`expr $arg : "fd\(.\)"`
-               makedev fd${unit} b $major $unit $floppy
-               makedev fd${unit}d360  b $major `expr $unit +  4` $floppy
-               makedev fd${unit}h1200 b $major `expr $unit +  8` $floppy
-               makedev fd${unit}D360  b $major `expr $unit + 12` $floppy
-               symlink fd${unit}H360 fd${unit}D360
-               makedev fd${unit}D720  b $major `expr $unit + 16` $floppy
-               symlink fd${unit}H720 fd${unit}D720
-               makedev fd${unit}h360  b $major `expr $unit + 20` $floppy
-               makedev fd${unit}h720  b $major `expr $unit + 24` $floppy
-               makedev fd${unit}H1440 b $major `expr $unit + 28` $floppy
-               makedev fd${unit}E2880 b $major `expr $unit + 32` $floppy
-               makedev fd${unit}CompaQ b $major `expr $unit + 36` $floppy
-
-               makedev fd${unit}h1440 b $major `expr $unit + 40` $floppy
-               makedev fd${unit}H1680 b $major `expr $unit + 44` $floppy
-               makedev fd${unit}h410  b $major `expr $unit + 48` $floppy
-               makedev fd${unit}H820  b $major `expr $unit + 52` $floppy
-               makedev fd${unit}h1476 b $major `expr $unit + 56` $floppy
-               makedev fd${unit}H1722 b $major `expr $unit + 60` $floppy
-               makedev fd${unit}h420  b $major `expr $unit + 64` $floppy
-               makedev fd${unit}H830  b $major `expr $unit + 68` $floppy
-               makedev fd${unit}h1494 b $major `expr $unit + 72` $floppy
-               makedev fd${unit}H1743 b $major `expr $unit + 76` $floppy
-               ;;
-       hd[a-d])
-               major=`Major hd 3` || continue
-               unit=`expr $arg : "hd\(.\)"`
-               base=`expr \( abcd : ".*$unit" - 1 \) \* 64`
-               makedev hd$unit b $major $base $disk
-               for part in 1 2 3 4 5 6 7 8 # 9 10 11 12 13 14 15 16
-               do
-                       makedev hd$unit$part b $major `expr $base + $part` $disk
-               done
-               ;;
-       hd1[a-d])
-               unit=`expr $arg : "hd1\(.\)"`
-               base=`expr \( abcd : ".*$unit" - 1 \) \* 64`
-               makedev hd1$unit b 22 $base $disk
-               for part in 1 2 3 4 5 6 7 8 # 9 10 11 12 13 14 15 16
-               do
-                       makedev hd1$unit$part b 22 `expr $base + $part` $disk
-               done
-               ;;
-       xd[a-d])
-               major=`Major xd 13` || continue
-               unit=`expr $arg : "xd\(.\)"`
-               base=`expr \( abcd : ".*$unit" - 1 \) \* 64`
-               makedev xd$unit b $major $base $disk
-               for part in 1 2 3 4 5 6 7 8 # 9 10 11 12 13 14 15 16
-               do
-                       makedev xd$unit$part b $major `expr $base + $part` $disk
-               done
-               ;;
-       sd[a-h])
-               major=`Major sd 8` || continue
-               unit=`expr $arg : "sd\(.\)"`
-               base=`expr \( abcdefgh : ".*$unit" - 1 \) \* 16`
-               makedev sd$unit b $major $base $disk
-               for part in 1 2 3 4 5 6 7 8 # 9 10 11 12 13 14 15
-               do
-                       minor=`expr $base + $part`
-                       makedev sd$unit$part b $major $minor $disk
-               done
-               ;;
-       loop)
-               major=`Major loop` || continue
-               for part in 0 1 2 3 4 5 6 7
-               do
-                       makedev loop$part b $major $part $disk
-               done
-               ;;
-       st[0-7])
-               major=`Major st 9`
-               unit=`expr $arg : "st\(.\)"`
-               makedev st$unit c $major $unit $tape
-               makedev nst$unit c $major `expr 128 + $unit` $tape
-               ;;
-       qic)
-               major=`Major tpqic02 12`
-               makedev rmt8       c $major   6 $tape
-               makedev rmt16      c $major   8 $tape
-               makedev tape-d     c $major 136 $tape
-               makedev tape-reset c $major 255 $tape
-               ;;
-       ftape)
-               major=`Major mt 27` || continue
-               for unit in 0 1 2 3
-               do
-                       makedev rft$unit c $major $unit $tape
-                       makedev nrft$unit c $major `expr $unit + 4` $tape
-               done
-               symlink ftape rft0
-               symlink nftape nrft0
-               ;;
-       scd[0-7])
-               major=`Major sr 11` || continue
-               unit=`expr $arg : "scd\(.\)"`
-               makedev scd$unit b $major $unit $cdrom
-               ;;
-       sonycd)
-               major=`Major cdu31a` || continue
-               makedev $arg b $major 0 $cdrom
-               ;;
-       mcd)
-               major=`Major mcd 23` || continue
-               makedev $arg b $major 0 $cdrom
-               ;;
-       cdu535)
-               makedev $arg b 24 0 $cdrom
-               ;;
-       lmscd)
-               makedev $arg b 24 0 $cdrom
-               ;;
-       sbpcd|sbpcd[123])
-               major=`Major $arg` || continue
-               base=`expr ${arg}0 : "sbpcd\(.\)"`
-               for minor in 0 1 2 3
-               do
-                       unit=`expr substr 0123456789abcdef \( $base \* 4 + $minor + 1 \) 1`
-                       makedev spbcd$unit b $major $minor $cdrom
-               done
-               [ $arg = sbpcd ] && symlink $arg ${arg}0
-               ;;
-       idecd)
-               major=`Major idecd` || continue
-               makedev $arg c $major 0 $cdrom
-               ;;
-       logiscan)
-               major=`Major logiscan` || continue
-               makedev $arg c $major 0 $scanner
-               ;;
-       m105scan)
-               major=`Major m105` || continue
-               makedev $arg c $major 0 $scanner
-               ;;
-       ac4096)
-               major=`Major ac4096` || continue
-               makedev $arg c $major 0 $scanner
-               ;;
-       audio)
-               major=`Major sound 14`
-               makedev mixer      c $major  0 $audio
-               makedev sequencer  c $major  1 $audio
-               makedev midi00     c $major  2 $audio
-               makedev dsp        c $major  3 $audio
-               makedev audio      c $major  4 $audio
-               makedev sndstat    c $major  6 $audio
-#              makedev sequencer2 c $major  8 $audio
-               makedev mixer1     c $major 16 $audio
-#              makedev patmgr0    c $major 17 $audio
-               makedev midi01     c $major 18 $audio
-               makedev dsp1       c $major 19 $audio
-               makedev audio1     c $major 20 $audio
-#              makedev patmgr1    c $major 33 $audio
-               makedev midi02     c $major 34 $audio
-               makedev midi03     c $major 50 $audio
-               ;;
-       pcaudio)
-               major=`Major pcsp` || continue
-               makedev pcmixer c $major 0 $audio
-               makedev pcsp    c $major 3 $audio
-               makedev pcaudio c $major 4 $audio
-               ;;
-       sg)
-               major=`Major sg 21`
-               for unit in a b c d e f g h
-               do
-                       minor=`expr abcdefgh : ".*$unit" - 1`
-                       makedev $arg$unit c $major $minor $scsi
-               done
-               ;;
-       fd)
-               # not really devices, we use the /proc filesystem
-               symlink fd     $procfs/self/fd
-               symlink stdin  fd/0
-               symlink stdout fd/1
-               symlink stderr fd/2
-               ;;
-       ibcs2)
-               major=`Major ibcs2` || continue
-               makedev socksys c $major 0 $ibcs2
-               symlink nfsd socksys
-               makedev spx     c $major 1 $ibcs2
-               symlink X0R null
-               ;;
-       apm)
-               major=`Major apm_bios` || continue
-               makedev $arg c $major 0 $system
-               ;;
-       dcf)
-               major=`Major dcf` || continue
-               makedev $arg c $major 0 $system
-               ;;
-       helloworld)
-               major=`Major hw` || continue
-               makedev helloworld c $major 0 $public
-               ;;
-       update)
-               if [ ! "$devices" ]
-               then
-                       echo "$0: don't appear to have any devices" >&2
-                       continue
-               fi
-               if [ "$opt_d" ]
-               then
-                       echo "$0: can't delete an update" >&2
-                       continue
-               fi
-               create=
-               delete=
-               devs="$devices"
-               if [ -f DEVICES ]
-               then
-                       exec 3<DEVICES
-                       while read device major <&3
-                       do
-                               eval now=\$major_$device
-                               if [ "$now" = "" ]
-                               then
-                                       delete="$delete `cvt $device`"
-                                       continue
-                               elif [ "$now" != $major ]
-                               then
-                                       create="$create "`cvt $device`
-                               fi
-                               devs=`expr "$devs" : "\(.*\) $device"``expr "$devs" : ".* $device\(.*\)"`
-                       done
-                       exec 3<&-
-               fi
-               create="$create "`cvt $devs`
-               $0 $opts -d $delete
-               $0 $opts $create
-               [ "$opt_n" ] && continue
-               for device in $devices
-               do
-                       if [ "`cvt $device`" ]
-                       then
-                           eval echo $device \$major_$device
-                       fi
-               done > DEVICES
-               ;;
-       *)
-               echo "$0: don't know how to make device \"$arg\"" >&2
-               ;;
-       esac
-done
-
-exit 0
diff --git a/sys-utils/MAKEDEV.8 b/sys-utils/MAKEDEV.8
deleted file mode 100644 (file)
index fe0c364..0000000
+++ /dev/null
@@ -1,147 +0,0 @@
-.\" MAKEDEV.8,v 1.1.1.1 1995/02/22 19:09:12 faith Exp
-.TH MAKEDEV 8 "14th August 1994" Linux "Linux Programmer's Manual"
-.SH NAME
-MAKEDEV \- create devices
-.SH SYNOPSIS
-.B "cd dev; ./MAKEDEV [ -n ] [ -v ] update"
-.br
-.BI "cd dev; ./MAKEDEV [ -n ] [ -v ]" "device"
-.SH DESCRIPTION
-.B MAKEDEV
-is a script that will create the devices in \fC/dev\fP used to interface
-with drivers in the kernel.
-.PP
-Note that programs giving the error \(*QENOENT: No such file or
-directory\(*U normally means that the device file is missing, whereas
-\(*QENODEV: No such device\(*U normally means the kernel does not have the
-driver configured or loaded.
-.SH OPTIONS
-.TP
-.B \-V
-Print out version (actually RCS version information) and exit.
-.TP
-.B \-n
-Do not actually update the devices, just print the actions that would be
-performed.
-.TP
-.B \-d
-Delete the devices.  The main use for this flag is by
-.I MAKEDEV
-itself.
-.TP
-.B \-v
-Be verbose.  Print out the actions as they are performed.  This is the
-same output as produced by
-.BR \-n .
-.SH CUSTOMISATION
-Since there is no standardisation in what names are used for system users
-and groups, it is possible that you may need to modify
-.B MAKEDEV
-to reflect your site's settings.  Near the top of the file is a mapping
-from device type to user, group and permissions (e.g. all CD-ROM devices
-are set from the \fC$cdrom\fP variable).  If you wish to change the
-defaults, this is the section to edit.
-.SH DEVICES
-.TP
-.B General Options
-.TP
-.B update
-This only works on kernels which have \fC/proc/interrupts\fP (introduced
-during 1.1.x).  This file is scanned to see what devices are currently
-configured into the kernel, and this is compared with the previous
-settings stored in the file called \fCDEVICES\fP.
-Devices which are new since then or have a different major number are
-created, and those which are no longer configured are deleted.
-.TP
-.B generic
-Create a generic subset of devices.
-.TP
-.B
-std
-Standard devices.
-.TP 
-.B local
-.TP
-.B Virtual Terminals
-.TP
-.B console
-Also known as tty0.
-.TP
-.B tty{0..63}
-Virtual consoles
-.TP
-.B Serial Devices
-.TP
-.I ttyS{0..63}
-serial ports and corresponding dialout device
-.TP
-.I cyclades
-Dial-in and dial-out devices for the cyclades intelligent I/O serial card.
-.TP
-.B Pseudo Terminals
-.TP
-.I pty[p-s]
-banks of of master and slave pseudo terminals
-.TP
-.B Parallel Ports
-.TP
-.I par[0-3] lp[0-3]
-parallel ports
-.TP
-.B Bus Mice
-.TP
-.I busmice
-The various bus mice devices.
-.TP
-.B Joystick Devices
-.TP
-.I js
-Joystick.  Creates \fCjs0\fP and \fCjs1\fP.
-.TP
-.B Disks Devices
-.TP
-.I fd[0-4]
-floppy disks
-.TP
-.I hd[a-d]
-AT hard disks (1st controller)
-.TP
-.I hd1[a-d]
-2nd AT controller hard disks
-.TP
-.I xd[a-d] 
-XT hard disks
-.TP
-.I sd[a-i]
-SCSI hard disks
-.TP
-.I loop
-Loopback disk devices
-.TP
-.B Tape Devices
-.TP
-.I st[0-7]
-SCSI tapes
-.TP
-.I qic
-QIC-80 tapes
-.TP
-.I ftape
-floppy driver tapes (QIC-117)
-.TP
-.B CDROM Devices
-.TP
-.I scd[0-7]
-SCSI CD players
-.TP
-.I sonycd
-Sony CDU-31A CD player
-.TP
-.I mcd
-Mitsumi CD player
-.TP
-.I cdu535
-Sony CDU-535 CD player
-.TP
-.I lmscd
-LMS/Philips CD player  (nee
\ No newline at end of file
index a584f16d13e7c3eff4a1657286134e749919e0dd..fc5afd4ebd30930428645fc3ed6ecbdeacbb4124 100644 (file)
@@ -1,6 +1,6 @@
 # Makefile -- Makefile for util-linux Linux utilities
 # Created: Sat Dec 26 20:09:40 1992
-# Revised: Sat Feb 11 17:52:09 1995 by faith@cs.unc.edu
+# Revised: Sat Oct  7 19:24:39 1995 by r.faith@ieee.org
 # Copyright 1992, 1993, 1994, 1995 Rickard E. Faith (faith@cs.unc.edu)
 #
 
@@ -10,46 +10,33 @@ include ../MCONFIG
 
 MAN1=          arch.1 readprofile.1
 
-MAN8=          MAKEDEV.8 chroot.8 clock.8 ctrlaltdel.8 dmesg.8 ipcrm.8 \
-               ipcs.8 kbdrate.8 lpcntl.8 ramsize.8 rdev.8 renice.8 \
+MAN8=          chroot.8 clock.8 ctrlaltdel.8 cytune.8 dmesg.8 \
+               ipcrm.8 ipcs.8 kbdrate.8 ramsize.8 rdev.8 renice.8 \
                rootflags.8 setserial.8 setsid.8 swapdev.8 sync.8 tunelp.8 \
-               update_state.8 vidmode.8
+               vidmode.8
 
 # Where to put binaries?
 # See the "install" rule for the links. . .
 
-DEV=            MAKEDEV
-
-SBIN=          clock kbdrate sln
+SBIN=          clock ctrlaltdel kbdrate sln
 
 BIN=            arch dmesg setserial sync
 
-USRSBIN=       chroot ctrlaltdel update_state
+USRSBIN=       chroot
 
-USRBIN=                ipcrm ipcs lpcntl rdev renice readprofile setsid tunelp
+USRBIN=                cytune ipcrm ipcs rdev renice readprofile setsid tunelp
 
 # Where to put datebase files?
 
 USRINFO=        ipc.info
 
-SCRIPTS=       reset update_state
-
 all: $(SBIN) $(BIN) $(USRSBIN) $(USRBIN)
 
 sln: sln.c
        $(CC) -static $(CFLAGS) $(LDFLAGS) $< -o $@
 
 sync: sync.S
-       /lib/cpp sync.S > sync.s
-       as -o sync.o sync.s
-       ld -s -N -e _main sync.o -o sync
-       -rm sync.s
-
-%.o: %.c
-       $(CC) -c $(CFLAGS) $< -o $@
-
-$(SCRIPTS):
-       cp $@.sh $@
+       $(CC) -nostdlib $(LDFLAGS) $< -o $@
 
 # Rules for everything else
 
@@ -60,25 +47,22 @@ ctrlaltdel: ctrlaltdel.o
 ipcrm: ipcrm.o
 ipcs: ipcs.o
 kbdrate: kbdrate.o
-lpcntl: lpcntl.o
 rdev: rdev.o
 renice: renice.o
 readprofile: readprofile.o
 setserial: setserial.o
 setsid: setsid.o
-update_state: update_state.sh
 
 install: all
-       $(INSTALLDIR) $(DEVDIR) $(SBINDIR) $(BINDIR) $(USRSBINDIR) $(USRBINDIR)
-       $(INSTALLBIN) $(DEV) $(DEVDIR)
+       $(INSTALLDIR) $(SBINDIR) $(BINDIR) $(USRSBINDIR) $(USRBINDIR)
        $(INSTALLBIN) $(SBIN) $(SBINDIR)
        $(INSTALLBIN) $(BIN) $(BINDIR)
        $(INSTALLBIN) $(USRSBIN) $(USRSBINDIR)
        $(INSTALLBIN) $(USRBIN) $(USRBINDIR)
-       (cd $(RDEVDIR); ln -sf rdev swapdev)
-       (cd $(RDEVDIR); ln -sf rdev ramsize)
-       (cd $(RDEVDIR); ln -sf rdev vidmode)
-       (cd $(RDEVDIR); ln -sf rdev rootflags)
+       (cd $(USRBINDIR); ln -sf rdev swapdev)
+       (cd $(USRBINDIR); ln -sf rdev ramsize)
+       (cd $(USRBINDIR); ln -sf rdev vidmode)
+       (cd $(USRBINDIR); ln -sf rdev rootflags)
        $(INSTALLDIR) $(MAN1DIR) $(MAN8DIR) $(INFODIR)
        $(INSTALLMAN) $(MAN1) $(MAN1DIR)
        $(INSTALLMAN) $(MAN8) $(MAN8DIR)
index 0cba832845b27ca85f147130ce391fb38d9c98d8..02652b2b665b800cb7296ce1a7cc56ae30d8e99d 100644 (file)
@@ -1,4 +1,4 @@
-README.MAKEDEV,v 1.1.1.1 1995/02/22 19:09:12 faith Exp
+$Id: README.MAKEDEV,v 2.2 1995/06/04 16:32:02 faith Exp $
 
 Here is the original comment taken from the MAKEDEV script.  One day,
 I'll do this properly.
@@ -17,6 +17,8 @@ If you are aware of any glaring omissions or errors, please let me know.
 Also, if you are a developer who wants your devices supported by MAKEDEV,
 let me know.
 
-Thanks to Ian Jackson for the original help and encouragement.
+Thanks go to many people.  Ian Jackson for the original help and
+encouragement, to Matthias Urlichs for plugging "MAKEDEV update", and
+to the many others that have bought errors and omissions to my attention.
 
        Nick Holloway <Nick.Holloway@alfie.demon.co.uk>  
index f4dd83ade0bbe7459c3fe167d8c49db2acd242dd..1f6139ae4412da858e1ebe522b1956d668f5dd50 100644 (file)
@@ -4,13 +4,13 @@
 .SH NAME
 clock \- manipulate the CMOS clock
 .SH SYNOPSIS
-.B "/etc/clock [ -u ] -r"
+.B "/sbin/clock [ -u ] -r"
 .br
-.B "/etc/clock [ -u ] -w"
+.B "/sbin/clock [ -u ] -w"
 .br
-.B "/etc/clock [ -u ] -s"
+.B "/sbin/clock [ -u ] -s"
 .br
-.B "/etc/clock [ -u ] -a"
+.B "/sbin/clock [ -u ] -a"
 .SH DESCRIPTION
 .B clock
 manipulates the CMOS clock in variaous ways, allowing it to be read or
index 488f37c072133840b2330f1bb2842447efa7c17a..026818ed4a13693adf6f54c96ac60ea73fab426c 100644 (file)
@@ -1,10 +1,10 @@
 .\" Copyright 1992, 1993 Rickard E. Faith (faith@cs.unc.edu)
 .\" May be distributed under the GNU General Public License
-.TH CTRLALTDEL 8 "25 October 1993" "Linux 0.99" "Linux Programmer's Manual"
+.TH CTRLALTDEL 8 "25 October 1993" "Linux 1.2" "Linux Programmer's Manual"
 .SH NAME
 ctrlaltdel \- set the function of the Ctrl-Alt-Del combination
 .SH SYNOPSIS
-.B "ctrlaltdel hard|soft"
+.BR "ctrlaltdel hard" " | " soft
 .SH DESCRIPTION
 Based on examination of the
 .I linux/kernel/sys.c
diff --git a/sys-utils/cytune.8 b/sys-utils/cytune.8
new file mode 100644 (file)
index 0000000..772915b
--- /dev/null
@@ -0,0 +1,181 @@
+.\" cytune.8 -- 
+.\" Created: Sat Mar  4 17:44:53 1995 by faith@cs.unc.edu
+.\" Update: Sat Mar  4 18:22:24 1995 by faith@cs.unc.edu
+.\" Update: Sun Mar  5 06:40:12 1995 by njs@scifi.emi.net
+.\" Copyright 1995 Rickard E. Faith (faith@cs.unc.edu)
+.\" 
+.\" Permission is granted to make and distribute verbatim copies of this
+.\" manual provided the copyright notice and this permission notice are
+.\" preserved on all copies.
+.\" 
+.\" Permission is granted to copy and distribute modified versions of this
+.\" manual under the conditions for verbatim copying, provided that the
+.\" entire resulting derived work is distributed under the terms of a
+.\" permission notice identical to this one
+.\" 
+.\" Since the Linux kernel and libraries are constantly changing, this
+.\" manual page may be incorrect or out-of-date.  The author(s) assume no
+.\" responsibility for errors or omissions, or for damages resulting from
+.\" the use of the information contained herein.  The author(s) may not
+.\" have taken the same level of care in the production of this manual,
+.\" which is licensed free of charge, as they might when working
+.\" professionally.
+.\" 
+.\" Formatted or processed versions of this manual, if unaccompanied by
+.\" the source, must acknowledge the copyright and authors of this work.
+.\" "
+.TH CYTUNE 8 " 4 Mar 1995" "" "Linux Programmer's Manual"
+.SH NAME
+cytune \- Tune Cyclades driver parameters
+.SH SYNOPSIS
+.BI "cytune [-q [-i " interval "]] ([-s " value "]|[-S " value "]) [-g|G] "
+.BI ([-t " timeout" ]|[-T " timeout" ]) " tty" " [" tty " ...]"
+.SH DESCRIPTION
+.B cytune
+queries and modifies the interruption threshold for the Cyclades driver.
+Each serial line on a Cyclades card has a 12-byte FIFO for input (and
+another 12-byte FIFO for output).  The "threshold" specifies how many input
+characters must be present in the FIFO before an interruption is raised.
+When a Cyclades tty is opened, this threshold is set to a default value
+based on baud rate:
+.sp
+.RS
+    Baud        Threshold
+.sp 
+50-4800            10
+.br
+9600                8
+.br
+19200               4
+.br
+38400               2
+.br
+57600-150000        1
+.RE
+.PP
+If the threshold is set too low, the large number of interruptions can load
+the machine and decrease overall system throughput.  If the threshold is set too high, the
+FIFO buffer can overflow, and characters will be lost.  Slower machines,
+however, may not be able to deal with the interrupt load, and will require
+that the threshold be adjusted upwards.
+.PP
+If the cyclades driver was compiled with 
+.B ENABLE_MONITORING
+defined, the cytune command can be used with the
+.B \-q
+option to report interrupts over the monitoring interval and 
+characters transferred over the monitoring interval.  It will also report 
+the state of the FIFO.  The maximum number of characters in the FIFO when 
+an interrupt occurred, the instantaneous count of characters in the FIFO,
+and how many characters are now in the FIFO are reported.  This output might 
+look like this:
+.sp
+.RS
+/dev/cubC0: 830 ints, 9130 chars; fifo: 11 threshold, 11 max, 11 now
+.br
+   166.259866 interrupts/second, 1828.858521 characters/second
+.RE
+.PP
+This output indicates that for this monitoring period, the interrupts were 
+always being handled within one character time, because
+.B max
+never rose above 
+.BR threshold .
+This is good, and you can probably run this way, provided that a large 
+number of samples come out this way.  You will lose characters if you 
+overrun the FIFO, as the Cyclades hardware does not seem to support 
+the RTS RS-232 signal line for hardware flow control from the 
+DCE to the DTE.
+.pp
+cytune will in query mode will produce a summary report when ended with 
+a SIGINT or when the threshold or timeout is changed.
+.PP
+There may be a responsiveness vs. throughput tradeoff.  The Cyclades card, 
+at the higher speeds, is capable of putting a very high interrupt load on the
+system.  This will reduce the amount of CPU time available for other tasks
+on your system.  However, the time it takes to respond to a single character
+may be increased if you increase the threshold.  This might be noticed by
+monitoring
+.BR ping (8)
+times on a SLIP link controlled by a Cyclades card.  If your SLIP link is
+generally used for interactive work such as
+.BR telnet (1),
+you may want to leave the threshold low, so that characters are responded
+to as quickly as possible.  If your SLIP link is generally used for file
+transfer, WWW, and the like, setting the FIFO to a high value is likely to
+reduce the load on your system while not significantly affecting
+throughput.  Alternatively, see the
+.B \-t
+or 
+.B \-T
+options to adjust the time that the cyclades waits before flushing its 
+buffer.  Units are 5ms.
+.PP
+If you are running a mouse on a Cyclades port, it is likely that you would
+want to maintain the threshold and timeout at a low value.
+.PP
+.SH OPTIONS
+.TP
+.BI \-s " value"
+Set the current threshold to
+.I value
+characters.  Note that if the
+.I tty
+is not being held open by another process, the threshold will be reset on
+the next open.  Only values between 1 and 12, inclusive, are permitted.
+.TP
+.BI \-t " value"
+Set the current flush timeout to
+.I value
+units.  Note that if the
+.I tty
+is not being held open by another process, the threshold will be reset on
+the next open.  Only values between 0 and 255, inclusive, are permitted.
+Setting
+.I value
+to zero forces the default, currently 0x20 (160ms), but soon to be 0x02
+(10ms).  Units are 5 ms.
+.TP
+.B \-g
+Get the current threshold and timeout.
+.TP
+.BI \-T " value"
+Set the default flush timeout to
+.I value
+units.  When the
+.I tty
+is next opened, this value will be used instead of the default.  If
+.I value
+is zero, then the the value will default to 0x20 (160ms), soon to be 0x02
+(10ms).
+.TP
+.B \-G
+Get the default threshold and flush timeout values.
+.TP
+.B \-q
+Gather statistics about the
+.IR tty .
+The results are only valid if the Cyclades driver has been compiled with
+.B ENABLE_MONITORING
+defined.  This is probably not the default.
+.TP
+.BI \-i " interval"
+Statistics will be gathered every
+.I interval
+seconds.
+.SH BUGS
+If you run two copies of cytune at the same time to report statistics 
+about the same port, the 'ints', 'chars', and 'max' value will be reset 
+and not reported 
+correctly.
+.BR cytune (8)
+should prevent this, but does not.
+.SH AUTHOR
+Nick Simicich (njs@scifi.emi.net), with modifications by Rik Faith
+(faith@cs.unc.edu)
+.SH FILES
+.I /dev/ttyC[0-8]
+.br
+.I /dev/cubC[0-8]
+.SH "SEE ALSO"
+.BR setserial (8)
diff --git a/sys-utils/cytune.c b/sys-utils/cytune.c
new file mode 100644 (file)
index 0000000..32a2700
--- /dev/null
@@ -0,0 +1,424 @@
+/* cytune.c -- Tune Cyclades driver
+ *
+ * Copyright 1995 Nick Simicich (njs@scifi.emi.net)
+ *
+ * Modifications by Rik Faith (faith@cs.unc.edu)
+ *
+ * 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 the Nick Simicich
+ * 4. Neither the name of the Nick Simicich nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NICK SIMICICH 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 NICK SIMICICH 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.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/serial.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/ioctl.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <linux/tty.h>
+#include <termios.h>
+#include <linux/tqueue.h>
+#include <linux/cyclades.h>
+#include <signal.h>
+
+#if 0
+#ifndef XMIT
+# include <linux/version.h>
+# if LINUX_VERSION_CODE > 66056
+#  define XMIT
+# endif
+#endif
+#endif
+                               /* Until it gets put in the kernel,
+                                  toggle by hand. */
+#undef XMIT
+
+struct cyclades_control {
+  struct cyclades_monitor c;
+  int cfile;
+  int maxmax;
+  double maxtran;
+  double maxxmit;
+  unsigned long threshold_value;
+  unsigned long timeout_value;
+};
+struct cyclades_control *cmon;
+int cmon_index;
+
+#define mvtime(tvpto, tvpfrom)  (((tvpto)->tv_sec = (tvpfrom)->tv_sec),(tvpto)->tv_usec = (tvpfrom)->tv_usec)
+
+
+inline double dtime(struct timeval * tvpnew, struct timeval * tvpold) {
+  double diff;
+  diff = (double)tvpnew->tv_sec - (double)tvpold->tv_sec;
+  diff += ((double)tvpnew->tv_usec - (double)tvpold->tv_usec)/1000000;
+  return diff;
+}
+
+static int global_argc, global_optind;
+static char ***global_argv;
+
+void summary(int signal) {
+  struct cyclades_control *cc;
+
+  int argc, optind;
+  char **argv;
+
+  int i,j;
+
+  argc = global_argc;
+  argv = *global_argv;
+  optind = global_optind;
+
+  if (signal > 0) {
+    for(i = optind; i < argc; i ++) {
+      j = i - optind;
+      cc = &cmon[cmon_index];
+      fprintf(stderr, "File %s, For threshold value %lu, Maximum characters "
+             "in fifo were %d,\nand the maximum transfer rate in "
+             "characters/second was %f\n", 
+             argv[i],
+             cc->threshold_value,
+             cc->maxmax,
+             cc->maxtran);
+    }
+    
+    exit(0);
+  }
+  cc = &cmon[cmon_index];
+  if (cc->threshold_value > 0 && signal != -1) {
+    fprintf(stderr, "File %s, For threshold value %lu and timrout value %lu,"
+           " Maximum characters "
+           "in fifo were %d,\nand the maximum transfer rate in "
+           "characters/second was %f\n", 
+           argv[cmon_index+optind],
+           cc->threshold_value,
+           cc->timeout_value,
+           cc->maxmax,
+           cc->maxtran);
+  }
+  cc->maxmax = 0;
+  cc->maxtran = 0.0;
+  cc->threshold_value = 0;
+  cc->timeout_value = 0;
+}
+
+static int query   = 0;
+static int interval = 1;
+
+static int set     = 0;
+static int set_val = -1;
+static int get     = 0;
+
+static int set_def     = 0;
+static int set_def_val = -1;
+static int get_def     = 0;
+
+static int set_time = 0;
+static int set_time_val = -1;
+
+static int set_def_time = 0;
+static int set_def_time_val = -1;
+
+
+int main(int argc, char *argv[]) {
+
+  struct timeval lasttime, thistime;
+  struct timezone tz = {0,DST_NONE};
+  double diff;
+  int errflg = 0;
+  int file;
+  int numfiles;
+  struct cyclades_monitor cywork;
+  
+  int i;
+  extern char *optarg;
+  extern int optind;
+  unsigned long threshold_value;
+  unsigned long timeout_value;
+  double xfer_rate;
+#ifdef XMIT
+  double xmit_rate;
+#endif
+  
+  global_argc = argc;          /* For signal routine. */
+  global_argv = &argv;         /* For signal routine. */
+
+  while (EOF != (i = getopt(argc, argv, 
+                           "qs:S:t:T:gGi:"))) {
+    switch (i) {
+    case 'q':
+      query = 1;
+      break;
+    case 'i':
+      interval = atoi(optarg);
+      if(interval <= 0) {
+       fprintf(stderr, "Invalid interval value: %s\n",optarg);
+       errflg ++;
+      }
+      break;
+    case 's':
+      ++set;
+      set_val = atoi(optarg);
+      if(set_val <= 0 || set_val > 12) {
+       fprintf(stderr, "Invalid set value: %s\n",optarg);
+       errflg ++;
+      }
+      break;
+    case 'S':
+       ++set_def;
+      set_def_val = atoi(optarg);
+      if(set_def_val < 0 || set_def_val > 12) {
+       fprintf(stderr, "Invalid default value: %s\n",optarg);
+       errflg ++;
+      }
+      break;
+    case 't':
+      ++set_time;
+      set_time_val = atoi(optarg);
+      if(set_time_val <= 0 || set_time_val > 255) {
+       fprintf(stderr, "Invalid set time value: %s\n",optarg);
+       errflg ++;
+      }
+      break;
+    case 'T':
+       ++set_def_time;
+      set_def_time_val = atoi(optarg);
+      if(set_def_time_val < 0 || set_def_time_val > 255) {
+       fprintf(stderr, "Invalid default time value: %s\n",optarg);
+       errflg ++;
+      }
+      break;
+    case 'g': ++get;     break;
+    case 'G': ++get_def; break;
+    default:
+      errflg ++;
+    }
+  }
+  numfiles = argc - optind;
+  if(errflg || (numfiles == 0)
+     || (!query && !set && !set_def && 
+        !get && !get_def && !set_time && !set_def_time) || 
+     (set && set_def) || (set_time && set_def_time) || 
+     (get && get_def)) {
+    fprintf(stderr, 
+           "Usage: %s [-q [-i interval]]"
+           " ([-s value]|[-S value]) ([-t value]|[-T value])"
+           " [-g|-G] file [file...]\n",
+           argv[0]);
+    exit(1);
+  }
+
+  global_optind = optind;      /* For signal routine. */
+
+  if (set || set_def) {
+    for(i = optind;i < argc;i ++) {
+      file = open(argv[i],O_RDONLY);
+      if(file == -1) {
+       fprintf(stderr, "Can't open %s: %s\n",argv[i],strerror(errno));
+       exit(1);
+      }
+      if(ioctl(file,
+              set ? CYSETTHRESH : CYSETDEFTHRESH,
+              set ? set_val : set_def_val)) {
+       fprintf(stderr, "Can't set %s to threshold %d: %s\n",
+               argv[i],set?set_val:set_def_val,strerror(errno));
+       exit(1);
+      }
+    }
+  }
+  if (set_time || set_def_time) {
+    for(i = optind;i < argc;i ++) {
+      file = open(argv[i],O_RDONLY);
+      if(file == -1) {
+       fprintf(stderr, "Can't open %s: %s\n",argv[i],strerror(errno));
+       exit(1);
+      }
+      if(ioctl(file,
+              set_time ? CYSETTIMEOUT : CYSETDEFTIMEOUT,
+              set_time ? set_time_val : set_def_time_val)) {
+       fprintf(stderr, "Can't set %s to time threshold %d: %s\n",
+               argv[i],set_time?set_time_val:set_def_time_val,strerror(errno));
+       exit(1);
+      }
+    }
+  }
+
+  if (get || get_def) {
+    for(i = optind;i < argc;i ++) {
+      file = open(argv[i],O_RDONLY);
+      if(file == -1) {
+       fprintf(stderr, "Can't open %s: %s\n",argv[i],strerror(errno));
+       exit(1);
+      }
+      if(ioctl(file, get ? CYGETTHRESH : CYGETDEFTHRESH, &threshold_value)) {
+       fprintf(stderr, "Can't get threshold for %s: %s\n",
+               argv[i],strerror(errno));
+       exit(1);
+      }
+      if(ioctl(file, get ? CYGETTIMEOUT : CYGETDEFTIMEOUT, &timeout_value)) {
+       fprintf(stderr, "Can't get timeout for %s: %s\n",
+               argv[i],strerror(errno));
+       exit(1);
+      }
+      printf("%s: %ld %s threshold and %ld %s timeout\n",
+            argv[i], threshold_value, 
+            get?"current":"default",
+            timeout_value,
+            get?"current":"default");
+    }
+  }
+
+  if(!query) return 0;         /* must have been something earlier */
+
+  /* query stuff after this line */
+  
+  cmon = (struct cyclades_control *) malloc(sizeof (struct cyclades_control)
+                                           * numfiles);
+  if(!cmon) {
+    perror("malloc failed");
+    exit(1);
+  }
+  if(signal(SIGINT, summary)||
+     signal(SIGQUIT, summary)||
+     signal(SIGTERM, summary)) {
+    perror("Can't set signal handler");
+    exit(1);
+  }
+  if(gettimeofday(&lasttime,&tz)) {
+    perror("gettimeofday failed");
+    exit(1);
+  }
+  for(i = optind; i < argc; i ++) {
+    cmon_index = i - optind;
+    cmon[cmon_index].cfile = open(argv[i], O_RDONLY);
+    if(-1 == cmon[cmon_index].cfile) {
+      fprintf(stderr, "Can't open %s: %s\n",argv[i],strerror(errno));
+      exit(1);
+    }
+    if(ioctl(cmon[cmon_index].cfile, CYGETMON, &cmon[cmon_index].c)) {
+      fprintf(stderr, "Can't issue CYGETMON on %s: %s\n",
+             argv[i],strerror(errno));
+      exit(1);
+    }
+    summary(-1);
+    if(ioctl(cmon[cmon_index].cfile, CYGETTHRESH, &threshold_value)) {
+      fprintf(stderr, "Can't get threshold for %s: %s\n",
+             argv[i],strerror(errno));
+      exit(1);
+    }
+    if(ioctl(cmon[cmon_index].cfile, CYGETTIMEOUT, &timeout_value)) {
+      fprintf(stderr, "Can't get timeout for %s: %s\n",
+             argv[i],strerror(errno));
+      exit(1);
+    }
+  }
+  while(1) {
+    sleep(interval);
+    
+    if(gettimeofday(&thistime,&tz)) {
+      perror("gettimeofday failed");
+      exit(1);
+    }
+    diff = dtime(&thistime, &lasttime);
+    mvtime(&lasttime, &thistime);
+
+    for(i = optind; i < argc; i ++) {
+      cmon_index = i - optind;
+      if(ioctl(cmon[cmon_index].cfile, CYGETMON, &cywork)) {
+       fprintf(stderr, "Can't issue CYGETMON on %s: %s\n",
+               argv[i],strerror(errno));
+       exit(1);
+      }
+      if(ioctl(cmon[cmon_index].cfile, CYGETTHRESH, &threshold_value)) {
+       fprintf(stderr, "Can't get threshold for %s: %s\n",
+               argv[i],strerror(errno));
+       exit(1);
+      }
+      if(ioctl(cmon[cmon_index].cfile, CYGETTIMEOUT, &timeout_value)) {
+       fprintf(stderr, "Can't get timeout for %s: %s\n",
+               argv[i],strerror(errno));
+       exit(1);
+      }
+
+      xfer_rate = cywork.char_count/diff;
+#ifdef XMIT
+      xmit_rate = cywork.send_count/diff;
+#endif
+
+      if(threshold_value != cmon[cmon_index].threshold_value ||
+        timeout_value != cmon[cmon_index].timeout_value) {
+       summary(-2);
+       /* Note that the summary must come before the setting of */
+       /* threshold_value */
+       cmon[cmon_index].threshold_value = threshold_value;      
+       cmon[cmon_index].timeout_value = timeout_value;  
+      } else {
+       /* Don't record this first cycle after change */
+       if(xfer_rate > cmon[cmon_index].maxtran) 
+         cmon[cmon_index].maxtran = xfer_rate;
+#ifdef XMIT
+       if(xmit_rate > cmon[cmon_index].maxxmit)
+          cmon[cmon_index].maxxmit = xmit_rate;
+#endif
+       if(cywork.char_max > cmon[cmon_index].maxmax) 
+         cmon[cmon_index].maxmax = cywork.char_max;
+      }
+
+#ifdef XMIT
+      printf("%s: %lu ints, %lu/%lu chars; "
+            "fifo: %lu thresh, %lu tmout, "
+            "%lu max, %lu now\n",
+            argv[i],
+            cywork.int_count,cywork.char_count,cywork.send_count,
+            threshold_value,timeout_value,
+            cywork.char_max,cywork.char_last);
+      printf("   %f int/sec; %f rec, %f send (char/sec)\n",
+            cywork.int_count/diff,
+            xfer_rate,
+            xmit_rate);
+#else
+      printf("%s: %lu ints, %lu chars; "
+            "fifo: %lu thresh, %lu tmout, "
+            "%lu max, %lu now\n",
+            argv[i],
+            cywork.int_count,cywork.char_count,
+            threshold_value,timeout_value,
+            cywork.char_max,cywork.char_last);
+      printf("   %f int/sec; %f rec (char/sec)\n",
+            cywork.int_count/diff,
+            xfer_rate);
+#endif
+      memcpy(&cmon[cmon_index].c, &cywork, sizeof (struct cyclades_monitor));
+    }
+  }
+
+  return 0;
+}
index 8e7f9c609c98f3a25d2b20da3240fc5759e6e19e..12df2261a9eb10f054357063957029a389bb0fad 100644 (file)
@@ -13,6 +13,7 @@ entry. */
 #include <pwd.h>
 #include <grp.h>
 #define __KERNEL__
+#include <linux/linkage.h>
 #include <sys/sem.h>
 #include <sys/msg.h>
 #include <sys/shm.h>
index 2fa8f5662510bdee5b1fbff8af558dea74551e76..5b7fd82b2b93eaeb160d6231e47a3fdcd049049c 100644 (file)
@@ -1,19 +1,22 @@
 /* File:
  *     sync.S
  * Compile:
- *     /lib/cpp sync.S > sync.s
- *     as -o sync.o sync.s
- *     ld -s -N -e _main sync.o -o sync
+ *     gcc -nostdlib sync.S -o sync
  * Author:
  *     Nick Holloway, with thanks to James Bonfield
+ *      Modified for ELF by Michael Shields
+ *      Rik Faith added __ASSEMBLY__ for gcc 2.5.8
  * Last Changed:
- *     September 1993.
+ *     1995-07-04
  */
-# include <sys/syscall.h>
+#include <sys/syscall.h>
+#ifndef __ASSEMBLY__
+#define __ASSEMBLY__
+#endif
+#include <linux/linkage.h>
 
         .text
-        .globl  _main
-_main:
+ENTRY(_start)
         movl    $(SYS_sync),%eax        /* sync () */
         int     $0x80
         movl    $(SYS_exit),%eax        /* exit ( 0 ) */
index 559118450bf5c49f99ddc176ccaba8afe3e1fe11..bff56762602e6e2e3ceef23d9e3b3d63c6fa98a1 100644 (file)
@@ -2,7 +2,7 @@
 .\" It may be distributed under the GNU Public License, version 2, or
 .\" any higher version.  See section COPYING of the GNU Public license
 .\" for conditions under which this file may be redistributed.
-.\" tunelp.8,v 1.1.1.1 1995/02/22 19:09:12 faith Exp
+.\" $Id: tunelp.8,v 1.5 1995/03/12 01:34:24 faith Exp $
 .TH tunelp 8 "26 August 1992" "Cohesive Systems" "Linux Programmer's Manual"
 .SH NAME
 tunelp \- set various parameters for the lp device
index 9005b172dc0b98c640a01fb119fc21d0a54061fc..a854b46b106883ebb780d41eec5dbf5326556202 100644 (file)
@@ -6,10 +6,13 @@
 *      for information on distribution conditions.                          *
 \****************************************************************************/
 
-/* tunelp.c,v 1.1.1.1 1995/02/22 19:09:12 faith Exp
- * tunelp.c,v
- * Revision 1.1.1.1  1995/02/22  19:09:12  faith
- * Imported sources
+/* $Id: tunelp.c,v 1.6 1995/06/04 01:47:11 faith Exp $
+ * $Log: tunelp.c,v $
+ * Revision 1.6  1995/06/04 01:47:11  faith
+ * Changes for util-linux-2.4
+ *
+ * Revision 1.5  1995/03/12  01:29:50  faith
+ * util-linux-2.1
  *
  * Revision 1.5  1995/01/13  10:33:43  johnsonm
  * Chris's changes for new ioctl numbers and backwards compatibility
@@ -195,7 +198,7 @@ int main (int argc, char ** argv) {
   }
 
   /* Allow for binaries compiled under a new kernel to work on the old ones */
-  if (LPGETIRQ >= 0x0600 && ioctl(fd, LPGETIRQ) < 0 && errno == EINVAL)
+  if (LPGETIRQ >= 0x0600 && ioctl(fd, LPGETIRQ, &irq) < 0 && errno == EINVAL)
     offset = 0x0600;   /* We don't understand the new ioctls */
 
   cmds = cmdst;
diff --git a/sys-utils/update_state.8 b/sys-utils/update_state.8
deleted file mode 100644 (file)
index 1013843..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-.\" Copyright 1994 Rickard E. Faith (faith@cs.unc.edu)
-.\" May be distributed under the GNU General Public License
-.\" "
-.TH update_state 8 "8 July 1994" "Linux 1.0" "Linux Programmer's Manual"
-.SH NAME
-update_state \- update system state
-.SH SYNOPSIS
-.BR update_state
-.SH DESCRIPTION
-.B update_state
-updates a bunch of system state.  It takes a long time to execute, and
-would be suitable for execution in a cron job.
-
-Currently,
-.B update_state
-performs the following functions: updates the locate database (in
-.IR /usr/lib/locate ), updates the whatis database (in
-.IR /usr/man ", " /usr/local/man ", " /usr/X386/man ", and "
-.IR /usr/interviews/man ),
-and updates the TeX ls-R cache file (in
-.IR /usr/lib/texmf ).
-.SH BUGS
-The script expects things to be where the FSSTND says they are.
-example, if you have
-.BR makewhatis (8)
-in
-.IR /usr/lib ,
-where it would be traditionally, then you lose, because it should be in
-.IR /usr/bin .
-.SH "SEE ALSO"
-.BR cron(8),
-.BR find(1),
-.BR locate(1),
-.SH AUTHOR
-Rik Faith (faith@cs.unc.edu)
diff --git a/sys-utils/update_state.sh b/sys-utils/update_state.sh
deleted file mode 100644 (file)
index f318d08..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-#!/bin/sh
-
-if test "`whoami`" != "root"; then
-    echo "This script must be executed by root"
-    exit 1
-fi
-
-if test -x /usr/lib/locate/updatedb; then
-    echo "WARNING: The /usr/lib/locate/find.codes file may violate the"
-    echo "         privacy of your users.  Please consider making it"
-    echo "         readable only by root."
-    echo ""
-    echo "Updating locate database"
-
-    /usr/lib/locate/updatedb
-fi
-
-if test -d /usr/lib/texmf; then
-    echo "Building ls-R cache file for TeX"
-    /bin/ls -LR /usr/lib/texmf > /tmp/ls-R.$$
-    if test -f /usr/lib/texmf/ls-R; then
-        cp /usr/lib/texmf/ls-R /usr/lib/texmf/ls-R.old
-    fi
-    mv /tmp/ls-R.$$ /usr/lib/texmf/ls-R
-fi
-
-if test -x /usr/bin/makewhatis; then
-    for i in /usr/man /usr/local/man /usr/X386/man /usr/interviews/man; do
-        if test -d $i; then
-            echo "Building whatis database in $i"
-            /usr/bin/makewhatis $i
-        fi
-    done
-fi
-
-if test -x /usr/bin/mandb; then
-    echo "Updating manpage database"
-    /usr/bin/mandb
-fi
-
-exit 0
index 36f3f0fb0c26e37a4b8bc5accaa38568b7dfda63..9892e3bd4a288406066a4fc7806221f6cb099e7f 100644 (file)
@@ -1,6 +1,6 @@
 # Makefile -- Makefile for syslogd utility for Linux
 # Created: Sat Oct  9 10:25:19 1993
-# Revised: Sat Feb 11 19:35:52 1995 by faith@cs.unc.edu
+# Revised: Fri Mar 10 21:21:51 1995 by faith@cs.unc.edu
 # Copyright 1992, 1993 Rickard E. Faith (faith@cs.unc.edu)
 #
 
@@ -16,9 +16,6 @@ ETC=       syslogd
 
 all: $(ETC)
 
-%.o: %.c
-       $(CC) -c $(CFLAGS) $< -o $@
-
 $(ETC):
        $(CC) $(LDFLAGS) $^ -o $@ $(LDLIBS)
 
index 93ce68b3689ab8a2c200d976fdcec08f97025b75..edb970ce175fafecf3dcd07eae361a1bbd5becec 100644 (file)
@@ -52,12 +52,17 @@ line applies, and an
 .Em action
 field which specifies the action to be taken if a message
 .Xr syslogd
-received matches the selection criteria.
+received matches the selection criteria.  There may not be
+.Em any
+spaces in the action field.
 The
 .Em selector
 field is separated from the
 .Em action
-field by one or more tab characters.
+field by one or more tab or space characters (this is a departure from the
+standard BSD way of doing things: both tabs
+.Em and
+spaces may be used to separate the selector from the action).
 .Pp
 The
 .Em Selector
index 69fb4255524bb050c21532157989a9656425a890..733e3a693c15ffa4c4d5753fb86ef242e8818f70 100644 (file)
  *    messages at a particular priority level, rather that all messages
  *    at or above a given priority level.
  *
- */
+ * Sat Jun 3 12:48:16 1995: Applied patches from
+ * Jochen.Hein@informatik.tu-clausthal.de to allow spaces *AND* tabs to
+ * separate the selector from the action. This means that no whitespace is
+ * allowed inside the selector.
+ * */
 
 #ifndef lint
 char copyright[] =
@@ -88,6 +92,8 @@ static char sccsid[] = "@(#)syslogd.c 5.45 (Berkeley) 3/2/91";
  * Rick <pclink@qus102.qld.npb.telecom.com.au>.  Anyone else
  * named Rick who wants to chip in?  :-)
  * More corrections by Neal Becker <neal@ctd.comsat.com> Sun Jan 16, 1994
+ * Patches from Jochen Hein (Jochen.Hein@informatik.tu-clausthal.de) to treat
+ *   spaces and tabs the same, applied Sat Mar 11 10:09:24 1995
  */
 
 #ifdef __linux__
@@ -145,7 +151,9 @@ char        *ConfFile = _PATH_LOGCONF;
 
 #ifdef __linux__
 #define CONFORM_TO_FSSTND
+#include "pathnames.h"
 #endif
+
 #ifdef CONFORM_TO_FSSTND
 char   *PidFile = "/var/run/syslog.pid";
 #else
@@ -451,7 +459,7 @@ main(argc, argv)
                                i = read(fd, line, MAXLINE);
                                if (i > 0) {
                                        line[i] = '\0';
-                                       printline(LocalHostName, line);
+                                       printmulti(LocalHostName, line, i);
                                }
                                else if (i == 0) {
                                        dprintf("stream closed (%d)\n", fd);
@@ -473,7 +481,7 @@ main(argc, argv)
                            (struct sockaddr *) &fromunix, &len);
                        if (i > 0) {
                                line[i] = '\0';
-                               printline(LocalHostName, line);
+                               printmulti(LocalHostName, line,i);
                        } else if (i < 0 && errno != EINTR)
                                logerror("recvfrom unix");
                }
@@ -489,7 +497,7 @@ main(argc, argv)
                                extern char *cvthname();
 
                                line[i] = '\0';
-                               printline(cvthname(&frominet), line);
+                               printmulti(cvthname(&frominet), line,i);
                        } else if (i < 0 && errno != EINTR)
                                logerror("recvfrom inet");
                }
@@ -506,6 +514,27 @@ usage()
        exit(1);
 }
 
+/*
+ * Break up null terminated lines for printline.
+ */
+
+printmulti(hname, msg, len)
+        char *hname;
+        char *msg;
+       int  len;
+{
+   int  i;
+   char *pt;
+
+   dprintf("strlen = %d, len = %d\n", strlen(msg), len );
+   for (pt = msg, i = 0; i < len; i++) {
+      if (msg[i] == '\0') {
+        printline(hname,pt);
+        pt = &msg[i+1];
+      }
+   }
+}
+
 /*
  * Take a raw input line, decode the message, and print the message
  * on the appropriate log files.
@@ -1167,19 +1196,19 @@ cfline(line, f)
                f->f_pmask[i] = 0;
 
        /* scan through the list of selectors */
-       for (p = line; *p && *p != '\t';) {
+       for (p = line; *p && *p != '\t' && *p != ' ';) {
 
                /* find the end of this facility name list */
-               for (q = p; *q && *q != '\t' && *q++ != '.'; )
+               for (q = p; *q && *q != '\t' && *q != ' ' && *q++ != '.'; )
                        continue;
 
                /* collect priority name */
-               for (bp = buf; *q && !index("\t,;", *q); )
+               for (bp = buf; *q && !index("\t,; ", *q); )
                        *bp++ = *q++;
                *bp = '\0';
 
                /* skip cruft */
-               while (index(", ;", *q))
+               while (index(",;", *q)) /* spaces no longer allowed! */
                        q++;
 
                /* decode priority name */
@@ -1201,8 +1230,8 @@ cfline(line, f)
                }
 
                /* scan facilities */
-               while (*p && !index("\t.;", *p)) {
-                       for (bp = buf; *p && !index("\t,;.", *p); )
+               while (*p && !index("\t.; ", *p)) {
+                       for (bp = buf; *p && !index("\t,;. ", *p); )
                                *bp++ = *p++;
                        *bp = '\0';
                        if (*buf == '*')
@@ -1233,7 +1262,7 @@ cfline(line, f)
        }
 
        /* skip to action part */
-       while (*p == '\t')
+       while (*p == '\t' || *p == ' ')
                p++;
 
        switch (*p)
diff --git a/syslogd/syslogd.c.orig b/syslogd/syslogd.c.orig
new file mode 100644 (file)
index 0000000..0124f6e
--- /dev/null
@@ -0,0 +1,1340 @@
+/*
+ * Copyright (c) 1983, 1988 Regents of the University of California.
+ * 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 the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS 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.
+ */
+
+#ifndef lint
+char copyright[] =
+"@(#) Copyright (c) 1983, 1988 Regents of the University of California.\n\
+ All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)syslogd.c  5.45 (Berkeley) 3/2/91";
+#endif /* not lint */
+
+/*
+ *  syslogd -- log system messages
+ *
+ * This program implements a system log. It takes a series of lines.
+ * Each line may have a priority, signified as "<n>" as
+ * the first characters of the line.  If this is
+ * not present, a default priority is used.
+ *
+ * To kill syslogd, send a signal 15 (terminate).  A signal 1 (hup) will
+ * cause it to reread its configuration file.
+ *
+ * Defined Constants:
+ *
+ * MAXLINE -- the maximimum line length that can be handled.
+ * DEFUPRI -- the default priority for user messages
+ * DEFSPRI -- the default priority for kernel messages
+ *
+ * Author: Eric Allman
+ * extensive changes by Ralph Campbell
+ * more extensive changes by Eric Allman (again)
+ *
+ * Modified, Sun Mar  7 15:21:13 1993, faith@cs.unc.edu for Linux:
+ *
+ * SUN_LEN_MISSING:      struct sockaddr does not have sun_len
+ * SYSLOG_STREAM:        syslog is implemented using stream sockets
+ * SYSLOG_INET:          support inet logging
+ * KLOG_STREAM:          kernel logging uses a stream device
+ * STATUS_BROKEN:        use "int status" instead of "union wait status"
+ * RE_INSTALL_SIGNAL:    signal() does *not* remain installed
+ * SYS_MSGBUF_H_MISSING: sys/msgbuf.h is missing
+ * FSYNC_MISSING:        fsync() is missing 
+ * KERNEL_NAME:          what the kernel is usually called
+ *
+ * Original Linux version by Rik Faith <faith@cs.unc.edu>
+ * with changes by Rick Sladkey <jrs@world.std.com> and
+ * Rick <pclink@qus102.qld.npb.telecom.com.au>.  Anyone else
+ * named Rick who wants to chip in?  :-)
+ */
+
+#ifdef __linux__
+#define SUN_LEN_MISSING
+#define SYSLOG_STREAM
+#define SYSLOG_INET
+#define KLOG_STREAM
+#undef  STATUS_BROKEN
+#define RE_INSTALL_SIGNAL
+#define SYS_MSGBUF_H_MISSING
+#undef  FSYNC_MISSING
+#define KERNEL_NAME    "linux"
+#endif
+
+#define        MAXLINE         1024            /* maximum line length */
+#define        MAXSVLINE       120             /* maximum saved line length */
+#define DEFUPRI                (LOG_USER|LOG_NOTICE)
+#define DEFSPRI                (LOG_KERN|LOG_CRIT)
+#define TIMERINTVL     30              /* interval for checking flush, mark */
+
+#include <sys/param.h>
+#include <sys/errno.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <sys/socket.h>
+#include <sys/file.h>
+#ifdef SYS_MSGBUF_H_MISSING
+#define MSG_BSIZE (MAXLINE*2)
+#else
+#include <sys/msgbuf.h>
+#endif
+#include <sys/uio.h>
+#include <sys/un.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <sys/signal.h>
+
+#include <netinet/in.h>
+#include <netdb.h>
+
+#include <utmp.h>
+#include <setjmp.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <string.h>
+#include <unistd.h>
+#include <paths.h>
+
+#define SYSLOG_NAMES
+#include <sys/syslog.h>
+
+char   *LogName = _PATH_LOG;
+char   *ConfFile = _PATH_LOGCONF;
+char   *PidFile = _PATH_LOGPID;
+char   ctty[] = _PATH_CONSOLE;
+
+#define FDMASK(fd)     (1 << (fd))
+
+#define        dprintf         if (Debug) printf
+
+#define MAXUNAMES      20      /* maximum number of user names */
+
+/*
+ * Flags to logmsg().
+ */
+
+#define IGN_CONS       0x001   /* don't print on console */
+#define SYNC_FILE      0x002   /* do fsync on file after printing */
+#define ADDDATE                0x004   /* add a date to the message */
+#define MARK           0x008   /* this message is a mark */
+
+/*
+ * This structure represents the files that will have log
+ * copies printed.
+ */
+
+struct filed {
+       struct  filed *f_next;          /* next in linked list */
+       short   f_type;                 /* entry type, see below */
+       short   f_file;                 /* file descriptor */
+       time_t  f_time;                 /* time this was last written */
+       u_char  f_pmask[LOG_NFACILITIES+1];     /* priority mask */
+       union {
+               char    f_uname[MAXUNAMES][UT_NAMESIZE+1];
+               struct {
+                       char    f_hname[MAXHOSTNAMELEN+1];
+                       struct sockaddr_in      f_addr;
+               } f_forw;               /* forwarding address */
+               char    f_fname[MAXPATHLEN];
+       } f_un;
+       char    f_prevline[MAXSVLINE];          /* last message logged */
+       char    f_lasttime[16];                 /* time of last occurrence */
+       char    f_prevhost[MAXHOSTNAMELEN+1];   /* host from which recd. */
+       int     f_prevpri;                      /* pri of f_prevline */
+       int     f_prevlen;                      /* length of f_prevline */
+       int     f_prevcount;                    /* repetition cnt of prevline */
+       int     f_repeatcount;                  /* number of "repeated" msgs */
+};
+
+/*
+ * Intervals at which we flush out "message repeated" messages,
+ * in seconds after previous message is logged.  After each flush,
+ * we move to the next interval until we reach the largest.
+ */
+int    repeatinterval[] = { 30, 120, 600 };    /* # of secs before flush */
+#define        MAXREPEAT ((sizeof(repeatinterval) / sizeof(repeatinterval[0])) - 1)
+#define        REPEATTIME(f)   ((f)->f_time + repeatinterval[(f)->f_repeatcount])
+#define        BACKOFF(f)      { if (++(f)->f_repeatcount > MAXREPEAT) \
+                                (f)->f_repeatcount = MAXREPEAT; \
+                       }
+
+/* values for f_type */
+#define F_UNUSED       0               /* unused entry */
+#define F_FILE         1               /* regular file */
+#define F_TTY          2               /* terminal */
+#define F_CONSOLE      3               /* console terminal */
+#define F_FORW         4               /* remote machine */
+#define F_USERS                5               /* list of users */
+#define F_WALL         6               /* everyone logged on */
+
+char   *TypeNames[7] = {
+       "UNUSED",       "FILE",         "TTY",          "CONSOLE",
+       "FORW",         "USERS",        "WALL"
+};
+
+struct filed *Files;
+struct filed consfile;
+
+int    Debug;                  /* debug flag */
+char   LocalHostName[MAXHOSTNAMELEN+1];        /* our hostname */
+char   *LocalDomain;           /* our local domain name */
+int    InetInuse = 0;          /* non-zero if INET sockets are being used */
+#ifdef SYSLOG_INET
+int    finet;                  /* Internet datagram socket */
+#endif /* SYSLOG_INET */
+int    LogPort;                /* port number for INET connections */
+int    Initialized = 0;        /* set when we have initialized ourselves */
+int    MarkInterval = 20 * 60; /* interval between marks in seconds */
+int    MarkSeq = 0;            /* mark sequence number */
+
+extern int errno;
+extern char *ctime(), *index(), *calloc();
+
+main(argc, argv)
+       int argc;
+       char **argv;
+{
+       register int i;
+       register char *p;
+       int funix, fklog, len;
+       struct sockaddr_un sunx, fromunix;
+       struct sockaddr_in sin, frominet;
+       FILE *fp;
+       int ch;
+       char line[MSG_BSIZE + 1];
+       extern int optind;
+       extern char *optarg;
+       void die(), domark(), init(), reapchild();
+#ifdef SYSLOG_STREAM
+       fd_set unixm;
+       int fd;
+#endif /* SYSLOG_STREAM */
+
+       while ((ch = getopt(argc, argv, "df:m:p:")) != EOF)
+               switch((char)ch) {
+               case 'd':               /* debug */
+                       Debug++;
+                       break;
+               case 'f':               /* configuration file */
+                       ConfFile = optarg;
+                       break;
+               case 'm':               /* mark interval */
+                       MarkInterval = atoi(optarg) * 60;
+                       break;
+               case 'p':               /* path */
+                       LogName = optarg;
+                       break;
+               case '?':
+               default:
+                       usage();
+               }
+       if (argc -= optind)
+               usage();
+
+       if (!Debug)
+               daemon(0, 0);
+       else
+               setlinebuf(stdout);
+
+       consfile.f_type = F_CONSOLE;
+       (void) strcpy(consfile.f_un.f_fname, ctty);
+       (void) gethostname(LocalHostName, sizeof LocalHostName);
+       if (p = index(LocalHostName, '.')) {
+               *p++ = '\0';
+               LocalDomain = p;
+       }
+       else
+               LocalDomain = "";
+       (void) signal(SIGTERM, die);
+       (void) signal(SIGINT, Debug ? die : SIG_IGN);
+       (void) signal(SIGQUIT, Debug ? die : SIG_IGN);
+       (void) signal(SIGCHLD, reapchild);
+       (void) signal(SIGALRM, domark);
+       (void) alarm(TIMERINTVL);
+       (void) unlink(LogName);
+
+       bzero((char *)&sunx, sizeof(sunx));
+       sunx.sun_family = AF_UNIX;
+       (void) strncpy(sunx.sun_path, LogName, sizeof sunx.sun_path);
+#ifdef SYSLOG_STREAM
+       funix = socket(AF_UNIX, SOCK_STREAM, 0);
+       if (funix < 0 || bind(funix, (struct sockaddr *) &sunx,
+           sizeof(sunx)) < 0 || listen(funix, 5) < 0 ||
+#else /* !SYSLOG_STREAM */
+       funix = socket(AF_UNIX, SOCK_DGRAM, 0);
+       if (funix < 0 || bind(funix, (struct sockaddr *) &sunx,
+           sizeof(sunx.sun_family)+sizeof(sunx.sun_len)+
+           strlen(sunx.sun_path)) < 0 ||
+#endif /* !SYSLOG_STREAM */
+           chmod(LogName, 0666) < 0) {
+               (void) sprintf(line, "cannot create %s", LogName);
+               logerror(line);
+               dprintf("cannot create %s (%d)\n", LogName, errno);
+               die(0);
+       }
+#ifdef SYSLOG_INET
+       finet = socket(AF_INET, SOCK_DGRAM, 0);
+       if (finet >= 0) {
+               struct servent *sp;
+
+               sp = getservbyname("syslog", "udp");
+               if (sp == NULL) {
+                       errno = 0;
+                       logerror("syslog/udp: unknown service");
+               }
+               else {
+                       bzero((char *) &sin, sizeof(sin));
+                       sin.sin_family = AF_INET;
+                       sin.sin_port = LogPort = sp->s_port;
+                       if (bind(finet, (struct sockaddr *) &sin,
+                                sizeof(sin)) < 0)
+                               logerror("bind");
+                       else {
+                               finet = -1;
+                               InetInuse = 1;
+                       }
+               }
+       }
+#endif /* SYSLOG_INET */
+       if ((fklog = open(_PATH_KLOG, O_RDONLY, 0)) < 0)
+               dprintf("can't open %s (%d)\n", _PATH_KLOG, errno);
+
+       /* tuck my process id away */
+       fp = fopen(PidFile, "w");
+       if (fp != NULL) {
+               fprintf(fp, "%d\n", getpid());
+               (void) fclose(fp);
+       }
+
+       dprintf("off & running....\n");
+
+       init();
+       (void) signal(SIGHUP, init);
+#ifdef SYSLOG_STREAM
+       FD_ZERO(&unixm);
+#endif /* SYSLOG_STREAM */
+
+       for (;;) {
+               int nfds;
+               fd_set readfds;
+
+#ifdef SYSLOG_STREAM
+               readfds = unixm;
+#else /* !SYSLOG_STREAM */
+               FD_ZERO(&readfds);
+#endif /* !SYSLOG_STREAM */
+               if (funix >= 0)
+                       FD_SET(funix, &readfds);
+               if (fklog >= 0)
+                       FD_SET(fklog, &readfds);
+#ifdef SYSLOG_INET
+               if (finet >= 0)
+                       FD_SET(finet, &readfds);
+#endif /* SYSLOG_INET */
+
+               errno = 0;
+               dprintf("readfds = %#x\n", *((long *)&readfds));
+               nfds = select(FD_SETSIZE, &readfds, (fd_set *) NULL,
+                   (fd_set *) NULL, (struct timeval *) NULL);
+               if (nfds == 0)
+                       continue;
+               if (nfds < 0) {
+                       if (errno != EINTR)
+                               logerror("select");
+                       continue;
+               }
+               dprintf("got a message (%d, %#x)\n", nfds, *((long *)&readfds));
+
+#ifdef KLOG_STREAM
+               if (FD_ISSET(fklog, &readfds)) {
+                       nfds--;
+                       for (;;) {
+                               i = klogread(fklog, line, sizeof(line) - 1);
+                               if (i > 0) {
+                                       line[i] = '\0';
+                                       printsys(line);
+                               }
+                               else {
+                                       if (i < 0 && errno != EINTR) {
+                                               logerror("klog");
+                                               fklog = -1;
+                                       }
+                                       break;
+                               }
+                       }
+               }
+#else /* !KLOG_STREAM */
+               if (FD_ISSET(fklog, &readfds)) {
+                       nfds--;
+                       i = read(fklog, line, sizeof(line) - 1);
+                       if (i > 0) {
+                               line[i] = '\0';
+                               printsys(line);
+                       } else if (i < 0 && errno != EINTR) {
+                               logerror("klog");
+                               fklog = -1;
+                       }
+               }
+#endif /* !KLOG_STREAM */
+
+#ifdef SYSLOG_STREAM
+                /* Accept a new unix connection. */
+                if (FD_ISSET(funix, &readfds)) {
+                       nfds--;
+                       len = sizeof fromunix;
+                       if ((fd = accept(funix, (struct sockaddr *) &fromunix,
+                                        &len)) >= 0) {
+                               FD_SET(fd, &unixm);
+                               dprintf("new stream connect (%d)\n", fd);
+                               FD_SET(fd, &readfds);
+                               nfds++;
+                       }
+                }
+               /* Recv from existing connections. */
+               for (fd = 0; nfds > 0 && fd < FD_SETSIZE; fd++) {
+                       if (FD_ISSET(fd, &unixm) && FD_ISSET(fd, &readfds)) {
+                               nfds--;
+                               dprintf("message from stream (%d)\n", fd);
+                               i = read(fd, line, MAXLINE);
+                               if (i > 0) {
+                                       line[i] = '\0';
+                                       printline(LocalHostName, line);
+                               }
+                               else if (i == 0) {
+                                       dprintf("stream closed (%d)\n", fd);
+                                       close(fd);
+                                       FD_CLR(fd, &unixm);
+                               }
+                               else if (i < 0 && errno != EINTR) {
+                                       logerror("recv stream");
+                                       close(fd);
+                                       FD_CLR(fd, &unixm);
+                               }
+                       }
+               }
+#else /* !SYSLOG_STREAM */
+               if (FD_ISSET(funix, &readfds)) {
+                       nfds--;
+                       len = sizeof fromunix;
+                       i = recvfrom(funix, line, MAXLINE, 0,
+                           (struct sockaddr *) &fromunix, &len);
+                       if (i > 0) {
+                               line[i] = '\0';
+                               printline(LocalHostName, line);
+                       } else if (i < 0 && errno != EINTR)
+                               logerror("recvfrom unix");
+               }
+#endif /* !SYSLOG_STREAM */
+
+#ifdef SYSLOG_INET
+               if (FD_ISSET(finet, &readfds)) {
+                       nfds--;
+                       len = sizeof frominet;
+                       i = recvfrom(finet, line, MAXLINE, 0,
+                           (struct sockaddr *) &frominet, &len);
+                       if (i > 0) {
+                               extern char *cvthname();
+
+                               line[i] = '\0';
+                               printline(cvthname(&frominet), line);
+                       } else if (i < 0 && errno != EINTR)
+                               logerror("recvfrom inet");
+               }
+#endif /* SYSLOG_INET */
+               if (nfds != 0)
+                       logerror("loose cannon");
+       }
+}
+
+usage()
+{
+       (void) fprintf(stderr,
+           "usage: syslogd [-f conffile] [-m markinterval] [-p logpath]\n");
+       exit(1);
+}
+
+/*
+ * Take a raw input line, decode the message, and print the message
+ * on the appropriate log files.
+ */
+
+printline(hname, msg)
+       char *hname;
+       char *msg;
+{
+       register char *p, *q;
+       register int c;
+       char line[MAXLINE + 1];
+       int pri;
+
+       /* test for special codes */
+       pri = DEFUPRI;
+       p = msg;
+       if (*p == '<') {
+               pri = 0;
+               while (isdigit(*++p))
+                       pri = 10 * pri + (*p - '0');
+               if (*p == '>')
+                       ++p;
+       }
+       if (pri &~ (LOG_FACMASK|LOG_PRIMASK))
+               pri = DEFUPRI;
+
+       /* don't allow users to log kernel messages */
+       if (LOG_FAC(pri) == LOG_KERN)
+               pri = LOG_MAKEPRI(LOG_USER, LOG_PRI(pri));
+
+       q = line;
+
+       while ((c = *p++ & 0177) != '\0' &&
+           q < &line[sizeof(line) - 1])
+               if (iscntrl(c)) {
+                       if (c == '\n')
+                               *q++ = ' ';
+                       else if (c == '\r')
+                               *q++ = ' ';
+                       else if (c == '\t')
+                               *q++ = '\t';
+                       else {
+                               *q++ = '^';
+                               *q++ = c ^ 0100;
+                       }
+               }
+               else
+                       *q++ = c;
+       *q = '\0';
+
+       logmsg(pri, line, hname, 0);
+}
+
+/*
+ * Take a raw input line from /dev/klog, split and format similar to syslog().
+ */
+
+printsys(msg)
+       char *msg;
+{
+       register char *p, *q;
+       register int c;
+       char line[MAXLINE + 1];
+       int pri, flags;
+       char *lp;
+
+#ifdef KERNEL_NAME
+       (void) sprintf(line, "%s: ", KERNEL_NAME);
+#else /* !KERNEL_NAME */
+       (void) strcpy(line, "vmunix: ");
+#endif /* !KERNEL_NAME */
+
+       lp = line + strlen(line);
+       for (p = msg; *p != '\0'; ) {
+               flags = SYNC_FILE | ADDDATE;    /* fsync file after write */
+               pri = DEFSPRI;
+               if (*p == '<') {
+                       pri = 0;
+                       while (isdigit(*++p))
+                               pri = 10 * pri + (*p - '0');
+                       if (*p == '>')
+                               ++p;
+               } else {
+                       /* kernel printf's come out on console */
+                       flags |= IGN_CONS;
+               }
+               if (pri &~ (LOG_FACMASK|LOG_PRIMASK))
+                       pri = DEFSPRI;
+               q = lp;
+               while (*p != '\0' && (c = *p++) != '\n' &&
+                   q < &line[MAXLINE])
+                       if (iscntrl(c)) {
+                               if (c == '\n')
+                                       *q++ = ' ';
+                               else if (c == '\r')
+                                       *q++ = ' ';
+                               else if (c == '\t')
+                                       *q++ = '\t';
+                               else {
+                                       *q++ = '^';
+                                       *q++ = c ^ 0100;
+                               }
+                       }
+                       else
+                               *q++ = c;
+               *q = '\0';
+               logmsg(pri, line, LocalHostName, flags);
+       }
+}
+
+time_t now;
+
+/*
+ * Log a message to the appropriate log files, users, etc. based on
+ * the priority.
+ */
+
+logmsg(pri, msg, from, flags)
+       int pri;
+       char *msg, *from;
+       int flags;
+{
+       register struct filed *f;
+       int fac, prilev;
+       int omask, msglen;
+       char *timestamp;
+       time_t time();
+
+       dprintf("logmsg: pri %o, flags %x, from %s, msg %s\n",
+           pri, flags, from, msg);
+
+       omask = sigblock(sigmask(SIGHUP)|sigmask(SIGALRM));
+
+       /*
+        * Check to see if msg looks non-standard.
+        */
+       msglen = strlen(msg);
+       if (msglen < 16 || msg[3] != ' ' || msg[6] != ' ' ||
+           msg[9] != ':' || msg[12] != ':' || msg[15] != ' ')
+               flags |= ADDDATE;
+
+       (void) time(&now);
+       if (flags & ADDDATE)
+               timestamp = ctime(&now) + 4;
+       else {
+               timestamp = msg;
+               msg += 16;
+               msglen -= 16;
+       }
+
+       /* extract facility and priority level */
+       if (flags & MARK)
+               fac = LOG_NFACILITIES;
+       else
+               fac = LOG_FAC(pri);
+       prilev = LOG_PRI(pri);
+
+       /* log the message to the particular outputs */
+       if (!Initialized) {
+               f = &consfile;
+#ifdef O_NOCTTY
+               f->f_file = open(ctty, O_WRONLY|O_NOCTTY, 0);
+#else /* !O_NOCTTY */
+               f->f_file = open(ctty, O_WRONLY, 0);
+#endif /* !O_NOCTTY */
+
+               if (f->f_file >= 0) {
+                       fprintlog(f, flags, msg);
+                       (void) close(f->f_file);
+               }
+               (void) sigsetmask(omask);
+               return;
+       }
+       for (f = Files; f; f = f->f_next) {
+               /* skip messages that are incorrect priority */
+               if (f->f_pmask[fac] < prilev ||
+                   f->f_pmask[fac] == INTERNAL_NOPRI)
+                       continue;
+
+               if (f->f_type == F_CONSOLE && (flags & IGN_CONS))
+                       continue;
+
+               /* don't output marks to recently written files */
+               if ((flags & MARK) && (now - f->f_time) < MarkInterval / 2)
+                       continue;
+
+               /*
+                * suppress duplicate lines to this file
+                */
+               if ((flags & MARK) == 0 && msglen == f->f_prevlen &&
+                   !strcmp(msg, f->f_prevline) &&
+                   !strcmp(from, f->f_prevhost)) {
+                       (void) strncpy(f->f_lasttime, timestamp, 15);
+                       f->f_prevcount++;
+                       dprintf("msg repeated %d times, %ld sec of %d\n",
+                           f->f_prevcount, now - f->f_time,
+                           repeatinterval[f->f_repeatcount]);
+                       /*
+                        * If domark would have logged this by now,
+                        * flush it now (so we don't hold isolated messages),
+                        * but back off so we'll flush less often
+                        * in the future.
+                        */
+                       if (now > REPEATTIME(f)) {
+                               fprintlog(f, flags, (char *)NULL);
+                               BACKOFF(f);
+                       }
+               } else {
+                       /* new line, save it */
+                       if (f->f_prevcount)
+                               fprintlog(f, 0, (char *)NULL);
+                       f->f_repeatcount = 0;
+                       (void) strncpy(f->f_lasttime, timestamp, 15);
+                       (void) strncpy(f->f_prevhost, from,
+                                       sizeof(f->f_prevhost));
+                       if (msglen < MAXSVLINE) {
+                               f->f_prevlen = msglen;
+                               f->f_prevpri = pri;
+                               (void) strcpy(f->f_prevline, msg);
+                               fprintlog(f, flags, (char *)NULL);
+                       } else {
+                               f->f_prevline[0] = 0;
+                               f->f_prevlen = 0;
+                               fprintlog(f, flags, msg);
+                       }
+               }
+       }
+       (void) sigsetmask(omask);
+}
+
+fprintlog(f, flags, msg)
+       register struct filed *f;
+       int flags;
+       char *msg;
+{
+       struct iovec iov[6];
+       register struct iovec *v;
+       register int l;
+       char line[MAXLINE + 1], repbuf[80], greetings[200];
+
+       v = iov;
+       if (f->f_type == F_WALL) {
+               v->iov_base = greetings;
+               v->iov_len = sprintf(greetings,
+                   "\r\n\7Message from syslogd@%s at %.24s ...\r\n",
+                   f->f_prevhost, ctime(&now));
+               v++;
+               v->iov_base = "";
+               v->iov_len = 0;
+               v++;
+       } else {
+               v->iov_base = f->f_lasttime;
+               v->iov_len = 15;
+               v++;
+               v->iov_base = " ";
+               v->iov_len = 1;
+               v++;
+       }
+       v->iov_base = f->f_prevhost;
+       v->iov_len = strlen(v->iov_base);
+       v++;
+       v->iov_base = " ";
+       v->iov_len = 1;
+       v++;
+
+       if (msg) {
+               v->iov_base = msg;
+               v->iov_len = strlen(msg);
+       } else if (f->f_prevcount > 1) {
+               v->iov_base = repbuf;
+               v->iov_len = sprintf(repbuf, "last message repeated %d times",
+                   f->f_prevcount);
+       } else {
+               v->iov_base = f->f_prevline;
+               v->iov_len = f->f_prevlen;
+       }
+       v++;
+
+       dprintf("Logging to %s", TypeNames[f->f_type]);
+       f->f_time = now;
+
+       switch (f->f_type) {
+       case F_UNUSED:
+               dprintf("\n");
+               break;
+
+       case F_FORW:
+               dprintf(" %s\n", f->f_un.f_forw.f_hname);
+               l = sprintf(line, "<%d>%.15s %s", f->f_prevpri,
+                   iov[0].iov_base, iov[4].iov_base);
+               if (l > MAXLINE)
+                       l = MAXLINE;
+               if (sendto(finet, line, l, 0,
+                   (struct sockaddr *)&f->f_un.f_forw.f_addr,
+                   sizeof f->f_un.f_forw.f_addr) != l) {
+                       int e = errno;
+                       (void) close(f->f_file);
+                       f->f_type = F_UNUSED;
+                       errno = e;
+                       logerror("sendto");
+               }
+               break;
+
+       case F_CONSOLE:
+               if (flags & IGN_CONS) {
+                       dprintf(" (ignored)\n");
+                       break;
+               }
+               /* FALLTHROUGH */
+
+       case F_TTY:
+       case F_FILE:
+               dprintf(" %s\n", f->f_un.f_fname);
+               if (f->f_type != F_FILE) {
+                       v->iov_base = "\r\n";
+                       v->iov_len = 2;
+               } else {
+                       v->iov_base = "\n";
+                       v->iov_len = 1;
+               }
+       again:
+               if (writev(f->f_file, iov, 6) < 0) {
+                       int e = errno;
+                       (void) close(f->f_file);
+                       /*
+                        * Check for errors on TTY's due to loss of tty
+                        */
+                       if ((e == EIO || e == EBADF) && f->f_type != F_FILE) {
+                               f->f_file = open(f->f_un.f_fname,
+                                   O_WRONLY|O_APPEND, 0);
+                               if (f->f_file < 0) {
+                                       f->f_type = F_UNUSED;
+                                       logerror(f->f_un.f_fname);
+                               } else
+                                       goto again;
+                       } else {
+                               f->f_type = F_UNUSED;
+                               errno = e;
+                               logerror(f->f_un.f_fname);
+                       }
+               }
+#ifdef FSYNC_MISSING
+               else if (flags & SYNC_FILE)
+                       (void) sync();
+#else
+               else if (flags & SYNC_FILE)
+                       (void) fsync(f->f_file);
+#endif
+               break;
+
+       case F_USERS:
+       case F_WALL:
+               dprintf("\n");
+               v->iov_base = "\r\n";
+               v->iov_len = 2;
+               wallmsg(f, iov);
+               break;
+       }
+       f->f_prevcount = 0;
+}
+
+/*
+ *  WALLMSG -- Write a message to the world at large
+ *
+ *     Write the specified message to either the entire
+ *     world, or a list of approved users.
+ */
+
+wallmsg(f, iov)
+       register struct filed *f;
+       struct iovec *iov;
+{
+       static int reenter;                     /* avoid calling ourselves */
+       register FILE *uf;
+       register int i;
+       struct utmp ut;
+       char *p, *ttymsg();
+
+       if (reenter++)
+               return;
+       if ((uf = fopen(_PATH_UTMP, "r")) == NULL) {
+               logerror(_PATH_UTMP);
+               reenter = 0;
+               return;
+       }
+       /* NOSTRICT */
+       while (fread((char *) &ut, sizeof ut, 1, uf) == 1) {
+               if (ut.ut_name[0] == '\0')
+                       continue;
+#ifdef USER_PROCESS
+               if (ut.ut_type != USER_PROCESS)
+                       continue;
+#endif
+               if (f->f_type == F_WALL) {
+                       if (p = ttymsg(iov, 6, ut.ut_line, 1)) {
+                               errno = 0;      /* already in msg */
+                               logerror(p);
+                       }
+                       continue;
+               }
+               /* should we send the message to this user? */
+               for (i = 0; i < MAXUNAMES; i++) {
+                       if (!f->f_un.f_uname[i][0])
+                               break;
+                       if (!strncmp(f->f_un.f_uname[i], ut.ut_name,
+                           UT_NAMESIZE)) {
+                               if (p = ttymsg(iov, 6, ut.ut_line, 1)) {
+                                       errno = 0;      /* already in msg */
+                                       logerror(p);
+                               }
+                               break;
+                       }
+               }
+       }
+       (void) fclose(uf);
+       reenter = 0;
+}
+
+void
+reapchild()
+{
+#ifdef STATUS_BROKEN
+       int status;
+#else
+       union wait status;
+#endif
+
+       while (wait3((int *)&status, WNOHANG, (struct rusage *) NULL) > 0)
+               ;
+}
+
+/*
+ * Return a printable representation of a host address.
+ */
+char *
+cvthname(f)
+       struct sockaddr_in *f;
+{
+       struct hostent *hp;
+       register char *p;
+       extern char *inet_ntoa();
+
+       dprintf("cvthname(%s)\n", inet_ntoa(f->sin_addr));
+
+       if (f->sin_family != AF_INET) {
+               dprintf("Malformed from address\n");
+               return ("???");
+       }
+       hp = gethostbyaddr((char *)&f->sin_addr,
+           sizeof(struct in_addr), f->sin_family);
+       if (hp == 0) {
+               dprintf("Host name for your address (%s) unknown\n",
+                       inet_ntoa(f->sin_addr));
+               return (inet_ntoa(f->sin_addr));
+       }
+       if ((p = index(hp->h_name, '.')) && strcmp(p + 1, LocalDomain) == 0)
+               *p = '\0';
+       return ((char *) hp->h_name);
+}
+
+void
+domark()
+{
+       register struct filed *f;
+       time_t time();
+
+       now = time((time_t *)NULL);
+       MarkSeq += TIMERINTVL;
+       if (MarkSeq >= MarkInterval) {
+               logmsg(LOG_INFO, "-- MARK --", LocalHostName, ADDDATE|MARK);
+               MarkSeq = 0;
+       }
+
+       for (f = Files; f; f = f->f_next) {
+               if (f->f_prevcount && now >= REPEATTIME(f)) {
+                       dprintf("flush %s: repeated %d times, %d sec.\n",
+                           TypeNames[f->f_type], f->f_prevcount,
+                           repeatinterval[f->f_repeatcount]);
+                       fprintlog(f, 0, (char *)NULL);
+                       BACKOFF(f);
+               }
+       }
+#ifdef RE_INSTALL_SIGNAL
+        (void) signal(SIGALRM, domark);
+#endif
+       (void) alarm(TIMERINTVL);
+}
+
+/*
+ * Print syslogd errors some place.
+ */
+logerror(type)
+       char *type;
+{
+       char buf[100], *strerror();
+
+       if (errno)
+               (void) sprintf(buf, "syslogd: %s: %s", type, strerror(errno));
+       else
+               (void) sprintf(buf, "syslogd: %s", type);
+       errno = 0;
+       dprintf("%s\n", buf);
+       logmsg(LOG_SYSLOG|LOG_ERR, buf, LocalHostName, ADDDATE);
+}
+
+void
+die(sig)
+{
+       register struct filed *f;
+       char buf[100];
+
+       for (f = Files; f != NULL; f = f->f_next) {
+               /* flush any pending output */
+               if (f->f_prevcount)
+                       fprintlog(f, 0, (char *)NULL);
+       }
+       if (sig) {
+               dprintf("syslogd: exiting on signal %d\n", sig);
+               (void) sprintf(buf, "exiting on signal %d", sig);
+               errno = 0;
+               logerror(buf);
+       }
+       (void) unlink(LogName);
+       exit(0);
+}
+
+/*
+ *  INIT -- Initialize syslogd from configuration table
+ */
+
+void
+init()
+{
+       register int i;
+       register FILE *cf;
+       register struct filed *f, *next, **nextp;
+       register char *p;
+       char cline[BUFSIZ];
+
+       dprintf("init\n");
+
+       /*
+        *  Close all open log files.
+        */
+       Initialized = 0;
+       for (f = Files; f != NULL; f = next) {
+               /* flush any pending output */
+               if (f->f_prevcount)
+                       fprintlog(f, 0, (char *)NULL);
+
+               switch (f->f_type) {
+                 case F_FILE:
+                 case F_TTY:
+                 case F_CONSOLE:
+                 case F_FORW:
+                       (void) close(f->f_file);
+                       break;
+               }
+               next = f->f_next;
+               free((char *) f);
+       }
+       Files = NULL;
+       nextp = &Files;
+
+       /* open the configuration file */
+       if ((cf = fopen(ConfFile, "r")) == NULL) {
+               dprintf("cannot open %s\n", ConfFile);
+               *nextp = (struct filed *)calloc(1, sizeof(*f));
+               cfline("*.ERR\t/dev/console", *nextp);
+               (*nextp)->f_next = (struct filed *)calloc(1, sizeof(*f));
+               cfline("*.PANIC\t*", (*nextp)->f_next);
+               Initialized = 1;
+               return;
+       }
+
+       /*
+        *  Foreach line in the conf table, open that file.
+        */
+       f = NULL;
+       while (fgets(cline, sizeof cline, cf) != NULL) {
+               /*
+                * check for end-of-section, comments, strip off trailing
+                * spaces and newline character.
+                */
+               for (p = cline; isspace(*p); ++p);
+               if (*p == '\0' || *p == '#')
+                       continue;
+               for (p = index(cline, '\0'); isspace(*--p););
+               *++p = '\0';
+               f = (struct filed *)calloc(1, sizeof(*f));
+               *nextp = f;
+               nextp = &f->f_next;
+               cfline(cline, f);
+       }
+
+       /* close the configuration file */
+       (void) fclose(cf);
+
+       Initialized = 1;
+
+       if (Debug) {
+               for (f = Files; f; f = f->f_next) {
+                       for (i = 0; i <= LOG_NFACILITIES; i++)
+                               if (f->f_pmask[i] == INTERNAL_NOPRI)
+                                       printf("X ");
+                               else
+                                       printf("%d ", f->f_pmask[i]);
+                       printf("%s: ", TypeNames[f->f_type]);
+                       switch (f->f_type) {
+                       case F_FILE:
+                       case F_TTY:
+                       case F_CONSOLE:
+                               printf("%s", f->f_un.f_fname);
+                               break;
+
+                       case F_FORW:
+                               printf("%s", f->f_un.f_forw.f_hname);
+                               break;
+
+                       case F_USERS:
+                               for (i = 0; i < MAXUNAMES && *f->f_un.f_uname[i]; i++)
+                                       printf("%s, ", f->f_un.f_uname[i]);
+                               break;
+                       }
+                       printf("\n");
+               }
+       }
+
+       logmsg(LOG_SYSLOG|LOG_INFO, "syslogd: restart", LocalHostName, ADDDATE);
+       dprintf("syslogd: restarted\n");
+}
+
+/*
+ * Crack a configuration file line
+ */
+
+cfline(line, f)
+       char *line;
+       register struct filed *f;
+{
+       register char *p;
+       register char *q;
+       register int i;
+       char *bp;
+       int pri;
+       struct hostent *hp;
+       char buf[MAXLINE], ebuf[100];
+
+       dprintf("cfline(%s)\n", line);
+
+       errno = 0;      /* keep strerror() stuff out of logerror messages */
+
+       /* clear out file entry */
+       bzero((char *) f, sizeof *f);
+       for (i = 0; i <= LOG_NFACILITIES; i++)
+               f->f_pmask[i] = INTERNAL_NOPRI;
+
+       /* scan through the list of selectors */
+       for (p = line; *p && *p != '\t';) {
+
+               /* find the end of this facility name list */
+               for (q = p; *q && *q != '\t' && *q++ != '.'; )
+                       continue;
+
+               /* collect priority name */
+               for (bp = buf; *q && !index("\t,;", *q); )
+                       *bp++ = *q++;
+               *bp = '\0';
+
+               /* skip cruft */
+               while (index(", ;", *q))
+                       q++;
+
+               /* decode priority name */
+               if (*buf == '*')
+                       pri = LOG_PRIMASK + 1;
+               else {
+                       pri = decode(buf, prioritynames);
+                       if (pri < 0) {
+                               (void) sprintf(ebuf,
+                                   "unknown priority name \"%s\"", buf);
+                               logerror(ebuf);
+                               return;
+                       }
+               }
+
+               /* scan facilities */
+               while (*p && !index("\t.;", *p)) {
+                       for (bp = buf; *p && !index("\t,;.", *p); )
+                               *bp++ = *p++;
+                       *bp = '\0';
+                       if (*buf == '*')
+                               for (i = 0; i < LOG_NFACILITIES; i++)
+                                       f->f_pmask[i] = pri;
+                       else {
+                               i = decode(buf, facilitynames);
+                               if (i < 0) {
+                                       (void) sprintf(ebuf,
+                                           "unknown facility name \"%s\"",
+                                           buf);
+                                       logerror(ebuf);
+                                       return;
+                               }
+                               f->f_pmask[i >> 3] = pri;
+                       }
+                       while (*p == ',' || *p == ' ')
+                               p++;
+               }
+
+               p = q;
+       }
+
+       /* skip to action part */
+       while (*p == '\t')
+               p++;
+
+       switch (*p)
+       {
+       case '@':
+               if (!InetInuse)
+                       break;
+               (void) strcpy(f->f_un.f_forw.f_hname, ++p);
+               hp = gethostbyname(p);
+               if (hp == NULL) {
+                       extern int h_errno, h_nerr;
+                       extern char **h_errlist;
+
+                       logerror((u_int)h_errno < h_nerr ?
+                           h_errlist[h_errno] : "Unknown error");
+                       break;
+               }
+               bzero((char *) &f->f_un.f_forw.f_addr,
+                        sizeof f->f_un.f_forw.f_addr);
+               f->f_un.f_forw.f_addr.sin_family = AF_INET;
+               f->f_un.f_forw.f_addr.sin_port = LogPort;
+               bcopy(hp->h_addr, (char *) &f->f_un.f_forw.f_addr.sin_addr, hp->h_length);
+               f->f_type = F_FORW;
+               break;
+
+       case '/':
+               (void) strcpy(f->f_un.f_fname, p);
+#ifdef O_NOCTTY
+               if ((f->f_file = open(p, O_WRONLY|O_APPEND|O_NOCTTY, 0)) < 0) {
+#else /* !O_NOCTTY */
+               if ((f->f_file = open(p, O_WRONLY|O_APPEND, 0)) < 0) {
+#endif /* !O_NOCTTY */
+                       f->f_file = F_UNUSED;
+                       logerror(p);
+                       break;
+               }
+               if (isatty(f->f_file))
+                       f->f_type = F_TTY;
+               else
+                       f->f_type = F_FILE;
+               if (strcmp(p, ctty) == 0)
+                       f->f_type = F_CONSOLE;
+               break;
+
+       case '*':
+               f->f_type = F_WALL;
+               break;
+
+       default:
+               for (i = 0; i < MAXUNAMES && *p; i++) {
+                       for (q = p; *q && *q != ','; )
+                               q++;
+                       (void) strncpy(f->f_un.f_uname[i], p, UT_NAMESIZE);
+                       if ((q - p) > UT_NAMESIZE)
+                               f->f_un.f_uname[i][UT_NAMESIZE] = '\0';
+                       else
+                               f->f_un.f_uname[i][q - p] = '\0';
+                       while (*q == ',' || *q == ' ')
+                               q++;
+                       p = q;
+               }
+               f->f_type = F_USERS;
+               break;
+       }
+}
+
+
+/*
+ *  Decode a symbolic name to a numeric value
+ */
+
+decode(name, codetab)
+       char *name;
+       CODE *codetab;
+{
+       register CODE *c;
+       register char *p;
+       char buf[40];
+
+       if (isdigit(*name))
+               return (atoi(name));
+
+       (void) strcpy(buf, name);
+       for (p = buf; *p; p++)
+               if (isupper(*p))
+                       *p = tolower(*p);
+       for (c = codetab; c->c_name; c++)
+               if (!strcmp(buf, c->c_name))
+                       return (c->c_val);
+
+       return (-1);
+}
+
+#ifdef KLOG_STREAM
+
+int klogread(fd, buf, size)
+       int fd;
+       char *buf;
+       int size;
+{
+       static char line[MAXLINE];
+       static char *pos = line;
+
+       int i;
+       char *obuf = buf;
+       char *s;
+       char *end;
+       *pos = '\0';    
+       if (!(end = strchr(line, '\n'))) {
+               struct timeval tv;
+               fd_set readfds;
+
+               tv.tv_sec = tv.tv_usec = 0;
+               FD_ZERO(&readfds);
+               FD_SET(fd, &readfds);
+               i = select(fd + 1, (fd_set *) &readfds, (fd_set *) NULL,
+                   (fd_set *) NULL, &tv);
+               if (i <= 0)
+                       return i;
+               i = read(fd, pos, sizeof(line) - 1 - (pos - line));
+               if (i <= 0)
+                       return i;
+               pos += i;
+               *pos = '\0';
+               if (!(end = strchr(line, '\n')))
+                       return 0;
+       }
+       for (s = line; s < end; s++)
+               if (*s != '\r')
+                       *buf++ = *s;
+       end++;
+       for (s = line; end < pos; s++)
+               *s = *end++;
+       pos = s;
+       return (buf - obuf);
+}
+
+#endif /* KLOG_STREAM */
index 40e8d118e7f793f1c12e4ae2e7196235c538f0f2..834531d2944219c028b3a3d0e43e6c0aebd0ac0d 100644 (file)
@@ -1,6 +1,6 @@
 # Makefile -- Makefile for util-linux Linux utilities
 # Created: Sat Dec 26 20:09:40 1992
-# Revised: Sun Feb 26 16:55:46 1995 by faith@cs.unc.edu
+# Revised: Sat Jun  3 14:11:08 1995 by r.faith@ieee.org
 # Copyright 1992, 1993, 1994, 1995 Rickard E. Faith (faith@cs.unc.edu)
 #
 
@@ -36,9 +36,6 @@ NEEDS_TERMCAP=  more ul
 
 all: $(BIN) $(USRBIN)
 
-%.o: %.c
-       $(CC) -c $(CFLAGS) $< -o $@
-
 $(NEEDS_TERMCAP):
        $(CC) $(LDFLAGS) $^ -o $@ -ltermcap
 
@@ -66,11 +63,11 @@ strings: strings.o $(BSD)/getopt.o
 ul: ul.o
 
 install install.shadow install.text-utils: all
-       install -d -m 755 /bin /usr/bin /usr/lib /usr/man/man1
-       install -m 755 $(BIN) /bin
-       install -m 755 $(USRBIN) /usr/bin
-       install -m 644 $(USRLIB) /usr/lib
-       install -m 644 $(MAN1) /usr/man/man1
+       $(INSTALLDIR) $(BINDIR) $(USRBINDIR) $(USRLIBDIR) $(MAN1DIR)
+       $(INSTALLBIN) $(BIN) $(BINDIR)
+       $(INSTALLBIN) $(USRBIN) $(USRBINDIR)
+       $(INSTALLDAT) $(USRLIB) $(USRLIBDIR)
+       $(INSTALLMAN) $(MAN1) $(MAN1DIR)
 
 .PHONY: clean distclean
 clean:
index 5503a94a8745859d56b825cd46a74a795d4deaef..8f66b73100e34f4dede8b0311a0069a1514511d8 100644 (file)
@@ -32,7 +32,7 @@
 .\"    from: @(#)rev.1 6.3 (Berkeley) 3/21/92
 .\"     Modified for Linux by Charles Hannum (mycroft@gnu.ai.mit.edu)
 .\"                       and Brian Koehmstedt (bpk@gnu.ai.mit.edu)
-.\"    rev.1,v 1.1.1.1 1995/02/22 19:09:19 faith Exp
+.\"    $Id: rev.1,v 1.2 1995/03/12 01:33:24 faith Exp $
 .\"
 .Dd March 21, 1992
 .Dt REV 1
index 9fd22e0f3bd56b9b840f45958283b6266323a0ee..1cede0bc3075ab7bdb0cb789b8f2a95d66fdb4d4 100644 (file)
@@ -45,7 +45,7 @@ char copyright[] =
 
 #ifndef lint
 /*static char sccsid[] = "from: @(#)rev.c      5.2 (Berkeley) 3/21/92";*/
-static char rcsid[] = "rev.c,v 1.1.1.1 1995/02/22 19:09:19 faith Exp";
+static char rcsid[] = "$Id: rev.c,v 1.3 1995/10/07 01:32:14 faith Exp $";
 #endif /* not lint */
 
 #include <sys/types.h>
@@ -110,7 +110,7 @@ main(argc, argv)
                         t = p + len - 1 - (*(p+len-1)=='\r'
                                           || *(p+len-1)=='\n');
                         for ( ; t >= p; --t)
-                               if(strcmp(t, '\0') != 0)
+                               if(strcmp(t, "\0") != 0)
                                  putchar(*t);
 #endif /* linux */
                        putchar('\n');
diff --git a/time/Makefile b/time/Makefile
deleted file mode 100644 (file)
index 117e99d..0000000
+++ /dev/null
@@ -1,318 +0,0 @@
-# @(#)Makefile 7.29
-# Revised: Sun Feb 26 22:05:06 1995 by faith@cs.unc.edu
-#          FOR LINUX
-
-include ../MCONFIG
-
-# Change the line below for your time zone (after finding the zone you want in
-# the time zone files, or adding it to a time zone file).
-# Alternately, if you discover you've got the wrong time zone, you can just
-#      zic -l rightzone
-# to correct things.
-# Use the command
-#      make zonenames
-# to get a list of the values you can use for LOCALTIME.
-
-LOCALTIME=     US/Eastern # Factory
-
-# If you want something other than Eastern United States time as a template
-# for handling POSIX-style time zone environment variables,
-# change the line below (after finding the zone you want in the
-# time zone files, or adding it to a time zone file).
-# (When a POSIX-style environment variable is handled, the rules in the template
-# file are used to determine "spring forward" and "fall back" days and
-# times; the environment variable itself specifies GMT offsets of standard and
-# summer time.)
-# Alternately, if you discover you've got the wrong time zone, you can just
-#      zic -p rightzone
-# to correct things.
-# Use the command
-#      make zonenames
-# to get a list of the values you can use for POSIXRULES.
-# If you want POSIX compatibility, use "America/New_York".
-
-POSIXRULES=    America/New_York
-
-# Everything gets put in subdirectories of. . .
-
-TOPDIR=                /usr
-
-# "Compiled" time zone information is placed in the "TZDIR" directory
-# (and subdirectories).
-# Use an absolute path name for TZDIR unless you're just testing the software.
-
-TZDIR=         $(TOPDIR)/lib/zoneinfo
-
-LIBDIR=                $(TOPDIR)/lib
-TZLIB=         $(LIBDIR)/libz.a
-
-# If you always want time values interpreted as "seconds since the epoch
-# (not counting leap seconds)", use
-#      REDO=           posix_only
-# below.  If you always want right time values interpreted as "seconds since
-# the epoch" (counting leap seconds)", use
-#      REDO=           right_only
-# below.  If you want both sets of data available, with leap seconds not
-# counted normally, use
-#      REDO=           posix_right
-# below.  If you want both sets of data available, with leap seconds counted
-# normally, use
-#      REDO=           right_posix
-# below.
-# POSIX mandates that leap seconds not be counted; for compatibility with it,
-# use either "posix_only" or "posix_right".
-
-REDO=          posix_right
-
-# Since "." may not be in PATH...
-
-YEARISTYPE=    ./yearistype
-
-# If you're on an AT&T-based system (rather than a BSD-based system), add
-#      -DUSG
-# to the end of the "CFLAGS=" line.
-#
-# If you're running on a system where "strchr" is known as "index"
-# (for example, a 4.[012]BSD system), add
-#      -Dstrchr=index
-# to the end of the "CFLAGS=" line.
-#
-# If you're running on a system with a "mkdir" function, feel free to add
-#      -Demkdir=mkdir
-# to the end of the "CFLAGS=" line
-#
-# If you want to use System V compatibility code, add
-#      -DUSG_COMPAT
-# to the end of the "CFLAGS=" line.  This arrange for "timezone" and "daylight"
-# variables to be kept up-to-date by the time conversion functions.  Neither
-# "timezone" nor "daylight" is described in X3J11's work.
-#
-# If your system has a "GMT offset" field in its "struct tm"s
-# (or if you decide to add such a field in your system's "time.h" file),
-# add the name to a define such as
-#      -DTM_GMTOFF=tm_gmtoff
-# or
-#      -DTM_GMTOFF=_tm_gmtoff
-# to the end of the "CFLAGS=" line.
-# Neither tm_gmtoff nor _tm_gmtoff is described in X3J11's work;
-# in its work, use of "tm_gmtoff" is described as non-conforming.
-# Both UCB and Sun have done the equivalent of defining TM_GMTOFF in
-# their recent releases.
-#
-# If your system has a "zone abbreviation" field in its "struct tm"s
-# (or if you decide to add such a field in your system's "time.h" file),
-# add the name to a define such as
-#      -DTM_ZONE=tm_zone
-# or
-#      -DTM_ZONE=_tm_zone
-# to the end of the "CFLAGS=" line.
-# Neither tm_zone nor _tm_zone is described in X3J11's work;
-# in its work, use of "tm_zone" is described as non-conforming.
-# Both UCB and Sun have done the equivalent of defining TM_ZONE in
-# their recent releases.
-#
-# If you want functions that were inspired by early versions of X3J11's work,
-# add
-#      -DSTD_INSPIRED
-# to the end of the "CFLAGS=" line.  This arranges for the functions
-# "tzsetwall", "offtime", "timelocal", "timegm", "timeoff",
-# "posix2time", and "time2posix" to be added to the time conversion library.
-# "tzsetwall" is like "tzset" except that it arranges for local wall clock
-# time (rather than the time specified in the TZ environment variable)
-# to be used.
-# "offtime" is like "gmtime" except that it accepts a second (long) argument
-# that gives an offset to add to the time_t when converting it.
-# "timelocal" is equivalent to "mktime".
-# "timegm" is like "timelocal" except that it turns a struct tm into
-# a time_t using GMT (rather than local time as "timelocal" does).
-# "timeoff" is like "timegm" except that it accepts a second (long) argument
-# that gives an offset to use when converting to a time_t.
-# "posix2time" and "time2posix" are described in an included manual page.
-# None of these functions are described in X3J11's current work.
-# Sun has provided "tzsetwall", "timelocal", and "timegm" in SunOS 4.0.
-# These functions may well disappear in future releases of the time
-# conversion package.
-#
-# If you want Source Code Control System ID's left out of object modules, add
-#      -DNOID
-# to the end of the "CFLAGS=" line.
-#
-# If you'll never want to handle solar-time-based time zones, add
-#      -DNOSOLAR
-# to the end of the "CFLAGS=" line
-# (and comment out the "SDATA=" line below).
-# This reduces (slightly) the run-time data-space requirements of
-# the time conversion functions; it may reduce the acceptability of your system
-# to folks in oil- and cash-rich places.
-#
-# If you want to allocate state structures in localtime, add
-#      -DALL_STATE
-# to the end of the "CFLAGS=" line.  Storage is obtained by calling malloc.
-#
-# If you want an "altzone" variable (a la System V Release 3.1), add
-#      -DALTZONE
-# to the end of the "CFLAGS=" line.
-# This variable is not described in X3J11's work.
-#
-# If you want a "gtime" function (a la MACH), add
-#      -DCMUCS
-# to the end of the "CFLAGS=" line
-# This function is not described in X3J11's work.
-#
-# NIST-PCTS:151-2, Version 1.4, (1993-12-03) is a test suite put
-# out by the National Institute of Standards and Technology
-# which claims to test C and Posix conformance.  If you want to pass PCTS, add
-#      -DPCTS
-# to the end of the "CFLAGS=" line.
-#
-# If you want strict compliance with XPG4 as of April 9, 1994, add
-#      -DXPG4_1994_04_09
-# to the end of the "CFLAGS=" line.  This causes "strftime" to always return
-# 53 as a week number (rather than 52 or 53) for those days in January that
-# before the first Monday in January when a "%V" format is used and January 1
-# falls on a Friday, Saturday, or Sunday.
-#
-# If your compiler supports the `long double' type, add
-#      -DHAVE_LONG_DOUBLE
-# to the end of the "CFLAGS=" line.
-#
-# XXX--note about LOCALE_HOME here
-# XXX--note about HAVE_SETLOCALE here
-
-LFLAGS=$(LDFLAGS)
-
-################################################################################
-
-CC=            gcc -DTZDIR=\"$(TZDIR)\"
-
-TZCSRCS= \
-       zic.c localtime.c asctime.c scheck.c ialloc.c emkdir.c getopt.c optind.c
-TZCOBJS= \
-       zic.o localtime.o asctime.o scheck.o ialloc.o emkdir.o getopt.o optind.o
-TZDSRCS=       zdump.c localtime.c asctime.c ialloc.c getopt.c optind.c
-TZDOBJS=       zdump.o localtime.o asctime.o ialloc.o getopt.o optind.o
-DATESRCS= \
-       date.c localtime.c getopt.c optind.c logwtmp.c strftime.c asctime.c
-DATEOBJS= \
-       date.o localtime.o getopt.o optind.o logwtmp.o strftime.o asctime.o
-LIBSRCS=       localtime.c asctime.c difftime.c
-LIBOBJS=       localtime.o asctime.o difftime.o
-HEADERS=       tzfile.h private.h
-NONLIBSRCS=    zic.c zdump.c scheck.c ialloc.c emkdir.c getopt.c optind.c
-NEWUCBSRCS=    date.c logwtmp.c strftime.c
-SOURCES=       $(HEADERS) $(LIBSRCS) $(NONLIBSRCS) $(NEWUCBSRCS)
-MANS=          newctime.3 newtzset.3 time2posix.3 tzfile.5 zic.8 zdump.8
-DOCS=          README Theory $(MANS) date.1 Makefile
-YDATA=         africa antarctica asia australasia \
-               europe northamerica southamerica pacificnew etcetera factory \
-               backward
-NDATA=         systemv
-SDATA=         solar87 solar88 solar89
-TDATA=         $(YDATA) $(NDATA) $(SDATA)
-DATA=          $(YDATA) $(NDATA) $(SDATA) leapseconds yearistype.sh
-USNO=          usno1988 usno1989 usno1989a
-ENCHILADA=     $(DOCS) $(SOURCES) $(DATA) $(USNO)
-
-# And for the benefit of csh users on systems that assume the user
-# shell should be used to handle commands in Makefiles. . .
-
-SHELL=         /bin/sh
-
-all:           zic zdump $(LIBOBJS)
-
-ALL:           all date
-
-install:       all $(DATA) $(REDO) $(TZLIB) $(MANS)
-               ./zic -y $(YEARISTYPE) \
-                       -d $(TZDIR) -l $(LOCALTIME) -p $(POSIXRULES)
-               $(INSTALLDIR) $(USRSBINDIR)
-               $(INSTALLBIN) zic zdump $(USRSBINDIR)
-               $(INSTALLDIR) $(MAN3DIR) $(MAN5DIR) $(MAN8DIR)
-               -rm -f $(MAN3DIR)/newctime.3 \
-                       $(MAN3DIR)/newtzset.3 \
-                       $(MAN5DIR)/tzfile.5 \
-                       $(MAN8DIR)/zdump.8 \
-                       $(MAN8DIR)/zic.8
-               $(INSTALLMAN) newctime.3 newtzset.3 $(MAN3DIR)
-               $(INSTALLMAN) tzfile.5 $(MAN5DIR)
-               $(INSTALLMAN) zdump.8 zic.8 $(MAN8DIR)
-
-INSTALL:       ALL install date.1
-               $(INSTALLDIR) $(BINDIR)
-               $(INSTALLBIN) date $(BINDIR)
-               $(INSTALLDIR) $(MAN1DIR)
-               -rm -f $(MAN1DIR)/date.1
-               $(INSTALLMAN) date.1 $(MAN1DIR)
-
-zdump:         $(TZDOBJS)
-               $(CC) $(CFLAGS) $(LFLAGS) $(TZDOBJS) -o $@
-
-zic:           $(TZCOBJS) yearistype
-               $(CC) $(CFLAGS) $(LFLAGS) $(TZCOBJS) -o $@
-
-yearistype:    yearistype.sh
-               cp yearistype.sh yearistype
-               chmod +x yearistype
-
-posix_only:    zic $(TDATA)
-               ./zic -y $(YEARISTYPE) -d $(TZDIR) -L /dev/null $(TDATA)
-
-right_only:    zic leapseconds $(TDATA)
-               ./zic -y $(YEARISTYPE) -d $(TZDIR) -L leapseconds $(TDATA)
-
-other_two:     zic leapseconds $(TDATA)
-               ./zic -y $(YEARISTYPE) -d $(TZDIR)/posix -L /dev/null $(TDATA)
-               ./zic -y $(YEARISTYPE) \
-                       -d $(TZDIR)/right -L leapseconds $(TDATA)
-
-posix_right:   posix_only other_two
-
-right_posix:   right_only other_two
-
-# The "ar d"s below ensure that obsolete object modules
-# (based on source provided with earlier versions of the time conversion stuff)
-# are removed from the library.
-
-$(TZLIB):      $(LIBOBJS)
-               -mkdir $(TOPDIR) $(LIBDIR)
-               sleep 3
-               ar ru $@ $(LIBOBJS)
-               if ar t $@ timemk.o 2>/dev/null ; then ar d $@ timemk.o ; fi
-               if ar t $@ ctime.o 2>/dev/null ; then ar d $@ ctime.o ; fi
-               if [ -x /usr/ucb/ranlib -o -x /usr/bin/ranlib ] ; \
-                       then ranlib $@ ; fi
-
-# We use the system's getopt and logwtmp in preference to ours if available.
-
-date:          $(DATEOBJS)
-               ar r ,lib.a getopt.o optind.o logwtmp.o
-               if [ -x /usr/ucb/ranlib -o -x /usr/bin/ranlib ] ; \
-                       then ranlib ,lib.a ; fi
-               $(CC) $(CFLAGS) date.o localtime.o asctime.o strftime.o \
-                       -lc ,lib.a -o $@
-               rm -f ,lib.a
-
-clean:
-               rm -f core *~ *.o *.out zdump zic yearistype date ,* *.tar.gz
-
-names:
-               @echo $(ENCHILADA)
-
-public:                $(ENCHILADA)
-               tar cf - $(DOCS) $(SOURCES) $(USNO) | gzip -9 > tzcode.tar.gz
-               tar cf - $(DATA) | gzip -9 > tzdata.tar.gz
-
-zonenames:     $(TDATA)
-               @awk '/^Zone/ { print $$2 } /^Link/ { print $$3 }' $(TDATA)
-
-asctime.o:     private.h tzfile.h
-date.o:                private.h
-difftime.o:    private.h
-emkdir.o:      private.h
-ialloc.o:      private.h
-localtime.o:   private.h tzfile.h
-scheck.o:      private.h
-strftime.o:    tzfile.h
-zic.o:         private.h tzfile.h
-
-.KEEP_STATE:
diff --git a/time/README.time b/time/README.time
deleted file mode 100644 (file)
index 809defd..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-@(#)README     7.6
-
-"What time is it?" -- Richard Deacon as The King
-"Any time you want it to be." -- Frank Baxter as The Scientist
-                                       (from the Bell System film on time)
-
-The 1989 update of the time zone package featured
-
-*      POSIXization (including interpretation of POSIX-style TZ environment
-       variables, provided by Guy Harris),
-*      ANSIfication (including versions of "mktime" and "difftime"),
-*      SVIDulation (an "altzone" variable)
-*      MACHination (the "gtime" function)
-*      corrections to some time zone data (including corrections to the rules
-       for Great Britain and New Zealand)
-*      reference data from the United States Naval Observatory for folks who
-       want to do additional time zones
-*      and the 1989 data for Saudi Arabia.
-
-(Since this code will be treated as "part of the implementation" in some places
-and as "part of the application" in others, there's no good way to name
-functions, such as timegm, that are not part of the proposed ANSI C standard;
-such functions have kept their old, underscore-free names in this update.)
-
-Support for the tz_abbr variable has been eliminated from this version
-(to forestall "kitchen sink" complaints from certain quarters :-).
-
-Support for Turbo C compilation has also been eliminated; it was present to
-allow checking in an ANSI-style environment, and such checking is now done with
-gcc.
-
-And the "dysize" function has disappeared; it was present to allow compilation
-of the "date" command on old BSD systems, and a version of "date" is now
-provided in the package.  The "date" command is not created when you "make all"
-since it may lack options provided by the version distributed with your
-operating system, or may not interact with the system in the same way the
-native version does.
-
-Since POSIX frowns on correct leap second handling, the default behavior of
-the "zic" command (in the absence of a "-L" option) has been changed to omit
-leap second information from its output files.
-
-Be sure to read the comments in "Makefile" and make any changes
-needed to make things right for your system.
-
-To use the new functions, use a "-lz" option when compiling or linking.
-
-Historical local time information has been included here not because it
-is particularly useful, but rather to:
-
-*      give an idea of the variety of local time rules that have
-       existed in the past and thus an idea of the variety that may be
-       expected in the future;
-
-*      provide a test of the generality of the local time rule description
-       system.
-
-The information in the time zone data files is by no means authoritative;
-if you know that the rules are different from those in a file, by all means
-feel free to change file (and please send the changed version to
-tz@elsie.nci.nih.gov for use in the future).  Europeans take note!
-
-Thanks to these Timezone Caballeros who've made major contributions to the
-time conversion package:  Keith Bostic; Bob Devine; Paul Eggert; Robert Elz;
-Guy Harris; Mark Horton; John Mackin; and Bradley White.  Thanks also to
-Michael Bloom, Art Neilson, Stephen Prince, John Sovereign, and Frank Wales
-for testing work, and to Gwillim Law for checking local mean time data.
-None of them are responsible for remaining errors.
-
-Look in the ~ftp/pub directory of elsie.nci.nih.gov
-for updated versions of these files.
-
-Please send comments or information to tz@elsie.nci.nih.gov.
diff --git a/time/Theory b/time/Theory
deleted file mode 100644 (file)
index 93a07c0..0000000
+++ /dev/null
@@ -1,120 +0,0 @@
-@(#)Theory     7.2
-
-These time and date functions are much like the System V Release 2.0 (SVR2)
-time and date functions; there are a few additions and changes to extend
-the usefulness of the SVR2 functions:
-
-*      In SVR2, time display in a process is controlled by the environment
-       variable TZ, which "must be a three-letter time zone name, followed
-       by a number representing the difference between local time and
-       Greenwich Mean Time in hours, followed by an optional three-letter
-       name for a daylight time zone;" when the optional daylight time zone is
-       present, "standard U.S.A. Daylight Savings Time conversion is applied."
-       This means that SVR2 can't deal with other (for example, Australian)
-       daylight savings time rules, or situations where more than two
-       time zone abbreviations are used in an area.
-
-*      In SVR2, time conversion information is compiled into each program
-       that does time conversion.  This means that when time conversion
-       rules change (as in the United States in 1987), all programs that
-       do time conversion must be recompiled to ensure proper results.
-
-*      In SVR2, time conversion fails for near-minimum or near-maximum
-       time_t values when doing conversions for places that don't use GMT.
-
-*      In SVR2, there's no tamper-proof way for a process to learn the
-       system's best idea of local wall clock.  (This is important for
-       applications that an administrator wants used only at certain times--
-       without regard to whether the user has fiddled the "TZ" environment
-       variable.  While an administrator can "do everything in GMT" to get
-       around the problem, doing so is inconvenient and precludes handling
-       daylight savings time shifts--as might be required to limit phone
-       calls to off-peak hours.)
-
-*      These functions can account for leap seconds, thanks to Bradley White
-       (bww@k.cs.cmu.edu).
-
-These are the changes that have been made to the SVR2 functions:
-
-*      The "TZ" environment variable is used in generating the name of a file
-       from which time zone information is read (or is interpreted a la
-       POSIX); "TZ" is no longer constrained to be a three-letter time zone
-       name followed by a number of hours and an optional three-letter
-       daylight time zone name.  The daylight saving time rules to be used
-       for a particular time zone are encoded in the time zone file;
-       the format of the file allows U.S., Australian, and other rules to be
-       encoded, and allows for situations where more than two time zone
-       abbreviations are used.
-
-       It was recognized that allowing the "TZ" environment variable to
-       take on values such as "US/Eastern" might cause "old" programs
-       (that expect "TZ" to have a certain form) to operate incorrectly;
-       consideration was given to using some other environment variable
-       (for example, "TIMEZONE") to hold the string used to generate the
-       time zone information file name.  In the end, however, it was decided
-       to continue using "TZ":  it is widely used for time zone purposes;
-       separately maintaining both "TZ" and "TIMEZONE" seemed a nuisance;
-       and systems where "new" forms of "TZ" might cause problems can simply
-       use TZ values such as "EST5EDT" which can be used both by
-       "new" programs (a la POSIX) and "old" programs (as zone names and
-       offsets).
-
-*      To handle places where more than two time zone abbreviations are used,
-       the functions "localtime" and "gmtime" set tzname[tmp->tm_isdst]
-       (where "tmp" is the value the function returns) to the time zone
-       abbreviation to be used.  This differs from SVR2, where the elements
-       of tzname are only changed as a result of calls to tzset.
-
-*      Since the "TZ" environment variable can now be used to control time
-       conversion, the "daylight" and "timezone" variables are no longer
-       needed or supported.  (You can use a compile-time option to cause
-       these variables to be defined and to be set by "tzset"; however, their
-       values will not be used by "localtime.")
-
-*      The "localtime" function has been set up to deliver correct results
-       for near-minimum or near-maximum time_t values.  (A comment in the
-       source code tells how to get compatibly wrong results).
-
-*      A function "tzsetwall" has been added to arrange for the system's
-       best approximation to local wall clock time to be delivered by
-       subsequent calls to "localtime."  Source code for portable
-       applications that "must" run on local wall clock time should call
-       "tzsetwall();" if such code is moved to "old" systems that don't provide
-       tzsetwall, you won't be able to generate an executable program.
-       (These time zone functions also arrange for local wall clock time to be
-       used if tzset is called--directly or indirectly--and there's no "TZ"
-       environment variable; portable applications should not, however, rely
-       on this behavior since it's not the way SVR2 systems behave.)
-
-Points of interest to folks with Version 7 or BSD systems:
-
-*      The BSD "timezone" function is not present in this package;
-       it's impossible to reliably map timezone's arguments (a "minutes west
-       of GMT" value and a "daylight saving time in effect" flag) to a
-       time zone abbreviation, and we refuse to guess.
-       Programs that in the past used the timezone function may now examine
-       tzname[localtime(&clock)->tm_isdst] to learn the correct time
-       zone abbreviation to use.  Alternatively, use localtime(&clock)->tm_zone
-       if this has been enabled.
-
-*      The BSD gettimeofday function is not used in this package;
-       this lets users control the time zone used in doing time conversions.
-       Users who don't try to control things (that is, users who do not set
-       the environment variable TZ) get the time conversion specified in the
-       file "/etc/zoneinfo/localtime"; see the time zone compiler writeup for
-       information on how to initialize this file.
-
-The functions that are conditionally compiled if STD_INSPIRED is defined should,
-at this point, be looked on primarily as food for thought.  They are not in
-any sense "standard compatible"--some are not, in fact, specified in *any*
-standard.  They do, however, represent responses of various authors to
-standardization proposals.
-
-Other time conversion proposals, in particular the one developed by folks at
-Hewlett Packard, offer a wider selection of functions that provide capabilities
-beyond those provided here.  The absence of such functions from this package
-is not meant to discourage the development, standardization, or use of such
-functions.  Rather, their absence reflects the decision to make this package
-close to SVR2 (with the exceptions outlined above) to ensure its broad
-acceptability.  If more powerful time conversion functions can be standardized,
-so much the better.
diff --git a/time/africa b/time/africa
deleted file mode 100644 (file)
index a978667..0000000
+++ /dev/null
@@ -1,603 +0,0 @@
-# @(#)africa   7.6
-
-# This data is by no means authoritative; if you think you know better,
-# go ahead and edit the file (and please send any changes to
-# tz@elsie.nci.nih.gov for general use in the future).
-
-# From Paul Eggert <eggert@twinsun.com> (November 18, 1993):
-#
-# A good source for time zone historical data outside the U.S. is
-# Thomas G. Shanks, The International Atlas (3rd edition),
-# San Diego: ACS Publications, Inc. (1991).
-# Except where otherwise noted, it is the source for the data below.
-#
-# Another source occasionally used is Edward W. Whitman, World Time Differences,
-# Whitman Publishing Co, 2 Niagara Av, Ealing, London (undated), which
-# I found in the UCLA library.
-#
-# I added so many Zone names that the old, mostly flat name space was unwieldy.
-# So I renamed the Zones to have the form AREA/LOCATION, where
-# AREA is the name of a continent or ocean, and
-# LOCATION is the name of a specific location within that region.
-# For example, the old zone name `Egypt' is now `Africa/Cairo'.
-#
-# Here are the general rules I used for choosing location names,
-# in decreasing order of importance:
-#
-#      Use only valid Posix file names.  Use only Ascii letters, digits, `.',
-#              `-' and `_'.  Do not exceed 14 characters or start with `-'.
-#              E.g. prefer `Brunei' to `Bandar_Seri_Begawan'.
-#      Include at least one location per time zone rule set per country.
-#              One such location is enough.
-#      If a name is ambiguous, use a less ambiguous alternative;
-#              e.g. many cities are named San Jose and Georgetown, so
-#              prefer `Costa_Rica' to `San_Jose' and `Guyana' to `Georgetown'.
-#      Keep locations compact.  Use cities or small islands, not countries
-#              or regions, so that any future time zone changes do not split
-#              locations into different time zones.  E.g. prefer `Paris'
-#              to `France', since France has had multiple time zones.
-#      Use traditional English spelling, e.g. prefer `Rome' to `Roma', and
-#              prefer `Athens' to the true name (which uses Greek letters).
-#              The Posix file name restrictions encourage this rule.
-#      Use the most populous among locations in a country's time zone,
-#              e.g. prefer `Shanghai' to `Beijing'.  Among locations with
-#              similar populations, pick the best-known location,
-#              e.g. prefer `Rome' to `Milan'.
-#      Use the singular form, e.g. prefer `Canary' to `Canaries'.
-#      Omit common suffixes like `_Islands' and `_City', unless that
-#              would lead to ambiguity.  E.g. prefer `Cayman' to
-#              `Cayman_Islands' and `Guatemala' to `Guatemala_City',
-#              but prefer `Mexico_City' to `Mexico' because the country
-#              of Mexico has several time zones.
-#      Use `_' to represent a space.
-#      Omit `.' from abbreviations in names, e.g. prefer `St_Helena'
-#              to `St._Helena'.
-#
-# We typically use traditional English time zone abbreviations,
-# and assume that applications translate them to other languages
-# as part of the normal localization process.
-#
-# I made up the following time zone abbreviations; corrections are welcome!
-#              LMT     Local Mean Time
-#      -2:00   CVT     Cape Verde Time (no longer used)
-#      -1:00   AAT     Atlantic Africa Time
-#       0:00   WAT     West Africa Time
-#       1:00   CAT     Central Africa Time
-#       2:00   SAT     South Africa Time
-#       3:00   EAT     East Africa Time
-#       4:00   SMT     Seychelles and Mascarene Time
-# The final `T' is replaced by `ST' for summer time, e.g. `SAST'.
-# BEAT is British East Africa Time, which was 2:30 before 1948 and 2:45 after.
-
-
-# Algeria
-# Rule NAME    FROM    TO      TYPE    IN      ON      AT      SAVE    LETTER/S
-Rule   Algeria 1911    only    -       Jan      1       0:00s  0       -
-Rule   Algeria 1916    only    -       Jun     14      23:00s  1:00    " DST"
-Rule   Algeria 1916    1919    -       Oct     Sun<=7  23:00s  0       -
-Rule   Algeria 1917    only    -       Mar     24      23:00s  1:00    " DST"
-Rule   Algeria 1918    only    -       Mar      9      23:00s  1:00    " DST"
-Rule   Algeria 1919    only    -       Mar      1      23:00s  1:00    " DST"
-Rule   Algeria 1920    only    -       Feb     14      23:00s  1:00    " DST"
-Rule   Algeria 1920    only    -       Oct     23      23:00s  0       -
-Rule   Algeria 1921    only    -       Mar     14      23:00s  1:00    " DST"
-Rule   Algeria 1921    only    -       Jun     21      23:00s  0       -
-Rule   Algeria 1939    only    -       Sep     11      23:00s  1:00    " DST"
-Rule   Algeria 1939    only    -       Nov     19       1:00   0       -
-Rule   Algeria 1944    1945    -       Apr     Mon<=7   2:00   1:00    " DST"
-Rule   Algeria 1944    only    -       Oct      8       2:00   0       -
-Rule   Algeria 1945    only    -       Sep     16       1:00   0       -
-Rule   Algeria 1971    only    -       Apr     25      23:00s  1:00    " DST"
-Rule   Algeria 1971    only    -       Sep     26      23:00s  0       -
-Rule   Algeria 1977    only    -       May      6       0:00   1:00    " DST"
-Rule   Algeria 1977    only    -       Oct     21       0:00   0       -
-Rule   Algeria 1978    only    -       Mar     24       1:00   1:00    " DST"
-Rule   Algeria 1978    only    -       Sep     22       3:00   0       -
-Rule   Algeria 1980    only    -       Apr     25       0:00   1:00    " DST"
-Rule   Algeria 1980    only    -       Oct     31       2:00   0       -
-# Shanks gives 0:09 for Paris Mean Time; go with Whitman's more precise 0:09:05.
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Africa/Algiers  0:12:12 -       LMT     1891 Mar 15 0:01
-                       0:09:05 -       PMT     1911 Mar 11    # Paris Mean Time
-                       0:00    Algeria WET%s   1940 Feb 25 2:00
-                       1:00    Algeria MET%s   1946 Oct  7
-                       0:00    -       WET     1956 Jan 29
-                       1:00    -       MET     1963 Apr 14
-                       0:00    Algeria WET%s   1977 Oct 21
-                       1:00    Algeria MET%s   1979 Oct 26
-                       0:00    Algeria WET%s   1981 May
-                       1:00    -       MET
-
-# Angola
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Africa/Luanda   0:52:56 -       LMT     1892
-                       0:52    -       LMT     1911 May 26 # Luanda Mean Time
-                       1:00    -       CAT
-
-# Benin
-# Whitman says they switched to 1:00 in 1946, not 1934; go with Shanks.
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone Africa/Porto-Novo 0:10:28 -       LMT     1912
-                       0:00    -       WAT     1934 Feb 26
-                       1:00    -       CAT
-
-# Botswana
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Africa/Gaborone 1:43:40 -       LMT     1885
-                       2:00    -       SAT     1943 Sep 19 2:00
-                       2:00    1:00    SAST    1944 Mar 19 2:00
-                       2:00    -       SAT
-
-# Burkina Faso
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone Africa/Ouagadougou        -0:06:04 -      LMT     1912
-                        0:00   -       WAT
-
-# Burundi
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone Africa/Bujumbura  1:57:28 -       LMT     1890
-                       2:00    -       SAT
-
-# Cameroon
-# Whitman says they switched to 1:00 in 1920; go with Shanks.
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Africa/Douala   0:38:48 -       LMT     1912
-                       1:00    -       CAT
-
-# Cape Verde
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone Atlantic/Cape_Verde -1:34:04 -    LMT     1907                    # Praia
-                       -2:00   -       CVT     1942 Sep
-                       -2:00   1:00    CVST    1945 Oct 15
-                       -2:00   -       CVT     1975 Nov 25 2:00
-                       -1:00   -       AAT
-
-# Central African Republic
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Africa/Bangui   1:14:20 -       LMT     1912
-                       1:00    -       CAT
-
-# Chad
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Africa/Ndjamena 1:00:12 -       LMT     1912
-                       1:00    -       CAT     1979 Oct 14
-                       1:00    1:00    CAST    1980 Mar  8
-                       1:00    -       CAT
-
-# Comoros
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Indian/Comoro   2:53:04 -       LMT     1911 Jul   # Moroni, Gran Comoro
-                       3:00    -       EAT
-
-# Congo
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone Africa/Brazzaville        1:01:08 -       LMT     1912
-                       1:00    -       CAT
-
-# Cote D'Ivoire
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Africa/Abidjan  -0:16:08 -      LMT     1912
-                        0:00   -       WAT
-
-# Djibouti
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Africa/Djibouti 2:52:36 -       LMT     1911 Jul
-                       3:00    -       EAT
-
-###############################################################################
-
-# Egypt
-
-# From Bob Devine (January 28, 1988):
-# Egypt: DST from first day of May to first of October (ending may
-# also be on Sept 30th not 31st -- you might want to ask one of the
-# soc.* groups, you might hit someone who could ask an embassy).
-# DST since 1960 except for 1981-82.
-
-# From U. S. Naval Observatory (January 19, 1989):
-# EGYPT               2 H  AHEAD OF UTC
-# EGYPT               3 H  AHEAD OF UTC  MAY 17 - SEP 30 (AFTER
-# EGYPT                                  RAMADAN)
-
-# From Shanks (1991):
-# Rule NAME    FROM    TO      TYPE    IN      ON      AT      SAVE    LETTER/S
-Rule   Egypt   1900    only    -       Oct      1      0:00    0       -
-Rule   Egypt   1940    only    -       Jul     15      0:00    1:00    " DST"
-Rule   Egypt   1940    only    -       Oct      1      0:00    0       -
-Rule   Egypt   1941    only    -       Apr     15      0:00    1:00    " DST"
-Rule   Egypt   1941    only    -       Sep     16      0:00    0       -
-Rule   Egypt   1942    1944    -       Apr      1      0:00    1:00    " DST"
-Rule   Egypt   1942    only    -       Oct     27      0:00    0       -
-Rule   Egypt   1943    1945    -       Nov      1      0:00    0       -
-Rule   Egypt   1945    only    -       Apr     16      0:00    1:00    " DST"
-Rule   Egypt   1957    only    -       May     10      0:00    1:00    " DST"
-Rule   Egypt   1957    1958    -       Oct      1      0:00    0       -
-Rule   Egypt   1958    only    -       May      1      0:00    1:00    " DST"
-Rule   Egypt   1959    1981    -       May      1      1:00    1:00    " DST"
-Rule   Egypt   1959    1965    -       Sep     30      3:00    0       -
-Rule   Egypt   1966    max     -       Oct      1      3:00    0       -
-Rule   Egypt   1982    only    -       Jul     25      1:00    1:00    " DST"
-Rule   Egypt   1983    only    -       Jul     12      1:00    1:00    " DST"
-Rule   Egypt   1984    1988    -       May      1      1:00    1:00    " DST"
-Rule   Egypt   1989    only    -       May      6      1:00    1:00    " DST"
-Rule   Egypt   1990    max     -       May      1      1:00    1:00    " DST"
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Africa/Cairo    2:05:00 -       LMT     1900 Oct
-                       2:00    Egypt   EET%s
-
-# Equatorial Guinea
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Africa/Malabo   0:35:08 -       LMT     1912
-                       0:00    -       WAT     1963 Dec 15
-                       1:00    -       CAT
-
-# Eritrea
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Africa/Asmera   2:35:32 -       LMT     1870
-                       2:36    -       AMT     1890          # Asmera Mean Time
-                       2:35    -       AAMT    1936 May 5    # Addis Ababa MT
-                       3:00    -       EAT
-
-# Ethiopia
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone Africa/Addis_Ababa        2:34:48 -       LMT     1870
-                       2:35    -       AAMT    1936 May 5    # Addis Ababa MT
-                       3:00    -       EAT
-
-# Gabon
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone Africa/Libreville 0:37:48 -       LMT     1912
-                       1:00    -       CAT
-
-# Gambia
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Africa/Banjul   -1:06:36 -      LMT     1912
-                       -1:07   -       BMT     1935    # Banjul Mean Time
-                       -1:00   -       AAT     1964
-                        0:00   -       WAT
-
-# Ghana
-# From Paul Eggert <eggert@twinsun.com> (November 18, 1993):
-# WATDT is my invention for ``West Africa one-Third Daylight Time''.
-# From Shanks (1991):
-# Rule NAME    FROM    TO      TYPE    IN      ON      AT      SAVE    LETTER/S
-Rule   Ghana   1918    only    -       Jan      1      0:00    0       WAT
-# Whitman says DST was observed from 1931 to ``the present''; go with Shanks.
-Rule   Ghana   1936    1942    -       Sep      1      0:00    0:20    WATDT
-Rule   Ghana   1936    1942    -       Dec     31      0:00    0       WAT
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Africa/Accra    -0:00:52 -      LMT     1918
-                        0:00   Ghana   %s
-
-# Guinea
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Africa/Conakry  -0:54:52 -      LMT     1912
-                        0:00   -       WAT     1934 Feb 26
-                        1:00   -       CAT     1960
-                        0:00   -       WAT
-
-# Guinea-Bissau
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Africa/Bissau   -1:02:20 -      LMT     1911 May 26
-                        1:00   -       CAT     1975
-                        0:00   -       WAT
-
-# Kenya
-# From Paul Eggert <eggert@twinsun.com> (November 18, 1993):
-# Shanks says the transition to 2:45 was in 1940, but it must have been 1948.
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Africa/Nairobi  2:27:16 -       LMT     1928 Jul
-                       3:00    -       EAT     1930
-                       2:30    -       BEAT    1948
-                       2:45    -       BEAT    1960
-                       3:00    -       EAT
-
-# Lesotho
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Africa/Maseru   1:50:00 -       LMT     1903 Mar
-                       2:00    -       SAT     1943 Sep 19 2:00
-                       2:00    1:00    SAST    1944 Mar 19 2:00
-                       2:00    -       SAT
-
-# Liberia
-# From Paul Eggert <eggert@twinsun.com> (November 18, 1993):
-# In 1972 Liberia was the last country to switch
-# from a GMT offset that was not a multiple of 15 minutes.
-# Time magazine reported that it was in honor of their leader's birthday.
-# For Liberia before 1972, Shanks reports -0:44, and Whitman reports -0:44:30;
-# go with Whitman.
-#
-# From Shanks (1991), as corrected by Whitman:
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Africa/Monrovia -0:43:08 -      LMT     1882
-                       -0:43:08 -      MMT     1919 Mar # Monrovia Mean Time
-                       -0:44:30 -      LST     1972 May # Liberia Standard Time
-                        0:00   -       WAT
-
-###############################################################################
-
-# Libya
-
-# From Bob Devine (January 28 1988):
-# Libya: Since 1982 April 1st to September 30th (?)
-
-# From U. S. Naval Observatory (January 19, 1989):
-# LIBYAN ARAB         1 H  AHEAD OF UTC  JAMAHIRIYA/LIBYA
-# LIBYAN ARAB         2 H  AHEAD OF UTC  APR 1 - SEP 30 JAMAHIRIYA/LIBYA
-
-# From Shanks (1991):
-# Rule NAME    FROM    TO      TYPE    IN      ON      AT      SAVE    LETTER/S
-Rule   Libya   1920    only    -       Jan      1      0:00    0       -
-Rule   Libya   1951    only    -       Oct     14      2:00    1:00    " DST"
-Rule   Libya   1952    only    -       Jan      1      0:00    0       -
-Rule   Libya   1953    only    -       Oct      9      2:00    1:00    " DST"
-Rule   Libya   1954    only    -       Jan      1      0:00    0       -
-Rule   Libya   1955    only    -       Sep     30      0:00    1:00    " DST"
-Rule   Libya   1956    only    -       Jan      1      0:00    0       -
-Rule   Libya   1982    1984    -       Apr      1      0:00    1:00    " DST"
-Rule   Libya   1982    1985    -       Oct      1      0:00    0       -
-Rule   Libya   1985    only    -       Apr      6      0:00    1:00    " DST"
-Rule   Libya   1986    only    -       Apr      4      0:00    1:00    " DST"
-Rule   Libya   1986    only    -       Oct      3      0:00    0       -
-Rule   Libya   1987    1989    -       Apr      1      0:00    1:00    " DST"
-Rule   Libya   1987    1990    -       Oct      1      0:00    0       -
-Rule   Libya   1990    only    -       May      4      0:00    1:00    " DST"
-# From Paul Eggert <eggert@twinsun.com> (November 18, 1993):
-# Here's a guess for years starting with 1991.
-Rule   Libya   1991    max     -       Apr      1      0:00    1:00    " DST"
-Rule   Libya   1991    max     -       Oct      1      0:00    0       -
-
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Africa/Tripoli  0:52:44 -       LMT     1920
-                       1:00    Libya   MET%s   1959
-                       2:00    -       EET     1982
-                       1:00    Libya   MET%s
-
-# Madagascar
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone Indian/Antananarivo 3:10:04 -     LMT     1911 Jul
-                       3:00    -       EAT     1954 Feb 27 23:00s
-                       3:00    1:00    EAST    1954 May 29 23:00s
-                       3:00    -       EAT
-
-# Malawi
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Africa/Blantyre 2:20:00 -       LMT     1903 Mar
-                       2:00    -       SAT
-
-# Mali
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Africa/Bamako   -0:32:00 -      LMT     1912
-                        0:00   -       WAT     1934 Feb 26
-                       -1:00   -       AAT     1960 Jun 20
-                        0:00   -       WAT
-# no longer different from Bamako, but too famous to omit
-Zone   Africa/Timbuktu -0:12:04 -      LMT     1912
-                        0:00   -       WAT
-
-# Mauritania
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone Africa/Nouakchott -1:03:48 -      LMT     1912
-                        0:00   -       WAT     1934 Feb 26
-                       -1:00   -       AAT     1960 Jun 20
-                        0:00   -       WAT
-
-# Mauritius
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone Indian/Mauritius  3:50:00 -       LMT     1907            # Port Louis
-                       4:00    -       SMT
-# Agalega Is, Rodriguez
-# no information; probably like Indian/Mauritius
-
-# Mayotte
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Indian/Mayotte  3:01:08 -       LMT     1911 Jul        # Dzaoudzi
-                       3:00    -       EAT
-
-# Morocco
-# Rule NAME    FROM    TO      TYPE    IN      ON      AT      SAVE    LETTER/S
-Rule   Morocco 1913    only    -       Oct     26       0:00   0       -
-Rule   Morocco 1939    only    -       Sep     12       0:00   1:00    " DST"
-Rule   Morocco 1939    only    -       Nov     19       0:00   0       -
-Rule   Morocco 1940    only    -       Feb     25       0:00   1:00    " DST"
-Rule   Morocco 1945    only    -       Nov     18       0:00   0       -
-Rule   Morocco 1950    only    -       Jun     11       0:00   1:00    " DST"
-Rule   Morocco 1950    only    -       Oct     29       0:00   0       -
-Rule   Morocco 1967    only    -       Jun      3      12:00   1:00    " DST"
-Rule   Morocco 1967    only    -       Oct      1       0:00   0       -
-Rule   Morocco 1974    only    -       Jun     24       0:00   1:00    " DST"
-Rule   Morocco 1974    only    -       Sep      1       0:00   0       -
-Rule   Morocco 1976    1977    -       May      1       0:00   1:00    " DST"
-Rule   Morocco 1976    only    -       Aug      1       0:00   0       -
-Rule   Morocco 1977    only    -       Sep     28       0:00   0       -
-Rule   Morocco 1978    only    -       Jun      1       0:00   1:00    " DST"
-Rule   Morocco 1978    only    -       Aug      4       0:00   0       -
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone Africa/Casablanca -0:30:20 -      LMT     1913 Oct 26
-                        0:00   Morocco WET%s   1984 Mar 16
-                        1:00   -       MET     1986
-                        0:00   -       WET
-# The following are controlled by Spain, and are like Europe/Madrid:
-# Alboran, Alhucemas Is, Ceuta, Chafarinas Is, Mellila.
-
-# Mozambique
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Africa/Maputo   2:10:20 -       LMT     1903 Mar
-                       2:00    -       SAT
-
-# Namibia
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Africa/Windhoek 1:08:24 -       LMT     1892 Feb 8
-                       1:30    -       SWAT    1903 Mar        # SW Africa Time
-                       2:00    -       SAT     1942 Sep 20 2:00
-                       2:00    1:00    SAST    1943 Mar 21 2:00
-                       2:00    -       SAT
-
-# Niger
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Africa/Niamey   0:08:28 -       LMT     1912
-                       1:00    -       CAT     1934 Feb 26
-                       0:00    -       WAT     1960
-                       1:00    -       CAT
-
-# Nigeria
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Africa/Lagos    0:13:36 -       LMT     1919 Sep
-                       1:00    -       CAT
-
-# Reunion
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Indian/Reunion  3:41:52 -       LMT     1911 Jun        # St Denis
-                       4:00    -       SMT
-
-# Rwanda
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Africa/Kigali   2:00:16 -       LMT     1935 Jun
-                       2:00    -       SAT
-
-# St Helena
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone Atlantic/St_Helena        -0:22:48 -      LMT     1890            # Jamestown
-                       -0:06   -       ?MT     1951    # a typo in Shanks?
-                        0:00   -       GMT
-# Whitman says Tristan da Cunha is on GMT, like Atlantic/St_Helena.
-#
-# Ascension, Gough, Inaccessible, Nightingale
-# no information; probably like Atlantic/St_Helena
-
-# Sao Tome and Principe
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Africa/Sao_Tome  0:26:56 -      LMT     1884
-                       -0:37   -       ?MT     1912    # a typo in Shanks?
-                        0:00   -       WAT
-
-# Senegal
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Africa/Dakar    -1:09:44 -      LMT     1912
-                       -1:00   -       AAT     1941 Jun
-                        0:00   -       WAT
-
-# Seychelles
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Indian/Mahe     3:41:48 -       LMT     1906 Jun        # Victoria
-                       4:00    -       SMT
-
-# Sierra Leone
-# Rule NAME    FROM    TO      TYPE    IN      ON      AT      SAVE    LETTER/S
-Rule   SL      1913    only    -       Oct     26      0:00    0       -
-# Whitman gives Mar 31 - Aug 31 for 1931 on; go with Shanks.
-Rule   SL      1935    1942    -       Jun      1      0:00    1:00    S
-Rule   SL      1935    1942    -       Oct      1      0:00    0       -
-Rule   SL      1957    1962    -       Jun      1      0:00    1:00    S
-Rule   SL      1957    1962    -       Sep      1      0:00    0       -
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Africa/Freetown -0:53:00 -      LMT     1882
-                       -0:53   -       FMT     1913 Jun
-                       -1:00   SL      AA%sT   1957
-                        0:00   SL      WA%sT
-
-# Somalia
-# From Paul Eggert <eggert@twinsun.com> (November 18, 1993):
-# Shanks omits the 1948 transition to 2:45; this is probably a typo.
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone Africa/Mogadishu  3:01:28 -       LMT     1893 Nov
-                       3:00    -       EAT     1931
-                       2:30    -       BEAT    1948
-                       2:45    -       BEAT    1957    # not in Shanks
-                       3:00    -       EAT
-
-# South Africa
-# Rule NAME    FROM    TO      TYPE    IN      ON      AT      SAVE    LETTER/S
-Rule   SA      1892    only    -       Feb     8       0:00    0       -
-Rule   SA      1942    1943    -       Sep     Sun>=15 2:00    1:00    S
-Rule   SA      1943    1944    -       Mar     Sun>=15 2:00    0       -
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone Africa/Johannesburg 1:52:00 -     LMT     1892 Feb 8
-                       1:30    -       SAT     1903 Mar
-                       2:00    SA      SA%sT
-# Prince Edward Is
-# no information
-
-# Sudan
-# Rule NAME    FROM    TO      TYPE    IN      ON      AT      SAVE    LETTER/S
-Rule   Sudan   1931    only    -       Feb      8      0:00    0       -
-Rule   Sudan   1970    only    -       May      1      0:00    1:00    " DST"
-Rule   Sudan   1970    max     -       Oct     15      0:00    0       -
-Rule   Sudan   1971    only    -       Apr     30      0:00    1:00    " DST"
-Rule   Sudan   1972    max     -       Apr     lastSun 0:00    1:00    " DST"
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Africa/Khartoum 2:10:08 -       LMT     1931
-                       2:00    Sudan   EET%s
-
-# Swaziland
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Africa/Mbabane  2:04:24 -       LMT     1903 Mar
-                       2:00    -       SAT
-
-# Tanzania
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone Africa/Dar_es_Salaam 2:37:08 -    LMT     1931
-                       3:00    -       EAT     1948
-                       2:45    -       BEAT    1961
-                       3:00    -       EAT
-
-# Togo
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Africa/Lome     0:04:52 -       LMT     1893
-                       0:00    -       WAT
-
-# Tunisia
-# Rule NAME    FROM    TO      TYPE    IN      ON      AT      SAVE    LETTER/S
-Rule   Tunisia 1911    only    -       Mar      9       0:00   0       -
-Rule   Tunisia 1939    only    -       Apr     15      23:00s  1:00    " DST"
-Rule   Tunisia 1939    only    -       Nov     18      23:00s  0       -
-Rule   Tunisia 1940    only    -       Feb     25      23:00s  1:00    " DST"
-Rule   Tunisia 1941    only    -       Oct      6       0:00   0       -
-Rule   Tunisia 1942    only    -       Mar      9       0:00   1:00    " DST"
-Rule   Tunisia 1942    only    -       Nov      2       3:00   0       -
-Rule   Tunisia 1943    only    -       Mar     29       2:00   1:00    " DST"
-Rule   Tunisia 1943    only    -       Apr     17       2:00   0       -
-Rule   Tunisia 1943    only    -       Apr     25       2:00   1:00    " DST"
-Rule   Tunisia 1943    only    -       Oct      4       2:00   0       -
-Rule   Tunisia 1944    1945    -       Apr     Mon>=1   2:00   1:00    " DST"
-Rule   Tunisia 1944    only    -       Oct      8       0:00   0       -
-Rule   Tunisia 1945    only    -       Sep     16       0:00   0       -
-Rule   Tunisia 1977    only    -       Apr     30       0:00s  1:00    " DST"
-Rule   Tunisia 1977    only    -       Sep     24       0:00s  0       -
-Rule   Tunisia 1978    only    -       May      1       0:00s  1:00    " DST"
-Rule   Tunisia 1978    only    -       Oct      1       0:00s  0       -
-Rule   Tunisia 1988    only    -       Jun      1       0:00s  1:00    " DST"
-Rule   Tunisia 1988    max     -       Sep     lastSun  0:00s  0       -
-Rule   Tunisia 1989    only    -       Mar     26       0:00s  1:00    " DST"
-Rule   Tunisia 1990    only    -       May      1       0:00s  1:00    " DST"
-Rule   Tunisia 1991    max     -       Mar     lastSun  0:00s  1:00    " DST"
-# Shanks gives 0:09 for Paris Mean Time; go with Whitman's more precise 0:09:05.
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Africa/Tunis    0:40:44 -       LMT     1881 May 12
-                       0:09:05 -       PMT     1911 Mar  9    # Paris Mean Time
-                       1:00    Tunisia MET%s
-
-# Uganda
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Africa/Kampala  2:09:40 -       LMT     1928 Jul
-                       3:00    -       EAT     1930
-                       2:30    -       BEAT    1948
-                       2:45    -       BEAT    1957
-                       3:00    -       EAT
-
-# Zaire
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone Africa/Kinshasa   1:01:12 -       LMT     1897 Nov 9
-                       1:00    -       CAT
-Zone Africa/Lumumbashi 1:49:52 -       LMT     1897 Nov 9
-                       2:00    -       SAT
-
-# Zambia
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Africa/Lusaka   1:53:08 -       LMT     1903 Mar
-                       2:00    -       SAT
-
-# Zimbabwe
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Africa/Harare   2:04:12 -       LMT     1903 Mar
-                       2:00    -       SAT
diff --git a/time/antarctica b/time/antarctica
deleted file mode 100644 (file)
index f5ed313..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-# @(#)antarctica       7.2
-
-# From Arthur David Olson (February 13, 1988):
-# No data available.
-
-# Balleny Is
-
-# British Antarctic Territories include
-#      South Orkney Is
-#      South Shetland Is
-
-# Amsterdam Island
-# Bouvet
-# Crozet Is
-# Heard and McDonald Is
-# Kerguelen Is
-# St Paul Island
-# Peter I Island
-# Scott Island
diff --git a/time/asctime.c b/time/asctime.c
deleted file mode 100644 (file)
index 880915e..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-#ifndef lint
-#ifndef NOID
-static char    elsieid[] = "@(#)asctime.c      7.6";
-#endif /* !defined NOID */
-#endif /* !defined lint */
-
-/*LINTLIBRARY*/
-
-#include "private.h"
-#include "tzfile.h"
-
-/*
-** A la X3J11, with core dump avoidance.
-*/
-
-char *
-asctime(timeptr)
-register const struct tm *     timeptr;
-{
-       static const char       wday_name[][3] = {
-               "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
-       };
-       static const char       mon_name[][3] = {
-               "Jan", "Feb", "Mar", "Apr", "May", "Jun",
-               "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
-       };
-       /*
-       ** Big enough for something such as
-       ** ??? ???-2147483648 -2147483648:-2147483648:-2147483648 -2147483648\n
-       ** (two three-character abbreviations, five strings denoting integers,
-       ** three explicit spaces, two explicit colons, a newline,
-       ** and a trailing ASCII nul).
-       */
-       static char             result[3 * 2 + 5 * INT_STRLEN_MAXIMUM(int) +
-                                       3 + 2 + 1 + 1];
-       register const char *   wn;
-       register const char *   mn;
-
-       if (timeptr->tm_wday < 0 || timeptr->tm_wday >= DAYSPERWEEK)
-               wn = "???";
-       else    wn = wday_name[timeptr->tm_wday];
-       if (timeptr->tm_mon < 0 || timeptr->tm_mon >= MONSPERYEAR)
-               mn = "???";
-       else    mn = mon_name[timeptr->tm_mon];
-       /*
-       ** The X3J11-suggested format is
-       **      "%.3s %.3s%3d %02.2d:%02.2d:%02.2d %d\n"
-       ** Since the .2 in 02.2d is ignored, we drop it.
-       */
-       (void) sprintf(result, "%.3s %.3s%3d %02d:%02d:%02d %d\n",
-               wn, mn,
-               timeptr->tm_mday, timeptr->tm_hour,
-               timeptr->tm_min, timeptr->tm_sec,
-               TM_YEAR_BASE + timeptr->tm_year);
-       return result;
-}
diff --git a/time/asia b/time/asia
deleted file mode 100644 (file)
index 78ecb30..0000000
--- a/time/asia
+++ /dev/null
@@ -1,803 +0,0 @@
-# @(#)asia     7.12
-
-# This data is by no means authoritative; if you think you know better,
-# go ahead and edit the file (and please send any changes to
-# tz@elsie.nci.nih.gov for general use in the future).
-
-# From Paul Eggert <eggert@twinsun.com> (August 18, 1994):
-#
-# A good source for time zone historical data outside the U.S. is
-# Thomas G. Shanks, The International Atlas (3rd edition),
-# San Diego: ACS Publications, Inc. (1991).
-# Except where otherwise noted, it is the source for the data below.
-#
-# Another source occasionally used is Edward W. Whitman, World Time Differences,
-# Whitman Publishing Co, 2 Niagara Av, Ealing, London (undated), which
-# I found in the UCLA library.
-#
-# A reliable and entertaining source about time zones is
-# Derek Howse, Greenwich time and the discovery of the longitude,
-# Oxford University Press (1980).
-#
-# I invented the abbreviations marked `*' in the following table;
-# the rest are from earlier versions of this file, or from other sources.
-# Corrections are welcome!
-#              std dst
-#              LMT     Local Mean Time
-#              LST     Local Star Time (Russian ``mestnoe zvezdnoe vremya'')
-#      2:00    EET  EET DST    Eastern European Time
-#      2:00    IST IDT Israel
-#      3:00    AST ADT Arabia*
-#      3:00    MSK MSD Moscow
-#      3:30    IST IDT Iran
-#      4:00    BSK BSD Baku*
-#      4:00    GST GDT Gulf*
-#      4:30    AFT     Afghanistan*
-#      5:00    ASK ASD Ashkhabad*
-#      5:00    PKT     Pakistan*
-#      5:30    IST IST India
-#      5:45    NPT     Nepal*
-#      6:00    BGT     Bengal, Bangladesh*
-#      6:00    TSK TSD Tashkent*
-#      6:30    BMT     Burma*
-#      7:00    ICT     Indochina*
-#      7:00    JVT     Java*
-#      8:00    BNT     Borneo, Brunei*
-#      8:00    CST CDT China
-#      8:00    HKT HKST Hong Kong
-#      8:00    PST PDT Philippines*
-#      8:00    SGT     Singapore
-#      8:00    UST UDT Ulan Bator*
-#      9:00    JST     Japan
-#      9:00    KST KDT Korea
-#      9:00    MLT     Moluccas*
-#      9:30    CST     Australian Central Standard Time
-#
-# See the `europe' file for Russia and Turkey in Asia.
-#
-# See the `africa' file for Zone naming conventions.
-
-# From Guy Harris:
-# Incorporates data for Singapore from Robert Elz' asia 1.1, as well as
-# additional information from Tom Yap, Sun Microsystems Intercontinental
-# Technical Support (including a page from the Official Airline Guide -
-# Worldwide Edition).  The names for time zones are guesses.
-
-###############################################################################
-
-# From Paul Eggert <eggert@twinsun.com> (May 28, 1994):
-# We don't know what happened to the clocks in the Caucausus and the ex-Soviet
-# Central Asia after 1990.  Until we get more info, stick with the pre-1991 rules.
-# Rule NAME    FROM    TO      TYPE    IN      ON      AT      SAVE    LETTER/S
-Rule   Russia  1981    1984    -       Apr     1       0:00    1:00    D
-Rule   Russia  1981    1983    -       Oct     1       0:00    0       K
-Rule   Russia  1984    max     -       Sep     lastSun 3:00    0       K
-Rule   Russia  1985    max     -       Mar     lastSun 2:00    1:00    D
-
-# Afghanistan
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Asia/Kabul      4:36:48 -       LMT     1890
-                       4:00    -       GST     1945
-                       4:30    -       AFT
-
-# Armenia
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Asia/Yerevan    2:58:00 -       LMT     1924 May  2
-                       3:00    -       MSK     1957 Mar
-                       4:00    Russia  BS%s
-
-# Azerbaijan
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Asia/Baku       3:19:24 -       LMT     1924 May  2
-                       3:00    -       MSK     1957 Mar
-                       4:00    Russia  BS%s
-
-# Bahrain
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Asia/Bahrain    3:22:20 -       LMT     1920            # Al-Manamah
-                       4:00    -       GST     1972 Jun
-                       3:00    -       AST
-
-# Bangladesh
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Asia/Dacca      6:01:40 -       LMT     1890
-                       5:53    -       CMT     1941 Oct    # Calcutta Mean Time
-                       6:30    -       BMT     1942 May 15
-                       5:30    -       IST     1942 Sep
-                       6:30    -       BMT     1951 Sep 30
-                       6:00    -       BGT
-
-# Bhutan
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Asia/Thimbu     5:58:36 -       LMT     1947 Aug 15
-                       5:30    -       IST     1987 Oct
-                       6:00    -       BGT
-
-# British Indian Ocean Territory
-# From Whitman:
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Indian/Chagos   5:00    -       PKT
-
-# Brunei
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Asia/Brunei     7:39:40 -       LMT     1926 Mar   # Bandar Seri Begawan
-                       7:30    -       BNT     1933
-                       8:00    -       BNT
-
-# Burma
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Asia/Rangoon    6:24:40 -       LMT     1880
-                       6:25    -       RMT     1920
-                       6:30    -       BMT     1942 May
-                       9:00    -       JST     1945 May 3
-                       6:30    -       BMT
-
-# Cambodia
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Asia/Phnom_Penh 6:59:40 -       LMT     1906 Jun  9
-                       7:06    -       SMT     1911 Mar 11 0:01     # Saigon MT
-                       7:00    -       ICT     1912 May
-                       8:00    -       ICT     1931 May
-                       7:00    -       ICT
-
-# People's Republic of China
-
-# From Guy Harris:
-# People's Republic of China.  Yes, they really have only one time zone.
-
-# From Bob Devine (January 28, 1988):
-# No they don't.  See TIME mag, February 17, 1986 p.52.  Even though
-# China is across 4 physical time zones, before Feb 1, 1986 only the
-# Peking (Bejing) time zone was recognized.  Since that date, China
-# has two of 'em -- Peking's and Urumqi (named after the capital of
-# the Xinjiang Uighur Autonomous Region).  I don't know about DST for it.
-#
-# . . .I just deleted the DST table and this editor makes it too
-# painful to suck in another copy..  So, here is what I have for
-# DST start/end dates for Peking's time zone (info from AP):
-#
-#     1986 May 4 - Sept 14
-#     1987 mid-April - ??
-
-# From Paul Eggert <eggert@twinsun.com> (November 18, 1993):
-# According to Shanks, China started using DST in 1986,
-# but it's still all one big happy time zone.
-
-# From U. S. Naval Observatory (January 19, 1989):
-# CHINA               8 H  AHEAD OF UTC  ALL OF CHINA, INCL TAIWAN
-# CHINA               9 H  AHEAD OF UTC  APR 17 - SEP 10
-
-# From Paul Eggert <eggert@twinsun.com> (November 18, 1993):
-# Shanks writes that China switched from the Chinese calendar on 1912 Feb 12.
-# He also writes that China has had a single time zone since 1980 May 1,
-# and that they instituted DST on 1986 May 4; this contradicts Devine's
-# note about Time magazine, though apparently _something_ happened in 1986.
-
-# From Shanks (1991):
-# Rule NAME    FROM    TO      TYPE    IN      ON      AT      SAVE    LETTER/S
-Rule   Shang   1928    only    -       Jan      1      0:00    0       S
-Rule   Shang   1940    only    -       Jun      3      0:00    1:00    D
-Rule   Shang   1940    1941    -       Oct      1      0:00    0       S
-Rule   Shang   1941    only    -       Mar     16      0:00    1:00    D
-Rule   PRC     1949    only    -       Jan      1      0:00    0       S
-Rule   PRC     1986    only    -       May      4      0:00    1:00    D
-Rule   PRC     1986    max     -       Sep     Sun>=11 0:00    0       S
-Rule   PRC     1987    max     -       Apr     Sun>=10 0:00    1:00    D
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Asia/Shanghai   8:05:52 -       LMT     1928
-                       8:00    Shang   C%sT    1949
-                       8:00    PRC     C%sT
-
-###############################################################################
-
-# Republic of China
-
-# Rule NAME    FROM    TO      TYPE    IN      ON      AT      SAVE    LETTER/S
-Rule   Taiwan  1896    only    -       Jan     1       0:00    0       S
-Rule   Taiwan  1945    1951    -       May     1       0:00    1:00    D
-Rule   Taiwan  1945    1951    -       Oct     1       0:00    0       S
-Rule   Taiwan  1952    only    -       Mar     1       0:00    1:00    D
-Rule   Taiwan  1952    1954    -       Nov     1       0:00    0       S
-Rule   Taiwan  1953    1959    -       Apr     1       0:00    1:00    D
-Rule   Taiwan  1955    1961    -       Oct     1       0:00    0       S
-Rule   Taiwan  1960    1961    -       Jun     1       0:00    1:00    D
-Rule   Taiwan  1974    1975    -       Apr     1       0:00    1:00    D
-Rule   Taiwan  1974    1975    -       Oct     1       0:00    0       S
-Rule   Taiwan  1980    only    -       Jun     30      0:00    1:00    D
-Rule   Taiwan  1980    only    -       Sep     30      0:00    0       S
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Asia/Taipei     8:06:00 -       LMT     1896
-                       8:00    Taiwan  C%sT
-
-###############################################################################
-# Hong Kong
-# Presumably Hong Kong will have DST again when it merges with China,
-# but it's too early to predict the details.
-# Rule NAME    FROM    TO      TYPE    IN      ON      AT      SAVE    LETTER/S
-Rule   HK      1904    only    -       Oct     30      0:00    0       -
-Rule   HK      1946    only    -       Apr     20      3:30    1:00    S
-Rule   HK      1946    only    -       Dec     1       3:30    0       -
-Rule   HK      1947    only    -       Apr     13      3:30    1:00    S
-Rule   HK      1947    only    -       Dec     30      3:30    0       -
-Rule   HK      1948    only    -       May     2       3:30    1:00    S
-Rule   HK      1948    1952    -       Oct     lastSun 3:30    0       -
-Rule   HK      1949    1953    -       Apr     Sun>=1  3:30    1:00    S
-Rule   HK      1953    only    -       Nov     1       3:30    0       -
-Rule   HK      1954    1964    -       Mar     Sun>=18 3:30    1:00    S
-Rule   HK      1954    only    -       Oct     31      3:30    0       -
-Rule   HK      1955    1964    -       Nov     Sun>=1  3:30    0       -
-Rule   HK      1965    1977    -       Apr     Sun>=16 3:30    1:00    S
-Rule   HK      1965    1977    -       Oct     Sun>=16 3:30    0       -
-Rule   HK      1979    1980    -       May     Sun>=8  3:30    1:00    S
-Rule   HK      1979    1980    -       Oct     Sun>=16 3:30    0       -
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Asia/Hong_Kong  7:36:36 -       LMT     1904 Oct 30
-                       8:00    HK      HK%sT
-
-# Macao
-# Presumably Macao will have DST again when it merges with China,
-# but it's too early to predict the details.
-# Rule NAME    FROM    TO      TYPE    IN      ON      AT      SAVE    LETTER/S
-Rule   Macao   1912    only    -       Jan     1       0:00    0       S
-Rule   Macao   1961    1962    -       Mar     Sun>=16 3:30    1:00    D
-Rule   Macao   1961    1964    -       Nov     Sun>=1  3:30    0       S
-Rule   Macao   1963    only    -       Mar     Sun>=16 0:00    1:00    D
-Rule   Macao   1964    only    -       Mar     Sun>=16 3:30    1:00    D
-Rule   Macao   1965    only    -       Mar     Sun>=16 0:00    1:00    D
-Rule   Macao   1965    only    -       Oct     31      0:00    0       S
-Rule   Macao   1966    1971    -       Apr     Sun>=16 3:30    1:00    D
-Rule   Macao   1966    1971    -       Oct     Sun>=16 3:30    0       S
-Rule   Macao   1972    1974    -       Apr     Sun>=15 0:00    1:00    D
-Rule   Macao   1972    1973    -       Oct     Sun>=15 0:00    0       S
-Rule   Macao   1974    1977    -       Oct     Sun>=15 3:30    0       S
-Rule   Macao   1975    1977    -       Apr     Sun>=15 3:30    1:00    D
-Rule   Macao   1978    1980    -       Apr     Sun>=15 0:00    1:00    D
-Rule   Macao   1978    1980    -       Oct     Sun>=15 0:00    0       S
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Asia/Macao      7:34:20 -       LMT     1912
-                       8:00    Macao   C%sT
-
-
-###############################################################################
-
-# Cyprus
-# Rule NAME    FROM    TO      TYPE    IN      ON      AT      SAVE    LETTER/S
-Rule   Cyprus  1921    only    -       Nov     14      0:00    0       -
-Rule   Cyprus  1975    only    -       Apr     13      0:00    1:00    " DST"
-Rule   Cyprus  1975    only    -       Oct     12      0:00    0       -
-Rule   Cyprus  1976    only    -       May     15      0:00    1:00    " DST"
-Rule   Cyprus  1976    only    -       Oct     11      0:00    0       -
-Rule   Cyprus  1977    1980    -       Apr     Sun>=1  0:00    1:00    " DST"
-Rule   Cyprus  1977    only    -       Sep     25      0:00    0       -
-Rule   Cyprus  1978    only    -       Oct     2       0:00    0       -
-Rule   Cyprus  1979    max     -       Sep     lastSun 0:00    0       -
-Rule   Cyprus  1981    max     -       Mar     lastSun 0:00    1:00    " DST"
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Asia/Nicosia    2:13:28 -       LMT     1921 Nov 14
-                       2:00    Cyprus  EET%s
-
-# Georgia
-# From Paul Eggert <eggert@twinsun.com> (1994-11-19):
-# Today's _Economist_ (p 60) reports that Georgia moved its clocks forward
-# an hour recently, due to a law proposed by Zurab Murvanidze,
-# an MP who went on a hunger strike for 11 days to force discussion about it!
-# Alas, we have no details.
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Asia/Tbilisi    2:59:16 -       LMT     1880
-                       2:59    -       LST     1924 May  2
-                       3:00    -       MSK     1957 Mar
-                       4:00    Russia  BS%s
-
-# India
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Asia/Calcutta   5:53:28 -       LMT     1880
-                       5:53    -       CMT     1941 Oct    # Calcutta Mean Time
-                       6:30    -       BMT     1942 May 15
-                       5:30    -       IST     1942 Sep
-                       5:30    1:00    IST     1945 Oct 15
-                       5:30    -       IST
-# The following are like Asia/Calcutta:
-#      Andaman Is
-#      Lakshadweep (Laccadive, Minicoy and Amindivi Is)
-#      Nicobar Is
-
-# Indonesia
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone Asia/Jakarta      7:07:12 -       LMT     1867 Aug 10
-                       7:07    -       JMT     1924 Jan  1 0:13
-                       7:20    -       JVT     1932 Nov
-                       7:30    -       JVT     1942 Mar 23
-                       9:00    -       JST     1945 Aug
-                       7:30    -       JVT     1948 May
-                       8:00    -       JVT     1950 May
-                       7:30    -       JVT     1964
-                       7:00    -       JVT
-Zone Asia/Ujung_Pandang 7:57:36 -      LMT     1920
-                       7:58    -       MMT     1932 Nov    # Macassar Mean Time
-                       8:00    -       BNT     1942 Feb  9
-                       9:00    -       JST     1945 Aug
-                       8:00    -       BNT
-Zone Asia/Jayapura     9:22:48 -       LMT     1932 Nov
-                       9:00    -       MLT     1944
-                       9:30    -       CST     1964
-                       9:00    -       MLT
-
-# Iran
-
-# Shanks has no record of DST after 1980.
-
-# From Bob Devine (January 28, 1988):
-# Iran: Last Sunday in March to third (?) Sunday in
-# September.  Since the revolution, the official calendar is Monarchic
-# calendar; I have no idea what the correspondence between dates are.
-
-# From U. S. Naval Observatory (January 19, 1989):
-# IRAN                3.5H AHEAD OF UTC
-
-# From Shanks (1991), with corrections from Devine:
-# Rule NAME    FROM    TO      TYPE    IN      ON      AT      SAVE    LETTER/S
-Rule   Iran    1977    only    -       Nov     1       0:00    0       S
-Rule   Iran    1978    1980    -       Mar     21      0:00    1:00    D
-Rule   Iran    1978    only    -       Oct     21      0:00    0       S
-Rule   Iran    1979    only    -       Sep     19      0:00    0       S
-Rule   Iran    1980    only    -       Sep     23      0:00    0       S
-Rule   Iran    1988    max     -       Mar     lastSun 2:00    1:00    D
-Rule   Iran    1988    max     -       Sep     Sun>=15 2:00    0       S
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Asia/Tehran     3:25:44 -       LMT     1916
-                       3:26    -       TMT     1946
-                       3:30    -       IST     1977 Nov
-                       4:00    Iran    G%sT    1979
-                       3:30    Iran    I%sT
-
-# Iraq
-# Rule NAME    FROM    TO      TYPE    IN      ON      AT      SAVE    LETTER/S
-Rule   Iraq    1982    only    -       May     1       0:00    1:00    D
-Rule   Iraq    1982    1984    -       Oct     1       0:00    0       S
-Rule   Iraq    1983    only    -       Mar     31      0:00    1:00    D
-Rule   Iraq    1984    1985    -       Apr     1       0:00    1:00    D
-Rule   Iraq    1985    max     -       Sep     lastSun 1:00s   0       S
-Rule   Iraq    1986    max     -       Mar     lastSun 1:00s   1:00    D
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Asia/Baghdad    2:57:40 -       LMT     1890
-                       2:58    -       BMT     1918        # Baghdad Mean Time
-                       3:00    -       AST     1982 May
-                       3:00    Iraq    A%sT
-
-
-###############################################################################
-
-# Israel
-
-# From U. S. Naval Observatory (January 19, 1989):
-# ISRAEL              2 H  AHEAD OF UTC
-# ISRAEL              3 H  AHEAD OF UTC  APR 10 - SEP 3
-
-# From Paul Eggert <eggert@twinsun.com> (November 18, 1993):
-#
-# Shanks gives the following rules for Jerusalem from 1918 through 1991.
-# After 1989 Shanks often disagrees with Silverberg; we go with Silverberg.
-
-# From Shanks (1991):
-# Rule NAME    FROM    TO      TYPE    IN      ON      AT      SAVE    LETTER/S
-Rule   Zion    1918    only    -       Jan      1      0:00    0       S
-Rule   Zion    1940    only    -       Jun      1      0:00    1:00    D
-Rule   Zion    1942    1944    -       Nov      1      0:00    0       S
-Rule   Zion    1943    only    -       Apr      1      2:00    1:00    D
-Rule   Zion    1944    only    -       Apr      1      0:00    1:00    D
-Rule   Zion    1945    only    -       Apr     16      0:00    1:00    D
-Rule   Zion    1945    only    -       Nov      1      2:00    0       S
-Rule   Zion    1946    only    -       Apr     16      2:00    1:00    D
-Rule   Zion    1946    only    -       Nov      1      0:00    0       S
-Rule   Zion    1948    only    -       May     23      0:00    2:00    DD
-Rule   Zion    1948    only    -       Sep      1      0:00    1:00    D
-Rule   Zion    1948    1949    -       Nov      1      2:00    0       S
-Rule   Zion    1949    only    -       May      1      0:00    1:00    D
-Rule   Zion    1950    only    -       Apr     16      0:00    1:00    D
-Rule   Zion    1950    only    -       Sep     15      3:00    0       S
-Rule   Zion    1951    only    -       Apr      1      0:00    1:00    D
-Rule   Zion    1951    only    -       Nov     11      3:00    0       S
-Rule   Zion    1952    only    -       Apr     20      2:00    1:00    D
-Rule   Zion    1952    only    -       Oct     19      3:00    0       S
-Rule   Zion    1953    only    -       Apr     12      2:00    1:00    D
-Rule   Zion    1953    only    -       Sep     13      3:00    0       S
-Rule   Zion    1954    only    -       Jun     13      0:00    1:00    D
-Rule   Zion    1954    only    -       Sep     12      0:00    0       S
-Rule   Zion    1955    only    -       Jun     11      2:00    1:00    D
-Rule   Zion    1955    only    -       Sep     11      0:00    0       S
-Rule   Zion    1956    only    -       Jun      3      0:00    1:00    D
-Rule   Zion    1956    only    -       Sep     30      3:00    0       S
-Rule   Zion    1957    only    -       Apr     29      2:00    1:00    D
-Rule   Zion    1957    only    -       Sep     22      0:00    0       S
-Rule   Zion    1974    only    -       Jul      7      0:00    1:00    D
-Rule   Zion    1974    only    -       Oct     13      0:00    0       S
-Rule   Zion    1975    only    -       Apr     20      0:00    1:00    D
-Rule   Zion    1975    only    -       Aug     31      0:00    0       S
-Rule   Zion    1985    only    -       Apr     14      0:00    1:00    D
-Rule   Zion    1985    only    -       Sep     15      0:00    0       S
-Rule   Zion    1986    only    -       May     18      0:00    1:00    D
-Rule   Zion    1986    only    -       Sep      7      0:00    0       S
-Rule   Zion    1987    only    -       Apr     15      0:00    1:00    D
-Rule   Zion    1987    only    -       Sep     13      0:00    0       S
-Rule   Zion    1988    only    -       Apr      9      0:00    1:00    D
-Rule   Zion    1988    only    -       Sep      3      0:00    0       S
-#Rule  Zion    1989    only    -       Apr     29      0:00    1:00    D
-#Rule  Zion    1989    only    -       Sep      2      0:00    0       S
-#Rule  Zion    1990    only    -       Mar     25      0:00    1:00    D
-#Rule  Zion    1990    only    -       Aug     26      0:00    0       S
-#Rule  Zion    1991    only    -       Mar     10      0:00    1:00    D
-#Rule  Zion    1991    only    -       Sep      1      0:00    0       S
-
-# From Ephraim Silverberg (September 5, 1993):
-#
-# According to the Office of the Secretary General of the Ministry of
-# Interior, there is NO set rule for Daylight-Savings/Standard time changes.
-# Each year they decide anew what havoc to wreak on the country.  However,
-# there is a "supposed" set of rules which is subject to change depending
-# on the party the Minister of Interior, the size of the coalition
-# government, the phase of the moon and the direction of the wind.  Hence,
-# changes may need to be made on a semi-annual basis.  One thing is entrenched
-# in law, however: that there must be at least 150 days on daylight savings
-# time annually.
-
-# Rule NAME    FROM    TO      TYPE    IN      ON      AT      SAVE    LETTER/S
-Rule   Zion    1989    only    -       Apr     30      0:00    1:00    D
-Rule   Zion    1989    only    -       Sep      3      0:00    0:00    S
-Rule   Zion    1990    only    -       Mar     25      0:00    1:00    D
-Rule   Zion    1990    only    -       Aug     26      0:00    0:00    S
-Rule   Zion    1991    only    -       Mar     24      0:00    1:00    D
-Rule   Zion    1991    only    -       Sep      1      0:00    0:00    S
-Rule   Zion    1992    only    -       Mar     29      0:00    1:00    D
-Rule   Zion    1992    only    -       Sep      6      0:00    0:00    S
-Rule   Zion    1993    only    -       Apr      2      0:00    1:00    D
-Rule   Zion    1993    only    -       Sep      5      0:00    0:00    S
-
-# The dates for 1994-1995 were obtained from Office of the Spokeswoman for
-# the Ministry of Interior, Jerusalem.  There are no dates yet for 1996 and
-# beyond so your guess is as good as theirs (those who are interested can
-# call 972-2-701411 and ask for the spokeswoman).
-
-# Rule NAME    FROM    TO      TYPE    IN      ON      AT      SAVE    LETTER/S
-Rule    Zion    1994    only    -       Apr      1      0:00    1:00    D
-Rule    Zion    1994    only    -       Aug     28      0:00    0:00    S
-Rule    Zion    1995    only    -       Mar     31      0:00    1:00    D
-Rule    Zion    1995    only    -       Aug     27      0:00    0:00    S
-
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Asia/Tel_Aviv   2:19:04 -       LMT     1880
-                       2:21    -       JMT     1918
-                       2:00    Zion    I%sT
-
-
-###############################################################################
-
-# Japan
-
-# `9:00' and `JST' is from Guy Harris.
-
-# From Paul Eggert <eggert@twinsun.com> (November 18, 1993):
-# Shanks says that the far southern Ryukyu Is (Nansei-Shoto) are 8:00,
-# but we don't have a good location name for them;
-# we don't even know the name of the principal town.
-# There is no information for Marcus.
-# Other Japanese possessions are probably like Asia/Tokyo.
-
-# From Shanks (1991):
-# Japan switched from the Japanese calendar on 1893 Jan 1.
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Asia/Tokyo      9:19:04 -       LMT     1896
-                       9:00    -       JST
-#Zone Asia/South_Ryukyu        8:14:44 -       LMT     1896    # Amitori
-#                      8:00    -       CST
-
-# Jordan
-# From Paul Eggert <eggert@twinsun.com> (November 18, 1993):
-# Most likely Shanks is merely guessing dates from 1992 on.
-# From Shanks (1991):
-# Rule NAME    FROM    TO      TYPE    IN      ON      AT      SAVE    LETTER/S
-Rule    Jordan 1931    only    -       Jan     1       0:00    0       -
-Rule    Jordan 1973    only    -       Jun     6       0:00    1:00    " DST"
-Rule    Jordan 1973    1975    -       Oct     1       0:00    0       -
-Rule    Jordan 1974    1977    -       May     1       0:00    1:00    " DST"
-Rule    Jordan 1976    only    -       Nov     1       0:00    0       -
-Rule    Jordan 1977    only    -       Oct     1       0:00    0       -
-Rule    Jordan 1978    only    -       Apr     30      0:00    1:00    " DST"
-Rule    Jordan 1978    only    -       Sep     30      0:00    0       -
-Rule    Jordan 1985    only    -       Apr     1       0:00    1:00    " DST"
-Rule    Jordan 1985    only    -       Oct     1       0:00    0       -
-Rule    Jordan 1986    1988    -       Apr     Fri>=1  0:00    1:00    " DST"
-Rule    Jordan 1986    1990    -       Oct     Fri>=1  0:00    0       -
-Rule    Jordan 1989    only    -       May     8       0:00    1:00    " DST"
-Rule    Jordan 1990    only    -       Apr     27      0:00    1:00    " DST"
-Rule    Jordan 1991    only    -       Apr     19      0:00    1:00    " DST"
-Rule    Jordan 1991    only    -       Sep     27      0:00    0       -
-Rule    Jordan 1992    max     -       Apr     Fri>=1  0:00    1:00    " DST"
-Rule    Jordan 1992    max     -       Oct     Fri>=1  0:00    0       -
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Asia/Amman      2:23:44 -       LMT     1931
-                       2:00    Jordan  EET%s
-
-# Kazakhstan
-# From Shanks (1991):
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Asia/Alma-Ata   5:07:48 -       LMT     1924 May  2
-                       5:00    -       TSK     1957 Mar
-                       6:00    Russia  TS%s
-
-# Kirgizstan
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Asia/Bishkek    4:58:24 -       LMT     1924 May  2
-                       5:00    -       TSK     1957 Mar
-                       6:00    Russia  TS%s
-
-###############################################################################
-
-# Korea
-
-# From Guy Harris:
-# According to someone at the Korean Times in San Francisco,
-# Daylight Savings Time was not observed until 1987.  He did not know
-# at what time of day DST starts or ends.
-
-# From Shanks (1991):
-# Rule NAME    FROM    TO      TYPE    IN      ON      AT      SAVE    LETTER/S
-Rule   ROK     1960    only    -       May     15      0:00    1:00    D
-Rule   ROK     1960    only    -       Sep     13      0:00    0       S
-Rule   ROK     1987    1988    -       May     Sun<=14 0:00    1:00    D
-Rule   ROK     1987    1988    -       Oct     Sun<=14 0:00    0       S
-
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Asia/Seoul      8:27:52 -       LMT     1890
-                       8:30    -       KST     1904 Dec
-                       9:00    -       KST     1928
-                       8:30    -       KST     1932
-                       9:00    -       KST     1954 Mar 21
-                       8:00    ROK     K%sT    1961 Aug 10
-                       8:30    -       KST     1968 Oct
-                       9:00    ROK     K%sT
-Zone   Asia/Pyongyang  8:23:00 -       LMT     1890
-                       8:30    -       KST     1904 Dec
-                       9:00    -       KST     1928
-                       8:30    -       KST     1932
-                       9:00    -       KST     1954 Mar 21
-                       8:00    -       KST     1961 Aug 10
-                       9:00    -       KST
-
-###############################################################################
-
-# Kuwait
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Asia/Kuwait     3:11:56 -       LMT     1950
-                       3:00    -       AST
-
-# Laos
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Asia/Vientiane  6:50:24 -       LMT     1906 Jun  9
-                       7:06    -       SMT     1911 Mar 11 0:01     # Saigon MT
-                       7:00    -       ICT     1912 May
-                       8:00    -       ICT     1931 May
-                       7:00    -       ICT
-
-# Lebanon
-# Rule NAME    FROM    TO      TYPE    IN      ON      AT      SAVE    LETTER/S
-Rule   Lebanon 1880    only    -       Jan     1       0:00    0       -
-Rule   Lebanon 1920    only    -       Mar     28      0:00    1:00    " DST"
-Rule   Lebanon 1920    only    -       Oct     25      0:00    0       -
-Rule   Lebanon 1921    only    -       Apr     3       0:00    1:00    " DST"
-Rule   Lebanon 1921    only    -       Oct     3       0:00    0       -
-Rule   Lebanon 1922    only    -       Mar     26      0:00    1:00    " DST"
-Rule   Lebanon 1922    only    -       Oct     8       0:00    0       -
-Rule   Lebanon 1923    only    -       Apr     22      0:00    1:00    " DST"
-Rule   Lebanon 1923    only    -       Sep     16      0:00    0       -
-Rule   Lebanon 1957    1961    -       May     1       0:00    1:00    " DST"
-Rule   Lebanon 1957    1961    -       Oct     1       0:00    0       -
-Rule   Lebanon 1972    only    -       Jun     22      0:00    1:00    " DST"
-Rule   Lebanon 1972    1977    -       Oct     1       0:00    0       -
-Rule   Lebanon 1973    1977    -       May     1       0:00    1:00    " DST"
-Rule   Lebanon 1978    only    -       Apr     30      0:00    1:00    " DST"
-Rule   Lebanon 1978    only    -       Sep     30      0:00    0       -
-Rule   Lebanon 1984    1987    -       May     1       0:00    1:00    " DST"
-Rule   Lebanon 1984    max     -       Oct     16      0:00    0       -
-Rule   Lebanon 1988    only    -       Jun     1       0:00    1:00    " DST"
-Rule   Lebanon 1989    only    -       May     10      0:00    1:00    " DST"
-Rule   Lebanon 1990    max     -       May     1       0:00    1:00    " DST"
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Asia/Beirut     2:22:00 -       LMT     1880
-                       2:00    Lebanon EET%s
-
-# Malaysia
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone Asia/Kuala_Lumpur 6:46:48 -       LMT     1880
-                       6:55    -       SMT     1905 Jun
-                       7:00    -       SGT     1933
-                       7:20    -       SGT     1942 Feb 15
-                       9:00    -       JST     1945 Sep 2
-                       7:20    -       SGT     1950
-                       7:30    -       SGT     1982 May
-                       8:00    -       SGT
-
-# Maldives
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Indian/Maldives 4:54:00 -       LMT     1880                    # Male
-                       4:54    -       MMT     1960
-                       5:00    -       PKT
-
-# Mongolia
-# Let's comment out the western and eastern Mongolian time zones
-# till we know what their principal towns are.
-# Rule NAME    FROM    TO      TYPE    IN      ON      AT      SAVE    LETTER/S
-Rule   Mongol  1978    only    -       Jan     1       0:00    0       S
-Rule   Mongol  1981    1984    -       Apr     1       0:00    1:00    T
-Rule   Mongol  1981    1984    -       Oct     1       0:00    0       S
-Rule   Mongol  1985    max     -       Mar     lastSun 2:00    1:00    T
-Rule   Mongol  1985    max     -       Sep     lastSun 3:00    0       S
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-#Zone  Asia/Dariv      6:14:32 -       LMT     1905 Aug
-#                      6:00    -       DST     1978
-#                      7:00    Mongol  D%sT
-Zone   Asia/Ulan_Bator 7:07:32 -       LMT     1905 Aug
-                       7:00    -       UST     1978
-                       8:00    Mongol  U%sT
-#Zone Asia/Baruun-Urt  7:33:00 -       LMT     1905 Aug
-#                      8:00    -       BST     1978
-#                      9:00    Mongol  B%sT
-
-# Nepal
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Asia/Katmandu   5:41:16 -       LMT     1920
-                       5:30    -       IST     1986
-                       5:45    -       NPT
-
-# Oman
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Asia/Muscat     3:54:20 -       LMT     1920
-                       4:00    -       GST
-
-# Pakistan
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Asia/Karachi    4:28:12 -       LMT     1907
-                       5:30    -       IST     1942 Sep
-                       5:30    1:00    IST     1945 Oct 15
-                       5:30    -       IST     1951 Sep 30
-                       5:00    -       PKT
-
-# Palestine
-# These rules for Egypt are stolen from the `africa' file.
-# Rule NAME    FROM    TO      TYPE    IN      ON      AT      SAVE    LETTER/S
-Rule   Egypt   1957    only    -       May     10      0:00    1:00    " DST"
-Rule   Egypt   1957    1958    -       Oct      1      0:00    0       -
-Rule   Egypt   1958    only    -       May      1      0:00    1:00    " DST"
-Rule   Egypt   1959    1981    -       May      1      1:00    1:00    " DST"
-Rule   Egypt   1959    1965    -       Sep     30      3:00    0       -
-Rule   Egypt   1966    max     -       Oct      1      3:00    0       -
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Asia/Gaza       2:17:52 -       LMT     1900 Oct
-                       2:00    -       EET     1957 May 10
-                       2:00    Egypt   EET%s   1967 Jun 30
-                       2:00    Zion    I%sT
-# This will undoubtedly change soon.
-
-# Philippines
-# Howse writes (p 162) that until 1844 the Philippines kept American date.
-# The rest of this data is from Shanks.
-# Rule NAME    FROM    TO      TYPE    IN      ON      AT      SAVE    LETTER/S
-Rule   Phil    1899    only    -       May     11      0:00    0       S
-Rule   Phil    1936    only    -       Nov     1       0:00    1:00    D
-Rule   Phil    1937    only    -       Feb     1       0:00    0       S
-Rule   Phil    1954    only    -       Apr     12      0:00    1:00    D
-Rule   Phil    1954    only    -       Jul     1       0:00    0       S
-Rule   Phil    1978    only    -       Mar     22      0:00    1:00    D
-Rule   Phil    1978    only    -       Sep     21      0:00    0       S
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Asia/Manila     -15:56:00 -     LMT     1844
-                       8:04:00 -       LMT     1899 May 11
-                       8:00    Phil    P%sT    1942 May
-                       9:00    -       JST     1944 Nov
-                       8:00    Phil    P%sT
-
-# Qatar
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Asia/Qatar      3:26:08 -       LMT     1920            # Al Dawhah
-                       4:00    -       GST     1972 Jun
-                       3:00    -       AST
-
-# Saudi Arabia
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Asia/Riyadh     3:06:52 -       LMT     1950
-                       3:00    -       AST
-
-# Singapore
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Asia/Singapore  6:55:24 -       LMT     1880
-                       6:55    -       SMT     1905 Jun
-                       7:00    -       SGT     1933
-                       7:20    -       SGT     1942 Feb 15
-                       9:00    -       JST     1945 Sep  2
-                       7:20    -       SGT     1950
-                       7:30    -       SGT     1982 May
-                       8:00    -       SGT
-
-# Sri Lanka
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Asia/Colombo    5:19:24 -       LMT     1880
-                       5:20    -       JMT     1906
-                       5:30    -       IST     1942 Jan  5
-                       5:30    0:30    IHST    1942 Sep
-                       5:30    1:00    IST     1945 Oct 16 2:00
-                       5:30    -       IST
-
-# Syria
-# Rule NAME    FROM    TO      TYPE    IN      ON      AT      SAVE    LETTER/S
-Rule   Syria   1920    only    -       Jan     1       0:00    0       -
-Rule   Syria   1920    1923    -       Apr     Sun>=15 2:00    1:00    " DST"
-Rule   Syria   1920    1923    -       Oct     Sun>=1  2:00    0       -
-Rule   Syria   1962    only    -       Apr     29      2:00    1:00    " DST"
-Rule   Syria   1962    only    -       Oct     1       2:00    0       -
-Rule   Syria   1963    1965    -       May     1       2:00    1:00    " DST"
-Rule   Syria   1963    only    -       Sep     30      2:00    0       -
-Rule   Syria   1964    only    -       Oct     1       2:00    0       -
-Rule   Syria   1965    only    -       Sep     30      2:00    0       -
-Rule   Syria   1966    only    -       Apr     24      2:00    1:00    " DST"
-Rule   Syria   1966    1976    -       Oct     1       2:00    0       -
-Rule   Syria   1967    1978    -       May     1       2:00    1:00    " DST"
-Rule   Syria   1977    1978    -       Sep     1       2:00    0       -
-Rule   Syria   1983    1984    -       Apr     9       2:00    1:00    " DST"
-Rule   Syria   1983    1984    -       Oct     1       2:00    0       -
-Rule   Syria   1986    only    -       Feb     16      2:00    1:00    " DST"
-Rule   Syria   1986    only    -       Oct     9       2:00    0       -
-Rule   Syria   1987    only    -       Mar     1       2:00    1:00    " DST"
-Rule   Syria   1987    1988    -       Oct     31      2:00    0       -
-Rule   Syria   1988    only    -       Mar     15      2:00    1:00    " DST"
-Rule   Syria   1989    only    -       Mar     31      2:00    1:00    " DST"
-Rule   Syria   1989    only    -       Oct     1       2:00    0       -
-Rule   Syria   1990    max     -       Apr     1       2:00    1:00    " DST"
-Rule   Syria   1990    max     -       Sep     30      2:00    0       -
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Asia/Damascus   2:25:12 -       LMT     1920
-                       2:00    Syria   EET%s
-
-# Tajikistan
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Asia/Dushanbe   4:35:12 -       LMT     1924 May  2
-                       5:00    -       TSK     1957 Mar
-                       6:00    Russia  TS%s
-
-# Thailand
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Asia/Bangkok    6:42:04 -       LMT     1880
-                       6:42    -       BMT     1920 Apr
-                       7:00    -       ICT
-
-# Turkmenistan
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Asia/Ashkhabad  3:53:32 -       LMT     1924 May  2
-                       4:00    -       ASK     1957 Mar
-                       5:00    Russia  AS%s
-
-# United Arab Emirates
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Asia/Dubai      3:41:12 -       LMT     1920
-                       4:00    -       GST
-
-# Uzbekistan
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Asia/Tashkent   4:37:12 -       LMT     1924 May  2
-                       5:00    -       TSK     1957 Mar
-                       6:00    Russia  TS%s
-
-# Vietnam
-# From Paul Eggert <eggert@twinsun.com> (November 18, 1993):
-# Saigon's official name is Thanh-Pho Ho Chi Minh, but it's too long.
-# We'll stick with the traditional name for now.
-# From Shanks (1991):
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Asia/Saigon     7:06:40 -       LMT     1906 Jun  9
-                       7:06    -       SMT     1911 Mar 11 0:01     # Saigon MT
-                       7:00    -       ICT     1912 May
-                       8:00    -       ICT     1931 May
-                       7:00    -       ICT
-
-# Yemen
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Asia/Aden       3:00:48 -       LMT     1950
-                       3:00    -       AST
diff --git a/time/australasia b/time/australasia
deleted file mode 100644 (file)
index f9cde45..0000000
+++ /dev/null
@@ -1,783 +0,0 @@
-# @(#)australasia      7.21
-# This file also includes Pacific islands.
-
-# Notes are at the end of this file
-
-###############################################################################
-
-# Australia
-
-# Rule NAME    FROM    TO      TYPE    IN      ON      AT      SAVE    LETTER/S
-Rule   Aus     1895    only    -       Jan      1      0:00    0       -
-# Shanks gives 1917 Jan 1 0:01; go with Whitman (and guess 2:00).
-Rule   Aus     1916    only    -       Oct      1      2:00    1:00    -
-Rule   Aus     1917    only    -       Mar     25      2:00    0       -
-Rule   Aus     1942    only    -       Jan      1      2:00    1:00    -
-Rule   Aus     1942    only    -       Mar     29      2:00    0       -
-Rule   Aus     1942    only    -       Sep     27      2:00    1:00    -
-Rule   Aus     1943    1944    -       Mar     lastSun 2:00    0       -
-Rule   Aus     1943    only    -       Oct      3      2:00    1:00    -
-# Whitman says W Australia didn't use DST in 1943/1944, and that
-# 1944/1945 was just like 1943/1944; go with Shanks.
-
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-# Northern Territory
-Zone Australia/Darwin   8:43:20 -      LMT     1895 Feb
-                        9:30   -       CST     1917 Jan 1 0:01
-                        9:30   Aus     CST
-# Western Australia
-Zone Australia/Perth    7:43:24 -      LMT     1895 Dec
-                        8:00   -       WST     1917 Jan 1 0:01
-                        8:00   Aus     WST     1974 Oct lastSun 2:00
-                        8:00   1:00    WST     1975 Mar Sun>=1 3:00
-                        8:00   -       WST     1983 Oct lastSun 2:00
-                        8:00   1:00    WST     1984 Mar Sun>=1 3:00
-                        8:00   -       WST     1991 Nov 17 2:00
-                        8:00   1:00    WST     1992 Mar Sun>=1 3:00
-                        8:00   -       WST
-# Queensland
-Zone Australia/Brisbane        10:12:08 -      LMT     1895
-                       10:00   -       EST     1917 Jan 1 0:01
-                       10:00   Aus     EST     1971 Oct lastSun 2:00
-                       10:00   1:00    EST     1972 Feb lastSun 3:00
-                       10:00   -       EST     1989 Oct lastSun 2:00
-                       10:00   1:00    EST     1990 Mar Sun>=1 3:00
-                       10:00   -       EST     1990 Oct lastSun 2:00
-                       10:00   1:00    EST     1991 Mar Sun>=1 3:00
-                       10:00   -       EST     1991 Oct lastSun 2:00
-                       10:00   1:00    EST     1992 Mar Sun>=1 3:00
-                       10:00   -       EST
-
-# South Australia
-# Rule NAME    FROM    TO      TYPE    IN      ON      AT      SAVE    LETTER/S
-Rule   AS      1971    1985    -       Oct     lastSun 2:00    1:00    -
-Rule   AS      1986    only    -       Oct     19      2:00    1:00    -
-Rule   AS      1987    max     -       Oct     lastSun 2:00    1:00    -
-Rule   AS      1972    only    -       Feb     27      3:00    0       -
-Rule   AS      1973    1985    -       Mar     Sun>=1  3:00    0       -
-Rule   AS      1986    1989    -       Mar     Sun>=15 3:00    0       -
-Rule   AS      1990    1994    even    Mar     Sun>=18 3:00    0       -
-Rule   AS      1990    1994    odd     Mar     Sun>=1  3:00    0       -
-Rule   AS      1995    max     -       Mar     lastSun 3:00    0       -
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone Australia/Adelaide        9:14:20 -       LMT     1895 Feb
-                       9:00    -       CST     1899 May
-                       9:30    -       CST     1917 Jan 1 0:01
-                       9:30    Aus     CST     1971 Oct lastSun 2:00
-                       9:30    AS      CST
-
-# Tasmania
-# Rule NAME    FROM    TO      TYPE    IN      ON      AT      SAVE    LETTER/S
-Rule   AT      1967    only    -       Oct     1       2:00    1:00    -
-Rule   AT      1968    only    -       Mar     31      3:00    0       -
-Rule   AT      1968    1985    -       Oct     lastSun 2:00    1:00    -
-Rule   AT      1969    1971    -       Mar     Sun>=8  3:00    0       -
-Rule   AT      1972    only    -       Feb     27      3:00    0       -
-Rule   AT      1973    1981    -       Mar     Sun>=1  3:00    0       -
-Rule   AT      1982    1983    -       Mar     lastSun 3:00    0       -
-Rule   AT      1984    1986    -       Mar     Sun>=1  3:00    0       -
-Rule   AT      1986    only    -       Oct     19      2:00    1:00    -
-Rule   AT      1987    1990    -       Mar     Sun>=15 3:00    0       -
-Rule   AT      1987    1990    -       Oct     lastSun 2:00    1:00    -
-Rule   AT      1991    max     -       Oct     Sun>=1  2:00    1:00    -
-Rule   AT      1991    max     -       Mar     lastSun 3:00    0       -
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone Australia/Hobart  9:49:16 -       LMT     1895 Sep
-                       10:00   -       EST     1917 Jan 1 0:01
-                       10:00   Aus     EST     1967 Oct 1 2:00
-                       10:00   AT      EST
-
-# Victoria
-# Rule NAME    FROM    TO      TYPE    IN      ON      AT      SAVE    LETTER/S
-Rule   AV      1971    1985    -       Oct     lastSun 2:00    1:00    -
-Rule   AV      1972    only    -       Feb     27      3:00    0       -
-Rule   AV      1973    1985    -       Mar     Sun>=1  3:00    0       -
-Rule   AV      1986    1990    -       Mar     Sun>=15 3:00    0       -
-Rule   AV      1986    only    -       Oct     19      2:00    1:00    -
-Rule   AV      1987    max     -       Oct     lastSun 2:00    1:00    -
-Rule   AV      1991    1994    -       Mar     Sun>=1  3:00    0       -
-Rule   AV      1995    max     -       Mar     lastSun 3:00    0       -
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone Australia/Melbourne 9:39:52 -     LMT     1895 Feb
-                       10:00   -       EST     1917 Jan 1 0:01
-                       10:00   Aus     EST     1971 Oct 31 2:00
-                       10:00   AV      EST
-
-# New South Wales
-# Rule NAME    FROM    TO      TYPE    IN      ON      AT      SAVE    LETTER/S
-Rule   AN      1971    1985    -       Oct     lastSun 2:00    1:00    -
-Rule   AN      1972    only    -       Feb     27      3:00    0       -
-Rule   AN      1973    1985    -       Mar     Sun>=1  3:00    0       -
-Rule   AN      1986    1989    -       Mar     Sun>=15 3:00    0       -
-Rule   AN      1986    only    -       Oct     19      2:00    1:00    -
-Rule   AN      1987    max     -       Oct     lastSun 2:00    1:00    -
-Rule   AN      1990    max     -       Mar     Sun>=1  3:00    0       -
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone Australia/Sydney  10:04:52 -      LMT     1895 Feb
-                       10:00   -       EST     1917 Jan 1 0:01
-                       10:00   Aus     EST     1971 Oct 31 2:00
-                       10:00   AN      EST
-Zone Australia/Broken_Hill 9:25:48 -   LMT     1895 Feb
-                       10:00   -       EST     1896 Aug 23
-                       9:00    -       CST     1899 May
-                       9:30    -       CST     1917 Jan 1 0:01
-                       9:30    Aus     CST     1971 Oct 31 2:00
-                       9:30    AN      CST
-
-# Australian Capital Territory
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone Australia/Canberra         9:56:32 -      LMT     1895 Feb
-                       10:00   -       EST     1917 Jan  1 0:01
-                       10:00   Aus     EST     1971 Oct 31 2:00
-                       10:00   AN      EST     1981 Oct 25 2:00
-                       10:00   1:00    EST     1982 Apr  4 3:00
-                       10:00   AN      EST
-
-# Australian miscellany
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone Australia/Lord_Howe 10:36:20 -    LMT     1895 Feb
-                       10:00   -       EST     1981 Mar
-                       10:30   AN      LHST
-Zone Indian/Christmas  7:02:52 -       LMT     1895 Feb
-                       7:00    -       JVT
-#
-# Ashmore Is, Cartier
-# no information; probably like Australia/Perth
-#
-# Macquarie, Manihiki, Penrhyn, Rakehanga
-# no information
-
-
-# Cook Is
-# Rule NAME    FROM    TO      TYPE    IN      ON      AT      SAVE    LETTER/S
-Rule   Cook    1978    only    -       Nov     12      0:00    0:30    HD
-Rule   Cook    1979    max     -       Mar     Sun>=1  0:00    0       H
-Rule   Cook    1979    max     -       Oct     lastSun 0:00    0:30    HD
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone Pacific/Rarotonga -10:39:04 -     LMT     1901            # Avarua
-                       -10:30  -       CIST    1978 Nov 12     # Cook Is ST
-                       -10:00  Cook    T%sT
-
-# Cocos
-# From USNO (1989):
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Indian/Cocos    6:30    -       CCT
-
-# Fiji
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Pacific/Fiji    11:53:40 -      LMT     1915 Oct 26     # Suva
-                       12:00   -       NZST
-
-# French Polynesia
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Pacific/Gambier  -8:59:48 -     LMT     1912 Oct        # Rikitea
-                        -9:00  -       GBT
-Zone   Pacific/Marquesas -9:18:00 -    LMT     1912 Oct
-                        -9:30  -       MQT
-Zone   Pacific/Tahiti   -9:58:16 -     LMT     1912 Oct        # Papeete
-                       -10:00  -       THT
-
-# Guam
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Pacific/Guam     9:39:00 -      LMT     1901            # Agana
-                       10:00   -       GST
-
-# Howland, Baker
-# no information; probably like Pacific/Samoa
-
-# Jarvis
-# no information; probably like Pacific/Kiritimati
-
-# Johnston
-# no information; probably like Pacific/Honolulu
-
-# Kiribati
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone Pacific/Tarawa     11:32:04 -     LMT     1901            # Bairiki
-                        12:00  -       NZST
-Zone Pacific/Enderbury -11:24:20 -     LMT     1901
-                       -12:00  -       KJT     1979 Oct
-                       -11:00  -       SST
-Zone Pacific/Kiritimati        -10:29:20 -     LMT     1901
-                       -10:40  -       LIT     1979 Oct        # Line Is Time
-                       -10:00  -       THT
-
-# Nauru
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Pacific/Nauru   11:07:40 -      LMT     1921 Jan 15     # Uaobe
-                       11:30   -       NST     1942 Mar 15
-                       9:00    -       JST     1944 Aug 15
-                       11:30   -       NST     1979 May
-                       12:00   -       NZST
-
-# New Caledonia
-# Rule NAME    FROM    TO      TYPE    IN      ON      AT      SAVE    LETTER/S
-Rule   NC      1912    only    -       Jan     13      0:00    0       S
-Rule   NC      1977    1978    -       Dec     Sun>=1  0:00    1:00    D
-Rule   NC      1978    1979    -       Feb     27      0:00    0       S
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Pacific/Noumea  11:05:48 -      LMT     1912 Jan 13
-                       11:00   NC      NC%sT
-
-
-###############################################################################
-
-# New Zealand
-
-# Rule NAME    FROM    TO      TYPE    IN      ON      AT      SAVE    LETTER/S
-Rule   NZ      1868    only    -       Jan     1       0:00    0       S
-# Shanks gives 1927 Nov 6 - 1928 Mar 4, 1928 Oct 14 - 1929 Mar 17,
-# 1929 Oct 13 - 1930 Mar 16; go with Whitman.
-Rule   NZ      1927    only    -       Nov     26      2:00    1:00    D
-Rule   NZ      1928    1929    -       Mar     Sun>=1  2:00    0       S
-Rule   NZ      1928    only    -       Nov      4      2:00    1:00    D
-Rule   NZ      1929    only    -       Oct     30      2:00    1:00    D
-Rule   NZ      1930    1933    -       Mar     Sun>=15 2:00    0       S
-Rule   NZ      1930    1933    -       Oct     Sun>=8  2:00    1:00    D
-# Shanks says DST stopped 1940 Sep lastSun; go with Whitman for war years.
-Rule   NZ      1934    1944    -       Apr     lastSun 2:00    0       S
-Rule   NZ      1934    1944    -       Sep     lastSun 2:00    1:00    D
-Rule   NZ      1974    only    -       Nov      3      2:00s   1:00    D
-Rule   NZ      1975    1988    -       Oct     lastSun 2:00s   1:00    D
-Rule   NZ      1989    only    -       Oct      8      2:00s   1:00    D
-Rule   NZ      1990    max     -       Oct     Sun>=1  2:00s   1:00    D
-Rule   NZ      1975    only    -       Feb     23      2:00s   0       S
-Rule   NZ      1976    1989    -       Mar     Sun>=1  2:00s   0       S
-Rule   NZ      1990    max     -       Mar     Sun>=15 2:00s   0       S
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone Pacific/Auckland  11:39:04 -      LMT     1868
-                                               # Shanks gives 1940 Sep 29 2:00;
-                                               # go with Whitman.
-                       11:30   NZ      NZ%sT   1945 Apr 29 2:00
-                       12:00   NZ      NZ%sT
-Zone Pacific/Chatham   12:45   -       NZ-CHAT
-
-
-# Antipodes Is, Kermadec Is
-# no information; probably like Pacific/Auckland
-
-###############################################################################
-
-
-# Niue
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Pacific/Niue    -11:19:40 -     LMT     1901            # Alofi
-                       -11:20  -       NIT     1951        # Niue I Time
-                       -11:30  -       NIT     1978 Oct 1
-                       -11:00  -       SST
-
-# Norfolk
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Pacific/Norfolk 11:11:52 -      LMT     1901            # Kingston
-                       11:12   -       NMT     1951
-                       11:30   -       NRFT
-
-# Pacific Islands Trust Territories
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone Pacific/Majuro    11:24:48 -      LMT     1901
-                       11:00   -       NCST    1969 Oct
-                       12:00   -       NZST
-Zone Pacific/Kwajalein 11:09:20 -      LMT     1901
-                       11:00   -       NCST    1969 Oct
-                       -12:00  -       KJT     1993 Aug 20
-                       12:00   -       NZST
-Zone Pacific/Truk      10:07:08 -      LMT     1901
-                       10:00   -       GST     1978 Oct
-                       11:00   -       NCST
-Zone Pacific/Ponape    10:33:00 -      LMT     1901
-                       11:00   -       NCST
-Zone Pacific/Yap       9:12:24 -       LMT     1901
-                       9:00    -       PLT     1969 Oct
-                       10:00   -       GST
-
-# Palau
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone Pacific/Palau     8:57:56 -       LMT     1901            # Koror
-                       9:00    -       PLT
-
-# Palmyra
-# no information; probably like Pacific/Kiritmati
-
-# Papua New Guinea
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone Pacific/Port_Moresby 9:48:40 -    LMT     1880
-                       9:49    -       PMMT    1895
-                       10:00   -       EST
-
-# Pitcairn
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone Pacific/Pitcairn  -8:40:20 -      LMT     1901            # Adamstown
-                       -8:30   -       PIT
-
-# Solomon Is
-# excludes Bougainville, for which see Papua New Guinea
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone Pacific/Guadalcanal 10:39:48 -    LMT     1912 Oct        # Honiara
-                       11:00   -       NCST
-
-# Tokelau Is
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Pacific/Fakaofo -11:24:56 -     LMT     1901
-                       -10:00  -       THT
-
-# Tonga
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone Pacific/Tongatapu 12:19:20 -      LMT     1901
-                       12:20   -       TMT     1968 Oct
-                       13:00   -       TGT
-
-# Tuvalu
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone Pacific/Funafuti  11:56:52 -      LMT     1901
-                       12:00   -       NZST
-
-# Vanuatu
-# Rule NAME    FROM    TO      TYPE    IN      ON      AT      SAVE    LETTER/S
-Rule   Vanuatu 1912    only    -       Jan     13      0:00    0       S
-Rule   Vanuatu 1983    only    -       Sep     25      0:00    1:00    D
-Rule   Vanuatu 1984    max     -       Mar     Sun>=23 0:00    0       S
-Rule   Vanuatu 1984    only    -       Oct     23      0:00    1:00    D
-Rule   Vanuatu 1985    max     -       Sep     Sun>=23 0:00    1:00    D
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Pacific/Efate   11:13:16 -      LMT     1912 Jan 13             # Vila
-                       11:00   -       NCST
-
-# Wake
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Pacific/Wake    11:06:28 -      LMT     1901
-                       12:00   -       NZST
-
-# Wallis and Futuna
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Pacific/Wallis  12:15:20 -      LMT     1901
-                       12:00   -       NZST
-
-# Western Samoa
-# See Pacific/Samoa in the `northamerica' file, of all places.
-
-###############################################################################
-
-# NOTES
-
-# This data is by no means authoritative; if you think you know better,
-# go ahead and edit the file (and please send any changes to
-# tz@elsie.nci.nih.gov for general use in the future).
-
-# From Paul Eggert <eggert@twinsun.com> (August 18, 1994):
-# A good source for time zone historical data outside the U.S. is
-# Thomas G. Shanks, The International Atlas (3rd edition),
-# San Diego: ACS Publications, Inc. (1991).
-# Except where noted, it is the source for the data above.
-#
-# Another source occasionally used is Edward W. Whitman, World Time Differences,
-# Whitman Publishing Co, 2 Niagara Av, Ealing, London (undated), which
-# I found in the UCLA library.
-#
-# A reliable and entertaining source about time zones is
-# Derek Howse, Greenwich time and the discovery of the longitude,
-# Oxford University Press (1980).
-#
-# I invented the abbreviations marked `*' in the following table;
-# the rest are from earlier versions of this file, or from other sources.
-# Corrections are welcome!
-#              std dst
-#              LMT     Local Mean Time
-#        6:30  CCT     Cocos*
-#        7:00  JVT     Java*
-#        8:00  WST WST Western Australia
-#        9:00  JST     Japan
-#        9:00  PLT     Palau*
-#        9:30  CST CST Central Australia
-#       10:00  EST EST Eastern Australia
-#       10:00  GST     Guam*
-#       10:30  LHST LHST Lord Howe*
-#       11:00  NCST NCDT New Caledonia*
-#       11:30  NRFT    Norfolk*
-#       12:00  NZST NZDT New Zealand
-#       12:45  NZ-CHAT Chatham
-#       13:00  TGT     Tongatapu*
-#      -12:00  KJT     Kwajalein (no longer used)*
-#      -11:00  SST     Samoa
-#      -10:40  LIT     Line Is (no longer used)*
-#      -10:00  THT     Tahiti*
-#      - 9:30  MQT     Marquesas*
-#      - 9:00  GBT     Gambier*
-#      - 8:30  PIT     Pitcairn*
-#
-# See the `northamerica' file for Hawaii and Samoa.
-# See the `southamerica' file for Easter I and the Galapagos Is.
-#
-# See the `africa' file for Zone naming conventions.
-
-###############################################################################
-
-# Australia
-
-# From John Mackin (March 6, 1991):
-# We in Australia have _never_ referred to DST as `daylight' time.
-# It is called `summer' time.  Now by a happy coincidence, `summer'
-# and `standard' happen to start with the same letter; hence, the
-# abbreviation does _not_ change...
-# The legislation does not actually define abbreviations, at least
-# in this State, but the abbreviation is just commonly taken to be the
-# initials of the phrase, and the legislation here uniformly uses
-# the phrase `summer time' and does not use the phrase `daylight
-# time'.
-# Announcers on the Commonwealth radio network, the ABC (for Australian
-# Broadcasting Commission), use the phrases `Eastern Standard Time'
-# or `Eastern Summer Time'.  (Note, though, that as I say in the
-# current australasia file, there is really no such thing.)  Announcers
-# on its overseas service, Radio Australia, use the same phrases
-# prefixed by the word `Australian' when referring to local times;
-# time announcements on that service, naturally enough, are made in UTC.
-
-# From Arthur David Olson (March 8 1992):
-# Given the above, what's chosen for year-round use is:
-#      CST     for any place operating at a GMTOFF of 9:30
-#      WST     for any place operating at a GMTOFF of 8:00
-#      EST     for any place operating at a GMTOFF of 10:00
-
-# From Paul Eggert (November 8, 1994):
-# Shanks reports 2:00 for all autumn changes in Australia and New Zealand.
-# Mark Prior <mrp@itd.adelaide.edu.au> writes that his newspaper
-# reports that NSW's fall 1995 change will occur at 2:00,
-# but Robert Elz says it's been 3:00 in Victoria since 1970
-# and perhaps the newspaper's `2:00' is referring to standard time.
-# And Robert Uzgalis <buz@cs.aukuni.ac.nz> says that the New Zealand Daylight
-# Savings Time Order in Council dated 1990-06-18 specifies 2:00 standard
-# time on both the first Sunday in October and the third Sunday in March.
-# For now we'll continue to assume 3:00 for changes since 1970.
-
-# Northern Territory
-
-# From George Shepherd via Simon Woodhead via Robert Elz (March 6, 1991):
-# # The NORTHERN TERRITORY..  [ Courtesy N.T. Dept of the Chief Minister ]
-# #                                    [ Nov 1990 ]
-# #    N.T. have never utilised any DST due to sub-tropical/tropical location.
-# ...
-# Zone        Australia/North         9:30    -       CST
-
-# From Bradley White (March 4, 1991):
-# A recent excerpt from an Australian newspaper...
-# the Northern Territory do[es] not have daylight saving.
-
-# Western Australia
-
-# From George Shepherd via Simon Woodhead via Robert Elz (March 6, 1991):
-# #  The state of WESTERN AUSTRALIA..  [ Courtesy W.A. dept Premier+Cabinet ]
-# #                                            [ Nov 1990 ]
-# #    W.A. suffers from a great deal of public and political opposition to
-# #    DST in principle. A bill is brought before parliament in most years, but
-# #    usually defeated either in the upper house, or in party caucus
-# #    before reaching parliament.
-# ...
-# Zone Australia/West          8:00    AW      %sST
-# ...
-# Rule AW      1974    only    -       Oct     lastSun 2:00    1:00    D
-# Rule AW      1975    only    -       Mar     Sun>=1  3:00    0       W
-# Rule AW      1983    only    -       Oct     lastSun 2:00    1:00    D
-# Rule AW      1984    only    -       Mar     Sun>=1  3:00    0       W
-
-# From Bradley White (March 4, 1991):
-# A recent excerpt from an Australian newspaper...
-# Western Australia...do[es] not have daylight saving.
-
-# From John D. Newman via Bradley White (November 2, 1991):
-# Western Australia is still on "winter time". Some DH in Sydney
-# rang me at home a few days ago at 6.00am. (He had just arrived at
-# work at 9.00am.)
-# W.A. is switching to Summer Time on Nov 17th just to confuse
-# everybody again.
-
-# From Arthur David Olson (March 8, 1992):
-# The 1992 ending date used in the rules is a best guess;
-# it matches what was used in the past.
-
-# Queensland
-# From George Shepherd via Simon Woodhead via Robert Elz (March 6, 1991):
-# #   The state of QUEENSLAND.. [ Courtesy Qld. Dept Premier Econ&Trade Devel ]
-# #                                            [ Dec 1990 ]
-# ...
-# Zone Australia/Queensland    10:00   AQ      %sST
-# ...
-# Rule AQ      1971    only    -       Oct     lastSun 2:00    1:00    D
-# Rule AQ      1972    only    -       Feb     lastSun 3:00    0       E
-# Rule AQ      1989    max     -       Oct     lastSun 2:00    1:00    D
-# Rule AQ      1990    max     -       Mar     Sun>=1  3:00    0       E
-
-# From Bradley White (December 24, 1989):
-# "Australia/Queensland" now observes daylight time (i.e. from
-# October 1989).
-
-# From Bradley White (March 4, 1991):
-# A recent excerpt from an Australian newspaper...
-# ...Queensland...[has] agreed to end daylight saving
-# at 3am tomorrow (March 3)...
-
-# From John Mackin (March 6, 1991):
-# I can certainly confirm for my part that Daylight Saving in NSW did in fact
-# end on Sunday, 3 March.  I don't know at what hour, though.  (It surprised
-# me.)
-
-# From Bradley White (March 8, 1992):
-# ...there was recently a referendum in Queensland which resulted
-# in the experimental daylight saving system being abandoned. So, ...
-# ...
-# Rule QLD     1989    1991    -       Oct     lastSun 2:00    1:00    D
-# Rule QLD     1990    1992    -       Mar     Sun>=1  3:00    0       S
-# ...
-
-# From Arthur David Olson (March 8, 1992):
-# The chosen rules the union of the 1971/1972 change and the 1989-1992 changes.
-
-# South Australia, Tasmania, Victoria
-
-# From Arthur David Olson (March 8, 1992):
-# The rules from version 7.1 follow.
-# There are lots of differences between these rules and
-# the Shepherd et al. rules.  Since the Shepherd et al. rules
-# and Bradley White's newspaper article are in agreement on
-# current DST ending dates, no worries.
-#
-# Rule Oz      1971    1985    -       Oct     lastSun 2:00    1:00    -
-# Rule Oz      1986    max     -       Oct     Sun<=24 2:00    1:00    -
-# Rule Oz      1972    only    -       Feb     27      3:00    0       -
-# Rule Oz      1973    1986    -       Mar     Sun>=1  3:00    0       -
-# Rule Oz      1987    max     -       Mar     Sun<=21 3:00    0       -
-# Zone Australia/Tasmania      10:00   Oz      EST
-# Zone Australia/South         9:30    Oz      CST
-# Zone Australia/Victoria      10:00   Oz      EST     1985 Oct lastSun 2:00
-#                              10:00   1:00    EST     1986 Mar Sun<=21 3:00
-#                              10:00   Oz      EST
-
-# From Robert Elz (March 6, 1991):
-# I believe that the current start date for DST is "lastSun" in Oct...
-# that changed Oct 89.  That is, we're back to the
-# original rule, and that rule currently applies in all the states
-# that have dst, incl Qld.  (Certainly it was true in Vic).
-# The file I'm including says that happened in 1988, I think
-# that's incorrect, but I'm not 100% certain.
-
-# South Australia
-
-# From Bradley White (March 4, 1991):
-# A recent excerpt from an Australian newspaper...
-# ...South Australia...[has] agreed to end daylight saving
-# at 3am tomorrow (March 3)...
-
-# From George Shepherd via Simon Woodhead via Robert Elz (March 6, 1991):
-# #   The state of SOUTH AUSTRALIA....[ Courtesy of S.A. Dept of Labour ]
-# #                                            [ Nov 1990 ]
-# ...
-# Zone Australia/South         9:30    AS      %sST
-# ...
-# Rule  AS     1971    max     -       Oct     lastSun 2:00    1:00    D
-# Rule  AS     1972    1985    -       Mar     Sun>=1  3:00    0       C
-# Rule  AS     1986    1990    -       Mar     Sun<=21 3:00    0       C
-# Rule  AS     1991    max     -       Mar     Sun>=1  3:00    0       C
-
-# From Bradley White (March 11, 1992):
-# Recent correspondence with a friend in Adelaide
-# contained the following exchange:  "Due to the Adelaide Festival,
-# South Australia delays setting back our clocks for a few weeks."
-
-# From Robert Elz (March 13, 1992):
-# I heard that apparently (or at least, it appears that)
-# South Aus will have an extra 3 weeks daylight saving every even
-# numbered year (from 1990).  That's when the Adelaide Festival
-# is on...
-
-# From Robert Elz (March 16, 1992, 00:57:07 +1000):
-# DST didn't end in Adelaide today (yesterday)....
-# But whether it's "4th Sunday" or "2nd last Sunday" I have no idea whatever...
-# (it's just as likely to be "the Sunday we pick for this year"...).
-
-# From Bradley White (April 11, 1994):
-# If Sun, 15 March, 1992 was at +1030 as kre asserts, but yet Sun, 20 March,
-# 1994 was at +0930 as John Connolly's customer seems to assert, then I can
-# only conclude that the actual rule is more complicated....
-
-# From John Warburton <jwarb@SACBH.com.au> (1994-10-07):
-# The new Daylight Savings dates for South Australia ...
-# was gazetted in the Government Hansard on Sep 26 1994....
-# start on last Sunday in October and end in last sunday in March.
-
-# Tasmania
-
-# From Bradley White (March 4, 1991):
-# A recent excerpt from an Australian newspaper...
-# ...Tasmania will revert to Australian Eastern Standard Time on March 31...
-
-# From George Shepherd via Simon Woodhead via Robert Elz (March 6, 1991):
-# #  The state of TASMANIA.. [Courtesy Tasmanian Dept of Premier + Cabinet ]
-# #                                    [ Nov 1990 ]
-# ...
-# Zone Australia/Tasmania      10:00   AT      %sST
-# ...
-# Rule AT      1967    only    -       Oct     Sun>=1  2:00    1:00    D
-# Rule AT      1968    only    -       Mar     lastSun 3:00    0       E
-# Rule AT      1968    1985    -       Oct     lastSun 2:00    1:00    D
-# Rule AT      1969    1971    -       Mar     Sun>=8  3:00    0       E
-# Rule AT      1972    only    -       Feb     lastSun 3:00    0       E
-# Rule AT      1973    1981    -       Mar     Sun>=1  3:00    0       E
-# Rule AT      1982    1983    -       Mar     lastSun 3:00    0       E
-# Rule AT      1984    1986    -       Mar     Sun>=1  3:00    0       E
-# Rule AT      1986    only    -       Oct     Sun>=15 2:00    1:00    D
-# Rule AT      1987    1990    -       Mar     Sun>=15 3:00    0       E
-# Rule AT      1987    only    -       Oct     Sun>=22 2:00    1:00    D
-# Rule AT      1988    1990    -       Oct     lastSun 2:00    1:00    D
-# Rule AT      1991    max     -       Oct     Sun>=1  2:00    1:00    D
-# Rule AT      1991    max     -       Mar     lastSun 3:00    0       E
-
-# From Bill Hart via Alexander Dupuy and Guy Harris (October 10, 1991):
-# My state Government in there eagerness to get a few more bucks for the
-# tourist industry industry decided to change the daylight savings times
-# yet again (we now have almost 6 months per year)...
-# ...
-# Rule  Oz      1986    1990    -       Oct     Sun<=24 2:00    1:00    -
-# Rule  Oz      1991    max     -       Oct     Sun>=1  2:00    1:00    -
-# ...
-# Rule  Oz      1987    1990    -       Mar     Sun<=21 3:00    0       -
-# Rule  Oz      1991    max     -       Mar     Sun<=31 3:00    0       -
-
-# From Bill Hart via Guy Harris (October 10, 1991):
-# Oh yes, the new daylight savings rules are uniquely tasmanian, we have
-# 6 weeks a year now when we are out of sync with the rest of Australia
-# (but nothing new about that).
-
-# Victoria
-
-# From Bradley White (March 4, 1991):
-# A recent excerpt from an Australian newspaper...
-# ...Victoria...[has] agreed to end daylight saving at 3am tomorrow (March 3)...
-
-# From George Shepherd via Simon Woodhead via Robert Elz (March 6, 1991):
-# #   The state of VICTORIA.. [ Courtesy of Vic. Dept of Premier + Cabinet ]
-# #                                            [ Nov 1990 ]
-# ...
-# Zone Australia/Victoria      10:00   AV      %sST
-# ...
-# Rule AV      1971    1985    -       Oct     lastSun 2:00    1:00    D
-# Rule AV      1972    only    -       Feb     lastSun 3:00    0       E
-# Rule AV      1973    1985    -       Mar     Sun>=1  3:00    0       E
-# Rule AV      1986    1990    -       Mar     Sun>=15 3:00    0       E
-# Rule AV      1986    1987    -       Oct     Sun>=15 2:00    1:00    D
-# Rule AV      1988    max     -       Oct     lastSun 2:00    1:00    D
-# Rule AV      1991    max     -       Mar     Sun>=1  3:00    0       E
-
-# New South Wales
-
-# From Arthur David Olson:
-# New South Wales and subjurisdictions have their own ideas of a fun time.
-# Based on law library research by John Mackin (john@basser.cs.su.oz),
-# who notes:
-#      In Australia, time is not legislated federally, but rather by the
-#      individual states.  Thus, while such terms as ``Eastern Standard Time''
-#      [I mean, of course, Australian EST, not any other kind] are in common
-#      use, _they have NO REAL MEANING_, as they are not defined in the
-#      legislation.  This is very important to understand.
-#      I have researched New South Wales time only...
-
-# From Dave Davey (March 3, 1990):
-# Rule NSW     1988    only    -       Mar     Sun>=1  3:00    0       -
-# Rule NSW     1989    only    -       Mar     Sun<=21 3:00    0       -
-
-# From Bradley White (March 4, 1991):
-# A recent excerpt from an Australian newspaper...
-# NSW...[has] agreed to end daylight saving at 3am tomorrow (March 3)...
-
-# From George Shepherd via Simon Woodhead via Robert Elz (March 6, 1991):
-# # The state of NEW SOUTH WALES.. [confirmed by Attorney General's Dept N.S.W]
-# #                                    [ Dec 1990 ]
-# ...
-# Rule  AN     1988    1989    -       Mar     Sun<=21 3:00    0       E
-# ...
-
-# From John Mackin (March 9, 1991)
-# I have confirmed the accuracy of the historical data for NSW in the
-# file Robert forwarded
-
-# From Arthur David Olson (March 8, 1992):
-# Sources differ on whether DST ended March 6 or March 20 in 1988;
-# March 20 (the "confirmed" date) is in the chosen rules.
-
-# Yancowinna
-
-# From John Basser (January 4, 1989):
-# `Broken Hill' means the County of Yancowinna.
-
-# From George Shepherd via Simon Woodhead via Robert Elz (March 6, 1991):
-# # YANCOWINNA..  [ Confirmation courtesy of Broken Hill Postmaster ]
-# #                                    [ Dec 1990 ]
-# ...
-# # Yancowinna uses Central Standard Time, despite it's location on the
-# # New South Wales side of the S.A. border. Most business and social dealings
-# # are with CST zones, therefore CST is legislated by local government
-# # although the switch to Summer Time occurs in line with N.S.W. There have
-# # been years when this did not apply, but the historical data is not
-# # presently available.
-# Zone Australia/Yancowinna    9:30     AY     %sST
-# ...
-# Rule  AY     1971    1985    -       Oct     lastSun 2:00    1:00    D
-# Rule  AY     1972    only    -       Feb     lastSun 3:00    0       C
-# [followed by other Rules]
-
-# Lord Howe Island
-
-# From George Shepherd via Simon Woodhead via Robert Elz (March 6, 1991):
-# LHI...               [ Courtesy of Pauline Van Winsen.. pauline@Aus ]
-#                                      [ Dec 1990 ]
-# Lord Howe Island is located off the New South Wales coast, and is half an
-# hour ahead of NSW time.
-
-###############################################################################
-
-# New Zealand, from Elz' asia 1.1
-# Elz says "no guarantees"
-
-# From Mark Davies (October 3, 1990):
-# the 1989/90 year was a trial of an extended "daylight saving" period.
-# This trial was deemed successful and the extended period adopted for
-# subsequent years (with the addition of a further week at the start).
-# source -- phone call to Ministry of Internal Affairs Head Office.
-
-# From George Shepherd via Simon Woodhead via Robert Elz (March 6, 1991):
-# # The Country of New Zealand   (Australia's east island -) Gee they hate that!
-# #                               or is Australia the west island of N.Z.
-# #    [ courtesy of Geoff Tribble.. Geofft@Aus.. Auckland N.Z. ]
-# #                            [ Nov 1990 ]
-# ...
-# Rule NZ      1974    1988    -       Oct     lastSun 2:00    1:00    D
-# Rule NZ      1989    max     -       Oct     Sun>=1  2:00    1:00    D
-# Rule NZ      1975    1989    -       Mar     Sun>=1  3:00    0       S
-# Rule NZ      1990    max     -       Mar     lastSun 3:00    0       S
-# ...
-# Zone NZ                      12:00   NZ              NZ%sT   # New Zealand
-# Zone NZ-CHAT                 12:45   -               NZ-CHAT # Chatham Island
-
-# From Arthur David Olson (March 8, 1992):
-# The chosen rules use the Davies October 8 values for the start of DST in 1989
-# rather than the October 1 value.
-
-###############################################################################
-
-# Fiji
-
-# Howse writes (p 162) that in 1879 the British governor of Fiji
-# enacted an ordinance standardizing the islands on +12:00.
-# Perhaps it didn't take.  We go with Shanks's more precise date in 1915.
-
-# Kwajalein
-
-# In comp.risks 14.87 (26 August 1993), Peter Neumann writes:
-# I wonder what happened in Kwajalein, where there was NO Friday,
-# August 20, 1993.  Thursday night at midnight Kwajalein switched sides with
-# respect to the International Date Line, to rejoin its fellow islands,
-# going from 11:59 p.m. Thursday to 12:00 m. Saturday in a blink.
-
-# Pacific Islands Trust Territories
-
-# Howse writes (p 162) ``The Spaniards, on the other hand, reached the
-# Philippines and the Ladrones from America,'' and implies that the Ladrones
-# (now called the Marianas) kept American date for quite some time.
-# Ignore this for now, as we have no hard data.  See also Asia/Manila.
diff --git a/time/backward b/time/backward
deleted file mode 100644 (file)
index 9298788..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-# @(#)backward 7.6
-
-# This file provides links between late-1993-vintage names for time zones
-# and their previous names.
-
-Link   Australia/Sydney        Australia/ACT
-Link   Australia/Lord_Howe     Australia/LHI
-Link   Australia/Sydney        Australia/NSW
-Link   Australia/Darwin        Australia/North
-Link   Australia/Brisbane      Australia/Queensland
-Link   Australia/Adelaide      Australia/South
-Link   Australia/Hobart        Australia/Tasmania
-Link   Australia/Melbourne     Australia/Victoria
-Link   Australia/Perth         Australia/West
-Link   Australia/Broken_Hill   Australia/Yancowinna
-Link   America/Porto_Acre      Brazil/Acre
-Link   America/Noronha         Brazil/DeNoronha
-Link   America/Sao_Paulo       Brazil/East
-Link   America/Manaus          Brazil/West
-Link   America/Halifax         Canada/Atlantic
-Link   America/Winnipeg        Canada/Central
-Link   America/Regina          Canada/East-Saskatchewan
-Link   America/Montreal        Canada/Eastern
-Link   America/Edmonton        Canada/Mountain
-Link   America/St_Johns        Canada/Newfoundland
-Link   America/Vancouver       Canada/Pacific
-Link   America/Regina          Canada/Saskatchewan
-Link   America/Whitehorse      Canada/Yukon
-Link   America/Santiago        Chile/Continental
-Link   Pacific/Easter          Chile/EasterIsland
-Link   America/Havana          Cuba
-Link   Africa/Cairo            Egypt
-Link   Europe/Dublin           Eire
-Link   Europe/London           GB
-Link   Etc/GMT                 GMT
-Link   Etc/GMT+0               GMT+0
-Link   Etc/GMT-0               GMT-0
-Link   Etc/GMT0                GMT0
-Link   Etc/Greenwich           Greenwich
-Link   Asia/Hong_Kong          Hongkong
-Link   Atlantic/Reykjavik      Iceland
-Link   Asia/Tehran             Iran
-Link   Asia/Tel_Aviv           Israel
-Link   America/Jamaica         Jamaica
-Link   Asia/Tokyo              Japan
-Link   Pacific/Kwajalein       Kwajalein
-Link   Africa/Tripoli          Libya
-Link   America/Tijuana         Mexico/BajaNorte
-Link   America/Mazatlan        Mexico/BajaSur
-Link   America/Mexico_City     Mexico/General
-Link   Pacific/Auckland        NZ
-Link   Pacific/Chatham         NZ-CHAT
-Link   Asia/Shanghai           PRC
-Link   Europe/Warsaw           Poland
-Link   Europe/Lisbon           Portugal
-Link   Asia/Taipei             ROC
-Link   Asia/Seoul              ROK
-Link   Asia/Singapore          Singapore
-Link   Europe/Istanbul         Turkey
-Link   Etc/UCT                 UCT
-Link   America/Anchorage       US/Alaska
-Link   America/Atka            US/Aleutian
-Link   America/Phoenix         US/Arizona
-Link   America/Chicago         US/Central
-Link   America/Fort_Wayne      US/East-Indiana
-Link   America/New_York        US/Eastern
-Link   Pacific/Honolulu        US/Hawaii
-Link   America/Knox_IN         US/Indiana-Starke
-Link   America/Detroit         US/Michigan
-Link   America/Denver          US/Mountain
-Link   America/Los_Angeles     US/Pacific
-Link   Pacific/Samoa           US/Samoa
-Link   Etc/UTC                 UTC
-Link   Etc/Universal           Universal
-Link   Etc/Zulu                Zulu
diff --git a/time/date.1 b/time/date.1
deleted file mode 100644 (file)
index e3bff1b..0000000
+++ /dev/null
@@ -1,153 +0,0 @@
-.TH DATE 1
-.SH NAME
-date \- show and set date and time
-.SH SYNOPSIS
-.if n .nh
-.if n .na
-.B date
-[
-.B \-u
-] [
-.B \-c
-] [
-.B \-n
-] [
-.B \-d
-dsttype
-] [
-.B \-t
-minutes-west
-] [
-\fB\-a \fR[\fB+\fR|\fB-]\fIsss\fB.\fIfff\fR
-] [
-.BI + format
-] [
-\fR[\fIyyyy\fR]\fImmddhhmm\fR[\fIyy\fR][\fB.\fIss\fR]
-]
-.SH DESCRIPTION
-.I Date
-without arguments writes the date and time to the standard output in
-the form
-.ce 1
-Wed Mar  8 14:54:40 EST 1989
-.br
-with
-.B EST
-replaced by the local time zone's abbreviation
-(or by the abbreviation for the time zone specified in the
-.B TZ
-environment variable if set).
-.PP
-If a command-line argument starts with a plus sign
-.RB (` + '),
-the rest of the argument is used as a
-.I format
-that controls what appears in the output.
-In the format, when a percent sign
-.RB (` % ')
-appears,
-it and the character after it are not output,
-but rather identify part of the date or time
-to be output in a particular way
-(or identify a special character to output):
-.nf
-.if t .in +.5i
-.if n .in +2
-.ta \w'%M\0\0'u +\w'Wed Mar  8 14:54:40 1989\0\0'u
-       Sample output   Explanation
-%a     Wed     Abbreviated weekday name
-%A     Wednesday       Full weekday name
-%b     Mar     Abbreviated month name
-%B     March   Full month name
-%c     03/08/89 14:54:40       Month/day/year Hour:minute:second
-%C     Wed Mar  8 14:54:40 1989        a la \fIasctime\^\fP(3)
-%d     08      Day of month (always two digits)
-%D     03/08/89        Month/day/year (eight characters)
-%e      8      Day of month (leading zero blanked)
-%h     Mar     Abbreviated month name
-%H     14      24-hour-clock hour (two digits)
-%I     02      12-hour-clock hour (two digits)
-%j     067     Julian day number (three digits)
-%k      2      12-hour-clock hour (leading zero blanked)
-%l     14      24-hour-clock hour (leading zero blanked)
-%m     03      Month number (two digits)
-%M     54      Minute (two digits)
-%n     \\n     newline character
-%p     PM      AM/PM designation
-%r     02:54:40 PM     Hour:minute:second AM/PM designation
-%R     14:54   Hour:minute
-%S     40      Second (two digits)
-%t     \\t     tab character
-%T     14:54:40        Hour:minute:second
-%U     10      Sunday-based week number (two digits)
-%w     3       Day number (one digit, Sunday is 0)
-%W     10      Monday-based week number (two digits)
-%x     03/08/89        Month/day/year (eight characters)
-%X     14:54:40        Hour:minute:second
-%y     89      Last two digits of year
-%Y     1989    Year in full
-%Z     EST     Time zone abbreviation
-.if t .in -.5i
-.if n .in -2
-.fi
-If a character other than one of those shown above appears after
-a percent sign in the format,
-that following character is output.
-All other characters in the format are copied unchanged to the output;
-a newline character is always added at the end of the output.
-.PP
-In Sunday-based week numbering,
-the first Sunday of the year begins week 1;
-days preceding it are part of ``week 0.''
-In Monday-based week numbering,
-the first Monday of the year begins week 1.
-.PP
-To set the date, use a command line argument with one of the following forms:
-.nf
-.if t .in +.5i
-.if n .in +2
-.ta \w'198903081454\0'u
-1454   24-hour-clock hours (first two digits) and minutes
-081454 Month day (first two digits), hours, and minutes
-03081454       Month (two digits, January is 01), month day, hours, minutes
-8903081454     Year, month, month day, hours, minutes
-0308145489     Month, month day, hours, minutes, year
-       (on System V-compatible systems)
-030814541989   Month, month day, hours, minutes, four-digit year
-198903081454   Four-digit year, month, month day, hours, minutes
-.if t .in -.5i
-.if n .in -2
-.fi
-If the century, year, month, or month day is not given,
-the current value is used.
-Any of the above forms may be followed by a period and two digits that give
-the seconds part of the new time; if no seconds are given, zero is assumed.
-.PP
-These options are available:
-.TP
-.BR \-u " or " \-c
-Use GMT when setting and showing the date and time.
-.TP
-.B \-n
-Do not notify other networked systems of the time change.
-.TP
-.BI "\-d " dsttype
-Set the kernel-stored Daylight Saving Time type to the given value.
-(The kernel-stored DST type is used mostly by ``old'' binaries.)
-.TP
-.BI "\-t " minutes-west
-Set the kernel-stored ``minutes west of GMT'' value to the one given on the
-command line.
-(The kernel-stored DST type is used mostly by ``old'' binaries.)
-.TP
-.BI "\-a " adjustment
-Change the time forward (or backward) by the number of seconds
-(and fractions thereof) specified in the
-.I adjustment\^
-argument.
-Either the seconds part or the fractions part of the argument (but not both)
-may be omitted.
-On BSD-based systems,
-the adjustment is made by changing the rate at which time advances;
-on System-V-based systems, the adjustment is made by changing the time.
-.\" @(#)date.1 7.2
diff --git a/time/date.c b/time/date.c
deleted file mode 100644 (file)
index 493b878..0000000
+++ /dev/null
@@ -1,900 +0,0 @@
-#ifndef lint
-#ifndef NOID
-static char    elsieid[] = "@(#)date.c 7.13";
-/*
-** Modified from the UCB version with the SCCS ID appearing below.
-*/
-#endif /* !defined NOID */
-#endif /* !defined lint */
-
-/*
- * Copyright (c) 1985, 1987, 1988 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by the University of California, 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'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANT[A]BILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifndef lint
-char copyright[] =
-"@(#) Copyright (c) 1985, 1987, 1988 The Regents of the University of California.\n\
- All rights reserved.\n";
-#endif /* not lint */
-
-#ifndef lint
-static char sccsid[] = "@(#)date.c     4.23 (Berkeley) 9/20/88";
-#endif /* not lint */
-
-#ifndef USG
-#include "sys/time.h"  /* for DST_NONE */
-#endif /* !defined USG */
-#include "private.h"
-#include "utmp.h"      /* for OLD_TIME (or its absence) */
-
-/*
-** The two things date knows about time are. . .
-*/
-
-#ifndef TM_YEAR_BASE
-#define TM_YEAR_BASE   1900
-#endif /* !defined TM_YEAR_BASE */
-
-#ifndef SECSPERMIN
-#define SECSPERMIN     60
-#endif /* !defined SECSPERMIN */
-
-extern double          atof();
-extern char **         environ;
-extern char *          getlogin();
-extern int             logwtmp();
-extern time_t          mktime();
-extern char *          optarg;
-extern int             optind;
-extern char *          strchr();
-extern time_t          time();
-extern char *          tzname[2];
-
-static int             retval = EXIT_SUCCESS;
-
-static void            checkfinal P((const char *, int, time_t, time_t));
-static int             comptm P((const struct tm *, const struct tm *));
-static time_t          convert P((const char *, int, time_t));
-static void            display P((const char *));
-static void            dogmt P((void));
-static void            errensure P((void));
-static void            iffy P((time_t, time_t, const char *, const char *));
-int                    main P((int, char**));
-static const char *    nondigit P((const char *));
-static void            oops P((const char *));
-static void            reset P((time_t, int));
-static void            timeout P((FILE *, const char *, const struct tm *));
-static void            usage P((void));
-static void            wildinput P((const char *, const char *, const char *));
-
-int
-main(argc, argv)
-const int      argc;
-char *         argv[];
-{
-       register const char *   format;
-       register const char *   value;
-       register const char *   cp;
-       register int            ch;
-       register int            dousg;
-       register int            aflag = 0;
-       register int            dflag = 0;
-       register int            nflag = 0;
-       register int            tflag = 0;
-       register int            minuteswest;
-       register int            dsttime;
-       register float          adjust;
-       time_t                  now;
-       time_t                  t;
-
-       INITIALIZE(dousg);
-       INITIALIZE(minuteswest);
-       INITIALIZE(dsttime);
-       INITIALIZE(adjust);
-       INITIALIZE(t);
-       (void) time(&now);
-       format = value = NULL;
-       while ((ch = getopt(argc, argv, "ucnd:t:a:")) != EOF) {
-               switch (ch) {
-               default:
-                       usage();
-               case 'u':               /* do it in GMT */
-               case 'c':
-                       dogmt();
-                       break;
-               case 'n':               /* don't set network */
-                       nflag = 1;
-                       break;
-               case 'd':               /* daylight savings time */
-                       if (dflag) {
-                               (void) fprintf(stderr,
-                                       "date: error: multiple -d's used");
-                               usage();
-                       }
-                       dflag = 1;
-                       cp = optarg;
-                       dsttime = atoi(cp);
-                       if (*cp == '\0' || *nondigit(cp) != '\0')
-                               wildinput("-t value", optarg,
-                                       "must be a non-negative number");
-                       break;
-               case 't':               /* minutes west of GMT */
-                       if (tflag) {
-                               (void) fprintf(stderr,
-                                       "date: error: multiple -t's used");
-                               usage();
-                       }
-                       tflag = 1;
-                       cp = optarg;
-                       minuteswest = atoi(cp);
-                       if (*cp == '+' || *cp == '-')
-                               ++cp;
-                       if (*cp == '\0' || *nondigit(cp) != '\0')
-                               wildinput("-d value", optarg,
-                                       "must be a number");
-                       break;
-               case 'a':               /* adjustment */
-                       if (aflag) {
-                               (void) fprintf(stderr,
-                                       "date: error: multiple -a's used");
-                               usage();
-                       }
-                       aflag = 1;
-                       cp = optarg;
-                       adjust = atof(cp);
-                       if (*cp == '+' || *cp == '-')
-                               ++cp;
-                       if (*cp == '\0' || strcmp(cp, ".") == 0)
-                               wildinput("-a value", optarg,
-                                       "must be a number");
-                       cp = nondigit(cp);
-                       if (*cp == '.')
-                               ++cp;
-                       if (*nondigit(cp) != '\0')
-                               wildinput("-a value", optarg,
-                                       "must be a number");
-                       break;
-               }
-       }
-       while (optind < argc) {
-               cp = argv[optind++];
-               if (*cp == '+')
-                       if (format == NULL)
-                               format = cp + 1;
-                       else {
-                               (void) fprintf(stderr,
-"date: error: multiple formats in command line\n");
-                               usage();
-                       }
-               else    if (value == NULL)
-                               value = cp;
-                       else {
-                               (void) fprintf(stderr,
-"date: error: multiple values in command line\n");
-                               usage();
-                       }
-       }
-       if (value != NULL) {
-               /*
-               ** This order ensures that "reasonable" twelve-digit inputs
-               ** (such as 120203042006) won't be misinterpreted
-               ** even if time_t's range all the way back to the thirteenth
-               ** century.  Do not change the order.
-               */
-               t = convert(value, (dousg = TRUE), now);
-               if (t == -1)
-                       t = convert(value, (dousg = FALSE), now);
-               if (t == -1) {
-                       /*
-                       ** Out of range values,
-                       ** or time that falls in a DST transition hole?
-                       */
-                       if ((cp = strchr(value, '.')) != NULL) {
-                               /*
-                               ** Ensure that the failure of
-                               **      TZ=US/Eastern date 8712312359.60
-                               ** doesn't get misdiagnosed.  (It was
-                               **      TZ=US/Eastern date 8712311859.60
-                               ** when the leap second was inserted.)
-                               ** The normal check won't work since
-                               ** the given time is valid in GMT.
-                               */
-                               if (atoi(cp + 1) >= SECSPERMIN)
-                                       wildinput("time", value,
-                                               "out of range seconds given");
-                       }
-                       dogmt();
-                       t = convert(value, FALSE, now);
-                       if (t == -1)
-                               t = convert(value, TRUE, now);
-                       wildinput("time", value,
-                               (t == -1) ?
-                               "out of range value given" :
-                               "time skipped when clock springs forward");
-               }
-       }
-       /*
-       ** Entire command line has now been checked.
-       */
-       if (aflag) {
-#ifdef DST_NONE
-               struct timeval  tv;
-
-               tv.tv_sec = (int) adjust;
-               tv.tv_usec = (int) ((adjust - tv.tv_sec) * 1000000);
-               if (adjtime(&tv, (struct timeval *) NULL) != 0)
-                       oops("date: error: adjtime");
-#endif /* defined DST_NONE */
-#ifndef DST_NONE
-               reset((time_t) (now + adjust), nflag);
-#endif /* !defined DST_NONE */
-               /*
-               ** Sun silently ignores everything else; we follow suit.
-               */
-               (void) exit(retval);
-       }
-       if (dflag || tflag) {
-#ifdef DST_NONE
-               struct timezone tz;
-
-               if (!dflag || !tflag)
-                       if (gettimeofday((struct timeval *) NULL, &tz) != 0)
-                               oops("date: error: gettimeofday");
-               if (dflag)
-                       tz.tz_dsttime = dsttime;
-               if (tflag)
-                       tz.tz_minuteswest = minuteswest;
-               if (settimeofday((struct timeval *) NULL, &tz) != 0)
-                       oops("date: error: settimeofday");
-#endif /* defined DST_NONE */
-#ifndef DST_NONE
-               (void) fprintf(stderr,
-"date: warning: kernel doesn't keep -d/-t information, option ignored\n");
-#endif /* !defined DST_NONE */
-       }
-
-       if (value == NULL)
-               display(format);
-
-       reset(t, nflag);
-
-       checkfinal(value, dousg, t, now);
-
-#ifdef EBUG
-       {
-               struct tm       tm;
-
-               tm = *localtime(&t);
-               timeout(stdout, "%c\n", &tm);
-               (void) exit(retval);
-       }
-#endif /* defined EBUG */
-
-       display(format);
-
-       /* gcc -Wall pacifier */
-       for ( ; ; )
-               continue;
-}
-
-static void
-dogmt()
-{
-       static char **  fakeenv;
-
-       if (fakeenv == NULL) {
-               register int    from, to, n;
-
-               for (n = 0;  environ[n] != NULL;  ++n)
-                       continue;
-               fakeenv = (char **) malloc((alloc_size_T) (n + 2) *
-                       sizeof *fakeenv);
-               if (fakeenv == NULL) {
-                       (void) perror("Memory exhausted");
-                       errensure();
-                       (void) exit(retval);
-               }
-               to = 0;
-               fakeenv[to++] = "TZ=GMT0";
-               for (from = 1; environ[from] != NULL; ++from)
-                       if (strncmp(environ[from], "TZ=", 3) != 0)
-                               fakeenv[to++] = environ[from];
-               fakeenv[to] = NULL;
-               environ = fakeenv;
-       }
-}
-
-#ifdef OLD_TIME
-
-/*
-** We assume we're on a System-V-based system,
-** should use stime,
-** should write System-V-format utmp entries,
-** and don't have network notification to worry about.
-*/
-
-#include "fcntl.h"     /* for O_WRONLY, O_APPEND */
-
-/*ARGSUSED*/
-static void
-reset(newt, nflag)
-const time_t   newt;
-const int      nflag;
-{
-       register int            fid;
-       time_t                  oldt;
-       static struct {
-               struct utmp     before;
-               struct utmp     after;
-       } s;
-
-       /*
-       ** Wouldn't it be great if stime returned the old time?
-       */
-       (void) time(&oldt);
-       if (stime(&newt) != 0)
-               oops("date: error: stime");
-       s.before.ut_type = OLD_TIME;
-       s.before.ut_time = oldt;
-       (void) strcpy(s.before.ut_line, OTIME_MSG);
-       s.after.ut_type = NEW_TIME;
-       s.after.ut_time = newt;
-       (void) strcpy(s.after.ut_line, NTIME_MSG);
-       fid = open(WTMP_FILE, O_WRONLY | O_APPEND);
-       if (fid < 0)
-               oops("date: error: log file open");
-       if (write(fid, (char *) &s, sizeof s) != sizeof s)
-               oops("date: error: log file write");
-       if (close(fid) != 0)
-               oops("date: error: log file close");
-       pututline(&s.before);
-       pututline(&s.after);
-}
-
-#endif /* defined OLD_TIME */
-#ifndef OLD_TIME
-
-/*
-** We assume we're on a BSD-based system,
-** should use settimeofday,
-** should write BSD-format utmp entries (using logwtmp),
-** and may get to worry about network notification.
-** The "time name" changes between 4.3-tahoe and 4.4;
-** we include sys/param.h to determine which we should use.
-*/
-
-#ifndef TIME_NAME
-#include "sys/param.h"
-#ifdef BSD4_4
-#define TIME_NAME      "date"
-#endif /* defined BSD4_4 */
-#ifndef BSD4_4
-#define TIME_NAME      ""
-#endif /* !defined BSD4_4 */
-#endif /* !defined TIME_NAME */
-
-#include "syslog.h"
-#include "sys/socket.h"
-#include "netinet/in.h"
-#include "netdb.h"
-#define TSPTYPES
-#include "protocols/timed.h"
-
-#ifndef TSP_SETDATE
-/*ARGSUSED*/
-#endif /* !defined TSP_SETDATE */
-static void
-reset(newt, nflag)
-const time_t   newt;
-const int      nflag;
-{
-       register const char *   username;
-       static struct timeval   tv;     /* static so tv_usec is 0 */
-
-#ifdef EBUG
-       return;
-#endif /* defined EBUG */
-       username = getlogin();
-       if (username == NULL || *username == '\0') /* single-user or no tty */
-               username = "root";
-       tv.tv_sec = newt;
-#ifdef TSP_SETDATE
-       if (nflag || !netsettime(tv))
-#endif /* defined TSP_SETDATE */
-       {
-               /*
-               ** "old" entry is always written, for compatibility.
-               */
-               logwtmp("|", TIME_NAME, "");
-               if (settimeofday(&tv, (struct timezone *) NULL) == 0) {
-                       logwtmp("{", TIME_NAME, "");    /* } */
-                       syslog(LOG_AUTH | LOG_NOTICE, "date set by %s",
-                               username);
-               } else  oops("date: error: settimeofday");
-       }
-}
-
-#endif /* !defined OLD_TIME */
-
-static void
-wildinput(item, value, reason)
-const char * const     item;
-const char * const     value;
-const char * const     reason;
-{
-       (void) fprintf(stderr, "date: error: bad command line %s \"%s\", %s\n",
-               item, value, reason);
-       usage();
-}
-
-static void
-errensure P((void))
-{
-       if (retval == EXIT_SUCCESS)
-               retval = EXIT_FAILURE;
-}
-
-static const char *
-nondigit(cp)
-register const char *  cp;
-{
-       while (isdigit(*cp))
-               ++cp;
-       return cp;
-}
-
-static void
-usage P((void))
-{
-       (void) fprintf(stderr, "date: usage is date ");
-       (void) fprintf(stderr, "[-u] ");
-       (void) fprintf(stderr, "[-c] ");
-       (void) fprintf(stderr, "[-n] ");
-       (void) fprintf(stderr, "[-d dst] ");
-       (void) fprintf(stderr, "[-t min-west] ");
-       (void) fprintf(stderr, "[-a sss.fff] ");
-       (void) fprintf(stderr, "[[yyyy]mmddhhmm[yyyy][.ss]] ");
-       (void) fprintf(stderr, "[+format]\n");
-       errensure();
-       (void) exit(retval);
-}
-
-static void
-oops(string)
-const char * const     string;
-{
-       (void) perror(string);
-       errensure();
-       display((char *) NULL);
-}
-
-static void
-display(format)
-const char * const     format;
-{
-       struct tm       tm;
-       time_t          now;
-
-       (void) time(&now);
-       tm = *localtime(&now);
-       if (format == NULL) {
-               timeout(stdout, "%a %b ", &tm);
-               (void) printf("%2d ", tm.tm_mday);
-               timeout(stdout, "%X %Z %Y", &tm);
-       } else  timeout(stdout, format, &tm);
-       (void) putchar('\n');
-       (void) fflush(stdout);
-       (void) fflush(stderr);
-       if (ferror(stdout) || ferror(stderr)) {
-               (void) fprintf(stderr,
-                       "date: error: couldn't write results\n");
-               errensure();
-       }
-       (void) exit(retval);
-}
-
-extern size_t  strftime();
-
-#define INCR   1024
-
-static void
-timeout(fp, format, tmp)
-FILE * const           fp;
-const char * const     format;
-const struct tm * const        tmp;
-{
-       char *  cp;
-       size_t  result;
-       size_t  size;
-
-       if (*format == '\0')
-               return;
-       size = INCR;
-       cp = malloc((alloc_size_T) size);
-       for ( ; ; ) {
-               if (cp == NULL) {
-                       (void) fprintf(stderr,
-                               "date: error: can't get memory\n");
-                       errensure();
-                       (void) exit(retval);
-               }
-               result = strftime(cp, size, format, tmp);
-               if (result != 0)
-                       break;
-               size += INCR;
-               cp = realloc(cp, (alloc_size_T) size);
-       }
-       (void) fwrite(cp, 1, result, fp);
-       free(cp);
-}
-
-static int
-comptm(atmp, btmp)
-register const struct tm * const atmp;
-register const struct tm * const btmp;
-{
-       register int    result;
-
-       if ((result = (atmp->tm_year - btmp->tm_year)) == 0 &&
-               (result = (atmp->tm_mon - btmp->tm_mon)) == 0 &&
-               (result = (atmp->tm_mday - btmp->tm_mday)) == 0 &&
-               (result = (atmp->tm_hour - btmp->tm_hour)) == 0 &&
-               (result = (atmp->tm_min - btmp->tm_min)) == 0)
-                       result = atmp->tm_sec - btmp->tm_sec;
-       return result;
-}
-
-/*
-** convert --
-**     convert user's input into a time_t.
-*/
-
-#define ATOI2(ar)      (ar[0] - '0') * 10 + (ar[1] - '0'); ar += 2;
-
-static time_t
-convert(value, dousg, t)
-register const char * const    value;
-const int                      dousg;
-const time_t                   t;
-{
-       register const char *   cp;
-       register char * dotp;
-       register int    cent, year_in_cent, month, hour, day, mins, secs;
-       struct tm       tm, outtm;
-       time_t          outt;
-
-       tm = *localtime(&t);
-       cent = (tm.tm_year + TM_YEAR_BASE) / 100;
-       year_in_cent = (tm.tm_year + TM_YEAR_BASE) - cent * 100;
-       month = tm.tm_mon + 1;
-       day = tm.tm_mday;
-       hour = tm.tm_hour;
-       mins = tm.tm_min;
-       secs = 0;
-
-       dotp = strchr(value, '.');
-       for (cp = value; *cp != '\0'; ++cp)
-               if (!isdigit(*cp) && cp != dotp)
-                       wildinput("time", value, "contains a nondigit");
-
-       if (dotp == NULL)
-               dotp = strchr(value, '\0');
-       else {
-               cp = dotp + 1;
-               if (strlen(cp) != 2)
-                       wildinput("time", value,
-                               "seconds part is not two digits");
-               secs = ATOI2(cp);
-       }
-
-       cp = value;
-       switch (dotp - cp) {
-               default:
-                       wildinput("time", value, "main part is wrong length");
-               case 12:
-                       if (!dousg) {
-                               cent = ATOI2(cp);
-                               year_in_cent = ATOI2(cp);
-                       }
-                       month = ATOI2(cp);
-                       day = ATOI2(cp);
-                       hour = ATOI2(cp);
-                       mins = ATOI2(cp);
-                       if (dousg) {
-                               cent = ATOI2(cp);
-                               year_in_cent = ATOI2(cp);
-                       }
-                       break;
-               case 8: /* mmddhhmm */
-                       month = ATOI2(cp);
-                       /* fall through to. . . */
-               case 6: /* ddhhmm */
-                       day = ATOI2(cp);
-                       /* fall through to. . . */
-               case 4: /* hhmm */
-                       hour = ATOI2(cp);
-                       mins = ATOI2(cp);
-                       break;
-               case 10:
-                       if (!dousg) {
-                               year_in_cent = ATOI2(cp);
-                       }
-                       month = ATOI2(cp);
-                       day = ATOI2(cp);
-                       hour = ATOI2(cp);
-                       mins = ATOI2(cp);
-                       if (dousg) {
-                               year_in_cent = ATOI2(cp);
-                       }
-                       break;
-       }
-
-       tm.tm_year = cent * 100 + year_in_cent - TM_YEAR_BASE;
-       tm.tm_mon = month - 1;
-       tm.tm_mday = day;
-       tm.tm_hour = hour;
-       tm.tm_min = mins;
-       tm.tm_sec = secs;
-       tm.tm_isdst = -1;
-       outtm = tm;
-       outt = mktime(&outtm);
-       return (comptm(&tm, &outtm) == 0) ? outt : -1;
-}
-
-/*
-** Code from here on out is either based on code provided by UCB
-** or is only called just before the program exits.
-*/
-
-/*
-** Check for iffy input.
-*/
-
-static void
-checkfinal(value, didusg, t, oldnow)
-const char * const     value;
-const int              didusg;
-const time_t           t;
-const time_t           oldnow;
-{
-       time_t          othert;
-       struct tm       tm;
-       struct tm       othertm;
-       register int    pass;
-       register long   offset;
-
-       /*
-       ** See if there's both a USG and a BSD interpretation.
-       */
-       othert = convert(value, !didusg, oldnow);
-       if (othert != -1 && othert != t)
-               iffy(t, othert, value, "year could be at start or end");
-       /*
-       ** See if there's both a DST and a STD version.
-       */
-       tm = *localtime(&t);
-       othertm = tm;
-       othertm.tm_isdst = !tm.tm_isdst;
-       othert = mktime(&othertm);
-       if (othert != -1 && othertm.tm_isdst != tm.tm_isdst &&
-               comptm(&tm, &othertm) == 0)
-                       iffy(t, othert, value,
-                           "both standard and summer time versions exist");
-/*
-** Final check.
-**
-** If a jurisdiction shifts time *without* shifting whether time is
-** summer or standard (as Hawaii, the United Kingdom, and Saudi Arabia
-** have done), routine checks for iffy times may not work.
-** So we perform this final check, deferring it until after the time has
-** been set--it may take a while, and we don't want to introduce an unnecessary
-** lag between the time the user enters their command and the time that
-** stime/settimeofday is called.
-**
-** We just check nearby times to see if any have the same representation
-** as the time that convert returned.  We work our way out from the center
-** for quick response in solar time situations.  We only handle common cases--
-** offsets of at most a minute, and offsets of exact numbers of minutes
-** and at most an hour.
-*/
-       for (offset = 1; offset <= 60; ++offset)
-               for (pass = 1; pass <= 4; ++pass) {
-                       if (pass == 1)
-                               othert = t + offset;
-                       else if (pass == 2)
-                               othert = t - offset;
-                       else if (pass == 3)
-                               othert = t + 60 * offset;
-                       else    othert = t - 60 * offset;
-                       othertm = *localtime(&othert);
-                       if (comptm(&tm, &othertm) == 0)
-                               iffy(t, othert, value,
-                                       "multiple matching times exist");
-               }
-}
-
-static void
-iffy(thist, thatt, value, reason)
-const time_t           thist;
-const time_t           thatt;
-const char * const     value;
-const char * const     reason;
-{
-       struct tm       tm;
-
-       (void) fprintf(stderr, "date: warning: ambiguous time \"%s\", %s.\n",
-               value, reason);
-       tm = *gmtime(&thist);
-       (void) fprintf(stderr, "Time was set as if you used\n");
-       /*
-       ** Avoid running afoul of SCCS!
-       */
-       timeout(stderr, "\tdate -u ", &tm);
-       timeout(stderr, "%m%d%H", &tm);
-       timeout(stderr, "%M", &tm);
-       timeout(stderr, "%Y.%S\n", &tm);
-       tm = *localtime(&thist);
-       timeout(stderr, "to get %c", &tm);
-       (void) fprintf(stderr, " (%s time)",
-               tm.tm_isdst ? "summer" : "standard");
-       (void) fprintf(stderr, ".  Use\n");
-       tm = *gmtime(&thatt);
-       timeout(stderr, "\tdate -u ", &tm);
-       timeout(stderr, "%m%d%H", &tm);
-       timeout(stderr, "%M", &tm);
-       timeout(stderr, "%Y.%S\n", &tm);
-       tm = *localtime(&thatt);
-       timeout(stderr, "to get %c", &tm);
-       (void) fprintf(stderr, " (%s time)",
-               tm.tm_isdst ? "summer" : "standard");
-       (void) fprintf(stderr, ".\n");
-       errensure();
-       (void) exit(retval);
-}
-
-#ifdef TSP_SETDATE
-#define WAITACK                2       /* seconds */
-#define WAITDATEACK    5       /* seconds */
-
-#ifndef errno
-extern int errno;
-#endif /* !defined errno */
-/*
- * Set the date in the machines controlled by timedaemons
- * by communicating the new date to the local timedaemon.
- * If the timedaemon is in the master state, it performs the
- * correction on all slaves.  If it is in the slave state, it
- * notifies the master that a correction is needed.
- * Returns 1 on success, 0 on failure.
- */
-netsettime(ntv)
-       struct timeval ntv;
-{
-       int s, length, port, timed_ack, found, err;
-       long waittime;
-       fd_set ready;
-       char hostname[MAXHOSTNAMELEN];
-       struct timeval tout;
-       struct servent *sp;
-       struct tsp msg;
-       struct sockaddr_in sin, dest, from;
-
-       sp = getservbyname("timed", "udp");
-       if (sp == 0) {
-               fputs("udp/timed: unknown service\n", stderr);
-               retval = 2;
-               return (0);
-       }
-       dest.sin_port = sp->s_port;
-       dest.sin_family = AF_INET;
-       dest.sin_addr.s_addr = htonl((u_long)INADDR_ANY);
-       s = socket(AF_INET, SOCK_DGRAM, 0);
-       if (s < 0) {
-               if (errno != EPROTONOSUPPORT)
-                       perror("date: socket");
-               goto bad;
-       }
-       bzero((char *)&sin, sizeof (sin));
-       sin.sin_family = AF_INET;
-       for (port = IPPORT_RESERVED - 1; port > IPPORT_RESERVED / 2; port--) {
-               sin.sin_port = htons((u_short)port);
-               if (bind(s, (struct sockaddr *)&sin, sizeof (sin)) >= 0)
-                       break;
-               if (errno != EADDRINUSE) {
-                       if (errno != EADDRNOTAVAIL)
-                               perror("date: bind");
-                       goto bad;
-               }
-       }
-       if (port == IPPORT_RESERVED / 2) {
-               fputs("date: All ports in use\n", stderr);
-               goto bad;
-       }
-       msg.tsp_type = TSP_SETDATE;
-       msg.tsp_vers = TSPVERSION;
-       if (gethostname(hostname, sizeof (hostname))) {
-               perror("gethostname");
-               goto bad;
-       }
-       (void) strncpy(msg.tsp_name, hostname, sizeof (hostname));
-       msg.tsp_seq = htons((u_short)0);
-       msg.tsp_time.tv_sec = htonl((u_long)ntv.tv_sec);
-       msg.tsp_time.tv_usec = htonl((u_long)ntv.tv_usec);
-       length = sizeof (struct sockaddr_in);
-       if (connect(s, &dest, length) < 0) {
-               perror("date: connect");
-               goto bad;
-       }
-       if (send(s, (char *)&msg, sizeof (struct tsp), 0) < 0) {
-               if (errno != ECONNREFUSED)
-                       perror("date: send");
-               goto bad;
-       }
-       timed_ack = -1;
-       waittime = WAITACK;
-loop:
-       tout.tv_sec = waittime;
-       tout.tv_usec = 0;
-       FD_ZERO(&ready);
-       FD_SET(s, &ready);
-       found = select(FD_SETSIZE, &ready, (fd_set *)0, (fd_set *)0, &tout);
-       length = sizeof(err);
-       if (getsockopt(s, SOL_SOCKET, SO_ERROR, (char *)&err, &length) == 0
-           && err) {
-               errno = err;
-               if (errno != ECONNREFUSED)
-                       perror("date: send (delayed error)");
-               goto bad;
-       }
-       if (found > 0 && FD_ISSET(s, &ready)) {
-               length = sizeof (struct sockaddr_in);
-               if (recvfrom(s, (char *)&msg, sizeof (struct tsp), 0, &from,
-                   &length) < 0) {
-                       if (errno != ECONNREFUSED)
-                               perror("date: recvfrom");
-                       goto bad;
-               }
-               msg.tsp_seq = ntohs(msg.tsp_seq);
-               msg.tsp_time.tv_sec = ntohl(msg.tsp_time.tv_sec);
-               msg.tsp_time.tv_usec = ntohl(msg.tsp_time.tv_usec);
-               switch (msg.tsp_type) {
-
-               case TSP_ACK:
-                       timed_ack = TSP_ACK;
-                       waittime = WAITDATEACK;
-                       goto loop;
-
-               case TSP_DATEACK:
-                       (void)close(s);
-                       return (1);
-
-               default:
-                       fprintf(stderr,
-                               "date: Wrong ack received from timed: %s\n",
-                               tsptype[msg.tsp_type]);
-                       timed_ack = -1;
-                       break;
-               }
-       }
-       if (timed_ack == -1)
-               fputs("date: Can't reach time daemon, time set locally.\n",
-                       stderr);
-bad:
-       (void)close(s);
-       retval = 2;
-       return (0);
-}
-#endif /* defined TSP_SETDATE */
diff --git a/time/difftime.c b/time/difftime.c
deleted file mode 100644 (file)
index 1832586..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-#ifndef lint
-#ifndef NOID
-static char    elsieid[] = "@(#)difftime.c     7.5";
-#endif /* !defined NOID */
-#endif /* !defined lint */
-
-/*LINTLIBRARY*/
-
-#include "private.h"
-
-/*
-** Algorithm courtesy Paul Eggert (eggert@twinsun.com).
-*/
-
-#ifdef HAVE_LONG_DOUBLE
-#define long_double    long double
-#endif /* defined HAVE_LONG_DOUBLE */
-#ifndef HAVE_LONG_DOUBLE
-#define long_double    double
-#endif /* !defined HAVE_LONG_DOUBLE */
-
-double
-difftime(time1, time0)
-const time_t   time1;
-const time_t   time0;
-{
-       time_t  delta;
-       time_t  hibit;
-
-       if (sizeof(time_t) < sizeof(double))
-               return (double) time1 - (double) time0;
-       if (sizeof(time_t) < sizeof(long_double))
-               return (long_double) time1 - (long_double) time0;
-       if (time1 < time0)
-               return -difftime(time0, time1);
-       /*
-       ** As much as possible, avoid loss of precision
-       ** by computing the difference before converting to double.
-       */
-       delta = time1 - time0;
-       if (delta >= 0)
-               return delta;
-       /*
-       ** Repair delta overflow.
-       */
-       hibit = 1;
-       while ((hibit <<= 1) > 0)
-               continue;
-       /*
-       ** The following expression rounds twice, which means
-       ** the result may not be the closest to the true answer.
-       ** For example, suppose time_t is 64-bit signed int,
-       ** long_double is IEEE 754 double with default rounding,
-       ** time1 = 9223372036854775807 and time0 = -1536.
-       ** Then the true difference is 9223372036854777343,
-       ** which rounds to 9223372036854777856
-       ** with a total error of 513.
-       ** But delta overflows to -9223372036854774273,
-       ** which rounds to -9223372036854774784, and correcting
-       ** this by subtracting 2 * (long_double) hibit
-       ** (i.e. by adding 2**64 = 18446744073709551616)
-       ** yields 9223372036854776832, which
-       ** rounds to 9223372036854775808
-       ** with a total error of 1535 instead.
-       ** This problem occurs only with very large differences.
-       ** It's too painful to fix this portably.
-       ** We are not alone in this problem;
-       ** many C compilers round twice when converting
-       ** large unsigned types to small floating types,
-       ** so if time_t is unsigned the "return delta" above
-       ** has the same double-rounding problem.
-       */
-       return delta - 2 * (long_double) hibit;
-}
diff --git a/time/emkdir.c b/time/emkdir.c
deleted file mode 100644 (file)
index 5cc62d2..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-#ifndef lint
-#ifndef NOID
-static char    elsieid[] = "@(#)emkdir.c       8.23";
-#endif /* !defined NOID */
-#endif /* !defined lint */
-
-#ifndef emkdir
-
-/*LINTLIBRARY*/
-
-#include "private.h"
-
-extern char *  imalloc P((int n));
-extern void    ifree P((char * p));
-
-static char *
-quoted(name)
-register const char *  name;
-{
-       register char * result;
-       register char * cp;
-       register int    c;
-
-       if (name == NULL)
-               name = "";
-       result = imalloc((int) (4 * strlen(name) + 3));
-       if (result == NULL)
-               return NULL;
-       cp = result;
-#ifdef unix
-       *cp++ = '\'';
-       while ((c = *name++) != '\0')
-               if (c == '\'') {
-                       *cp++ = c;
-                       *cp++ = '\\';
-                       *cp++ = c;
-                       *cp++ = c;
-               } else  *cp++ = c;
-       *cp++ = '\'';
-#endif /* defined unix */
-#ifndef unix
-       while ((c = *name++) != '\0')
-               if (c == '/')
-                       *cp++ = '\\';
-               else    *cp++ = c;
-#endif /* !defined unix */
-       *cp = '\0';
-       return result;
-}
-
-int
-emkdir(name, mode)
-const char *   name;
-const int      mode;
-{
-       register int            result;
-       register const char *   format;
-       register char *         command;
-       register char *         qname;
-
-       if ((qname = quoted(name)) == NULL)
-               return -1;
-#ifdef unix
-       format = "mkdir 2>&- %s && chmod 2>&- %o %s";
-#endif /* defined unix */
-#ifndef unix
-       format = "mkdir %s";
-#endif /* !defined unix */
-       command = imalloc((int) (strlen(format) + 2 * strlen(qname) + 20 + 1));
-       if (command == NULL) {
-               ifree(qname);
-               return -1;
-       }
-       (void) sprintf(command, format, qname, mode, qname);
-       ifree(qname);
-       result = system(command);
-       ifree(command);
-       return (result == 0) ? 0 : -1;
-}
-
-/*
-** UNIX was a registered trademark of UNIX System Laboratories in 1993.
-*/
-
-#endif /* !defined emkdir */
diff --git a/time/etcetera b/time/etcetera
deleted file mode 100644 (file)
index ed619ae..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-# @(#)etcetera 7.4
-
-# All of these are set up just so people can "zic -l" to a timezone
-# that's right for their area, even if it doesn't have a name or DST rules
-# (half hour zones are too much to bother with -- when someone asks!)
-
-Zone   Etc/GMT         0       -       GMT
-Link   Etc/GMT                         Etc/UTC
-Link   Etc/GMT                         Etc/UCT
-Link   Etc/GMT                         Etc/Universal
-Link   Etc/GMT                         Etc/Greenwich
-Link   Etc/GMT                         Etc/Zulu
-Link   Etc/GMT                         Etc/GMT-0
-Link   Etc/GMT                         Etc/GMT+0
-Link   Etc/GMT                         Etc/GMT0
-
-# We use POSIX-style signedness in the names and output,
-# internal-style signedness in the specifications.
-# For example, TZ=Etc/GMT+4 corresponds to 4 hours _behind_ GMT;
-# it is equivalent to TZ=GMT+4, which is implemented directly as per POSIX.
-
-# Earlier incarnations of this package were not POSIX-compliant,
-# and had lines such as
-#              Zone    GMT-12          -12     -       GMT-1200
-# We did not want things to change quietly if someone accustomed to the old
-# way does a
-#              zic -l GMT-12
-# so we moved the names into the Etc subdirectory.
-
-Zone   Etc/GMT-13      13      -       GMT-13 # 12 hours ahead of GMT, plus DST
-Zone   Etc/GMT-12      12      -       GMT-12
-Zone   Etc/GMT-11      11      -       GMT-11
-Zone   Etc/GMT-10      10      -       GMT-10
-Zone   Etc/GMT-9       9       -       GMT-9
-Zone   Etc/GMT-8       8       -       GMT-8
-Zone   Etc/GMT-7       7       -       GMT-7
-Zone   Etc/GMT-6       6       -       GMT-6
-Zone   Etc/GMT-5       5       -       GMT-5
-Zone   Etc/GMT-4       4       -       GMT-4
-Zone   Etc/GMT-3       3       -       GMT-3
-Zone   Etc/GMT-2       2       -       GMT-2
-Zone   Etc/GMT-1       1       -       GMT-1
-Zone   Etc/GMT+1       -1      -       GMT+1
-Zone   Etc/GMT+2       -2      -       GMT+2
-Zone   Etc/GMT+3       -3      -       GMT+3
-Zone   Etc/GMT+4       -4      -       GMT+4
-Zone   Etc/GMT+5       -5      -       GMT+5
-Zone   Etc/GMT+6       -6      -       GMT+6
-Zone   Etc/GMT+7       -7      -       GMT+7
-Zone   Etc/GMT+8       -8      -       GMT+8
-Zone   Etc/GMT+9       -9      -       GMT+9
-Zone   Etc/GMT+10      -10     -       GMT+10
-Zone   Etc/GMT+11      -11     -       GMT+11
-Zone   Etc/GMT+12      -12     -       GMT+12
diff --git a/time/europe b/time/europe
deleted file mode 100644 (file)
index a802cfe..0000000
+++ /dev/null
@@ -1,2072 +0,0 @@
-# @(#)europe   7.17
-
-# This data is by no means authoritative; if you think you know better,
-# go ahead and edit the file (and please send any changes to
-# tz@elsie.nci.nih.gov for general use in the future).
-
-# From Paul Eggert <eggert@twinsun.com> (November 18, 1993):
-# A good source for time zone historical data outside the U.S. is
-# Thomas G. Shanks, The International Atlas (3rd edition),
-# San Diego: ACS Publications, Inc. (1991).
-# Except where otherwise noted, it is the source for the data below.
-#
-# Another source occasionally used is Edward W. Whitman, World Time Differences,
-# Whitman Publishing Co, 2 Niagara Av, Ealing, London (undated), which
-# I found in the UCLA library.
-#
-# I invented the abbreviations marked `*' in the following table;
-# the rest are from earlier versions of this file, or from other sources.
-# The starred Russian names are dubious.  Corrections are welcome!
-#              std dst
-#              LMT     Local Mean Time
-#              LST     Local Star Time (Russian ``mestnoe zvezdnoe vremya'')
-#      -4:00   AST     Atlantic
-#      -3:00   WGT+DST Western Greenland*
-#      -2:00   MGT+DST Middle Greenland*
-#      -1:00   EGT+DST Eastern Greenland*
-#      -1:00   ACT+DST Azores and Canaries*
-#      -1:00   IST IDT Iceland (no longer used)*
-#       0:00   GMT BST Greenwich, British Summer
-#       0:00   WET+DST Western Europe
-#       1:00   MET+DST Middle Europe
-#       2:00   EET+DST Eastern Europe
-#       3:00   MSK MSD Moscow
-#       3:00   TUR+DST Turkey (no longer used)*
-#       4:00   KSK KSD Kuybyshev*
-#       5:00   ESK ESD Yekaterinburg*
-#       6:00   OSK OSD Omsk*
-#       6:00   NSK NSD Novosibirsk (was 7:00 until 1994)
-#       7:00   TSK TSD Tomsk*
-#       8:00   ISK ISD Irkutsk*
-#       9:00   YSK YSD Yakutsk*
-#      10:00   VSK VSD Vladivostok*
-#      11:00   GSK GSD Magadan*
-#      12:00   PSK PSD Petropavlovsk-Kamchatski*
-#      13:00   ASK ASD Anadyr*
-#
-# See the `africa' file for Zone naming conventions.
-#
-# A reliable and entertaining source about time zones, especially in Britain,
-# is Derek Howse, Greenwich time and the discovery of the longitude,
-# Oxford University Press (1980).
-
-# From Andrew A. Chernov <ache@astral.msk.su> (November 12, 1993):
-# LST is Local Star Time (``mestnoe zvezdnoe vremya'').
-
-# From Peter Ilieve <peter@memex.co.uk> (December 4, 1994),
-# The original six [EU members]: Belguim, France, (West) Germany, Italy,
-# Luxembourg, the Netherlands.
-# Plus, from 1 Jan 73: Denmark, Ireland, United Kingdom.
-# Plus, from 1 Jan 81: Greece.
-# Plus, from 1 Jan 86: Spain, Portugal.
-# Plus, from 1 Jan 95: Austria, Finland, Sweden. (Norway negotiated terms for
-# entry but in a referendum on 28 Nov 94 the people voted No by 52.2% to 47.8%
-# on a turnout of 88.6%. This was almost the same result as Norway's previous
-# referendum in 1972, they are the only country to have said No twice.
-# Referendums in the other three countries voted Yes.)
-# ...
-# The only [current nonmember using EU rules] I can speak for is Estonia,
-# which uses EU dates but not at 01:00 GMT, they use midnight GMT. I don't
-# think they know yet what they will do from 1996 onwards.
-# ...
-# There shouldn't be any [current members who are not using EU rules].
-# A Directive has the force of law, member states are obliged to enact
-# national law to implement it. The only contentious issue was the
-# different end date for the UK and Ireland, and this was always allowed
-# in the Directive.
-
-###############################################################################
-
-# United Kingdom
-
-# From Peter Ilieve <peter@memex.co.uk> (July 6, 1994):
-#
-# On 17 Jan 1994 the Independent, a UK quality newspaper, had a piece about
-# historical vistas along the Thames in west London. There was a photo
-# and a sketch map showing some of the sightlines involved. One paragraph
-# of the text said:
-#
-# `An old stone obelisk marking a forgotten terrestrial meridian stands
-# beside the river at Kew. In the 18th century, before time and longditude
-# was standardised by the Royal Observatory in Greenwich, scholars observed
-# this stone and the movement of stars from Kew Observatory nearby. They
-# made their calculations and set the time for the Horse Guards and Parliament,
-# but now the stone is obscured by scrubwood and can only be seen by walking
-# along the towpath within a few yards of it.'
-#
-# I have a one inch to one mile map of London and my estimate of the stone's
-# position is 51 deg. 28' 30" N, 0 deg. 18' 45" W. The longditude should
-# be within about +-2". The Ordnance Survey grid reference is TQ172761.
-#
-# [This yields GMTOFF = -0:01:15 for London LMT in the 18th century.]
-
-# From Paul Eggert <eggert@twinsun.com> (November 18, 1993):
-#
-# Howse writes that Britain was the first country to use standard time.
-# The railways cared most about the inconsistencies of local mean time,
-# and it was they who forced a uniform time on the country.
-# The original idea was credited to Dr. William Hyde Wollaston (1766-1828);
-# it was popularized in 1840 by Capt. Basil Hall, RN (1788-1844),
-# famed explorer and former Commissioner for Longitude.
-# The first railway to adopt London time was the Great Western Railway
-# in November 1840; other railways followed suit, and by 1847 most
-# (though not all) railways used London time.  On 1847 Sep 22 the
-# Railway Clearing House, an industry standards body, recommended that GMT be
-# adopted at all stations; the January 1848 Bradshaw's lists most major
-# railways as using GMT.  By 1855 the vast majority of public
-# clocks in Britain were set to GMT (though some, like the Great Clock
-# in Tom Tower at Christ Church, Oxford, were fitted with two minute hands,
-# one for local time and one for GMT).  The last major holdout was the legal
-# system, which stubbornly stuck to local time for many years, leading
-# to oddities like polls opening at 08:13 and closing at 16:13.
-# The legal system finally switched to GMT when the Statutes (Definition
-# of Time) Act took effect; it received the Royal Assent on 1880 Aug 2.
-#
-# In the tables below, we condense this complicated story into a single
-# transition date for London, namely 1847 Sep 22.  We don't know as much
-# about Dublin, so we use 1880 Aug 2, the legal transition time.
-
-# From Arthur David Olson (January 19, 1989):
-#
-# A source at the British Information Office in New York avers that it's
-# known as "British" Summer Time in all parts of the United Kingdom.
-
-# Date: 4 Jan 89 08:57:25 GMT (Wed)
-# From: Jonathan Leffler <nih-csl!uunet!mcvax!sphinx.co.uk!john>
-# [British Summer Time] is fixed annually by Act of Parliament.
-# If you can predict what Parliament will do, you should be in
-# politics making a fortune, not computing.
-
-# From Peter Ilieve <peter@memex.co.uk> (September 3, 1993):
-#
-# Our Government...couldn't...make a decision after the 1989 consultation
-# exercise about the UK changing its timezone so it just let things drift
-# (different from deciding to keep the status quo).  According to the
-# Summer Time Order 1992 (SI 1992/1729) the dates of Summer Time for 1993
-# and 1994 are:
-#      Start           End
-# 1993 28 March        24 October
-# 1994 27 March        23 October
-# All start and end times are at 01:00 GMT.
-#
-# There [was] an error in your tables for the start and end times prior to 1981.
-# The UK always used to change at 02:00 GMT. In 1981 it changed to 01:00 GMT
-# as a part of EC harmonisation and has remained at that time since.
-#
-# I have found the default algorithm for UK Summer Time, it is in the
-# Summer Time Act 1972. Section 1 states that in the absence of an Order
-# in Council Summer Time starts at 02:00 GMT on the morning of the day
-# after the third Saturday in March, unless that day is Easter Day, in
-# which case it is the morning of the day after the second Saturday.
-# It ends at 02:00 GMT on the morning of the day after the fourth Saturday
-# in October. (All the redundant `morning of the day ...' is in the Act.)
-# This is only of passing interest now as it will always be overridden by
-# an Order in Council (a Statutary Instrument, the SI thing mentioned above)
-# to specify the EC specified dates.
-
-# From Peter Ilieve <peter@memex.co.uk> (October 18, 1993):
-#
-# My contact in the Ministry of Defence Public Relations department
-# accepted the challenge of looking into this and produced the following,
-# from Hansard (the official record of the UK Parliament), Oral Answers,
-# 1 March 1945, cols 1559--60:
-#
-# `58. Major Sir Goronwy Owen asked the Secretary of State for the Home
-# Department if he is now able to state the Government's proposals
-# regarding double summer time.
-#
-# [two other similar questions omitted]
-#
-# Mr. H. Morrison: The Government, in reviewing the matter, have
-# considered, [...] the conclusion has been reached that the adoption of
-# double summer time from the beginning of April is essential to the
-# maintenance of the war effort. [...] As 1st April is Easter Sunday,
-# when very early services are held in many churches, it is proposed that
-# double summer time shall start not in the night preceding Easter
-# Sunday, but in the night of Sunday- Monday so that it will operate from
-# Monday, 2nd April.'
-
-# From Peter Ilieve <peter@memex.co.uk> (September 3, 1993):
-#
-# > # Current rules
-# > Rule GB-Eire 1981  max     -       Mar     lastSun 1:00s   1:00    BST
-# > Rule GB-Eire 1981  max     -       Oct     Sun>=23 1:00s   0       GMT
-#
-# The ending rule here doesn't match the EC rules, which specify the fourth
-# Sunday in October for the UK and Eire. The `fourth Sunday' rule wasn't
-# followed in 1989, but then the sixth EC directive wasn't in force then
-# and I don't know what previous ones said. 1995 is the next year with
-# the 4th Sun on 22 Oct, but that year isn't covered by the UK Summer Time
-# Order or the sixth EC directive. Your Oct Sun>=23 rule matches history
-# and with things only announced for 2 years or so in advance who knows
-# what will happen.
-#
-# There are renewed rumours that the Government here will make another
-# attempt at resolving this issue, which is what prompted me to start
-# asking the Home Office and the EC about it again. The EC categorically
-# state they are not asking anybody to change timezone, they only want
-# common start/end dates. The UK Govt. seem to want to change our zone
-# and blame the resulting fuss on the EC. Me, I think we should scrap
-# summer time completely, noon is when the Sun is overhead, and that should
-# be the end of it.
-
-# From Peter Ilieve <peter@memex.co.uk> (October 22, 1993):
-#
-# I now have the text of the Summer Time Act 1916, the granddaddy of them all.
-# It is headed: `An Act to provide for the Time in Great Britain and Ireland
-# being in advance of Greenwich and Dublin mean time respectively in the
-# summer months'.
-#
-# It specifies 21 May and 1 October for 1916 (both at 02:00 GMT) and whatever
-# dates an Order in Council may specify for subsequent years.
-#
-# Section 4 states: `This act shall apply to Ireland in like manner as it
-# applies to Great Britain, with the substitution however of references
-# to Dublin mean time for references to Greenwich mean time.'
-#
-# Lorna, my learned legal friend who supplied it, also offers this quote
-# from Halsbury's Statutes on the extent of Acts:
-#
-# `An Act of the United Kingdom Parliament is to be construed prima facie
-# to apply to the whole of the United Kingdom and not to any place outside.
-# [...] The expression "United Kingdom" for this purpose includes (since
-# 1922) Great Britain (ie. England, Wales and Scotland) and Northern Ireland,
-# but it does not include the Channel Islands or the Isle of Man.'
-#
-# She goes on to say the seminal event of 1922 was the establishment of
-# the Irish Free State, now called Eire.
-#
-# The Act doesn't say anything about Wales (or Scotland) so I would assert
-# that Shanks is wrong here. I would like to know why he thinks Wales
-# was different.
-#
-# It also confirms the fact that Ireland followed Dublin time back then,
-# and 25 minutes behind Greenwich, as Shanks has it, would be correct.
-
-# From Peter Ilieve <peter@memex.co.uk> (October 28, 1993):
-#
-# I now have before me, thanks to my learned legal friend Lorna, the text of
-# the Time (Ireland) Act 1916.
-#
-# It says that as from 2 AM Dublin Mean Time on 1 October 1916 the time
-# for general purposes in Ireland shall be the same as the rest of Great
-# Britain (ie. GMT with the Summer Time periods specified by the Summer Time
-# Act 1916)....  As Ireland was behind GMT/BST at 02:00 DMT on 1 Oct GB would
-# have already put the clocks back. Using DST as Dublin Summer Time the
-# sequence would have been:
-# Dublin               London
-# 02:34 DST    02:59 BST
-# 02:35 DST    02:00 GMT
-# 02:59 DST    02:24 GMT
-# 02:25 GMT    02:25 GMT
-# with the transition 03:00 DST -> 02:00 DMT -> 02:25 GMT all at once.
-#
-# In a table of repeals in the Schedule to the Act it mentions the
-# Statutes (Definition of Time) Act 1880. This is presumably the source
-# of the 1880 date in Shanks.  The little bit of it that is repealed
-# also refers solely to Ireland and Dublin Mean Time.
-
-# From Peter Ilieve <peter@memex.co.uk> (October 29, 1993):
-#
-# My case is that, with the sole exception of Ireland in 1916 using Dublin
-# Mean Time, Summer Time has been uniform throughout the United Kingdom
-# ever since it first started in 1916.
-#
-# The United Kingdom is England, Wales and Scotland plus all of Ireland from
-# 1916 up to and including 1921, or plus Northern Ireland from 1922 to date.
-#
-# The dates used are those specified in the table in Summer Time: A Consultation
-# Document (Cm 722, 1989) that are now included in the europe file, with a
-# change to a single date, the start in 1924. I made a typo in my 1989 mail
-# and the table itself is also wrong.  The correct date is 13 April.
-# The times were 02:00 GMT up to and including 1980, 01:00 GMT from 1981 on,
-# except for wartime double summer time.
-#
-# As evidence I would cite:
-#
-# - The Summer Time Act, 1916.
-#
-# This specifically states that it applies to Ireland, specifies dates of
-# 21 May and 1 October and times of 02:00, and says that in Ireland the
-# times relate to Dublin mean time. It specifies an offset of 1 hour.
-#
-# - The Time (Ireland) Act, 1916
-#
-# This abolishes Dublin mean time on 02:00 DMT 1 October 1916.
-# It repeals that section of the Statutes (Definition of Time) Act, 1880
-# that specifies DMT. It is therefore a safe bet that DMT existed at least
-# from 1880 and was the only alternative standard time in the UK.
-#
-# - The Summer Time Act, 1922
-#
-# This specifies an offset of 1 hour and dates of the day after the third
-# Saturday in April, unless that be Easter, in which case it is the day after
-# the second Saturday, and the day after the third Saturday in September.
-# The time is 02:00 GMT. It applied in 1922 and 1923, and longer if Parliament
-# so approved.
-#
-# It specifically states that it applies to Northern Ireland, the Channel
-# Islands, and the Isle of Man.
-#
-# - The Summer Time Act, 1925
-#
-# This makes the 1922 Act permanent, with a change to the end date to the
-# day after the first Saturday in October. It says nothing about extent,
-# so that part of the 1922 Act will still apply.
-#
-# - The Defence (Summer Time) Regulations, 1939, SR&O 1939 No. 1379
-#   [SR&O == Statutary Regulation and Order]
-#
-# These were made under the Emergency Powers (Defence) Act, 1939.
-# It changes the end date to be the day after the third Saturday in November.
-# It makes consequential changes to some vehicle lighting legislation,
-# which includes the Motor Vehicles and Road Traffic (Northern Ireland) Act,
-# 1934, so it seems clear it applies in Northern Ireland.
-#
-# - An Order in Council amending the The Defence (Summer Time) Regulations,
-#   1939, SR&O 1940 No. 1883
-#
-# This continues summer time throughout the year after it starts in 1940.
-# It says nothing about extent and has no consequential changes.
-#
-# - An Order in Council amending the The Defence (Summer Time) Regulations,
-#   1939, SR&O 1941 No. 476
-#
-# This introduces double summer time, starting at 01:00 GMT on the day after
-# the first Saturday in May and ending at 01:00 GMT on the day after the
-# second Saturday in August, offset another hour from normal summer time,
-# which continues throughout the rest of the year. It goes on a lot about
-# consequential changes to agricultural wages legislation, and says in part
-# `... and in its application to Northern Ireland have effect as
-# if for the references to the Agricultural Wages (Regulation) Acts, 1924 and
-# 1940, there were substituted references to the Agricultural Wages (Regulation)
-# Acts (Northern Ireland), 1939 and 1940, ...'. It also has a similar section
-# for Scotland. Both sections substitute the local Agricultural Wages Board
-# for the Agricultural Wages Board for England and Wales, showing that
-# England and Wales were indivisible.
-#
-# - An Order in Council amending the The Defence (Summer Time) Regulations,
-#   1939, SR&O 1942 No. 506
-#
-# This changes the start date of double summer time to the day after the first
-# Saturday in April. It says nothing about extent.
-#
-# - An Order in Council amending the The Defence (Summer Time) Regulations,
-#   1939, SR&O 1944 No. 932
-#
-# This changed the end date of double summer time to 17 September 1944.
-# (I don't have the text of this, just a note of what it did, the text almost
-# certainly had the `day after the nth Saturday' form.)
-#
-# (I am missing whatever regulations there were to change things in 1945
-# and the Summer Time Act, 1947.)
-#
-# - The British Standard Time Act, 1968
-#
-# This came into force on 27 October 1968 and continued summer time throughout
-# the year as an experiment until it expired on 31 October 1971.
-# There was no double summer time so we didn't have to change the clocks at all.
-# It specifically said it applied to Northern Ireland. It also said it
-# applied to Jersey, Guernsey and the Isle of Man unless they passed
-# measures saying it didn't.
-#
-# - The Manx Time Act, 1968
-#
-# This is an Act of Tynwald (the Isle of Man Parliament) that said that
-# henceforth Manx time would be the same as the time in Great Britain.
-#
-# - The Summer Time Act, 1972
-#
-# This specified a reversion to normal summer time behaviour with a start
-# date of the day after the third Saturday in March, unless that is Easter,
-# when it is the day after the second Saturday, and an end date of the day
-# after the fourth Saturday in October. Times are at 02:00 GMT, offset is
-# 1 hour.
-#
-# It has the same wording about extent as the British Standard Time Act, 1968,
-# applying to Northern Ireland unconditionally and to Jersey, Guernsey and the
-# Isle of Man if they don't do something about it.
-#
-# (I am missing various Summer Time Orders that modified the 1972 Act to
-# harmonise with the EC since 1981. The major change is that the time changes
-# to 01:00 GMT.)
-#
-# - The Summer Time Order, 1992, SI 1992/1729 [SI == Statutary Instrument]
-#
-# This specifies dates of:
-#       Start       End
-# 1993  28 March    24 October
-# 1994  27 March    23 October
-# All start and end times are at 01:00 GMT....
-#
-# - Some text on the extent of Acts, from Halsbury's Statutes
-#
-# `An Act of the United Kingdom Parliament is to be construed prima facie
-# to apply to the whole of the United Kingdom and not to any place outside.
-# [...] The expression "United Kingdom" for this purpose includes (since
-# 1922) Great Britain (ie. England, Wales and Scotland) and Northern Ireland,
-# but it does not include the Channel Islands or the Isle of Man.'
-#
-# So, many of these measures specifically include Northern Ireland,
-# the Channel Islands and the Isle of Man. None of them exclude any
-# part of the UK. The default interpretation of Acts is that they apply
-# throughout the UK.
-#
-# With that, I rest my case Milud :-)
-#
-# Thanks are due to my learned legal friend Lorna Montgomerie, who dug out
-# the dusty old statutes, and to Melanie Allison of the Ministry of Defence,
-# who provided the wartime regulations and a snippet of Hansard explaining
-# why double summer time started on a Monday in 1945 (it was Easter).
-
-# From Peter Ilieve <peter@memex.co.uk> (November 18, 1993)
-#
-# Here is a revised version of my tabrules file for the perl script I sent
-# before. I have personally verified the various Orders back to 1953 and
-# all the Acts.
-#
-# There are no changes to the dates we already have.
-#
-# My doubt about an early start in 1967 on 18 Feb was misplaced, the Order
-# does say 18 Feb. This is an interesting case as the first Order gave a
-# different date of 7 April 1967 for the Isle of Man but this was changed
-# before it came into effect by another Order for the Isle of Man alone.
-#
-# I don't think I will be able to find any more of the earlier Orders.
-# The annual volumes for 1949--52 do not contain the various Summer Time
-# Orders. They therefore don't appear in the index. They rate a mention in
-# italics in the numerical list at the start but that is all.
-# I think what happens is that the annual volume is produced well after the
-# end of the year in question, by which time the Summer Time Order is spent.
-# They assume that nobody would ever be stupid enough to want to see it
-# again so they leave it out.
-#
-# It might be a good idea to put this table, or the output of tabscript
-# showing all the moves because of Easter, in the europe file comments in
-# place of my old transcription of the Green Paper table [the UK Government
-# paper "Summer Time: A Consultation Document" (HMSO Cm722 June 1989)].
-#
-#              Peter Ilieve            peter@memex.co.uk
-#
-#
-# ## control file for tabscript, a program to generate UK summer time dates
-# ## matching the table in Cm 722, the 1989 Green Paper.
-# ## Lines like this are comments.
-# ## Lines with a single # at the start are copied into the output
-# ## Control lines are of the form
-# ## <years> <start date> <end date> <flags> <double start> <double end>
-# ## <years> is either a single year or a hyphen separated range, with --
-# ## also accepted as I use this in TeX a lot.
-# ## <start date> and <end date> are a digit followed bu a month name.
-# ## It is either an nth Saturday or an explicit date, depending on <flags>.
-# ## 0 and/or none are used when there is no date, as during 1968--71.
-# ## <flags> can contain `fixed' to indicate explicit dates and `double'
-# ## to indicate double summer time dates are present.
-# ## At present double requires fixed as well.
-# ## <double start> and <double end> are like the start and end dates, with
-# ## the exception of the 0 and/or none feature.
-#
-# ## Blank lines are also ignored.
-#
-# ## Places where I am uncertain, not having personally verified the dates
-# ## against the Act or Order, are marked ???
-# ## These dates are taken from the Cm 722 table.
-#
-# # Summer Time Act, 1916
-# 1916 21 May 1 October fixed
-#
-# ## I haven't yet looked for Orders for 1916--22 and I doubt I will find them.
-# # unknown Order or Orders ???
-# 1917 8 apr 17 sep fixed
-# 1918 24 mar 30 sep fixed
-# 1919 30 mar 29 sep fixed
-# # end date extended in 1920 from 27 Sep because of coal strike (from Cm 722)
-# 1920 28 mar 25 oct fixed
-# 1921 3 apr 3 oct fixed
-#
-# # Summer Time Act, 1922
-# # came into force 22 July 1922, too late for 1922, so missing Order ???
-# 1922 26 mar 8 oct fixed
-# 1923-1924 3 April 3 September
-#
-# # Summer Time Act, 1925
-# 1925--1938 3 April 1 October
-#
-# # Defence (Summer Time) Regulations, 1939
-# 1939 3 April 3 November
-# # 1940 amendment (SR&O 1940 Nos. 172 & 1883)
-# 1940 4 feb 0 none
-# # 1941 amendment (SR&O 1941 No. 476)
-# 1941 0 none 0 none fixed,double 4 may 10 aug
-# # 1942 amendment (SR&O 1942 No. 506)
-# 1942 0 none 0 none fixed,double 5 apr 9 aug
-# 1943 0 none 0 none fixed,double 4 apr 15 aug
-# # 1944 amendment (SR&O 1944 No. 932)
-# 1944 0 none 0 none fixed,double 2 apr 17 sep
-# # 1945 dates from Hansard, Oral Answers, 1 March 1945
-# 1945 0 none 7 oct fixed,double 2 apr 15 jul
-#
-# # reversion to Summer Time Act, 1925
-# 1946 3 April 1 October
-#
-# # Summer Time Act, 1947
-# # Fixed dates for 1947 only, gives power to have double summer time
-# 1947 16 mar 2 nov fixed,double 13 apr 10 aug
-# ## I can't find any trace of the Order for 1948.
-# # Unknown Order ???
-# 1948 14 mar 31 oct fixed
-# ## I know the numbers for the 1949--52 ones but the text is missing from the
-# ## annual volumes. I also don't know if the 49 Order was for 49 or 50, etc.
-# # Summer Time Order, 1949 (SI1949/373) ???
-# 1949 3 apr 30 oct fixed
-# # Summer Time Order, 1950 (SI1950/518) ???
-# 1950 16 apr 22 oct fixed
-# # Summer Time Order, 1951 (SI1951/430) ???
-# 1951 15 apr 21 oct fixed
-# # Summer Time Order, 1952 (SI1952/451) ???
-# 1952 20 apr 26 oct fixed
-#
-# # reversion to Summer Time Act, 1925
-# 1953--1960 3 April 1 October
-#
-# ## All Orders from here on specify fixed dates, not day after nth Sunday
-# ## Start pattern looks like Mar lastSun up to 1963, Mar Sun>=19 up to 1967.
-# ## End pattern looks like Oct Sun>=23 up to 1967.
-# # Summer Time Order, 1961 (SI1961/71)
-# 1961 26 March 29 October fixed
-# # Summer Time (1962) Order, 1961 (SI1961/2465)
-# 1962 25 Mar 28 Oct fixed
-# # Summer Time Order, 1963 (SI1963/81)
-# 1963 31 March 27 October fixed
-# # Summer Time (1964) Order, 1963 (SI1963/2101)
-# 1964 22 March 25 October fixed
-# # Summer Time Order, 1964 (SI1964/1201)
-# 1965 21 Mar 24 Oct fixed
-# 1966 20 Mar 23 Oct fixed
-# 1967 19 Mar 29 Oct fixed
-# # Summer Time Order, 1967 (SI1967/1148)
-# # Specifies different start date of 7 April for Isle of Man
-# # Summer Time Order, 1968 (SI1968/117)
-# # Changes Isle of Man start date to 18 Feb to match rest of UK
-# # British Standard Time Act, 1968
-# 1968 18 feb 0 none fixed
-# 1969--1970 0 none 0 none
-# 1971 0 none 31 oct fixed
-#
-# # Summer Time Act, 1972
-# 1972-1980 3 March 4 October
-#
-# # The pattern here looks like Last Sun in Mar, day after 4th Sat in Oct
-# # First EC Directive ???
-# # Summer Time Order, 1980 (SI1980/1089)
-# 1981    29 Mar  25 Oct fixed
-# 1982    28 Mar  24 Oct fixed
-# # Second EC Directive ???
-# # Summer Time Order, 1982 (SI1982/1673)
-# 1983    27 Mar  23 Oct fixed
-# 1984    25 Mar  28 Oct fixed
-# 1985    31 Mar  27 Oct fixed
-# # Third EC Directive ???
-# # Summer Time Order, 1986 (SI1986/223)
-# 1986    30 Mar  26 Oct fixed
-# 1987    29 Mar  25 Oct fixed
-# 1988    27 Mar  23 Oct fixed
-# # Fourth EC Directive ???
-# # Summer Time Order, 1988 (SI1988/931)
-# 1989    26 Mar  29 Oct fixed
-# # Fifth EC Directive ???
-# # Summer Time Order, 1989 (SI1989/985)
-# 1990    25 Mar  28 Oct fixed
-# 1991    31 Mar  27 Oct fixed
-# 1992    29 Mar  25 Oct fixed
-# # Sixth EC Directive
-# # Summer Time Order, 1992 (SI1992/1729)
-# 1993    28 Mar  24 Oct fixed
-# 1994    27 Mar  23 Oct fixed
-
-# From Peter Ilieve <peter@memex.co.uk> (August 18, 1994):
-# I now have the text of the 7th EC directive on summer time arrangements
-# (94/21/EC), which was approved on 30 May....
-# The major changes from existing practice are that 1995 will be the last year
-# that the UK and Eire finish on a different date from everyone else,
-# and the common end date from 1996 onwards will be the last Sunday in October.
-# Year  Start          End             End (UK & Eire, 1995 only)
-# (rule) (last Sun)    (last Sun)      (4th Sun)
-# 1995 26 March        24 September    22 October
-# 1996 31 March        27 October
-# 1997 30 March        26 October
-#
-# From Peter Ilieve <peter@memex.co.uk> (1994-12-01):
-# The final piece of the legislative jigsaw for summer time in the UK for
-# 1995-97 is now in place.  The Summer Time Order 1994 (SI 1994/2798)
-# came into force on 16 November.  It restates the dates from the EC
-# seventh Summer Time Directive....
-
-# From Peter Ilieve <peter@memex.co.uk> (March 28, 1994):
-# The UK/Eire end date of 22 October [1995] conflicts with your current rule of
-# Oct Sun>=23, and the historical UK formula of Sun after 4th Sat.
-# The last time 4th Sun and Sun after 4th Sat differed was in 1989,
-# when 29 October was used.  That year was covered by a UK Summer Time Order
-# for only a single year and it looks as though there was a matching 4th EC
-# directive for just this year.  I don't have the text of the 5th EC
-# directive (for 1990--92) but my guess would be it said 4th Sun.
-# To maintain strict historical accuracy you could start a new UK ending rule
-# of Oct Sun>=22 in 1990.
-
-# From Paul Eggert <eggert@twinsun.com> (November 18, 1993):
-#
-# As Ilieve remarks, the date `20 April 1924' in the table of ``Summer Time: A
-# Consultation Document'' (Cm 722, 1989) table is a transcription error;
-# 20 April was an Easter Sunday.  Shanks has 13 April, the correct date.
-# Also, the table is not quite right for 1925 through 1938; the correct rules
-# (which Shanks uses) are given in the Summer Time Acts of 1922 and 1925.
-# Shanks and the UK Government paper disagree about the Apr 1956 transition;
-# since we have no other data, and since Shanks was correct in the other
-# points of disagreement about London, we'll believe Shanks for now.
-# Also, for lack of other data, we'll follow Shanks for Eire in 1940-1948.
-#
-# Given Peter Ilieve's comments, the following claims by Shanks are incorrect:
-#     * Wales did not switch from GMT to daylight savings time until
-#      1921 Apr 3, when they began to conform with the rest of Great Britain.
-# Actually, Wales was identical after 1880.
-#     * Eire had two transitions on 1916 Oct 1.
-# It actually just had one transition.
-#     * Northern Ireland used single daylight savings time throughout WW II.
-# Actually, it conformed to Britain.
-#
-# The following claim by Shanks is possible though doubtful;
-# we'll ignore it for now.
-#     * Jersey, Guernsey, and the Isle of Man did not switch from GMT
-#      to daylight savings time until 1921 Apr 3, when they began to
-#      conform with Great Britain.
-#
-# Whitman says Dublin Mean Time was -0:25:21, which is more precise than Shanks.
-
-# Rule NAME    FROM    TO      TYPE    IN      ON      AT      SAVE    LETTER/S
-Rule   GB-Eire 1847    only    -       Sep     22      0:00    0       GMT
-# 1916 to 1925--irregular
-Rule   GB-Eire 1916    only    -       May     21      2:00s   1:00    BST
-Rule   GB-Eire 1916    only    -       Oct      1      2:00s   0       GMT
-Rule   GB-Eire 1917    only    -       Apr      8      2:00s   1:00    BST
-Rule   GB-Eire 1917    only    -       Sep     17      2:00s   0       GMT
-Rule   GB-Eire 1918    only    -       Mar     24      2:00s   1:00    BST
-Rule   GB-Eire 1918    only    -       Sep     30      2:00s   0       GMT
-Rule   GB-Eire 1919    only    -       Mar     30      2:00s   1:00    BST
-Rule   GB-Eire 1919    only    -       Sep     29      2:00s   0       GMT
-Rule   GB-Eire 1920    only    -       Mar     28      2:00s   1:00    BST
-Rule   GB-Eire 1920    only    -       Oct     25      2:00s   0       GMT
-Rule   GB-Eire 1921    only    -       Apr      3      2:00s   1:00    BST
-Rule   GB-Eire 1921    only    -       Oct      3      2:00s   0       GMT
-Rule   GB-Eire 1922    only    -       Mar     26      2:00s   1:00    BST
-Rule   GB-Eire 1922    only    -       Oct      8      2:00s   0       GMT
-Rule   GB-Eire 1923    only    -       Apr     Sun>=16 2:00s   1:00    BST
-Rule   GB-Eire 1923    1924    -       Sep     Sun>=16 2:00s   0       GMT
-Rule   GB-Eire 1924    only    -       Apr     13      2:00s   1:00    BST
-# 1925 to 1939 start--regular, except for avoiding Easter
-Rule   GB-Eire 1925    1926    -       Apr     Sun>=16 2:00s   1:00    BST
-Rule   GB-Eire 1925    1938    -       Oct     Sun>=2  2:00s   0       GMT
-Rule   GB-Eire 1927    only    -       Apr     10      2:00s   1:00    BST
-Rule   GB-Eire 1928    1929    -       Apr     Sun>=16 2:00s   1:00    BST
-Rule   GB-Eire 1930    only    -       Apr     13      2:00s   1:00    BST
-Rule   GB-Eire 1931    1932    -       Apr     Sun>=16 2:00s   1:00    BST
-Rule   GB-Eire 1933    only    -       Apr      9      2:00s   1:00    BST
-Rule   GB-Eire 1934    only    -       Apr     Sun>=16 2:00s   1:00    BST
-Rule   GB-Eire 1935    only    -       Apr     14      2:00s   1:00    BST
-Rule   GB-Eire 1936    1937    -       Apr     Sun>=16 2:00s   1:00    BST
-Rule   GB-Eire 1938    only    -       Apr     10      2:00s   1:00    BST
-Rule   GB-Eire 1939    only    -       Apr     Sun>=16 2:00s   1:00    BST
-# 1939 end to 1947--irregular, and with double summer time
-Rule   GB-Eire 1939    only    -       Nov     19      2:00s   0       GMT
-Rule   GB-Eire 1940    only    -       Feb     25      2:00s   1:00    BST
-Rule   GB-Eire 1941    only    -       May     Sun>=2  1:00s   2:00    DST
-Rule   GB-Eire 1941    1943    -       Aug     Sun>=9  1:00s   1:00    BST
-Rule   GB-Eire 1942    1944    -       Apr     Sun>=2  1:00s   2:00    DST
-Rule   GB-Eire 1944    only    -       Sep     Sun>=16 1:00s   1:00    BST
-# Double daylight starts on a Monday in 1945--see above.
-Rule   GB-Eire 1945    only    -       Apr      2      1:00s   2:00    DST
-Rule   GB-Eire 1945    only    -       Jul     15      1:00s   1:00    BST
-Rule   GB-Eire 1945    only    -       Oct      7      2:00s   0       GMT
-Rule   GB-Eire 1946    only    -       Apr     14      2:00s   1:00    BST
-Rule   GB-Eire 1946    only    -       Oct      6      2:00s   0       GMT
-Rule   GB-Eire 1947    only    -       Mar     16      2:00s   1:00    BST
-Rule   GB-Eire 1947    only    -       Apr     13      1:00s   2:00    DST
-Rule   GB-Eire 1947    only    -       Aug     10      1:00s   1:00    BST
-Rule   GB-Eire 1947    only    -       Nov      2      2:00s   0       GMT
-# So much for double saving time.  1948 and 1949, irregular.
-Rule   GB-Eire 1948    only    -       Mar     14      2:00s   1:00    BST
-Rule   GB-Eire 1948    1949    -       Oct     lastSun 2:00s   0       GMT
-Rule   GB-Eire 1949    only    -       Apr      3      2:00s   1:00    BST
-# 1950 through start of 1953, regular.
-Rule   GB-Eire 1950    1953    -       Apr     Sun>=14 2:00s   1:00    BST
-Rule   GB-Eire 1950    1952    -       Oct     Sun>=21 2:00s   0       GMT
-# 1954 to 1980, starting rules
-Rule   GB-Eire 1954    only    -       Apr     11      2:00s   1:00    BST
-Rule   GB-Eire 1955    1956    -       Apr     Sun>=16 2:00s   1:00    BST
-Rule   GB-Eire 1957    only    -       Apr     14      2:00s   1:00    BST
-Rule   GB-Eire 1958    1959    -       Apr     Sun>=16 2:00s   1:00    BST
-Rule   GB-Eire 1960    only    -       Apr     10      2:00s   1:00    BST
-Rule   GB-Eire 1961    1963    -       Mar     lastSun 2:00s   1:00    BST
-Rule   GB-Eire 1964    1967    -       Mar     Sun>=19 2:00s   1:00    BST
-Rule   GB-Eire 1972    1980    -       Mar     Sun>=16 2:00s   1:00    BST
-# 1953 to 1980, ending rules
-Rule   GB-Eire 1953    1960    -       Oct     Sun>=1  2:00s   0       GMT
-Rule   GB-Eire 1961    1967    -       Oct     Sun>=23 2:00s   0       GMT
-Rule   GB-Eire 1971    only    -       Oct     31      3:00    0       GMT
-Rule   GB-Eire 1972    1980    -       Oct     Sun>=23 2:00s   0       GMT
-# 1981 on
-Rule   GB-Eire 1981    max     -       Mar     lastSun 1:00s   1:00    BST
-Rule   GB-Eire 1981    1989    -       Oct     Sun>=23 1:00s   0       GMT
-Rule   GB-Eire 1990    1995    -       Oct     Sun>=22 1:00s   0       GMT
-Rule   GB-Eire 1996    max     -       Oct     lastSun 1:00s   0       GMT
-#Rule  GB-Eire 1981    max     -       Mar     lastSun 1:00u   1:00    BST
-#Rule  GB-Eire 1981    1989    -       Oct     Sun>=23 1:00u   0       GMT
-#Rule  GB-Eire 1990    1995    -       Oct     Sun>=22 1:00u   0       GMT
-#Rule  GB-Eire 1996    max     -       Oct     lastSun 1:00u   0       GMT
-# Also see W-Eur, which (starting 1996) differs only in LETTER/S.
-
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Europe/London   -0:01:15 -      LMT     1847 Sep 22
-                        0:00   GB-Eire %s      1968 Feb 18 2:00
-                        1:00   -       BST     1971 Oct 31 2:00
-                        0:00   GB-Eire %s
-Zone   Europe/Belfast  -0:23:40 -      LMT     1880 Aug  2
-                       -0:25:21 -      DMT     1916 May 21 2:00    # Dublin MT
-                       -0:25:21 1:00   DST     1916 Oct  1 3:00
-                        0:00   GB-Eire %s      1968 Feb 18 2:00
-                        1:00   -       BST     1971 Oct 31 3:00
-                        0:00   GB-Eire %s
-Zone   Europe/Dublin   -0:25:21 -      LMT     1880 Aug  2
-                       -0:25:21 -      DMT     1916 May 21 2:00    # Dublin MT
-                       -0:25:21 1:00   DST     1916 Oct  1 3:00
-                        0:00   GB-Eire %s      1940 Feb 25 2:00
-                        0:00   1:00    BST     1946 Oct  6 2:00
-                        0:00   -       GMT     1947 Mar 16 2:00
-                        0:00   1:00    BST     1947 Nov  2 2:00
-                        0:00   -       GMT     1948 Apr 18 2:00
-                        0:00   GB-Eire %s      1968 Feb 18 2:00
-                        1:00   -       BST     1971 Oct 31 3:00
-                        0:00   GB-Eire %s
-
-###############################################################################
-
-# Continental Europe
-
-# The *-Eur rules now correspond to the European Community (EC).
-# Three rulesets are used because the EC changes at 01:00 UTC, not local time.
-# Older *-Eur rules are for convenience in the tables.
-
-# Rule NAME    FROM    TO      TYPE    IN      ON      AT      SAVE    LETTER/S
-Rule   W-Eur   1800    only    -       Jan      1       0:00   0       -
-Rule   W-Eur   1977    1980    -       Apr     Sun>=1   1:00s  1:00    " DST"
-Rule   W-Eur   1977    only    -       Sep     lastSun  1:00s  0       -
-Rule   W-Eur   1978    only    -       Oct      1       1:00s  0       -
-Rule   W-Eur   1979    1995    -       Sep     lastSun  1:00s  0       -
-Rule   W-Eur   1981    max     -       Mar     lastSun  1:00s  1:00    " DST"
-Rule   W-Eur   1996    max     -       Oct     lastSun  1:00s  0       -
-# Also see GB-Eire, which (starting 1996) differs only in LETTER/S.
-
-Rule   M-Eur   1800    only    -       Jan      1       0:00   0       -
-Rule   M-Eur   1916    only    -       Apr     30      23:00   1:00    " DST"
-Rule   M-Eur   1916    only    -       Oct      1       1:00   0       -
-Rule   M-Eur   1917    1918    -       Apr     Mon>=15  2:00s  1:00    " DST"
-Rule   M-Eur   1917    1918    -       Sep     Mon>=15  2:00s  0       -
-Rule   M-Eur   1940    only    -       Apr      1       2:00s  1:00    " DST"
-# Shanks says DST was continuous from 1940 Apr 1 to 1942 Nov 2; go with Whitman.
-Rule   M-Eur   1940    only    -       Dec     31       2:00s  0       -
-Rule   M-Eur   1941    only    -       Feb     25       2:00s  1:00    " DST"
-Rule   M-Eur   1941    only    -       Oct      5       2:00s  0       -
-Rule   M-Eur   1942    only    -       Jan      1       2:00s  1:00    " DST"
-Rule   M-Eur   1942    only    -       Nov      2       2:00s  0       -
-Rule   M-Eur   1943    only    -       Mar     29       2:00s  1:00    " DST"
-Rule   M-Eur   1943    only    -       Oct      4       2:00s  0       -
-Rule   M-Eur   1944    only    -       Apr      3       2:00s  1:00    " DST"
-# Whitman gives 1944 Oct 7; go with Shanks.
-Rule   M-Eur   1944    only    -       Oct      2       2:00s  0       -
-Rule   M-Eur   1977    1980    -       Apr     Sun>=1   2:00s  1:00    " DST"
-Rule   M-Eur   1977    only    -       Sep     lastSun  2:00s  0       -
-Rule   M-Eur   1978    only    -       Oct      1       2:00s  0       -
-Rule   M-Eur   1979    1995    -       Sep     lastSun  2:00s  0       -
-Rule   M-Eur   1981    max     -       Mar     lastSun  2:00s  1:00    " DST"
-Rule   M-Eur   1996    max     -       Oct     lastSun  2:00s  0       -
-
-Rule   E-Eur   1981    max     -       Mar     lastSun  3:00s  1:00    " DST"
-Rule   E-Eur   1981    1995    -       Sep     lastSun  3:00s  0       -
-Rule   E-Eur   1996    max     -       Oct     lastSun  3:00s  0       -
-
-# Rule NAME    FROM    TO      TYPE    IN      ON      AT      SAVE    LETTER/S
-Rule   Russia  1880    only    -       Jan      1       0:00   0       -
-Rule   Russia  1917    only    -       Jul      1      23:00   1:00    " DST"
-Rule   Russia  1917    only    -       Dec     28       0:00   0       -
-Rule   Russia  1918    only    -       May     31      22:00   2:00    " DDST"
-Rule   Russia  1918    only    -       Sep     17       0:00   1:00    " DST"
-Rule   Russia  1919    only    -       May     31      23:00   2:00    " DDST"
-Rule   Russia  1919    only    -       Jul      1       2:00   1:00    D
-Rule   Russia  1919    only    -       Aug     16       0:00   0       K
-Rule   Russia  1921    only    -       Feb     14      23:00   1:00    D
-# Shanks gives 1921 Mar 21 for the following transition.
-# From Andrew A. Chernov <ache@astral.msk.su> (November 12, 1993):
-# My sources says, that it is Mar 20, not 21.
-Rule   Russia  1921    only    -       Mar     20      23:00   2:00    DD
-Rule   Russia  1921    only    -       Sep      1       0:00   1:00    D
-Rule   Russia  1921    only    -       Oct      1       0:00   0       K
-Rule   Russia  1981    1984    -       Apr      1       0:00   1:00    D
-Rule   Russia  1981    1983    -       Oct      1       0:00   0       K
-Rule   Russia  1984    max     -       Sep     lastSun  2:00s  0       K
-Rule   Russia  1985    max     -       Mar     lastSun  2:00s  1:00    D
-
-# These are for backward compatibility with older versions.
-
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   WET             0:00    W-Eur   WET%s
-Zone   MET             1:00    M-Eur   MET%s
-Zone   EET             2:00    E-Eur   EET%s
-Zone   W-SU            3:00    M-Eur   ????
-
-# Tom Hoffman says that MET is also known as Central European Time
-
-Link   MET     CET
-
-# Albania
-# Rule NAME    FROM    TO      TYPE    IN      ON      AT      SAVE    LETTER/S
-Rule   Albania 1940    only    -       Jun     16      0:00    1:00    " DST"
-Rule   Albania 1942    only    -       Nov      2      3:00    0       -
-Rule   Albania 1943    only    -       Mar     29      2:00    1:00    " DST"
-Rule   Albania 1943    only    -       Apr     10      3:00    0       -
-Rule   Albania 1974    only    -       May      4      0:00    1:00    " DST"
-Rule   Albania 1974    only    -       Oct      2      0:00    0       -
-Rule   Albania 1975    only    -       May      1      0:00    1:00    " DST"
-Rule   Albania 1975    only    -       Oct      2      0:00    0       -
-Rule   Albania 1976    only    -       May      2      0:00    1:00    " DST"
-Rule   Albania 1976    only    -       Oct      3      0:00    0       -
-Rule   Albania 1977    only    -       May      8      0:00    1:00    " DST"
-Rule   Albania 1977    only    -       Oct      2      0:00    0       -
-Rule   Albania 1978    only    -       May      6      0:00    1:00    " DST"
-Rule   Albania 1978    only    -       Oct      1      0:00    0       -
-Rule   Albania 1979    only    -       May      5      0:00    1:00    " DST"
-Rule   Albania 1979    only    -       Sep     30      0:00    0       -
-Rule   Albania 1980    only    -       May      3      0:00    1:00    " DST"
-Rule   Albania 1980    only    -       Oct      4      0:00    0       -
-Rule   Albania 1981    only    -       Apr     26      0:00    1:00    " DST"
-Rule   Albania 1981    only    -       Sep     27      0:00    0       -
-Rule   Albania 1982    only    -       May      2      0:00    1:00    " DST"
-Rule   Albania 1982    only    -       Oct      3      0:00    0       -
-Rule   Albania 1983    only    -       Apr     18      0:00    1:00    " DST"
-Rule   Albania 1983    only    -       Oct      1      0:00    0       -
-Rule   Albania 1984    only    -       Apr      1      0:00    1:00    " DST"
-Rule   Albania 1984    only    -       Oct      1      0:00    0       -
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Europe/Tirane   1:19:20 -       LMT     1914
-                       1:00    -       MET     1940 Jun 16
-                       1:00    Albania MET%s   1985 Mar 31 1:00
-                       1:00    W-Eur   MET%s
-#                      This may change to `M-Eur' soon, for EC compatibility.
-
-# Andorra
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Europe/Andorra  0:06:04 -       LMT     1901
-                       0:00    -       WET     1946 Sep 30
-                       1:00    -       MET     1985 Mar 31 2:00
-                       1:00    M-Eur   MET%s
-
-# Austria
-# Rule NAME    FROM    TO      TYPE    IN      ON      AT      SAVE    LETTER/S
-Rule   Austria 1918    only    -       Jun     16      3:00    0       -
-Rule   Austria 1920    only    -       Apr      5      2:00s   1:00    " DST"
-Rule   Austria 1920    only    -       Sep     13      2:00s   0       -
-Rule   Austria 1945    only    -       Apr      2      2:00s   1:00    " DST"
-Rule   Austria 1945    only    -       Nov     18      2:00s   0       -
-Rule   Austria 1946    only    -       Apr     14      2:00s   1:00    " DST"
-Rule   Austria 1946    1948    -       Oct     Sun>=1  2:00s   0       -
-Rule   Austria 1947    only    -       Apr      6      2:00s   1:00    " DST"
-Rule   Austria 1948    only    -       Apr     18      2:00s   1:00    " DST"
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Europe/Vienna   1:05:20 -       LMT     1893 Apr
-                       1:00    M-Eur   MET%s   1918 Jun 16 3:00
-                       1:00    Austria MET%s   1940 Apr  1 2:00
-                       1:00    M-Eur   MET%s   1945 Apr  2 2:00
-                       1:00    Austria MET%s   1981 Mar 29 2:00
-                       1:00    M-Eur   MET%s
-
-# Belarus
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Europe/Minsk    1:50:16 -       LMT     1880
-                       2:31    Russia  LST%s   1919 Jul 1 2:00
-                       3:00    Russia  MS%s    1922 Oct
-                       2:00    -       EET     1930 Jun 21
-                       3:00    Russia  MS%s    1991 Mar 31 2:00s
-# From Paul Eggert <eggert@twinsun.com> (May 28, 1994): A guess at recent dates:
-                       2:00    1:00  "EET DST" 1991 Sep 29 2:00s
-                       2:00    -       EET     1992 Jan 19 2:00s
-                       3:00    Russia  MS%s
-
-# Belgium
-# Whitman and Shanks disagree; go with Shanks, usually.
-# Rule NAME    FROM    TO      TYPE    IN      ON      AT      SAVE    LETTER/S
-# From Whitman:
-Rule   Belgium 1919    only    -       Mar      1      23:00s  1:00    " DST"
-Rule   Belgium 1919    only    -       Oct      4      23:00s  0       -
-# Shanks gives 1920 Feb 14 23:00s; go with Whitman.
-Rule   Belgium 1920    1921    -       Mar     14      23:00s  1:00    " DST"
-Rule   Belgium 1920    only    -       Oct     23      23:00s  0       -
-Rule   Belgium 1921    only    -       Oct     25      23:00s  0       -
-Rule   Belgium 1922    only    -       Mar     25      23:00s  1:00    " DST"
-# Whitman gives 1927 Oct 1 2:00s and 1928 Oct 7 2:00s; go with Shanks.
-Rule   Belgium 1922    1928    -       Oct     Sat>=1  23:00s  0       -
-Rule   Belgium 1923    only    -       Apr     21      23:00s  1:00    " DST"
-Rule   Belgium 1924    only    -       Mar     29      23:00s  1:00    " DST"
-Rule   Belgium 1925    only    -       Apr      4      23:00s  1:00    " DST"
-Rule   Belgium 1926    only    -       Apr     17      23:00s  1:00    " DST"
-Rule   Belgium 1927    only    -       Apr      9      23:00s  1:00    " DST"
-Rule   Belgium 1928    only    -       Apr     14      23:00s  1:00    " DST"
-Rule   Belgium 1929    only    -       Apr     21       2:00s  1:00    " DST"
-Rule   Belgium 1929    1938    -       Oct     Sun>=2   2:00s  0       -
-Rule   Belgium 1930    only    -       Apr     13       2:00s  1:00    " DST"
-Rule   Belgium 1931    only    -       Apr     19       2:00s  1:00    " DST"
-Rule   Belgium 1932    only    -       Apr     17       2:00s  1:00    " DST"
-Rule   Belgium 1933    only    -       Mar     26       2:00s  1:00    " DST"
-Rule   Belgium 1934    only    -       Apr      8       2:00s  1:00    " DST"
-Rule   Belgium 1935    only    -       Mar     31       2:00s  1:00    " DST"
-Rule   Belgium 1936    only    -       Apr     19       2:00s  1:00    " DST"
-# Whitman says 1937 Apr 18 2:00s; go with Shanks.
-Rule   Belgium 1937    only    -       Apr      4       2:00s  1:00    " DST"
-# Whitman says 1938 Apr 10 2:00s; go with Shanks.
-Rule   Belgium 1938    only    -       Mar     27       2:00s  1:00    " DST"
-Rule   Belgium 1939    only    -       Apr     16       2:00s  1:00    " DST"
-Rule   Belgium 1939    only    -       Nov     19       2:00s  0       -
-Rule   Belgium 1945    only    -       Apr      2       2:00s  1:00    " DST"
-Rule   Belgium 1945    only    -       Sep     16       2:00s  0       -
-Rule   Belgium 1946    only    -       May     19       2:00s  1:00    " DST"
-Rule   Belgium 1946    only    -       Oct      7       2:00s  0       -
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Europe/Brussels 0:17:20 -       LMT     1880
-                       0:17    -       BST     1892 May  1 12:00
-                       0:00    -       WET     1914 Aug  4
-                       1:00    M-Eur   MET%s   1919 Mar  1 23:00
-                       0:00    Belgium WET%s   1940 Feb 24 23:00
-                       1:00    M-Eur   MET%s   1945 Apr  2  2:00
-                       1:00    Belgium MET%s   1977 Apr  3  2:00
-                       1:00    M-Eur   MET%s
-
-# Bosnia and Herzegovina
-# They switched from the Julian to the Gregorian calendar on 1918 Mar 18.
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Europe/Sarajevo 1:13:40 -       LMT     1884
-                       1:00    -       MET     1941 Apr 18 23:00
-                       1:00    M-Eur   MET%s   1945 May  8  2:00s
-                       1:00    1:00  "MET DST" 1945 Sep 16  2:00s
-                       1:00    -       MET     1983 Mar 27  2:00s
-                       1:00    M-Eur   MET%s
-
-# Bulgaria
-# Part switched from the Julian to the Gregorian calendar on 1915 Nov 14;
-# the rest switched on 1920 Sep 17.
-# Rule NAME    FROM    TO      TYPE    IN      ON      AT      SAVE    LETTER/S
-Rule   Bulg    1979    only    -       Mar     31      23:00   1:00    " DST"
-Rule   Bulg    1979    only    -       Oct      1       1:00   0       -
-Rule   Bulg    1980    1982    -       Apr     Sat<=7  23:00   1:00    " DST"
-Rule   Bulg    1980    only    -       Sep     29       1:00   0       -
-Rule   Bulg    1981    only    -       Sep     27       2:00   0       -
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Europe/Sofia    1:33:16 -       LMT     1880
-                       1:57    -       TST     1894 Nov 30
-                       2:00    -       EET     1942 Nov  2  3:00
-                       1:00    M-Eur   MET%s   1945 Apr  2  3:00
-                       2:00    -       EET     1979 Mar 31 23:00
-                       2:00    Bulg    EET%s   1982 Sep 26  2:00
-                       2:00    M-Eur   EET%s
-#                      This may change to `E-Eur' soon, for EC compatibility.
-
-# Croatia
-# They switched from the Julian to the Gregorian calendar on 1918 Mar 18.
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Europe/Zagreb   1:03:52 -       LMT     1884
-                       1:00    -       MET     1941 Apr 18 23:00
-                       1:00    M-Eur   MET%s   1945 May  8  2:00s
-                       1:00    1:00  "MET DST" 1945 Sep 16  2:00s
-                       1:00    -       MET     1983 Mar 27  2:00s
-                       1:00    M-Eur   MET%s
-
-# Czech Republic
-# Rule NAME    FROM    TO      TYPE    IN      ON      AT      SAVE    LETTER/S
-Rule   Czech   1944    only    -       Sep     17      2:00s   0       -
-Rule   Czech   1945    only    -       Apr      8      2:00s   1:00    " DST"
-Rule   Czech   1945    only    -       Nov     18      2:00s   0       -
-Rule   Czech   1946    only    -       May      6      2:00s   1:00    " DST"
-Rule   Czech   1946    1949    -       Oct     Sun>=1  2:00s   0       -
-Rule   Czech   1947    only    -       Apr     20      2:00s   1:00    " DST"
-Rule   Czech   1948    only    -       Apr     18      2:00s   1:00    " DST"
-Rule   Czech   1949    only    -       Apr      9      2:00s   1:00    " DST"
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Europe/Prague   0:57:44 -       LMT     1850
-                       0:58    -       PMT     1891 Oct     # Prague Mean Time
-                       1:00    M-Eur   MET%s   1944 Sep 17 2:00s
-                       1:00    Czech   MET%s   1979 Apr  1 2:00
-                       1:00    M-Eur   MET%s
-
-# Denmark
-# Rule NAME    FROM    TO      TYPE    IN      ON      AT      SAVE    LETTER/S
-Rule   Denmark 1916    only    -       May     14      23:00   1:00    " DST"
-Rule   Denmark 1916    only    -       Sep     30      23:00   0       -
-Rule   Denmark 1940    only    -       May     15       0:00   1:00    " DST"
-Rule   Denmark 1945    only    -       Apr      2       2:00s  1:00    " DST"
-Rule   Denmark 1945    only    -       Aug     15       2:00s  0       -
-Rule   Denmark 1946    only    -       May      1       2:00s  1:00    " DST"
-Rule   Denmark 1946    only    -       Sep      1       2:00s  0       -
-Rule   Denmark 1947    only    -       May      4       2:00s  1:00    " DST"
-Rule   Denmark 1947    only    -       Aug     10       2:00s  0       -
-Rule   Denmark 1948    only    -       May      9       2:00s  1:00    " DST"
-Rule   Denmark 1948    only    -       Aug      8       2:00s  0       -
-# Whitman also gives 1949 Apr 9 to 1949 Oct 1, and disagrees in minor ways
-# about many of the above dates; go with Shanks.
-#
-# For 1894, Shanks says Jan, Whitman Apr; go with Whitman.
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone Europe/Copenhagen  0:50:20 -      LMT     1890
-                        0:50   -       CMT     1894 Apr  # Copenhagen Mean Time
-                        1:00   Denmark MET%s   1942 Nov  2 2:00s
-                        1:00   M-Eur   MET%s   1945 Apr  2 2:00
-                        1:00   Denmark MET%s   1980 Apr  6 2:00
-                        1:00   M-Eur   MET%s
-Zone Atlantic/Faeroe   -0:27:04 -      LMT     1908 Jan 11     # Torshavn
-                        0:00   -       WET     1981 Mar 29 1:00
-                        0:00   W-Eur   WET%s
-Zone America/Scoresbysund -1:29:00 -   LMT     1916 Jul 28
-                       -2:00   -       MGT     1980 Apr  6 2:00
-                       -2:00   M-Eur   MGT%s   1981 Mar 29
-                       -1:00   M-Eur   EGT%s
-Zone America/Godthab   -3:26:56 -      LMT     1916 Jul 28
-                       -3:00   -       WGT     1980 Apr  6 2:00
-                       -3:00   M-Eur   WGT%s
-Zone America/Thule     -4:35:08 -      LMT     1916 Jul 28
-                       -4:00   -       AST
-
-# Estonia
-# They switched from the Julian to the Gregorian calendar on 1918 Feb 15.
-#
-# From Peter Ilieve <peter@memex.co.uk> (1994-10-15):
-# A relative in Tallinn confirms the accuracy of the data for 1989 onwards
-# [through 1994] and gives the legal authority for it,
-# a regulation of the Government of Estonia, No. 111 of 1989....
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Europe/Tallinn  1:39:00 -       LMT     1880
-                       1:39    -       LST     1918 Feb
-                       1:00    M-Eur   MET%s   1919 Jul
-                       1:39    -       LST     1921 May
-                       2:00    -       EET     1940 Aug  6
-                       3:00    -       MSK     1941 Sep 15
-                       1:00    M-Eur   MET%s   1944 Sep 22
-                       3:00    Russia  MS%s    1989 Mar 26 2:00s
-                       2:00    1:00  "EET DST" 1989 Sep 24 2:00s
-                       2:00    M-Eur   EET%s
-#                      This may change to `E-Eur' soon, for EC compatibility.
-
-# Finland
-#
-# From Hannu Strang <chs@apu.fi> (25 Sep 1994 06:03:37 UTC):
-# Well, here in Helsinki we're just changing from summer time to regular one,
-# and it's supposed to change at 4am...
-#
-# From Paul Eggert <eggert@twinsun.com> (25 Sep 1994):
-# Shanks says Finland has switched at 02:00 standard time since 1981.
-# Go with Strang instead.
-#
-# Rule NAME    FROM    TO      TYPE    IN      ON      AT      SAVE    LETTER/S
-Rule   Finland 1921    only    -       May     1       0:00    0       -
-Rule   Finland 1942    only    -       Apr     3       0:00    1:00    " DST"
-Rule   Finland 1942    only    -       Oct     3       0:00    0       -
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Europe/Helsinki 1:39:52 -       LMT     1878 May 31
-                       1:40    -       HMT     1921 May    # Helsinki Mean Time
-                       2:00    Finland EET%s   1981 Mar 29 2:00
-                       2:00    E-Eur   EET%s
-
-# France
-# Shanks seems to use `24:00' ambiguously; we resolve it with Whitman.
-# From Shanks (1991):
-# Rule NAME    FROM    TO      TYPE    IN      ON      AT      SAVE    LETTER/S
-Rule   France  1911    only    -       Jan      1       0:00   0       -
-Rule   France  1916    only    -       Jun     14      23:00s  1:00    " DST"
-Rule   France  1916    1919    -       Oct     Sun>=1   0:00   0       -
-Rule   France  1917    only    -       Mar     24      23:00s  1:00    " DST"
-Rule   France  1918    only    -       Mar      9      23:00s  1:00    " DST"
-Rule   France  1919    only    -       Mar      1      23:00s  1:00    " DST"
-Rule   France  1920    only    -       Feb     14      23:00s  1:00    " DST"
-Rule   France  1920    only    -       Oct     23      23:00s  0       -
-Rule   France  1921    only    -       Mar     14      23:00s  1:00    " DST"
-Rule   France  1921    only    -       Oct     25      23:00s  0       -
-Rule   France  1922    only    -       Mar     25      23:00s  1:00    " DST"
-Rule   France  1922    1938    -       Oct     Sat>=1  23:00s  0       -
-Rule   France  1923    only    -       May     26      23:00s  1:00    " DST"
-Rule   France  1924    only    -       Mar     29      23:00s  1:00    " DST"
-Rule   France  1925    only    -       Apr      4      23:00s  1:00    " DST"
-Rule   France  1926    only    -       Apr     17      23:00s  1:00    " DST"
-Rule   France  1927    only    -       Apr      9      23:00s  1:00    " DST"
-Rule   France  1928    only    -       Apr     14      23:00s  1:00    " DST"
-Rule   France  1929    only    -       Apr     20      23:00s  1:00    " DST"
-Rule   France  1930    only    -       Apr     12      23:00s  1:00    " DST"
-Rule   France  1931    only    -       Apr     18      23:00s  1:00    " DST"
-Rule   France  1932    only    -       Apr      2      23:00s  1:00    " DST"
-Rule   France  1933    only    -       Mar     25      23:00s  1:00    " DST"
-Rule   France  1934    only    -       Apr      7      23:00s  1:00    " DST"
-Rule   France  1935    only    -       Mar     30      23:00s  1:00    " DST"
-Rule   France  1936    only    -       Apr     18      23:00s  1:00    " DST"
-Rule   France  1937    only    -       Apr      3      23:00s  1:00    " DST"
-Rule   France  1938    only    -       Mar     26      23:00s  1:00    " DST"
-Rule   France  1939    only    -       Apr     15      23:00s  1:00    " DST"
-Rule   France  1939    only    -       Nov     18      23:00s  0       -
-Rule   France  1940    only    -       Feb     25       2:00   1:00    " DST"
-# The French rules for 1941-1944 were not used in Paris,
-# but were used in other places (e.g. Monaco).
-Rule   France  1941    only    -       May      5       0:00   2:00    " DDST"
-Rule   France  1941    only    -       Oct      6       1:00   1:00    " DST"
-Rule   France  1942    only    -       Mar      8       0:00   2:00    " DDST"
-Rule   France  1942    only    -       Nov      2       3:00   1:00    " DST"
-Rule   France  1943    only    -       Mar     29       2:00   2:00    " DDST"
-Rule   France  1943    only    -       Nov      4       3:00   1:00    " DST"
-Rule   France  1944    only    -       Apr      3       2:00   2:00    " DDST"
-Rule   France  1944    only    -       Oct      8       1:00   1:00    " DST"
-Rule   France  1945    only    -       Apr      2       2:00   2:00    " DDST"
-Rule   France  1945    only    -       Sep     16       3:00   0       -
-# From Paul Eggert <eggert@twinsun.com) (November 18, 1993):
-# Shanks gives no times for 1975, but according to Cm722,
-# France introduced summer time in 1975 from 20 March to 22 September.
-Rule   France  1975    only    -       Mar     20       2:00s  1:00    " DST"
-Rule   France  1975    only    -       Sep     22       2:00s  0       -
-Rule   France  1976    only    -       Mar     28       2:00s  1:00    " DST"
-Rule   France  1976    only    -       Sep     lastSun  2:00s  0       -
-# Shanks gives 0:09 for Paris Mean Time; go with Whitman's more precise 0:09:05.
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Europe/Paris    0:09:05 -       LMT     1891 Mar 15 0:01
-                       0:09:05 -       PMT     1911 Mar 11    # Paris Mean Time
-                       0:00    France  WET%s   1940 Jun 14
-                       1:00    M-Eur   MET%s   1944 Aug 25
-                       0:00    France  WET%s   1945 Sep 16 3:00
-                       1:00    France  MET%s   1977 Apr Sun>=1 2:00
-                       1:00    M-Eur   MET%s
-
-# Germany
-# Rule NAME    FROM    TO      TYPE    IN      ON      AT      SAVE    LETTER/S
-Rule   Germany 1945    only    -       Apr      2      2:00s   1:00    " DST"
-Rule   Germany 1945    only    -       May     24      2:00    2:00    " DDST"
-Rule   Germany 1945    only    -       Sep     24      3:00    1:00    " DST"
-Rule   Germany 1945    only    -       Nov     18      2:00s   0       -
-Rule   Germany 1946    only    -       Apr     14      2:00s   1:00    " DST"
-# Whitman gives 1948 Oct 31; go with Shanks.
-Rule   Germany 1946    1949    -       Oct     Sun>=1  2:00s   0       -
-Rule   Germany 1947    only    -       Apr      6      2:00s   1:00    " DST"
-Rule   Germany 1947    only    -       May     11      2:00s   2:00    " DDST"
-Rule   Germany 1947    only    -       Jun     29      3:00    1:00    " DST"
-Rule   Germany 1948    only    -       Apr     18      2:00s   1:00    " DST"
-Rule   Germany 1949    only    -       Apr     10      2:00s   1:00    " DST"
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Europe/Berlin   0:53:28 -       LMT     1893 Apr
-                       1:00    M-Eur   MET%s   1945 Apr 2 2:00
-                       1:00    Germany MET%s   1980 Apr 6 2:00
-                       1:00    M-Eur   MET%s
-
-# Gibraltar
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone Europe/Gibraltar  -0:21:24 -      LMT     1880 Aug  2
-                       0:00    GB-Eire %s      1957 Apr 14 2:00
-                       1:00    -       MET     1982 Mar 28 2:00
-                       1:00    M-Eur   MET%s
-
-# Greece
-# They adopted the Julian calendar in 1846.
-# Part switched to the Gregorian calendar on 1916 Jul 28.
-# The rest switched on 1920 Mar 18.
-# Rule NAME    FROM    TO      TYPE    IN      ON      AT      SAVE    LETTER/S
-Rule   Greece  1916    only    -       July    28      0:01    0       -
-# Whitman gives 1932 Jul 5 - Nov 1; go with Shanks.
-Rule   Greece  1932    only    -       Jul      7      0:00    1:00    " DST"
-Rule   Greece  1932    only    -       Sep      1      0:00    0       -
-# Whitman gives 1941 Apr 25 - ?; go with Shanks.
-Rule   Greece  1941    only    -       Apr      7      0:00    1:00    " DST"
-# Whitman gives 1942 Feb 2 - ?; go with Shanks.
-Rule   Greece  1942    only    -       Nov      2      3:00    0       -
-Rule   Greece  1943    only    -       Mar     30      0:00    1:00    " DST"
-Rule   Greece  1943    only    -       Oct      4      0:00    0       -
-# Whitman gives 1944 Oct 3 - Oct 31; go with Shanks.
-Rule   Greece  1952    only    -       Jul      1      0:00    1:00    " DST"
-Rule   Greece  1952    only    -       Nov      2      0:00    0       -
-Rule   Greece  1975    only    -       Apr     12      0:00s   1:00    " DST"
-Rule   Greece  1975    only    -       Nov     26      0:00s   0       -
-Rule   Greece  1976    only    -       Apr     11      2:00s   1:00    " DST"
-Rule   Greece  1976    only    -       Oct     10      2:00s   0       -
-Rule   Greece  1977    1978    -       Apr     Sun>=1  2:00s   1:00    " DST"
-Rule   Greece  1977    only    -       Sep     26      2:00s   0       -
-Rule   Greece  1978    only    -       Sep     24      4:00    0       -
-Rule   Greece  1979    only    -       Apr      1      9:00    1:00    " DST"
-Rule   Greece  1979    only    -       Sep     29      2:00    0       -
-Rule   Greece  1980    only    -       Apr      1      0:00    1:00    " DST"
-Rule   Greece  1980    only    -       Sep     28      0:00    0       -
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Europe/Athens   1:34:52 -       LMT     1895 Sep 14
-                       1:35    -       AMT     1916 Jul 28 0:01     # Athens MT
-                       2:00    Greece  EET%s   1941 Apr 30
-                       1:00    Greece  MET%s   1944 Apr  4
-                       2:00    Greece  EET%s   1981 Mar 29 2:00
-#                      Greece must change by 1996 for EC compatibility.
-                       2:00    M-Eur   EET%s   1996 # Guess the last minute.
-                       2:00    E-Eur   EET%s
-
-# Hungary
-# Rule NAME    FROM    TO      TYPE    IN      ON      AT      SAVE    LETTER/S
-Rule   Hungary 1918    only    -       Sep     29       2:00s  0       -
-Rule   Hungary 1919    only    -       Apr     15       3:00   1:00    " DST"
-Rule   Hungary 1919    only    -       Sep     15       3:00   0       -
-Rule   Hungary 1920    only    -       Apr      5       3:00   1:00    " DST"
-Rule   Hungary 1920    only    -       Sep     30       3:00   0       -
-Rule   Hungary 1945    only    -       May      1      23:00   1:00    " DST"
-Rule   Hungary 1945    only    -       Nov      3       0:00   0       -
-Rule   Hungary 1946    only    -       Mar     31       2:00s  1:00    " DST"
-Rule   Hungary 1946    1949    -       Oct     Sun>=1   2:00s  0       -
-Rule   Hungary 1947    1949    -       Apr     Sun>=4   2:00s  1:00    " DST"
-Rule   Hungary 1950    only    -       Apr     17       2:00s  1:00    " DST"
-Rule   Hungary 1950    only    -       Oct     23       2:00s  0       -
-Rule   Hungary 1954    1955    -       May     23       0:00   1:00    " DST"
-Rule   Hungary 1954    1955    -       Oct      3       0:00   0       -
-Rule   Hungary 1956    only    -       Jun     Sun>=1   0:00   1:00    " DST"
-Rule   Hungary 1956    only    -       Sep     lastSun  0:00   0       -
-Rule   Hungary 1957    only    -       Jun     Sun>=1   1:00   1:00    " DST"
-Rule   Hungary 1957    only    -       Sep     lastSun  3:00   0       -
-Rule   Hungary 1980    only    -       Apr      6       1:00   1:00    " DST"
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Europe/Budapest 1:16:20 -       LMT     1890 Oct
-                       1:00    M-Eur   MET%s   1918 Jul
-                       1:00    Hungary MET%s   1941 Apr  6  2:00
-                       1:00    M-Eur   MET%s   1945 May  1 23:00
-                       1:00    Hungary MET%s   1980 Sep 28  2:00s
-                       1:00    M-Eur   MET%s
-
-# Iceland
-#
-# From Adam David <adam@veda.is> (November 6, 1993):
-# The name of the timezone in Iceland for system / mail / news purposes is GMT.
-#
-# (December 5, 1993):
-# This material is paraphrased from the 1988 edition of the University of
-# Iceland Almanak.
-#
-# From January 1st, 1908 the whole of Iceland was standardised at 1 hour
-# behind GMT. Previously, local mean solar time was used in different parts
-# of Iceland, the almanak had been based on Reykjavik mean solar time which
-# was 1 hour and 28 minutes behind GMT.
-#
-# "first day of winter" referred to [below] means the first day of the 26 weeks
-# of winter, according to the old icelandic calendar that dates back to the
-# time the norsemen first settled Iceland.  The first day of winter is always
-# Saturday, but is not dependent on the Julian or Gregorian calendars.
-#
-# (December 10, 1993):
-# I have a reference from the Oxford Icelandic-English dictionary for the
-# beginning of winter, which ties it to the ecclesiastical calendar (and thus
-# to the julian/gregorian calendar) over the period in question.
-#      the winter begins on the Saturday next before St. Luke's day
-#      (old style), or on St. Luke's day, if a Saturday.
-# St. Luke's day ought to be traceable from ecclesiastical sources. "old style"
-# might be a reference to the Julian calendar as opposed to Gregorian, or it
-# might mean something else (???). The Gregorian calendar was not introduced
-# in Iceland until 1700.
-#
-# From Paul Eggert <eggert@twinsun.com> (December 9, 1993):
-# The Iceland Almanak, Shanks and Whitman disagree on many points.
-# We go with the Almanak, except for one claim from Shanks, namely that
-# Reykavik was -1:28 from 1837 to 1908, local mean time before that.
-#
-# Rule NAME    FROM    TO      TYPE    IN      ON      AT      SAVE    LETTER/S
-Rule   Iceland 1908    only    -       Jan      1       0:00   0       S
-Rule   Iceland 1917    1918    -       Feb     19      23:00   1:00    D
-Rule   Iceland 1917    only    -       Oct     21       1:00   0       S
-Rule   Iceland 1918    only    -       Nov     16       1:00   0       S
-Rule   Iceland 1939    only    -       Apr     29      23:00   1:00    D
-Rule   Iceland 1939    only    -       Nov     29       2:00   0       S
-Rule   Iceland 1940    only    -       Feb     25       2:00   1:00    D
-Rule   Iceland 1940    only    -       Nov      3       2:00   0       S
-Rule   Iceland 1941    only    -       Mar      2       1:00s  1:00    D
-Rule   Iceland 1941    only    -       Nov      2       1:00s  0       S
-Rule   Iceland 1942    only    -       Mar      8       1:00s  1:00    D
-Rule   Iceland 1942    only    -       Oct     25       1:00s  0       S
-# 1943-1946 - first Sunday in March until first Sunday in winter
-Rule   Iceland 1943    1946    -       Mar     Sun>=1   1:00s  1:00    D
-Rule   Iceland 1943    1948    -       Oct     Sun>=22  1:00s  0       S
-# 1947-1967 - first Sunday in April until first Sunday in winter
-Rule   Iceland 1947    1967    -       Apr     Sun>=1   1:00s  1:00    D
-# 1949 Oct transition delayed by 1 week
-Rule   Iceland 1949    only    -       Oct     30       1:00s  0       S
-Rule   Iceland 1950    1966    -       Oct     Sun>=22  1:00s  0       S
-Rule   Iceland 1967    only    -       Oct     29       1:00s  0       S
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone Atlantic/Reykjavik        -1:27:24 -      LMT     1837
-                       -1:28   -       RMT     1908       # Reykjavik Mean Time
-                       -1:00   Iceland I%sT    1968 Apr 7 1:00s
-                        0:00   -       GMT
-
-# Italy
-# Rule NAME    FROM    TO      TYPE    IN      ON      AT      SAVE    LETTER/S
-Rule   Italy   1893    only    -       Nov      1      0:00s   0       S
-# Shanks gives transition times of 1916-1920 as 24:00; go with Whitman.
-Rule   Italy   1916    only    -       Jun      3      0:00s   1:00    " DST"
-Rule   Italy   1916    only    -       Sep     30      0:00s   0       -
-Rule   Italy   1917    only    -       Mar     31      0:00s   1:00    " DST"
-Rule   Italy   1917    only    -       Sep     30      0:00s   0       -
-Rule   Italy   1918    only    -       Mar      9      0:00s   1:00    " DST"
-Rule   Italy   1918    1919    -       Oct     Sun>=1  0:00s   0       -
-Rule   Italy   1919    only    -       Mar      1      0:00s   1:00    " DST"
-Rule   Italy   1920    only    -       Mar     20      0:00s   1:00    " DST"
-# Shanks gives 1920 Sep 18; go with Whitman.
-Rule   Italy   1920    only    -       Oct      1      0:00s   0       -
-Rule   Italy   1940    only    -       Jun     15      0:00    1:00    " DST"
-Rule   Italy   1945    only    -       Apr      2      2:00    1:00    " DST"
-Rule   Italy   1945    only    -       Sep     17      0:00    0       -
-Rule   Italy   1946    only    -       Mar     17      2:00s   1:00    " DST"
-Rule   Italy   1946    only    -       Oct      6      2:00s   0       -
-Rule   Italy   1947    only    -       Mar     16      0:00s   1:00    " DST"
-Rule   Italy   1947    only    -       Oct      5      0:00s   0       -
-Rule   Italy   1948    only    -       Feb     29      2:00s   1:00    " DST"
-Rule   Italy   1948    only    -       Oct      3      2:00s   0       -
-Rule   Italy   1966    1968    -       May     Sun>=22 0:00    1:00    " DST"
-Rule   Italy   1966    1969    -       Sep     Sun>=22 0:00    0       -
-Rule   Italy   1969    only    -       Jun      1      0:00    1:00    " DST"
-Rule   Italy   1970    only    -       May     31      0:00    1:00    " DST"
-Rule   Italy   1970    only    -       Sep     lastSun 0:00    0       -
-Rule   Italy   1971    1972    -       May     Sun>=22 0:00    1:00    " DST"
-Rule   Italy   1971    only    -       Sep     lastSun 1:00    0       -
-Rule   Italy   1972    only    -       Oct      1      0:00    0       -
-Rule   Italy   1973    only    -       Jun      3      0:00    1:00    " DST"
-Rule   Italy   1973    1974    -       Sep     lastSun 0:00    0       -
-Rule   Italy   1974    only    -       May     26      0:00    1:00    " DST"
-Rule   Italy   1975    only    -       Jun      1      0:00s   1:00    " DST"
-Rule   Italy   1975    1977    -       Sep     lastSun 0:00s   0       -
-Rule   Italy   1976    only    -       May     30      0:00s   1:00    " DST"
-Rule   Italy   1977    1979    -       May     Sun>=22 0:00s   1:00    " DST"
-Rule   Italy   1978    only    -       Oct      1      0:00s   0       -
-Rule   Italy   1979    only    -       Sep     30      0:00s   0       -
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Europe/Rome     0:49:56 -       LMT     1866 Sep 22
-                       0:50    -       RMT     1893 Nov        # Rome Mean Time
-                       1:00    Italy   MET%s   1942 Nov  2 2:00s
-                       1:00    M-Eur   MET%s   1945 Apr  2 2:00s
-                       1:00    Italy   MET%s   1980 Apr  6 2:00
-                       1:00    M-Eur   MET%s
-# Vatican is identical to Europe/Rome; San Marino is like Europe/Rome.
-
-# Latvia
-# They switched from the Julian to the Gregorian calendar on 1918 Feb 15.
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Europe/Riga     1:36:24 -       LMT     1880
-                       1:36    -       LST     1918 Apr 15 2:00
-                       1:36    M-Eur   LST%s   1919 Apr  1 2:00
-                       1:36    1:00  "LST DST" 1919 May 22 3:00
-                       1:36    -       LST     1926 May 11
-                       2:00    -       EET     1940 Aug  5
-                       3:00    -       MSK     1941 Jul
-                       1:00    M-Eur   MET%s   1944 Aug  8
-                       3:00    Russia  MS%s    1991 Mar 31 2:00s
-                       2:00    1:00  "EET DST" 1991 Sep 29 2:00s
-                       2:00    M-Eur   EET%s
-#                      This may change to `E-Eur' soon, for EC compatibility.
-
-# Liechtenstein
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Europe/Vaduz    0:38:04 -       LMT     1894 Jun
-                       1:00    -       MET     1981 Mar 29 2:00
-                       1:00    M-Eur   MET%s
-
-# Lithuania
-# They switched from the Julian to the Gregorian calendar on 1918 Feb 15.
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Europe/Vilnius  1:41:16 -       LMT     1880
-                       1:24    -       LST     1917            # Kaunas
-                       1:36    -       LST     1919 Oct 10
-                       1:00    -       MET     1920 Jul 12
-                       2:00    -       EET     1920 Oct  9
-                       1:00    -       MET     1940 Aug  3
-                       3:00    -       MSK     1941 Jun 24
-                       1:00    M-Eur   MET%s   1944 Aug
-                       3:00    Russia  MS%s    1991 Mar 31 2:00s
-                       2:00    1:00  "EET DST" 1991 Sep 29 2:00s
-                       2:00    M-Eur   EET%s
-#                      This may change to `E-Eur' soon, for EC compatibility.
-
-# Luxembourg
-# Whitman disagrees with most of these dates in minor ways; go with Shanks.
-# Rule NAME    FROM    TO      TYPE    IN      ON      AT      SAVE    LETTER/S
-Rule   Lux     1904    only    -       Jun      1       0:00   0       -
-Rule   Lux     1916    only    -       May     14      23:00   1:00    " DST"
-Rule   Lux     1916    only    -       Oct      1       1:00   0       -
-Rule   Lux     1917    only    -       Apr     28      23:00   1:00    " DST"
-Rule   Lux     1917    only    -       Sep     17       1:00   0       -
-Rule   Lux     1918    only    -       Apr     Mon>=15  2:00s  1:00    " DST"
-Rule   Lux     1918    only    -       Sep     Mon>=15  2:00s  0       -
-Rule   Lux     1919    only    -       Mar      1      23:00   1:00    " DST"
-Rule   Lux     1919    only    -       Oct      5       3:00   0       -
-Rule   Lux     1920    only    -       Feb     14      23:00   1:00    " DST"
-Rule   Lux     1920    only    -       Oct     24       2:00   0       -
-Rule   Lux     1921    only    -       Mar     14      23:00   1:00    " DST"
-Rule   Lux     1921    only    -       Oct     26       2:00   0       -
-Rule   Lux     1922    only    -       Mar     25      23:00   1:00    " DST"
-Rule   Lux     1922    only    -       Oct     Sun>=2   1:00   0       -
-Rule   Lux     1923    only    -       Apr     21      23:00   1:00    " DST"
-Rule   Lux     1923    only    -       Oct     Sun>=2   2:00   0       -
-Rule   Lux     1924    only    -       Mar     29      23:00   1:00    " DST"
-Rule   Lux     1924    1928    -       Oct     Sun>=2   1:00   0       -
-Rule   Lux     1925    only    -       Apr      5      23:00   1:00    " DST"
-Rule   Lux     1926    only    -       Apr     17      23:00   1:00    " DST"
-Rule   Lux     1927    only    -       Apr      9      23:00   1:00    " DST"
-Rule   Lux     1928    only    -       Apr     14      23:00   1:00    " DST"
-Rule   Lux     1929    only    -       Apr     20      23:00   1:00    " DST"
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone Europe/Luxembourg 0:24:36 -       LMT     1904 Jun
-                       1:00    Lux     MET%s   1918 Nov 25
-                       0:00    Lux     WET%s   1929 Oct  6 2:00s
-                       0:00    Belgium WET%s   1940 May 14 3:00
-                       1:00    M-Eur   WET%s   1944 Sep 18 3:00
-                       1:00    Belgium MET%s   1979 Apr  1 2:00
-                       1:00    M-Eur   MET%s
-
-# Macedonia
-# They switched from the Julian to the Gregorian calendar on 1918 Mar 18.
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Europe/Skopje   1:25:44 -       LMT     1884
-                       1:00    -       MET     1941 Apr 18 23:00
-                       1:00    M-Eur   MET%s   1945 May  8  2:00s
-                       1:00    1:00  "MET DST" 1945 Sep 16  2:00s
-                       1:00    -       MET     1983 Mar 27  2:00s
-                       1:00    M-Eur   MET%s
-
-# Malta
-# Rule NAME    FROM    TO      TYPE    IN      ON      AT      SAVE    LETTER/S
-Rule   Malta   1973    only    -       Mar     31      0:00s   1:00    " DST"
-Rule   Malta   1973    only    -       Sep     29      0:00s   0       -
-Rule   Malta   1974    only    -       Apr     21      0:00s   1:00    " DST"
-Rule   Malta   1974    only    -       Sep     16      0:00s   0       -
-Rule   Malta   1975    1979    -       Apr     Sun>=15 2:00    1:00    " DST"
-Rule   Malta   1975    1980    -       Sep     Sun>=15 2:00    0       -
-Rule   Malta   1980    only    -       Mar     31      2:00    1:00    " DST"
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Europe/Malta    0:58:04 -       LMT     1893 Nov  2     # Valletta
-                       1:00    Italy   MET%s   1942 Nov  2 2:00s
-                       1:00    M-Eur   MET%s   1945 Apr  2 2:00s
-                       1:00    Italy   MET%s   1973 Mar 31
-                       1:00    Malta   MET%s   1981 Mar 29 2:00s
-                       1:00    M-Eur   MET%s
-
-# Moldova
-# They switched from the Julian to the Gregorian calendar on 1919 Mar 18.
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Europe/Chisinau 1:55:20 -       LMT     1924 May  2
-                       2:00    -       EET     1930 Jun 21
-                       3:00    Russia  MS%s    1991 Mar 31 2:00s
-                       2:00    1:00  "EET DST" 1991 Sep 29 2:00s
-                       2:00    M-Eur   EET%s
-#                      This may change to `E-Eur' soon, for EC compatibility.
-
-# Monaco
-# Shanks gives 0:09 for Paris Mean Time; go with Whitman's more precise 0:09:05.
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Europe/Monaco   0:29:32 -       LMT     1891 Mar 15
-                       0:09:05 -       PMT     1911 Mar 11    # Paris Mean Time
-                       0:00    France  WET%s   1945 Sep 16 3:00
-                       1:00    France  MET%s   1977 Apr Sun>=1 2:00
-                       1:00    M-Eur   MET%s
-
-# Netherlands
-# Rule NAME    FROM    TO      TYPE    IN      ON      AT      SAVE    LETTER/S
-Rule   Neth    1892    only    -       May      1      0:00    0       AMT
-# Shanks gives 1916 May 1 0:00 and 1916 Oct 1 0:00; go with Whitman.
-Rule   Neth    1916    only    -       May      1      2:00s   1:00    NST
-Rule   Neth    1916    only    -       Oct      2      2:00s   0       AMT
-Rule   Neth    1917    only    -       Apr     16      2:00s   1:00    NST
-Rule   Neth    1917    only    -       Sep     17      2:00s   0       AMT
-# Whitman gives 1918 Apr 14, 1918 Oct 31, and 1921 Sep 28; go with Shanks.
-Rule   Neth    1918    1921    -       Apr     Mon>=1  2:00s   1:00    NST
-Rule   Neth    1918    1921    -       Sep     Mon>=24 2:00s   0       AMT
-Rule   Neth    1922    only    -       Mar     26      2:00s   1:00    NST
-# Whitman gives 1939 Oct 1; go with Shanks.
-Rule   Neth    1922    1939    -       Oct     Sun>=2  2:00s   0       AMT
-Rule   Neth    1923    only    -       Jun      1      2:00s   1:00    NST
-Rule   Neth    1924    only    -       Mar     30      2:00s   1:00    NST
-# Whitman gives 1925 Apr 5; go with Shanks.
-Rule   Neth    1925    only    -       Jun      5      2:00s   1:00    NST
-# For 1926 through 1930 Whitman gives Apr 15; go with Shanks.
-Rule   Neth    1926    1931    -       May     15      2:00s   1:00    NST
-Rule   Neth    1932    only    -       May     22      2:00s   1:00    NST
-Rule   Neth    1933    1936    -       May     15      2:00s   1:00    NST
-Rule   Neth    1937    only    -       May     22      2:00s   1:00    NST
-# Whitman gives 1939 Apr 15 and 1940 Apr 19; go with Shanks.
-Rule   Neth    1938    1939    -       May     15      2:00s   1:00    NST
-Rule   Neth    1945    only    -       Apr      2      2:00s   1:00    -
-Rule   Neth    1945    only    -       May     20      2:00s   0       " DST"
-# Before 1937, Shanks says just `0:20'; we use Whitman's more precise figure.
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone Europe/Amsterdam  0:19:28 -       LMT     1892 May
-                       0:19:28 Neth    %s      1937 Jul
-                       0:20    Neth    %s      1940 May 16 0:40
-                       1:00    M-Eur   MET%s   1945 Apr  2 2:00
-                       1:00    Neth    MET%s   1977 Apr Sun>=1 2:00
-                       1:00    M-Eur   MET%s
-
-# Norway
-# Rule NAME    FROM    TO      TYPE    IN      ON      AT      SAVE    LETTER/S
-Rule   Norway  1892    only    -       May      1      0:00    0       -
-# Whitman gives 1916 May 21 - 1916 Oct 21; go with Shanks.
-Rule   Norway  1916    only    -       May     22      1:00    1:00    " DST"
-Rule   Norway  1916    only    -       Sep     30      0:00    0       -
-# Shanks omits the following transition; go with Whitman.
-Rule   Norway  1935    only    -       Aug     11      0:00    1:00    " DST"
-# Whitman says DST observed until 1942 Nov 1, then 1943 Mar 29 - Oct 4,
-# 1944 Apr 3 - Oct 2, and 1945 Apr 1 - Oct 1; go with Shanks after 1940.
-Rule   Norway  1945    only    -       Apr      2      2:00s   1:00    " DST"
-Rule   Norway  1945    only    -       Oct      1      2:00s   0       -
-Rule   Norway  1959    1964    -       Mar     Sun>=15 2:00s   1:00    " DST"
-Rule   Norway  1959    1965    -       Sep     Sun>=15 2:00s   0       -
-Rule   Norway  1965    only    -       Apr     25      2:00s   1:00    " DST"
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Europe/Oslo     0:43:00 -       LMT     1895
-                       1:00    Norway  MET%s   1940 Aug 10 23:00
-                       1:00    M-Eur   MET%s   1945 Apr  2  2:00
-                       1:00    Norway  MET%s   1980 Apr  6  2:00
-                       1:00    M-Eur   MET%s
-# Svalbard is like Europe/Oslo.
-#
-# From Whitman:
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone Atlantic/Jan_Mayen        -1:00   -       EGT
-
-# Poland
-# Austrian and German Poland switched from the Julian to the Gregorian calendar
-# on 1582 Oct 15.  Russian Poland switched on 1918 Jan 14.
-# Rule NAME    FROM    TO      TYPE    IN      ON      AT      SAVE    LETTER/S
-Rule   Poland  1918    1919    -       Sep     16      2:00s   0       -
-Rule   Poland  1919    only    -       Apr     15      2:00s   1:00    " DST"
-# Whitman gives 1944 Nov 30; go with Shanks.
-Rule   Poland  1944    only    -       Oct      4      2:00    0       -
-# For 1944-1948 Whitman gives the previous day; go with Shanks.
-Rule   Poland  1945    only    -       Apr     29      0:00    1:00    " DST"
-Rule   Poland  1945    only    -       Nov      1      0:00    0       -
-Rule   Poland  1946    only    -       Apr     14      0:00    1:00    " DST"
-Rule   Poland  1946    only    -       Sep      7      0:00    0       -
-Rule   Poland  1947    only    -       May      4      0:00    1:00    " DST"
-Rule   Poland  1947    1948    -       Oct     Sun>=1  0:00    0       -
-Rule   Poland  1948    only    -       Apr     18      0:00    1:00    " DST"
-# Whitman also gives 1949 Apr 9 - 1949 Oct 1; go with Shanks.
-Rule   Poland  1957    only    -       Jun      2      1:00s   1:00    " DST"
-Rule   Poland  1957    1958    -       Sep     lastSun 1:00s   0       -
-Rule   Poland  1958    only    -       Mar     30      1:00s   1:00    " DST"
-Rule   Poland  1959    only    -       May     31      1:00s   1:00    " DST"
-Rule   Poland  1959    1961    -       Oct     Sun>=1  1:00s   0       -
-Rule   Poland  1960    only    -       Apr      3      1:00s   1:00    " DST"
-Rule   Poland  1961    1964    -       May     Sun>=25 1:00s   1:00    " DST"
-Rule   Poland  1962    1964    -       Sep     lastSun 1:00s   0       -
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Europe/Warsaw   1:24:00 -       LMT     1880
-                       1:24    -       WMT     1915 Aug  5   # Warsaw Mean Time
-                       1:00    M-Eur   MET%s   1918 Sep 16 3:00
-                       2:00    Poland  EET%s   1922 Jun
-                       1:00    Poland  MET%s   1940 Jun 23 2:00
-                       1:00    M-Eur   MET%s   1944 Oct
-                       1:00    Poland  MET%s   1977 Apr  3 1:00
-                       1:00    W-Eur   MET%s
-#                      This may change to `M-Eur' soon, for EC compatibility.
-
-# Portugal
-# Rule NAME    FROM    TO      TYPE    IN      ON      AT      SAVE    LETTER/S
-Rule   Port    1911    only    -       May     24       0:00   0       -
-Rule   Port    1916    only    -       Jun     17      23:00   1:00    " DST"
-# Whitman gives 1916 Oct 31; go with Shanks.
-Rule   Port    1916    only    -       Nov      1       1:00   0       -
-Rule   Port    1917    only    -       Feb     28      23:00s  1:00    " DST"
-Rule   Port    1917    1921    -       Oct     14      23:00s  0       -
-Rule   Port    1918    only    -       Mar      1      23:00s  1:00    " DST"
-Rule   Port    1919    only    -       Feb     28      23:00s  1:00    " DST"
-Rule   Port    1920    only    -       Feb     29      23:00s  1:00    " DST"
-Rule   Port    1921    only    -       Feb     28      23:00s  1:00    " DST"
-Rule   Port    1924    only    -       Apr     16      23:00s  1:00    " DST"
-Rule   Port    1924    only    -       Oct     14      23:00s  0       -
-Rule   Port    1926    only    -       Apr     17      23:00s  1:00    " DST"
-Rule   Port    1926    1929    -       Oct     Sat>=1  23:00s  0       -
-Rule   Port    1927    only    -       Apr      9      23:00s  1:00    " DST"
-Rule   Port    1928    only    -       Apr     14      23:00s  1:00    " DST"
-Rule   Port    1929    only    -       Apr     20      23:00s  1:00    " DST"
-Rule   Port    1931    only    -       Apr     18      23:00s  1:00    " DST"
-# Whitman gives 1931 Oct 8; go with Shanks.
-Rule   Port    1931    1932    -       Oct     Sat>=1  23:00s  0       -
-Rule   Port    1932    only    -       Apr      2      23:00s  1:00    " DST"
-# Shanks gives 1934 Apr 4; go with Whitman.
-Rule   Port    1934    only    -       Apr      7      23:00s  1:00    " DST"
-# Whitman gives 1934 Oct 5; go with Shanks.
-Rule   Port    1934    1938    -       Oct     Sat>=1  23:00s  0       -
-# Shanks gives 1935 Apr 30; go with Whitman.
-Rule   Port    1935    only    -       Mar     30      23:00s  1:00    " DST"
-Rule   Port    1936    only    -       Apr     18      23:00s  1:00    " DST"
-# Whitman gives 1937 Apr 2; go with Shanks.
-Rule   Port    1937    only    -       Apr      3      23:00s  1:00    " DST"
-Rule   Port    1938    only    -       Mar     26      23:00s  1:00    " DST"
-Rule   Port    1939    only    -       Apr     15      23:00s  1:00    " DST"
-# Whitman gives 1939 Oct 7; go with Shanks.
-Rule   Port    1939    only    -       Nov     18      23:00s  0       -
-Rule   Port    1940    only    -       Feb     24      23:00s  1:00    " DST"
-# Shanks gives 1940 Oct 7; go with Whitman.
-Rule   Port    1940    1941    -       Oct      5      23:00s  0       -
-Rule   Port    1941    only    -       Apr      5      23:00s  1:00    " DST"
-Rule   Port    1942    1945    -       Mar     Sat>=8  23:00s  1:00    " DST"
-Rule   Port    1942    only    -       Apr     25      22:00s  2:00    " DDST"
-Rule   Port    1942    only    -       Aug     15      22:00s  1:00    " DST"
-Rule   Port    1942    1945    -       Oct     Sat>=24 23:00s  0       -
-Rule   Port    1943    only    -       Apr     17      22:00s  2:00    " DDST"
-Rule   Port    1943    1945    -       Aug     Sat>=25 22:00s  1:00    " DST"
-Rule   Port    1944    1945    -       Apr     Sat>=21 22:00s  2:00    " DDST"
-Rule   Port    1946    only    -       Apr     Sat>=1  23:00s  1:00    " DST"
-Rule   Port    1946    only    -       Oct     Sat>=1  23:00s  0       -
-Rule   Port    1947    1949    -       Apr     Sun>=1   2:00s  1:00    " DST"
-Rule   Port    1947    1949    -       Oct     Sun>=1   2:00s  0       -
-# Shanks says DST was observed in 1950; go with Whitman.
-# Whitman gives Oct lastSun for 1952 on; go with Shanks.
-Rule   Port    1951    1965    -       Apr     Sun>=1   2:00s  1:00    " DST"
-Rule   Port    1951    1965    -       Oct     Sun>=1   2:00s  0       -
-Rule   Port    1977    only    -       Mar     27       0:00s  1:00    " DST"
-Rule   Port    1977    only    -       Sep     25       0:00s  0       -
-Rule   Port    1978    1979    -       Apr     Sun>=1   0:00s  1:00    " DST"
-Rule   Port    1978    only    -       Oct      1       0:00s  0       -
-Rule   Port    1979    1982    -       Sep     lastSun  1:00s  0       -
-Rule   Port    1980    only    -       Mar     lastSun  0:00s  1:00    " DST"
-Rule   Port    1981    1982    -       Mar     lastSun  1:00s  1:00    " DST"
-Rule   Port    1983    only    -       Mar     lastSun  2:00s  1:00    " DST"
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Europe/Lisbon   -0:36:32 -      LMT     1884
-                       -0:37   -       LMT     1911 May 24   # Lisbon Mean Time
-                        0:00   Port    WET%s   1966 Apr  3 2:00
-                        1:00   -       MET     1976 Sep 26 1:00
-                        0:00   Port    WET%s   1983 Sep 25 1:00s
-                        0:00   W-Eur   WET%s   1992 Sep 27 1:00s
-# From Rui Pedro Salgueiro <rps@inescca.inescc.pt> (November 12, 1992):
-# Portugal has recently (September, 27) changed timezone
-# (from WET to MET or CET) to harmonize with EEC.
-                       1:00    M-Eur   MET%s
-# We don't know what happened to Madeira or the Azores,
-# so we'll just use Shanks for now.
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone Atlantic/Azores   -1:42:40 -      LMT     1884            # Ponta Delgada
-                       -1:55   -       HMT     1911 May 24  # Horta Mean Time
-                       -2:00   Port    ACT%s   1966 Apr  3 2:00
-                       -1:00   -       ACT     1977 Mar 27
-                       -1:00   -       ACT     1983 Sep 25 1:00s
-                       -1:00   W-Eur   ACT%s
-Zone Atlantic/Madeira  -1:07:36 -      LMT     1884            # Funchal
-                       -1:08   -       FMT     1911 May 24  # Funchal Mean Time
-                       -1:00   Port    ACT%s   1966 Apr  3 2:00
-                        0:00   -       WET     1977 Mar 27
-                        0:00   Port    WET%s   1983 Sep 25 1:00s
-                        0:00   W-Eur   WET%s
-
-# Slovakia
-Link Europe/Prague Europe/Bratislava
-
-# Romania
-# Catholic Romania switched from the Julian to the Gregorian calendar on
-# on 1919 Mar 18.  Greek Orthodox Romania switched on 1920 Mar 18.
-# Rule NAME    FROM    TO      TYPE    IN      ON      AT      SAVE    LETTER/S
-Rule   Romania 1931    only    -       Jul     24       0:00   0       -
-Rule   Romania 1932    only    -       May     21       0:00s  1:00    " DST"
-Rule   Romania 1932    1939    -       Oct     Sun>=1   0:00s  0       -
-Rule   Romania 1933    1939    -       Apr     Sun>=2   0:00s  1:00    " DST"
-Rule   Romania 1979    only    -       May     27       0:00   1:00    " DST"
-Rule   Romania 1979    only    -       Sep     lastSun  0:00   0       -
-Rule   Romania 1980    only    -       Apr      5      23:00   1:00    " DST"
-Rule   Romania 1980    only    -       Sep     lastSun  1:00   0       -
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone Europe/Bucharest  1:44:24 -       LMT     1891 Oct
-                       1:44    -       BMT     1931 Jul 24     # Bucharest MT
-                       2:00    Romania EET%s   1981 Mar 29 2:00s
-                       2:00    M-Eur   EET%s
-#                      This may change to `E-Eur' soon, for EC compatibility.
-
-# Russia
-# From Paul Eggert <eggert@twinsun.com> (May 28, 1994):
-# Moscow and Novosibirsk time zone names, and Moscow rules after 1991,
-# are from Andrew A. Chernov <ache@astral.msk.su>.
-# I invented the other time zone names, and (unless otherwise specified)
-# guessed what happened after 1991; the clocks were chaotic, and we know little.
-# The rest is from Shanks.
-#
-# From Shanks (1991):
-# Western Russia switched from the Julian to the Gregorian calendar
-# on 1918 Jan 14.  Eastern Russia switched on 1920 Mar 18.
-# In 1929 the Soviet Union instituted a 5 day week; in 1932 it instituted
-# a 6 day week; on 1940 Jun 27 it returned to the Gregorian week.
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone Europe/Moscow      2:30:20 -      LMT     1880
-                        2:31   Russia  LST%s   1919 Jul  1 2:00
-                        3:00   Russia  MS%s    1922 Oct
-                        2:00   -       EET     1930 Jun 21
-                        3:00   Russia  MS%s    1991 Mar 31 2:00s
-                        2:00   1:00  "EET DST" 1991 Sep 29 2:00s
-                        2:00   -       EET     1992 Jan 19 2:00s
-                        3:00   Russia  MS%s
-Zone Europe/Kuybyshev   3:20:36 -      LMT     1924 May  2
-                        3:00   -       KSK     1957 Mar
-                        4:00   Russia  KS%s    1991 Mar 31 2:00s
-                        3:00   1:00    KSD     1991 Sep 29 2:00s
-                        3:00   -       KSK     1992 Jan 19 2:00s
-                        4:00   Russia  KS%s
-Zone Asia/Yekaterinburg         4:02:34 -      LMT     1924 May  2
-                        4:00   -       SSK     1957 Mar
-                        5:00   Russia  SS%s    1991 Mar 31 2:00s
-                        4:00   1:00    SSD     1991 Sep 29 2:00s
-                        4:00   -       SSK     1992 Jan 19 2:00s
-                        5:00   Russia  ES%s    # name change from Sverdlovsk
-Zone Asia/Omsk          4:53:36 -      LMT     1924 May  2
-                        5:00   -       OSK     1957 Mar
-                        6:00   Russia  OS%s    1991 Mar 31 2:00s
-                        5:00   1:00    OSD     1991 Sep 29 2:00s
-                        5:00   -       OSK     1992 Jan 19 2:00s
-                        6:00   Russia  OS%s
-# From Stanislaw A. Kuzikowski <S.A.Kuz@iae.nsk.su> (June 29, 1994):
-# But now it is some months since Novosibirsk is 3 hours ahead of Moscow!
-# I do not know why they have decided to make this change;
-# as far as I remember it was done exactly during winter->summer switching
-# so we (Novosibirsk) simply did not switch.
-# Tomsk is still 4 hours ahead of Moscow.
-Zone Asia/Novosibirsk   5:31:40 -      LMT     1924 May  2
-                        6:00   -       NSK     1957 Mar
-                        7:00   Russia  NS%s    1991 Mar 31 2:00s
-                        6:00   1:00    NSD     1991 Sep 29 2:00s
-                        6:00   -       NSK     1992 Jan 19 2:00s
-                        7:00   Russia  NS%s    1994 Mar 27 2:00s
-                        6:00   1:00    NSD     1994 Sep 25 2:00s
-                        6:00   Russia  NS%s
-Zone Asia/Tomsk                 5:39:52 -      LMT     1924 May  2
-                        6:00   -       TSK     1957 Mar
-                        7:00   Russia  TS%s    1991 Mar 31 2:00s
-                        6:00   1:00    TSD     1991 Sep 29 2:00s
-                        6:00   -       TSK     1992 Jan 19 2:00s
-                        7:00   Russia  TS%s
-Zone Asia/Irkutsk       6:57:20 -      LMT     1880
-                        6:57   -       LST     1924 May  2
-                        7:00   -       ISK     1957 Mar
-                        8:00   Russia  IS%s    1991 Mar 31 2:00s
-                        7:00   1:00    ISD     1991 Sep 29 2:00s
-                        7:00   -       ISK     1992 Jan 19 2:00s
-                        8:00   Russia  IS%s
-Zone Asia/Yakutsk       8:38:40 -      LMT     1924 May  2
-                        8:00   -       YSK     1957 Mar
-                        9:00   Russia  YS%s    1991 Mar 31 2:00s
-                        8:00   1:00    YSD     1991 Sep 29 2:00s
-                        8:00   -       YSK     1992 Jan 19 2:00s
-                        9:00   Russia  YS%s
-Zone Asia/Vladivostok   8:47:44 -      LMT     1880
-                        8:48   -       LST     1924 May  2
-                        9:00   -       VSK     1957 Mar
-                       10:00   Russia  VS%s    1991 Mar 31 2:00s
-                        9:00   1:00    VSD     1991 Sep 29 2:00s
-                        9:00   -       VSK     1992 Jan 19 2:00s
-                       10:00   Russia  VS%s
-# MSK is taken; settle for GSK.
-Zone Asia/Magadan      10:03:12 -      LMT     1924 May  2
-                       10:00   -       GSK     1957 Mar
-                       11:00   Russia  GS%s    1991 Mar 31 2:00s
-                       10:00   1:00    GSD     1991 Sep 29 2:00s
-                       10:00   -       GSK     1992 Jan 19 2:00s
-                       11:00   Russia  GS%s
-# This name should be Asia/Petropavlovsk-Kamchatski, but that's too long.
-Zone Asia/Kamchatka    10:34:36 -      LMT     1924 May  2
-                       11:00   -       PSK     1957 Mar
-                       12:00   Russia  PS%s    1991 Mar 31 2:00s
-                       11:00   1:00    PSD     1991 Sep 29 2:00s
-                       11:00   -       PSK     1992 Jan 19 2:00s
-                       12:00   Russia  PS%s
-Zone Asia/Anadyr       11:49:56 -      LMT     1924 May  2
-                       12:00   -       ASK     1957 Mar
-                       13:00   Russia  AS%s    1991 Mar 31 2:00s
-                       12:00   1:00    ASD     1991 Sep 29 2:00s
-                       12:00   -       ASK     1992 Jan 19 2:00s
-                       13:00   Russia  AS%s
-
-# Serbia
-# They switched from the Julian to the Gregorian calendar on 1918 Mar 18.
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Europe/Belgrade 1:22:00 -       LMT     1884
-                       1:00    -       MET     1941 Apr 18 23:00
-                       1:00    M-Eur   MET%s   1945 May  8  2:00s
-                       1:00    1:00  "MET DST" 1945 Sep 16  2:00s
-                       1:00    -       MET     1983 Mar 27  2:00s
-                       1:00    M-Eur   MET%s
-
-# Slovenia
-# They switched from the Julian to the Gregorian calendar on 1918 Mar 18.
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone Europe/Ljubljana  0:58:04 -       LMT     1884
-                       1:00    -       MET     1941 Apr 18 23:00
-                       1:00    M-Eur   MET%s   1945 May  8  2:00s
-                       1:00    1:00  "MET DST" 1945 Sep 16  2:00s
-                       1:00    -       MET     1983 Mar 27  2:00s
-                       1:00    M-Eur   MET%s
-
-# Spain
-# Rule NAME    FROM    TO      TYPE    IN      ON      AT      SAVE    LETTER/S
-Rule   Spain   1901    only    -       Jan      1       0:00   0       -
-# For 1917-1919 Whitman gives Apr Sat>=1 - Oct Sat>=1; go with Shanks.
-Rule   Spain   1917    only    -       May      5      23:00s  1:00    " DST"
-Rule   Spain   1917    1919    -       Oct      6      23:00s  0       -
-Rule   Spain   1918    only    -       Apr     15      23:00s  1:00    " DST"
-Rule   Spain   1919    only    -       Apr      5      23:00s  1:00    " DST"
-# Whitman gives 1921 Feb 28 - Oct 14; go with Shanks.
-Rule   Spain   1924    only    -       Apr     16      23:00s  1:00    " DST"
-# Whitman gives 1924 Oct 14; go with Shanks.
-Rule   Spain   1924    only    -       Oct      4      23:00s  0       -
-Rule   Spain   1926    only    -       Apr     17      23:00s  1:00    " DST"
-# Whitman says no DST in 1929; go with Shanks.
-Rule   Spain   1926    1929    -       Oct     Sat>=1  23:00s  0       -
-Rule   Spain   1927    only    -       Apr      9      23:00s  1:00    " DST"
-Rule   Spain   1928    only    -       Apr     14      23:00s  1:00    " DST"
-Rule   Spain   1929    only    -       Apr     20      23:00s  1:00    " DST"
-# Whitman gives 1937 Jun 16, 1938 Apr 16, 1940 Apr 13; go with Shanks.
-Rule   Spain   1937    only    -       May     22      23:00s  1:00    " DST"
-Rule   Spain   1937    1939    -       Oct     Sat>=1  23:00s  0       -
-Rule   Spain   1938    only    -       Mar     22      23:00s  1:00    " DST"
-Rule   Spain   1939    only    -       Apr     15      23:00s  1:00    " DST"
-Rule   Spain   1940    only    -       Mar     16      23:00s  1:00    " DST"
-# Whitman says no DST 1942-1945; go with Shanks.
-Rule   Spain   1942    only    -       May      2      22:00s  2:00    " DDST"
-Rule   Spain   1942    only    -       Sep      1      22:00s  1:00    " DST"
-Rule   Spain   1943    1946    -       Apr     Sat>=13 22:00s  2:00    " DDST"
-Rule   Spain   1943    only    -       Oct      3      22:00s  1:00    " DST"
-Rule   Spain   1944    only    -       Oct     10      22:00s  1:00    " DST"
-Rule   Spain   1945    only    -       Sep     30       1:00   1:00    " DST"
-Rule   Spain   1949    only    -       Apr     30      23:00   1:00    " DST"
-Rule   Spain   1949    only    -       Sep     30       1:00   0       -
-Rule   Spain   1974    1975    -       Apr     Sat>=13 23:00   1:00    " DST"
-Rule   Spain   1974    1975    -       Oct     Sun>=1   1:00   0       -
-Rule   Spain   1976    only    -       Mar     27      23:00   1:00    " DST"
-Rule   Spain   1976    1977    -       Sep     lastSun  1:00   0       -
-Rule   Spain   1977    1978    -       Apr      2      23:00   1:00    " DST"
-Rule   Spain   1978    only    -       Oct      1       1:00   0       -
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Europe/Madrid   -0:14:44 -      LMT     1901
-                        0:00   Spain   WET%s   1946 Sep 30
-                        1:00   Spain   MET%s   1979 Apr  1 2:00
-                        1:00   M-Eur   MET%s
-Zone   Atlantic/Canary -1:01:36 -      LMT     1922 Mar # Las Palmas de Gran C.
-                       -1:00   -       ACT     1946 Sep 30 1:00
-                        0:00   -       WET     1980 Apr  6 0:00s
-                        0:00   1:00  "WET DST" 1980 Sep 28 0:00s
-                        0:00   W-Eur   WET%s
-
-# Sweden
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone Europe/Stockholm  1:12:12 -       LMT     1878 May 31
-                       1:12    -       SMT     1900 Jan  1  1:00 # Stockholm MT
-                       1:00    -       MET     1916 Apr 14 23:00s
-                       1:00    1:00  "MET DST" 1916 Sep 30 23:00s
-                       1:00    -       MET     1980 Apr  6  2:00
-                       1:00    M-Eur   MET%s
-
-# Switzerland
-# From Howse (1988), p 82:
-# By the end of the 18th century clocks and watches became commonplace
-# and their performance improved enormously.  Communities began to keep
-# mean time in preference to apparent time -- Geneva from 1780 ....
-# Rule NAME    FROM    TO      TYPE    IN      ON      AT      SAVE    LETTER/S
-Rule   Swiss   1894    only    -       Jun     1       0:00    0       -
-# From Whitman (who writes ``Midnight?''):
-Rule   Swiss   1940    only    -       Nov      2      0:00    1:00    " DST"
-Rule   Swiss   1940    only    -       Dec     31      0:00    0       " DST"
-# From Shanks (1991):
-Rule   Swiss   1941    1942    -       May     Sun>=1  2:00    1:00    " DST"
-Rule   Swiss   1941    1942    -       Oct     Sun>=1  0:00    0       " DST"
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Europe/Zurich   0:34:08 -       LMT     1848 Sep 12
-                       0:30    -       SST     1894 Jun   # Swiss Standard Time
-                       1:00    Swiss   MET%s   1981 Mar 29 2:00
-                       1:00    M-Eur   MET%s
-
-# Turkey
-# European Turkey switched to the Gregorian calendar in 1908.
-# Asian Turkey switched in 1914.
-# Rule NAME    FROM    TO      TYPE    IN      ON      AT      SAVE    LETTER/S
-Rule   Turkey  1910    only    -       Oct      1      0:00    0       -
-Rule   Turkey  1916    only    -       May      1      0:00    1:00    " DST"
-Rule   Turkey  1916    only    -       Oct      1      0:00    0       -
-Rule   Turkey  1920    only    -       Mar     28      0:00    1:00    " DST"
-Rule   Turkey  1920    only    -       Oct     25      0:00    0       -
-Rule   Turkey  1921    only    -       Apr      3      0:00    1:00    " DST"
-Rule   Turkey  1921    only    -       Oct      3      0:00    0       -
-Rule   Turkey  1922    only    -       Mar     26      0:00    1:00    " DST"
-Rule   Turkey  1922    only    -       Oct      8      0:00    0       -
-# Whitman gives 1923 Apr 28 - Sep 16 and no DST in 1924-1925; go with Shanks.
-Rule   Turkey  1924    only    -       May     13      0:00    1:00    " DST"
-Rule   Turkey  1924    1925    -       Oct      1      0:00    0       -
-Rule   Turkey  1925    only    -       May      1      0:00    1:00    " DST"
-# Shanks omits the first two transitions in 1940; go with Whitman.
-Rule   Turkey  1940    only    -       Jun     30      0:00    1:00    " DST"
-Rule   Turkey  1940    only    -       Oct      5      0:00    0       -
-Rule   Turkey  1940    only    -       Dec      1      0:00    1:00    " DST"
-Rule   Turkey  1941    only    -       Sep     21      0:00    0       -
-Rule   Turkey  1942    only    -       Apr      1      0:00    1:00    " DST"
-# Whitman omits the next two transition and gives 1945 Oct 1; go with Shanks.
-Rule   Turkey  1942    only    -       Nov      1      0:00    0       -
-Rule   Turkey  1945    only    -       Apr      2      0:00    1:00    " DST"
-Rule   Turkey  1945    only    -       Oct      8      0:00    0       -
-Rule   Turkey  1946    only    -       Jun      1      0:00    1:00    " DST"
-Rule   Turkey  1946    only    -       Oct      1      0:00    0       -
-Rule   Turkey  1947    1948    -       Apr     Sun>=16 0:00    1:00    " DST"
-Rule   Turkey  1947    1950    -       Oct     Sun>=2  0:00    0       -
-Rule   Turkey  1949    only    -       Apr     10      0:00    1:00    " DST"
-Rule   Turkey  1950    only    -       Apr     19      0:00    1:00    " DST"
-Rule   Turkey  1951    only    -       Apr     22      0:00    1:00    " DST"
-Rule   Turkey  1951    only    -       Oct      8      0:00    0       -
-Rule   Turkey  1962    only    -       Jul     15      0:00    1:00    " DST"
-Rule   Turkey  1962    only    -       Oct      8      0:00    0       -
-Rule   Turkey  1964    only    -       May     15      0:00    1:00    " DST"
-Rule   Turkey  1964    only    -       Oct      1      0:00    0       -
-Rule   Turkey  1970    1972    -       May     Sun>=2  0:00    1:00    " DST"
-Rule   Turkey  1970    1972    -       Oct     Sun>=2  0:00    0       -
-Rule   Turkey  1973    only    -       Jun      3      1:00    1:00    " DST"
-Rule   Turkey  1973    only    -       Nov      4      3:00    0       -
-Rule   Turkey  1974    only    -       Mar     31      2:00    1:00    " DST"
-Rule   Turkey  1974    only    -       Nov      3      5:00    0       -
-Rule   Turkey  1975    only    -       Mar     30      0:00    1:00    " DST"
-Rule   Turkey  1975    1976    -       Oct     lastSun 0:00    0       -
-Rule   Turkey  1976    only    -       Jun      1      0:00    1:00    " DST"
-Rule   Turkey  1977    1978    -       Apr     Sun>=1  0:00    1:00    " DST"
-Rule   Turkey  1977    only    -       Oct     16      0:00    0       -
-Rule   Turkey  1979    1980    -       Apr     Sun>=1  3:00    1:00    " DST"
-Rule   Turkey  1979    1982    -       Oct     Mon>=11 0:00    0       -
-Rule   Turkey  1981    1982    -       Mar     lastSun 3:00    1:00    " DST"
-Rule   Turkey  1983    only    -       Jul     31      0:00    1:00    " DST"
-Rule   Turkey  1983    only    -       Oct      2      0:00    0       -
-Rule   Turkey  1985    only    -       Apr     20      0:00    1:00    " DST"
-Rule   Turkey  1985    only    -       Sep     28      0:00    0       -
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   Europe/Istanbul 1:55:52 -       LMT     1880
-                       1:57    -       OMT     1910 Oct     # Ottoman Mean Time
-                       2:00    Turkey  EET%s   1978 Oct 15
-                       3:00    Turkey  TUR%s   1985 Apr 20
-                       2:00    Turkey  EET%s   1986
-                       2:00    M-Eur   EET%s
-#                      This may change to `E-Eur' soon, for EC compatibility.
-Link   Europe/Istanbul Asia/Istanbul   # Istanbul is in both continents.
-
-# Ukraine
-# Rule NAME    FROM    TO      TYPE    IN      ON      AT      SAVE    LETTER/S
-Rule   Ukraine 1919    only    -       Jul      1       2:00   1:00    " DST"
-Rule   Ukraine 1919    only    -       Aug     16       0:00   0       -
-Rule   Ukraine 1921    only    -       Feb     14      23:00   1:00    " DST"
-Rule   Ukraine 1921    only    -       Mar     21      23:00   2:00    " DDST"
-Rule   Ukraine 1921    only    -       Sep      1       0:00   1:00    " DST"
-Rule   Ukraine 1921    only    -       Oct      1       0:00   0       -
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone Europe/Kiev       2:02:04 -       LMT     1880
-                       2:02    Russia  LST%s   1919 Jul  1 2:00
-                       2:02    Ukraine LST%s   1924 May  2
-                       2:00    -       EET     1930 Jun 21
-                       3:00    Russia  MS%s    1990 Jul 17
-                       2:00    M-Eur   EET%s
-#                      This may change to `E-Eur' soon, for EC compatibility.
-Zone Europe/Simferopol 2:16:24 -       LMT     1880
-                       2:08    Russia  LST%s   1919 Jul  1 2:00
-                       2:08    Ukraine LST%s   1924 May  2
-                       2:00    -       EET     1930 Jun 21
-                       3:00    Russia  MS%s    1991 Mar 31 2:00s
-                       2:00    1:00  "EET DST" 1991 Sep 29 2:00s
-# From Paul Eggert <eggert@twinsun.com> (May 28, 1994):
-# Today's _Economist_ (p 45) reports that Crimea switched
-# from Kiev to Moscow time sometime after the January elections.
-# For now, we'll guess that there was a 2-hour leap forward on March 27.
-                       2:00    M-Eur   EET%s   1994 Mar 27 2:00s
-                       3:00    Russia  MS%s
-
-###############################################################################
-
-# One source shows that Bulgaria, Cyprus, Finland, and Greece observe DST from
-# the last Sunday in March to the last Sunday in September in 1986.
-# The source shows Romania changing a day later than everybody else.
-#
-# According to Bernard Sieloff's source, Poland is in the MET time zone but
-# uses the WE DST rules.  The Western USSR uses EET+1 and ME DST rules.
-# Bernard Sieloff's source claims Romania switches on the same day, but at
-# 00:00 standard time (i.e., 01:00 DST).  It also claims that Turkey
-# switches on the same day, but switches on at 01:00 standard time
-# and off at 00:00 standard time (i.e., 01:00 DST)
-
-# ...
-# Date: Wed, 28 Jan 87 16:56:27 -0100
-# From: seismo!mcvax!cgcha!wtho (Tom Hofmann)
-# Message-Id: <8701281556.AA22174@cgcha.uucp>
-# ...
-#
-# ...the European time rules are...standardized since 1981, when
-# most European coun[tr]ies started DST.  Before that year, only
-# a few countries (UK, France, Italy) had DST, each according
-# to own national rules.  In 1981, however, DST started on
-# 'Apr firstSun', and not on 'Mar lastSun' as in the following
-# years...
-# But also since 1981 there are some more national exceptions
-# than listed in 'europe': Switzerland, for example, joined DST
-# one year later, Denmark ended DST on 'Oct 1' instead of 'Sep
-# lastSun' in 1981---I don't know how they handle now.
-#
-# Finally, DST ist always from 'Apr 1' to 'Oct 1' in the
-# Soviet Union (as far as I know).
-#
-# Tom Hofmann, Scientific Computer Center, CIBA-GEIGY AG,
-# 4002 Basle, Switzerland
-# UUCP: ...!mcvax!cernvax!cgcha!wtho
-
-# ...
-# Date: Wed, 4 Feb 87 22:35:22 +0100
-# From: seismo!mcvax!cwi.nl!dik (Dik T. Winter)
-# ...
-#
-# The information from Tom Hofmann is (as far as I know) not entirely correct.
-# After a request from chongo at amdahl I tried to retrieve all information
-# about DST in Europe.  I was able to find all from about 1969.
-#
-# ...standardization on DST in Europe started in about 1977 with switches on
-# first Sunday in April and last Sunday in September...
-# In 1981 UK joined Europe insofar that
-# the starting day for both shifted to last Sunday in March.  And from 1982
-# the whole of Europe used DST, with switch dates April 1 and October 1 in
-# the Sov[i]et Union.  In 1985 the SU reverted to standard Europe[a]n switch
-# dates...
-#
-# It should also be remembered that time-zones are not constants; e.g.
-# Portugal switched in 1976 from MET (or CET) to WET with DST...
-# Note also that though there were rules for switch dates not
-# all countries abided to these dates, and many individual deviations
-# occurred, though not since 1982 I believe.  Another note: it is always
-# assumed that DST is 1 hour ahead of normal time, this need not be the
-# case; at least in the Netherlands there have been times when DST was 2 hours
-# in advance of normal time.
-#
-# ...
-# dik t. winter, cwi, amsterdam, nederland
-# INTERNET   : dik@cwi.nl
-# BITNET/EARN: dik@mcvax
-
-# From Bob Devine (January 28, 1988):
-# ...
-# Greece: Last Sunday in April to last Sunday in September (iffy on dates).
-# Since 1978.  Change at midnight.
-# ...
-# Monaco: has same DST as France.
-# ...
-
-# ...
-# Date: Fri, 3 Sep 93 13:43:41 BST
-# From: Peter Ilieve <peter@memex.co.uk>
-# ...
-# Turning to Europe, I now have a copy of the `Sixth Council Directive 92/20/EEC
-# of 26 March 1992 on summertime arrangements'. This only covers 1993 and
-# 1994, a seventh one is in the works but I doubt that the algorithm will
-# change. This says summertime starts at 01:00 GMT on the last Sunday in March
-# and ends at 01:00 GMT on the last Sunday in September, except for the UK
-# and Eire where it ends at 01:00 GMT on the fourth Sunday in October.
-# It says the arrangements for 1995 onwards will be decided by 1 January 1994,
-# but as the sixth directive was supposed to appear by 1 Jan 92 and didn't
-# arrive til March I wouldn't hold your breath.
-#
-# The first summertime directive was adopted in 1980, although the UK didn't
-# seem to use it until 1981. I suspect it would be safe to move your start
-# dates for the -Eur rules back to 1981.
diff --git a/time/factory b/time/factory
deleted file mode 100644 (file)
index d95df23..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-# @(#)factory  7.1
-
-# For companies who don't want to put time zone specification in
-# their installation procedures.  When users run date, they'll get the message.
-# Also useful for the "comp.sources" version.
-
-# Zone NAME    GMTOFF  RULES   FORMAT
-Zone   Factory 0       - "Local time zone must be set--see zic manual page"
diff --git a/time/getopt.c b/time/getopt.c
deleted file mode 100644 (file)
index dbe60b1..0000000
+++ /dev/null
@@ -1,93 +0,0 @@
-#ifndef lint
-#ifndef NOID
-static char    elsieid[] = "@(#)getopt.c       7.5";
-/* Modified from the UCB version with the SCCS ID appearing below. */
-#endif /* !defined NOID */
-#endif /* !defined lint */
-
-/*LINTLIBRARY*/
-
-/*
- * Copyright (c) 1987 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 written prior permission. This software
- * is provided ``as is'' without express or implied warranty.
- */
-
-#ifdef LIBC_SCCS
-#ifndef lint
-static char sccsid[] = "@(#)getopt.c   4.5 (Berkeley) 11/24/87";
-#endif /* !defined lint */
-#endif /* defined LIBC_SCCS */
-
-#include <stdio.h>
-
-/*
- * get option letter from argument vector
- */
-extern int     opterr;         /* if error message should be printed */
-extern int     optind;         /* index into parent argv vector */
-extern int     optopt;         /* character checked for validity */
-extern char *  optarg;         /* argument associated with option */
-
-#define BADCH  (int)'?'
-static char    EMSG[1];
-#define tell(s)        { \
-       if (opterr) { \
-               (void) fputs(*nargv, stderr); \
-               (void) fputs(s, stderr); \
-               (void) fputc(optopt, stderr); \
-               (void) fputc((int)'\n', stderr); \
-       } \
-       return(BADCH); \
-}
-
-extern char *  strchr();
-
-int
-getopt(nargc, nargv, ostr)
-       int     nargc;
-       char    **nargv, *ostr;
-{
-       static char     *place = EMSG;          /* option letter processing */
-       register char   *oli;                   /* option letter list index */
-
-       if (!*place) {                          /* update scanning pointer */
-               if (optind >= nargc || *(place = nargv[optind]) != '-' ||
-                       !*++place)
-                               return(EOF);
-               if (*place == '-') {            /* found "--" */
-                       ++optind;
-                       return(EOF);
-               }
-       }                                       /* option letter okay? */
-       if ((optopt = (int)*place++) == (int)':' ||
-               !(oli = strchr(ostr, optopt))) {
-                       if (!*place)
-                               ++optind;
-                       tell(": illegal option -- ");
-       }
-       if (*++oli != ':') {                    /* don't need argument */
-               optarg = NULL;
-               if (!*place)
-                       ++optind;
-       }
-       else {                                  /* need an argument */
-               if (*place)                     /* no white space */
-                       optarg = place;
-               else if (nargc <= ++optind) {   /* no arg */
-                       place = EMSG;
-                       tell(": option requires an argument -- ");
-               }
-               else                            /* white space */
-                       optarg = nargv[optind];
-               place = EMSG;
-               ++optind;
-       }
-       return(optopt);                         /* dump back option letter */
-}
diff --git a/time/ialloc.c b/time/ialloc.c
deleted file mode 100644 (file)
index d6a1b22..0000000
+++ /dev/null
@@ -1,103 +0,0 @@
-#ifndef lint
-#ifndef NOID
-static char    elsieid[] = "@(#)ialloc.c       8.24";
-#endif /* !defined NOID */
-#endif /* !defined lint */
-
-/*LINTLIBRARY*/
-
-#include "private.h"
-
-#ifdef MAL
-#define NULLMAL(x)     ((x) == NULL || (x) == MAL)
-#endif /* defined MAL */
-#ifndef MAL
-#define NULLMAL(x)     ((x) == NULL)
-#endif /* !defined MAL */
-
-#define nonzero(n)     (((n) == 0) ? 1 : (n))
-
-char * icalloc P((int nelem, int elsize));
-char * icatalloc P((char * old, const char * new));
-char * icpyalloc P((const char * string));
-char * imalloc P((int n));
-void * irealloc P((void * pointer, int size));
-void   ifree P((char * pointer));
-
-char *
-imalloc(n)
-const int      n;
-{
-#ifdef MAL
-       register char * result;
-
-       result = malloc((alloc_size_T) nonzero(n));
-       return NULLMAL(result) ? NULL : result;
-#endif /* defined MAL */
-#ifndef MAL
-       return malloc((alloc_size_T) nonzero(n));
-#endif /* !defined MAL */
-}
-
-char *
-icalloc(nelem, elsize)
-int    nelem;
-int    elsize;
-{
-       if (nelem == 0 || elsize == 0)
-               nelem = elsize = 1;
-       return calloc((alloc_size_T) nelem, (alloc_size_T) elsize);
-}
-
-void *
-irealloc(pointer, size)
-void * const   pointer;
-const int      size;
-{
-       if (NULLMAL(pointer))
-               return imalloc(size);
-       return realloc((genericptr_T) pointer, (alloc_size_T) nonzero(size));
-}
-
-char *
-icatalloc(old, new)
-char * const           old;
-const char * const     new;
-{
-       register char * result;
-       register int    oldsize, newsize;
-
-       newsize = NULLMAL(new) ? 0 : strlen(new);
-       if (NULLMAL(old))
-               oldsize = 0;
-       else if (newsize == 0)
-               return old;
-       else    oldsize = strlen(old);
-       if ((result = irealloc(old, oldsize + newsize + 1)) != NULL)
-               if (!NULLMAL(new))
-                       (void) strcpy(result + oldsize, new);
-       return result;
-}
-
-char *
-icpyalloc(string)
-const char * const     string;
-{
-       return icatalloc((char *) NULL, string);
-}
-
-void
-ifree(p)
-char * const   p;
-{
-       if (!NULLMAL(p))
-               (void) free(p);
-}
-
-void
-icfree(p)
-char * const   p;
-{
-       if (!NULLMAL(p))
-               (void) free(p);
-}
diff --git a/time/leapseconds b/time/leapseconds
deleted file mode 100644 (file)
index d610692..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-# @(#)leapseconds      7.7
-
-# Allowance for leapseconds added to each timezone file.
-
-# The International Earth Rotation Service periodically uses leap seconds
-# to keep UTC to within 0.9 s of TAI (atomic time); see
-# Terry J Quinn, The BIPM and the accurate measure of time,
-# Proc IEEE 79, 7 (July 1991), 894-905.
-# There were no leap seconds before 1972, because the official mechanism
-# accounting for the discrepancy between atomic time and the earth's rotation
-# did not exist until the early 1970s.
-
-# The correction (+ or -) is made at the given time, so lines
-# will typically look like:
-#      Leap    YEAR    MON     DAY     23:59:60        +       R/S
-# or
-#      Leap    YEAR    MON     DAY     23:59:59        -       R/S
-
-# If the leapsecond is Rolling (R) the given time is local time
-# If the leapsecond is Stationary (S) the given time is GMT
-
-# Leap YEAR    MONTH   DAY     HH:MM:SS        CORR    R/S
-Leap   1972    Jun     30      23:59:60        +       S
-Leap   1972    Dec     31      23:59:60        +       S
-Leap   1973    Dec     31      23:59:60        +       S
-Leap   1974    Dec     31      23:59:60        +       S
-Leap   1975    Dec     31      23:59:60        +       S
-Leap   1976    Dec     31      23:59:60        +       S
-Leap   1977    Dec     31      23:59:60        +       S
-Leap   1978    Dec     31      23:59:60        +       S
-Leap   1979    Dec     31      23:59:60        +       S
-Leap   1981    Jun     30      23:59:60        +       S
-Leap   1982    Jun     30      23:59:60        +       S
-Leap   1983    Jun     30      23:59:60        +       S
-Leap   1985    Jun     30      23:59:60        +       S
-Leap   1987    Dec     31      23:59:60        +       S
-Leap   1989    Dec     31      23:59:60        +       S
-Leap   1990    Dec     31      23:59:60        +       S
-Leap   1992    Jun     30      23:59:60        +       S
-Leap   1993    Jun     30      23:59:60        +       S
-Leap   1994    Jun     30      23:59:60        +       S
diff --git a/time/localtime.c b/time/localtime.c
deleted file mode 100644 (file)
index 1ae36fe..0000000
+++ /dev/null
@@ -1,1569 +0,0 @@
-#ifndef lint
-#ifndef NOID
-static char    elsieid[] = "@(#)localtime.c    7.26";
-#endif /* !defined NOID */
-#endif /* !defined lint */
-
-/*
-** Leap second handling from Bradley White (bww@k.gp.cs.cmu.edu).
-** POSIX-style TZ environment variable handling from Guy Harris
-** (guy@auspex.com).
-*/
-
-/*LINTLIBRARY*/
-
-#include "private.h"
-#include "tzfile.h"
-#include "fcntl.h"
-
-#define ACCESS_MODE    O_RDONLY
-
-#ifdef O_BINARY
-#define OPEN_MODE      (O_RDONLY | O_BINARY)
-#endif /* defined O_BINARY */
-#ifndef O_BINARY
-#define OPEN_MODE      O_RDONLY
-#endif /* !defined O_BINARY */
-
-#ifndef WILDABBR
-/*
-** Someone might make incorrect use of a time zone abbreviation:
-**     1.      They might reference tzname[0] before calling tzset (explicitly
-**             or implicitly).
-**     2.      They might reference tzname[1] before calling tzset (explicitly
-**             or implicitly).
-**     3.      They might reference tzname[1] after setting to a time zone
-**             in which Daylight Saving Time is never observed.
-**     4.      They might reference tzname[0] after setting to a time zone
-**             in which Standard Time is never observed.
-**     5.      They might reference tm.TM_ZONE after calling offtime.
-** What's best to do in the above cases is open to debate;
-** for now, we just set things up so that in any of the five cases
-** WILDABBR is used.  Another possibility:  initialize tzname[0] to the
-** string "tzname[0] used before set", and similarly for the other cases.
-** And another:  initialize tzname[0] to "ERA", with an explanation in the
-** manual page of what this "time zone abbreviation" means (doing this so
-** that tzname[0] has the "normal" length of three characters).
-*/
-#define WILDABBR       "   "
-#endif /* !defined WILDABBR */
-
-static char            wildabbr[] = "WILDABBR";
-
-static const char      gmt[] = "GMT";
-
-struct ttinfo {                                /* time type information */
-       long            tt_gmtoff;      /* GMT offset in seconds */
-       int             tt_isdst;       /* used to set tm_isdst */
-       int             tt_abbrind;     /* abbreviation list index */
-       int             tt_ttisstd;     /* TRUE if transition is std time */
-};
-
-struct lsinfo {                                /* leap second information */
-       time_t          ls_trans;       /* transition time */
-       long            ls_corr;        /* correction to apply */
-};
-
-#define BIGGEST(a, b)  (((a) > (b)) ? (a) : (b))
-
-#ifdef TZNAME_MAX
-#define MY_TZNAME_MAX  TZNAME_MAX
-#endif /* defined TZNAME_MAX */
-#ifndef TZNAME_MAX
-#define MY_TZNAME_MAX  255
-#endif /* !defined TZNAME_MAX */
-
-struct state {
-       int             leapcnt;
-       int             timecnt;
-       int             typecnt;
-       int             charcnt;
-       time_t          ats[TZ_MAX_TIMES];
-       unsigned char   types[TZ_MAX_TIMES];
-       struct ttinfo   ttis[TZ_MAX_TYPES];
-       char            chars[BIGGEST(BIGGEST(TZ_MAX_CHARS + 1, sizeof gmt),
-                               (2 * (MY_TZNAME_MAX + 1)))];
-       struct lsinfo   lsis[TZ_MAX_LEAPS];
-};
-
-struct rule {
-       int             r_type;         /* type of rule--see below */
-       int             r_day;          /* day number of rule */
-       int             r_week;         /* week number of rule */
-       int             r_mon;          /* month number of rule */
-       long            r_time;         /* transition time of rule */
-};
-
-#define JULIAN_DAY             0       /* Jn - Julian day */
-#define DAY_OF_YEAR            1       /* n - day of year */
-#define MONTH_NTH_DAY_OF_WEEK  2       /* Mm.n.d - month, week, day of week */
-
-/*
-** Prototypes for static functions.
-*/
-
-static long            detzcode P((const char * codep));
-static const char *    getzname P((const char * strp));
-static const char *    getnum P((const char * strp, int * nump, int min,
-                               int max));
-static const char *    getsecs P((const char * strp, long * secsp));
-static const char *    getoffset P((const char * strp, long * offsetp));
-static const char *    getrule P((const char * strp, struct rule * rulep));
-static void            gmtload P((struct state * sp));
-static void            gmtsub P((const time_t * timep, long offset,
-                               struct tm * tmp));
-static void            localsub P((const time_t * timep, long offset,
-                               struct tm * tmp));
-static int             increment_overflow P((int * number, int delta));
-static int             normalize_overflow P((int * tensptr, int * unitsptr,
-                               int base));
-static void            settzname P((void));
-static time_t          time1 P((struct tm * tmp, void (* funcp)(),
-                               long offset));
-static time_t          time2 P((struct tm *tmp, void (* funcp)(),
-                               long offset, int * okayp));
-static void            timesub P((const time_t * timep, long offset,
-                               const struct state * sp, struct tm * tmp));
-static int             tmcomp P((const struct tm * atmp,
-                               const struct tm * btmp));
-static time_t          transtime P((time_t janfirst, int year,
-                               const struct rule * rulep, long offset));
-static int             tzload P((const char * name, struct state * sp));
-static int             tzparse P((const char * name, struct state * sp,
-                               int lastditch));
-
-#ifdef ALL_STATE
-static struct state *  lclptr;
-static struct state *  gmtptr;
-#endif /* defined ALL_STATE */
-
-#ifndef ALL_STATE
-static struct state    lclmem;
-static struct state    gmtmem;
-#define lclptr         (&lclmem)
-#define gmtptr         (&gmtmem)
-#endif /* State Farm */
-
-#ifndef TZ_STRLEN_MAX
-#define TZ_STRLEN_MAX 255
-#endif
-
-static char            lcl_TZname[TZ_STRLEN_MAX + 1];
-static int             lcl_is_set;
-static int             gmt_is_set;
-
-char *                 tzname[2] = {
-       wildabbr,
-       wildabbr
-};
-
-/*
-** Section 4.12.3 of X3.159-1989 requires that
-**     Except for the strftime function, these functions [asctime,
-**     ctime, gmtime, localtime] return values in one of two static
-**     objects: a broken-down time structure and an array of char.
-** Thanks to Paul Eggert (eggert@twinsun.com) for noting this.
-*/
-
-static struct tm       tm;
-
-#ifdef USG_COMPAT
-time_t                 timezone = 0;
-int                    daylight = 0;
-#endif /* defined USG_COMPAT */
-
-#ifdef ALTZONE
-time_t                 altzone = 0;
-#endif /* defined ALTZONE */
-
-static long
-detzcode(codep)
-const char * const     codep;
-{
-       register long   result;
-       register int    i;
-
-       result = 0;
-       for (i = 0; i < 4; ++i)
-               result = (result << 8) | (codep[i] & 0xff);
-       return result;
-}
-
-static void
-settzname P((void))
-{
-       register const struct state * const     sp = lclptr;
-       register int                            i;
-
-       tzname[0] = wildabbr;
-       tzname[1] = wildabbr;
-#ifdef USG_COMPAT
-       daylight = 0;
-       timezone = 0;
-#endif /* defined USG_COMPAT */
-#ifdef ALTZONE
-       altzone = 0;
-#endif /* defined ALTZONE */
-#ifdef ALL_STATE
-       if (sp == NULL) {
-               tzname[0] = tzname[1] = gmt;
-               return;
-       }
-#endif /* defined ALL_STATE */
-       for (i = 0; i < sp->typecnt; ++i) {
-               register const struct ttinfo * const    ttisp = &sp->ttis[i];
-
-               tzname[ttisp->tt_isdst] =
-                       (char *) &sp->chars[ttisp->tt_abbrind];
-#ifdef USG_COMPAT
-               if (ttisp->tt_isdst)
-                       daylight = 1;
-               if (i == 0 || !ttisp->tt_isdst)
-                       timezone = -(ttisp->tt_gmtoff);
-#endif /* defined USG_COMPAT */
-#ifdef ALTZONE
-               if (i == 0 || ttisp->tt_isdst)
-                       altzone = -(ttisp->tt_gmtoff);
-#endif /* defined ALTZONE */
-       }
-       /*
-       ** And to get the latest zone names into tzname. . .
-       */
-       for (i = 0; i < sp->timecnt; ++i) {
-               register const struct ttinfo * const    ttisp =
-                                                       &sp->ttis[
-                                                               sp->types[i]];
-
-               tzname[ttisp->tt_isdst] =
-                       (char *) &sp->chars[ttisp->tt_abbrind];
-       }
-}
-
-static int
-tzload(name, sp)
-register const char *          name;
-register struct state * const  sp;
-{
-       register const char *   p;
-       register int            i;
-       register int            fid;
-
-       if (name == NULL && (name = TZDEFAULT) == NULL)
-               return -1;
-       {
-               register int    doaccess;
-               char            fullname[FILENAME_MAX + 1];
-
-               if (name[0] == ':')
-                       ++name;
-               doaccess = name[0] == '/';
-               if (!doaccess) {
-                       if ((p = TZDIR) == NULL)
-                               return -1;
-                       if ((strlen(p) + strlen(name) + 1) >= sizeof fullname)
-                               return -1;
-                       (void) strcpy(fullname, p);
-                       (void) strcat(fullname, "/");
-                       (void) strcat(fullname, name);
-                       /*
-                       ** Set doaccess if '.' (as in "../") shows up in name.
-                       */
-                       if (strchr(name, '.') != NULL)
-                               doaccess = TRUE;
-                       name = fullname;
-               }
-               if (doaccess && access(name, ACCESS_MODE) != 0)
-                       return -1;
-               if ((fid = open(name, OPEN_MODE)) == -1)
-                       return -1;
-       }
-       {
-               register const struct tzhead *  tzhp;
-               char                            buf[sizeof *sp + sizeof *tzhp];
-               int                             ttisstdcnt;
-
-               i = read(fid, buf, sizeof buf);
-               if (close(fid) != 0 || i < sizeof *tzhp)
-                       return -1;
-               tzhp = (struct tzhead *) buf;
-               ttisstdcnt = (int) detzcode(tzhp->tzh_ttisstdcnt);
-               sp->leapcnt = (int) detzcode(tzhp->tzh_leapcnt);
-               sp->timecnt = (int) detzcode(tzhp->tzh_timecnt);
-               sp->typecnt = (int) detzcode(tzhp->tzh_typecnt);
-               sp->charcnt = (int) detzcode(tzhp->tzh_charcnt);
-               if (sp->leapcnt < 0 || sp->leapcnt > TZ_MAX_LEAPS ||
-                       sp->typecnt <= 0 || sp->typecnt > TZ_MAX_TYPES ||
-                       sp->timecnt < 0 || sp->timecnt > TZ_MAX_TIMES ||
-                       sp->charcnt < 0 || sp->charcnt > TZ_MAX_CHARS ||
-                       (ttisstdcnt != sp->typecnt && ttisstdcnt != 0))
-                               return -1;
-               if (i < sizeof *tzhp +
-                       sp->timecnt * (4 + sizeof (char)) +
-                       sp->typecnt * (4 + 2 * sizeof (char)) +
-                       sp->charcnt * sizeof (char) +
-                       sp->leapcnt * 2 * 4 +
-                       ttisstdcnt * sizeof (char))
-                               return -1;
-               p = buf + sizeof *tzhp;
-               for (i = 0; i < sp->timecnt; ++i) {
-                       sp->ats[i] = detzcode(p);
-                       p += 4;
-               }
-               for (i = 0; i < sp->timecnt; ++i) {
-                       sp->types[i] = (unsigned char) *p++;
-                       if (sp->types[i] >= sp->typecnt)
-                               return -1;
-               }
-               for (i = 0; i < sp->typecnt; ++i) {
-                       register struct ttinfo *        ttisp;
-
-                       ttisp = &sp->ttis[i];
-                       ttisp->tt_gmtoff = detzcode(p);
-                       p += 4;
-                       ttisp->tt_isdst = (unsigned char) *p++;
-                       if (ttisp->tt_isdst != 0 && ttisp->tt_isdst != 1)
-                               return -1;
-                       ttisp->tt_abbrind = (unsigned char) *p++;
-                       if (ttisp->tt_abbrind < 0 ||
-                               ttisp->tt_abbrind > sp->charcnt)
-                                       return -1;
-               }
-               for (i = 0; i < sp->charcnt; ++i)
-                       sp->chars[i] = *p++;
-               sp->chars[i] = '\0';    /* ensure '\0' at end */
-               for (i = 0; i < sp->leapcnt; ++i) {
-                       register struct lsinfo *        lsisp;
-
-                       lsisp = &sp->lsis[i];
-                       lsisp->ls_trans = detzcode(p);
-                       p += 4;
-                       lsisp->ls_corr = detzcode(p);
-                       p += 4;
-               }
-               for (i = 0; i < sp->typecnt; ++i) {
-                       register struct ttinfo *        ttisp;
-
-                       ttisp = &sp->ttis[i];
-                       if (ttisstdcnt == 0)
-                               ttisp->tt_ttisstd = FALSE;
-                       else {
-                               ttisp->tt_ttisstd = *p++;
-                               if (ttisp->tt_ttisstd != TRUE &&
-                                       ttisp->tt_ttisstd != FALSE)
-                                               return -1;
-                       }
-               }
-       }
-       return 0;
-}
-
-static const int       mon_lengths[2][MONSPERYEAR] = {
-       { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
-       { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
-};
-
-static const int       year_lengths[2] = {
-       DAYSPERNYEAR, DAYSPERLYEAR
-};
-
-/*
-** Given a pointer into a time zone string, scan until a character that is not
-** a valid character in a zone name is found.  Return a pointer to that
-** character.
-*/
-
-static const char *
-getzname(strp)
-register const char *  strp;
-{
-       register char   c;
-
-       while ((c = *strp) != '\0' && !isdigit(c) && c != ',' && c != '-' &&
-               c != '+')
-                       ++strp;
-       return strp;
-}
-
-/*
-** Given a pointer into a time zone string, extract a number from that string.
-** Check that the number is within a specified range; if it is not, return
-** NULL.
-** Otherwise, return a pointer to the first character not part of the number.
-*/
-
-static const char *
-getnum(strp, nump, min, max)
-register const char *  strp;
-int * const            nump;
-const int              min;
-const int              max;
-{
-       register char   c;
-       register int    num;
-
-       if (strp == NULL || !isdigit(*strp))
-               return NULL;
-       num = 0;
-       while ((c = *strp) != '\0' && isdigit(c)) {
-               num = num * 10 + (c - '0');
-               if (num > max)
-                       return NULL;    /* illegal value */
-               ++strp;
-       }
-       if (num < min)
-               return NULL;            /* illegal value */
-       *nump = num;
-       return strp;
-}
-
-/*
-** Given a pointer into a time zone string, extract a number of seconds,
-** in hh[:mm[:ss]] form, from the string.
-** If any error occurs, return NULL.
-** Otherwise, return a pointer to the first character not part of the number
-** of seconds.
-*/
-
-static const char *
-getsecs(strp, secsp)
-register const char *  strp;
-long * const           secsp;
-{
-       int     num;
-
-       /*
-       ** `HOURSPERDAY * DAYSPERWEEK - 1' allows quasi-Posix rules like
-       ** "M10.4.6/26", which does not conform to Posix,
-       ** but which specifies the equivalent of
-       ** ``02:00 on the first Sunday on or after 23 Oct''.
-       */
-       strp = getnum(strp, &num, 0, HOURSPERDAY * DAYSPERWEEK - 1);
-       if (strp == NULL)
-               return NULL;
-       *secsp = num * (long) SECSPERHOUR;
-       if (*strp == ':') {
-               ++strp;
-               strp = getnum(strp, &num, 0, MINSPERHOUR - 1);
-               if (strp == NULL)
-                       return NULL;
-               *secsp += num * SECSPERMIN;
-               if (*strp == ':') {
-                       ++strp;
-                       /* `SECSPERMIN' allows for leap seconds.  */
-                       strp = getnum(strp, &num, 0, SECSPERMIN);
-                       if (strp == NULL)
-                               return NULL;
-                       *secsp += num;
-               }
-       }
-       return strp;
-}
-
-/*
-** Given a pointer into a time zone string, extract an offset, in
-** [+-]hh[:mm[:ss]] form, from the string.
-** If any error occurs, return NULL.
-** Otherwise, return a pointer to the first character not part of the time.
-*/
-
-static const char *
-getoffset(strp, offsetp)
-register const char *  strp;
-long * const           offsetp;
-{
-       register int    neg;
-
-       if (*strp == '-') {
-               neg = 1;
-               ++strp;
-       } else if (isdigit(*strp) || *strp++ == '+')
-               neg = 0;
-       else    return NULL;            /* illegal offset */
-       strp = getsecs(strp, offsetp);
-       if (strp == NULL)
-               return NULL;            /* illegal time */
-       if (neg)
-               *offsetp = -*offsetp;
-       return strp;
-}
-
-/*
-** Given a pointer into a time zone string, extract a rule in the form
-** date[/time].  See POSIX section 8 for the format of "date" and "time".
-** If a valid rule is not found, return NULL.
-** Otherwise, return a pointer to the first character not part of the rule.
-*/
-
-static const char *
-getrule(strp, rulep)
-const char *                   strp;
-register struct rule * const   rulep;
-{
-       if (*strp == 'J') {
-               /*
-               ** Julian day.
-               */
-               rulep->r_type = JULIAN_DAY;
-               ++strp;
-               strp = getnum(strp, &rulep->r_day, 1, DAYSPERNYEAR);
-       } else if (*strp == 'M') {
-               /*
-               ** Month, week, day.
-               */
-               rulep->r_type = MONTH_NTH_DAY_OF_WEEK;
-               ++strp;
-               strp = getnum(strp, &rulep->r_mon, 1, MONSPERYEAR);
-               if (strp == NULL)
-                       return NULL;
-               if (*strp++ != '.')
-                       return NULL;
-               strp = getnum(strp, &rulep->r_week, 1, 5);
-               if (strp == NULL)
-                       return NULL;
-               if (*strp++ != '.')
-                       return NULL;
-               strp = getnum(strp, &rulep->r_day, 0, DAYSPERWEEK - 1);
-       } else if (isdigit(*strp)) {
-               /*
-               ** Day of year.
-               */
-               rulep->r_type = DAY_OF_YEAR;
-               strp = getnum(strp, &rulep->r_day, 0, DAYSPERLYEAR - 1);
-       } else  return NULL;            /* invalid format */
-       if (strp == NULL)
-               return NULL;
-       if (*strp == '/') {
-               /*
-               ** Time specified.
-               */
-               ++strp;
-               strp = getsecs(strp, &rulep->r_time);
-       } else  rulep->r_time = 2 * SECSPERHOUR;        /* default = 2:00:00 */
-       return strp;
-}
-
-/*
-** Given the Epoch-relative time of January 1, 00:00:00 GMT, in a year, the
-** year, a rule, and the offset from GMT at the time that rule takes effect,
-** calculate the Epoch-relative time that rule takes effect.
-*/
-
-static time_t
-transtime(janfirst, year, rulep, offset)
-const time_t                           janfirst;
-const int                              year;
-register const struct rule * const     rulep;
-const long                             offset;
-{
-       register int    leapyear;
-       register time_t value;
-       register int    i;
-       int             d, m1, yy0, yy1, yy2, dow;
-
-       INITIALIZE(value);
-       leapyear = isleap(year);
-       switch (rulep->r_type) {
-
-       case JULIAN_DAY:
-               /*
-               ** Jn - Julian day, 1 == January 1, 60 == March 1 even in leap
-               ** years.
-               ** In non-leap years, or if the day number is 59 or less, just
-               ** add SECSPERDAY times the day number-1 to the time of
-               ** January 1, midnight, to get the day.
-               */
-               value = janfirst + (rulep->r_day - 1) * SECSPERDAY;
-               if (leapyear && rulep->r_day >= 60)
-                       value += SECSPERDAY;
-               break;
-
-       case DAY_OF_YEAR:
-               /*
-               ** n - day of year.
-               ** Just add SECSPERDAY times the day number to the time of
-               ** January 1, midnight, to get the day.
-               */
-               value = janfirst + rulep->r_day * SECSPERDAY;
-               break;
-
-       case MONTH_NTH_DAY_OF_WEEK:
-               /*
-               ** Mm.n.d - nth "dth day" of month m.
-               */
-               value = janfirst;
-               for (i = 0; i < rulep->r_mon - 1; ++i)
-                       value += mon_lengths[leapyear][i] * SECSPERDAY;
-
-               /*
-               ** Use Zeller's Congruence to get day-of-week of first day of
-               ** month.
-               */
-               m1 = (rulep->r_mon + 9) % 12 + 1;
-               yy0 = (rulep->r_mon <= 2) ? (year - 1) : year;
-               yy1 = yy0 / 100;
-               yy2 = yy0 % 100;
-               dow = ((26 * m1 - 2) / 10 +
-                       1 + yy2 + yy2 / 4 + yy1 / 4 - 2 * yy1) % 7;
-               if (dow < 0)
-                       dow += DAYSPERWEEK;
-
-               /*
-               ** "dow" is the day-of-week of the first day of the month.  Get
-               ** the day-of-month (zero-origin) of the first "dow" day of the
-               ** month.
-               */
-               d = rulep->r_day - dow;
-               if (d < 0)
-                       d += DAYSPERWEEK;
-               for (i = 1; i < rulep->r_week; ++i) {
-                       if (d + DAYSPERWEEK >=
-                               mon_lengths[leapyear][rulep->r_mon - 1])
-                                       break;
-                       d += DAYSPERWEEK;
-               }
-
-               /*
-               ** "d" is the day-of-month (zero-origin) of the day we want.
-               */
-               value += d * SECSPERDAY;
-               break;
-       }
-
-       /*
-       ** "value" is the Epoch-relative time of 00:00:00 GMT on the day in
-       ** question.  To get the Epoch-relative time of the specified local
-       ** time on that day, add the transition time and the current offset
-       ** from GMT.
-       */
-       return value + rulep->r_time + offset;
-}
-
-/*
-** Given a POSIX section 8-style TZ string, fill in the rule tables as
-** appropriate.
-*/
-
-static int
-tzparse(name, sp, lastditch)
-const char *                   name;
-register struct state * const  sp;
-const int                      lastditch;
-{
-       const char *                    stdname;
-       const char *                    dstname;
-       size_t                          stdlen;
-       size_t                          dstlen;
-       long                            stdoffset;
-       long                            dstoffset;
-       register time_t *               atp;
-       register unsigned char *        typep;
-       register char *                 cp;
-       register int                    load_result;
-
-       INITIALIZE(dstname);
-       stdname = name;
-       if (lastditch) {
-               stdlen = strlen(name);  /* length of standard zone name */
-               name += stdlen;
-               if (stdlen >= sizeof sp->chars)
-                       stdlen = (sizeof sp->chars) - 1;
-       } else {
-               name = getzname(name);
-               stdlen = name - stdname;
-               if (stdlen < 3)
-                       return -1;
-       }
-       if (*name == '\0')
-               return -1;      /* was "stdoffset = 0;" */
-       else {
-               name = getoffset(name, &stdoffset);
-               if (name == NULL)
-                       return -1;
-       }
-       load_result = tzload(TZDEFRULES, sp);
-       if (load_result != 0)
-               sp->leapcnt = 0;                /* so, we're off a little */
-       if (*name != '\0') {
-               dstname = name;
-               name = getzname(name);
-               dstlen = name - dstname;        /* length of DST zone name */
-               if (dstlen < 3)
-                       return -1;
-               if (*name != '\0' && *name != ',' && *name != ';') {
-                       name = getoffset(name, &dstoffset);
-                       if (name == NULL)
-                               return -1;
-               } else  dstoffset = stdoffset - SECSPERHOUR;
-               if (*name == ',' || *name == ';') {
-                       struct rule     start;
-                       struct rule     end;
-                       register int    year;
-                       register time_t janfirst;
-                       time_t          starttime;
-                       time_t          endtime;
-
-                       ++name;
-                       if ((name = getrule(name, &start)) == NULL)
-                               return -1;
-                       if (*name++ != ',')
-                               return -1;
-                       if ((name = getrule(name, &end)) == NULL)
-                               return -1;
-                       if (*name != '\0')
-                               return -1;
-                       sp->typecnt = 2;        /* standard time and DST */
-                       /*
-                       ** Two transitions per year, from EPOCH_YEAR to 2037.
-                       */
-                       sp->timecnt = 2 * (2037 - EPOCH_YEAR + 1);
-                       if (sp->timecnt > TZ_MAX_TIMES)
-                               return -1;
-                       sp->ttis[0].tt_gmtoff = -dstoffset;
-                       sp->ttis[0].tt_isdst = 1;
-                       sp->ttis[0].tt_abbrind = stdlen + 1;
-                       sp->ttis[1].tt_gmtoff = -stdoffset;
-                       sp->ttis[1].tt_isdst = 0;
-                       sp->ttis[1].tt_abbrind = 0;
-                       atp = sp->ats;
-                       typep = sp->types;
-                       janfirst = 0;
-                       for (year = EPOCH_YEAR; year <= 2037; ++year) {
-                               starttime = transtime(janfirst, year, &start,
-                                       stdoffset);
-                               endtime = transtime(janfirst, year, &end,
-                                       dstoffset);
-                               if (starttime > endtime) {
-                                       *atp++ = endtime;
-                                       *typep++ = 1;   /* DST ends */
-                                       *atp++ = starttime;
-                                       *typep++ = 0;   /* DST begins */
-                               } else {
-                                       *atp++ = starttime;
-                                       *typep++ = 0;   /* DST begins */
-                                       *atp++ = endtime;
-                                       *typep++ = 1;   /* DST ends */
-                               }
-                               janfirst += year_lengths[isleap(year)] *
-                                       SECSPERDAY;
-                       }
-               } else {
-                       int             sawstd;
-                       int             sawdst;
-                       long            stdfix;
-                       long            dstfix;
-                       long            oldfix;
-                       int             isdst;
-                       register int    i;
-
-                       if (*name != '\0')
-                               return -1;
-                       if (load_result != 0)
-                               return -1;
-                       /*
-                       ** Compute the difference between the real and
-                       ** prototype standard and summer time offsets
-                       ** from GMT, and put the real standard and summer
-                       ** time offsets into the rules in place of the
-                       ** prototype offsets.
-                       */
-                       sawstd = FALSE;
-                       sawdst = FALSE;
-                       stdfix = 0;
-                       dstfix = 0;
-                       for (i = 0; i < sp->typecnt; ++i) {
-                               if (sp->ttis[i].tt_isdst) {
-                                       oldfix = dstfix;
-                                       dstfix = sp->ttis[i].tt_gmtoff +
-                                               dstoffset;
-                                       if (sawdst && (oldfix != dstfix))
-                                               return -1;
-                                       sp->ttis[i].tt_gmtoff = -dstoffset;
-                                       sp->ttis[i].tt_abbrind = stdlen + 1;
-                                       sawdst = TRUE;
-                               } else {
-                                       oldfix = stdfix;
-                                       stdfix = sp->ttis[i].tt_gmtoff +
-                                               stdoffset;
-                                       if (sawstd && (oldfix != stdfix))
-                                               return -1;
-                                       sp->ttis[i].tt_gmtoff = -stdoffset;
-                                       sp->ttis[i].tt_abbrind = 0;
-                                       sawstd = TRUE;
-                               }
-                       }
-                       /*
-                       ** Make sure we have both standard and summer time.
-                       */
-                       if (!sawdst || !sawstd)
-                               return -1;
-                       /*
-                       ** Now correct the transition times by shifting
-                       ** them by the difference between the real and
-                       ** prototype offsets.  Note that this difference
-                       ** can be different in standard and summer time;
-                       ** the prototype probably has a 1-hour difference
-                       ** between standard and summer time, but a different
-                       ** difference can be specified in TZ.
-                       */
-                       isdst = FALSE;  /* we start in standard time */
-                       for (i = 0; i < sp->timecnt; ++i) {
-                               register const struct ttinfo *  ttisp;
-
-                               /*
-                               ** If summer time is in effect, and the
-                               ** transition time was not specified as
-                               ** standard time, add the summer time
-                               ** offset to the transition time;
-                               ** otherwise, add the standard time offset
-                               ** to the transition time.
-                               */
-                               ttisp = &sp->ttis[sp->types[i]];
-                               sp->ats[i] +=
-                                       (isdst && !ttisp->tt_ttisstd) ?
-                                               dstfix : stdfix;
-                               isdst = ttisp->tt_isdst;
-                       }
-               }
-       } else {
-               dstlen = 0;
-               sp->typecnt = 1;                /* only standard time */
-               sp->timecnt = 0;
-               sp->ttis[0].tt_gmtoff = -stdoffset;
-               sp->ttis[0].tt_isdst = 0;
-               sp->ttis[0].tt_abbrind = 0;
-       }
-       sp->charcnt = stdlen + 1;
-       if (dstlen != 0)
-               sp->charcnt += dstlen + 1;
-       if (sp->charcnt > sizeof sp->chars)
-               return -1;
-       cp = sp->chars;
-       (void) strncpy(cp, stdname, stdlen);
-       cp += stdlen;
-       *cp++ = '\0';
-       if (dstlen != 0) {
-               (void) strncpy(cp, dstname, dstlen);
-               *(cp + dstlen) = '\0';
-       }
-       return 0;
-}
-
-static void
-gmtload(sp)
-struct state * const   sp;
-{
-       if (tzload(gmt, sp) != 0)
-               (void) tzparse(gmt, sp, TRUE);
-}
-
-#ifndef STD_INSPIRED
-/*
-** A non-static declaration of tzsetwall in a system header file
-** may cause a warning about this upcoming static declaration...
-*/
-static
-#endif /* !defined STD_INSPIRED */
-void
-tzsetwall P((void))
-{
-       if (lcl_is_set < 0)
-               return;
-       lcl_is_set = -1;
-
-#ifdef ALL_STATE
-       if (lclptr == NULL) {
-               lclptr = (struct state *) malloc(sizeof *lclptr);
-               if (lclptr == NULL) {
-                       settzname();    /* all we can do */
-                       return;
-               }
-       }
-#endif /* defined ALL_STATE */
-       if (tzload((char *) NULL, lclptr) != 0)
-               gmtload(lclptr);
-       settzname();
-}
-
-void
-tzset P((void))
-{
-       register const char *   name;
-
-       name = getenv("TZ");
-       if (name == NULL) {
-               tzsetwall();
-               return;
-       }
-
-       if (lcl_is_set > 0  &&  strcmp(lcl_TZname, name) == 0)
-               return;
-       lcl_is_set = (strlen(name) < sizeof(lcl_TZname));
-       if (lcl_is_set)
-               (void) strcpy(lcl_TZname, name);
-
-#ifdef ALL_STATE
-       if (lclptr == NULL) {
-               lclptr = (struct state *) malloc(sizeof *lclptr);
-               if (lclptr == NULL) {
-                       settzname();    /* all we can do */
-                       return;
-               }
-       }
-#endif /* defined ALL_STATE */
-       if (*name == '\0') {
-               /*
-               ** User wants it fast rather than right.
-               */
-               lclptr->leapcnt = 0;            /* so, we're off a little */
-               lclptr->timecnt = 0;
-               lclptr->ttis[0].tt_gmtoff = 0;
-               lclptr->ttis[0].tt_abbrind = 0;
-               (void) strcpy(lclptr->chars, gmt);
-       } else if (tzload(name, lclptr) != 0)
-               if (name[0] == ':' || tzparse(name, lclptr, FALSE) != 0)
-                       (void) gmtload(lclptr);
-       settzname();
-}
-
-/*
-** The easy way to behave "as if no library function calls" localtime
-** is to not call it--so we drop its guts into "localsub", which can be
-** freely called.  (And no, the PANS doesn't require the above behavior--
-** but it *is* desirable.)
-**
-** The unused offset argument is for the benefit of mktime variants.
-*/
-
-/*ARGSUSED*/
-static void
-localsub(timep, offset, tmp)
-const time_t * const   timep;
-const long             offset;
-struct tm * const      tmp;
-{
-       register const struct state *   sp;
-       register const struct ttinfo *  ttisp;
-       register int                    i;
-       const time_t                    t = *timep;
-
-       sp = lclptr;
-#ifdef ALL_STATE
-       if (sp == NULL) {
-               gmtsub(timep, offset, tmp);
-               return;
-       }
-#endif /* defined ALL_STATE */
-       if (sp->timecnt == 0 || t < sp->ats[0]) {
-               i = 0;
-               while (sp->ttis[i].tt_isdst)
-                       if (++i >= sp->typecnt) {
-                               i = 0;
-                               break;
-                       }
-       } else {
-               for (i = 1; i < sp->timecnt; ++i)
-                       if (t < sp->ats[i])
-                               break;
-               i = sp->types[i - 1];
-       }
-       ttisp = &sp->ttis[i];
-       /*
-       ** To get (wrong) behavior that's compatible with System V Release 2.0
-       ** you'd replace the statement below with
-       **      t += ttisp->tt_gmtoff;
-       **      timesub(&t, 0L, sp, tmp);
-       */
-       timesub(&t, ttisp->tt_gmtoff, sp, tmp);
-       tmp->tm_isdst = ttisp->tt_isdst;
-       tzname[tmp->tm_isdst] = (char *) &sp->chars[ttisp->tt_abbrind];
-#ifdef TM_ZONE
-       tmp->TM_ZONE = &sp->chars[ttisp->tt_abbrind];
-#endif /* defined TM_ZONE */
-}
-
-struct tm *
-localtime(timep)
-const time_t * const   timep;
-{
-       tzset();
-       localsub(timep, 0L, &tm);
-       return &tm;
-}
-
-/*
-** gmtsub is to gmtime as localsub is to localtime.
-*/
-
-static void
-gmtsub(timep, offset, tmp)
-const time_t * const   timep;
-const long             offset;
-struct tm * const      tmp;
-{
-       if (!gmt_is_set) {
-               gmt_is_set = TRUE;
-#ifdef ALL_STATE
-               gmtptr = (struct state *) malloc(sizeof *gmtptr);
-               if (gmtptr != NULL)
-#endif /* defined ALL_STATE */
-                       gmtload(gmtptr);
-       }
-       timesub(timep, offset, gmtptr, tmp);
-#ifdef TM_ZONE
-       /*
-       ** Could get fancy here and deliver something such as
-       ** "GMT+xxxx" or "GMT-xxxx" if offset is non-zero,
-       ** but this is no time for a treasure hunt.
-       */
-       if (offset != 0)
-               tmp->TM_ZONE = wildabbr;
-       else {
-#ifdef ALL_STATE
-               if (gmtptr == NULL)
-                       tmp->TM_ZONE = gmt;
-               else    tmp->TM_ZONE = gmtptr->chars;
-#endif /* defined ALL_STATE */
-#ifndef ALL_STATE
-               tmp->TM_ZONE = gmtptr->chars;
-#endif /* State Farm */
-       }
-#endif /* defined TM_ZONE */
-}
-
-struct tm *
-gmtime(timep)
-const time_t * const   timep;
-{
-       gmtsub(timep, 0L, &tm);
-       return &tm;
-}
-
-#ifdef STD_INSPIRED
-
-struct tm *
-offtime(timep, offset)
-const time_t * const   timep;
-const long             offset;
-{
-       gmtsub(timep, offset, &tm);
-       return &tm;
-}
-
-#endif /* defined STD_INSPIRED */
-
-static void
-timesub(timep, offset, sp, tmp)
-const time_t * const                   timep;
-const long                             offset;
-register const struct state * const    sp;
-register struct tm * const             tmp;
-{
-       register const struct lsinfo *  lp;
-       register long                   days;
-       register long                   rem;
-       register int                    y;
-       register int                    yleap;
-       register const int *            ip;
-       register long                   corr;
-       register int                    hit;
-       register int                    i;
-
-       corr = 0;
-       hit = 0;
-#ifdef ALL_STATE
-       i = (sp == NULL) ? 0 : sp->leapcnt;
-#endif /* defined ALL_STATE */
-#ifndef ALL_STATE
-       i = sp->leapcnt;
-#endif /* State Farm */
-       while (--i >= 0) {
-               lp = &sp->lsis[i];
-               if (*timep >= lp->ls_trans) {
-                       if (*timep == lp->ls_trans) {
-                               hit = ((i == 0 && lp->ls_corr > 0) ||
-                                       lp->ls_corr > sp->lsis[i - 1].ls_corr);
-                               if (hit)
-                                       while (i > 0 &&
-                                               sp->lsis[i].ls_trans ==
-                                               sp->lsis[i - 1].ls_trans + 1 &&
-                                               sp->lsis[i].ls_corr ==
-                                               sp->lsis[i - 1].ls_corr + 1) {
-                                                       ++hit;
-                                                       --i;
-                                       }
-                       }
-                       corr = lp->ls_corr;
-                       break;
-               }
-       }
-       days = *timep / SECSPERDAY;
-       rem = *timep % SECSPERDAY;
-#ifdef mc68k
-       if (*timep == 0x80000000) {
-               /*
-               ** A 3B1 muffs the division on the most negative number.
-               */
-               days = -24855;
-               rem = -11648;
-       }
-#endif /* mc68k */
-       rem += (offset - corr);
-       while (rem < 0) {
-               rem += SECSPERDAY;
-               --days;
-       }
-       while (rem >= SECSPERDAY) {
-               rem -= SECSPERDAY;
-               ++days;
-       }
-       tmp->tm_hour = (int) (rem / SECSPERHOUR);
-       rem = rem % SECSPERHOUR;
-       tmp->tm_min = (int) (rem / SECSPERMIN);
-       tmp->tm_sec = (int) (rem % SECSPERMIN);
-       if (hit)
-               /*
-               ** A positive leap second requires a special
-               ** representation.  This uses "... ??:59:60" et seq.
-               */
-               tmp->tm_sec += hit;
-       tmp->tm_wday = (int) ((EPOCH_WDAY + days) % DAYSPERWEEK);
-       if (tmp->tm_wday < 0)
-               tmp->tm_wday += DAYSPERWEEK;
-       y = EPOCH_YEAR;
-       if (days >= 0)
-               for ( ; ; ) {
-                       yleap = isleap(y);
-                       if (days < (long) year_lengths[yleap])
-                               break;
-                       ++y;
-                       days = days - (long) year_lengths[yleap];
-               }
-       else do {
-               --y;
-               yleap = isleap(y);
-               days = days + (long) year_lengths[yleap];
-       } while (days < 0);
-       tmp->tm_year = y - TM_YEAR_BASE;
-       tmp->tm_yday = (int) days;
-       ip = mon_lengths[yleap];
-       for (tmp->tm_mon = 0; days >= (long) ip[tmp->tm_mon]; ++(tmp->tm_mon))
-               days = days - (long) ip[tmp->tm_mon];
-       tmp->tm_mday = (int) (days + 1);
-       tmp->tm_isdst = 0;
-#ifdef TM_GMTOFF
-       tmp->TM_GMTOFF = offset;
-#endif /* defined TM_GMTOFF */
-}
-
-char *
-ctime(timep)
-const time_t * const   timep;
-{
-/*
-** Section 4.12.3.2 of X3.159-1989 requires that
-**     The ctime funciton converts the calendar time pointed to by timer
-**     to local time in the form of a string.  It is equivalent to
-**             asctime(localtime(timer))
-*/
-       return asctime(localtime(timep));
-}
-
-/*
-** Adapted from code provided by Robert Elz, who writes:
-**     The "best" way to do mktime I think is based on an idea of Bob
-**     Kridle's (so its said...) from a long time ago. (mtxinu!kridle now).
-**     It does a binary search of the time_t space.  Since time_t's are
-**     just 32 bits, its a max of 32 iterations (even at 64 bits it
-**     would still be very reasonable).
-*/
-
-#ifndef WRONG
-#define WRONG  (-1)
-#endif /* !defined WRONG */
-
-/*
-** Simplified normalize logic courtesy Paul Eggert (eggert@twinsun.com).
-*/
-
-static int
-increment_overflow(number, delta)
-int *  number;
-int    delta;
-{
-       int number0;
-       
-       number0 = *number;
-       *number += delta;
-       return (*number < number0) != (delta < 0);
-}
-
-static int
-normalize_overflow(tensptr, unitsptr, base)
-int * const    tensptr;
-int * const    unitsptr;
-const int      base;
-{
-       register int    tensdelta;
-
-       tensdelta = (*unitsptr >= 0) ?
-               (*unitsptr / base) :
-               (-1 - (-1 - *unitsptr) / base);
-       *unitsptr -= tensdelta * base;
-       return increment_overflow(tensptr, tensdelta);
-}
-
-static int
-tmcomp(atmp, btmp)
-register const struct tm * const atmp;
-register const struct tm * const btmp;
-{
-       register int    result;
-
-       if ((result = (atmp->tm_year - btmp->tm_year)) == 0 &&
-               (result = (atmp->tm_mon - btmp->tm_mon)) == 0 &&
-               (result = (atmp->tm_mday - btmp->tm_mday)) == 0 &&
-               (result = (atmp->tm_hour - btmp->tm_hour)) == 0 &&
-               (result = (atmp->tm_min - btmp->tm_min)) == 0)
-                       result = atmp->tm_sec - btmp->tm_sec;
-       return result;
-}
-
-static time_t
-time2(tmp, funcp, offset, okayp)
-struct tm * const      tmp;
-void (* const          funcp)();
-const long             offset;
-int * const            okayp;
-{
-       register const struct state *   sp;
-       register int                    dir;
-       register int                    bits;
-       register int                    i, j ;
-       register int                    saved_seconds;
-       time_t                          newt;
-       time_t                          t;
-       struct tm                       yourtm, mytm;
-
-       *okayp = FALSE;
-       yourtm = *tmp;
-       if (normalize_overflow(&yourtm.tm_hour, &yourtm.tm_min, MINSPERHOUR))
-               return WRONG;
-       if (normalize_overflow(&yourtm.tm_mday, &yourtm.tm_hour, HOURSPERDAY))
-               return WRONG;
-       if (normalize_overflow(&yourtm.tm_year, &yourtm.tm_mon, MONSPERYEAR))
-               return WRONG;
-       /*
-       ** Turn yourtm.tm_year into an actual year number for now.
-       ** It is converted back to an offset from TM_YEAR_BASE later.
-       */
-       if (increment_overflow(&yourtm.tm_year, TM_YEAR_BASE))
-               return WRONG;
-       while (yourtm.tm_mday <= 0) {
-               if (increment_overflow(&yourtm.tm_year, -1))
-                       return WRONG;
-               yourtm.tm_mday += year_lengths[isleap(yourtm.tm_year)];
-       }
-       while (yourtm.tm_mday > DAYSPERLYEAR) {
-               yourtm.tm_mday -= year_lengths[isleap(yourtm.tm_year)];
-               if (increment_overflow(&yourtm.tm_year, 1))
-                       return WRONG;
-       }
-       for ( ; ; ) {
-               i = mon_lengths[isleap(yourtm.tm_year)][yourtm.tm_mon];
-               if (yourtm.tm_mday <= i)
-                       break;
-               yourtm.tm_mday -= i;
-               if (++yourtm.tm_mon >= MONSPERYEAR) {
-                       yourtm.tm_mon = 0;
-                       if (increment_overflow(&yourtm.tm_year, 1))
-                               return WRONG;
-               }
-       }
-       if (increment_overflow(&yourtm.tm_year, -TM_YEAR_BASE))
-               return WRONG;
-       if (yourtm.tm_year + TM_YEAR_BASE < EPOCH_YEAR) {
-               /*
-               ** We can't set tm_sec to 0, because that might push the
-               ** time below the minimum representable time.
-               ** Set tm_sec to 59 instead.
-               ** This assumes that the minimum representable time is
-               ** not in the same minute that a leap second was deleted from,
-               ** which is a safer assumption than using 58 would be.
-               */
-               if (increment_overflow(&yourtm.tm_sec, 1 - SECSPERMIN))
-                       return WRONG;
-               saved_seconds = yourtm.tm_sec;
-               yourtm.tm_sec = SECSPERMIN - 1;
-       } else {
-               saved_seconds = yourtm.tm_sec;
-               yourtm.tm_sec = 0;
-       }
-       /*
-       ** Calculate the number of magnitude bits in a time_t
-       ** (this works regardless of whether time_t is
-       ** signed or unsigned, though lint complains if unsigned).
-       */
-       for (bits = 0, t = 1; t > 0; ++bits, t <<= 1)
-               continue;
-       /*
-       ** If time_t is signed, then 0 is the median value,
-       ** if time_t is unsigned, then 1 << bits is median.
-       */
-       t = (t < 0) ? 0 : ((time_t) 1 << bits);
-       for ( ; ; ) {
-               (*funcp)(&t, offset, &mytm);
-               dir = tmcomp(&mytm, &yourtm);
-               if (dir != 0) {
-                       if (bits-- < 0)
-                               return WRONG;
-                       if (bits < 0)
-                               --t;
-                       else if (dir > 0)
-                               t -= (time_t) 1 << bits;
-                       else    t += (time_t) 1 << bits;
-                       continue;
-               }
-               if (yourtm.tm_isdst < 0 || mytm.tm_isdst == yourtm.tm_isdst)
-                       break;
-               /*
-               ** Right time, wrong type.
-               ** Hunt for right time, right type.
-               ** It's okay to guess wrong since the guess
-               ** gets checked.
-               */
-               /*
-               ** The (void *) casts are the benefit of SunOS 3.3 on Sun 2's.
-               */
-               sp = (const struct state *)
-                       (((void *) funcp == (void *) localsub) ?
-                       lclptr : gmtptr);
-#ifdef ALL_STATE
-               if (sp == NULL)
-                       return WRONG;
-#endif /* defined ALL_STATE */
-               for (i = 0; i < sp->typecnt; ++i) {
-                       if (sp->ttis[i].tt_isdst != yourtm.tm_isdst)
-                               continue;
-                       for (j = 0; j < sp->typecnt; ++j) {
-                               if (sp->ttis[j].tt_isdst == yourtm.tm_isdst)
-                                       continue;
-                               newt = t + sp->ttis[j].tt_gmtoff -
-                                       sp->ttis[i].tt_gmtoff;
-                               (*funcp)(&newt, offset, &mytm);
-                               if (tmcomp(&mytm, &yourtm) != 0)
-                                       continue;
-                               if (mytm.tm_isdst != yourtm.tm_isdst)
-                                       continue;
-                               /*
-                               ** We have a match.
-                               */
-                               t = newt;
-                               goto label;
-                       }
-               }
-               return WRONG;
-       }
-label:
-       newt = t + saved_seconds;
-       if ((newt < t) != (saved_seconds < 0))
-               return WRONG;
-       t = newt;
-       (*funcp)(&t, offset, tmp);
-       *okayp = TRUE;
-       return t;
-}
-
-static time_t
-time1(tmp, funcp, offset)
-struct tm * const      tmp;
-void (* const          funcp)();
-const long             offset;
-{
-       register time_t                 t;
-       register const struct state *   sp;
-       register int                    samei, otheri;
-       int                             okay;
-
-       if (tmp->tm_isdst > 1)
-               tmp->tm_isdst = 1;
-       t = time2(tmp, funcp, offset, &okay);
-#ifdef PCTS
-       /*
-       ** PCTS code courtesy Grant Sullivan (grant@osf.org).
-       */
-       if (okay)
-               return t;
-       if (tmp->tm_isdst < 0)
-               tmp->tm_isdst = 0;      /* reset to std and try again */
-#endif /* defined PCTS */
-#ifndef PCTS
-       if (okay || tmp->tm_isdst < 0)
-               return t;
-#endif /* !defined PCTS */
-       /*
-       ** We're supposed to assume that somebody took a time of one type
-       ** and did some math on it that yielded a "struct tm" that's bad.
-       ** We try to divine the type they started from and adjust to the
-       ** type they need.
-       */
-       /*
-       ** The (void *) casts are the benefit of SunOS 3.3 on Sun 2's.
-       */
-       sp = (const struct state *) (((void *) funcp == (void *) localsub) ?
-               lclptr : gmtptr);
-#ifdef ALL_STATE
-       if (sp == NULL)
-               return WRONG;
-#endif /* defined ALL_STATE */
-       for (samei = 0; samei < sp->typecnt; ++samei) {
-               if (sp->ttis[samei].tt_isdst != tmp->tm_isdst)
-                       continue;
-               for (otheri = 0; otheri < sp->typecnt; ++otheri) {
-                       if (sp->ttis[otheri].tt_isdst == tmp->tm_isdst)
-                               continue;
-                       tmp->tm_sec += sp->ttis[otheri].tt_gmtoff -
-                                       sp->ttis[samei].tt_gmtoff;
-                       tmp->tm_isdst = !tmp->tm_isdst;
-                       t = time2(tmp, funcp, offset, &okay);
-                       if (okay)
-                               return t;
-                       tmp->tm_sec -= sp->ttis[otheri].tt_gmtoff -
-                                       sp->ttis[samei].tt_gmtoff;
-                       tmp->tm_isdst = !tmp->tm_isdst;
-               }
-       }
-       return WRONG;
-}
-
-time_t
-mktime(tmp)
-struct tm * const      tmp;
-{
-       tzset();
-       return time1(tmp, localsub, 0L);
-}
-
-#ifdef STD_INSPIRED
-
-time_t
-timelocal(tmp)
-struct tm * const      tmp;
-{
-       tmp->tm_isdst = -1;     /* in case it wasn't initialized */
-       return mktime(tmp);
-}
-
-time_t
-timegm(tmp)
-struct tm * const      tmp;
-{
-       tmp->tm_isdst = 0;
-       return time1(tmp, gmtsub, 0L);
-}
-
-time_t
-timeoff(tmp, offset)
-struct tm * const      tmp;
-const long             offset;
-{
-       tmp->tm_isdst = 0;
-       return time1(tmp, gmtsub, offset);
-}
-
-#endif /* defined STD_INSPIRED */
-
-#ifdef CMUCS
-
-/*
-** The following is supplied for compatibility with
-** previous versions of the CMUCS runtime library.
-*/
-
-long
-gtime(tmp)
-struct tm * const      tmp;
-{
-       const time_t    t = mktime(tmp);
-
-       if (t == WRONG)
-               return -1;
-       return t;
-}
-
-#endif /* defined CMUCS */
-
-/*
-** XXX--is the below the right way to conditionalize??
-*/
-
-#ifdef STD_INSPIRED
-
-/*
-** IEEE Std 1003.1-1988 (POSIX) legislates that 536457599
-** shall correspond to "Wed Dec 31 23:59:59 GMT 1986", which
-** is not the case if we are accounting for leap seconds.
-** So, we provide the following conversion routines for use
-** when exchanging timestamps with POSIX conforming systems.
-*/
-
-static long
-leapcorr(timep)
-time_t *       timep;
-{
-       register struct state *         sp;
-       register struct lsinfo *        lp;
-       register int                    i;
-
-       sp = lclptr;
-       i = sp->leapcnt;
-       while (--i >= 0) {
-               lp = &sp->lsis[i];
-               if (*timep >= lp->ls_trans)
-                       return lp->ls_corr;
-       }
-       return 0;
-}
-
-time_t
-time2posix(t)
-time_t t;
-{
-       tzset();
-       return t - leapcorr(&t);
-}
-
-time_t
-posix2time(t)
-time_t t;
-{
-       time_t  x;
-       time_t  y;
-
-       tzset();
-       /*
-       ** For a positive leap second hit, the result
-       ** is not unique.  For a negative leap second
-       ** hit, the corresponding time doesn't exist,
-       ** so we return an adjacent second.
-       */
-       x = t + leapcorr(&t);
-       y = x - leapcorr(&x);
-       if (y < t) {
-               do {
-                       x++;
-                       y = x - leapcorr(&x);
-               } while (y < t);
-               if (t != y)
-                       return x - 1;
-       } else if (y > t) {
-               do {
-                       --x;
-                       y = x - leapcorr(&x);
-               } while (y > t);
-               if (t != y)
-                       return x + 1;
-       }
-       return x;
-}
-
-#endif /* defined STD_INSPIRED */
diff --git a/time/logwtmp.c b/time/logwtmp.c
deleted file mode 100644 (file)
index 6cf3237..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-#ifndef lint
-#ifndef NOID
-static char    elsieid[] = "@(#)logwtmp.c      7.4";
-/* As received from UCB, with include reordering and OLD_TIME condition. */
-#endif /* !defined NOID */
-#endif /* !defined lint */
-
-/*
- * Copyright (c) 1988 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by the University of California, 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'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANT[A]BILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifndef lint
-#ifdef LIBC_SCCS
-static char sccsid[] = "@(#)logwtmp.c  5.2 (Berkeley) 9/20/88";
-#endif /* defined LIBC_SCCS */
-#endif /* !defined lint */
-
-#include <sys/types.h>
-#include <utmp.h>
-
-#ifndef OLD_TIME
-
-#include <sys/file.h>
-#include <sys/time.h>
-#include <sys/stat.h>
-
-#define WTMPFILE       "/usr/adm/wtmp"
-
-logwtmp(line, name, host)
-       char *line, *name, *host;
-{
-       struct utmp ut;
-       struct stat buf;
-       int fd;
-       time_t time();
-       char *strncpy();
-
-       if ((fd = open(WTMPFILE, O_WRONLY|O_APPEND, 0)) < 0)
-               return;
-       if (!fstat(fd, &buf)) {
-               (void)strncpy(ut.ut_line, line, sizeof(ut.ut_line));
-               (void)strncpy(ut.ut_name, name, sizeof(ut.ut_name));
-               (void)strncpy(ut.ut_host, host, sizeof(ut.ut_host));
-               (void)time(&ut.ut_time);
-               if (write(fd, (char *)&ut, sizeof(struct utmp)) !=
-                       sizeof(struct utmp))
-                               (void)ftruncate(fd, buf.st_size);
-       }
-       (void)close(fd);
-}
-
-#endif /* !defined OLD_TIME */
diff --git a/time/newctime.3 b/time/newctime.3
deleted file mode 100644 (file)
index 4639360..0000000
+++ /dev/null
@@ -1,220 +0,0 @@
-.TH NEWCTIME 3
-.SH NAME
-asctime, ctime, difftime, gmtime, localtime, mktime \- convert date and time to ASCII
-.SH SYNOPSIS
-.nf
-.B extern char *tzname[2];
-.PP
-.B void tzset()
-.PP
-.B #include <sys/types.h>
-.PP
-.B char *ctime(clock)
-.B time_t *clock;
-.PP
-.B double difftime(time1, time0)
-.B time_t time1;
-.B time_t time0;
-.PP
-.B #include <time.h>
-.PP
-.B char *asctime(tm)
-.B struct tm *tm;
-.PP
-.B struct tm *localtime(clock)
-.B long *clock;
-.PP
-.B struct tm *gmtime(clock)
-.B long *clock;
-.PP
-.B time_t mktime(tm)
-.B struct tm *tm;
-.PP
-.B cc ... -lz
-.fi
-.SH DESCRIPTION
-.I Ctime\^
-converts a long integer, pointed to by
-.IR clock ,
-representing the time in seconds since
-00:00:00 UTC, January 1, 1970,
-and returns a pointer to a
-26-character string
-of the form
-.br
-.ce
-.eo
-Thu Nov 24 18:22:48 1986\n\0
-.ec
-.br
-All the fields have constant width.
-.PP
-.IR Localtime\^
-and
-.I gmtime\^
-return pointers to ``tm'' structures, described below.
-.I Localtime\^
-corrects for the time zone and any time zone adjustments
-(such as Daylight Saving Time in the U.S.A.).
-Before doing so,
-.I localtime\^
-calls
-.I tzset\^
-(if
-.I tzset\^
-has not been called in the current process).
-After filling in the ``tm'' structure,
-.I localtime
-sets the
-.BR tm_isdst 'th
-element of
-.B tzname
-to a pointer to an
-ASCII string that's the time zone abbreviation to be used with
-.IR localtime 's
-return value.
-.PP
-.I Gmtime\^
-converts to Coordinated Universal Time.
-.PP
-.I Asctime\^
-converts a time value contained in a
-``tm'' structure to a 26-character string,
-as shown in the above example,
-and returns a pointer
-to the string.
-.PP
-.I Mktime\^
-converts the broken-down time,
-expressed as local time,
-in the structure pointed to by
-.I tm
-into a calendar time value with the same encoding as that of the values
-returned by the
-.I time
-function.
-The original values of the
-.B tm_wday
-and
-.B tm_yday
-components of the structure are ignored,
-and the original values of the other components are not restricted
-to their normal ranges.
-(A positive or zero value for
-.B tm_isdst
-causes
-.I mktime
-to presume initially that summer time (for example, Daylight Saving Time
-in the U.S.A.)
-respectively,
-is or is not in effect for the specified time.
-A negative value for
-.B tm_isdst
-causes the
-.I mktime
-function to attempt to divine whether summer time is in effect
-for the specified time.)
-On successful completion, the values of the
-.B tm_wday
-and
-.B tm_yday
-components of the structure are set appropriately,
-and the other components are set to represent the specified calendar time,
-but with their values forced to their normal ranges; the final value of
-.B tm_mday
-is not set until
-.B tm_mon
-and
-.B tm_year
-are determined.
-.I Mktime\^
-returns the specified calendar time;
-If the calendar time cannot be represented,
-it returns
-.BR -1 .
-.PP
-.I Difftime\^
-returns the difference between two calendar times,
-.RI ( time1
--
-.IR time0 ),
-expressed in seconds.
-.PP
-Declarations of all the functions and externals, and the ``tm'' structure,
-are in the
-.B <time.h>\^
-header file.
-The structure (of type)
-.B struct tm
-includes the following fields:
-.RS
-.PP
-.nf
-.ta .5i +\w'long tm_gmtoff;\0\0'u
-       int tm_sec;     /\(** seconds (0 - 60) \(**/
-       int tm_min;     /\(** minutes (0 - 59) \(**/
-       int tm_hour;    /\(** hours (0 - 23) \(**/
-       int tm_mday;    /\(** day of month (1 - 31) \(**/
-       int tm_mon;     /\(** month of year (0 - 11) \(**/
-       int tm_year;    /\(** year \- 1900 \(**/
-       int tm_wday;    /\(** day of week (Sunday = 0) \(**/
-       int tm_yday;    /\(** day of year (0 - 365) \(**/
-       int tm_isdst;   /\(** is summer time in effect? \(**/
-       char \(**tm_zone;       /\(** abbreviation of timezone name \(**/
-       long tm_gmtoff; /\(** offset from UTC in seconds \(**/
-.fi
-.RE
-.PP
-The
-.I tm_zone
-and
-.I tm_gmtoff
-fields exist, and are filled in, only if arrangements to do
-so were made when the library containing these functions was
-created.
-There is no guarantee that these fields will continue to exist
-in this form in future releases of this code.
-.PP
-.I Tm_isdst\^
-is non-zero if summer time is in effect.
-.PP
-.I Tm_gmtoff
-is the offset (in seconds) of the time represented
-from UTC, with positive values indicating east
-of the Prime Meridian.
-.SH FILES
-.ta \w'/usr/local/etc/zoneinfo/posixrules\0\0'u
-/usr/local/etc/zoneinfo        time zone information directory
-.br
-/usr/local/etc/zoneinfo/localtime      local time zone file
-.br
-/usr/local/etc/zoneinfo/posixrules     used with POSIX-style TZ's
-.br
-/usr/local/etc/zoneinfo/GMT    for UTC leap seconds
-.sp
-If
-.B /usr/local/etc/zoneinfo/GMT
-is absent,
-UTC leap seconds are loaded from
-.BR /usr/local/etc/zoneinfo/posixrules .
-.SH SEE ALSO
-getenv(3),
-newtzset(3),
-time(2),
-tzfile(5)
-.SH NOTES
-The return values point to static data;
-the data is overwritten by each call.
-The
-.B tm_zone
-field of a returned
-.B "struct tm"
-points to a static array of characters, which
-will also be overwritten at the next call
-(and by calls to
-.IR tzset ).
-.PP
-Avoid using out-of-range values with
-.I mktime
-when setting up lunch with promptness sticklers in Riyadh.
-.\" @(#)newctime.3     7.9
diff --git a/time/newtzset.3 b/time/newtzset.3
deleted file mode 100644 (file)
index 1ca50ca..0000000
+++ /dev/null
@@ -1,236 +0,0 @@
-.TH NEWTZSET 3
-.SH NAME
-tzset \- initialize time conversion information
-.SH SYNOPSIS
-.nf
-.B void tzset()
-.PP
-.B cc ... -lz
-.fi
-.SH DESCRIPTION
-.I Tzset
-uses the value of the environment variable
-.B TZ
-to set time conversion information used by
-.IR localtime .
-If
-.B TZ
-does not appear in the environment,
-the best available approximation to local wall clock time, as specified
-by the
-.IR tzfile (5)-format
-file
-.B localtime
-in the system time conversion information directory, is used by
-.IR localtime .
-If
-.B TZ
-appears in the environment but its value is a null string,
-Coordinated Universal Time (UTC) is used (without leap second
-correction).  If
-.B TZ
-appears in the environment and its value is not a null string:
-.IP
-if the value begins with a colon, it is used as a pathname of a file
-from which to read the time conversion information;
-.IP
-if the value does not begin with a colon, it is first used as the
-pathname of a file from which to read the time conversion information,
-and, if that file cannot be read, is used directly as a specification of
-the time conversion information.
-.PP
-When
-.B TZ
-is used as a pathname, if it begins with a slash,
-it is used as an absolute pathname; otherwise,
-it is used as a pathname relative to a system time conversion information
-directory.
-The file must be in the format specified in
-.IR tzfile (5).
-.PP
-When
-.B TZ
-is used directly as a specification of the time conversion information,
-it must have the following syntax (spaces inserted for clarity):
-.IP
-\fIstd\|offset\fR[\fIdst\fR[\fIoffset\fR][\fB,\fIrule\fR]]
-.PP
-Where:
-.RS
-.TP 15
-.IR std " and " dst
-Three or more bytes that are the designation for the standard
-.RI ( std )
-or summer
-.RI ( dst )
-time zone.  Only
-.I std
-is required; if
-.I dst
-is missing, then summer time does not apply in this locale.
-Upper- and lowercase letters are explicitly allowed.  Any characters
-except a leading colon
-.RB ( : ),
-digits, comma
-.RB ( , ),
-minus
-.RB ( \(mi ),
-plus
-.RB ( \(pl ),
-and ASCII NUL are allowed.
-.TP
-.I offset
-Indicates the value one must add to the local time to arrive at
-Coordinated Universal Time.  The
-.I offset
-has the form:
-.RS
-.IP
-\fIhh\fR[\fB:\fImm\fR[\fB:\fIss\fR]]
-.RE
-.IP
-The minutes
-.RI ( mm )
-and seconds
-.RI ( ss )
-are optional.  The hour
-.RI ( hh )
-is required and may be a single digit.  The
-.I offset
-following
-.I std
-is required.  If no
-.I offset
-follows
-.IR dst ,
-summer time is assumed to be one hour ahead of standard time.  One or
-more digits may be used; the value is always interpreted as a decimal
-number.  The hour must be between zero and 24, and the minutes (and
-seconds) \(em if present \(em between zero and 59.  If preceded by a
-.RB `` \(mi '',
-the time zone shall be east of the Prime Meridian; otherwise it shall be
-west (which may be indicated by an optional preceding
-.RB `` \(pl '').
-.TP
-.I rule
-Indicates when to change to and back from summer time.  The
-.I rule
-has the form:
-.RS
-.IP
-\fIdate\fB/\fItime\fB,\fIdate\fB/\fItime\fR
-.RE
-.IP
-where the first
-.I date
-describes when the change from standard to summer time occurs and the
-second
-.I date
-describes when the change back happens.  Each
-.I time
-field describes when, in current local time, the change to the other
-time is made.
-.IP
-The format of
-.I date
-is one of the following:
-.RS
-.TP 10
-.BI J n
-The Julian day
-.I n
-.RI "(1\ \(<=" "\ n\ " "\(<=\ 365).
-Leap days are not counted; that is, in all years \(em including leap
-years \(em February 28 is day 59 and March 1 is day 60.  It is
-impossible to explicitly refer to the occasional February 29.
-.TP
-.I n
-The zero-based Julian day
-.RI "(0\ \(<=" "\ n\ " "\(<=\ 365).
-Leap days are counted, and it is possible to refer to February 29.
-.TP
-.BI M m . n . d
-The
-.IR d' th
-day
-.RI "(0\ \(<=" "\ d\ " "\(<=\ 6)
-of week
-.I n
-of month
-.I m
-of the year
-.RI "(1\ \(<=" "\ n\ " "\(<=\ 5,
-.RI "1\ \(<=" "\ m\ " "\(<=\ 12,
-where week 5 means ``the last
-.I d
-day in month
-.IR m ''
-which may occur in either the fourth or the fifth week).  Week 1 is the
-first week in which the
-.IR d' th
-day occurs.  Day zero is Sunday.
-.RE
-.IP "" 15
-The
-.I time
-has the same format as
-.I offset
-except that no leading sign
-.RB (`` \(mi ''
-or
-.RB `` \(pl '')
-is allowed.  The default, if
-.I time
-is not given, is
-.BR 02:00:00 .
-.RE
-.LP
-If no
-.I rule
-is present in
-.BR TZ ,
-the rules specified
-by the
-.IR tzfile (5)-format
-file
-.B posixrules
-in the system time conversion information directory are used, with the
-standard and summer time offsets from UTC replaced by those specified by
-the
-.I offset
-values in
-.BR TZ .
-.PP
-For compatibility with System V Release 3.1, a semicolon
-.RB ( ; )
-may be used to separate the
-.I rule
-from the rest of the specification.
-.PP
-If the
-.B TZ
-environment variable does not specify a
-.IR tzfile (5)-format
-and cannot be interpreted as a direct specification,
-UTC is used.
-.SH FILES
-.ta \w'/usr/local/etc/zoneinfo/posixrules\0\0'u
-/usr/local/etc/zoneinfo        time zone information directory
-.br
-/usr/local/etc/zoneinfo/localtime      local time zone file
-.br
-/usr/local/etc/zoneinfo/posixrules     used with POSIX-style TZ's
-.br
-/usr/local/etc/zoneinfo/GMT    for UTC leap seconds
-.sp
-If
-.B /usr/local/etc/zoneinfo/GMT
-is absent,
-UTC leap seconds are loaded from
-.BR /usr/local/etc/zoneinfo/posixrules .
-.SH SEE ALSO
-getenv(3),
-newctime(3),
-time(2),
-tzfile(5)
-.\" @(#)newtzset.3     7.3
diff --git a/time/northamerica b/time/northamerica
deleted file mode 100644 (file)
index 40733fd..0000000
+++ /dev/null
@@ -1,953 +0,0 @@
-# @(#)northamerica     7.12
-# also includes Central America and the Caribbean
-
-# This data is by no means authoritative; if you think you know better,
-# go ahead and edit the file (and please send any changes to
-# tz@elsie.nci.nih.gov for general use in the future).
-
-# From Paul Eggert <eggert@twinsun.com> (August 17, 1994):
-# A reliable and entertaining source about time zones is
-# Derek Howse, Greenwich time and the discovery of the longitude,
-# Oxford University Press (1980).
-
-###############################################################################
-
-# United States
-
-# From Arthur David Olson:
-# US Daylight Saving Time ended on the last Sunday of *October* in 1974.
-# See, for example, the front page of the Saturday, October 26, 1974
-# and Sunday, October 27, 1974 editions of the Washington Post.
-
-# From seismo!munnari!kre:
-# I recall also being told by someone once that Canada didn't have
-# the DST variations in 74/75 that the US did, but I am not nearly
-# sure enough of this to add anything.
-
-# From Arthur David Olson:
-# The above has been confirmed by Bob Devine; we'll go with it here.
-
-# From Arthur David Olson:
-# Before the Uniform Time Act of 1966 took effect in 1967, observance of
-# Daylight Saving Time in the US was by local option, except during wartime.
-
-# Rule NAME    FROM    TO      TYPE    IN      ON      AT      SAVE    LETTER/S
-Rule   US      1918    1919    -       Mar     lastSun 2:00    1:00    D
-Rule   US      1918    1919    -       Oct     lastSun 2:00    0       S
-Rule   US      1942    only    -       Feb     9       2:00    1:00    W # War
-Rule   US      1945    only    -       Sep     30      2:00    0       S
-Rule   US      1967    max     -       Oct     lastSun 2:00    0       S
-Rule   US      1967    1973    -       Apr     lastSun 2:00    1:00    D
-Rule   US      1974    only    -       Jan     6       2:00    1:00    D
-Rule   US      1975    only    -       Feb     23      2:00    1:00    D
-Rule   US      1976    1986    -       Apr     lastSun 2:00    1:00    D
-Rule   US      1987    max     -       Apr     Sun>=1  2:00    1:00    D
-
-# From Bob Devine (January 28, 1988):
-# ...Alaska (and Hawaii) had the timezone names changed in 1967.
-#    old                        new
-#    Pacific Standard Time(PST)  -same-
-#    Yukon Standard Time(YST)    -same-
-#    Central Alaska S.T. (CAT)   Alaska-Hawaii St[an]dard Time (AHST)
-#    Nome Standard Time (NT)     Bering Standard Time (BST)
-#
-# ...Alaska's timezone lines were redrawn in 1983 to give only 2 tz.
-#    The YST zone now covers nearly all of the state, AHST just part
-#    of the Aleutian islands.   No DST.
-
-# From U. S. Naval Observatory (January 19, 1989):
-# USA  EASTERN       5 H  BEHIND UTC    NEW YORK, WASHINGTON
-# USA  EASTERN       4 H  BEHIND UTC    APR 3 - OCT 30
-# USA  CENTRAL       6 H  BEHIND UTC    CHICAGO, HOUSTON
-# USA  CENTRAL       5 H  BEHIND UTC    APR 3 - OCT 30
-# USA  MOUNTAIN      7 H  BEHIND UTC    DENVER
-# USA  MOUNTAIN      6 H  BEHIND UTC    APR 3 - OCT 30
-# USA  PACIFIC       8 H  BEHIND UTC    L.A., SAN FRANCISCO
-# USA  PACIFIC       7 H  BEHIND UTC    APR 3 - OCT 30
-# USA  ALASKA STD    9 H  BEHIND UTC    MOST OF ALASKA     (AKST)
-# USA  ALASKA STD    8 H  BEHIND UTC    APR 3 - OCT 30 (AKDT)
-# USA  ALEUTIAN     10 H  BEHIND UTC    ISLANDS WEST OF 170W
-# USA  - " -         9 H  BEHIND UTC    APR 3 - OCT 30
-# USA  HAWAII       10 H  BEHIND UTC
-# USA  BERING       11 H  BEHIND UTC    SAMOA, MIDWAY
-
-# From Arthur David Olson (January 21, 1989):
-# The above dates are for 1988.
-# Note the "AKST" and "AKDT" abbreviations, the claim that there's
-# no DST in Samoa, and the claim that there is DST in Alaska and the
-# Aleutians.
-
-# From Arthur David Olson (February 13, 1988):
-# Legal standard time zone names, from United States Code (1982 Edition and
-# Supplement III), Title 15, Chapter 6, Section 260 and forward.  First, names
-# up to April 1, 1967 (when most provisions of the Uniform Time Act of 1966
-# took effect), as explained in sections 263 and 261:
-#      (none)
-#      United States standard eastern time
-#      United States standard mountain time
-#      United States standard central time
-#      United States standard Pacific time
-#      (none)
-#      United States standard Alaska time
-#      (none)
-# Next, names from April 1, 1967 until November 30, 1983 (the date for
-# public law 98-181):
-#      Atlantic standard time
-#      eastern standard time
-#      central standard time
-#      mountain standard time
-#      Pacific standard time
-#      Yukon standard time
-#      Alaska-Hawaii standard time
-#      Bering standard time
-# And after November 30, 1983:
-#      Atlantic standard time
-#      eastern standard time
-#      central standard time
-#      mountain standard time
-#      Pacific standard time
-#      Alaska standard time
-#      Hawaii-Aleutian standard time
-#      Samoa standard time
-# The law doesn't give abbreviations.
-
-# From Paul Eggert <eggert@twinsun.com> (August 16, 1994):
-# Howse writes that Alaska switched from the Julian to the Gregorian calendar,
-# and from east-of-GMT to west-of-GMT days, in 1867 when the US purchased it
-# from Russia.  We don't have this data pinned down yet, though.
-
-# Easy stuff first--including Alaska, where we ignore history (since we
-# can't tell if we should give Yukon time or Alaska-Hawaii time for "old"
-# times).
-
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone America/New_York  -5:00   US      E%sT
-Zone America/Chicago   -6:00   US      C%sT
-Zone America/Denver    -7:00   US      M%sT
-Zone America/Los_Angeles -8:00 US      P%sT
-Zone America/Anchorage -9:00   US      AK%sT
-                                       # AK%sT is the abbreviation per USNO
-
-# Mainland US areas that are always Standard as of 1986.
-
-Zone America/Fort_Wayne -5:00  US      E%sT    1946
-                       -5:00   -       EST     # Always EST as of 1986
-# From Arthur David Olson (October 28, 1991):
-# An article on page A3 of the Sunday, October 27, 1991 Washington Post
-# notes that Starke County switched from Central time to Eastern time as of
-# October 27, 1991.
-Zone America/Knox_IN   -6:00   US      C%sT    1991 Oct 27 2:00
-                       -5:00   -       EST     # Always EST as of 1991
-Zone America/Phoenix   -7:00   US      M%sT    1946
-                       -7:00   -       MST     # Always MST as of 1986
-
-# From Arthur David Olson (February 13, 1988):
-# However. . .a writer from the Inter Tribal Council of Arizona, Inc.,
-# notes in private correspondence dated 12/28/87 that "Presently, only the
-# Navajo Nation participates in the Daylight Saving Time policy, due to its
-# large size and location in three states."  (The "only" means that other
-# tribal nations don't use DST.)
-
-Link America/Denver Navajo
-
-# From Bob Devine (January 28, 1988):
-# Michigan didn't observe DST from 1968 to 1973.
-
-Zone America/Detroit   -5:00   US      E%sT    1968
-                       -5:00   -       EST     1973
-                       -5:00   US      E%sT
-
-# Samoa just changes names.  No DST, per Naval Observatory.
-#
-# Howse writes that in 1879 the King of Samoa decided to change
-# ``the date in his kingdom from the Antipodean to the American system,
-# ordaining -- by a masterpiece of diplomatic flattery -- that
-# the Fourth of July should be celebrated twice in that year.''
-
-Zone Pacific/Samoa      12:37:12 -     LMT     1879 Jul  5
-                       -11:22:48 -     LMT     1911
-                       -11:30  -       SST     1950
-                       -11:00  -       NST     1967 Apr        # N=Nome
-                       -11:00  -       BST     1983 Nov 30     # B=Bering
-                       -11:00  -       SST                     # S=Samoa
-
-Zone Pacific/Midway    -11:49:28 -     LMT     1901
-                       -11:00  -       NST     1967 Apr        # N=Nome
-                       -11:00  -       BST     1983 Nov 30     # B=Bering
-                       -11:00  -       SST                     # S=Samoa
-
-# Aleutian has a name change.  DST, per Naval Observatory.
-
-Zone America/Atka      -10:00  US      AH%sT   1983 Nov 30
-                       -10:00  US      HA%sT
-
-# From Arthur David Olson:
-# And then there's Hawaii.
-# DST was observed for one day in 1933;
-# Standard time was change by half an hour in 1947;
-# it's always standard as of 1986.
-
-Zone Pacific/Honolulu  -10:30  US      H%sT    1933 Apr 30 2:00
-                       -10:30  1:00    HDT     1933 May  1 2:00
-                       -10:30  US      H%sT    1947 Jun  8 2:00
-                       -10:00  -       HST
-
-# Navassa
-# no information; probably like US/Eastern
-
-
-# Old names, for S5 users
-
-# Link LINK-FROM               LINK-TO
-Link   America/New_York        EST5EDT
-Link   America/Chicago         CST6CDT
-Link   America/Denver          MST7MDT
-Link   America/Los_Angeles     PST8PDT
-Link   America/Fort_Wayne      EST
-Link   America/Phoenix         MST
-Link   Pacific/Honolulu        HST
-
-################################################################################
-
-
-# From Paul Eggert <eggert@twinsun.com> (November 18, 1993):
-# A good source for time zone historical data outside the U.S. is
-# Thomas G. Shanks, The International Atlas (3rd edition),
-# San Diego: ACS Publications, Inc. (1991).
-# Except where otherwise noted, it is the source for the data below.
-#
-# Another source occasionally used is Edward W. Whitman, World Time Differences,
-# Whitman Publishing Co, 2 Niagara Av, Ealing, London (undated), which
-# I found in the UCLA library.
-#
-# I invented the abbreviation SPST for St Pierre Standard Time; SPDT likewise.
-# Corrections are welcome!
-#
-# See the `europe' file for Greenland.
-#
-# See the `africa' file for Zone naming conventions.
-
-
-
-# Canada
-
-# Canada is reportedly lots easier than the US--leastways since 1951.
-# I don't know what they did before then.
-# 4.3BSD claims that it's perfectly regular.
-# According to a posting in "comp.bugs.misc", "comp.unix.wizards", etc.
-# on February 8, 1987, by Dave Sherman of the Law Society of Upper Canada,
-# "...Canada (well, Ontario and at least some of the other provinces) are
-# adopting the new daylight savings time rules...".  We assume all of
-# Canada is doing so.
-
-# From Bob Devine (January 28, 1988):
-# All of Canada did have DST from your first rule except Saskatchewan.
-# Which parts did not observe DST is hard to pinpoint but most of the
-# province follows the rules.
-# NOTE: those that didn't have DST for that rule, also
-# probably did not have it for several years previous.
-
-# From U. S. Naval Observatory (January 19, 1989):
-# CANADA   NEW FDL    3.5H BEHIND UTC    ST.JOHN'S
-# CANADA   NEW FDL    1.5H BEHIND UTC    APR 3 - OCT 29
-# CANADA   ATLANTIC   4 H  BEHIND UTC    HALIFAX
-# CANADA   ATLANTIC   3 H  BEHIND UTC    APR 3 - OCT 29
-# CANADA   EASTERN    5 H  BEHIND UTC    TORONTO, MONTREAL, OTTAWA
-# CANADA   EASTERN    4 H  BEHIND UTC    APR 3 - OCT 29
-# CANADA   CENTRAL    6 H  BEHIND UTC    REGINA, WINNIPEG
-# CANADA   CENTRAL    5 H  BEHIND UTC    APR 3 - OCT 29
-# CANADA   MOUNTAIN   7 H  BEHIND UTC    CALGARY, EDMONTON
-# CANADA   MOUNTAIN   6 H  BEHIND UTC    APR 3 - OCT 29
-# CANADA   PACIFIC    8 H  BEHIND UTC    VANCOUVER
-# CANADA   PACIFIC    7 H  BEHIND UTC    APR 3 - OCT 29
-# CANADA   YUKON      SAME AS PACIFIC    DAWSON
-
-# From Arthur David Olson (January 21, 1989):
-# April 3 fell on a Sunday in 1988; October 29 fell on a Sunday in 1989.  Ahem.
-# Note claim that there's double DST in Newfoundland and that Yukon should
-# be same as Pacific.
-
-# From W. Jones (jones@skdad.usask.ca) (November 6, 1992):
-# The. . .below is based on information I got from our law library, the
-# provincial archives, and the provincial Community Services department.
-# A precise history would require digging through newspaper archives, and
-# since you didn't say what you wanted, I didn't bother.
-#
-# Saskatchewan is split by a time zone meridian (105W) and over the years
-# the boundary became pretty ragged as communities near it reevaluated
-# their affiliations in one direction or the other.  In 1965 a provincial
-# referendum favoured legislating common time practices.
-#
-# On 15 April 1966 the Time Act (c. T-14, Revised Statutes of
-# Saskatchewan 1978) was proclaimed, and established that the eastern
-# part of Saskatchewan would use CST year round, that districts in
-# northwest Saskatchewan would by default follow CST but could opt to
-# follow Mountain Time rules (thus 1 hour difference in the winter and
-# zero in the summer), and that districts in southwest Saskatchewan would
-# by default follow MT but could opt to follow CST.
-#
-# It took a few years for the dust to settle (I know one story of a town
-# on one time zone having its school in another, such that a mom had to
-# serve her family lunch in two shifts), but presently it seems that only
-# a few towns on the border with Alberta (e.g. Lloydminster) follow MT
-# rules any more; all other districts appear to have used CST year round
-# since sometime in the 1960s.
-#
-# Here's how I would summarize things.  Establish a "Saskatchewan" CST
-# time zone, and note that it officially exists as of 15 April 1966.  Any
-# current exceptions can put themselves in the "Mountain" zone, since
-# those are the rules they follow.  Any past exceptions can be forgotten,
-# since that's what those who live here have done.
-
-# From Arthur David Olson (November 21, 1992):
-# East-Saskatchewan kept to avoid problems for folks using that zone by name;
-# plain Saskatchewan added.
-
-# From Alain LaBont<e'> <ALB@immedia.ca> (1994-11-14):
-# I post here the time zone abbreviations standardized in Canada
-# for both English and French in the CAN/CSA-Z234.4-89 standard....
-#
-#      UTC     Standard time   Daylight savings time
-#      offset  French  English French  English
-#      -2:30   -       -       HAT     NDT
-#      -3      -       -       HAA     ADT
-#      -3:30   HNT     NST     -       -
-#      -4      HNA     AST     HAE     EDT
-#      -5      HNE     EST     HAC     CDT
-#      -6      HNC     CST     HAR     MDT
-#      -7      HNR     MST     HAP     PDT
-#      -8      HNP     PST     HAY     YDT
-#      -9      HNY     YST     -       -
-#
-#      HN: Heure Normale       ST: Standard Time
-#      HA: Heure Avanc<e'>e    DT: Daylight saving Time
-#
-#      A: de l'Atlantique      Atlantic
-#      C: du Centre            Central
-#      E: de l'Est             Eastern
-#      M:                      Mountain
-#      N:                      Newfoundland
-#      P: du Pacifique         Pacific
-#      R: des Rocheuses
-#      T: de Terre-Neuve
-#      Y: du Yukon             Yukon
-#
-# From Paul Eggert <eggert@twinsun.com> (1994-11-22):
-# Alas, this sort of thing must be handled by localization software.
-
-
-
-# From Shanks (1991):
-# Rule NAME    FROM    TO      TYPE    IN      ON      AT      SAVE    LETTER/S
-Rule   StJohns 1884    only    -       Jan      1      0:00    0       S
-Rule   StJohns 1917    1918    -       Apr     Sun>=8  2:00    1:00    D
-Rule   StJohns 1917    only    -       Sep     17      2:00    0       S
-Rule   StJohns 1918    only    -       Oct     31      2:00    0       S
-# Whitman gives 1919 Apr 5 and 1920 Apr 5; go with Shanks.
-Rule   StJohns 1919    only    -       May      5      23:00   1:00    D
-Rule   StJohns 1919    only    -       Aug     12      23:00   0       S
-# For 1931-1935 Whitman gives Apr same date; go with Shanks.
-Rule   StJohns 1920    1935    -       May     Sun>=1  23:00   1:00    D
-Rule   StJohns 1920    1935    -       Oct     lastSun 23:00   0       S
-# For 1936-1941 Shanks gives May Mon>=9 and Oct Mon>=2; go with Whitman.
-Rule   StJohns 1936    1941    -       May     Sun>=8  0:00    1:00    D
-Rule   StJohns 1936    1941    -       Oct     Sun>=1  0:00    0       S
-# Shanks gives 1942 May 11 - 1945 Sep 30; go with Whitman.
-Rule   StJohns 1942    only    -       Mar      1      0:00    1:00    D
-Rule   StJohns 1942    only    -       Dec     31      0:00    0       S
-Rule   StJohns 1943    only    -       May     30      0:00    1:00    D
-Rule   StJohns 1943    only    -       Sep      5      0:00    0       S
-Rule   StJohns 1944    only    -       Jul     10      0:00    1:00    D
-Rule   StJohns 1944    only    -       Sep      2      0:00    0       S
-Rule   StJohns 1945    only    -       Jan      1      0:00    1:00    D
-Rule   StJohns 1945    only    -       Oct      7      2:00    0       S
-# For 1946-9 Whitman gives May 5,4,9,1 - Oct 1,5,3,2, and for 1950 he gives
-# Apr 30 - Sep 24; go with Shanks.
-Rule   StJohns 1946    1950    -       May     Sun>=8  2:00    1:00    D
-Rule   StJohns 1946    1950    -       Oct     Sun>=2  2:00    0       S
-Rule   StJohns 1951    1986    -       Apr     lastSun 2:00    1:00    D
-Rule   StJohns 1951    1959    -       Sep     lastSun 2:00    0       S
-Rule   StJohns 1960    max     -       Oct     lastSun 2:00    0       S
-Rule   StJohns 1987    only    -       Apr     Sun>=1  2:00    1:00    D
-Rule   StJohns 1988    only    -       Apr     Sun>=1  2:00    2:00    D
-Rule   StJohns 1989    max     -       Apr     Sun>=1  2:00    1:00    D
-# St John's has an apostrophe, but Posix file names can't have apostrophes.
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone America/St_Johns  -3:30:52 -      LMT     1884
-                       -3:31   StJohns N%sT    1935 Mar 30
-                       -3:30   StJohns N%sT
-
-# Rule NAME    FROM    TO      TYPE    IN      ON      AT      SAVE    LETTER/S
-Rule Halifax   1902    only    -       Jun     15      0:00    0       S
-Rule Halifax   1916    only    -       Apr      1      0:00    1:00    D
-Rule Halifax   1916    only    -       Oct      1      0:00    0       S
-Rule Halifax   1918    only    -       Apr     14      2:00    1:00    D
-Rule Halifax   1918    only    -       Oct     31      2:00    0       S
-Rule Halifax   1920    only    -       May      9      0:00    1:00    D
-Rule Halifax   1920    only    -       Aug     29      0:00    0       S
-Rule Halifax   1921    only    -       May      6      0:00    1:00    D
-Rule Halifax   1921    1922    -       Sep      5      0:00    0       S
-Rule Halifax   1922    only    -       Apr     30      0:00    1:00    D
-Rule Halifax   1923    1925    -       May     Sun>=1  0:00    1:00    D
-Rule Halifax   1923    only    -       Sep      4      0:00    0       S
-Rule Halifax   1924    only    -       Sep     15      0:00    0       S
-Rule Halifax   1925    only    -       Sep     28      0:00    0       S
-Rule Halifax   1926    only    -       May     16      0:00    1:00    D
-Rule Halifax   1926    only    -       Sep     13      0:00    0       S
-Rule Halifax   1927    only    -       May      1      0:00    1:00    D
-Rule Halifax   1927    only    -       Sep     26      0:00    0       S
-Rule Halifax   1928    1931    -       May     Sun>=8  0:00    1:00    D
-Rule Halifax   1928    only    -       Sep      9      0:00    0       S
-Rule Halifax   1929    only    -       Sep      3      0:00    0       S
-Rule Halifax   1930    only    -       Sep     15      0:00    0       S
-Rule Halifax   1931    1932    -       Sep     Mon>=24 0:00    0       S
-Rule Halifax   1933    only    -       Apr     30      0:00    1:00    D
-Rule Halifax   1933    only    -       Oct      2      0:00    0       S
-Rule Halifax   1934    only    -       May     20      0:00    1:00    D
-Rule Halifax   1934    only    -       Sep     16      0:00    0       S
-Rule Halifax   1935    only    -       Jun      2      0:00    1:00    D
-Rule Halifax   1935    only    -       Sep     30      0:00    0       S
-Rule Halifax   1936    only    -       Jun      1      0:00    1:00    D
-Rule Halifax   1936    only    -       Sep     14      0:00    0       S
-Rule Halifax   1937    1938    -       May     Sun>=1  0:00    1:00    D
-Rule Halifax   1937    1941    -       Sep     Mon>=24 0:00    0       S
-Rule Halifax   1939    only    -       May     28      0:00    1:00    D
-Rule Halifax   1940    1941    -       May     Sun>=1  0:00    1:00    D
-Rule Halifax   1942    only    -       Feb     9       2:00    1:00    D
-Rule Halifax   1945    1959    -       Sep     lastSun 2:00    0       S
-Rule Halifax   1946    1959    -       Apr     lastSun 2:00    1:00    D
-Rule Halifax   1962    1986    -       Apr     lastSun 2:00    1:00    D
-Rule Halifax   1962    max     -       Oct     lastSun 2:00    0       S
-Rule Halifax   1987    max     -       Apr     Sun>=1  2:00    1:00    D
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone America/Halifax   -4:14:24 -      LMT     1902 Jun 15
-                       -4:00   Halifax A%sT
-
-# Rule NAME    FROM    TO      TYPE    IN      ON      AT      SAVE    LETTER/S
-Rule   Mont    1884    only    -       Jan      1      0:00    0       S
-Rule   Mont    1917    only    -       Mar     25      2:00    1:00    D
-Rule   Mont    1917    only    -       Apr     24      0:00    0       S
-Rule   Mont    1918    only    -       Apr     14      2:00    1:00    D
-Rule   Mont    1918    only    -       Oct     31      2:00    0       S
-Rule   Mont    1919    only    -       Mar     31      2:30    1:00    D
-Rule   Mont    1919    only    -       Oct     25      2:30    0       S
-Rule   Mont    1920    only    -       May      2      2:30    1:00    D
-Rule   Mont    1920    only    -       Oct      3      2:30    0       S
-Rule   Mont    1921    only    -       May      1      2:00    1:00    D
-Rule   Mont    1921    only    -       Oct      2      2:30    0       S
-Rule   Mont    1922    only    -       Apr     30      2:00    1:00    D
-Rule   Mont    1922    only    -       Oct      1      2:30    0       S
-Rule   Mont    1924    only    -       May     17      2:00    1:00    D
-Rule   Mont    1924    1926    -       Sep     lastSun 2:30    0       S
-Rule   Mont    1925    1926    -       May     Sun>=1  2:00    1:00    D
-Rule   Mont    1927    only    -       May      1      0:00    1:00    D
-Rule   Mont    1927    1932    -       Sep     Sun>=25 0:00    0       S
-Rule   Mont    1928    1931    -       Apr     Sun>=25 0:00    1:00    D
-Rule   Mont    1932    only    -       May      1      0:00    1:00    D
-Rule   Mont    1933    1940    -       Apr     Sun>=24 0:00    1:00    D
-Rule   Mont    1933    only    -       Oct      1      0:00    0       S
-Rule   Mont    1934    1939    -       Sep     Sun>=24 0:00    0       S
-Rule   Mont    1945    1948    -       Sep     lastSun 2:00    0       S
-Rule   Mont    1946    1986    -       Apr     lastSun 2:00    1:00    D
-Rule   Mont    1949    1950    -       Oct     lastSun 2:00    0       S
-Rule   Mont    1951    1956    -       Sep     lastSun 2:00    0       S
-Rule   Mont    1957    max     -       Oct     lastSun 2:00    0       S
-Rule   Mont    1987    max     -       Apr     Sun>=1  2:00    1:00    D
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone America/Montreal  -4:54:16 -      LMT     1884
-                       -5:00   Mont    E%sT
-
-# Rule NAME    FROM    TO      TYPE    IN      ON      AT      SAVE    LETTER/S
-Rule   Winn    1887    only    -       Jul     16      0:00    0       S
-Rule   Winn    1916    only    -       Apr     23      0:00    1:00    D
-Rule   Winn    1916    only    -       Sep     17      0:00    0       S
-Rule   Winn    1918    only    -       Apr     14      2:00    1:00    D
-Rule   Winn    1918    only    -       Oct     31      2:00    0       S
-Rule   Winn    1937    only    -       May     16      2:00    1:00    D
-Rule   Winn    1937    only    -       Sep     23      2:00    0       S
-Rule   Winn    1942    only    -       Feb      9      2:00    1:00    D
-Rule   Winn    1945    only    -       Sep     lastSun 2:00    0       S
-Rule   Winn    1946    only    -       May     12      2:00    1:00    D
-Rule   Winn    1946    only    -       Oct     13      2:00    0       S
-Rule   Winn    1947    1949    -       Apr     lastSun 2:00    1:00    D
-Rule   Winn    1947    1958    -       Sep     lastSun 2:00    0       S
-Rule   Winn    1948    only    -       May      1      2:00    1:00    D
-Rule   Winn    1948    1960    -       Apr     lastSun 2:00    1:00    D
-Rule   Winn    1959    only    -       Oct     lastSun 2:00    0       S
-Rule   Winn    1960    only    -       Sep     lastSun 2:00    0       S
-Rule   Winn    1963    only    -       Apr     lastSun 2:00    1:00    D
-Rule   Winn    1963    only    -       Sep     lastSun 2:00    0       S
-Rule   Winn    1966    1986    -       Apr     lastSun 2:00    1:00    D
-Rule   Winn    1966    max     -       Sep     lastSun 2:00    0       S
-Rule   Winn    1987    max     -       Apr     Sun>=1  2:00    1:00    D
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone America/Winnipeg  -6:28:36 -      LMT     1887 Jul 16
-                       -6:00   Winn    C%sT
-
-# Rule NAME    FROM    TO      TYPE    IN      ON      AT      SAVE    LETTER/S
-Rule   Regina  1905    only    -       Sep      1      0:00    0       S
-Rule   Regina  1918    only    -       Apr     14      2:00    1:00    D
-Rule   Regina  1918    only    -       Oct     31      2:00    0       S
-Rule   Regina  1930    1934    -       May     Sun>=1  0:00    1:00    D
-Rule   Regina  1930    1934    -       Oct     Sun>=1  0:00    0       S
-Rule   Regina  1937    1941    -       Apr     Sun>=8  0:00    1:00    D
-Rule   Regina  1937    only    -       Oct     Sun>=8  0:00    0       S
-Rule   Regina  1938    only    -       Oct     Sun>=1  0:00    0       S
-Rule   Regina  1939    1941    -       Oct     Sun>=8  0:00    0       S
-Rule   Regina  1942    only    -       Feb      9      2:00    1:00    D
-Rule   Regina  1945    only    -       Sep     lastSun 2:00    0       S
-Rule   Regina  1946    only    -       Apr     14      2:00    1:00    D
-Rule   Regina  1946    only    -       Oct     13      2:00    0       S
-Rule   Regina  1947    1960    -       Apr     lastSun 2:00    1:00    D
-Rule   Regina  1947    1959    -       Sep     lastSun 2:00    0       S
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   America/Regina  -6:58:36 -      LMT     1905 Sep
-                       -7:00   Regina  M%sT    1966 Apr 15
-                       -6:00   -       CST
-
-# Rule NAME    FROM    TO      TYPE    IN      ON      AT      SAVE    LETTER/S
-Rule   Edm     1906    only    -       Sep      1      0:00    0       S
-Rule   Edm     1918    1919    -       Apr     Sun>=8  2:00    1:00    D
-Rule   Edm     1918    only    -       Oct     31      2:00    0       S
-Rule   Edm     1919    only    -       May     27      2:00    0       S
-Rule   Edm     1920    1923    -       Apr     lastSun 2:00    1:00    D
-Rule   Edm     1920    only    -       Oct     lastSun 2:00    0       S
-Rule   Edm     1921    1923    -       Sep     lastSun 2:00    0       S
-Rule   Edm     1942    only    -       Feb      9      2:00    1:00    D
-Rule   Edm     1945    only    -       Sep     lastSun 2:00    0       S
-Rule   Edm     1947    only    -       Apr     lastSun 2:00    1:00    D
-Rule   Edm     1947    only    -       Sep     lastSun 2:00    0       S
-Rule   Edm     1967    only    -       Apr     lastSun 2:00    1:00    D
-Rule   Edm     1967    only    -       Oct     lastSun 2:00    0       S
-Rule   Edm     1969    only    -       Apr     lastSun 2:00    1:00    D
-Rule   Edm     1969    only    -       Oct     lastSun 2:00    0       S
-Rule   Edm     1972    1986    -       Apr     lastSun 2:00    1:00    D
-Rule   Edm     1972    max     -       Oct     lastSun 2:00    0       S
-Rule   Edm     1987    max     -       Apr     Sun>=1  2:00    1:00    D
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone America/Edmonton  -7:33:52 -      LMT     1906 Sep
-                       -7:00   Edm     M%sT
-
-# Rule NAME    FROM    TO      TYPE    IN      ON      AT      SAVE    LETTER/S
-Rule   Vanc    1884    only    -       Jan      1      0:00    0       S
-Rule   Vanc    1918    only    -       Apr     14      2:00    1:00    D
-Rule   Vanc    1918    only    -       Oct     31      2:00    0       S
-Rule   Vanc    1942    only    -       Feb      9      2:00    1:00    D
-Rule   Vanc    1945    only    -       Sep     30      2:00    0       S
-Rule   Vanc    1946    1986    -       Apr     lastSun 2:00    1:00    D
-Rule   Vanc    1946    only    -       Oct     13      2:00    0       S
-Rule   Vanc    1947    1961    -       Sep     lastSun 2:00    0       S
-Rule   Vanc    1962    max     -       Oct     lastSun 2:00    0       S
-Rule   Vanc    1987    max     -       Apr     Sun>=1  2:00    1:00    D
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone America/Vancouver -8:12:28 -      LMT     1884
-                       -8:00   Vanc    P%sT
-
-# Rule NAME    FROM    TO      TYPE    IN      ON      AT      SAVE    LETTER/S
-Rule   Yukon   1900    only    -       Jan      1      0:00    0       S
-Rule   Yukon   1918    only    -       Apr     14      2:00    1:00    D
-Rule   Yukon   1918    only    -       Oct     27      2:00    0       S
-Rule   Yukon   1919    only    -       May     25      2:00    1:00    D
-Rule   Yukon   1919    only    -       Nov      1      0:00    0       S
-Rule   Yukon   1942    only    -       Feb      9      2:00    1:00    D
-Rule   Yukon   1965    only    -       Apr     25      0:00    1:00    D
-Rule   Yukon   1965    only    -       Oct     31      2:00    0       S
-Rule   Yukon   1980    1986    -       Apr     lastSun 2:00    1:00    D
-Rule   Yukon   1980    max     -       Oct     lastSun 2:00    0       S
-Rule   Yukon   1987    max     -       Apr     Sun>=1  2:00    1:00    D
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone America/Whitehorse        -9:00:12 -      LMT     1900 Aug 20
-                       -9:00   Yukon   Y%sT    1966 Jul
-                       -8:00   Yukon   P%sT
-# Parts of Yukon (e.g. Dawson) didn't switch to -8:00 until 1973 Oct 28.
-
-###############################################################################
-
-# Mexico
-
-# From Guy Harris:
-# Rules are from the Official Airline Guide, Worldwide Edition, for 1987.
-# Rules prior to 1987 are unknown.
-# The comments in the OAG say "Only Ensenada, Mexicale, San Felipe and Tijuana
-# observe DST."  This is presumably Baja California Norte, above 28th parallel,
-# as listed there; Mexico/BajaSur is for "Baja California Sur and N. Pacific
-# Coast (States of Sinaloa and Sonora)."
-
-# From Bob Devine (January 28, 1988):
-# The Federal District (where Mexico City is) has observed [DST] several
-# times but not recently.
-#
-# I don't where to drawn the line in the North Baja area.  28th latitude
-# sounds good -- but it may be higher (how far [d]o radio stations from
-# San Diego affect culture?).
-#
-# The dates of DST probably go back to 1981.  The rules are the same as
-# US's.  This is going to be a headache for US presidential electi[o]n years!
-
-# From Arthur David Olson (February 13, 1988)
-# Since the 1981 starting date is only "probable," we'll keep the 1987
-# starting date below.
-
-# From U. S. Naval Observatory (January 19, 1989):
-# MEXICO BAJA CAL N   7 H  BEHIND UTC    BAJA CALIFORNIA SUR AND
-# MEXICO BAJA CAL N                      N. PACIFIC COAST (STATES
-# MEXICO BAJA CAL N                      OF SINALOA AND SONORA)
-# MEXICO BAJA CAL N   8 H  BEHIND UTC    ABOVE 28TH PARALLAL APR 3
-# MEXICO BAJA CAL N                      - OCT 29
-# MEXICO BAJA CAL N   7 H  BEHIND UTC    ABOVE 28TH PARALLAL APR 3
-# MEXICO BAJA CAL N                      - 0CT 29
-# MEXICO              6 H  BEHIND UTC    STATES OF DURANGO,
-# MEXICO                                 COAHUILA, NUEVO LEON,
-# MEXICO                                 TAMAULIPAS
-# MEXICO              5 H  BEHIND UTC    STATES OF DURANGO,
-# MEXICO                                 COAHUILA, NUEVO LEON,
-# MEXICO                                 TAMAULIPAS  APR 3 - OCT 29
-# MEXICO              6 H  BEHIND UTC    GENERAL MEXICO, STATES OF
-# MEXICO                                 CAMPECHE, QUINTANA ROO AND
-# MEXICO                                 YUCATAN
-
-# From Arthur David Olson (January 21, 1989):
-# April 3 fell on a Sunday in 1988; October 29 fell on a Sunday in 1989.  Ahem.
-# USNO claims there should be four Mexican zones rather than three:
-# a zone that's GMT-8 with DST; a zone that's always GMT-7;
-# a zone that's GMT-6 with DST; and a zone that's always GMT-6.
-
-# From Paul Eggert <eggert@twinsun.com> (November 18, 1993):
-# Shanks also says there are four zones, but disagrees about the fourth.
-# Instead of GMT-6 with DST, he says there's GMT-8 without DST.
-
-# From Shanks (1991):
-# Rule NAME    FROM    TO      TYPE    IN      ON      AT      SAVE    LETTER/S
-Rule   Mexico  1922    only    -       Jan     1       0:00    0       S
-Rule   Mexico  1939    only    -       Feb     5       0:00    1:00    D
-Rule   Mexico  1939    only    -       Jun     25      0:00    0       S
-Rule   Mexico  1940    only    -       Dec     9       0:00    1:00    D
-Rule   Mexico  1941    only    -       Apr     1       0:00    0       S
-Rule   Mexico  1943    only    -       Dec     16      0:00    1:00    D
-Rule   Mexico  1944    only    -       May     1       0:00    0       S
-Rule   Mexico  1950    only    -       Feb     12      0:00    1:00    D
-Rule   Mexico  1950    only    -       Jul     30      0:00    0       S
-Rule   BajaN   1950    1966    -       Apr     lastSun 2:00    1:00    D
-Rule   BajaN   1950    1961    -       Sep     lastSun 2:00    0       S
-Rule   BajaN   1961    1966    -       Oct     lastSun 2:00    0       S
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone America/Mexico_City -6:36:36 -    LMT     1922 Jan  1  0:23:24
-                       -7:00   -       MST     1927 Jun 10 23:00
-                       -6:00   -       CST     1930 Nov 15
-                       -7:00   -       MST     1931 May  1 23:00
-                       -6:00   -       CST     1931 Oct
-                       -7:00   -       MST     1932 Mar 30 23:00
-                       -6:00   Mexico  C%sT
-Zone America/Mazatlan  -7:05:40 -      LMT     1921 Dec 31 23:54:20
-                       -7:00   -       MST     1927 Jun 10 23:00
-                       -6:00   -       CST     1930 Nov 15
-                       -7:00   -       MST     1931 May  1 23:00
-                       -6:00   -       CST     1931 Oct
-                       -7:00   -       MST     1932 Mar 30 23:00
-                       -6:00   -       CST     1942 Apr
-                       -7:00   -       MST     1949 Jan 14
-                       -8:00   -       PST     1970
-                       -7:00   -       MST
-Zone America/Tijuana   -7:48:04 -      LMT     1922 Jan  1  0:11:56
-                       -8:00   -       PST     1927 Jun 10 23:00
-                       -7:00   -       MST     1930 Nov 16
-                       -8:00   -       PST     1942 Apr
-                       -7:00   -       MST     1949 Jan 14
-                       -8:00   BajaN   P%sT    1967 Apr lastSun 2:00
-                       -8:00   US      P%sT
-Zone America/Ensenada  -7:46:28 -      LMT     1922 Jan  1  0:13:32
-                       -8:00   -       PST     1927 Jun 10 23:00
-                       -7:00   -       MST     1930 Nov 16
-                       -8:00   -       PST     1942 Apr
-                       -7:00   -       MST     1949 Jan 14
-                       -8:00   -       PST
-#
-# Revillagigedo Is
-# no information
-
-###############################################################################
-
-# Anguilla
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone America/Anguilla  -4:12:16 -      LMT     1912 Mar 2
-                       -4:00   -       AST
-
-# Antigua and Barbuda
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   America/Antigua -4:07:12 -      LMT     1912 Mar 2
-                       -5:00   -       EST     1951
-                       -4:00   -       AST
-
-# Bahamas
-# Rule NAME    FROM    TO      TYPE    IN      ON      AT      SAVE    LETTER/S
-Rule   Bahamas 1912    only    -       Mar     2       0:00    0       S
-Rule   Bahamas 1964    max     -       Oct     lastSun 2:00    0       S
-Rule   Bahamas 1964    1986    -       Apr     lastSun 2:00    1:00    D
-Rule   Bahamas 1987    max     -       Apr     Sun>=1  2:00    1:00    D
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   America/Nassau  -5:09:24 -      LMT     1912 Mar 2
-                       -5:00   Bahamas E%sT
-
-# Barbados
-# Rule NAME    FROM    TO      TYPE    IN      ON      AT      SAVE    LETTER/S
-Rule   Barb    1932    only    -       Jan     1       0:00    0       S
-Rule   Barb    1977    only    -       Jun     12      2:00    1:00    D
-Rule   Barb    1977    1978    -       Oct     Sun>=1  2:00    0       S
-Rule   Barb    1978    1980    -       Apr     Sun>=15 2:00    1:00    D
-Rule   Barb    1979    only    -       Sep     30      2:00    0       S
-Rule   Barb    1980    only    -       Sep     25      2:00    0       S
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone America/Barbados  -3:58:28 -      LMT     1924            # Bridgetown
-                       -3:58   -       BMT     1932      # Bridgetown Mean Time
-                       -4:00   Barb    A%sT
-
-# Belize
-# Whitman entirely disagrees with Shanks; go with Shanks.
-# Rule NAME    FROM    TO      TYPE    IN      ON      AT      SAVE    LETTER/S
-Rule   Belize  1912    only    -       Apr      1      0:00    0       S
-Rule   Belize  1918    1942    -       Oct     Sun>=2  0:00    0:30    HD
-Rule   Belize  1919    1943    -       Feb     Sun>=9  0:00    0       S
-Rule   Belize  1973    only    -       Dec      5      0:00    1:00    D
-Rule   Belize  1974    only    -       Feb      9      0:00    0       S
-Rule   Belize  1982    only    -       Dec     18      0:00    1:00    D
-Rule   Belize  1983    only    -       Feb     12      0:00    0       S
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   America/Belize  -5:52:48 -      LMT     1912 Apr
-                       -6:00   Belize  C%sT
-
-# Bermuda
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone Atlantic/Bermuda  -4:19:04 -      LMT     1930 Jan  1 2:00    # Hamilton
-                       -4:00   -       AST     1974 Apr 28 2:00
-                       -4:00   Bahamas A%sT
-
-# Cayman Is
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   America/Cayman  -5:25:32 -      LMT     1890            # Georgetown
-                       -5:07   -       KMT     1912 Feb    # Kingston Mean Time
-                       -5:00   -       EST
-
-# Clipperton
-# no information
-
-# Costa Rica
-# Shanks gives some very odd dates for 1991, and stops there.
-# For now, we won't guess further.
-# Rule NAME    FROM    TO      TYPE    IN      ON      AT      SAVE    LETTER/S
-Rule   CR      1921    only    -       Jan     15      0:00    0       S
-Rule   CR      1979    1980    -       Feb     lastSun 0:00    1:00    D
-Rule   CR      1979    1980    -       Jun     Sun>=1  0:00    0       S
-Rule   CR      1991    only    -       Jan     19      0:00    1:00    D
-Rule   CR      1991    only    -       Jul     1       0:00    0       S
-# There are too many San Joses elsewhere, so we'll use `Costa Rica'.
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone America/Costa_Rica        -5:36:20 -      LMT     1890            # San Jose
-                       -5:36   -       SJMT    1921 Jan 15 # San Jose Mean Time
-                       -6:00   CR      C%sT
-# Coco
-# no information; probably like America/Costa_Rica
-
-# Cuba
-
-# From Bob Devine (January 28, 1988):
-# . . .DST is from 2nd Sunday in May to 2nd Sunday in October since 1981.
-# Change at midnight.  In 1979 & 1980, started at 3rd Sunday in March
-# (I think).
-
-# From U. S. Naval Observatory (January 19, 1989):
-# CUBA                5 H  BEHIND UTC
-# CUBA                4 H  BEHIND UTC    MAR 20 - OCT 8
-
-# From Shanks (1991):
-# Rule NAME    FROM    TO      TYPE    IN      ON      AT      SAVE    LETTER/S
-Rule   Cuba    1925    only    -       Jul     19      12:00   0       S
-Rule   Cuba    1928    only    -       Jun     10      0:00    1:00    D
-Rule   Cuba    1928    only    -       Oct     10      0:00    0       S
-Rule   Cuba    1940    1942    -       Jun     Sun>=1  0:00    1:00    D
-Rule   Cuba    1940    1942    -       Sep     Sun>=1  0:00    0       S
-Rule   Cuba    1945    1946    -       Jun     Sun>=1  0:00    1:00    D
-Rule   Cuba    1945    1946    -       Sep     Sun>=1  0:00    0       S
-Rule   Cuba    1965    only    -       Jun     1       0:00    1:00    D
-Rule   Cuba    1965    only    -       Sep     30      0:00    0       S
-Rule   Cuba    1966    only    -       May     29      0:00    1:00    D
-Rule   Cuba    1966    only    -       Oct     2       0:00    0       S
-Rule   Cuba    1967    only    -       Apr     8       0:00    1:00    D
-Rule   Cuba    1967    1968    -       Sep     Sun>=8  0:00    0       S
-Rule   Cuba    1968    only    -       Apr     14      0:00    1:00    D
-Rule   Cuba    1969    1977    -       Apr     lastSun 0:00    1:00    D
-Rule   Cuba    1969    1971    -       Oct     lastSun 0:00    0       S
-Rule   Cuba    1972    1974    -       Oct     8       0:00    0       S
-Rule   Cuba    1975    1977    -       Oct     lastSun 0:00    0       S
-Rule   Cuba    1978    only    -       May     7       0:00    1:00    D
-Rule   Cuba    1978    1980    -       Oct     Sun>=8  0:00    0       S
-Rule   Cuba    1979    1980    -       Mar     Sun>=15 0:00    1:00    D
-Rule   Cuba    1981    1985    -       May     Sun>=5  0:00    1:00    D
-Rule   Cuba    1981    max     -       Oct     Sun>=8  0:00    0       S
-Rule   Cuba    1986    1989    -       Mar     Sun>=14 0:00    1:00    D
-Rule   Cuba    1990    only    -       Apr     1       0:00    1:00    D
-Rule   Cuba    1991    max     -       Mar     Sun>=14 0:00    1:00    D
-
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   America/Havana  -5:29:28 -      LMT     1890
-                       -5:30   -       HMT     1925 Jul 19 12:00 # Havana MT
-                       -5:00   Cuba    C%sT
-
-# Dominica
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone America/Dominica  -4:05:36 -      LMT     1911 Jul 1 0:01         # Roseau
-                       -4:00   -       AST
-
-# Dominican Republic
-# Rule NAME    FROM    TO      TYPE    IN      ON      AT      SAVE    LETTER/S
-Rule   DR      1933    only    -       Apr     1       12:00   0       S
-Rule   DR      1966    only    -       Oct     30      0:00    1:00    D
-Rule   DR      1967    only    -       Feb     28      0:00    0       S
-Rule   DR      1969    1973    -       Oct     lastSun 0:00    0:30    HD
-Rule   DR      1970    only    -       Feb     21      0:00    0       S
-Rule   DR      1971    only    -       Jan     20      0:00    0       S
-Rule   DR      1972    1974    -       Jan     21      0:00    0       S
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone America/Santo_Domingo -4:39:36 -  LMT     1890
-                       -4:40   -       SDMT    1933 Apr  1 12:00 # S. Dom. MT
-                       -5:00   DR      E%sT    1974 Oct 27
-                       -4:00   -       AST
-
-# El Salvador
-# Rule NAME    FROM    TO      TYPE    IN      ON      AT      SAVE    LETTER/S
-Rule   Salv    1921    only    -       Jan     1       0:00    0       S
-Rule   Salv    1987    1988    -       May     Sun>=1  0:00    1:00    D
-Rule   Salv    1987    1988    -       Sep     lastSun 0:00    0       S
-# There are too many San Salvadors elsewhere, so we'll use `El Salvador'.
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone America/El_Salvador -5:56:48 -    LMT     1921            # San Salvador
-                       -6:00   Salv    C%sT
-
-# Grenada
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   America/Grenada -4:07:00 -      LMT     1911 Jul
-                       -4:00   -       AST
-
-# Guadeloupe
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone America/Guadeloupe        -4:06:08 -      LMT     1911 Jun 8      # Pointe a Pitre
-                       -4:00   -       AST
-
-# Guatemala
-# Rule NAME    FROM    TO      TYPE    IN      ON      AT      SAVE    LETTER/S
-Rule   Guat    1918    only    -       Oct     5       0:00    0       S
-Rule   Guat    1973    only    -       Nov     25      0:00    1:00    D
-Rule   Guat    1974    only    -       Feb     24      0:00    0       S
-Rule   Guat    1983    only    -       May     21      0:00    1:00    D
-Rule   Guat    1983    only    -       Sep     22      0:00    0       S
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone America/Guatemala -6:02:04 -      LMT     1918 Oct 5
-                       -6:00   Guat    C%sT
-
-# Haiti
-# Rule NAME    FROM    TO      TYPE    IN      ON      AT      SAVE    LETTER/S
-Rule   Haiti   1917    only    -       Jan     24      12:00   0       S
-Rule   Haiti   1983    only    -       May     8       0:00    1:00    D
-Rule   Haiti   1984    1987    -       Apr     lastSun 0:00    1:00    D
-Rule   Haiti   1983    1987    -       Oct     lastSun 0:00    0       S
-Rule   Haiti   1988    max     -       Apr     Sun>=1  2:00    1:00    D
-Rule   Haiti   1988    max     -       Oct     lastSun 2:00    0       S
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone America/Port-au-Prince -4:49:20 - LMT     1890
-                       -4:49   -       PPMT    1917 Jan 24 12:00 # P-a-P MT
-                       -5:00   Haiti   E%sT
-
-# Honduras
-# Shanks says 1921 Jan 1; go with Whitman's more precise Apr 1.
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone America/Tegucigalpa -5:48:52 -    LMT     1921 Apr
-                       -6:00   Salv    C%sT
-
-# Jamaica
-
-# From Bob Devine (January 28, 1988):
-# Follows US rules.
-
-# From U. S. Naval Observatory (January 19, 1989):
-# JAMAICA             5 H  BEHIND UTC
-
-# From Shanks (1991):
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   America/Jamaica -5:07:12 -      LMT     1890            # Kingston
-                       -5:07   -       KMT     1912 Feb    # Kingston Mean Time
-                       -5:00   -       EST     1974 Jan 6 2:00
-                       -5:00   US      E%sT
-
-# Martinique
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone America/Martinique        -4:04:20 -      LMT     1890            # Fort-de-France
-                       -4:04   -       FFMT    1911 May     # Fort-de-France MT
-                       -4:00   -       AST     1980 Apr  6
-                       -4:00   1:00    ADT     1980 Sep 28
-                       -4:00   -       AST
-
-# Montserrat
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone America/Montserrat        -4:08:52 -      LMT     1911 Jul 1 0:01   # Plymouth
-                       -4:00   -       AST
-
-# Nicaragua
-# Rule NAME    FROM    TO      TYPE    IN      ON      AT      SAVE    LETTER/S
-Rule   Nic     1975    only    -       Feb     16      0:00    0       S
-Rule   Nic     1979    1980    -       Mar     Sun>=16 0:00    1:00    D
-Rule   Nic     1979    1980    -       Jun     Mon>=23 0:00    0       S
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   America/Managua -5:45:08 -      LMT     1890
-                       -5:45   -       MMT     1934 Jun 23  # Managua Mean Time
-                       -6:00   -       CST     1973 May
-                       -5:00   -       EST     1975 Feb 16
-                       -6:00   Nic     C%sT
-
-# Panama
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   America/Panama  -5:18:08 -      LMT     1890
-                       -5:20   -       PMT     1908 Apr 22   # Panama Mean Time
-                       -5:00   -       EST
-
-# Puerto Rico
-# There are too many San Juans elsewhere, so we'll use `Puerto_Rico'.
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone America/Puerto_Rico -4:24:28 -    LMT     1899 Mar 28 12:00    # San Juan
-                       -4:00   -       AST     1942 May  3
-                       -4:00   1:00    ADT     1945 Sep 30  2:00
-                       -4:00   -       AST
-
-# St Kitts-Nevis
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone America/St_Kitts  -4:10:52 -      LMT     1912 Mar 2      # Basseterre
-                       -4:00   -       AST
-
-# St Lucia
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone America/St_Lucia  -4:04:00 -      LMT     1890            # Castries
-                       -4:04   -       CMT     1912        # Castries Mean Time
-                       -4:00   -       AST
-
-# St Pierre and Miquelon
-# There are too many St Pierres elsewhere, so we'll use `Miquelon'.
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone America/Miquelon  -3:44:40 -      LMT     1911 May 15     # St Pierre
-                       -4:00   -       AST     1980 May
-                       -3:00   Mont    SP%sT
-
-# St Vincent and the Grenadines
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone America/St_Vincent        -4:04:56 -      LMT     1890            # Kingstown
-                       -4:05   -       KMT     1912       # Kingstown Mean Time
-                       -4:00   -       AST
-
-# Turks and Caicos
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone America/Grand_Turk        -4:44:32 -      LMT     1890
-                       -5:07   -       KMT     1912 Feb    # Kingston Mean Time
-                       -5:00   -       EST     1979 Apr 29 2:00
-                       -5:00   US      E%sT
-
-# Virgin Is (British and US)
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   America/Virgin  -4:19:44 -      LMT     1911 Jul    # Charlotte Amalie
-                       -4:00   -       AST
diff --git a/time/optind.c b/time/optind.c
deleted file mode 100644 (file)
index 70c1db2..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-#ifndef lint
-#ifndef NOID
-static char    elsieid[] = "@(#)optind.c       7.3";
-#endif /* !defined NOID */
-#endif /* !defined lint */
-
-int    opterr = 1,             /* if error message should be printed */
-       optind = 1;             /* index into parent argv vector */
-char   *optarg;                /* argument associated with option */
-int     optopt;
diff --git a/time/pacificnew b/time/pacificnew
deleted file mode 100644 (file)
index cd1477c..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-# @(#)pacificnew       7.6
-
-# From Arthur David Olson (April 5, 1989):
-# On April 5, 1989, the U. S. House of Representatives passed (238-154) a bill
-# establishing "Pacific Presidential Election Time"; it was not acted on
-# by the Senate or signed into law by the President.
-# You might want to change the "PE" (Presidential Election) below to
-# "Q" (Quadrennial) to maintain three-character zone abbreviations.
-# If you're really conservative, you might want to change it to "D".
-# Avoid "L" (Leap Year), which won't be true in 2100.
-
-# If Presidential Election Time is ever established, replace "XXXX" below
-# with the year the law takes effect and uncomment the "##" lines.
-
-# Rule NAME    FROM    TO      TYPE    IN      ON      AT      SAVE    LETTER/S
-## Rule        Twilite XXXX    max     -       Apr     Sun>=1  2:00    1:00    D
-## Rule        Twilite XXXX    max     uspres  Oct     lastSun 2:00    1:00    PE
-## Rule        Twilite XXXX    max     uspres  Nov     Sun>=7  2:00    0       S
-## Rule        Twilite XXXX    max     nonpres Oct     lastSun 2:00    0       S
-
-# Zone NAME            GMTOFF  RULES/SAVE      FORMAT  [UNTIL]
-## Zone        US/Pacific-PET  -8:00   US              P%sT    XXXX
-##                     -8:00   Twilite         P%sT
-
-# For now...
-Link   America/Los_Angeles     US/Pacific-New  ##
diff --git a/time/private.h b/time/private.h
deleted file mode 100644 (file)
index 8852b83..0000000
+++ /dev/null
@@ -1,210 +0,0 @@
-#ifndef PRIVATE_H
-
-#define PRIVATE_H
-
-/*
-** This header is for use ONLY with the time conversion code.
-** There is no guarantee that it will remain unchanged,
-** or that it will remain at all.
-** Do NOT copy it to any system include directory.
-** Thank you!
-*/
-
-/*
-** ID
-*/
-
-#ifndef lint
-#ifndef NOID
-static char    privatehid[] = "@(#)private.h   7.10";
-#endif /* !defined NOID */
-#endif /* !defined lint */
-
-/*
-** const
-*/
-
-#ifndef const
-#ifndef __STDC__
-#define const
-#endif /* !defined __STDC__ */
-#endif /* !defined const */
-
-/*
-** void
-*/
-
-#ifndef void
-#ifndef __STDC__
-#ifndef vax
-#ifndef sun
-#define void   char
-#endif /* !defined sun */
-#endif /* !defined vax */
-#endif /* !defined __STDC__ */
-#endif /* !defined void */
-
-/*
-** INITIALIZE
-*/
-
-#ifndef GNUC_or_lint
-#ifdef lint
-#define GNUC_or_lint
-#endif /* defined lint */
-#ifdef __GNUC__
-#define GNUC_or_lint
-#endif /* defined __GNUC__ */
-#endif /* !defined GNUC_or_lint */
-
-#ifndef INITIALIZE
-#ifdef GNUC_or_lint
-#define INITIALIZE(x)  ((x) = 0)
-#endif /* defined GNUC_or_lint */
-#ifndef GNUC_or_lint
-#define INITIALIZE(x)
-#endif /* !defined GNUC_or_lint */
-#endif /* !defined INITIALIZE */
-
-/*
-** P((args))
-*/
-
-#ifndef P
-#ifdef __STDC__
-#define P(x)   x
-#endif /* defined __STDC__ */
-#ifndef __STDC__
-#define P(x)   ()
-#endif /* !defined __STDC__ */
-#endif /* !defined P */
-
-/*
-** genericptr_T
-*/
-
-#ifdef __STDC__
-typedef void *         genericptr_T;
-#endif /* defined __STDC__ */
-#ifndef __STDC__
-typedef char *         genericptr_T;
-#endif /* !defined __STDC__ */
-
-#include "sys/types.h" /* for time_t */
-#include "stdio.h"
-#include "ctype.h"
-#include "errno.h"
-#include "string.h"
-#include "limits.h"    /* for CHAR_BIT */
-#ifndef _TIME_
-#include "time.h"
-#endif /* !defined _TIME_ */
-
-#ifndef remove
-extern int     unlink P((const char * filename));
-#define remove unlink
-#endif /* !defined remove */
-
-#ifndef FILENAME_MAX
-
-#ifndef MAXPATHLEN
-#ifdef unix
-#include "sys/param.h"
-#endif /* defined unix */
-#endif /* !defined MAXPATHLEN */
-
-#ifdef MAXPATHLEN
-#define FILENAME_MAX   MAXPATHLEN
-#endif /* defined MAXPATHLEN */
-#ifndef MAXPATHLEN
-#define FILENAME_MAX   1024            /* Pure guesswork */
-#endif /* !defined MAXPATHLEN */
-
-#endif /* !defined FILENAME_MAX */
-
-#ifndef EXIT_SUCCESS
-#define EXIT_SUCCESS   0
-#endif /* !defined EXIT_SUCCESS */
-
-#ifndef EXIT_FAILURE
-#define EXIT_FAILURE   1
-#endif /* !defined EXIT_FAILURE */
-
-#ifdef __STDC__
-
-#define alloc_size_T   size_t
-#define qsort_size_T   size_t
-#define fwrite_size_T  size_t
-
-#endif /* defined __STDC__ */
-#ifndef __STDC__
-
-#ifndef alloc_size_T
-#define alloc_size_T   unsigned
-#endif /* !defined alloc_size_T */
-
-#ifndef qsort_size_T
-#ifdef USG
-#define qsort_size_T   unsigned
-#endif /* defined USG */
-#ifndef USG
-#define qsort_size_T   int
-#endif /* !defined USG */
-#endif /* !defined qsort_size_T */
-
-#ifndef fwrite_size_T
-#define fwrite_size_T  int
-#endif /* !defined fwrite_size_T */
-
-#ifndef USG
-extern char *          sprintf P((char * buf, const char * format, ...));
-#endif /* !defined USG */
-
-#endif /* !defined __STDC__ */
-
-/*
-** Ensure that these are declared--redundantly declaring them shouldn't hurt.
-*/
-
-extern char *          getenv P((const char * name));
-extern genericptr_T    malloc P((alloc_size_T size));
-extern genericptr_T    calloc P((alloc_size_T nelem, alloc_size_T elsize));
-extern genericptr_T    realloc P((genericptr_T oldptr, alloc_size_T newsize));
-
-#ifdef USG
-extern void            exit P((int s));
-extern void            qsort P((genericptr_T base, qsort_size_T nelem,
-                               qsort_size_T elsize, int (*comp)()));
-extern void            perror P((const char * string));
-extern void            free P((char * buf));
-#endif /* defined USG */
-
-#ifndef TRUE
-#define TRUE   1
-#endif /* !defined TRUE */
-
-#ifndef FALSE
-#define FALSE  0
-#endif /* !defined FALSE */
-
-#ifndef INT_STRLEN_MAXIMUM
-/*
-** 302 / 1000 is log10(2.0) rounded up.
-** Subtract one for the sign bit;
-** add one for integer division truncation;
-** add one more for a minus sign.
-*/
-#define INT_STRLEN_MAXIMUM(type) \
-       ((sizeof(type) * CHAR_BIT - 1) * 302 / 1000 + 2)
-#endif /* !defined INT_STRLEN_MAXIMUM */
-
-#ifndef LOCALE_HOME
-#define LOCALE_HOME    "/usr/lib/locale"
-#endif /* !defined LOCALE_HOME */
-
-/*
-** UNIX was a registered trademark of UNIX System Laboratories in 1993.
-** VAX is a trademark of Digital Equipment Corporation.
-*/
-
-#endif /* !defined PRIVATE_H */
diff --git a/time/scheck.c b/time/scheck.c
deleted file mode 100644 (file)
index 404c6b2..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-#ifndef lint
-#ifndef NOID
-static char    elsieid[] = "@(#)scheck.c       8.12";
-#endif /* !defined lint */
-#endif /* !defined NOID */
-
-/*LINTLIBRARY*/
-
-#include "private.h"
-
-extern char *  imalloc P((int n));
-extern void    ifree P((char * p));
-
-char *
-scheck(string, format)
-const char * const     string;
-char * const           format;
-{
-       register char *         fbuf;
-       register const char *   fp;
-       register char *         tp;
-       register int            c;
-       register char *         result;
-       char                    dummy;
-       static char             nada;
-
-       result = &nada;
-       if (string == NULL || format == NULL)
-               return result;
-       fbuf = imalloc((int) (2 * strlen(format) + 4));
-       if (fbuf == NULL)
-               return result;
-       fp = format;
-       tp = fbuf;
-       while ((*tp++ = c = *fp++) != '\0') {
-               if (c != '%')
-                       continue;
-               if (*fp == '%') {
-                       *tp++ = *fp++;
-                       continue;
-               }
-               *tp++ = '*';
-               if (*fp == '*')
-                       ++fp;
-               while (isascii(*fp) && isdigit(*fp))
-                       *tp++ = *fp++;
-               if (*fp == 'l' || *fp == 'h')
-                       *tp++ = *fp++;
-               else if (*fp == '[')
-                       do *tp++ = *fp++;
-                               while (*fp != '\0' && *fp != ']');
-               if ((*tp++ = *fp++) == '\0')
-                       break;
-       }
-       *(tp - 1) = '%';
-       *tp++ = 'c';
-       *tp = '\0';
-       if (sscanf(string, fbuf, &dummy) != 1)
-               result = (char *) format;
-       ifree(fbuf);
-       return result;
-}
diff --git a/time/solar87 b/time/solar87
deleted file mode 100644 (file)
index a4e2f39..0000000
+++ /dev/null
@@ -1,386 +0,0 @@
-# @(#)solar87  7.2
-
-# So much for footnotes about Saudi Arabia.
-# Apparent noon times below are for Riyadh; your mileage will vary.
-# Times were computed using formulas in the U.S. Naval Observatory's
-# Almanac for Computers 1987; the formulas "will give EqT to an accuracy of
-# [plus or minus two] seconds during the current year."
-#
-# Rounding to the nearest five seconds results in fewer than
-# 256 different "time types"--a limit that's faced because time types are
-# stored on disk as unsigned chars.
-
-# Rule NAME    FROM    TO      TYPE    IN      ON      AT      SAVE    LETTER/S
-Rule   sol87   1987    only    -       Jan     1       12:03:20s -0:03:20 -
-Rule   sol87   1987    only    -       Jan     2       12:03:50s -0:03:50 -
-Rule   sol87   1987    only    -       Jan     3       12:04:15s -0:04:15 -
-Rule   sol87   1987    only    -       Jan     4       12:04:45s -0:04:45 -
-Rule   sol87   1987    only    -       Jan     5       12:05:10s -0:05:10 -
-Rule   sol87   1987    only    -       Jan     6       12:05:40s -0:05:40 -
-Rule   sol87   1987    only    -       Jan     7       12:06:05s -0:06:05 -
-Rule   sol87   1987    only    -       Jan     8       12:06:30s -0:06:30 -
-Rule   sol87   1987    only    -       Jan     9       12:06:55s -0:06:55 -
-Rule   sol87   1987    only    -       Jan     10      12:07:20s -0:07:20 -
-Rule   sol87   1987    only    -       Jan     11      12:07:45s -0:07:45 -
-Rule   sol87   1987    only    -       Jan     12      12:08:10s -0:08:10 -
-Rule   sol87   1987    only    -       Jan     13      12:08:30s -0:08:30 -
-Rule   sol87   1987    only    -       Jan     14      12:08:55s -0:08:55 -
-Rule   sol87   1987    only    -       Jan     15      12:09:15s -0:09:15 -
-Rule   sol87   1987    only    -       Jan     16      12:09:35s -0:09:35 -
-Rule   sol87   1987    only    -       Jan     17      12:09:55s -0:09:55 -
-Rule   sol87   1987    only    -       Jan     18      12:10:15s -0:10:15 -
-Rule   sol87   1987    only    -       Jan     19      12:10:35s -0:10:35 -
-Rule   sol87   1987    only    -       Jan     20      12:10:55s -0:10:55 -
-Rule   sol87   1987    only    -       Jan     21      12:11:10s -0:11:10 -
-Rule   sol87   1987    only    -       Jan     22      12:11:30s -0:11:30 -
-Rule   sol87   1987    only    -       Jan     23      12:11:45s -0:11:45 -
-Rule   sol87   1987    only    -       Jan     24      12:12:00s -0:12:00 -
-Rule   sol87   1987    only    -       Jan     25      12:12:15s -0:12:15 -
-Rule   sol87   1987    only    -       Jan     26      12:12:30s -0:12:30 -
-Rule   sol87   1987    only    -       Jan     27      12:12:40s -0:12:40 -
-Rule   sol87   1987    only    -       Jan     28      12:12:55s -0:12:55 -
-Rule   sol87   1987    only    -       Jan     29      12:13:05s -0:13:05 -
-Rule   sol87   1987    only    -       Jan     30      12:13:15s -0:13:15 -
-Rule   sol87   1987    only    -       Jan     31      12:13:25s -0:13:25 -
-Rule   sol87   1987    only    -       Feb     1       12:13:35s -0:13:35 -
-Rule   sol87   1987    only    -       Feb     2       12:13:40s -0:13:40 -
-Rule   sol87   1987    only    -       Feb     3       12:13:50s -0:13:50 -
-Rule   sol87   1987    only    -       Feb     4       12:13:55s -0:13:55 -
-Rule   sol87   1987    only    -       Feb     5       12:14:00s -0:14:00 -
-Rule   sol87   1987    only    -       Feb     6       12:14:05s -0:14:05 -
-Rule   sol87   1987    only    -       Feb     7       12:14:10s -0:14:10 -
-Rule   sol87   1987    only    -       Feb     8       12:14:10s -0:14:10 -
-Rule   sol87   1987    only    -       Feb     9       12:14:15s -0:14:15 -
-Rule   sol87   1987    only    -       Feb     10      12:14:15s -0:14:15 -
-Rule   sol87   1987    only    -       Feb     11      12:14:15s -0:14:15 -
-Rule   sol87   1987    only    -       Feb     12      12:14:15s -0:14:15 -
-Rule   sol87   1987    only    -       Feb     13      12:14:15s -0:14:15 -
-Rule   sol87   1987    only    -       Feb     14      12:14:15s -0:14:15 -
-Rule   sol87   1987    only    -       Feb     15      12:14:10s -0:14:10 -
-Rule   sol87   1987    only    -       Feb     16      12:14:10s -0:14:10 -
-Rule   sol87   1987    only    -       Feb     17      12:14:05s -0:14:05 -
-Rule   sol87   1987    only    -       Feb     18      12:14:00s -0:14:00 -
-Rule   sol87   1987    only    -       Feb     19      12:13:55s -0:13:55 -
-Rule   sol87   1987    only    -       Feb     20      12:13:50s -0:13:50 -
-Rule   sol87   1987    only    -       Feb     21      12:13:45s -0:13:45 -
-Rule   sol87   1987    only    -       Feb     22      12:13:35s -0:13:35 -
-Rule   sol87   1987    only    -       Feb     23      12:13:30s -0:13:30 -
-Rule   sol87   1987    only    -       Feb     24      12:13:20s -0:13:20 -
-Rule   sol87   1987    only    -       Feb     25      12:13:10s -0:13:10 -
-Rule   sol87   1987    only    -       Feb     26      12:13:00s -0:13:00 -
-Rule   sol87   1987    only    -       Feb     27      12:12:50s -0:12:50 -
-Rule   sol87   1987    only    -       Feb     28      12:12:40s -0:12:40 -
-Rule   sol87   1987    only    -       Mar     1       12:12:30s -0:12:30 -
-Rule   sol87   1987    only    -       Mar     2       12:12:20s -0:12:20 -
-Rule   sol87   1987    only    -       Mar     3       12:12:05s -0:12:05 -
-Rule   sol87   1987    only    -       Mar     4       12:11:55s -0:11:55 -
-Rule   sol87   1987    only    -       Mar     5       12:11:40s -0:11:40 -
-Rule   sol87   1987    only    -       Mar     6       12:11:25s -0:11:25 -
-Rule   sol87   1987    only    -       Mar     7       12:11:15s -0:11:15 -
-Rule   sol87   1987    only    -       Mar     8       12:11:00s -0:11:00 -
-Rule   sol87   1987    only    -       Mar     9       12:10:45s -0:10:45 -
-Rule   sol87   1987    only    -       Mar     10      12:10:30s -0:10:30 -
-Rule   sol87   1987    only    -       Mar     11      12:10:15s -0:10:15 -
-Rule   sol87   1987    only    -       Mar     12      12:09:55s -0:09:55 -
-Rule   sol87   1987    only    -       Mar     13      12:09:40s -0:09:40 -
-Rule   sol87   1987    only    -       Mar     14      12:09:25s -0:09:25 -
-Rule   sol87   1987    only    -       Mar     15      12:09:10s -0:09:10 -
-Rule   sol87   1987    only    -       Mar     16      12:08:50s -0:08:50 -
-Rule   sol87   1987    only    -       Mar     17      12:08:35s -0:08:35 -
-Rule   sol87   1987    only    -       Mar     18      12:08:15s -0:08:15 -
-Rule   sol87   1987    only    -       Mar     19      12:08:00s -0:08:00 -
-Rule   sol87   1987    only    -       Mar     20      12:07:40s -0:07:40 -
-Rule   sol87   1987    only    -       Mar     21      12:07:25s -0:07:25 -
-Rule   sol87   1987    only    -       Mar     22      12:07:05s -0:07:05 -
-Rule   sol87   1987    only    -       Mar     23      12:06:50s -0:06:50 -
-Rule   sol87   1987    only    -       Mar     24      12:06:30s -0:06:30 -
-Rule   sol87   1987    only    -       Mar     25      12:06:10s -0:06:10 -
-Rule   sol87   1987    only    -       Mar     26      12:05:55s -0:05:55 -
-Rule   sol87   1987    only    -       Mar     27      12:05:35s -0:05:35 -
-Rule   sol87   1987    only    -       Mar     28      12:05:15s -0:05:15 -
-Rule   sol87   1987    only    -       Mar     29      12:05:00s -0:05:00 -
-Rule   sol87   1987    only    -       Mar     30      12:04:40s -0:04:40 -
-Rule   sol87   1987    only    -       Mar     31      12:04:25s -0:04:25 -
-Rule   sol87   1987    only    -       Apr     1       12:04:05s -0:04:05 -
-Rule   sol87   1987    only    -       Apr     2       12:03:45s -0:03:45 -
-Rule   sol87   1987    only    -       Apr     3       12:03:30s -0:03:30 -
-Rule   sol87   1987    only    -       Apr     4       12:03:10s -0:03:10 -
-Rule   sol87   1987    only    -       Apr     5       12:02:55s -0:02:55 -
-Rule   sol87   1987    only    -       Apr     6       12:02:35s -0:02:35 -
-Rule   sol87   1987    only    -       Apr     7       12:02:20s -0:02:20 -
-Rule   sol87   1987    only    -       Apr     8       12:02:05s -0:02:05 -
-Rule   sol87   1987    only    -       Apr     9       12:01:45s -0:01:45 -
-Rule   sol87   1987    only    -       Apr     10      12:01:30s -0:01:30 -
-Rule   sol87   1987    only    -       Apr     11      12:01:15s -0:01:15 -
-Rule   sol87   1987    only    -       Apr     12      12:00:55s -0:00:55 -
-Rule   sol87   1987    only    -       Apr     13      12:00:40s -0:00:40 -
-Rule   sol87   1987    only    -       Apr     14      12:00:25s -0:00:25 -
-Rule   sol87   1987    only    -       Apr     15      12:00:10s -0:00:10 -
-Rule   sol87   1987    only    -       Apr     16      11:59:55s 0:00:05 -
-Rule   sol87   1987    only    -       Apr     17      11:59:45s 0:00:15 -
-Rule   sol87   1987    only    -       Apr     18      11:59:30s 0:00:30 -
-Rule   sol87   1987    only    -       Apr     19      11:59:15s 0:00:45 -
-Rule   sol87   1987    only    -       Apr     20      11:59:05s 0:00:55 -
-Rule   sol87   1987    only    -       Apr     21      11:58:50s 0:01:10 -
-Rule   sol87   1987    only    -       Apr     22      11:58:40s 0:01:20 -
-Rule   sol87   1987    only    -       Apr     23      11:58:25s 0:01:35 -
-Rule   sol87   1987    only    -       Apr     24      11:58:15s 0:01:45 -
-Rule   sol87   1987    only    -       Apr     25      11:58:05s 0:01:55 -
-Rule   sol87   1987    only    -       Apr     26      11:57:55s 0:02:05 -
-Rule   sol87   1987    only    -       Apr     27      11:57:45s 0:02:15 -
-Rule   sol87   1987    only    -       Apr     28      11:57:35s 0:02:25 -
-Rule   sol87   1987    only    -       Apr     29      11:57:25s 0:02:35 -
-Rule   sol87   1987    only    -       Apr     30      11:57:15s 0:02:45 -
-Rule   sol87   1987    only    -       May     1       11:57:10s 0:02:50 -
-Rule   sol87   1987    only    -       May     2       11:57:00s 0:03:00 -
-Rule   sol87   1987    only    -       May     3       11:56:55s 0:03:05 -
-Rule   sol87   1987    only    -       May     4       11:56:50s 0:03:10 -
-Rule   sol87   1987    only    -       May     5       11:56:45s 0:03:15 -
-Rule   sol87   1987    only    -       May     6       11:56:40s 0:03:20 -
-Rule   sol87   1987    only    -       May     7       11:56:35s 0:03:25 -
-Rule   sol87   1987    only    -       May     8       11:56:30s 0:03:30 -
-Rule   sol87   1987    only    -       May     9       11:56:25s 0:03:35 -
-Rule   sol87   1987    only    -       May     10      11:56:25s 0:03:35 -
-Rule   sol87   1987    only    -       May     11      11:56:20s 0:03:40 -
-Rule   sol87   1987    only    -       May     12      11:56:20s 0:03:40 -
-Rule   sol87   1987    only    -       May     13      11:56:20s 0:03:40 -
-Rule   sol87   1987    only    -       May     14      11:56:20s 0:03:40 -
-Rule   sol87   1987    only    -       May     15      11:56:20s 0:03:40 -
-Rule   sol87   1987    only    -       May     16      11:56:20s 0:03:40 -
-Rule   sol87   1987    only    -       May     17      11:56:20s 0:03:40 -
-Rule   sol87   1987    only    -       May     18      11:56:20s 0:03:40 -
-Rule   sol87   1987    only    -       May     19      11:56:25s 0:03:35 -
-Rule   sol87   1987    only    -       May     20      11:56:25s 0:03:35 -
-Rule   sol87   1987    only    -       May     21      11:56:30s 0:03:30 -
-Rule   sol87   1987    only    -       May     22      11:56:35s 0:03:25 -
-Rule   sol87   1987    only    -       May     23      11:56:40s 0:03:20 -
-Rule   sol87   1987    only    -       May     24      11:56:45s 0:03:15 -
-Rule   sol87   1987    only    -       May     25      11:56:50s 0:03:10 -
-Rule   sol87   1987    only    -       May     26      11:56:55s 0:03:05 -
-Rule   sol87   1987    only    -       May     27      11:57:00s 0:03:00 -
-Rule   sol87   1987    only    -       May     28      11:57:10s 0:02:50 -
-Rule   sol87   1987    only    -       May     29      11:57:15s 0:02:45 -
-Rule   sol87   1987    only    -       May     30      11:57:25s 0:02:35 -
-Rule   sol87   1987    only    -       May     31      11:57:30s 0:02:30 -
-Rule   sol87   1987    only    -       Jun     1       11:57:40s 0:02:20 -
-Rule   sol87   1987    only    -       Jun     2       11:57:50s 0:02:10 -
-Rule   sol87   1987    only    -       Jun     3       11:58:00s 0:02:00 -
-Rule   sol87   1987    only    -       Jun     4       11:58:10s 0:01:50 -
-Rule   sol87   1987    only    -       Jun     5       11:58:20s 0:01:40 -
-Rule   sol87   1987    only    -       Jun     6       11:58:30s 0:01:30 -
-Rule   sol87   1987    only    -       Jun     7       11:58:40s 0:01:20 -
-Rule   sol87   1987    only    -       Jun     8       11:58:50s 0:01:10 -
-Rule   sol87   1987    only    -       Jun     9       11:59:05s 0:00:55 -
-Rule   sol87   1987    only    -       Jun     10      11:59:15s 0:00:45 -
-Rule   sol87   1987    only    -       Jun     11      11:59:30s 0:00:30 -
-Rule   sol87   1987    only    -       Jun     12      11:59:40s 0:00:20 -
-Rule   sol87   1987    only    -       Jun     13      11:59:50s 0:00:10 -
-Rule   sol87   1987    only    -       Jun     14      12:00:05s -0:00:05 -
-Rule   sol87   1987    only    -       Jun     15      12:00:15s -0:00:15 -
-Rule   sol87   1987    only    -       Jun     16      12:00:30s -0:00:30 -
-Rule   sol87   1987    only    -       Jun     17      12:00:45s -0:00:45 -
-Rule   sol87   1987    only    -       Jun     18      12:00:55s -0:00:55 -
-Rule   sol87   1987    only    -       Jun     19      12:01:10s -0:01:10 -
-Rule   sol87   1987    only    -       Jun     20      12:01:20s -0:01:20 -
-Rule   sol87   1987    only    -       Jun     21      12:01:35s -0:01:35 -
-Rule   sol87   1987    only    -       Jun     22      12:01:50s -0:01:50 -
-Rule   sol87   1987    only    -       Jun     23      12:02:00s -0:02:00 -
-Rule   sol87   1987    only    -       Jun     24      12:02:15s -0:02:15 -
-Rule   sol87   1987    only    -       Jun     25      12:02:25s -0:02:25 -
-Rule   sol87   1987    only    -       Jun     26      12:02:40s -0:02:40 -
-Rule   sol87   1987    only    -       Jun     27      12:02:50s -0:02:50 -
-Rule   sol87   1987    only    -       Jun     28      12:03:05s -0:03:05 -
-Rule   sol87   1987    only    -       Jun     29      12:03:15s -0:03:15 -
-Rule   sol87   1987    only    -       Jun     30      12:03:30s -0:03:30 -
-Rule   sol87   1987    only    -       Jul     1       12:03:40s -0:03:40 -
-Rule   sol87   1987    only    -       Jul     2       12:03:50s -0:03:50 -
-Rule   sol87   1987    only    -       Jul     3       12:04:05s -0:04:05 -
-Rule   sol87   1987    only    -       Jul     4       12:04:15s -0:04:15 -
-Rule   sol87   1987    only    -       Jul     5       12:04:25s -0:04:25 -
-Rule   sol87   1987    only    -       Jul     6       12:04:35s -0:04:35 -
-Rule   sol87   1987    only    -       Jul     7       12:04:45s -0:04:45 -
-Rule   sol87   1987    only    -       Jul     8       12:04:55s -0:04:55 -
-Rule   sol87   1987    only    -       Jul     9       12:05:05s -0:05:05 -
-Rule   sol87   1987    only    -       Jul     10      12:05:15s -0:05:15 -
-Rule   sol87   1987    only    -       Jul     11      12:05:20s -0:05:20 -
-Rule   sol87   1987    only    -       Jul     12      12:05:30s -0:05:30 -
-Rule   sol87   1987    only    -       Jul     13      12:05:40s -0:05:40 -
-Rule   sol87   1987    only    -       Jul     14      12:05:45s -0:05:45 -
-Rule   sol87   1987    only    -       Jul     15      12:05:50s -0:05:50 -
-Rule   sol87   1987    only    -       Jul     16      12:06:00s -0:06:00 -
-Rule   sol87   1987    only    -       Jul     17      12:06:05s -0:06:05 -
-Rule   sol87   1987    only    -       Jul     18      12:06:10s -0:06:10 -
-Rule   sol87   1987    only    -       Jul     19      12:06:15s -0:06:15 -
-Rule   sol87   1987    only    -       Jul     20      12:06:15s -0:06:15 -
-Rule   sol87   1987    only    -       Jul     21      12:06:20s -0:06:20 -
-Rule   sol87   1987    only    -       Jul     22      12:06:25s -0:06:25 -
-Rule   sol87   1987    only    -       Jul     23      12:06:25s -0:06:25 -
-Rule   sol87   1987    only    -       Jul     24      12:06:25s -0:06:25 -
-Rule   sol87   1987    only    -       Jul     25      12:06:30s -0:06:30 -
-Rule   sol87   1987    only    -       Jul     26      12:06:30s -0:06:30 -
-Rule   sol87   1987    only    -       Jul     27      12:06:30s -0:06:30 -
-Rule   sol87   1987    only    -       Jul     28      12:06:30s -0:06:30 -
-Rule   sol87   1987    only    -       Jul     29      12:06:25s -0:06:25 -
-Rule   sol87   1987    only    -       Jul     30      12:06:25s -0:06:25 -
-Rule   sol87   1987    only    -       Jul     31      12:06:25s -0:06:25 -
-Rule   sol87   1987    only    -       Aug     1       12:06:20s -0:06:20 -
-Rule   sol87   1987    only    -       Aug     2       12:06:15s -0:06:15 -
-Rule   sol87   1987    only    -       Aug     3       12:06:10s -0:06:10 -
-Rule   sol87   1987    only    -       Aug     4       12:06:05s -0:06:05 -
-Rule   sol87   1987    only    -       Aug     5       12:06:00s -0:06:00 -
-Rule   sol87   1987    only    -       Aug     6       12:05:55s -0:05:55 -
-Rule   sol87   1987    only    -       Aug     7       12:05:50s -0:05:50 -
-Rule   sol87   1987    only    -       Aug     8       12:05:40s -0:05:40 -
-Rule   sol87   1987    only    -       Aug     9       12:05:35s -0:05:35 -
-Rule   sol87   1987    only    -       Aug     10      12:05:25s -0:05:25 -
-Rule   sol87   1987    only    -       Aug     11      12:05:15s -0:05:15 -
-Rule   sol87   1987    only    -       Aug     12      12:05:05s -0:05:05 -
-Rule   sol87   1987    only    -       Aug     13      12:04:55s -0:04:55 -
-Rule   sol87   1987    only    -       Aug     14      12:04:45s -0:04:45 -
-Rule   sol87   1987    only    -       Aug     15      12:04:35s -0:04:35 -
-Rule   sol87   1987    only    -       Aug     16      12:04:25s -0:04:25 -
-Rule   sol87   1987    only    -       Aug     17      12:04:10s -0:04:10 -
-Rule   sol87   1987    only    -       Aug     18      12:04:00s -0:04:00 -
-Rule   sol87   1987    only    -       Aug     19      12:03:45s -0:03:45 -
-Rule   sol87   1987    only    -       Aug     20      12:03:30s -0:03:30 -
-Rule   sol87   1987    only    -       Aug     21      12:03:15s -0:03:15 -
-Rule   sol87   1987    only    -       Aug     22      12:03:00s -0:03:00 -
-Rule   sol87   1987    only    -       Aug     23      12:02:45s -0:02:45 -
-Rule   sol87   1987    only    -       Aug     24      12:02:30s -0:02:30 -
-Rule   sol87   1987    only    -       Aug     25      12:02:15s -0:02:15 -
-Rule   sol87   1987    only    -       Aug     26      12:02:00s -0:02:00 -
-Rule   sol87   1987    only    -       Aug     27      12:01:40s -0:01:40 -
-Rule   sol87   1987    only    -       Aug     28      12:01:25s -0:01:25 -
-Rule   sol87   1987    only    -       Aug     29      12:01:05s -0:01:05 -
-Rule   sol87   1987    only    -       Aug     30      12:00:50s -0:00:50 -
-Rule   sol87   1987    only    -       Aug     31      12:00:30s -0:00:30 -
-Rule   sol87   1987    only    -       Sep     1       12:00:10s -0:00:10 -
-Rule   sol87   1987    only    -       Sep     2       11:59:50s 0:00:10 -
-Rule   sol87   1987    only    -       Sep     3       11:59:35s 0:00:25 -
-Rule   sol87   1987    only    -       Sep     4       11:59:15s 0:00:45 -
-Rule   sol87   1987    only    -       Sep     5       11:58:55s 0:01:05 -
-Rule   sol87   1987    only    -       Sep     6       11:58:35s 0:01:25 -
-Rule   sol87   1987    only    -       Sep     7       11:58:15s 0:01:45 -
-Rule   sol87   1987    only    -       Sep     8       11:57:55s 0:02:05 -
-Rule   sol87   1987    only    -       Sep     9       11:57:30s 0:02:30 -
-Rule   sol87   1987    only    -       Sep     10      11:57:10s 0:02:50 -
-Rule   sol87   1987    only    -       Sep     11      11:56:50s 0:03:10 -
-Rule   sol87   1987    only    -       Sep     12      11:56:30s 0:03:30 -
-Rule   sol87   1987    only    -       Sep     13      11:56:10s 0:03:50 -
-Rule   sol87   1987    only    -       Sep     14      11:55:45s 0:04:15 -
-Rule   sol87   1987    only    -       Sep     15      11:55:25s 0:04:35 -
-Rule   sol87   1987    only    -       Sep     16      11:55:05s 0:04:55 -
-Rule   sol87   1987    only    -       Sep     17      11:54:45s 0:05:15 -
-Rule   sol87   1987    only    -       Sep     18      11:54:20s 0:05:40 -
-Rule   sol87   1987    only    -       Sep     19      11:54:00s 0:06:00 -
-Rule   sol87   1987    only    -       Sep     20      11:53:40s 0:06:20 -
-Rule   sol87   1987    only    -       Sep     21      11:53:15s 0:06:45 -
-Rule   sol87   1987    only    -       Sep     22      11:52:55s 0:07:05 -
-Rule   sol87   1987    only    -       Sep     23      11:52:35s 0:07:25 -
-Rule   sol87   1987    only    -       Sep     24      11:52:15s 0:07:45 -
-Rule   sol87   1987    only    -       Sep     25      11:51:55s 0:08:05 -
-Rule   sol87   1987    only    -       Sep     26      11:51:35s 0:08:25 -
-Rule   sol87   1987    only    -       Sep     27      11:51:10s 0:08:50 -
-Rule   sol87   1987    only    -       Sep     28      11:50:50s 0:09:10 -
-Rule   sol87   1987    only    -       Sep     29      11:50:30s 0:09:30 -
-Rule   sol87   1987    only    -       Sep     30      11:50:10s 0:09:50 -
-Rule   sol87   1987    only    -       Oct     1       11:49:50s 0:10:10 -
-Rule   sol87   1987    only    -       Oct     2       11:49:35s 0:10:25 -
-Rule   sol87   1987    only    -       Oct     3       11:49:15s 0:10:45 -
-Rule   sol87   1987    only    -       Oct     4       11:48:55s 0:11:05 -
-Rule   sol87   1987    only    -       Oct     5       11:48:35s 0:11:25 -
-Rule   sol87   1987    only    -       Oct     6       11:48:20s 0:11:40 -
-Rule   sol87   1987    only    -       Oct     7       11:48:00s 0:12:00 -
-Rule   sol87   1987    only    -       Oct     8       11:47:45s 0:12:15 -
-Rule   sol87   1987    only    -       Oct     9       11:47:25s 0:12:35 -
-Rule   sol87   1987    only    -       Oct     10      11:47:10s 0:12:50 -
-Rule   sol87   1987    only    -       Oct     11      11:46:55s 0:13:05 -
-Rule   sol87   1987    only    -       Oct     12      11:46:40s 0:13:20 -
-Rule   sol87   1987    only    -       Oct     13      11:46:25s 0:13:35 -
-Rule   sol87   1987    only    -       Oct     14      11:46:10s 0:13:50 -
-Rule   sol87   1987    only    -       Oct     15      11:45:55s 0:14:05 -
-Rule   sol87   1987    only    -       Oct     16      11:45:45s 0:14:15 -
-Rule   sol87   1987    only    -       Oct     17      11:45:30s 0:14:30 -
-Rule   sol87   1987    only    -       Oct     18      11:45:20s 0:14:40 -
-Rule   sol87   1987    only    -       Oct     19      11:45:05s 0:14:55 -
-Rule   sol87   1987    only    -       Oct     20      11:44:55s 0:15:05 -
-Rule   sol87   1987    only    -       Oct     21      11:44:45s 0:15:15 -
-Rule   sol87   1987    only    -       Oct     22      11:44:35s 0:15:25 -
-Rule   sol87   1987    only    -       Oct     23      11:44:25s 0:15:35 -
-Rule   sol87   1987    only    -       Oct     24      11:44:20s 0:15:40 -
-Rule   sol87   1987    only    -       Oct     25      11:44:10s 0:15:50 -
-Rule   sol87   1987    only    -       Oct     26      11:44:05s 0:15:55 -
-Rule   sol87   1987    only    -       Oct     27      11:43:55s 0:16:05 -
-Rule   sol87   1987    only    -       Oct     28      11:43:50s 0:16:10 -
-Rule   sol87   1987    only    -       Oct     29      11:43:45s 0:16:15 -
-Rule   sol87   1987    only    -       Oct     30      11:43:45s 0:16:15 -
-Rule   sol87   1987    only    -       Oct     31      11:43:40s 0:16:20 -
-Rule   sol87   1987    only    -       Nov     1       11:43:40s 0:16:20 -
-Rule   sol87   1987    only    -       Nov     2       11:43:35s 0:16:25 -
-Rule   sol87   1987    only    -       Nov     3       11:43:35s 0:16:25 -
-Rule   sol87   1987    only    -       Nov     4       11:43:35s 0:16:25 -
-Rule   sol87   1987    only    -       Nov     5       11:43:35s 0:16:25 -
-Rule   sol87   1987    only    -       Nov     6       11:43:40s 0:16:20 -
-Rule   sol87   1987    only    -       Nov     7       11:43:40s 0:16:20 -
-Rule   sol87   1987    only    -       Nov     8       11:43:45s 0:16:15 -
-Rule   sol87   1987    only    -       Nov     9       11:43:50s 0:16:10 -
-Rule   sol87   1987    only    -       Nov     10      11:43:55s 0:16:05 -
-Rule   sol87   1987    only    -       Nov     11      11:44:00s 0:16:00 -
-Rule   sol87   1987    only    -       Nov     12      11:44:05s 0:15:55 -
-Rule   sol87   1987    only    -       Nov     13      11:44:15s 0:15:45 -
-Rule   sol87   1987    only    -       Nov     14      11:44:20s 0:15:40 -
-Rule   sol87   1987    only    -       Nov     15      11:44:30s 0:15:30 -
-Rule   sol87   1987    only    -       Nov     16      11:44:40s 0:15:20 -
-Rule   sol87   1987    only    -       Nov     17      11:44:50s 0:15:10 -
-Rule   sol87   1987    only    -       Nov     18      11:45:05s 0:14:55 -
-Rule   sol87   1987    only    -       Nov     19      11:45:15s 0:14:45 -
-Rule   sol87   1987    only    -       Nov     20      11:45:30s 0:14:30 -
-Rule   sol87   1987    only    -       Nov     21      11:45:45s 0:14:15 -
-Rule   sol87   1987    only    -       Nov     22      11:46:00s 0:14:00 -
-Rule   sol87   1987    only    -       Nov     23      11:46:15s 0:13:45 -
-Rule   sol87   1987    only    -       Nov     24      11:46:30s 0:13:30 -
-Rule   sol87   1987    only    -       Nov     25      11:46:50s 0:13:10 -
-Rule   sol87   1987    only    -       Nov     26      11:47:10s 0:12:50 -
-Rule   sol87   1987    only    -       Nov     27      11:47:25s 0:12:35 -
-Rule   sol87   1987    only    -       Nov     28      11:47:45s 0:12:15 -
-Rule   sol87   1987    only    -       Nov     29      11:48:05s 0:11:55 -
-Rule   sol87   1987    only    -       Nov     30      11:48:30s 0:11:30 -
-Rule   sol87   1987    only    -       Dec     1       11:48:50s 0:11:10 -
-Rule   sol87   1987    only    -       Dec     2       11:49:10s 0:10:50 -
-Rule   sol87   1987    only    -       Dec     3       11:49:35s 0:10:25 -
-Rule   sol87   1987    only    -       Dec     4       11:50:00s 0:10:00 -
-Rule   sol87   1987    only    -       Dec     5       11:50:25s 0:09:35 -
-Rule   sol87   1987    only    -       Dec     6       11:50:50s 0:09:10 -
-Rule   sol87   1987    only    -       Dec     7       11:51:15s 0:08:45 -
-Rule   sol87   1987    only    -       Dec     8       11:51:40s 0:08:20 -
-Rule   sol87   1987    only    -       Dec     9       11:52:05s 0:07:55 -
-Rule   sol87   1987    only    -       Dec     10      11:52:30s 0:07:30 -
-Rule   sol87   1987    only    -       Dec     11      11:53:00s 0:07:00 -
-Rule   sol87   1987    only    -       Dec     12      11:53:25s 0:06:35 -
-Rule   sol87   1987    only    -       Dec     13      11:53:55s 0:06:05 -
-Rule   sol87   1987    only    -       Dec     14      11:54:25s 0:05:35 -
-Rule   sol87   1987    only    -       Dec     15      11:54:50s 0:05:10 -
-Rule   sol87   1987    only    -       Dec     16      11:55:20s 0:04:40 -
-Rule   sol87   1987    only    -       Dec     17      11:55:50s 0:04:10 -
-Rule   sol87   1987    only    -       Dec     18      11:56:20s 0:03:40 -
-Rule   sol87   1987    only    -       Dec     19      11:56:50s 0:03:10 -
-Rule   sol87   1987    only    -       Dec     20      11:57:20s 0:02:40 -
-Rule   sol87   1987    only    -       Dec     21      11:57:50s 0:02:10 -
-Rule   sol87   1987    only    -       Dec     22      11:58:20s 0:01:40 -
-Rule   sol87   1987    only    -       Dec     23      11:58:50s 0:01:10 -
-Rule   sol87   1987    only    -       Dec     24      11:59:20s 0:00:40 -
-Rule   sol87   1987    only    -       Dec     25      11:59:50s 0:00:10 -
-Rule   sol87   1987    only    -       Dec     26      12:00:20s -0:00:20 -
-Rule   sol87   1987    only    -       Dec     27      12:00:45s -0:00:45 -
-Rule   sol87   1987    only    -       Dec     28      12:01:15s -0:01:15 -
-Rule   sol87   1987    only    -       Dec     29      12:01:45s -0:01:45 -
-Rule   sol87   1987    only    -       Dec     30      12:02:15s -0:02:15 -
-Rule   sol87   1987    only    -       Dec     31      12:02:45s -0:02:45 -
-
-# Riyadh is at about 46 degrees 46 minutes East:  3 hrs, 7 mins, 4 secs
-# Before and after 1987, we'll operate on local mean solar time.
-
-# Zone NAME                    GMTOFF  RULES/SAVE      FORMAT  [UNTIL]
-Zone   Mideast/Riyadh87        3:07:04 -               ??      1987
-                               3:07:04 sol87           ??      1988
-                               3:07:04 -               ??
diff --git a/time/solar88 b/time/solar88
deleted file mode 100644 (file)
index 0384b17..0000000
+++ /dev/null
@@ -1,386 +0,0 @@
-# @(#)solar88  7.2
-
-# Apparent noon times below are for Riyadh; they're a bit off for other places.
-# Times were computed using formulas in the U.S. Naval Observatory's
-# Almanac for Computers 1988; the formulas "will give EqT to an accuracy of
-# [plus or minus two] seconds during the current year."
-#
-# Rounding to the nearest five seconds results in fewer than
-# 256 different "time types"--a limit that's faced because time types are
-# stored on disk as unsigned chars.
-
-# Rule NAME    FROM    TO      TYPE    IN      ON      AT      SAVE    LETTER/S
-Rule   sol88   1988    only    -       Jan     1       12:03:15s -0:03:15 -
-Rule   sol88   1988    only    -       Jan     2       12:03:40s -0:03:40 -
-Rule   sol88   1988    only    -       Jan     3       12:04:10s -0:04:10 -
-Rule   sol88   1988    only    -       Jan     4       12:04:40s -0:04:40 -
-Rule   sol88   1988    only    -       Jan     5       12:05:05s -0:05:05 -
-Rule   sol88   1988    only    -       Jan     6       12:05:30s -0:05:30 -
-Rule   sol88   1988    only    -       Jan     7       12:06:00s -0:06:00 -
-Rule   sol88   1988    only    -       Jan     8       12:06:25s -0:06:25 -
-Rule   sol88   1988    only    -       Jan     9       12:06:50s -0:06:50 -
-Rule   sol88   1988    only    -       Jan     10      12:07:15s -0:07:15 -
-Rule   sol88   1988    only    -       Jan     11      12:07:40s -0:07:40 -
-Rule   sol88   1988    only    -       Jan     12      12:08:05s -0:08:05 -
-Rule   sol88   1988    only    -       Jan     13      12:08:25s -0:08:25 -
-Rule   sol88   1988    only    -       Jan     14      12:08:50s -0:08:50 -
-Rule   sol88   1988    only    -       Jan     15      12:09:10s -0:09:10 -
-Rule   sol88   1988    only    -       Jan     16      12:09:30s -0:09:30 -
-Rule   sol88   1988    only    -       Jan     17      12:09:50s -0:09:50 -
-Rule   sol88   1988    only    -       Jan     18      12:10:10s -0:10:10 -
-Rule   sol88   1988    only    -       Jan     19      12:10:30s -0:10:30 -
-Rule   sol88   1988    only    -       Jan     20      12:10:50s -0:10:50 -
-Rule   sol88   1988    only    -       Jan     21      12:11:05s -0:11:05 -
-Rule   sol88   1988    only    -       Jan     22      12:11:25s -0:11:25 -
-Rule   sol88   1988    only    -       Jan     23      12:11:40s -0:11:40 -
-Rule   sol88   1988    only    -       Jan     24      12:11:55s -0:11:55 -
-Rule   sol88   1988    only    -       Jan     25      12:12:10s -0:12:10 -
-Rule   sol88   1988    only    -       Jan     26      12:12:25s -0:12:25 -
-Rule   sol88   1988    only    -       Jan     27      12:12:40s -0:12:40 -
-Rule   sol88   1988    only    -       Jan     28      12:12:50s -0:12:50 -
-Rule   sol88   1988    only    -       Jan     29      12:13:00s -0:13:00 -
-Rule   sol88   1988    only    -       Jan     30      12:13:10s -0:13:10 -
-Rule   sol88   1988    only    -       Jan     31      12:13:20s -0:13:20 -
-Rule   sol88   1988    only    -       Feb     1       12:13:30s -0:13:30 -
-Rule   sol88   1988    only    -       Feb     2       12:13:40s -0:13:40 -
-Rule   sol88   1988    only    -       Feb     3       12:13:45s -0:13:45 -
-Rule   sol88   1988    only    -       Feb     4       12:13:55s -0:13:55 -
-Rule   sol88   1988    only    -       Feb     5       12:14:00s -0:14:00 -
-Rule   sol88   1988    only    -       Feb     6       12:14:05s -0:14:05 -
-Rule   sol88   1988    only    -       Feb     7       12:14:10s -0:14:10 -
-Rule   sol88   1988    only    -       Feb     8       12:14:10s -0:14:10 -
-Rule   sol88   1988    only    -       Feb     9       12:14:15s -0:14:15 -
-Rule   sol88   1988    only    -       Feb     10      12:14:15s -0:14:15 -
-Rule   sol88   1988    only    -       Feb     11      12:14:15s -0:14:15 -
-Rule   sol88   1988    only    -       Feb     12      12:14:15s -0:14:15 -
-Rule   sol88   1988    only    -       Feb     13      12:14:15s -0:14:15 -
-Rule   sol88   1988    only    -       Feb     14      12:14:15s -0:14:15 -
-Rule   sol88   1988    only    -       Feb     15      12:14:10s -0:14:10 -
-Rule   sol88   1988    only    -       Feb     16      12:14:10s -0:14:10 -
-Rule   sol88   1988    only    -       Feb     17      12:14:05s -0:14:05 -
-Rule   sol88   1988    only    -       Feb     18      12:14:00s -0:14:00 -
-Rule   sol88   1988    only    -       Feb     19      12:13:55s -0:13:55 -
-Rule   sol88   1988    only    -       Feb     20      12:13:50s -0:13:50 -
-Rule   sol88   1988    only    -       Feb     21      12:13:45s -0:13:45 -
-Rule   sol88   1988    only    -       Feb     22      12:13:40s -0:13:40 -
-Rule   sol88   1988    only    -       Feb     23      12:13:30s -0:13:30 -
-Rule   sol88   1988    only    -       Feb     24      12:13:20s -0:13:20 -
-Rule   sol88   1988    only    -       Feb     25      12:13:15s -0:13:15 -
-Rule   sol88   1988    only    -       Feb     26      12:13:05s -0:13:05 -
-Rule   sol88   1988    only    -       Feb     27      12:12:55s -0:12:55 -
-Rule   sol88   1988    only    -       Feb     28      12:12:45s -0:12:45 -
-Rule   sol88   1988    only    -       Feb     29      12:12:30s -0:12:30 -
-Rule   sol88   1988    only    -       Mar     1       12:12:20s -0:12:20 -
-Rule   sol88   1988    only    -       Mar     2       12:12:10s -0:12:10 -
-Rule   sol88   1988    only    -       Mar     3       12:11:55s -0:11:55 -
-Rule   sol88   1988    only    -       Mar     4       12:11:45s -0:11:45 -
-Rule   sol88   1988    only    -       Mar     5       12:11:30s -0:11:30 -
-Rule   sol88   1988    only    -       Mar     6       12:11:15s -0:11:15 -
-Rule   sol88   1988    only    -       Mar     7       12:11:00s -0:11:00 -
-Rule   sol88   1988    only    -       Mar     8       12:10:45s -0:10:45 -
-Rule   sol88   1988    only    -       Mar     9       12:10:30s -0:10:30 -
-Rule   sol88   1988    only    -       Mar     10      12:10:15s -0:10:15 -
-Rule   sol88   1988    only    -       Mar     11      12:10:00s -0:10:00 -
-Rule   sol88   1988    only    -       Mar     12      12:09:45s -0:09:45 -
-Rule   sol88   1988    only    -       Mar     13      12:09:30s -0:09:30 -
-Rule   sol88   1988    only    -       Mar     14      12:09:10s -0:09:10 -
-Rule   sol88   1988    only    -       Mar     15      12:08:55s -0:08:55 -
-Rule   sol88   1988    only    -       Mar     16      12:08:40s -0:08:40 -
-Rule   sol88   1988    only    -       Mar     17      12:08:20s -0:08:20 -
-Rule   sol88   1988    only    -       Mar     18      12:08:05s -0:08:05 -
-Rule   sol88   1988    only    -       Mar     19      12:07:45s -0:07:45 -
-Rule   sol88   1988    only    -       Mar     20      12:07:30s -0:07:30 -
-Rule   sol88   1988    only    -       Mar     21      12:07:10s -0:07:10 -
-Rule   sol88   1988    only    -       Mar     22      12:06:50s -0:06:50 -
-Rule   sol88   1988    only    -       Mar     23      12:06:35s -0:06:35 -
-Rule   sol88   1988    only    -       Mar     24      12:06:15s -0:06:15 -
-Rule   sol88   1988    only    -       Mar     25      12:06:00s -0:06:00 -
-Rule   sol88   1988    only    -       Mar     26      12:05:40s -0:05:40 -
-Rule   sol88   1988    only    -       Mar     27      12:05:20s -0:05:20 -
-Rule   sol88   1988    only    -       Mar     28      12:05:05s -0:05:05 -
-Rule   sol88   1988    only    -       Mar     29      12:04:45s -0:04:45 -
-Rule   sol88   1988    only    -       Mar     30      12:04:25s -0:04:25 -
-Rule   sol88   1988    only    -       Mar     31      12:04:10s -0:04:10 -
-Rule   sol88   1988    only    -       Apr     1       12:03:50s -0:03:50 -
-Rule   sol88   1988    only    -       Apr     2       12:03:35s -0:03:35 -
-Rule   sol88   1988    only    -       Apr     3       12:03:15s -0:03:15 -
-Rule   sol88   1988    only    -       Apr     4       12:03:00s -0:03:00 -
-Rule   sol88   1988    only    -       Apr     5       12:02:40s -0:02:40 -
-Rule   sol88   1988    only    -       Apr     6       12:02:25s -0:02:25 -
-Rule   sol88   1988    only    -       Apr     7       12:02:05s -0:02:05 -
-Rule   sol88   1988    only    -       Apr     8       12:01:50s -0:01:50 -
-Rule   sol88   1988    only    -       Apr     9       12:01:35s -0:01:35 -
-Rule   sol88   1988    only    -       Apr     10      12:01:15s -0:01:15 -
-Rule   sol88   1988    only    -       Apr     11      12:01:00s -0:01:00 -
-Rule   sol88   1988    only    -       Apr     12      12:00:45s -0:00:45 -
-Rule   sol88   1988    only    -       Apr     13      12:00:30s -0:00:30 -
-Rule   sol88   1988    only    -       Apr     14      12:00:15s -0:00:15 -
-Rule   sol88   1988    only    -       Apr     15      12:00:00s 0:00:00 -
-Rule   sol88   1988    only    -       Apr     16      11:59:45s 0:00:15 -
-Rule   sol88   1988    only    -       Apr     17      11:59:30s 0:00:30 -
-Rule   sol88   1988    only    -       Apr     18      11:59:20s 0:00:40 -
-Rule   sol88   1988    only    -       Apr     19      11:59:05s 0:00:55 -
-Rule   sol88   1988    only    -       Apr     20      11:58:55s 0:01:05 -
-Rule   sol88   1988    only    -       Apr     21      11:58:40s 0:01:20 -
-Rule   sol88   1988    only    -       Apr     22      11:58:30s 0:01:30 -
-Rule   sol88   1988    only    -       Apr     23      11:58:15s 0:01:45 -
-Rule   sol88   1988    only    -       Apr     24      11:58:05s 0:01:55 -
-Rule   sol88   1988    only    -       Apr     25      11:57:55s 0:02:05 -
-Rule   sol88   1988    only    -       Apr     26      11:57:45s 0:02:15 -
-Rule   sol88   1988    only    -       Apr     27      11:57:35s 0:02:25 -
-Rule   sol88   1988    only    -       Apr     28      11:57:30s 0:02:30 -
-Rule   sol88   1988    only    -       Apr     29      11:57:20s 0:02:40 -
-Rule   sol88   1988    only    -       Apr     30      11:57:10s 0:02:50 -
-Rule   sol88   1988    only    -       May     1       11:57:05s 0:02:55 -
-Rule   sol88   1988    only    -       May     2       11:56:55s 0:03:05 -
-Rule   sol88   1988    only    -       May     3       11:56:50s 0:03:10 -
-Rule   sol88   1988    only    -       May     4       11:56:45s 0:03:15 -
-Rule   sol88   1988    only    -       May     5       11:56:40s 0:03:20 -
-Rule   sol88   1988    only    -       May     6       11:56:35s 0:03:25 -
-Rule   sol88   1988    only    -       May     7       11:56:30s 0:03:30 -
-Rule   sol88   1988    only    -       May     8       11:56:25s 0:03:35 -
-Rule   sol88   1988    only    -       May     9       11:56:25s 0:03:35 -
-Rule   sol88   1988    only    -       May     10      11:56:20s 0:03:40 -
-Rule   sol88   1988    only    -       May     11      11:56:20s 0:03:40 -
-Rule   sol88   1988    only    -       May     12      11:56:20s 0:03:40 -
-Rule   sol88   1988    only    -       May     13      11:56:20s 0:03:40 -
-Rule   sol88   1988    only    -       May     14      11:56:20s 0:03:40 -
-Rule   sol88   1988    only    -       May     15      11:56:20s 0:03:40 -
-Rule   sol88   1988    only    -       May     16      11:56:20s 0:03:40 -
-Rule   sol88   1988    only    -       May     17      11:56:20s 0:03:40 -
-Rule   sol88   1988    only    -       May     18      11:56:25s 0:03:35 -
-Rule   sol88   1988    only    -       May     19      11:56:25s 0:03:35 -
-Rule   sol88   1988    only    -       May     20      11:56:30s 0:03:30 -
-Rule   sol88   1988    only    -       May     21      11:56:35s 0:03:25 -
-Rule   sol88   1988    only    -       May     22      11:56:40s 0:03:20 -
-Rule   sol88   1988    only    -       May     23      11:56:45s 0:03:15 -
-Rule   sol88   1988    only    -       May     24      11:56:50s 0:03:10 -
-Rule   sol88   1988    only    -       May     25      11:56:55s 0:03:05 -
-Rule   sol88   1988    only    -       May     26      11:57:00s 0:03:00 -
-Rule   sol88   1988    only    -       May     27      11:57:05s 0:02:55 -
-Rule   sol88   1988    only    -       May     28      11:57:15s 0:02:45 -
-Rule   sol88   1988    only    -       May     29      11:57:20s 0:02:40 -
-Rule   sol88   1988    only    -       May     30      11:57:30s 0:02:30 -
-Rule   sol88   1988    only    -       May     31      11:57:40s 0:02:20 -
-Rule   sol88   1988    only    -       Jun     1       11:57:50s 0:02:10 -
-Rule   sol88   1988    only    -       Jun     2       11:57:55s 0:02:05 -
-Rule   sol88   1988    only    -       Jun     3       11:58:05s 0:01:55 -
-Rule   sol88   1988    only    -       Jun     4       11:58:15s 0:01:45 -
-Rule   sol88   1988    only    -       Jun     5       11:58:30s 0:01:30 -
-Rule   sol88   1988    only    -       Jun     6       11:58:40s 0:01:20 -
-Rule   sol88   1988    only    -       Jun     7       11:58:50s 0:01:10 -
-Rule   sol88   1988    only    -       Jun     8       11:59:00s 0:01:00 -
-Rule   sol88   1988    only    -       Jun     9       11:59:15s 0:00:45 -
-Rule   sol88   1988    only    -       Jun     10      11:59:25s 0:00:35 -
-Rule   sol88   1988    only    -       Jun     11      11:59:35s 0:00:25 -
-Rule   sol88   1988    only    -       Jun     12      11:59:50s 0:00:10 -
-Rule   sol88   1988    only    -       Jun     13      12:00:00s 0:00:00 -
-Rule   sol88   1988    only    -       Jun     14      12:00:15s -0:00:15 -
-Rule   sol88   1988    only    -       Jun     15      12:00:25s -0:00:25 -
-Rule   sol88   1988    only    -       Jun     16      12:00:40s -0:00:40 -
-Rule   sol88   1988    only    -       Jun     17      12:00:55s -0:00:55 -
-Rule   sol88   1988    only    -       Jun     18      12:01:05s -0:01:05 -
-Rule   sol88   1988    only    -       Jun     19      12:01:20s -0:01:20 -
-Rule   sol88   1988    only    -       Jun     20      12:01:30s -0:01:30 -
-Rule   sol88   1988    only    -       Jun     21      12:01:45s -0:01:45 -
-Rule   sol88   1988    only    -       Jun     22      12:02:00s -0:02:00 -
-Rule   sol88   1988    only    -       Jun     23      12:02:10s -0:02:10 -
-Rule   sol88   1988    only    -       Jun     24      12:02:25s -0:02:25 -
-Rule   sol88   1988    only    -       Jun     25      12:02:35s -0:02:35 -
-Rule   sol88   1988    only    -       Jun     26      12:02:50s -0:02:50 -
-Rule   sol88   1988    only    -       Jun     27      12:03:00s -0:03:00 -
-Rule   sol88   1988    only    -       Jun     28      12:03:15s -0:03:15 -
-Rule   sol88   1988    only    -       Jun     29      12:03:25s -0:03:25 -
-Rule   sol88   1988    only    -       Jun     30      12:03:40s -0:03:40 -
-Rule   sol88   1988    only    -       Jul     1       12:03:50s -0:03:50 -
-Rule   sol88   1988    only    -       Jul     2       12:04:00s -0:04:00 -
-Rule   sol88   1988    only    -       Jul     3       12:04:10s -0:04:10 -
-Rule   sol88   1988    only    -       Jul     4       12:04:25s -0:04:25 -
-Rule   sol88   1988    only    -       Jul     5       12:04:35s -0:04:35 -
-Rule   sol88   1988    only    -       Jul     6       12:04:45s -0:04:45 -
-Rule   sol88   1988    only    -       Jul     7       12:04:55s -0:04:55 -
-Rule   sol88   1988    only    -       Jul     8       12:05:05s -0:05:05 -
-Rule   sol88   1988    only    -       Jul     9       12:05:10s -0:05:10 -
-Rule   sol88   1988    only    -       Jul     10      12:05:20s -0:05:20 -
-Rule   sol88   1988    only    -       Jul     11      12:05:30s -0:05:30 -
-Rule   sol88   1988    only    -       Jul     12      12:05:35s -0:05:35 -
-Rule   sol88   1988    only    -       Jul     13      12:05:45s -0:05:45 -
-Rule   sol88   1988    only    -       Jul     14      12:05:50s -0:05:50 -
-Rule   sol88   1988    only    -       Jul     15      12:05:55s -0:05:55 -
-Rule   sol88   1988    only    -       Jul     16      12:06:00s -0:06:00 -
-Rule   sol88   1988    only    -       Jul     17      12:06:05s -0:06:05 -
-Rule   sol88   1988    only    -       Jul     18      12:06:10s -0:06:10 -
-Rule   sol88   1988    only    -       Jul     19      12:06:15s -0:06:15 -
-Rule   sol88   1988    only    -       Jul     20      12:06:20s -0:06:20 -
-Rule   sol88   1988    only    -       Jul     21      12:06:25s -0:06:25 -
-Rule   sol88   1988    only    -       Jul     22      12:06:25s -0:06:25 -
-Rule   sol88   1988    only    -       Jul     23      12:06:25s -0:06:25 -
-Rule   sol88   1988    only    -       Jul     24      12:06:30s -0:06:30 -
-Rule   sol88   1988    only    -       Jul     25      12:06:30s -0:06:30 -
-Rule   sol88   1988    only    -       Jul     26      12:06:30s -0:06:30 -
-Rule   sol88   1988    only    -       Jul     27      12:06:30s -0:06:30 -
-Rule   sol88   1988    only    -       Jul     28      12:06:30s -0:06:30 -
-Rule   sol88   1988    only    -       Jul     29      12:06:25s -0:06:25 -
-Rule   sol88   1988    only    -       Jul     30      12:06:25s -0:06:25 -
-Rule   sol88   1988    only    -       Jul     31      12:06:20s -0:06:20 -
-Rule   sol88   1988    only    -       Aug     1       12:06:15s -0:06:15 -
-Rule   sol88   1988    only    -       Aug     2       12:06:15s -0:06:15 -
-Rule   sol88   1988    only    -       Aug     3       12:06:10s -0:06:10 -
-Rule   sol88   1988    only    -       Aug     4       12:06:05s -0:06:05 -
-Rule   sol88   1988    only    -       Aug     5       12:05:55s -0:05:55 -
-Rule   sol88   1988    only    -       Aug     6       12:05:50s -0:05:50 -
-Rule   sol88   1988    only    -       Aug     7       12:05:45s -0:05:45 -
-Rule   sol88   1988    only    -       Aug     8       12:05:35s -0:05:35 -
-Rule   sol88   1988    only    -       Aug     9       12:05:25s -0:05:25 -
-Rule   sol88   1988    only    -       Aug     10      12:05:20s -0:05:20 -
-Rule   sol88   1988    only    -       Aug     11      12:05:10s -0:05:10 -
-Rule   sol88   1988    only    -       Aug     12      12:05:00s -0:05:00 -
-Rule   sol88   1988    only    -       Aug     13      12:04:50s -0:04:50 -
-Rule   sol88   1988    only    -       Aug     14      12:04:35s -0:04:35 -
-Rule   sol88   1988    only    -       Aug     15      12:04:25s -0:04:25 -
-Rule   sol88   1988    only    -       Aug     16      12:04:15s -0:04:15 -
-Rule   sol88   1988    only    -       Aug     17      12:04:00s -0:04:00 -
-Rule   sol88   1988    only    -       Aug     18      12:03:50s -0:03:50 -
-Rule   sol88   1988    only    -       Aug     19      12:03:35s -0:03:35 -
-Rule   sol88   1988    only    -       Aug     20      12:03:20s -0:03:20 -
-Rule   sol88   1988    only    -       Aug     21      12:03:05s -0:03:05 -
-Rule   sol88   1988    only    -       Aug     22      12:02:50s -0:02:50 -
-Rule   sol88   1988    only    -       Aug     23      12:02:35s -0:02:35 -
-Rule   sol88   1988    only    -       Aug     24      12:02:20s -0:02:20 -
-Rule   sol88   1988    only    -       Aug     25      12:02:00s -0:02:00 -
-Rule   sol88   1988    only    -       Aug     26      12:01:45s -0:01:45 -
-Rule   sol88   1988    only    -       Aug     27      12:01:30s -0:01:30 -
-Rule   sol88   1988    only    -       Aug     28      12:01:10s -0:01:10 -
-Rule   sol88   1988    only    -       Aug     29      12:00:50s -0:00:50 -
-Rule   sol88   1988    only    -       Aug     30      12:00:35s -0:00:35 -
-Rule   sol88   1988    only    -       Aug     31      12:00:15s -0:00:15 -
-Rule   sol88   1988    only    -       Sep     1       11:59:55s 0:00:05 -
-Rule   sol88   1988    only    -       Sep     2       11:59:35s 0:00:25 -
-Rule   sol88   1988    only    -       Sep     3       11:59:20s 0:00:40 -
-Rule   sol88   1988    only    -       Sep     4       11:59:00s 0:01:00 -
-Rule   sol88   1988    only    -       Sep     5       11:58:40s 0:01:20 -
-Rule   sol88   1988    only    -       Sep     6       11:58:20s 0:01:40 -
-Rule   sol88   1988    only    -       Sep     7       11:58:00s 0:02:00 -
-Rule   sol88   1988    only    -       Sep     8       11:57:35s 0:02:25 -
-Rule   sol88   1988    only    -       Sep     9       11:57:15s 0:02:45 -
-Rule   sol88   1988    only    -       Sep     10      11:56:55s 0:03:05 -
-Rule   sol88   1988    only    -       Sep     11      11:56:35s 0:03:25 -
-Rule   sol88   1988    only    -       Sep     12      11:56:15s 0:03:45 -
-Rule   sol88   1988    only    -       Sep     13      11:55:50s 0:04:10 -
-Rule   sol88   1988    only    -       Sep     14      11:55:30s 0:04:30 -
-Rule   sol88   1988    only    -       Sep     15      11:55:10s 0:04:50 -
-Rule   sol88   1988    only    -       Sep     16      11:54:50s 0:05:10 -
-Rule   sol88   1988    only    -       Sep     17      11:54:25s 0:05:35 -
-Rule   sol88   1988    only    -       Sep     18      11:54:05s 0:05:55 -
-Rule   sol88   1988    only    -       Sep     19      11:53:45s 0:06:15 -
-Rule   sol88   1988    only    -       Sep     20      11:53:25s 0:06:35 -
-Rule   sol88   1988    only    -       Sep     21      11:53:00s 0:07:00 -
-Rule   sol88   1988    only    -       Sep     22      11:52:40s 0:07:20 -
-Rule   sol88   1988    only    -       Sep     23      11:52:20s 0:07:40 -
-Rule   sol88   1988    only    -       Sep     24      11:52:00s 0:08:00 -
-Rule   sol88   1988    only    -       Sep     25      11:51:40s 0:08:20 -
-Rule   sol88   1988    only    -       Sep     26      11:51:15s 0:08:45 -
-Rule   sol88   1988    only    -       Sep     27      11:50:55s 0:09:05 -
-Rule   sol88   1988    only    -       Sep     28      11:50:35s 0:09:25 -
-Rule   sol88   1988    only    -       Sep     29      11:50:15s 0:09:45 -
-Rule   sol88   1988    only    -       Sep     30      11:49:55s 0:10:05 -
-Rule   sol88   1988    only    -       Oct     1       11:49:35s 0:10:25 -
-Rule   sol88   1988    only    -       Oct     2       11:49:20s 0:10:40 -
-Rule   sol88   1988    only    -       Oct     3       11:49:00s 0:11:00 -
-Rule   sol88   1988    only    -       Oct     4       11:48:40s 0:11:20 -
-Rule   sol88   1988    only    -       Oct     5       11:48:25s 0:11:35 -
-Rule   sol88   1988    only    -       Oct     6       11:48:05s 0:11:55 -
-Rule   sol88   1988    only    -       Oct     7       11:47:50s 0:12:10 -
-Rule   sol88   1988    only    -       Oct     8       11:47:30s 0:12:30 -
-Rule   sol88   1988    only    -       Oct     9       11:47:15s 0:12:45 -
-Rule   sol88   1988    only    -       Oct     10      11:47:00s 0:13:00 -
-Rule   sol88   1988    only    -       Oct     11      11:46:45s 0:13:15 -
-Rule   sol88   1988    only    -       Oct     12      11:46:30s 0:13:30 -
-Rule   sol88   1988    only    -       Oct     13      11:46:15s 0:13:45 -
-Rule   sol88   1988    only    -       Oct     14      11:46:00s 0:14:00 -
-Rule   sol88   1988    only    -       Oct     15      11:45:45s 0:14:15 -
-Rule   sol88   1988    only    -       Oct     16      11:45:35s 0:14:25 -
-Rule   sol88   1988    only    -       Oct     17      11:45:20s 0:14:40 -
-Rule   sol88   1988    only    -       Oct     18      11:45:10s 0:14:50 -
-Rule   sol88   1988    only    -       Oct     19      11:45:00s 0:15:00 -
-Rule   sol88   1988    only    -       Oct     20      11:44:45s 0:15:15 -
-Rule   sol88   1988    only    -       Oct     21      11:44:40s 0:15:20 -
-Rule   sol88   1988    only    -       Oct     22      11:44:30s 0:15:30 -
-Rule   sol88   1988    only    -       Oct     23      11:44:20s 0:15:40 -
-Rule   sol88   1988    only    -       Oct     24      11:44:10s 0:15:50 -
-Rule   sol88   1988    only    -       Oct     25      11:44:05s 0:15:55 -
-Rule   sol88   1988    only    -       Oct     26      11:44:00s 0:16:00 -
-Rule   sol88   1988    only    -       Oct     27      11:43:55s 0:16:05 -
-Rule   sol88   1988    only    -       Oct     28      11:43:50s 0:16:10 -
-Rule   sol88   1988    only    -       Oct     29      11:43:45s 0:16:15 -
-Rule   sol88   1988    only    -       Oct     30      11:43:40s 0:16:20 -
-Rule   sol88   1988    only    -       Oct     31      11:43:40s 0:16:20 -
-Rule   sol88   1988    only    -       Nov     1       11:43:35s 0:16:25 -
-Rule   sol88   1988    only    -       Nov     2       11:43:35s 0:16:25 -
-Rule   sol88   1988    only    -       Nov     3       11:43:35s 0:16:25 -
-Rule   sol88   1988    only    -       Nov     4       11:43:35s 0:16:25 -
-Rule   sol88   1988    only    -       Nov     5       11:43:40s 0:16:20 -
-Rule   sol88   1988    only    -       Nov     6       11:43:40s 0:16:20 -
-Rule   sol88   1988    only    -       Nov     7       11:43:45s 0:16:15 -
-Rule   sol88   1988    only    -       Nov     8       11:43:45s 0:16:15 -
-Rule   sol88   1988    only    -       Nov     9       11:43:50s 0:16:10 -
-Rule   sol88   1988    only    -       Nov     10      11:44:00s 0:16:00 -
-Rule   sol88   1988    only    -       Nov     11      11:44:05s 0:15:55 -
-Rule   sol88   1988    only    -       Nov     12      11:44:10s 0:15:50 -
-Rule   sol88   1988    only    -       Nov     13      11:44:20s 0:15:40 -
-Rule   sol88   1988    only    -       Nov     14      11:44:30s 0:15:30 -
-Rule   sol88   1988    only    -       Nov     15      11:44:40s 0:15:20 -
-Rule   sol88   1988    only    -       Nov     16      11:44:50s 0:15:10 -
-Rule   sol88   1988    only    -       Nov     17      11:45:00s 0:15:00 -
-Rule   sol88   1988    only    -       Nov     18      11:45:15s 0:14:45 -
-Rule   sol88   1988    only    -       Nov     19      11:45:25s 0:14:35 -
-Rule   sol88   1988    only    -       Nov     20      11:45:40s 0:14:20 -
-Rule   sol88   1988    only    -       Nov     21      11:45:55s 0:14:05 -
-Rule   sol88   1988    only    -       Nov     22      11:46:10s 0:13:50 -
-Rule   sol88   1988    only    -       Nov     23      11:46:30s 0:13:30 -
-Rule   sol88   1988    only    -       Nov     24      11:46:45s 0:13:15 -
-Rule   sol88   1988    only    -       Nov     25      11:47:05s 0:12:55 -
-Rule   sol88   1988    only    -       Nov     26      11:47:20s 0:12:40 -
-Rule   sol88   1988    only    -       Nov     27      11:47:40s 0:12:20 -
-Rule   sol88   1988    only    -       Nov     28      11:48:00s 0:12:00 -
-Rule   sol88   1988    only    -       Nov     29      11:48:25s 0:11:35 -
-Rule   sol88   1988    only    -       Nov     30      11:48:45s 0:11:15 -
-Rule   sol88   1988    only    -       Dec     1       11:49:05s 0:10:55 -
-Rule   sol88   1988    only    -       Dec     2       11:49:30s 0:10:30 -
-Rule   sol88   1988    only    -       Dec     3       11:49:55s 0:10:05 -
-Rule   sol88   1988    only    -       Dec     4       11:50:15s 0:09:45 -
-Rule   sol88   1988    only    -       Dec     5       11:50:40s 0:09:20 -
-Rule   sol88   1988    only    -       Dec     6       11:51:05s 0:08:55 -
-Rule   sol88   1988    only    -       Dec     7       11:51:35s 0:08:25 -
-Rule   sol88   1988    only    -       Dec     8       11:52:00s 0:08:00 -
-Rule   sol88   1988    only    -       Dec     9       11:52:25s 0:07:35 -
-Rule   sol88   1988    only    -       Dec     10      11:52:55s 0:07:05 -
-Rule   sol88   1988    only    -       Dec     11      11:53:20s 0:06:40 -
-Rule   sol88   1988    only    -       Dec     12      11:53:50s 0:06:10 -
-Rule   sol88   1988    only    -       Dec     13      11:54:15s 0:05:45 -
-Rule   sol88   1988    only    -       Dec     14      11:54:45s 0:05:15 -
-Rule   sol88   1988    only    -       Dec     15      11:55:15s 0:04:45 -
-Rule   sol88   1988    only    -       Dec     16      11:55:45s 0:04:15 -
-Rule   sol88   1988    only    -       Dec     17      11:56:15s 0:03:45 -
-Rule   sol88   1988    only    -       Dec     18      11:56:40s 0:03:20 -
-Rule   sol88   1988    only    -       Dec     19      11:57:10s 0:02:50 -
-Rule   sol88   1988    only    -       Dec     20      11:57:40s 0:02:20 -
-Rule   sol88   1988    only    -       Dec     21      11:58:10s 0:01:50 -
-Rule   sol88   1988    only    -       Dec     22      11:58:40s 0:01:20 -
-Rule   sol88   1988    only    -       Dec     23      11:59:10s 0:00:50 -
-Rule   sol88   1988    only    -       Dec     24      11:59:40s 0:00:20 -
-Rule   sol88   1988    only    -       Dec     25      12:00:10s -0:00:10 -
-Rule   sol88   1988    only    -       Dec     26      12:00:40s -0:00:40 -
-Rule   sol88   1988    only    -       Dec     27      12:01:10s -0:01:10 -
-Rule   sol88   1988    only    -       Dec     28      12:01:40s -0:01:40 -
-Rule   sol88   1988    only    -       Dec     29      12:02:10s -0:02:10 -
-Rule   sol88   1988    only    -       Dec     30      12:02:35s -0:02:35 -
-Rule   sol88   1988    only    -       Dec     31      12:03:05s -0:03:05 -
-
-# Riyadh is at about 46 degrees 46 minutes East:  3 hrs, 7 mins, 4 secs
-# Before and after 1988, we'll operate on local mean solar time.
-
-# Zone NAME                    GMTOFF  RULES/SAVE      FORMAT  [UNTIL]
-Zone   Mideast/Riyadh88        3:07:04 -               ??      1988
-                               3:07:04 sol88           ??      1989
-                               3:07:04 -               ??
diff --git a/time/solar89 b/time/solar89
deleted file mode 100644 (file)
index 3221f97..0000000
+++ /dev/null
@@ -1,391 +0,0 @@
-# @(#)solar89  7.2
-
-# Apparent noon times below are for Riyadh; they're a bit off for other places.
-# Times were computed using a formula provided by the U. S. Naval Observatory:
-#      eqt = -105.8 * sin(l) + 596.2 * sin(2 * l) + 4.4 * sin(3 * l)
-#              -12.7 * sin(4 * l) - 429.0 * cos(l) - 2.1 * cos (2 * l)
-#              + 19.3 * cos(3 * l);
-# where l is the "mean longitude of the Sun" given by
-#      l = 279.642 degrees + 0.985647 * d
-# and d is the interval in days from January 0, 0 hours Universal Time
-# (equaling the day of the year plus the fraction of a day from zero hours).
-# The accuracy of the formula is plus or minus three seconds.
-#
-# Rounding to the nearest five seconds results in fewer than
-# 256 different "time types"--a limit that's faced because time types are
-# stored on disk as unsigned chars.
-
-# Rule NAME    FROM    TO      TYPE    IN      ON      AT      SAVE    LETTER/S
-Rule   sol89   1989    only    -       Jan     1       12:03:35s -0:03:35 -
-Rule   sol89   1989    only    -       Jan     2       12:04:05s -0:04:05 -
-Rule   sol89   1989    only    -       Jan     3       12:04:30s -0:04:30 -
-Rule   sol89   1989    only    -       Jan     4       12:05:00s -0:05:00 -
-Rule   sol89   1989    only    -       Jan     5       12:05:25s -0:05:25 -
-Rule   sol89   1989    only    -       Jan     6       12:05:50s -0:05:50 -
-Rule   sol89   1989    only    -       Jan     7       12:06:15s -0:06:15 -
-Rule   sol89   1989    only    -       Jan     8       12:06:45s -0:06:45 -
-Rule   sol89   1989    only    -       Jan     9       12:07:10s -0:07:10 -
-Rule   sol89   1989    only    -       Jan     10      12:07:35s -0:07:35 -
-Rule   sol89   1989    only    -       Jan     11      12:07:55s -0:07:55 -
-Rule   sol89   1989    only    -       Jan     12      12:08:20s -0:08:20 -
-Rule   sol89   1989    only    -       Jan     13      12:08:45s -0:08:45 -
-Rule   sol89   1989    only    -       Jan     14      12:09:05s -0:09:05 -
-Rule   sol89   1989    only    -       Jan     15      12:09:25s -0:09:25 -
-Rule   sol89   1989    only    -       Jan     16      12:09:45s -0:09:45 -
-Rule   sol89   1989    only    -       Jan     17      12:10:05s -0:10:05 -
-Rule   sol89   1989    only    -       Jan     18      12:10:25s -0:10:25 -
-Rule   sol89   1989    only    -       Jan     19      12:10:45s -0:10:45 -
-Rule   sol89   1989    only    -       Jan     20      12:11:05s -0:11:05 -
-Rule   sol89   1989    only    -       Jan     21      12:11:20s -0:11:20 -
-Rule   sol89   1989    only    -       Jan     22      12:11:35s -0:11:35 -
-Rule   sol89   1989    only    -       Jan     23      12:11:55s -0:11:55 -
-Rule   sol89   1989    only    -       Jan     24      12:12:10s -0:12:10 -
-Rule   sol89   1989    only    -       Jan     25      12:12:20s -0:12:20 -
-Rule   sol89   1989    only    -       Jan     26      12:12:35s -0:12:35 -
-Rule   sol89   1989    only    -       Jan     27      12:12:50s -0:12:50 -
-Rule   sol89   1989    only    -       Jan     28      12:13:00s -0:13:00 -
-Rule   sol89   1989    only    -       Jan     29      12:13:10s -0:13:10 -
-Rule   sol89   1989    only    -       Jan     30      12:13:20s -0:13:20 -
-Rule   sol89   1989    only    -       Jan     31      12:13:30s -0:13:30 -
-Rule   sol89   1989    only    -       Feb     1       12:13:40s -0:13:40 -
-Rule   sol89   1989    only    -       Feb     2       12:13:45s -0:13:45 -
-Rule   sol89   1989    only    -       Feb     3       12:13:55s -0:13:55 -
-Rule   sol89   1989    only    -       Feb     4       12:14:00s -0:14:00 -
-Rule   sol89   1989    only    -       Feb     5       12:14:05s -0:14:05 -
-Rule   sol89   1989    only    -       Feb     6       12:14:10s -0:14:10 -
-Rule   sol89   1989    only    -       Feb     7       12:14:10s -0:14:10 -
-Rule   sol89   1989    only    -       Feb     8       12:14:15s -0:14:15 -
-Rule   sol89   1989    only    -       Feb     9       12:14:15s -0:14:15 -
-Rule   sol89   1989    only    -       Feb     10      12:14:20s -0:14:20 -
-Rule   sol89   1989    only    -       Feb     11      12:14:20s -0:14:20 -
-Rule   sol89   1989    only    -       Feb     12      12:14:20s -0:14:20 -
-Rule   sol89   1989    only    -       Feb     13      12:14:15s -0:14:15 -
-Rule   sol89   1989    only    -       Feb     14      12:14:15s -0:14:15 -
-Rule   sol89   1989    only    -       Feb     15      12:14:10s -0:14:10 -
-Rule   sol89   1989    only    -       Feb     16      12:14:10s -0:14:10 -
-Rule   sol89   1989    only    -       Feb     17      12:14:05s -0:14:05 -
-Rule   sol89   1989    only    -       Feb     18      12:14:00s -0:14:00 -
-Rule   sol89   1989    only    -       Feb     19      12:13:55s -0:13:55 -
-Rule   sol89   1989    only    -       Feb     20      12:13:50s -0:13:50 -
-Rule   sol89   1989    only    -       Feb     21      12:13:40s -0:13:40 -
-Rule   sol89   1989    only    -       Feb     22      12:13:35s -0:13:35 -
-Rule   sol89   1989    only    -       Feb     23      12:13:25s -0:13:25 -
-Rule   sol89   1989    only    -       Feb     24      12:13:15s -0:13:15 -
-Rule   sol89   1989    only    -       Feb     25      12:13:05s -0:13:05 -
-Rule   sol89   1989    only    -       Feb     26      12:12:55s -0:12:55 -
-Rule   sol89   1989    only    -       Feb     27      12:12:45s -0:12:45 -
-Rule   sol89   1989    only    -       Feb     28      12:12:35s -0:12:35 -
-Rule   sol89   1989    only    -       Mar     1       12:12:25s -0:12:25 -
-Rule   sol89   1989    only    -       Mar     2       12:12:10s -0:12:10 -
-Rule   sol89   1989    only    -       Mar     3       12:12:00s -0:12:00 -
-Rule   sol89   1989    only    -       Mar     4       12:11:45s -0:11:45 -
-Rule   sol89   1989    only    -       Mar     5       12:11:35s -0:11:35 -
-Rule   sol89   1989    only    -       Mar     6       12:11:20s -0:11:20 -
-Rule   sol89   1989    only    -       Mar     7       12:11:05s -0:11:05 -
-Rule   sol89   1989    only    -       Mar     8       12:10:50s -0:10:50 -
-Rule   sol89   1989    only    -       Mar     9       12:10:35s -0:10:35 -
-Rule   sol89   1989    only    -       Mar     10      12:10:20s -0:10:20 -
-Rule   sol89   1989    only    -       Mar     11      12:10:05s -0:10:05 -
-Rule   sol89   1989    only    -       Mar     12      12:09:50s -0:09:50 -
-Rule   sol89   1989    only    -       Mar     13      12:09:30s -0:09:30 -
-Rule   sol89   1989    only    -       Mar     14      12:09:15s -0:09:15 -
-Rule   sol89   1989    only    -       Mar     15      12:09:00s -0:09:00 -
-Rule   sol89   1989    only    -       Mar     16      12:08:40s -0:08:40 -
-Rule   sol89   1989    only    -       Mar     17      12:08:25s -0:08:25 -
-Rule   sol89   1989    only    -       Mar     18      12:08:05s -0:08:05 -
-Rule   sol89   1989    only    -       Mar     19      12:07:50s -0:07:50 -
-Rule   sol89   1989    only    -       Mar     20      12:07:30s -0:07:30 -
-Rule   sol89   1989    only    -       Mar     21      12:07:15s -0:07:15 -
-Rule   sol89   1989    only    -       Mar     22      12:06:55s -0:06:55 -
-Rule   sol89   1989    only    -       Mar     23      12:06:35s -0:06:35 -
-Rule   sol89   1989    only    -       Mar     24      12:06:20s -0:06:20 -
-Rule   sol89   1989    only    -       Mar     25      12:06:00s -0:06:00 -
-Rule   sol89   1989    only    -       Mar     26      12:05:40s -0:05:40 -
-Rule   sol89   1989    only    -       Mar     27      12:05:25s -0:05:25 -
-Rule   sol89   1989    only    -       Mar     28      12:05:05s -0:05:05 -
-Rule   sol89   1989    only    -       Mar     29      12:04:50s -0:04:50 -
-Rule   sol89   1989    only    -       Mar     30      12:04:30s -0:04:30 -
-Rule   sol89   1989    only    -       Mar     31      12:04:10s -0:04:10 -
-Rule   sol89   1989    only    -       Apr     1       12:03:55s -0:03:55 -
-Rule   sol89   1989    only    -       Apr     2       12:03:35s -0:03:35 -
-Rule   sol89   1989    only    -       Apr     3       12:03:20s -0:03:20 -
-Rule   sol89   1989    only    -       Apr     4       12:03:00s -0:03:00 -
-Rule   sol89   1989    only    -       Apr     5       12:02:45s -0:02:45 -
-Rule   sol89   1989    only    -       Apr     6       12:02:25s -0:02:25 -
-Rule   sol89   1989    only    -       Apr     7       12:02:10s -0:02:10 -
-Rule   sol89   1989    only    -       Apr     8       12:01:50s -0:01:50 -
-Rule   sol89   1989    only    -       Apr     9       12:01:35s -0:01:35 -
-Rule   sol89   1989    only    -       Apr     10      12:01:20s -0:01:20 -
-Rule   sol89   1989    only    -       Apr     11      12:01:05s -0:01:05 -
-Rule   sol89   1989    only    -       Apr     12      12:00:50s -0:00:50 -
-Rule   sol89   1989    only    -       Apr     13      12:00:35s -0:00:35 -
-Rule   sol89   1989    only    -       Apr     14      12:00:20s -0:00:20 -
-Rule   sol89   1989    only    -       Apr     15      12:00:05s -0:00:05 -
-Rule   sol89   1989    only    -       Apr     16      11:59:50s 0:00:10 -
-Rule   sol89   1989    only    -       Apr     17      11:59:35s 0:00:25 -
-Rule   sol89   1989    only    -       Apr     18      11:59:20s 0:00:40 -
-Rule   sol89   1989    only    -       Apr     19      11:59:10s 0:00:50 -
-Rule   sol89   1989    only    -       Apr     20      11:58:55s 0:01:05 -
-Rule   sol89   1989    only    -       Apr     21      11:58:45s 0:01:15 -
-Rule   sol89   1989    only    -       Apr     22      11:58:30s 0:01:30 -
-Rule   sol89   1989    only    -       Apr     23      11:58:20s 0:01:40 -
-Rule   sol89   1989    only    -       Apr     24      11:58:10s 0:01:50 -
-Rule   sol89   1989    only    -       Apr     25      11:58:00s 0:02:00 -
-Rule   sol89   1989    only    -       Apr     26      11:57:50s 0:02:10 -
-Rule   sol89   1989    only    -       Apr     27      11:57:40s 0:02:20 -
-Rule   sol89   1989    only    -       Apr     28      11:57:30s 0:02:30 -
-Rule   sol89   1989    only    -       Apr     29      11:57:20s 0:02:40 -
-Rule   sol89   1989    only    -       Apr     30      11:57:15s 0:02:45 -
-Rule   sol89   1989    only    -       May     1       11:57:05s 0:02:55 -
-Rule   sol89   1989    only    -       May     2       11:57:00s 0:03:00 -
-Rule   sol89   1989    only    -       May     3       11:56:50s 0:03:10 -
-Rule   sol89   1989    only    -       May     4       11:56:45s 0:03:15 -
-Rule   sol89   1989    only    -       May     5       11:56:40s 0:03:20 -
-Rule   sol89   1989    only    -       May     6       11:56:35s 0:03:25 -
-Rule   sol89   1989    only    -       May     7       11:56:30s 0:03:30 -
-Rule   sol89   1989    only    -       May     8       11:56:30s 0:03:30 -
-Rule   sol89   1989    only    -       May     9       11:56:25s 0:03:35 -
-Rule   sol89   1989    only    -       May     10      11:56:25s 0:03:35 -
-Rule   sol89   1989    only    -       May     11      11:56:20s 0:03:40 -
-Rule   sol89   1989    only    -       May     12      11:56:20s 0:03:40 -
-Rule   sol89   1989    only    -       May     13      11:56:20s 0:03:40 -
-Rule   sol89   1989    only    -       May     14      11:56:20s 0:03:40 -
-Rule   sol89   1989    only    -       May     15      11:56:20s 0:03:40 -
-Rule   sol89   1989    only    -       May     16      11:56:20s 0:03:40 -
-Rule   sol89   1989    only    -       May     17      11:56:20s 0:03:40 -
-Rule   sol89   1989    only    -       May     18      11:56:25s 0:03:35 -
-Rule   sol89   1989    only    -       May     19      11:56:25s 0:03:35 -
-Rule   sol89   1989    only    -       May     20      11:56:30s 0:03:30 -
-Rule   sol89   1989    only    -       May     21      11:56:35s 0:03:25 -
-Rule   sol89   1989    only    -       May     22      11:56:35s 0:03:25 -
-Rule   sol89   1989    only    -       May     23      11:56:40s 0:03:20 -
-Rule   sol89   1989    only    -       May     24      11:56:45s 0:03:15 -
-Rule   sol89   1989    only    -       May     25      11:56:55s 0:03:05 -
-Rule   sol89   1989    only    -       May     26      11:57:00s 0:03:00 -
-Rule   sol89   1989    only    -       May     27      11:57:05s 0:02:55 -
-Rule   sol89   1989    only    -       May     28      11:57:15s 0:02:45 -
-Rule   sol89   1989    only    -       May     29      11:57:20s 0:02:40 -
-Rule   sol89   1989    only    -       May     30      11:57:30s 0:02:30 -
-Rule   sol89   1989    only    -       May     31      11:57:35s 0:02:25 -
-Rule   sol89   1989    only    -       Jun     1       11:57:45s 0:02:15 -
-Rule   sol89   1989    only    -       Jun     2       11:57:55s 0:02:05 -
-Rule   sol89   1989    only    -       Jun     3       11:58:05s 0:01:55 -
-Rule   sol89   1989    only    -       Jun     4       11:58:15s 0:01:45 -
-Rule   sol89   1989    only    -       Jun     5       11:58:25s 0:01:35 -
-Rule   sol89   1989    only    -       Jun     6       11:58:35s 0:01:25 -
-Rule   sol89   1989    only    -       Jun     7       11:58:45s 0:01:15 -
-Rule   sol89   1989    only    -       Jun     8       11:59:00s 0:01:00 -
-Rule   sol89   1989    only    -       Jun     9       11:59:10s 0:00:50 -
-Rule   sol89   1989    only    -       Jun     10      11:59:20s 0:00:40 -
-Rule   sol89   1989    only    -       Jun     11      11:59:35s 0:00:25 -
-Rule   sol89   1989    only    -       Jun     12      11:59:45s 0:00:15 -
-Rule   sol89   1989    only    -       Jun     13      12:00:00s 0:00:00 -
-Rule   sol89   1989    only    -       Jun     14      12:00:10s -0:00:10 -
-Rule   sol89   1989    only    -       Jun     15      12:00:25s -0:00:25 -
-Rule   sol89   1989    only    -       Jun     16      12:00:35s -0:00:35 -
-Rule   sol89   1989    only    -       Jun     17      12:00:50s -0:00:50 -
-Rule   sol89   1989    only    -       Jun     18      12:01:05s -0:01:05 -
-Rule   sol89   1989    only    -       Jun     19      12:01:15s -0:01:15 -
-Rule   sol89   1989    only    -       Jun     20      12:01:30s -0:01:30 -
-Rule   sol89   1989    only    -       Jun     21      12:01:40s -0:01:40 -
-Rule   sol89   1989    only    -       Jun     22      12:01:55s -0:01:55 -
-Rule   sol89   1989    only    -       Jun     23      12:02:10s -0:02:10 -
-Rule   sol89   1989    only    -       Jun     24      12:02:20s -0:02:20 -
-Rule   sol89   1989    only    -       Jun     25      12:02:35s -0:02:35 -
-Rule   sol89   1989    only    -       Jun     26      12:02:45s -0:02:45 -
-Rule   sol89   1989    only    -       Jun     27      12:03:00s -0:03:00 -
-Rule   sol89   1989    only    -       Jun     28      12:03:10s -0:03:10 -
-Rule   sol89   1989    only    -       Jun     29      12:03:25s -0:03:25 -
-Rule   sol89   1989    only    -       Jun     30      12:03:35s -0:03:35 -
-Rule   sol89   1989    only    -       Jul     1       12:03:45s -0:03:45 -
-Rule   sol89   1989    only    -       Jul     2       12:04:00s -0:04:00 -
-Rule   sol89   1989    only    -       Jul     3       12:04:10s -0:04:10 -
-Rule   sol89   1989    only    -       Jul     4       12:04:20s -0:04:20 -
-Rule   sol89   1989    only    -       Jul     5       12:04:30s -0:04:30 -
-Rule   sol89   1989    only    -       Jul     6       12:04:40s -0:04:40 -
-Rule   sol89   1989    only    -       Jul     7       12:04:50s -0:04:50 -
-Rule   sol89   1989    only    -       Jul     8       12:05:00s -0:05:00 -
-Rule   sol89   1989    only    -       Jul     9       12:05:10s -0:05:10 -
-Rule   sol89   1989    only    -       Jul     10      12:05:20s -0:05:20 -
-Rule   sol89   1989    only    -       Jul     11      12:05:25s -0:05:25 -
-Rule   sol89   1989    only    -       Jul     12      12:05:35s -0:05:35 -
-Rule   sol89   1989    only    -       Jul     13      12:05:40s -0:05:40 -
-Rule   sol89   1989    only    -       Jul     14      12:05:50s -0:05:50 -
-Rule   sol89   1989    only    -       Jul     15      12:05:55s -0:05:55 -
-Rule   sol89   1989    only    -       Jul     16      12:06:00s -0:06:00 -
-Rule   sol89   1989    only    -       Jul     17      12:06:05s -0:06:05 -
-Rule   sol89   1989    only    -       Jul     18      12:06:10s -0:06:10 -
-Rule   sol89   1989    only    -       Jul     19      12:06:15s -0:06:15 -
-Rule   sol89   1989    only    -       Jul     20      12:06:20s -0:06:20 -
-Rule   sol89   1989    only    -       Jul     21      12:06:20s -0:06:20 -
-Rule   sol89   1989    only    -       Jul     22      12:06:25s -0:06:25 -
-Rule   sol89   1989    only    -       Jul     23      12:06:25s -0:06:25 -
-Rule   sol89   1989    only    -       Jul     24      12:06:30s -0:06:30 -
-Rule   sol89   1989    only    -       Jul     25      12:06:30s -0:06:30 -
-Rule   sol89   1989    only    -       Jul     26      12:06:30s -0:06:30 -
-Rule   sol89   1989    only    -       Jul     27      12:06:30s -0:06:30 -
-Rule   sol89   1989    only    -       Jul     28      12:06:30s -0:06:30 -
-Rule   sol89   1989    only    -       Jul     29      12:06:25s -0:06:25 -
-Rule   sol89   1989    only    -       Jul     30      12:06:25s -0:06:25 -
-Rule   sol89   1989    only    -       Jul     31      12:06:20s -0:06:20 -
-Rule   sol89   1989    only    -       Aug     1       12:06:20s -0:06:20 -
-Rule   sol89   1989    only    -       Aug     2       12:06:15s -0:06:15 -
-Rule   sol89   1989    only    -       Aug     3       12:06:10s -0:06:10 -
-Rule   sol89   1989    only    -       Aug     4       12:06:05s -0:06:05 -
-Rule   sol89   1989    only    -       Aug     5       12:06:00s -0:06:00 -
-Rule   sol89   1989    only    -       Aug     6       12:05:50s -0:05:50 -
-Rule   sol89   1989    only    -       Aug     7       12:05:45s -0:05:45 -
-Rule   sol89   1989    only    -       Aug     8       12:05:35s -0:05:35 -
-Rule   sol89   1989    only    -       Aug     9       12:05:30s -0:05:30 -
-Rule   sol89   1989    only    -       Aug     10      12:05:20s -0:05:20 -
-Rule   sol89   1989    only    -       Aug     11      12:05:10s -0:05:10 -
-Rule   sol89   1989    only    -       Aug     12      12:05:00s -0:05:00 -
-Rule   sol89   1989    only    -       Aug     13      12:04:50s -0:04:50 -
-Rule   sol89   1989    only    -       Aug     14      12:04:40s -0:04:40 -
-Rule   sol89   1989    only    -       Aug     15      12:04:30s -0:04:30 -
-Rule   sol89   1989    only    -       Aug     16      12:04:15s -0:04:15 -
-Rule   sol89   1989    only    -       Aug     17      12:04:05s -0:04:05 -
-Rule   sol89   1989    only    -       Aug     18      12:03:50s -0:03:50 -
-Rule   sol89   1989    only    -       Aug     19      12:03:35s -0:03:35 -
-Rule   sol89   1989    only    -       Aug     20      12:03:25s -0:03:25 -
-Rule   sol89   1989    only    -       Aug     21      12:03:10s -0:03:10 -
-Rule   sol89   1989    only    -       Aug     22      12:02:55s -0:02:55 -
-Rule   sol89   1989    only    -       Aug     23      12:02:40s -0:02:40 -
-Rule   sol89   1989    only    -       Aug     24      12:02:20s -0:02:20 -
-Rule   sol89   1989    only    -       Aug     25      12:02:05s -0:02:05 -
-Rule   sol89   1989    only    -       Aug     26      12:01:50s -0:01:50 -
-Rule   sol89   1989    only    -       Aug     27      12:01:30s -0:01:30 -
-Rule   sol89   1989    only    -       Aug     28      12:01:15s -0:01:15 -
-Rule   sol89   1989    only    -       Aug     29      12:00:55s -0:00:55 -
-Rule   sol89   1989    only    -       Aug     30      12:00:40s -0:00:40 -
-Rule   sol89   1989    only    -       Aug     31      12:00:20s -0:00:20 -
-Rule   sol89   1989    only    -       Sep     1       12:00:00s 0:00:00 -
-Rule   sol89   1989    only    -       Sep     2       11:59:45s 0:00:15 -
-Rule   sol89   1989    only    -       Sep     3       11:59:25s 0:00:35 -
-Rule   sol89   1989    only    -       Sep     4       11:59:05s 0:00:55 -
-Rule   sol89   1989    only    -       Sep     5       11:58:45s 0:01:15 -
-Rule   sol89   1989    only    -       Sep     6       11:58:25s 0:01:35 -
-Rule   sol89   1989    only    -       Sep     7       11:58:05s 0:01:55 -
-Rule   sol89   1989    only    -       Sep     8       11:57:45s 0:02:15 -
-Rule   sol89   1989    only    -       Sep     9       11:57:20s 0:02:40 -
-Rule   sol89   1989    only    -       Sep     10      11:57:00s 0:03:00 -
-Rule   sol89   1989    only    -       Sep     11      11:56:40s 0:03:20 -
-Rule   sol89   1989    only    -       Sep     12      11:56:20s 0:03:40 -
-Rule   sol89   1989    only    -       Sep     13      11:56:00s 0:04:00 -
-Rule   sol89   1989    only    -       Sep     14      11:55:35s 0:04:25 -
-Rule   sol89   1989    only    -       Sep     15      11:55:15s 0:04:45 -
-Rule   sol89   1989    only    -       Sep     16      11:54:55s 0:05:05 -
-Rule   sol89   1989    only    -       Sep     17      11:54:35s 0:05:25 -
-Rule   sol89   1989    only    -       Sep     18      11:54:10s 0:05:50 -
-Rule   sol89   1989    only    -       Sep     19      11:53:50s 0:06:10 -
-Rule   sol89   1989    only    -       Sep     20      11:53:30s 0:06:30 -
-Rule   sol89   1989    only    -       Sep     21      11:53:10s 0:06:50 -
-Rule   sol89   1989    only    -       Sep     22      11:52:45s 0:07:15 -
-Rule   sol89   1989    only    -       Sep     23      11:52:25s 0:07:35 -
-Rule   sol89   1989    only    -       Sep     24      11:52:05s 0:07:55 -
-Rule   sol89   1989    only    -       Sep     25      11:51:45s 0:08:15 -
-Rule   sol89   1989    only    -       Sep     26      11:51:25s 0:08:35 -
-Rule   sol89   1989    only    -       Sep     27      11:51:05s 0:08:55 -
-Rule   sol89   1989    only    -       Sep     28      11:50:40s 0:09:20 -
-Rule   sol89   1989    only    -       Sep     29      11:50:20s 0:09:40 -
-Rule   sol89   1989    only    -       Sep     30      11:50:00s 0:10:00 -
-Rule   sol89   1989    only    -       Oct     1       11:49:45s 0:10:15 -
-Rule   sol89   1989    only    -       Oct     2       11:49:25s 0:10:35 -
-Rule   sol89   1989    only    -       Oct     3       11:49:05s 0:10:55 -
-Rule   sol89   1989    only    -       Oct     4       11:48:45s 0:11:15 -
-Rule   sol89   1989    only    -       Oct     5       11:48:30s 0:11:30 -
-Rule   sol89   1989    only    -       Oct     6       11:48:10s 0:11:50 -
-Rule   sol89   1989    only    -       Oct     7       11:47:50s 0:12:10 -
-Rule   sol89   1989    only    -       Oct     8       11:47:35s 0:12:25 -
-Rule   sol89   1989    only    -       Oct     9       11:47:20s 0:12:40 -
-Rule   sol89   1989    only    -       Oct     10      11:47:00s 0:13:00 -
-Rule   sol89   1989    only    -       Oct     11      11:46:45s 0:13:15 -
-Rule   sol89   1989    only    -       Oct     12      11:46:30s 0:13:30 -
-Rule   sol89   1989    only    -       Oct     13      11:46:15s 0:13:45 -
-Rule   sol89   1989    only    -       Oct     14      11:46:00s 0:14:00 -
-Rule   sol89   1989    only    -       Oct     15      11:45:50s 0:14:10 -
-Rule   sol89   1989    only    -       Oct     16      11:45:35s 0:14:25 -
-Rule   sol89   1989    only    -       Oct     17      11:45:20s 0:14:40 -
-Rule   sol89   1989    only    -       Oct     18      11:45:10s 0:14:50 -
-Rule   sol89   1989    only    -       Oct     19      11:45:00s 0:15:00 -
-Rule   sol89   1989    only    -       Oct     20      11:44:50s 0:15:10 -
-Rule   sol89   1989    only    -       Oct     21      11:44:40s 0:15:20 -
-Rule   sol89   1989    only    -       Oct     22      11:44:30s 0:15:30 -
-Rule   sol89   1989    only    -       Oct     23      11:44:20s 0:15:40 -
-Rule   sol89   1989    only    -       Oct     24      11:44:10s 0:15:50 -
-Rule   sol89   1989    only    -       Oct     25      11:44:05s 0:15:55 -
-Rule   sol89   1989    only    -       Oct     26      11:44:00s 0:16:00 -
-Rule   sol89   1989    only    -       Oct     27      11:43:50s 0:16:10 -
-Rule   sol89   1989    only    -       Oct     28      11:43:45s 0:16:15 -
-Rule   sol89   1989    only    -       Oct     29      11:43:40s 0:16:20 -
-Rule   sol89   1989    only    -       Oct     30      11:43:40s 0:16:20 -
-Rule   sol89   1989    only    -       Oct     31      11:43:35s 0:16:25 -
-Rule   sol89   1989    only    -       Nov     1       11:43:35s 0:16:25 -
-Rule   sol89   1989    only    -       Nov     2       11:43:35s 0:16:25 -
-Rule   sol89   1989    only    -       Nov     3       11:43:30s 0:16:30 -
-Rule   sol89   1989    only    -       Nov     4       11:43:35s 0:16:25 -
-Rule   sol89   1989    only    -       Nov     5       11:43:35s 0:16:25 -
-Rule   sol89   1989    only    -       Nov     6       11:43:35s 0:16:25 -
-Rule   sol89   1989    only    -       Nov     7       11:43:40s 0:16:20 -
-Rule   sol89   1989    only    -       Nov     8       11:43:45s 0:16:15 -
-Rule   sol89   1989    only    -       Nov     9       11:43:50s 0:16:10 -
-Rule   sol89   1989    only    -       Nov     10      11:43:55s 0:16:05 -
-Rule   sol89   1989    only    -       Nov     11      11:44:00s 0:16:00 -
-Rule   sol89   1989    only    -       Nov     12      11:44:05s 0:15:55 -
-Rule   sol89   1989    only    -       Nov     13      11:44:15s 0:15:45 -
-Rule   sol89   1989    only    -       Nov     14      11:44:25s 0:15:35 -
-Rule   sol89   1989    only    -       Nov     15      11:44:35s 0:15:25 -
-Rule   sol89   1989    only    -       Nov     16      11:44:45s 0:15:15 -
-Rule   sol89   1989    only    -       Nov     17      11:44:55s 0:15:05 -
-Rule   sol89   1989    only    -       Nov     18      11:45:10s 0:14:50 -
-Rule   sol89   1989    only    -       Nov     19      11:45:20s 0:14:40 -
-Rule   sol89   1989    only    -       Nov     20      11:45:35s 0:14:25 -
-Rule   sol89   1989    only    -       Nov     21      11:45:50s 0:14:10 -
-Rule   sol89   1989    only    -       Nov     22      11:46:05s 0:13:55 -
-Rule   sol89   1989    only    -       Nov     23      11:46:25s 0:13:35 -
-Rule   sol89   1989    only    -       Nov     24      11:46:40s 0:13:20 -
-Rule   sol89   1989    only    -       Nov     25      11:47:00s 0:13:00 -
-Rule   sol89   1989    only    -       Nov     26      11:47:20s 0:12:40 -
-Rule   sol89   1989    only    -       Nov     27      11:47:35s 0:12:25 -
-Rule   sol89   1989    only    -       Nov     28      11:47:55s 0:12:05 -
-Rule   sol89   1989    only    -       Nov     29      11:48:20s 0:11:40 -
-Rule   sol89   1989    only    -       Nov     30      11:48:40s 0:11:20 -
-Rule   sol89   1989    only    -       Dec     1       11:49:00s 0:11:00 -
-Rule   sol89   1989    only    -       Dec     2       11:49:25s 0:10:35 -
-Rule   sol89   1989    only    -       Dec     3       11:49:50s 0:10:10 -
-Rule   sol89   1989    only    -       Dec     4       11:50:15s 0:09:45 -
-Rule   sol89   1989    only    -       Dec     5       11:50:35s 0:09:25 -
-Rule   sol89   1989    only    -       Dec     6       11:51:00s 0:09:00 -
-Rule   sol89   1989    only    -       Dec     7       11:51:30s 0:08:30 -
-Rule   sol89   1989    only    -       Dec     8       11:51:55s 0:08:05 -
-Rule   sol89   1989    only    -       Dec     9       11:52:20s 0:07:40 -
-Rule   sol89   1989    only    -       Dec     10      11:52:50s 0:07:10 -
-Rule   sol89   1989    only    -       Dec     11      11:53:15s 0:06:45 -
-Rule   sol89   1989    only    -       Dec     12      11:53:45s 0:06:15 -
-Rule   sol89   1989    only    -       Dec     13      11:54:10s 0:05:50 -
-Rule   sol89   1989    only    -       Dec     14      11:54:40s 0:05:20 -
-Rule   sol89   1989    only    -       Dec     15      11:55:10s 0:04:50 -
-Rule   sol89   1989    only    -       Dec     16      11:55:40s 0:04:20 -
-Rule   sol89   1989    only    -       Dec     17      11:56:05s 0:03:55 -
-Rule   sol89   1989    only    -       Dec     18      11:56:35s 0:03:25 -
-Rule   sol89   1989    only    -       Dec     19      11:57:05s 0:02:55 -
-Rule   sol89   1989    only    -       Dec     20      11:57:35s 0:02:25 -
-Rule   sol89   1989    only    -       Dec     21      11:58:05s 0:01:55 -
-Rule   sol89   1989    only    -       Dec     22      11:58:35s 0:01:25 -
-Rule   sol89   1989    only    -       Dec     23      11:59:05s 0:00:55 -
-Rule   sol89   1989    only    -       Dec     24      11:59:35s 0:00:25 -
-Rule   sol89   1989    only    -       Dec     25      12:00:05s -0:00:05 -
-Rule   sol89   1989    only    -       Dec     26      12:00:35s -0:00:35 -
-Rule   sol89   1989    only    -       Dec     27      12:01:05s -0:01:05 -
-Rule   sol89   1989    only    -       Dec     28      12:01:35s -0:01:35 -
-Rule   sol89   1989    only    -       Dec     29      12:02:00s -0:02:00 -
-Rule   sol89   1989    only    -       Dec     30      12:02:30s -0:02:30 -
-Rule   sol89   1989    only    -       Dec     31      12:03:00s -0:03:00 -
-
-# Riyadh is at about 46 degrees 46 minutes East:  3 hrs, 7 mins, 4 secs
-# Before and after 1989, we'll operate on local mean solar time.
-
-# Zone NAME                    GMTOFF  RULES/SAVE      FORMAT  [UNTIL]
-Zone   Mideast/Riyadh89        3:07:04 -               ??      1989
-                               3:07:04 sol89           ??      1990
-                               3:07:04 -               ??
diff --git a/time/southamerica b/time/southamerica
deleted file mode 100644 (file)
index b40ce55..0000000
+++ /dev/null
@@ -1,397 +0,0 @@
-# @(#)southamerica     7.6
-
-# This data is by no means authoritative; if you think you know better,
-# go ahead and edit the file (and please send any changes to
-# tz@elsie.nci.nih.gov for general use in the future).
-
-# From Paul Eggert <eggert@twinsun.com> (November 18, 1993):
-# A good source for time zone historical data outside the U.S. is
-# Thomas G. Shanks, The International Atlas (3rd edition),
-# San Diego: ACS Publications, Inc. (1991).
-# Except where otherwise noted, it is the source for the data below.
-#
-# I invented the abbreviations marked `*' in the following table;
-# the rest are from earlier versions of this file, or from other sources.
-# Some of these are just plausible excuses for common English abbreviations.
-# Corrections are welcome!
-#              std dst
-#              LMT     Local Mean Time
-#      -2:00   FST FDT Fernando de Noronha
-#      -3:00   EST EDT Eastern South America (conflicts with -5:00)
-#      -4:00   AST ADT Andes*, Antilles*, Asuncion*, Atlantic
-#      -4:00   CST CDT Chile (conflicts with -6:00)
-#      -4:00   WST WDT Western Brazil
-#      -5:00   AST ADT Acre (conflicts with -4:00)
-#      -5:00   EST EDT Eastern, Ecuador*
-#      -6:00   CST CDT Archipelago of Columbus*, Central
-#      -7:00   MST MDT Mataveri*, Mountain
-#
-# See the `africa' file for Zone naming conventions.
-
-# From Guy Harris:
-# From Official Airline Guide - Worldwide Edition (1987).  Countries not
-# listed here do not observe DST, according to the OAG.  Time zone names
-# are pure inventions, and none are supplied for countries not observing
-# DST; updates from natives would be appreciated.  The times that DST
-# starts and ends are based on the assumption that they switch a 2AM just
-# as everybody else does.
-
-###############################################################################
-
-###############################################################################
-
-# Argentina
-
-# From Bob Devine (January 28, 1988):
-# Argentina: first Sunday in October to first Sunday in April since 1976.
-# Double Summer time from 1969 to 1974.  Switches at midnight.
-
-# From U. S. Naval Observatory (January 19, 19889):
-# ARGENTINA           3 H BEHIND   UTC
-
-# Rule NAME    FROM    TO      TYPE    IN      ON      AT      SAVE    LETTER/S
-Rule   Arg     1930    only    -       Dec      1      0:00    1:00    D
-Rule   Arg     1931    only    -       Apr      1      0:00    0       S
-Rule   Arg     1931    only    -       Oct     15      0:00    1:00    D
-Rule   Arg     1932    1940    -       Mar      1      0:00    0       S
-Rule   Arg     1932    1939    -       Nov      1      0:00    1:00    D
-Rule   Arg     1940    only    -       Jul      1      0:00    1:00    D
-Rule   Arg     1941    only    -       Jun     15      0:00    0       S
-Rule   Arg     1941    only    -       Oct     15      0:00    1:00    D
-Rule   Arg     1943    only    -       Aug      1      0:00    0       S
-Rule   Arg     1943    only    -       Oct     15      0:00    1:00    D
-Rule   Arg     1946    only    -       Mar      1      0:00    0       S
-Rule   Arg     1946    only    -       Oct      1      0:00    1:00    D
-Rule   Arg     1963    only    -       Oct      1      0:00    0       S
-Rule   Arg     1963    only    -       Dec     15      0:00    1:00    D
-Rule   Arg     1964    1966    -       Mar      1      0:00    0       S
-Rule   Arg     1964    1966    -       Oct     15      0:00    1:00    D
-Rule   Arg     1967    only    -       Apr      1      0:00    0       S
-Rule   Arg     1967    1968    -       Oct     Sun<=7  0:00    1:00    D
-Rule   Arg     1968    1969    -       Apr     Sun<=7  0:00    0       S
-Rule   Arg     1974    only    -       Jan     23      0:00    1:00    D
-Rule   Arg     1974    only    -       May      1      0:00    0       S
-Rule   Arg     1974    1976    -       Oct     Sun<=7  0:00    1:00    D
-Rule   Arg     1975    1977    -       Apr     Sun<=7  0:00    0       S
-Rule   Arg     1985    only    -       Nov      2      0:00    1:00    D
-Rule   Arg     1986    only    -       Mar     14      0:00    0       S
-Rule   Arg     1986    1987    -       Oct     25      0:00    1:00    D
-Rule   Arg     1987    only    -       Feb     13      0:00    0       S
-Rule   Arg     1988    only    -       Feb      7      0:00    0       S
-Rule   Arg     1988    only    -       Dec      1      0:00    1:00    D
-Rule   Arg     1989    only    -       Mar     16      0:00    0       S
-Rule   Arg     1989    only    -       Oct     15      0:00    1:00    D
-Rule   Arg     1990    only    -       Mar      4      0:00    0       S
-# _The Economist_ (8 Jan 1994, p 42) reports that Argentina
-# had DST in 1991-2 and 1992-3, but not in 1990-1 or in 1993-4.
-# It has something to do with electricity companies meeting demand in summer.
-# We don't know the 1991-3 transition times, unfortunately.
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone America/Buenos_Aires -3:53:48 -   LMT     1894 Nov
-                       -4:17   -       CMT     1920 May    # Cordoba Mean Time
-                       -4:00   -       AST     1930 Dec
-                       -4:00   Arg     A%sT    1969 Oct 5
-                       -3:00   Arg     E%sT
-
-# Bolivia
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   America/La_Paz  -4:32:36 -      LMT     1890
-                       -4:33   -       LPMT    1931 Oct 15 # La Paz Mean Time
-                       -4:33   1:00    LPDT    1932 Mar 21
-                       -4:00   -       AST
-
-# Brazil
-
-# From Guy Harris:
-# The OAG lists October 25, 1987 and February 12, 1988 as the starting and
-# ending dates, giving them as "estimated date(s) based on previous year".  We
-# infer a rule here from one example, always a dangerous practice....  Yes,
-# they really do switch on Saturday, according to the OAG.
-# "Brazil/Acre" is for the Territory of Acre; "Brazil/DeNoronha" is for
-# Fernando De Noronha.
-
-# From Bob Devine (January 28, 1988):
-# The only information I found is that there was no DST up to 1985.
-# But there was some before 1952!
-
-# From U. S. Naval Observatory (January 16, 1989):
-# BRAZIL     WEST     5 H  BEHIND UTC    TERRITORY OF ACRE
-# BRAZIL     WEST     4 H  BEHIND UTC    ACRE OCT 23, '88-FEB 11,
-# BRAZIL                                 '89 (ESTIMATED)
-# BRAZIL     CENTRAL  4 H  BEHIND UTC    MANAUS
-# BRAZIL     CENTRAL  3 H  BEHIND UTC    MANAUS OCT 23, '88-FEB 11,
-# BRAZIL     CENTRAL                     '89 (ESTIMATED)
-# BRAZIL     EAST     3 H  BEHIND UTC    COASTAL STATES, RIO, SAO
-# BRAZIL     EAST                        PAULO, BRASILIA
-# BRAZIL     EAST     2 H  BEHIND UTC    COASTAL STATES, RIO, SAO
-# BRAZIL                                 PAULO, BRASILIA OCT 23,
-# BRAZIL                                 '88-FEB 11, '89
-# BRAZIL                                 (ESTIMATED)
-# BRAZIL              2 H  BEHIND UTC    ATLANTIC ISLANDS, FERNANDO
-# BRAZIL                                 DE NORONHA
-# BRAZIL              1 H  BEHIND UTC    OCT 23, '88-FEB 11, '89
-# BRAZIL                                 (ESTIMATED)
-# BRAZIL              3 H  BEHIND UTC    FOR MOST MAJOR AIRPORTS.
-
-# From Paul Eggert <eggert@twinsun.com> (November 18, 1993):
-# The mayor of Rio recently attempted to change the time zone rules
-# just in his city, in order to leave more summer time for the tourist trade.
-# The rule change lasted only part of the day;
-# the federal government refused to follow the city's rules, and business
-# was in a chaos, so the mayor backed down that afternoon.
-# Shanks claims Acre stopped observing DST after 1988 Feb 7, but it
-# could just be that his table ran out of room.  We're extrapolating
-# about time zone changes after 1990 Feb 11.
-
-# Rule NAME    FROM    TO      TYPE    IN      ON      AT      SAVE    LETTER/S
-Rule   Brazil  1914    only    -       Jan      1       0:00   0       S
-Rule   Brazil  1931    only    -       Oct      3      11:00   1       D
-Rule   Brazil  1932    1933    -       Apr      1       0:00   0       S
-Rule   Brazil  1932    only    -       Oct      3       0:00   1       D
-Rule   Brazil  1949    1952    -       Dec      1       0:00   1       D
-Rule   Brazil  1950    only    -       Apr     16       0:00   0       S
-Rule   Brazil  1951    1953    -       Apr      1       0:00   0       S
-Rule   Brazil  1963    only    -       Dec      9       0:00   1       D
-Rule   Brazil  1964    only    -       Mar      1       0:00   0       S
-Rule   Brazil  1965    only    -       Jan     31       0:00   1       D
-Rule   Brazil  1965    only    -       Apr      1       0:00   0       S
-Rule   Brazil  1965    only    -       Dec      1       0:00   1       D
-Rule   Brazil  1966    1968    -       Mar      1       0:00   0       S
-Rule   Brazil  1966    1967    -       Nov      1       0:00   1       D
-Rule   Brazil  1985    only    -       Nov      2       0:00   1       D
-Rule   Brazil  1986    only    -       Mar     15       0:00   0       S
-Rule   Brazil  1986    1987    -       Oct     Sat<=28  0:00   1       D
-Rule   Brazil  1987    only    -       Feb     14       0:00   0       S
-Rule   Brazil  1988    only    -       Feb      7       0:00   0       S
-Rule   Brazil  1989    only    -       Jan     22       0:00   0       S
-Rule   Brazil  1988    max     -       Oct     Sun>=15  0:00   1       D
-Rule   Brazil  1990    max     -       Feb     Sun>=8   0:00   0       S
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone America/Noronha   -2:09:40 -      LMT     1914
-                       -2:00   -       FST     1963 Dec 9
-                       -2:00   Brazil  F%sT
-Zone America/Sao_Paulo -3:06:28 -      LMT     1914
-                       -3:00   Brazil  E%sT
-Zone America/Manaus    -4:00:04 -      LMT     1914
-                       -4:00   -       WST     1963 Dec 9
-                       -4:00   Brazil  W%sT
-# Rio_Branco is too ambiguous, since there's a Rio Branco in Uruguay too.
-Zone America/Porto_Acre        -4:31:12 -      LMT     1914
-                       -5:00   -       AST     1963 Dec 9
-                       -5:00   Brazil  A%sT
-#
-# Martin Vaz and Trinidade are like America/Noronha.
-
-
-# Chile
-
-# From Guy Harris:
-# The OAG lists October 11, 1987 and March 12, 1988 as the starting and
-# ending dates, giving them as "estimated date(s) based on previous year."
-
-# From Bob Devine (January 28, 1988):
-# Chile has had 2nd Sunday in October to 2nd Sunday in March DST since 1977.
-# Switch is at midnight. OAG is right.
-
-# Rule NAME    FROM    TO      TYPE    IN      ON      AT      SAVE    LETTER/S
-Rule   Chile   1918    only    -       Sep     1       0:00    1:00    D
-Rule   Chile   1919    only    -       Jul     2       0:00    0       S
-Rule   Chile   1927    1931    -       Sep     1       0:00    1:00    D
-Rule   Chile   1928    1932    -       Apr     1       0:00    0       S
-Rule   Chile   1969    max     -       Oct     Sun>=8  0:00    1:00    D
-Rule   Chile   1970    max     -       Mar     Sun>=8  0:00    0       S
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone America/Santiago  -4:42:40 -      LMT     1890
-                       -4:43   -       SMT     1910        # Santiago Mean Time
-                       -5:00   Chile   C%sT    1932 Sep
-                       -4:00   Chile   C%sT
-Zone Pacific/Easter    -7:17:28 -      LMT     1890        # Mataveri
-                       -7:17   -       MMT     1932 Sep    # Mataveri Mean Time
-                       -7:00   Chile   M%sT    1982 Mar 14
-                       -6:00   Chile   C%sT
-#
-# Whitman says Juan Fernandez Is are like America/Santiago.
-# San Ambrosio, San Felix
-# no information; probably like America/Santiago
-
-
-# Colombia
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   America/Bogota  -4:56:20 -      LMT     1884 Mar 13
-                       -4:56   -       BMT     1914 Nov 23 # Bogota Mean Time
-                       -5:00   -       EST
-# Malpelo, Providencia, San Andres
-# no information; probably like America/Bogota
-
-# Curacao
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   America/Curacao -4:35:44 -      LMT     1912 Feb 12     # Willemstad
-                       -4:30   -       NAST    1965    # Netherlands Antilles
-                       -4:00   -       AST
-
-# Ecuador
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone America/Guayaquil -5:19:20 -      LMT     1890
-                       -5:14   -       QMT     1931 # Quito Mean Time
-                       -5:00   -       EST
-Zone Pacific/Galapagos -5:58:24 -      LMT     1931 # Puerto Baquerizo Moreno
-                       -5:00   -       EST     1986
-                       -6:00   -       CST
-
-# Falklands
-# Rule NAME    FROM    TO      TYPE    IN      ON      AT      SAVE    LETTER/S
-Rule   Falk    1912    only    -       Mar     12      0:00    0       S
-Rule   Falk    1937    1938    -       Sep     lastSun 0:00    1:00    D
-Rule   Falk    1938    1942    -       Mar     Sun>=19 0:00    0       S
-Rule   Falk    1939    only    -       Oct     1       0:00    1:00    D
-Rule   Falk    1940    1942    -       Sep     lastSun 0:00    1:00    D
-Rule   Falk    1943    only    -       Jan     1       0:00    0       S
-Rule   Falk    1983    only    -       Sep     lastSun 0:00    1:00    D
-Rule   Falk    1984    1985    -       Apr     lastSun 0:00    0       S
-Rule   Falk    1984    only    -       Sep     16      0:00    1:00    D
-Rule   Falk    1985    max     -       Sep     Sun>=9  0:00    1:00    D
-Rule   Falk    1986    max     -       Apr     Sun>=16 0:00    0       S
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone Atlantic/Stanley  -3:51:24 -      LMT     1890
-                       -3:51   -       SMT     1912 Mar 12  # Stanley Mean Time
-                       -4:00   Falk    A%sT    1983 May
-                       -3:00   Falk    E%sT    1985 Sep 15
-                       -4:00   Falk    A%sT
-
-# French Guiana
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone America/Cayenne   -3:29:20 -      LMT     1911 Jul
-                       -4:00   -       AST     1967 Oct
-                       -3:00   -       EST
-
-# Guyana
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   America/Guyana  -3:52:40 -      LMT     1915 Mar        # Georgetown
-                       -3:45   -       BGST    1975 Jul 31  # British Guiana ST
-                       -3:00   -       EST
-
-
-# Paraguay
-
-# From Bob Devine (January 28, 1988):
-# Paraguay: First day in October to last in March.  Midnight switch??
-# Since 1980.
-
-# From U. S. Naval Observatory (January 19, 1989):
-# PARAGUAY            4 H  BEHIND UTC
-# PARAGUAY            3 H  BEHIND UTC    OCT 1, '88-MAR 31, '89
-
-# From Shanks (1991):
-# Rule NAME    FROM    TO      TYPE    IN      ON      AT      SAVE    LETTER/S
-Rule   Para    1974    only    -       Apr      1      0:00    0       S
-Rule   Para    1975    1978    -       Oct      1      0:00    1:00    D
-Rule   Para    1975    1978    -       Mar      1      0:00    0       S
-# Shanks says 1979 was all DST.
-Rule   Para    1980    max     -       Apr      1      0:00    0       S
-Rule   Para    1980    1988    -       Oct      1      0:00    1:00    D
-Rule   Para    1989    only    -       Oct     22      0:00    1:00    D
-Rule   Para    1990    max     -       Oct      1      0:00    1:00    D
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone America/Asuncion  -3:50:40 -      LMT     1890
-                       -3:51   -       AMT     1931 Oct 10 # Asuncion Mean Time
-                       -4:00   -       AST     1972 Oct
-                       -3:00   -       EST     1974 Apr
-                       -4:00   Para    A%sT
-
-# Peru
-# Rule NAME    FROM    TO      TYPE    IN      ON      AT      SAVE    LETTER/S
-Rule   Peru    1908    only    -       Jul     28      0:00    0       S
-Rule   Peru    1938    only    -       Jan      1      0:00    1:00    D
-Rule   Peru    1938    only    -       Apr      1      0:00    0       S
-Rule   Peru    1938    1939    -       Sep     lastSun 0:00    1:00    D
-Rule   Peru    1939    1940    -       Mar     Sun>=24 0:00    0       S
-Rule   Peru    1987    only    -       Jan      1      0:00    1:00    D
-Rule   Peru    1987    only    -       Apr      1      0:00    0       S
-Rule   Peru    1990    only    -       Jan      1      0:00    1:00    D
-Rule   Peru    1990    only    -       Apr      1      0:00    0       S
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   America/Lima    -5:08:12 -      LMT     1890
-                       -5:09   -       LMT     1908 Jul 28
-                       -5:00   Peru    E%sT
-
-# South Georgia
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone Atlantic/South_Georgia -2:26:08 - LMT     1890            # Grytviken
-                       -2:00   -       FST
-
-# South Sandwich Is
-# no information
-
-# Suriname
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone America/Paramaribo        -3:40:40 -      LMT     1911
-                       -3:40:52 -      PMT     1935     # Paramaribo Mean Time
-                       -3:40:36 -      PMT     1945 Oct # The capital moved?
-                       -3:30   -       DGST    1984 Oct # Dutch Guiana Std Time
-                       -3:00   -       EST
-
-# Trinidad and Tobago
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone America/Port_of_Spain -4:06:04 -  LMT     1912 Mar 2
-                       -4:00   -       AST
-
-# Uruguay
-# From Paul Eggert <eggert@twinsun.com> (November 18, 1993):
-# Uruguay wins the prize for the strangest peacetime manipulation of the rules.
-# Your guess is as good as mine for what happened after 1989.
-# From Shanks (1991):
-# Rule NAME    FROM    TO      TYPE    IN      ON      AT      SAVE    LETTER/S
-Rule   Uruguay 1920    only    -       May      1       0:00   0       S
-# Whitman gives 1923 Oct 1; go with Shanks.
-Rule   Uruguay 1923    only    -       Oct      2       0:00   0:30    HD
-Rule   Uruguay 1924    1926    -       Apr      1       0:00   0       S
-Rule   Uruguay 1924    1925    -       Oct      1       0:00   0:30    HD
-Rule   Uruguay 1933    1935    -       Oct     lastSun  0:00   0:30    HD
-# Shanks gives 1935 Apr 1 0:00 and 1936 Mar 30 0:00; go with Whitman.
-Rule   Uruguay 1934    1936    -       Mar     Sat>=25 23:30s  0       S
-Rule   Uruguay 1936    only    -       Nov      1       0:00   0:30    HD
-Rule   Uruguay 1937    1941    -       Mar     lastSun  0:00   0       S
-# Whitman gives 1937 Oct 3; go with Shanks.
-Rule   Uruguay 1937    1940    -       Oct     lastSun  0:00   0:30    HD
-# Whitman gives 1941 Oct 24 - 1942 Mar 27, 1942 Dec 14 - 1943 Apr 13,
-# and 1943 Apr 13 ``to present time''; go with Shanks.
-Rule   Uruguay 1941    only    -       Aug      1       0:00   0       S
-Rule   Uruguay 1942    only    -       Jan      1       0:00   0:30    HD
-Rule   Uruguay 1942    only    -       Dec     14       0:00   1:00    D
-Rule   Uruguay 1943    only    -       Mar     14       0:00   0       S
-Rule   Uruguay 1959    only    -       May     24       0:00   1:00    D
-Rule   Uruguay 1959    only    -       Nov     15       0:00   0       S
-Rule   Uruguay 1960    only    -       Jan     17       0:00   1:00    D
-Rule   Uruguay 1960    only    -       Mar      6       0:00   0       S
-Rule   Uruguay 1965    1967    -       Apr     Sun>=1   0:00   1:00    D
-Rule   Uruguay 1965    only    -       Sep     26       0:00   0       S
-Rule   Uruguay 1966    1967    -       Oct     31       0:00   0       S
-Rule   Uruguay 1968    1970    -       May     27       0:00   0:30    HD
-Rule   Uruguay 1968    1970    -       Dec      2       0:00   0       S
-Rule   Uruguay 1972    only    -       Apr     24       0:00   1:00    D
-Rule   Uruguay 1972    only    -       Aug     15       0:00   0       S
-Rule   Uruguay 1974    only    -       Mar     10       0:00   0:30    HD
-Rule   Uruguay 1974    only    -       Dec     22       0:00   1:00    D
-Rule   Uruguay 1976    only    -       Oct      1       0:00   0       S
-Rule   Uruguay 1977    only    -       Dec      4       0:00   1:00    D
-Rule   Uruguay 1978    only    -       Apr      1       0:00   0       S
-Rule   Uruguay 1979    only    -       Oct      1       0:00   1:00    D
-Rule   Uruguay 1980    only    -       May      1       0:00   0       S
-Rule   Uruguay 1987    only    -       Dec     14       0:00   1:00    D
-Rule   Uruguay 1988    only    -       Mar     14       0:00   0       S
-Rule   Uruguay 1988    only    -       Dec     11       0:00   1:00    D
-Rule   Uruguay 1989    only    -       Mar     12       0:00   0       S
-Rule   Uruguay 1989    only    -       Oct     29       0:00   1:00    D
-Rule   Uruguay 1990    only    -       Mar      4       0:00   0       S
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone America/Montevideo        -3:44:44 -      LMT     1898 Jun 28
-                       -3:45   -       MMT     1920 May  1     # Montevideo MT
-                       -3:30   Uruguay U%sT    1942 Dec 14     # Uruguay ST
-                       -3:00   Uruguay E%sT
-
-# Venezuela
-# Zone NAME            GMTOFF  RULES   FORMAT  [UNTIL]
-Zone   America/Caracas -4:27:44 -      LMT     1890
-                       -4:28   -       CMT     1912 Feb 12  # Caracas Mean Time
-                       -4:30   -       VZT     1965            # Venezuela Time
-                       -4:00   -       AST
diff --git a/time/strftime.c b/time/strftime.c
deleted file mode 100644 (file)
index 39f1aab..0000000
+++ /dev/null
@@ -1,576 +0,0 @@
-#ifndef lint
-#ifndef NOID
-static char    elsieid[] = "@(#)strftime.c     7.33";
-/*
-** Based on the UCB version with the ID appearing below.
-** This is ANSIish only when "multibyte character == plain character".
-*/
-#endif /* !defined NOID */
-#endif /* !defined lint */
-
-#include "private.h"
-
-/*
-** Copyright (c) 1989 The Regents of the University of California.
-** All rights reserved.
-**
-** Redistribution and use in source and binary forms are permitted
-** provided that the above copyright notice and this paragraph are
-** duplicated in all such forms and that any documentation,
-** advertising materials, and other materials related to such
-** distribution and use acknowledge that the software was developed
-** by the University of California, 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'' AND WITHOUT ANY EXPRESS OR
-** IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
-** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
-*/
-
-#ifndef LIBC_SCCS
-#ifndef lint
-static const char      sccsid[] = "@(#)strftime.c      5.4 (Berkeley) 3/14/89";
-#endif /* !defined lint */
-#endif /* !defined LIBC_SCCS */
-
-#include "tzfile.h"
-#include "fcntl.h"
-#if HAVE_SETLOCALE - 0
-#include "locale.h"
-#endif /* HAVE_SETLOCALE - 0 */
-
-struct lc_time_T {
-       const char *    mon[12];
-       const char *    month[12];
-       const char *    wday[7];
-       const char *    weekday[7];
-       const char *    X_fmt;
-       const char *    x_fmt;
-       const char *    c_fmt;
-       const char *    am;
-       const char *    pm;
-       const char *    date_fmt;
-};
-
-#ifdef LOCALE_HOME
-static struct lc_time_T                localebuf;
-static struct lc_time_T *      _loc P((void));
-#define Locale _loc()
-#endif /* defined LOCALE_HOME */
-#ifndef LOCALE_HOME
-#define Locale (&C_time_locale)
-#endif /* !defined LOCALE_HOME */
-
-static const struct lc_time_T  C_time_locale = {
-       {
-               "Jan", "Feb", "Mar", "Apr", "May", "Jun",
-               "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
-       }, {
-               "January", "February", "March", "April", "May", "June",
-               "July", "August", "September", "October", "November", "December"
-       }, {
-               "Sun", "Mon", "Tue", "Wed",
-               "Thu", "Fri", "Sat"
-       }, {
-               "Sunday", "Monday", "Tuesday", "Wednesday",
-               "Thursday", "Friday", "Saturday"
-       },
-
-       /* X_fmt */
-       "%H:%M:%S",
-
-       /*
-       ** x_fmt
-       ** Since the C language standard calls for
-       ** "date, using locale's date format," anything goes.
-       ** Using just numbers (as here) makes Quakers happier;
-       ** it's also compatible with SVR4.
-       */
-       "%m/%d/%y",
-
-       /*
-       ** c_fmt
-       ** Note that
-       **      "%a %b %d %H:%M:%S %Y"
-       ** is used by Solaris 2.3.
-       */
-       "%D %X",        /* %m/%d/%y %H:%M:%S */
-
-       /* am */
-       "AM",
-       
-       /* pm */
-       "PM",
-
-       /* date_fmt */
-       "%a %b %e %H:%M:%S %Z %Y"
-};
-
-static char *  _add P((const char *, char *, const char *));
-static char *  _conv P((int, const char *, char *, const char *));
-static char *_fmt P((const char *, const struct tm *, char *, const char *));
-
-size_t strftime P((char *, size_t, const char *, const struct tm *));
-
-extern char *  tzname[];
-
-size_t
-strftime(s, maxsize, format, t)
-char * const           s;
-const size_t           maxsize;
-const char * const     format;
-const struct tm * const        t;
-{
-       char *  p;
-
-       tzset();
-#ifdef LOCALE_HOME
-       localebuf.mon[0] = 0;
-#endif /* defined LOCALE_HOME */
-       p = _fmt(((format == NULL) ? "%c" : format), t, s, s + maxsize);
-       if (p == s + maxsize)
-               return 0;
-       *p = '\0';
-       return p - s;
-}
-
-static char *
-_fmt(format, t, pt, ptlim)
-const char *           format;
-const struct tm * const        t;
-char *                 pt;
-const char * const     ptlim;
-{
-       for ( ; *format; ++format) {
-               if (*format == '%') {
-label:
-                       switch (*++format) {
-                       case '\0':
-                               --format;
-                               break;
-                       case 'A':
-                               pt = _add((t->tm_wday < 0 || t->tm_wday > 6) ?
-                                       "?" : Locale->weekday[t->tm_wday],
-                                       pt, ptlim);
-                               continue;
-                       case 'a':
-                               pt = _add((t->tm_wday < 0 || t->tm_wday > 6) ?
-                                       "?" : Locale->wday[t->tm_wday],
-                                       pt, ptlim);
-                               continue;
-                       case 'B':
-                               pt = _add((t->tm_mon < 0 || t->tm_mon > 11) ?
-                                       "?" : Locale->month[t->tm_mon],
-                                       pt, ptlim);
-                               continue;
-                       case 'b':
-                       case 'h':
-                               pt = _add((t->tm_mon < 0 || t->tm_mon > 11) ?
-                                       "?" : Locale->mon[t->tm_mon],
-                                       pt, ptlim);
-                               continue;
-                       case 'C':
-                               /*
-                               ** %C used to do a...
-                               **      _fmt("%a %b %e %X %Y", t);
-                               ** ...whereas now POSIX 1003.2 calls for
-                               ** something completely different.
-                               ** (ado, 5/24/93)
-                               */
-                               pt = _conv((t->tm_year + TM_YEAR_BASE) / 100,
-                                       "%02d", pt, ptlim);
-                               continue;
-                       case 'c':
-                               pt = _fmt(Locale->c_fmt, t, pt, ptlim);
-                               continue;
-                       case 'D':
-                               pt = _fmt("%m/%d/%y", t, pt, ptlim);
-                               continue;
-                       case 'd':
-                               pt = _conv(t->tm_mday, "%02d", pt, ptlim);
-                               continue;
-                       case 'E':
-                       case 'O':
-                               /*
-                               ** POSIX locale extensions, a la
-                               ** Arnold Robbins' strftime version 3.0.
-                               ** The sequences
-                               **      %Ec %EC %Ex %Ey %EY
-                               **      %Od %oe %OH %OI %Om %OM
-                               **      %OS %Ou %OU %OV %Ow %OW %Oy
-                               ** are supposed to provide alternate
-                               ** representations.
-                               ** (ado, 5/24/93)
-                               */
-                               goto label;
-                       case 'e':
-                               pt = _conv(t->tm_mday, "%2d", pt, ptlim);
-                               continue;
-                       case 'H':
-                               pt = _conv(t->tm_hour, "%02d", pt, ptlim);
-                               continue;
-                       case 'I':
-                               pt = _conv((t->tm_hour % 12) ?
-                                       (t->tm_hour % 12) : 12,
-                                       "%02d", pt, ptlim);
-                               continue;
-                       case 'j':
-                               pt = _conv(t->tm_yday + 1, "%03d", pt, ptlim);
-                               continue;
-                       case 'k':
-                               /*
-                               ** This used to be...
-                               **      _conv(t->tm_hour % 12 ?
-                               **              t->tm_hour % 12 : 12, 2, ' ');
-                               ** ...and has been changed to the below to
-                               ** match SunOS 4.1.1 and Arnold Robbins'
-                               ** strftime version 3.0.  That is, "%k" and
-                               ** "%l" have been swapped.
-                               ** (ado, 5/24/93)
-                               */
-                               pt = _conv(t->tm_hour, "%2d", pt, ptlim);
-                               continue;
-#ifdef KITCHEN_SINK
-                       case 'K':
-                               /*
-                               ** After all this time, still unclaimed!
-                               */
-                               pt = _add("kitchen sink", pt, ptlim);
-                               continue;
-#endif /* defined KITCHEN_SINK */
-                       case 'l':
-                               /*
-                               ** This used to be...
-                               **      _conv(t->tm_hour, 2, ' ');
-                               ** ...and has been changed to the below to
-                               ** match SunOS 4.1.1 and Arnold Robbin's
-                               ** strftime version 3.0.  That is, "%k" and
-                               ** "%l" have been swapped.
-                               ** (ado, 5/24/93)
-                               */
-                               pt = _conv((t->tm_hour % 12) ?
-                                       (t->tm_hour % 12) : 12,
-                                       "%2d", pt, ptlim);
-                               continue;
-                       case 'M':
-                               pt = _conv(t->tm_min, "%02d", pt, ptlim);
-                               continue;
-                       case 'm':
-                               pt = _conv(t->tm_mon + 1, "%02d", pt, ptlim);
-                               continue;
-                       case 'n':
-                               pt = _add("\n", pt, ptlim);
-                               continue;
-                       case 'p':
-                               pt = _add((t->tm_hour >= 12) ?
-                                       Locale->pm :
-                                       Locale->am,
-                                       pt, ptlim);
-                               continue;
-                       case 'R':
-                               pt = _fmt("%H:%M", t, pt, ptlim);
-                               continue;
-                       case 'r':
-                               pt = _fmt("%I:%M:%S %p", t, pt, ptlim);
-                               continue;
-                       case 'S':
-                               pt = _conv(t->tm_sec, "%02d", pt, ptlim);
-                               continue;
-                       case 'T':
-                               pt = _fmt("%H:%M:%S", t, pt, ptlim);
-                               continue;
-                       case 't':
-                               pt = _add("\t", pt, ptlim);
-                               continue;
-                       case 'U':
-                               pt = _conv((t->tm_yday + 7 - t->tm_wday) / 7,
-                                       "%02d", pt, ptlim);
-                               continue;
-                       case 'u':
-                               /*
-                               ** From Arnold Robbins' strftime version 3.0:
-                               ** "ISO 8601: Weekday as a decimal number
-                               ** [1 (Monday) - 7]"
-                               ** (ado, 5/24/93)
-                               */
-                               pt = _conv((t->tm_wday == 0) ? 7 : t->tm_wday,
-                                       "%d", pt, ptlim);
-                               continue;
-                       case 'V':
-                               /*
-                               ** From Arnold Robbins' strftime version 3.0:
-                               ** "the week number of the year (the first
-                               ** Monday as the first day of week 1) as a
-                               ** decimal number (01-53).  The method for
-                               ** determining the week number is as specified
-                               ** by ISO 8601 (to wit: if the week containing
-                               ** January 1 has four or more days in the new
-                               ** year, then it is week 1, otherwise it is
-                               ** week 53 of the previous year and the next
-                               ** week is week 1)."
-                               ** (ado, 5/24/93)
-                               */
-                               /*
-                               ** XXX--If January 1 falls on a Friday,
-                               ** January 1-3 are part of week 53 of the
-                               ** previous year.  By analogy, if January
-                               ** 1 falls on a Thursday, are December 29-31
-                               ** of the PREVIOUS year part of week 1???
-                               ** (ado 5/24/93)
-                               */
-                               /*
-                               ** You are understood not to expect this.
-                               */
-                               {
-                                       int     i;
-
-                                       i = (t->tm_yday + 10 - (t->tm_wday ?
-                                               (t->tm_wday - 1) : 6)) / 7;
-                                       if (i == 0) {
-                                               /*
-                                               ** What day of the week does
-                                               ** January 1 fall on?
-                                               */
-                                               i = t->tm_wday -
-                                                       (t->tm_yday - 1);
-                                               /*
-                                               ** Fri Jan 1: 53
-                                               ** Sun Jan 1: 52
-                                               ** Sat Jan 1: 53 if previous
-                                               **               year a leap
-                                               **               year, else 52
-                                               */
-                                               if (i == TM_FRIDAY)
-                                                       i = 53;
-                                               else if (i == TM_SUNDAY)
-                                                       i = 52;
-                                               else    i = isleap(t->tm_year +
-                                                               TM_YEAR_BASE) ?
-                                                               53 : 52;
-#ifdef XPG4_1994_04_09
-                                               /*
-                                               ** As of 4/9/94, though,
-                                               ** XPG4 calls for 53
-                                               ** unconditionally.
-                                               */
-                                               i = 53;
-#endif /* defined XPG4_1994_04_09 */
-                                       }
-                                       pt = _conv(i, "%02d", pt, ptlim);
-                               }
-                               continue;
-                       case 'v':
-                               /*
-                               ** From Arnold Robbins' strftime version 3.0:
-                               ** "date as dd-bbb-YYYY"
-                               ** (ado, 5/24/93)
-                               */
-                               pt = _fmt("%e-%b-%Y", t, pt, ptlim);
-                               continue;
-                       case 'W':
-                               pt = _conv((t->tm_yday + 7 -
-                                       (t->tm_wday ?
-                                       (t->tm_wday - 1) : 6)) / 7,
-                                       "%02d", pt, ptlim);
-                               continue;
-                       case 'w':
-                               pt = _conv(t->tm_wday, "%d", pt, ptlim);
-                               continue;
-                       case 'X':
-                               pt = _fmt(Locale->X_fmt, t, pt, ptlim);
-                               continue;
-                       case 'x':
-                               pt = _fmt(Locale->x_fmt, t, pt, ptlim);
-                               continue;
-                       case 'y':
-                               pt = _conv((t->tm_year + TM_YEAR_BASE) % 100,
-                                       "%02d", pt, ptlim);
-                               continue;
-                       case 'Y':
-                               pt = _conv(t->tm_year + TM_YEAR_BASE, "%04d",
-                                       pt, ptlim);
-                               continue;
-                       case 'Z':
-#ifdef TM_ZONE
-                               if (t->TM_ZONE != NULL)
-                                       pt = _add(t->TM_ZONE, pt, ptlim);
-                               else
-#endif /* defined TM_ZONE */
-                               if (t->tm_isdst == 0 || t->tm_isdst == 1) {
-                                       pt = _add(tzname[t->tm_isdst],
-                                               pt, ptlim);
-                               } else  pt = _add("?", pt, ptlim);
-                               continue;
-                       case '+':
-                               pt = _fmt(Locale->date_fmt, t, pt, ptlim);
-                               continue;
-                       case '%':
-                       /*
-                        * X311J/88-090 (4.12.3.5): if conversion char is
-                        * undefined, behavior is undefined.  Print out the
-                        * character itself as printf(3) also does.
-                        */
-                       default:
-                               break;
-                       }
-               }
-               if (pt == ptlim)
-                       break;
-               *pt++ = *format;
-       }
-       return pt;
-}
-
-static char *
-_conv(n, format, pt, ptlim)
-const int              n;
-const char * const     format;
-char * const           pt;
-const char * const     ptlim;
-{
-       char    buf[INT_STRLEN_MAXIMUM(int) + 1];
-
-       (void) sprintf(buf, format, n);
-       return _add(buf, pt, ptlim);
-}
-
-static char *
-_add(str, pt, ptlim)
-const char *           str;
-char *                 pt;
-const char * const     ptlim;
-{
-       while (pt < ptlim && (*pt = *str++) != '\0')
-               ++pt;
-       return pt;
-}
-
-#ifdef LOCALE_HOME
-static struct lc_time_T *
-_loc P((void))
-{
-       static const char       locale_home[] = LOCALE_HOME;
-       static const char       lc_time[] = "LC_TIME";
-       static char *           locale_buf;
-       static char             locale_buf_C[] = "C";
-
-       int                     fd;
-       int                     oldsun; /* "...ain't got nothin' to do..." */
-       char *                  lbuf;
-       char *                  name;
-       char *                  p;
-       const char **           ap;
-       const char *            plim;
-       char                    filename[FILENAME_MAX];
-       struct stat             st;
-       size_t                  namesize;
-       size_t                  bufsize;
-
-       /*
-       ** Use localebuf.mon[0] to signal whether locale is already set up.
-       */
-       if (localebuf.mon[0])
-               return &localebuf;
-#if HAVE_SETLOCALE - 0
-       name = setlocale(LC_TIME, (char *) NULL);
-#endif /* HAVE_SETLOCALE - 0 */
-#if !(HAVE_SETLOCALE - 0)
-       if ((name = getenv("LC_ALL")) == NULL || *name == '\0')
-               if ((name = getenv(lc_time)) == NULL || *name == '\0')
-                       name = getenv("LANG");
-#endif /* !(HAVE_SETLOCALE - 0) */
-       if (name == NULL || *name == '\0')
-               goto no_locale;
-       /*
-       ** If the locale name is the same as our cache, use the cache.
-       */
-       lbuf = locale_buf;
-       if (lbuf != NULL && strcmp(name, lbuf) == 0) {
-               p = lbuf;
-               for (ap = (const char **) &localebuf;
-                       ap < (const char **) (&localebuf + 1);
-                               ++ap)
-                                       *ap = p += strlen(p) + 1;
-               return &localebuf;
-       }
-       /*
-       ** Slurp the locale file into the cache.
-       */
-       namesize = strlen(name) + 1;
-       if (sizeof(filename) <
-               sizeof(locale_home) + namesize + sizeof(lc_time))
-                       goto no_locale;
-       oldsun = 0;
-       (void) sprintf(filename, "%s/%s/%s", locale_home, name, lc_time);
-       fd = open(filename, O_RDONLY);
-       if (fd < 0) {
-               /*
-               ** Old Sun systems have a different naming and data convention.
-               */
-               oldsun = 1;
-               (void) sprintf(filename, "%s/%s/%s", locale_home,
-                       lc_time, name);
-               fd = open(filename, O_RDONLY);
-               if (fd < 0)
-                       goto no_locale;
-       }
-       if (fstat(fd, &st) != 0)
-               goto bad_locale;
-       if (st.st_size <= 0)
-               goto bad_locale;
-       bufsize = namesize + st.st_size;
-       locale_buf = NULL;
-       lbuf = (lbuf == NULL || lbuf == locale_buf_C) ?
-               malloc(bufsize) : realloc(lbuf, bufsize);
-       if (lbuf == NULL)
-               goto bad_locale;
-       (void) strcpy(lbuf, name);
-       p = lbuf + namesize;
-       plim = p + st.st_size;
-       if (read(fd, p, (size_t) st.st_size) != st.st_size)
-               goto bad_lbuf;
-       if (close(fd) != 0)
-               goto bad_lbuf;
-       /*
-       ** Parse the locale file into localebuf.
-       */
-       if (plim[-1] != '\n')
-               goto bad_lbuf;
-       for (ap = (const char **) &localebuf;
-               ap < (const char **) (&localebuf + 1);
-                       ++ap) {
-                               if (p == plim)
-                                       goto bad_lbuf;
-                               *ap = p;
-                               while (*p != '\n')
-                                       ++p;
-                               *p++ = '\0';
-       }
-       if (oldsun) {
-               /*
-               ** SunOS 4 used an obsolescent format; see localdtconv(3).
-               ** c_fmt had the ``short format for dates and times together''
-               ** (SunOS 4 date, "%a %b %e %T %Z %Y" in the C locale);
-               ** date_fmt had the ``long format for dates''
-               ** (SunOS 4 strftime %C, "%A, %B %e, %Y" in the C locale).
-               ** Discard the latter in favor of the former.
-               */
-               localebuf.date_fmt = localebuf.c_fmt;
-       }
-       /*
-       ** Record the successful parse in the cache.
-       */
-       locale_buf = lbuf;
-
-       return &localebuf;
-
-bad_lbuf:
-       free(lbuf);
-bad_locale:
-       (void) close(fd);
-no_locale:
-       localebuf = C_time_locale;
-       locale_buf = locale_buf_C;
-       return &localebuf;
-}
-#endif /* defined LOCALE_HOME */
diff --git a/time/systemv b/time/systemv
deleted file mode 100644 (file)
index a6f79d2..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-# @(#)systemv  7.2
-
-# Old rules, should the need arise.
-# No attempt is made to handle Newfoundland, since it cannot be expressed
-# using the System V "TZ" scheme (half-hour offset), or anything outside
-# North America (no support for non-standard DST start/end dates), nor
-# the change in the DST rules in the US in 1987 (can't split between
-# Canada, with no changes, and the US)
-#
-# Be sure to compile this *without* leap second correction for true conformance.
-
-# Rule NAME    FROM    TO      TYPE    IN      ON      AT      SAVE    LETTER/S
-Rule   SystemV min     1973    -       Apr     lastSun 2:00    1:00    D
-Rule   SystemV min     1973    -       Oct     lastSun 2:00    0       S
-Rule   SystemV 1974    only    -       Jan     6       2:00    1:00    D
-Rule   SystemV 1974    only    -       Nov     lastSun 2:00    0       S
-Rule   SystemV 1975    only    -       Feb     23      2:00    1:00    D
-Rule   SystemV 1975    only    -       Oct     lastSun 2:00    0       S
-Rule   SystemV 1976    max     -       Apr     lastSun 2:00    1:00    D
-Rule   SystemV 1976    max     -       Oct     lastSun 2:00    0       S
-
-# Zone NAME            GMTOFF  RULES/SAVE      FORMAT  [UNTIL]
-Zone   SystemV/AST4ADT -4:00   SystemV         A%sT
-Zone   SystemV/EST5EDT -5:00   SystemV         E%sT
-Zone   SystemV/CST6CDT -6:00   SystemV         C%sT
-Zone   SystemV/MST7MDT -7:00   SystemV         M%sT
-Zone   SystemV/PST8PDT -8:00   SystemV         P%sT
-Zone   SystemV/YST9YDT -9:00   SystemV         Y%sT
-Zone   SystemV/AST4    -4:00   -               AST
-Zone   SystemV/EST5    -5:00   -               EST
-Zone   SystemV/CST6    -6:00   -               CST
-Zone   SystemV/MST7    -7:00   -               MST
-Zone   SystemV/PST8    -8:00   -               PST
-Zone   SystemV/YST9    -9:00   -               YST
-Zone   SystemV/HST10   -10:00  -               HST
diff --git a/time/time2posix.3 b/time/time2posix.3
deleted file mode 100644 (file)
index 846a52e..0000000
+++ /dev/null
@@ -1,119 +0,0 @@
-.TH TIME2POSIX 3
-.SH NAME
-time2posix, posix2time \- convert seconds since the Epoch
-.SH SYNOPSIS
-.nf
-.B #include <sys/types.h>
-.B #include <time.h>
-.PP
-.B time_t time2posix(t)
-.B time_t t
-.PP
-.B time_t posix2time(t)
-.B time_t t
-.PP
-.B cc ... -lz
-.fi
-.SH DESCRIPTION
-IEEE Standard 1003.1
-(POSIX)
-legislates that a time_t value of
-536457599 shall correspond to "Wed Dec 31 23:59:59 GMT 1986."
-This effectively implies that POSIX time_t's cannot include leap
-seconds and,
-therefore,
-that the system time must be adjusted as each leap occurs.
-.PP
-If the time package is configured with leap-second support
-enabled,
-however,
-no such adjustment is needed and
-time_t values continue to increase over leap events
-(as a true `seconds since...' value).
-This means that these values will differ from those required by POSIX
-by the net number of leap seconds inserted since the Epoch.
-.PP
-Typically this is not a problem as the type time_t is intended
-to be
-(mostly)
-opaque\(emtime_t values should only be obtained-from and
-passed-to functions such as
-.IR time(2) ,
-.IR localtime(3) ,
-.IR mktime(3) ,
-and
-.IR difftime(3) .
-However,
-POSIX gives an arithmetic
-expression for directly computing a time_t value from a given date/time,
-and the same relationship is assumed by some
-(usually older)
-applications.
-Any programs creating/dissecting time_t's
-using such a relationship will typically not handle intervals
-over leap seconds correctly.
-.PP
-The
-.I time2posix
-and
-.I posix2time
-functions are provided to address this time_t mismatch by converting
-between local time_t values and their POSIX equivalents.
-This is done by accounting for the number of time-base changes that
-would have taken place on a POSIX system as leap seconds were inserted
-or deleted.
-These converted values can then be used in lieu of correcting the older
-applications,
-or when communicating with POSIX-compliant systems.
-.PP
-.I Time2posix
-is single-valued.
-That is,
-every local time_t
-corresponds to a single POSIX time_t.
-.I Posix2time
-is less well-behaved:
-for a positive leap second hit the result is not unique,
-and for a negative leap second hit the corresponding
-POSIX time_t doesn't exist so an adjacent value is returned.
-Both of these are good indicators of the inferiority of the
-POSIX representation.
-.PP
-The following table summarizes the relationship between a time
-T and it's conversion to,
-and back from,
-the POSIX representation over the leap second inserted at the end of June,
-1993.
-.nf
-.ta \w'93/06/30 'u +\w'23:59:59 'u +\w'A+0 'u +\w'X=time2posix(T) 'u
-DATE   TIME    T       X=time2posix(T) posix2time(X)
-93/06/30       23:59:59        A+0     B+0     A+0
-93/06/30       23:59:60        A+1     B+1     A+1 or A+2
-93/07/01       00:00:00        A+2     B+1     A+1 or A+2
-93/07/01       00:00:01        A+3     B+2     A+3
-
-A leap second deletion would look like...
-
-DATE   TIME    T       X=time2posix(T) posix2time(X)
-??/06/30       23:59:58        A+0     B+0     A+0
-??/07/01       00:00:00        A+1     B+2     A+1
-??/07/01       00:00:01        A+2     B+3     A+2
-.sp
-.ce
-       [Note: posix2time(B+1) => A+0 or A+1]
-.fi
-.PP
-If leap-second support is not enabled,
-local time_t's and
-POSIX time_t's are equivalent,
-and both
-.I time2posix
-and
-.I posix2time
-degenerate to the identity function.
-.SH SEE ALSO
-difftime(3),
-localtime(3),
-mktime(3),
-time(2)
-.\" @(#)time2posix.3   7.3
diff --git a/time/tzfile.5 b/time/tzfile.5
deleted file mode 100644 (file)
index 1d47033..0000000
+++ /dev/null
@@ -1,123 +0,0 @@
-.TH TZFILE 5
-.SH NAME
-tzfile \- time zone information
-.SH SYNOPSIS
-.B
-#include <tzfile.h>
-.SH DESCRIPTION
-The time zone information files used by
-.IR tzset (3)
-begin with bytes reserved for future use,
-followed by four four-byte values of type
-.BR long ,
-written in a ``standard'' byte order
-(the high-order byte of the value is written first).
-These values are,
-in order:
-.TP
-.I tzh_ttisstdcnt
-The number of standard/wall indicators stored in the file.
-.TP
-.I tzh_leapcnt
-The number of leap seconds for which data is stored in the file.
-.TP
-.I tzh_timecnt
-The number of "transition times" for which data is stored
-in the file.
-.TP
-.I tzh_typecnt
-The number of "local time types" for which data is stored
-in the file (must not be zero).
-.TP
-.I tzh_charcnt
-The number of characters of "time zone abbreviation strings"
-stored in the file.
-.PP
-The above header is followed by
-.I tzh_timecnt
-four-byte values of type
-.BR long ,
-sorted in ascending order.
-These values are written in ``standard'' byte order.
-Each is used as a transition time (as returned by
-.IR time (2))
-at which the rules for computing local time change.
-Next come
-.I tzh_timecnt
-one-byte values of type
-.BR "unsigned char" ;
-each one tells which of the different types of ``local time'' types
-described in the file is associated with the same-indexed transition time.
-These values serve as indices into an array of
-.I ttinfo
-structures that appears next in the file;
-these structures are defined as follows:
-.in +.5i
-.sp
-.nf
-.ta .5i +\w'unsigned int\0\0'u
-struct ttinfo {
-       long    tt_gmtoff;
-       int     tt_isdst;
-       unsigned int    tt_abbrind;
-};
-.in -.5i
-.fi
-.sp
-Each structure is written as a four-byte value for
-.I tt_gmtoff
-of type
-.BR long ,
-in a standard byte order, followed by a one-byte value for
-.I tt_isdst
-and a one-byte value for
-.IR tt_abbrind .
-In each structure,
-.I tt_gmtoff
-gives the number of seconds to be added to GMT,
-.I tt_isdst
-tells whether
-.I tm_isdst
-should be set by
-.I localtime (3)
-and
-.I tt_abbrind
-serves as an index into the array of time zone abbreviation characters
-that follow the
-.I ttinfo
-structure(s) in the file.
-.PP
-Then there are
-.I tzh_leapcnt
-pairs of four-byte values, written in standard byte order;
-the first value of each pair gives the time
-(as returned by
-.IR time(2))
-at which a leap second occurs;
-the second gives the
-.I total
-number of leap seconds to be applied after the given time.
-The pairs of values are sorted in ascending order by time.
-.PP
-Finally there are
-.I tzh_ttisstdcnt
-standard/wall indicators, each stored as a one-byte value;
-they tell whether the transition times associated with local time types
-were specified as standard time or wall clock time,
-and are used when a time zone file is used in handling POSIX-style
-time zone environment variables.
-.PP
-.I Localtime
-uses the first standard-time
-.I ttinfo
-structure in the file
-(or simply the first
-.I ttinfo
-structure in the absence of a standard-time structure)
-if either
-.I tzh_timecnt
-is zero or the time argument is less than the first transition time recorded
-in the file.
-.SH SEE ALSO
-newctime(3)
-.\" @(#)tzfile.5       7.2
diff --git a/time/tzfile.h b/time/tzfile.h
deleted file mode 100644 (file)
index 45b4d7d..0000000
+++ /dev/null
@@ -1,170 +0,0 @@
-#ifndef TZFILE_H
-
-#define TZFILE_H
-
-/*
-** This header is for use ONLY with the time conversion code.
-** There is no guarantee that it will remain unchanged,
-** or that it will remain at all.
-** Do NOT copy it to any system include directory.
-** Thank you!
-*/
-
-/*
-** ID
-*/
-
-#ifndef lint
-#ifndef NOID
-static char    tzfilehid[] = "@(#)tzfile.h     7.4";
-#endif /* !defined NOID */
-#endif /* !defined lint */
-
-/*
-** Information about time zone files.
-*/
-
-#ifndef TZDIR
-#define TZDIR  "/usr/local/etc/zoneinfo" /* Time zone object file directory */
-#endif /* !defined TZDIR */
-
-#ifndef TZDEFAULT
-#define TZDEFAULT      "localtime"
-#endif /* !defined TZDEFAULT */
-
-#ifndef TZDEFRULES
-#define TZDEFRULES     "posixrules"
-#endif /* !defined TZDEFRULES */
-
-/*
-** Each file begins with. . .
-*/
-
-struct tzhead {
-       char    tzh_reserved[24];       /* reserved for future use */
-       char    tzh_ttisstdcnt[4];      /* coded number of trans. time flags */
-       char    tzh_leapcnt[4];         /* coded number of leap seconds */
-       char    tzh_timecnt[4];         /* coded number of transition times */
-       char    tzh_typecnt[4];         /* coded number of local time types */
-       char    tzh_charcnt[4];         /* coded number of abbr. chars */
-};
-
-/*
-** . . .followed by. . .
-**
-**     tzh_timecnt (char [4])s         coded transition times a la time(2)
-**     tzh_timecnt (unsigned char)s    types of local time starting at above
-**     tzh_typecnt repetitions of
-**             one (char [4])          coded GMT offset in seconds
-**             one (unsigned char)     used to set tm_isdst
-**             one (unsigned char)     that's an abbreviation list index
-**     tzh_charcnt (char)s             '\0'-terminated zone abbreviations
-**     tzh_leapcnt repetitions of
-**             one (char [4])          coded leap second transition times
-**             one (char [4])          total correction after above
-**     tzh_ttisstdcnt (char)s          indexed by type; if TRUE, transition
-**                                     time is standard time, if FALSE,
-**                                     transition time is wall clock time
-**                                     if absent, transition times are
-**                                     assumed to be wall clock time
-*/
-
-/*
-** In the current implementation, "tzset()" refuses to deal with files that
-** exceed any of the limits below.
-*/
-
-#ifndef TZ_MAX_TIMES
-/*
-** The TZ_MAX_TIMES value below is enough to handle a bit more than a
-** year's worth of solar time (corrected daily to the nearest second) or
-** 138 years of Pacific Presidential Election time
-** (where there are three time zone transitions every fourth year).
-*/
-#define TZ_MAX_TIMES   370
-#endif /* !defined TZ_MAX_TIMES */
-
-#ifndef TZ_MAX_TYPES
-#ifndef NOSOLAR
-#define TZ_MAX_TYPES   256 /* Limited by what (unsigned char)'s can hold */
-#endif /* !defined NOSOLAR */
-#ifdef NOSOLAR
-#define TZ_MAX_TYPES   10      /* Maximum number of local time types */
-#endif /* !defined NOSOLAR */
-#endif /* !defined TZ_MAX_TYPES */
-
-#ifndef TZ_MAX_CHARS
-#define TZ_MAX_CHARS   50      /* Maximum number of abbreviation characters */
-                               /* (limited by what unsigned chars can hold) */
-#endif /* !defined TZ_MAX_CHARS */
-
-#ifndef TZ_MAX_LEAPS
-#define TZ_MAX_LEAPS   50      /* Maximum number of leap second corrections */
-#endif /* !defined TZ_MAX_LEAPS */
-
-#define SECSPERMIN     60
-#define MINSPERHOUR    60
-#define HOURSPERDAY    24
-#define DAYSPERWEEK    7
-#define DAYSPERNYEAR   365
-#define DAYSPERLYEAR   366
-#define SECSPERHOUR    (SECSPERMIN * MINSPERHOUR)
-#define SECSPERDAY     ((long) SECSPERHOUR * HOURSPERDAY)
-#define MONSPERYEAR    12
-
-#define TM_SUNDAY      0
-#define TM_MONDAY      1
-#define TM_TUESDAY     2
-#define TM_WEDNESDAY   3
-#define TM_THURSDAY    4
-#define TM_FRIDAY      5
-#define TM_SATURDAY    6
-
-#define TM_JANUARY     0
-#define TM_FEBRUARY    1
-#define TM_MARCH       2
-#define TM_APRIL       3
-#define TM_MAY         4
-#define TM_JUNE                5
-#define TM_JULY                6
-#define TM_AUGUST      7
-#define TM_SEPTEMBER   8
-#define TM_OCTOBER     9
-#define TM_NOVEMBER    10
-#define TM_DECEMBER    11
-
-#define TM_YEAR_BASE   1900
-
-#define EPOCH_YEAR     1970
-#define EPOCH_WDAY     TM_THURSDAY
-
-/*
-** Accurate only for the past couple of centuries;
-** that will probably do.
-*/
-
-#define isleap(y) ((((y) % 4) == 0 && ((y) % 100) != 0) || ((y) % 400) == 0)
-
-#ifndef USG
-
-/*
-** Use of the underscored variants may cause problems if you move your code to
-** certain System-V-based systems; for maximum portability, use the
-** underscore-free variants.  The underscored variants are provided for
-** backward compatibility only; they may disappear from future versions of
-** this file.
-*/
-
-#define SECS_PER_MIN   SECSPERMIN
-#define MINS_PER_HOUR  MINSPERHOUR
-#define HOURS_PER_DAY  HOURSPERDAY
-#define DAYS_PER_WEEK  DAYSPERWEEK
-#define DAYS_PER_NYEAR DAYSPERNYEAR
-#define DAYS_PER_LYEAR DAYSPERLYEAR
-#define SECS_PER_HOUR  SECSPERHOUR
-#define SECS_PER_DAY   SECSPERDAY
-#define MONS_PER_YEAR  MONSPERYEAR
-
-#endif /* !defined USG */
-
-#endif /* !defined TZFILE_H */
diff --git a/time/usno1988 b/time/usno1988
deleted file mode 100644 (file)
index dcb7283..0000000
+++ /dev/null
@@ -1,111 +0,0 @@
-# @(#)usno1988 7.1
-#
-# From Arthur David Olson (January 19, 1989):
-#
-# Here's some United States Naval Observatory time zone data from
-# February 1988.  It's here mostly to convince you that the USNO has indeed
-# been updating its files (see its 1989 data elsewhere).
-#
-ANDORRA             1 H AHEAD OF UTC
-ARGENTINA           3 H BEHIND   UTC
-BRASIL   WEST       5 H BEHIND UTC        (CRUZEIRO DO SUL)
-BRASIL   CENTRAL    4 H BEHIND UTC              (MANAUS)
-BRASIL   EAST       3 H BEHIND UTC   COASTAL STATES, RIO, SP, BRASILIA
-BRASIL              2 H BEHIND UTC   ATLANTIC ISLANDS
-BRAZIL              5 H BEHIND UTC   WEST (CRUZEIRO DO SUL)
-BRAZIL              4 H BEHIND UTC   CENTRAL    (MANAUS)
-BRAZIL              3 H BEHIND UTC   COASTAL STATES, RIO, SP, BRASILIA
-BRAZIL              3 H BEHIND UTC   FOR MOST MAJOR AIRPORTS.
-BRAZIL              2 H BEHIND UTC   ATLANTIC ISLANDS
-BULGARIA            2 H AHEAD OF UTC WINTER
-BULGARIA            3 H AHEAD OF UTC SUMMER MAR31 - SEP 85, 0100 LOCAL
-CHINA               8 H AHEAD OF UTC; ALL OF CHINA, INCL TAIWAN
-CUBA                5 H BEHIND UTC IN WINTER
-CUBA                4 H BEHIND UTC MAY 8 - OCT 8
-CYPRUS              2 H AHEAD UTC IN WINTER
-CYPRUS              3 H AHEAD UTC MAR 25 - SEP 30
-DENMARK             1 H AHEAD UTC IN WINTER
-DENMARK             2 H AHEAD UTC MAR 31 - SEP 30  , 0200 LOCAL
-DENMK. FAEROE IS    1 H AHEAD UTC MAR 31 - SEP 30  , 0200 LOCAL
-EGYPT               2 H AHEAD UTC
-EGYPT               3 H AHEAD UTC SUMMER (AFTER RAMADAN)
-ENGLAND             ON UTC IN WINTER; WALES, SCOTLAND, N.I., CH.IS.
-ENGLAND             1 H AHEAD OF UTC; SUMMER TIL 28 OCT 0200 LOCAL
-FINLAND             2 H AHEAD OF UTC IN WINTER
-FINLAND             3 H AHEAD OF UTC MAR 25 - SEP 30
-FRANCE              1 H AHEAD OF UTC IN WINTER
-FRANCE              2 H AHEAD OF UTC MAR 31 - SEP 30 , 0100 LOCAL
-GREECE              2 H AHEAD OF UTC IN WINTER
-GREECE              3 H AHEAD OF UTC IN SUMMER EFF. 31MAR85 02/03 LOCAL
-GREECE              3 H AHEAD OF UTC MAR 25 - SEP 30
-GREENLAND           4 H BEHIND UTC  IN THULE AIRBASE YEAR ROUND
-GREENLAND           3 H BEHIND UTC  IN WINTER AT SONDRESTROM
-GREENLAND           2 H BEHIND UTC  30 MAR - 30 SEP 2200 LOCAL AT -"-
-GREENLAND           2 H BEHIND UTC  AROUND SCORESBY SUND
-ICELAND             ON UTC
-IRAN                3.5H AHEAD OF UTC
-IRELAND             ON UTC IN WINTER
-IRELAND             1 H AHEAD OF UTC MAR 31 - OCT 23  0200 LOCAL
-ITALY               1 H AHEAD OF UTC IN WINTER
-ITALY               2 H AHEAD OF UTC MAR 31 - SEP 30, 0030 LOCAL
-JAMAICA             5 H BEHIND UTC IN WINTER
-JAMAICA             4 H BEHIND UTC APR 29 - OCT 29
-LIBYA               2 H AHEAD OF UTC
-MEXICO BAJA CAL N   8 H BEHIND UTC IN WINTER; NORTH BAJA CAL, TIJUANA
-MEXICO BAJA CAL N   7 H BEHIND UTC APR 29 - OCT 29
-MEXICO BAJA CAL S   7 H BEHIND UTC ALL YEAR; MAZATLAN
-MEXICO CENTRAL      6 H BEHIND UTC ALL YEAR; MEXICO CITY
-MONACO              1 H AHEAD UTC IN WINTER
-MONACO              2 H AHEAD UTC MAR 25 - SEP30
-PARAGUAY            4 H BEHIND UTC IN WINTER
-PARAGUAY            3 H BEHIND UTC SEP 30 - MAR 30
-POLAND              1 H AHEAD OF UTC IN WINTER
-POLAND              2 H AHEAD OF UTC MAR 24 - SEP     0200 LOCAL
-PORTUGAL            ON UTC IN WINTER
-PORTUGAL            1 H AHEAD OF UTC IN SUMMER MAR 31 - SEP 29   0100 LOCAL
-PORTUGAL AZORES     1 H BEHIND UTC IN WINTER
-PORTUGAL AZORES     ON UTC IN SUMMER MAR 31 - SEP 29
-PORTUGAL MADEIRA    ON UTC ALL YEAR;
-ROMANIA             2 H AHEAD OF UTC IN WINTER
-ROMANIA             3 H AHEAD OF UTC APR 3 - SEP 24
-SCOTLAND            SEE ENGLAND
-SWITZERLAND         1 H AHEAD OF UTC IN WINTER
-SWITZERLAND         2 H AHEAD OF UTC MAR 31 - SEP 30  0200 LOCAL
-TURKEY              3 H AHEAD OF UTC
-USA   EASTERN       5 H BEHIND UTC IN WINTER; NEW YORK, WASHINGTON
-USA   EASTERN       4 H BEHIND UTC APR 29 - OCT 29
-USA   CENTRAL       6 H BEHIND UTC IN WINTER; CHICAGO, HOUSTON
-USA   CENTRAL       5 H BEHIND UTC APR 29 - OCT 29
-USA   MOUNTAIN      7 H BEHIND UTC IN WINTER; DENVER
-USA   MOUNTAIN      6 H BEHIND UTC APR 29 - OCT 29
-USA   PACIFIC       8 H BEHIND UTC IN WINTER; L.A., SAN FRANCISCO
-USA   PACIFIC       7 H BEHIND UTC APR 29 - OCT 29
-USA   ALASKA STD    9 H BEHIND UTC IN WINTER; MOST OF ALASKA     (AKST)
-USA   ALASKA STD    8 H BEHIND UTC APR 29 - OCT 29               (AKDT)
-USA   ALEUTIAN     10 H BEHIND UTC IN WINTER; ISLANDS WEST OF 170W
-USA   - " -         9 H BEHIND UTC APR 29 - OCT 29
-USA   HAWAII       10 H BEHIND UTC ALL YEAR;
-USA   BERING       11 H BEHIND UTC ALL YEAR; SAMOA, MIDWAY
-USSR WEST EUROP     3 H AHEAD OF UTC IN WINTER; LENINGRAD, MOSCOW
-USSR WEST EUROP     4 H AHEAD OF UTC APR 1 - SEP 30
-USSR CENTRAL EUR    4 H AHEAD OF UTC IN WINTER; ROSTOV, BAKU
-USSR CENTRAL EUR    5 H AHEAD OF UTC APR 1 - SEP 30
-USSR EAST EUROP     5 H AHEAD OF UTC IN WINTER; SVERDLOVSK
-USSR EAST EUROP     6 H AHEAD OF UTC APR 1 - SEP 30
-USSR WEST SIBERIAN  6 H AHEAD OF UTC IN WINTER; TASHKENT, ALMA ATA
-USSR WEST SIBERIAN  7 H AHEAD OF UTC APR 1 - SEP 30
-USSR WEST-CENTRAL   7 H AHEAD OF UTC IN WINTER; NOVOSIBIRSK
-USSR WEST-CENTRAL   8 H AHEAD OF UTC APR 1 - SEP 30
-USSR WEST-CENTRAL   8 H AHEAD OF UTC IN WINTER; IRKUTSK
-USSR WEST-CENTRAL   9 H AHEAD OF UTC APR 1 - SEP 30
-USSR CENTRAL SIB    9 H AHEAD OF UTC IN WINTER; YAKUTSK
-USSR CENTRAL SIB   10 H AHEAD OF UTC APR 1 - SEP 30
-USSR CENTRAL SIB   10 H AHEAD OF UTC IN WINTER; VLADIVOSTOK
-USSR CENTRAL SIB   11 H AHEAD OF UTC APR 1 - SEP 30
-USSR EAST SIBERIA  11 H AHEAD OF UTC IN WINTER; MAGADAN
-USSR EAST SIBERIA  12 H AHEAD OF UTC APR 1 - SEP 30
-USSR EAST SIBERIA  12 H AHEAD OF UTC IN WINTER; PETROPAVLOVSK
-USSR EAST SIBERIA  13 H AHEAD OF UTC APR 1 - SEP 30
-USSR EAST SIBERIA  13 H AHEAD OF UTC IN WINTER; UELEN
-USSR EAST SIBERIA  14 H AHEAD OF UTC APR 1 - SEP 30
-WALES               SEE ENGLAND
diff --git a/time/usno1989 b/time/usno1989
deleted file mode 100644 (file)
index 91a69c6..0000000
+++ /dev/null
@@ -1,452 +0,0 @@
-# @(#)usno1989 7.1
-#
-# From Arthur David Olson (January 19, 1989):
-#
-# Here's time zone information from the United States Naval Observatory;
-# no corrections have been made, and there are some obvious challenges.
-# The USNO warns:
-#      DUE TO FREQUENT CHANGES IN THE LOCAL LAWS GOVERNING DAYLIGHT
-#      SAVING TIME, WE CANNOT GUARANTEE THE ACCURACY OF THIS
-#      INFORMATION.  PLEASE ALERT US TO ANY DISCREPANCY YOU MAY
-#      DISCOVER.
-#
-AFGHANISTAN         4.5H AHEAD OF UTC
-ALBANIA             1 H  AHEAD OF UTC
-ALBANIA             2 H  AHEAD OF UTC  MAR 27 - SEP 24
-ALBANIA                                (ESTIMATED)
-ALGERIA             1 H  AHEAD OF UTC
-AMERICAN SAMOA     11 H  BEHIND UTC
-ANDORRA             1 H  AHEAD OF UTC
-ANDORRA             2 H  AHEAD OF UTC  MAR 27 - SEP 24
-ANDORRA                                (ESTIMATED)
-ANGOLA              1 H  AHEAD OF UTC
-ARGENTINA           3 H  BEHIND UTC
-ARUBA               4 H  BEHIND UTC    ALSO BONAIRE, CURACAO,
-ARUBA                                  ST.MAARTEN
-AUSTRALIA  WEST     8 H  AHEAD OF UTC  PERTH, EXMOUTH
-AUSTRALIA  N.T.     9.5H AHEAD OF UTC  DARWIN  NO ADVANCED TIME
-AUSTRALIA  N.T.                                IN SUMMER
-AUSTRALIA  SOUTH    9.5H AHEAD OF UTC  ADELAIDE
-AUSTRALIA                              INCLUDING BROKEN HILL, NSW
-AUSTRALIA  SOUTH   10.5H AHEAD OF UTC  ADELAIDE OCT 30, '88-MAR
-AUSTRALIA  SOUTH                       18, '89 INCLUDING BROKEN
-AUSTRIALIA SOUTH                       HILL, NSW
-AUSTRALIA  QUEENL  10 H  AHEAD OF UTC
-AUSTRALIA  NSW     10 H  AHEAD OF UTC  SYDNEY
-AUSTRALIA  NSW     11 H  AHEAD OF UTC  SYDNEY OCT 30, '88-MAR 18,
-AUSTRALIA  NSW                         '89
-AUSTRALIA  TASM.   10 H  AHEAD OF UTC  HOBART
-AUSTRALIA  TASM.   11 H  AHEAD OF UTC  HOBART OCT 30, '88-MAR 18,
-AUSTRALIA  TASM.                       '89
-AUSTRIA             1 H  AHEAD OF UTC
-AUSTRIA             2 H  AHEAD OF UTC  MAR 27 - SEPT 24
-AZORES                   SEE PORTUGAL
-BAHAMAS             5 H  BEHIND UTC    EXCLUDING TURKS AND CAICOS
-BAHAMAS                                ISLANDS)
-BAHAMAS             4 H  BEHIND UTC    APR 3 - OCT 29 (SAME
-BAHAMAS                                EXCLUSION)
-BAHRAIN             3 H  AHEAD OF UTC
-BANGLADESH          6 H  AHEAD OF UTC
-BARBADOS            4 H  BEHIND UTC
-BELGIUM             1 H  AHEAD OF UTC
-BELGIUM             2 H  AHEAD OF UTC  MAR 27 - SEP 24
-BELIZE              6 H  BEHIND UTC
-BENIN PEOPLES REP   1 H  AHEAD OF UTC  DAHOMEY
-BERMUDA             4 H  BEHIND UTC
-BERMUDA             3 H  BEHIND UTC    APR 3 - OCT 29
-BHUTAN              6 H  AHEAD OF UTC
-BOLIVIA             4 H  BEHIND UTC
-BONAIRE             4 H  BEHIND UTC    ALSO ARUBA,CURACAO,
-BONAIRE                                ST.MAARTEN, SABA
-BOTSWANA            2 H  AHEAD OF UTC
-BRAZIL     WEST     5 H  BEHIND UTC    TERRITORY OF ACRE
-BRAZIL     WEST     4 H  BEHIND UTC    ACRE OCT 23, '88-FEB 11,
-BRAZIL                                 '89 (ESTIMATED)
-BRAZIL     CENTRAL  4 H  BEHIND UTC    MANAUS
-BRAZIL     CENTRAL  3 H  BEHIND UTC    MANAUS OCT 23, '88-FEB 11,
-BRAZIL     CENTRAL                     '89 (ESTIMATED)
-BRAZIL     EAST     3 H  BEHIND UTC    COASTAL STATES, RIO, SAO
-BRAZIL     EAST                        PAULO, BRASILIA
-BRAZIL     EAST     2 H  BEHIND UTC    COASTAL STATES, RIO, SAO
-BRAZIL                                 PAULO, BRASILIA OCT 23,
-BRAZIL                                 '88-FEB 11, '89
-BRAZIL                                 (ESTIMATED)
-BRAZIL              2 H  BEHIND UTC    ATLANTIC ISLANDS, FERNANDO
-BRAZIL                                 DE NORONHA
-BRAZIL              1 H  BEHIND UTC    OCT 23, '88-FEB 11, '89
-BRAZIL                                 (ESTIMATED)
-BRAZIL              3 H  BEHIND UTC    FOR MOST MAJOR AIRPORTS.
-BRITISH VIRGIN I.   4 H  BEHIND UTC
-BRUNEI              8 H  AHEAD OF UTC
-BULGARIA            2 H  AHEAD OF UTC
-BULGARIA            3 H  AHEAD OF UTC  MAR 27 - SEP 24
-BURKINA FASO        ON UTC
-BURMA               6.5H AHEAD OF UTC
-BURUNDI             2 H  AHEAD OF UTC
-CAMBODIA            SEE KAMPUCHEA
-CAMEROON            1 H  AHEAD OF UTC
-CANADA   NEW FDL    3.5H BEHIND UTC    ST.JOHN'S
-CANADA   NEW FDL    1.5H BEHIND UTC    APR 3 - OCT 29
-CANADA   ATLANTIC   4 H  BEHIND UTC    HALIFAX
-CANADA   ATLANTIC   3 H  BEHIND UTC    APR 3 - OCT 29
-CANADA   EASTERN    5 H  BEHIND UTC    TORONTO, MONTREAL, OTTAWA
-CANADA   EASTERN    4 H  BEHIND UTC    APR 3 - OCT 29
-CANADA   CENTRAL    6 H  BEHIND UTC    REGINA, WINNIPEG
-CANADA   CENTRAL    5 H  BEHIND UTC    APR 3 - OCT 29
-CANADA   MOUNTAIN   7 H  BEHIND UTC    CALGARY, EDMONTON
-CANADA   MOUNTAIN   6 H  BEHIND UTC    APR 3 - OCT 29
-CANADA   PACIFIC    8 H  BEHIND UTC    VANCOUVER
-CANADA   PACIFIC    7 H  BEHIND UTC    APR 3 - OCT 29
-CANADA   YUKON      SAME AS PACIFIC    DAWSON
-CAPE VERDE          1 H  BEHIND UTC
-CAYMAN ISLANDS      5 H  BEHIND UTC
-CAROLINE ISLAND    10 H  AHEAD OF UTC  EXCLUDING PONAPE IS.,
-CAROLINE ISLAND                       KUSAIE, AND PINGELAP
-CENTRAL AFRICA      1 H  AHEAD OF UTC
-CEYLON              5.5H AHEAD OF UTC, SEE SRI LANKA
-CHAD                1 H  AHEAD OF UTC
-CHANNEL ISLANDS     SEE ENGLAND
-CHILE               4 H  BEHIND UTC    CONTINENTAL
-CHILE               3 H  BEHIND UTC    OCT 9, '88-MAR 11, '89
-CHILE               6 H  BEHIND UTC    EASTER ISLAND
-CHILE               5 H  BEHIND UTC    OCT 9, '88-MAR 11, '89
-CHINA               8 H  AHEAD OF UTC  ALL OF CHINA, INCL TAIWAN
-CHINA               9 H  AHEAD OF UTC  APR 17 - SEP 10
-COCOS (Keeling) I.  6.5H AHEAD OF UTC
-COLOMBIA            5 H  BEHIND UTC
-COMOROS             3 H  AHEAD OF UTC
-CONGO               1 H  AHEAD OF UTC
-COOK ISLANDS       10 H  BEHIND UTC
-COOK ISLANDS        9.5H  BEHIND UTC   OCT 30, '88-MAR 24, '89
-COOK ISLANDS                           (ESTIMATED)
-COSTA RICA          6 H  BEHIND UTC
-COTE D'IVOIRE       ON UTC
-CUBA                5 H  BEHIND UTC
-CUBA                4 H  BEHIND UTC    MAR 20 - OCT 8
-CURACAO             4 H  BEHIND UTC    ALSO BONAIRE, ARUBA,
-CURACAO                                ST.MAARTEN
-CYPRUS              2 H  AHEAD OF UTC
-CYPRUS              3 H  AHEAD OF UTC  MAR 27 - SEP 24
-CZECHOSLOVAKIA      1 H  AHEAD OF UTC
-CZECHOSLOVAKIA      2 H  AHEAD OF UTC  MAR 27 - SEP 24
-DENMARK             1 H  AHEAD OF UTC
-DENMARK             2 H  AHEAD OF UTC  MAR 27 - SEP 24
-DENMK. FAEROE IS    1 H  AHEAD OF UTC  MAR 27 - SEP 24
-DJIBOUTI            3 H  AHEAD OF UTC
-DOMINICA            4 H  BEHIND UTC
-DOMINICAN REP       4 H  BEHIND UTC
-ECUADOR             5 H  BEHIND UTC    CONTINENTAL
-ECUADOR             6 H  BEHIND UTC    GALAPAGOS ISLANDS
-EGYPT               2 H  AHEAD OF UTC
-EGYPT               3 H  AHEAD OF UTC  MAY 17 - SEP 30 (AFTER
-EGYPT                                  RAMADAN)
-EL SALVADOR         6 H  BEHIND UTC
-ENGLAND             ON UTC             (WALES, SCOTLAND, N.I.,
-ENGLAND                                CH. IS.)
-ENGLAND             1 H  AHEAD OF UTC  MAR 27 - OCT 22
-ENEZUELA           4 H  BEHIND UTC
-EQUITORIAL GUINEA   1 H  AHEAD OF UTC
-ETHIOPIA            3 H  AHEAD OF UTC
-FALKLAND ISLANDS    4 H  BEHIND UTC
-FALKLAND ISLANDS    3 H  BEHIND UTC    SEP 11, '88-APR 15, '89
-FALKLAND ISLANDS                       (ESTIMATED)
-FAROE ISLAND        ON UTC
-FAROE ISLAND        1 H  AHEAD OF UTC  MAR 27 - SEP 24
-FIJI               12 H  AHEAD OF UTC
-FINLAND             2 H  AHEAD OF UTC
-FINLAND             3 H  AHEAD OF UTC  MAR 27 - SEP 24
-FRANCE              1 H  AHEAD OF UTC
-FRANCE              2 H  AHEAD OF UTC  MAR 27 - SEP 24
-FRENCH GUIANA       3 H  BEHIND UTC
-FRENCH POLYNESIA    9 H  BEHIND UTC    GAMBIER ISLAND
-FRENCH POLYNESIA    9.5H BEHIND UTC    MARQUESAS ISLANDS
-FRENCH POLYNESIA   10 H  BEHIND UTC    SOCIETY ISLANDS, TUBUAI
-FRENCH POLYNESIA                       ISLANDS, TUAMOTU ISLAND,
-FRENCH POLYNESIA                       TAHITI
-GABON               1 H  AHEAD OF UTC
-GAMBIA              ON UTC
-GERMANY ALL         1 H  AHEAD OF UTC
-GERMANY ALL         2 H  AHEAD OF UTC  MAR 27 - SEP 24
-GHANA               ON UTC
-GIBRALTAR           1 H  AHEAD OF UTC
-GIBRALTAR           2 H  AHEAD OF UTC  MAR 27 - SEP 24
-GREECE              2 H  AHEAD OF UTC
-GREECE              3 H  AHEAD OF UTC  MAR 27 - SEP 24
-GREENLAND           4 H  BEHIND UTC    THULE AIRBASE YEAR ROUND
-GREENLAND           3 H  BEHIND UTC    ANGMAGSSALIK AND W. COAST
-GREENLAND           2 H  BEHIND UTC    MAR 27 - SEP 24
-GREENLAND           1 H  BEHIND UTC    SCORESBYSUND
-GREENLAND           ON UTC             MAR 27 - SEP 24
-GRENADA             4 H  BEHIND UTC
-GUADELOUPE          4 H  BEHIND UTC    ST. BARTHELEMY, NORTHERN
-GUADELOUPE                             ST. MARTIN MARTINIQUE
-GUAM               10 H  AHEAD OF UTC
-GUATEMALA           6 H  BEHIND UTC
-GUINEA              ON UTC
-GUINEA BISSAU       ON UTC
-GUINEA REPUBLIC     ON UTC
-GUINEA EQUATORIAL   1 H  AHEAD OF UTC
-GUYANA              3 H  BEHIND UTC
-HAITI               5 H  BEHIND UTC
-HAITI               4 H  BEHIND UTC    APR 3 - OCT 29
-HOLLAND             SEE NETHERLANDS
-HONDURAS            6 H  BEHIND UTC
-HONG KONG           8 H  AHEAD OF UTC
-HUNGARY             1 H  AHEAD OF UTC
-HUNGARY             2 H  AHEAD OF UTC  MAR 27 - SEP 24
-ICELAND             ON UTC
-INDIA               5.5H AHEAD OF UTC  INCLUDING ANDAMAN ISLANDS
-INDONESIA WEST      7 H  AHEAD OF UTC  SUMATRA, JAVA, BALI,
-INDONESIA WEST                         JAKARTA
-INDONESIA CENTRAL   8 H  AHEAD OF UTC  KALIMANTAN, SULAWESI
-INDONESIA EAST      9 H  AHEAD OF UTC  IRIAN, BARAT
-IRAN                3.5H AHEAD OF UTC
-IRAQ                3 H  AHEAD OF UTC
-IRAQ                4 H  AHEAD OF UTC  APR 1 - SEP 30
-IRELAND             ON UTC
-IRELAND             1 H  AHEAD OF UTC  MAR 27 - OCT 22
-ISRAEL              2 H  AHEAD OF UTC
-ISRAEL              3 H  AHEAD OF UTC  APR 10 - SEP 3
-ITALY               1 H  AHEAD OF UTC
-ITALY               2 H  AHEAD OF UTC  MAR 27 - SEP 24
-IVORY COAST         ON UTC
-IWAN              8 H  AHEAD OF UTC
-JAMAICA             5 H  BEHIND UTC
-JAPAN               9 H  AHEAD OF UTC
-JOHNSTON ISLAND    10 H  BEHIND UTC
-JORDAN              2 H  AHEAD OF UTC
-JORDAN              3 H  AHEAD OF UTC  APR 1 - OCT 6
-KAMPUCHEA           7 H  AHEAD OF UTC
-KENYA               3 H  AHEAD OF UTC
-KIRIBATI, REP OF   12 H  AHEAD OF UTC  CANTON, ENDERBURY ISLANDS
-KIRIBATI, REP OF   11 H  AHEAD OF UTC  CHRISTMAS ISLAND
-KOREA               9 H  AHEAD OF UTC
-KOREA, REP OF       9 H  AHEAD OF UTC
-KOREA, REP OF      10 H  AHEAD OF UTC  MAY 8 - OCT 8
-KUWAIT              3 H  AHEAD OF UTC
-KUSAIE, PINGELAP  12 H  AHEAD OF UTC  INCLUDING MARSHALL IS.,
-KUSAIE, PINGELAP                      EXCLUDING KWAJALEIN)
-KWAJALEIN         12 H  BEHIND UTC
-LAOS                7 H  AHEAD OF UTC
-LEBANON             2 H  AHEAD OF UTC
-LEBANON             3 H  AHEAD OF UTC  JUN 1 - OCT 31
-LEEWARD ISLANDS     4 H BEHIND UTC     ANTIGUA, DOMINICA,
-LEEWARD ISLANDS                        MONTSERRAT, ST.
-LEEWARD ISLAANDS                       CHRISTOPHER, ST. KITTS,
-LEEWARD ISLANDS                        NEVIS, ANGUILLA
-LESOTHO             2 H  AHEAD OF UTC
-LIBERIA             ON UTC
-LIBYAN ARAB         1 H  AHEAD OF UTC  JAMAHIRIYA/LIBYA
-LIBYAN ARAB         2 H  AHEAD OF UTC  APR 1 - SEP 30 JAMAHIRIYA/LIBYA
-LIECHTENSTEIN       1 H  AHEAD OF UTC
-LIECHTENSTEIN       2 H  AHEAD OF UTC  MAR 27 - SEP 24
-LUXEMBOURG          1 H  AHEAD OF UTC
-LUXEMBOURG          2 H  AHEAD OF UTC  MAR 27 - SEP 24
-MACAO               8 H  AHEAD OF UTC
-MADAGASCAR          3 H  AHEAD OF UTC
-MADEIRA             SEE PORTUGAL
-MALAWI              2 H  AHEAD OF UTC
-MALAYSIA            8 H  AHEAD OF UTC
-MALDIVES            5 H  AHEAD OF UTC
-MALI                ON UTC
-MALTA               1 H  AHEAD OF UTC
-MALTA               2 H  AHEAD OF UTC  MAR 27 - SEP 24
-MARTINIQUE          4 H  BEHIND UTC
-MAURITANIA          ON UTC
-MAURITIUS           4 H  AHEAD OF UTC
-MARIANA ISLAND    10 H  AHEAD OF UTC  EXCLUDING GUAM
-MEXICO BAJA CAL N   7 H  BEHIND UTC    BAJA CALIFORNIA SUR AND
-MEXICO BAJA CAL N                      N. PACIFIC COAST (STATES
-MEXICO BAJA CAL N                      OF SINALOA AND SONORA)
-MEXICO BAJA CAL N   8 H  BEHIND UTC    ABOVE 28TH PARALLAL APR 3
-MEXICO BAJA CAL N                      - OCT 29
-MEXICO BAJA CAL N   7 H  BEHIND UTC    ABOVE 28TH PARALLAL APR 3
-MEXICO BAJA CAL N                      - 0CT 29
-MEXICO              6 H  BEHIND UTC    STATES OF DURANGO,
-MEXICO                                 COAHUILA, NUEVO LEON,
-MEXICO                                 TAMAULIPAS
-MEXICO              5 H  BEHIND UTC    STATES OF DURANGO,
-MEXICO                                 COAHUILA, NUEVO LEON,
-MEXICO                                 TAMAULIPAS  APR 3 - OCT 29
-MEXICO              6 H  BEHIND UTC    GENERAL MEXICO, STATES OF
-MEXICO                                 CAMPECHE, QUINTANA ROO AND
-MEXICO                                 YUCATAN
-MIDWAY ISLAND      11 H  BEHIND UTC
-MONACO              1 H  AHEAD OF UTC
-MONACO              2 H  AHEAD OF UTC  MAR 27 - SEP 24
-MONGOLIA            8 H  AHEAD OF UTC
-MONGOLIA            9 H  AHEAD OF UTC  MAR 27 - SEP 24
-MONTSERRAT          4 H  BEHIND UTC
-MOROCCO             ON UTC
-MOZAMBIQUE          2 H  AHEAD OF UTC
-NAMIBIA             2 H  AHEAD OF UTC
-NAURU, REP OF      12 H  AHEAD OF UTC
-NEPAL              5H45M AHEAD OF UTC
-NETHERLANDS         1 H  AHEAD OF UTC
-NETHERLANDS         2 H  AHEAD OF UTC  MAR 27 - SEP 24
-NETHERLANDS         4 H  BEHIND UTC    ANTILLES AND SOUTHERN ST.
-NETHERLANDS                            MAARTEN
-NEW CALEDONIA      11 H  AHEAD OF UTC
-NEW HEBRIDES        SEE VANUATU
-NEW ZEALAND        12 H  AHEAD OF UTC  (EXCLUDING CHATHAM ISLAND)
-NEW ZEALAND        13 H  AHEAD OF UTC  OCT 30, '88-MAR 4, '89
-NEW ZEALAND       12H45M AHEAD OF UTC  CHATHAM ISLAND
-NICARAGUA           6 H  BEHIND UTC
-NIGER               1 H  AHEAD OF UTC
-NIGERIA             1 H  AHEAD OF UTC
-NIUE ISLAND        11 H  BEHIND UTC
-NORFOLK ISLAND    11H30M AHEAD OF UTC
-NORTHERN IRELAND    ON UTC             WALES, SCOTLAND, N.I.,
-NORTHERN IRELAND                       CH.IS.
-NORTHERN IRELAND    1 H  AHEAD OF UTC  MAR 27 - OCT 22
-NORWAY              1 H  AHEAD OF UTC
-NORWAY              2 H  AHEAD OF UTC  MAR 27 - SEP 24
-OGO                ON UTC
-OMAN                4 H  AHEAD OF UTC
-PACIFIC ISLAND T.T.
-PALAU ISLAND       9 H  AHEAD OF UTC
-PAKISTAN            5 H  AHEAD OF UTC
-PANAMA              5 H  BEHIND UTC
-PAPUA NEW GUINEA   10 H  AHEAD OF UTC  INCLUDING BOUGAINVILLE
-PAPUA NEW GUINEA                       ISLAND
-PARAGUAY            4 H  BEHIND UTC
-PARAGUAY            3 H  BEHIND UTC    OCT 1, '88-MAR 31, '89
-PERU                5 H  BEHIND UTC
-PHILIPPINES         8 H  AHEAD OF UTC
-PONAPE ISLAND     11 H  AHEAD OF UTC
-POLAND              1 H  AHEAD OF UTC
-POLAND              2 H  AHEAD OF UTC  MAR 27 - SEP 24
-PORTUGAL MAINLAND   ON UTC
-PORTUGAL MAINLAND   1 H  AHEAD OF UTC  MAR 27 - SEP 24
-PORTUGAL AZORES     1 H  BEHIND UTC
-PORTUGAL AZORES     ON UTC             MAR 27 - SEP 24
-PORTUGAL MADEIRA    ON UTC
-PORTUGAL MADEIRA    1 H  AHEAD OF UTC  MAR 27 - SEP 24
-PUERTO RICO         4 H  BEHIND UTC
-QATAR               3 H  AHEAD OF UTC
-ROMANIA             2 H  AHEAD OF UTC
-ROMANIA             3 H  AHEAD OF UTC  MAR 27 - SEP 24
-RUSSIA              SEE USSR
-RWANDA              2 H  AHEAD OF UTC
-SABA                4 H  BEHIND UTC    ALSO BONAIRE, CURACAO,
-SAMOA              11 H  BEHIND UTC
-SAN MARINO          1 H  AHEAD OF UTC
-SAN MARINO          2 H  AHEAD OF UTC  MAR 27 - SEP 24
-SAN SALVADOR        6  H  BEHIND UTC
-SAO TOME ISLAND     ON UTC             AND PRINCIPE ISLAND
-SAUDI ARABIA        3 H  AHEAD OF UTC
-SCOTLAND            SEE ENGLAND
-SENEGAL             ON UTC
-SEYCHELLES          4 H  AHEAD OF UTC
-SIERRA LEONE        ON UTC
-SINGAPORE           8 H  AHEAD OF UTC
-SOLOMON ISLANDS    11 H  AHEAD OF UTC  EXCLUDING BOUGAINVILLE
-SOLOMON ISLANDS                        ISLAND
-SOMALI              3 H  AHEAD OF UTC
-SOUTH AFRICA        2 H  AHEAD OF UTC
-SPAIN  CANARY IS    ON UTC
-SPAIN  CANARY IS    1 H  AHEAD OF UTC  MAR 27 - SEP 24
-SPAIN               1 H  AHEAD OF UTC  CONTINENTAL, BALEARIC AND
-SPAIN                                  MALLORCA ISLANDS
-SPAIN               2 H  AHEAD OF UTC  CONTINENTAL, BALEARIC AND
-SPAIN                                  MALLORCA ISLANDS  MAR 27 -
-SPAIN                                  SEP 24
-SPAIN  MAINLAND     1 H  AHEAD OF UTC  MELILLA
-SPAIN  MAINLAND     2 H  AHEAD OF UTC  MAR 27 - SEP 24
-SRI LANKA          5H30M AHEAD OF UTC
-ST.MAARTEN
-ST.KITTS-NEVIS     4 H  BEHIND UTC
-ST.LUCIA           4 H  BEHIND UTC
-ST.PIERRE          3 H  BEHIND UTC    INCLUDING MIQUELON
-ST.PIERRE          2 H  BEHIND UTC    INLCUDING MIQUELON  APR 3
-ST.PIERRE                             - OCT 29
-ST.VINCENT         4 H  BEHIND UTC    INCLUDING THE GRENADINES
-ST. HELENA          ON UTC
-SURINAME            3 H  BEHIND UTC
-SWAZILAND           2 H  AHEAD OF UTC
-SWEDEN              1 H  AHEAD OF UTC
-SWEDEN              2 H  AHEAD OF UTC  MAR 27 - SEP 24
-SWITZERLAND         1 H  AHEAD OF UTC
-SWITZERLAND         2 H  AHEAD OF UTC  MAR 27 - SEP 24
-SYRIA               2 H  AHEAD OF UTC
-SYRIA               3 H  AHEAD OF UTC  MAR 15 - OCT 30
-TAHITI             10 H  BEHIND UTC
-TANZANIA            3 H  AHEAD OF UTC
-THAILAND            7 H  AHEAD OF UTC
-TRINIDAD / TOBAGO   4 H  BEHIND UTC
-TUNISIA             1 H  AHEAD OF UTC
-TUNISIA             2 H  AHEAD OF UTC  APR 10 - SEP 24
-TURKEY              2 H  AHEAD OF UTC
-TURKEY              3 H  AHEAD OF UTC  MAR 27 - SEP 24
-TURKS AND CAICOS    5 H  BEHIND UTC
-TURKS AND CAICOS    4 H  BEHIND UTC    APR 3 - OCT 29
-TUVALU             12 H  AHEAD OF UTC
-UDAN               2 H  AHEAD OF UTC
-UGANDA              3 H  AHEAD OF UTC
-UNITED ARAB EMIR.   4 H  AHEAD OF UTC  ABU DHABI, DUBAI, SHARJAH,
-UNITED ARAB EMIR                       RAS AL KHAIMAH
-UNITED KINGDOM      ON UTC             WALES, SCOTLAND, N.I., CH.
-UNITED KINGDOM                         IS.
-UNITED KINGDOM      1 H  AHEAD OF UTC  MAR 27 - OCT 22
-UNITED STATES       SEE USA
-UPPER VOLTA         ON UTC
-URUGUAY             3 H  BEHIND UTC
-URUGUAY             2 H  BEHIND UTC    DEC 11, '88-FEB 25, '89
-URAGUAY                                (ESTIMATED)
-USA  EASTERN       5 H  BEHIND UTC    NEW YORK, WASHINGTON
-USA  EASTERN       4 H  BEHIND UTC    APR 3 - OCT 30
-USA  CENTRAL       6 H  BEHIND UTC    CHICAGO, HOUSTON
-USA  CENTRAL       5 H  BEHIND UTC    APR 3 - OCT 30
-USA  MOUNTAIN      7 H  BEHIND UTC    DENVER
-USA  MOUNTAIN      6 H  BEHIND UTC    APR 3 - OCT 30
-USA  PACIFIC       8 H  BEHIND UTC    L.A., SAN FRANCISCO
-USA  PACIFIC       7 H  BEHIND UTC    APR 3 - OCT 30
-USA  ALASKA STD    9 H  BEHIND UTC    MOST OF ALASKA     (AKST)
-USA  ALASKA STD    8 H  BEHIND UTC    APR 3 - OCT 30 (AKDT)
-USA  ALEUTIAN     10 H  BEHIND UTC    ISLANDS WEST OF 170W
-USA  - " -         9 H  BEHIND UTC    APR 3 - OCT 30
-USA  HAWAII       10 H  BEHIND UTC
-USA  BERING       11 H  BEHIND UTC    SAMOA, MIDWAY
-USA  FOR SPECIFIC INFO ON USA ZONES/TIMES CALL DOT 202-426-4520
-USSR WEST EUROP     3 H  AHEAD OF UTC  LENINGRAD, MOSCOW
-USSR WEST EUROP     4 H  AHEAD OF UTC  APR 1 - SEP 30
-USSR CENTRAL EUR    4 H  AHEAD OF UTC  ROSTOV, BAKU
-USSR CENTRAL EUR    5 H  AHEAD OF UTC  APR 1 - SEP 30
-USSR EAST EUROP     5 H  AHEAD OF UTC  SVERDLOVSK
-USSR EAST EUROP     6 H  AHEAD OF UTC  APR 1 - SEP 30
-USSR WEST SIBERIAN  6 H  AHEAD OF UTC  TASHKENT, ALMA ATA
-USSR WEST SIBERIAN  7 H  AHEAD OF UTC  APR 1 - SEP 30
-USSR WEST-CENTRAL   7 H  AHEAD OF UTC  NOVOSIBIRSK
-USSR WEST-CENTRAL   8 H  AHEAD OF UTC  APR 1 - SEP 30
-USSR WEST-CENTRAL   8 H  AHEAD OF UTC  IRKUTSK
-USSR WEST-CENTRAL   9 H  AHEAD OF UTC  APR 1 - SEP 30
-USSR CENTRAL SIB    9 H  AHEAD OF UTC  YAKUTSK
-USSR CENTRAL SIB   10 H  AHEAD OF UTC  APR 1 - SEP 30
-USSR CENTRAL SIB   10 H  AHEAD OF UTC  VLADIVOSTOK
-USSR CENTRAL SIB   11 H  AHEAD OF UTC  APR 1 - SEP 30
-USSR EAST SIBERIA  11 H  AHEAD OF UTC  MAGADAN
-USSR EAST SIBERIA  12 H  AHEAD OF UTC  APR 1 - SEP 30
-USSR EAST SIBERIA  12 H  AHEAD OF UTC  PETROPAVLOVSK
-USSR EAST SIBERIA  13 H  AHEAD OF UTC  APR 1 - SEP 30
-USSR EAST SIBERIA  13 H  AHEAD OF UTC  UELEN
-USSR EAST SIBERIA  14 H  AHEAD OF UTC  APR 1 - SEP 30
-VANUATU            11 H  AHEAD OF UTC  (NEW HEBRIDES)
-VANUATU            12 H  AHEAD OF UTC  SEP 25, '88-MAR 25, '89
-VANUATU                                (ESTIMATED)
-VATICAN             1 H  AHEAD OF UTC
-VATICAN             2 H  AHEAD OF UTC  MAR 27 - SEP 24
-VIETNAM             7 H  AHEAD OF UTC
-VIRGIN ISLANDS      4 H  BEHIND UTC    ST.CROIX, ST.THOMAS,
-VIRGIN ISLANDS                         ST.JOHN
-WAKE ISLAND        12 H  AHEAD OF UTC
-WALES               SEE ENGLAND
-WALLIS/FUTUNA IS.  12 H  AHEAD OF UTC
-WINDWARD ISLANDS    4 H  BEHIND UTC    GRENADA, ST. LUCIA
-YEMEN               3 H  AHEAD OF UTC  BOTH REPUBLICS
-YUGOSLAVIA          1 H  AHEAD OF UTC
-YUGOSLAVIA          2 H  AHEAD OF UTC  MAR 27 - SEP 24
-ZAIRE  EAST         1 H  AHEAD OF UTC  KINSHASA MBANDAKA
-ZAIRE  WEST         2 H  AHEAD OF UTC  LUBUMBASHI, KASAI, KIVU,
-ZAIRE  WEST                            HAUT-ZAIRE, SHABA
-ZAMBIA              2 H  AHEAD OF UTC
-ZIMBABWE            2 H  AHEAD OF UTC
diff --git a/time/usno1989a b/time/usno1989a
deleted file mode 100644 (file)
index 42cd9b3..0000000
+++ /dev/null
@@ -1,452 +0,0 @@
-# @(#)usno1989a        7.2
-#
-# From Arthur David Olson (February 7, 1994):
-#
-# Here's time zone information from the United States Naval Observatory,
-# with corrections from Paul Eggert (eggert@twinsun.com).
-# The USNO warns:
-#      DUE TO FREQUENT CHANGES IN THE LOCAL LAWS GOVERNING DAYLIGHT
-#      SAVING TIME, WE CANNOT GUARANTEE THE ACCURACY OF THIS
-#      INFORMATION.  PLEASE ALERT US TO ANY DISCREPANCY YOU MAY
-#      DISCOVER.
-#
-AFGHANISTAN         4.5H AHEAD OF UTC
-ALBANIA             1 H  AHEAD OF UTC
-ALBANIA             2 H  AHEAD OF UTC  MAR 27 - SEP 24
-ALBANIA                                (ESTIMATED)
-ALGERIA             1 H  AHEAD OF UTC
-AMERICAN SAMOA     11 H  BEHIND UTC
-ANDORRA             1 H  AHEAD OF UTC
-ANDORRA             2 H  AHEAD OF UTC  MAR 27 - SEP 24
-ANDORRA                                (ESTIMATED)
-ANGOLA              1 H  AHEAD OF UTC
-ARGENTINA           3 H  BEHIND UTC
-ARUBA               4 H  BEHIND UTC    ALSO BONAIRE, CURACAO,
-ARUBA                                  ST.MAARTEN
-AUSTRALIA  WEST     8 H  AHEAD OF UTC  PERTH, EXMOUTH
-AUSTRALIA  N.T.     9.5H AHEAD OF UTC  DARWIN  NO ADVANCED TIME
-AUSTRALIA  N.T.                                IN SUMMER
-AUSTRALIA  SOUTH    9.5H AHEAD OF UTC  ADELAIDE
-AUSTRALIA                              INCLUDING BROKEN HILL, NSW
-AUSTRALIA  SOUTH   10.5H AHEAD OF UTC  ADELAIDE OCT 30, '88-MAR
-AUSTRALIA  SOUTH                       18, '89 INCLUDING BROKEN
-AUSTRIALIA SOUTH                       HILL, NSW
-AUSTRALIA  QUEENL  10 H  AHEAD OF UTC
-AUSTRALIA  NSW     10 H  AHEAD OF UTC  SYDNEY
-AUSTRALIA  NSW     11 H  AHEAD OF UTC  SYDNEY OCT 30, '88-MAR 18,
-AUSTRALIA  NSW                         '89
-AUSTRALIA  TASM.   10 H  AHEAD OF UTC  HOBART
-AUSTRALIA  TASM.   11 H  AHEAD OF UTC  HOBART OCT 30, '88-MAR 18,
-AUSTRALIA  TASM.                       '89
-AUSTRIA             1 H  AHEAD OF UTC
-AUSTRIA             2 H  AHEAD OF UTC  MAR 27 - SEPT 24
-AZORES                   SEE PORTUGAL
-BAHAMAS             5 H  BEHIND UTC    EXCLUDING TURKS AND CAICOS
-BAHAMAS                                ISLANDS)
-BAHAMAS             4 H  BEHIND UTC    APR 3 - OCT 29 (SAME
-BAHAMAS                                EXCLUSION)
-BAHRAIN             3 H  AHEAD OF UTC
-BANGLADESH          6 H  AHEAD OF UTC
-BARBADOS            4 H  BEHIND UTC
-BELGIUM             1 H  AHEAD OF UTC
-BELGIUM             2 H  AHEAD OF UTC  MAR 27 - SEP 24
-BELIZE              6 H  BEHIND UTC
-BENIN PEOPLES REP   1 H  AHEAD OF UTC  DAHOMEY
-BERMUDA             4 H  BEHIND UTC
-BERMUDA             3 H  BEHIND UTC    APR 3 - OCT 29
-BHUTAN              6 H  AHEAD OF UTC
-BOLIVIA             4 H  BEHIND UTC
-BONAIRE             4 H  BEHIND UTC    ALSO ARUBA,CURACAO,
-BONAIRE                                ST.MAARTEN, SABA
-BOTSWANA            2 H  AHEAD OF UTC
-BRAZIL     WEST     5 H  BEHIND UTC    TERRITORY OF ACRE
-BRAZIL     WEST     4 H  BEHIND UTC    ACRE OCT 23, '88-FEB 11,
-BRAZIL                                 '89 (ESTIMATED)
-BRAZIL     CENTRAL  4 H  BEHIND UTC    MANAUS
-BRAZIL     CENTRAL  3 H  BEHIND UTC    MANAUS OCT 23, '88-FEB 11,
-BRAZIL     CENTRAL                     '89 (ESTIMATED)
-BRAZIL     EAST     3 H  BEHIND UTC    COASTAL STATES, RIO, SAO
-BRAZIL     EAST                        PAULO, BRASILIA
-BRAZIL     EAST     2 H  BEHIND UTC    COASTAL STATES, RIO, SAO
-BRAZIL                                 PAULO, BRASILIA OCT 23,
-BRAZIL                                 '88-FEB 11, '89
-BRAZIL                                 (ESTIMATED)
-BRAZIL              2 H  BEHIND UTC    ATLANTIC ISLANDS, FERNANDO
-BRAZIL                                 DE NORONHA
-BRAZIL              1 H  BEHIND UTC    OCT 23, '88-FEB 11, '89
-BRAZIL                                 (ESTIMATED)
-BRAZIL              3 H  BEHIND UTC    FOR MOST MAJOR AIRPORTS.
-BRITISH VIRGIN I.   4 H  BEHIND UTC
-BRUNEI              8 H  AHEAD OF UTC
-BULGARIA            2 H  AHEAD OF UTC
-BULGARIA            3 H  AHEAD OF UTC  MAR 27 - SEP 24
-BURKINA FASO        ON UTC
-BURMA               6.5H AHEAD OF UTC
-BURUNDI             2 H  AHEAD OF UTC
-CAMBODIA            SEE KAMPUCHEA
-CAMEROON            1 H  AHEAD OF UTC
-CANADA   NEW FDL    3.5H BEHIND UTC    ST.JOHN'S
-CANADA   NEW FDL    1.5H BEHIND UTC    APR 3 - OCT 29
-CANADA   ATLANTIC   4 H  BEHIND UTC    HALIFAX
-CANADA   ATLANTIC   3 H  BEHIND UTC    APR 3 - OCT 29
-CANADA   EASTERN    5 H  BEHIND UTC    TORONTO, MONTREAL, OTTAWA
-CANADA   EASTERN    4 H  BEHIND UTC    APR 3 - OCT 29
-CANADA   CENTRAL    6 H  BEHIND UTC    REGINA, WINNIPEG
-CANADA   CENTRAL    5 H  BEHIND UTC    APR 3 - OCT 29
-CANADA   MOUNTAIN   7 H  BEHIND UTC    CALGARY, EDMONTON
-CANADA   MOUNTAIN   6 H  BEHIND UTC    APR 3 - OCT 29
-CANADA   PACIFIC    8 H  BEHIND UTC    VANCOUVER
-CANADA   PACIFIC    7 H  BEHIND UTC    APR 3 - OCT 29
-CANADA   YUKON      SAME AS PACIFIC    DAWSON
-CAPE VERDE          1 H  BEHIND UTC
-CAYMAN ISLANDS      5 H  BEHIND UTC
-CAROLINE ISLAND    10 H  AHEAD OF UTC  EXCLUDING PONAPE IS.,
-CAROLINE ISLAND                        KUSAIE, AND PINGELAP
-CENTRAL AFRICA      1 H  AHEAD OF UTC
-CEYLON              5.5H AHEAD OF UTC, SEE SRI LANKA
-CHAD                1 H  AHEAD OF UTC
-CHANNEL ISLANDS     SEE ENGLAND
-CHILE               4 H  BEHIND UTC    CONTINENTAL
-CHILE               3 H  BEHIND UTC    OCT 9, '88-MAR 11, '89
-CHILE               6 H  BEHIND UTC    EASTER ISLAND
-CHILE               5 H  BEHIND UTC    OCT 9, '88-MAR 11, '89
-CHINA               8 H  AHEAD OF UTC  ALL OF CHINA, INCL TAIWAN
-CHINA               9 H  AHEAD OF UTC  APR 17 - SEP 10
-COCOS (Keeling) I.  6.5H AHEAD OF UTC
-COLOMBIA            5 H  BEHIND UTC
-COMOROS             3 H  AHEAD OF UTC
-CONGO               1 H  AHEAD OF UTC
-COOK ISLANDS       10 H  BEHIND UTC
-COOK ISLANDS        9.5H BEHIND UTC    OCT 30, '88-MAR 24, '89
-COOK ISLANDS                           (ESTIMATED)
-COSTA RICA          6 H  BEHIND UTC
-COTE D'IVOIRE       ON UTC
-CUBA                5 H  BEHIND UTC
-CUBA                4 H  BEHIND UTC    MAR 20 - OCT 8
-CURACAO             4 H  BEHIND UTC    ALSO BONAIRE, ARUBA,
-CURACAO                                ST.MAARTEN
-CYPRUS              2 H  AHEAD OF UTC
-CYPRUS              3 H  AHEAD OF UTC  MAR 27 - SEP 24
-CZECHOSLOVAKIA      1 H  AHEAD OF UTC
-CZECHOSLOVAKIA      2 H  AHEAD OF UTC  MAR 27 - SEP 24
-DENMARK             1 H  AHEAD OF UTC
-DENMARK             2 H  AHEAD OF UTC  MAR 27 - SEP 24
-DENMK. FAEROE IS    1 H  AHEAD OF UTC  MAR 27 - SEP 24
-DJIBOUTI            3 H  AHEAD OF UTC
-DOMINICA            4 H  BEHIND UTC
-DOMINICAN REP       4 H  BEHIND UTC
-ECUADOR             5 H  BEHIND UTC    CONTINENTAL
-ECUADOR             6 H  BEHIND UTC    GALAPAGOS ISLANDS
-EGYPT               2 H  AHEAD OF UTC
-EGYPT               3 H  AHEAD OF UTC  MAY 17 - SEP 30 (AFTER
-EGYPT                                  RAMADAN)
-EL SALVADOR         6 H  BEHIND UTC
-ENGLAND             ON UTC             (WALES, SCOTLAND, N.I.,
-ENGLAND                                CH. IS.)
-ENGLAND             1 H  AHEAD OF UTC  MAR 27 - OCT 22
-EQUATORIAL GUINEA   1 H  AHEAD OF UTC
-ETHIOPIA            3 H  AHEAD OF UTC
-FALKLAND ISLANDS    4 H  BEHIND UTC
-FALKLAND ISLANDS    3 H  BEHIND UTC    SEP 11, '88-APR 15, '89
-FALKLAND ISLANDS                       (ESTIMATED)
-FAROE ISLAND        ON UTC
-FAROE ISLAND        1 H  AHEAD OF UTC  MAR 27 - SEP 24
-FIJI               12 H  AHEAD OF UTC
-FINLAND             2 H  AHEAD OF UTC
-FINLAND             3 H  AHEAD OF UTC  MAR 27 - SEP 24
-FRANCE              1 H  AHEAD OF UTC
-FRANCE              2 H  AHEAD OF UTC  MAR 27 - SEP 24
-FRENCH GUIANA       3 H  BEHIND UTC
-FRENCH POLYNESIA    9 H  BEHIND UTC    GAMBIER ISLAND
-FRENCH POLYNESIA    9.5H BEHIND UTC    MARQUESAS ISLANDS
-FRENCH POLYNESIA   10 H  BEHIND UTC    SOCIETY ISLANDS, TUBUAI
-FRENCH POLYNESIA                       ISLANDS, TUAMOTU ISLAND,
-FRENCH POLYNESIA                       TAHITI
-GABON               1 H  AHEAD OF UTC
-GAMBIA              ON UTC
-GERMANY ALL         1 H  AHEAD OF UTC
-GERMANY ALL         2 H  AHEAD OF UTC  MAR 27 - SEP 24
-GHANA               ON UTC
-GIBRALTAR           1 H  AHEAD OF UTC
-GIBRALTAR           2 H  AHEAD OF UTC  MAR 27 - SEP 24
-GREECE              2 H  AHEAD OF UTC
-GREECE              3 H  AHEAD OF UTC  MAR 27 - SEP 24
-GREENLAND           4 H  BEHIND UTC    THULE AIRBASE YEAR ROUND
-GREENLAND           3 H  BEHIND UTC    ANGMAGSSALIK AND W. COAST
-GREENLAND           2 H  BEHIND UTC    MAR 27 - SEP 24
-GREENLAND           1 H  BEHIND UTC    SCORESBYSUND
-GREENLAND           ON UTC             MAR 27 - SEP 24
-GRENADA             4 H  BEHIND UTC
-GUADELOUPE          4 H  BEHIND UTC    ST. BARTHELEMY, NORTHERN
-GUADELOUPE                             ST. MARTIN MARTINIQUE
-GUAM               10 H  AHEAD OF UTC
-GUATEMALA           6 H  BEHIND UTC
-GUINEA              ON UTC
-GUINEA BISSAU       ON UTC
-GUINEA REPUBLIC     ON UTC
-GUINEA EQUATORIAL   1 H  AHEAD OF UTC
-GUYANA              3 H  BEHIND UTC
-HAITI               5 H  BEHIND UTC
-HAITI               4 H  BEHIND UTC    APR 3 - OCT 29
-HOLLAND             SEE NETHERLANDS
-HONDURAS            6 H  BEHIND UTC
-HONG KONG           8 H  AHEAD OF UTC
-HUNGARY             1 H  AHEAD OF UTC
-HUNGARY             2 H  AHEAD OF UTC  MAR 27 - SEP 24
-ICELAND             ON UTC
-INDIA               5.5H AHEAD OF UTC  INCLUDING ANDAMAN ISLANDS
-INDONESIA WEST      7 H  AHEAD OF UTC  SUMATRA, JAVA, BALI,
-INDONESIA WEST                         JAKARTA
-INDONESIA CENTRAL   8 H  AHEAD OF UTC  KALIMANTAN, SULAWESI
-INDONESIA EAST      9 H  AHEAD OF UTC  IRIAN, BARAT
-IRAN                3.5H AHEAD OF UTC
-IRAQ                3 H  AHEAD OF UTC
-IRAQ                4 H  AHEAD OF UTC  APR 1 - SEP 30
-IRELAND             ON UTC
-IRELAND             1 H  AHEAD OF UTC  MAR 27 - OCT 22
-ISRAEL              2 H  AHEAD OF UTC
-ISRAEL              3 H  AHEAD OF UTC  APR 10 - SEP 3
-ITALY               1 H  AHEAD OF UTC
-ITALY               2 H  AHEAD OF UTC  MAR 27 - SEP 24
-IVORY COAST         ON UTC
-JAMAICA             5 H  BEHIND UTC
-JAPAN               9 H  AHEAD OF UTC
-JOHNSTON ISLAND    10 H  BEHIND UTC
-JORDAN              2 H  AHEAD OF UTC
-JORDAN              3 H  AHEAD OF UTC  APR 1 - OCT 6
-KAMPUCHEA           7 H  AHEAD OF UTC
-KENYA               3 H  AHEAD OF UTC
-KIRIBATI, REP OF   12 H  AHEAD OF UTC  CANTON, ENDERBURY ISLANDS
-KIRIBATI, REP OF   11 H  AHEAD OF UTC  CHRISTMAS ISLAND
-KOREA               9 H  AHEAD OF UTC
-KOREA, REP OF       9 H  AHEAD OF UTC
-KOREA, REP OF      10 H  AHEAD OF UTC  MAY 8 - OCT 8
-KUWAIT              3 H  AHEAD OF UTC
-KUSAIE, PINGELAP   12 H  AHEAD OF UTC  INCLUDING MARSHALL IS.,
-KUSAIE, PINGELAP                       EXCLUDING KWAJALEIN)
-KWAJALEIN          12 H  BEHIND UTC
-LAOS                7 H  AHEAD OF UTC
-LEBANON             2 H  AHEAD OF UTC
-LEBANON             3 H  AHEAD OF UTC  JUN 1 - OCT 31
-LEEWARD ISLANDS     4 H  BEHIND UTC    ANTIGUA, DOMINICA,
-LEEWARD ISLANDS                        MONTSERRAT, ST.
-LEEWARD ISLAANDS                       CHRISTOPHER, ST. KITTS,
-LEEWARD ISLANDS                        NEVIS, ANGUILLA
-LESOTHO             2 H  AHEAD OF UTC
-LIBERIA             ON UTC
-LIBYAN ARAB         1 H  AHEAD OF UTC  JAMAHIRIYA/LIBYA
-LIBYAN ARAB         2 H  AHEAD OF UTC  APR 1 - SEP 30 JAMAHIRIYA/LIBYA
-LIECHTENSTEIN       1 H  AHEAD OF UTC
-LIECHTENSTEIN       2 H  AHEAD OF UTC  MAR 27 - SEP 24
-LUXEMBOURG          1 H  AHEAD OF UTC
-LUXEMBOURG          2 H  AHEAD OF UTC  MAR 27 - SEP 24
-MACAO               8 H  AHEAD OF UTC
-MADAGASCAR          3 H  AHEAD OF UTC
-MADEIRA             SEE PORTUGAL
-MALAWI              2 H  AHEAD OF UTC
-MALAYSIA            8 H  AHEAD OF UTC
-MALDIVES            5 H  AHEAD OF UTC
-MALI                ON UTC
-MALTA               1 H  AHEAD OF UTC
-MALTA               2 H  AHEAD OF UTC  MAR 27 - SEP 24
-MARTINIQUE          4 H  BEHIND UTC
-MAURITANIA          ON UTC
-MAURITIUS           4 H  AHEAD OF UTC
-MARIANA ISLANDS    10 H  AHEAD OF UTC  EXCLUDING GUAM
-MEXICO BAJA CAL N   7 H  BEHIND UTC    BAJA CALIFORNIA SUR AND
-MEXICO BAJA CAL N                      N. PACIFIC COAST (STATES
-MEXICO BAJA CAL N                      OF SINALOA AND SONORA)
-MEXICO BAJA CAL N   8 H  BEHIND UTC    ABOVE 28TH PARALLAL APR 3
-MEXICO BAJA CAL N                      - OCT 29
-MEXICO BAJA CAL N   7 H  BEHIND UTC    ABOVE 28TH PARALLAL APR 3
-MEXICO BAJA CAL N                      - 0CT 29
-MEXICO              6 H  BEHIND UTC    STATES OF DURANGO,
-MEXICO                                 COAHUILA, NUEVO LEON,
-MEXICO                                 TAMAULIPAS
-MEXICO              5 H  BEHIND UTC    STATES OF DURANGO,
-MEXICO                                 COAHUILA, NUEVO LEON,
-MEXICO                                 TAMAULIPAS  APR 3 - OCT 29
-MEXICO              6 H  BEHIND UTC    GENERAL MEXICO, STATES OF
-MEXICO                                 CAMPECHE, QUINTANA ROO AND
-MEXICO                                 YUCATAN
-MIDWAY ISLAND      11 H  BEHIND UTC
-MONACO              1 H  AHEAD OF UTC
-MONACO              2 H  AHEAD OF UTC  MAR 27 - SEP 24
-MONGOLIA            8 H  AHEAD OF UTC
-MONGOLIA            9 H  AHEAD OF UTC  MAR 27 - SEP 24
-MONTSERRAT          4 H  BEHIND UTC
-MOROCCO             ON UTC
-MOZAMBIQUE          2 H  AHEAD OF UTC
-NAMIBIA             2 H  AHEAD OF UTC
-NAURU, REP OF      12 H  AHEAD OF UTC
-NEPAL              5H45M AHEAD OF UTC
-NETHERLANDS         1 H  AHEAD OF UTC
-NETHERLANDS         2 H  AHEAD OF UTC  MAR 27 - SEP 24
-NETHERLANDS         4 H  BEHIND UTC    ANTILLES AND SOUTHERN ST.
-NETHERLANDS                            MAARTEN
-NEW CALEDONIA      11 H  AHEAD OF UTC
-NEW HEBRIDES        SEE VANUATU
-NEW ZEALAND        12 H  AHEAD OF UTC  (EXCLUDING CHATHAM ISLAND)
-NEW ZEALAND        13 H  AHEAD OF UTC  OCT 30, '88-MAR 4, '89
-NEW ZEALAND       12H45M AHEAD OF UTC  CHATHAM ISLAND
-NICARAGUA           6 H  BEHIND UTC
-NIGER               1 H  AHEAD OF UTC
-NIGERIA             1 H  AHEAD OF UTC
-NIUE ISLAND        11 H  BEHIND UTC
-NORFOLK ISLAND    11H30M AHEAD OF UTC
-NORTHERN IRELAND    ON UTC             WALES, SCOTLAND, N.I.,
-NORTHERN IRELAND                       CH.IS.
-NORTHERN IRELAND    1 H  AHEAD OF UTC  MAR 27 - OCT 22
-NORWAY              1 H  AHEAD OF UTC
-NORWAY              2 H  AHEAD OF UTC  MAR 27 - SEP 24
-OMAN                4 H  AHEAD OF UTC
-PACIFIC ISLAND T.T.
-PALAU ISLANDS       9 H  AHEAD OF UTC
-PAKISTAN            5 H  AHEAD OF UTC
-PANAMA              5 H  BEHIND UTC
-PAPUA NEW GUINEA   10 H  AHEAD OF UTC  INCLUDING BOUGAINVILLE
-PAPUA NEW GUINEA                       ISLAND
-PARAGUAY            4 H  BEHIND UTC
-PARAGUAY            3 H  BEHIND UTC    OCT 1, '88-MAR 31, '89
-PERU                5 H  BEHIND UTC
-PHILIPPINES         8 H  AHEAD OF UTC
-PONAPE ISLAND      11 H  AHEAD OF UTC
-POLAND              1 H  AHEAD OF UTC
-POLAND              2 H  AHEAD OF UTC  MAR 27 - SEP 24
-PORTUGAL MAINLAND   ON UTC
-PORTUGAL MAINLAND   1 H  AHEAD OF UTC  MAR 27 - SEP 24
-PORTUGAL AZORES     1 H  BEHIND UTC
-PORTUGAL AZORES     ON UTC             MAR 27 - SEP 24
-PORTUGAL MADEIRA    ON UTC
-PORTUGAL MADEIRA    1 H  AHEAD OF UTC  MAR 27 - SEP 24
-PUERTO RICO         4 H  BEHIND UTC
-QATAR               3 H  AHEAD OF UTC
-ROMANIA             2 H  AHEAD OF UTC
-ROMANIA             3 H  AHEAD OF UTC  MAR 27 - SEP 24
-RUSSIA              SEE USSR
-RWANDA              2 H  AHEAD OF UTC
-SABA                4 H  BEHIND UTC    ALSO BONAIRE, CURACAO,
-SAMOA              11 H  BEHIND UTC
-SAN MARINO          1 H  AHEAD OF UTC
-SAN MARINO          2 H  AHEAD OF UTC  MAR 27 - SEP 24
-SAN SALVADOR        6 H  BEHIND UTC
-SAO TOME ISLAND     ON UTC             AND PRINCIPE ISLAND
-SAUDI ARABIA        3 H  AHEAD OF UTC
-SCOTLAND            SEE ENGLAND
-SENEGAL             ON UTC
-SEYCHELLES          4 H  AHEAD OF UTC
-SIERRA LEONE        ON UTC
-SINGAPORE           8 H  AHEAD OF UTC
-SOLOMON ISLANDS    11 H  AHEAD OF UTC  EXCLUDING BOUGAINVILLE
-SOLOMON ISLANDS                        ISLAND
-SOMALI              3 H  AHEAD OF UTC
-SOUTH AFRICA        2 H  AHEAD OF UTC
-SPAIN  CANARY IS    ON UTC
-SPAIN  CANARY IS    1 H  AHEAD OF UTC  MAR 27 - SEP 24
-SPAIN               1 H  AHEAD OF UTC  CONTINENTAL, BALEARIC AND
-SPAIN                                  MALLORCA ISLANDS
-SPAIN               2 H  AHEAD OF UTC  CONTINENTAL, BALEARIC AND
-SPAIN                                  MALLORCA ISLANDS  MAR 27 -
-SPAIN                                  SEP 24
-SPAIN  MAINLAND     1 H  AHEAD OF UTC  MELILLA
-SPAIN  MAINLAND     2 H  AHEAD OF UTC  MAR 27 - SEP 24
-SRI LANKA          5H30M AHEAD OF UTC
-ST. MAARTEN
-ST. KITTS-NEVIS     4 H  BEHIND UTC
-ST. LUCIA           4 H  BEHIND UTC
-ST. PIERRE          3 H  BEHIND UTC    INCLUDING MIQUELON
-ST. PIERRE          2 H  BEHIND UTC    INLCUDING MIQUELON  APR 3
-ST. PIERRE                             - OCT 29
-ST. VINCENT         4 H  BEHIND UTC    INCLUDING THE GRENADINES
-ST. HELENA          ON UTC
-SUDAN               2 H  AHEAD OF UTC
-SURINAME            3 H  BEHIND UTC
-SWAZILAND           2 H  AHEAD OF UTC
-SWEDEN              1 H  AHEAD OF UTC
-SWEDEN              2 H  AHEAD OF UTC  MAR 27 - SEP 24
-SWITZERLAND         1 H  AHEAD OF UTC
-SWITZERLAND         2 H  AHEAD OF UTC  MAR 27 - SEP 24
-SYRIA               2 H  AHEAD OF UTC
-SYRIA               3 H  AHEAD OF UTC  MAR 15 - OCT 30
-TAHITI             10 H  BEHIND UTC
-TAIWAN              8 H  AHEAD OF UTC
-TANZANIA            3 H  AHEAD OF UTC
-THAILAND            7 H  AHEAD OF UTC
-TOGO                ON UTC
-TRINIDAD / TOBAGO   4 H  BEHIND UTC
-TUNISIA             1 H  AHEAD OF UTC
-TUNISIA             2 H  AHEAD OF UTC  APR 10 - SEP 24
-TURKEY              2 H  AHEAD OF UTC
-TURKEY              3 H  AHEAD OF UTC  MAR 27 - SEP 24
-TURKS AND CAICOS    5 H  BEHIND UTC
-TURKS AND CAICOS    4 H  BEHIND UTC    APR 3 - OCT 29
-TUVALU             12 H  AHEAD OF UTC
-UGANDA              3 H  AHEAD OF UTC
-UNITED ARAB EMIR.   4 H  AHEAD OF UTC  ABU DHABI, DUBAI, SHARJAH,
-UNITED ARAB EMIR                       RAS AL KHAIMAH
-UNITED KINGDOM      ON UTC             WALES, SCOTLAND, N.I., CH.
-UNITED KINGDOM                         IS.
-UNITED KINGDOM      1 H  AHEAD OF UTC  MAR 27 - OCT 22
-UNITED STATES       SEE USA
-UPPER VOLTA         ON UTC
-URUGUAY             3 H  BEHIND UTC
-URUGUAY             2 H  BEHIND UTC    DEC 11, '88-FEB 25, '89
-URAGUAY                                (ESTIMATED)
-USA   EASTERN       5 H  BEHIND UTC    NEW YORK, WASHINGTON
-USA   EASTERN       4 H  BEHIND UTC    APR 3 - OCT 30
-USA   CENTRAL       6 H  BEHIND UTC    CHICAGO, HOUSTON
-USA   CENTRAL       5 H  BEHIND UTC    APR 3 - OCT 30
-USA   MOUNTAIN      7 H  BEHIND UTC    DENVER
-USA   MOUNTAIN      6 H  BEHIND UTC    APR 3 - OCT 30
-USA   PACIFIC       8 H  BEHIND UTC    L.A., SAN FRANCISCO
-USA   PACIFIC       7 H  BEHIND UTC    APR 3 - OCT 30
-USA   ALASKA STD    9 H  BEHIND UTC    MOST OF ALASKA     (AKST)
-USA   ALASKA STD    8 H  BEHIND UTC    APR 3 - OCT 30 (AKDT)
-USA   ALEUTIAN     10 H  BEHIND UTC    ISLANDS WEST OF 170W
-USA   - " -         9 H  BEHIND UTC    APR 3 - OCT 30
-USA   HAWAII       10 H  BEHIND UTC
-USA   BERING       11 H  BEHIND UTC    SAMOA, MIDWAY
-USA  FOR SPECIFIC INFO ON USA ZONES/TIMES CALL DOT 202-426-4520
-USSR WEST EUROP     3 H  AHEAD OF UTC  LENINGRAD, MOSCOW
-USSR WEST EUROP     4 H  AHEAD OF UTC  APR 1 - SEP 30
-USSR CENTRAL EUR    4 H  AHEAD OF UTC  ROSTOV, BAKU
-USSR CENTRAL EUR    5 H  AHEAD OF UTC  APR 1 - SEP 30
-USSR EAST EUROP     5 H  AHEAD OF UTC  SVERDLOVSK
-USSR EAST EUROP     6 H  AHEAD OF UTC  APR 1 - SEP 30
-USSR WEST SIBERIAN  6 H  AHEAD OF UTC  TASHKENT, ALMA ATA
-USSR WEST SIBERIAN  7 H  AHEAD OF UTC  APR 1 - SEP 30
-USSR WEST-CENTRAL   7 H  AHEAD OF UTC  NOVOSIBIRSK
-USSR WEST-CENTRAL   8 H  AHEAD OF UTC  APR 1 - SEP 30
-USSR WEST-CENTRAL   8 H  AHEAD OF UTC  IRKUTSK
-USSR WEST-CENTRAL   9 H  AHEAD OF UTC  APR 1 - SEP 30
-USSR CENTRAL SIB    9 H  AHEAD OF UTC  YAKUTSK
-USSR CENTRAL SIB   10 H  AHEAD OF UTC  APR 1 - SEP 30
-USSR CENTRAL SIB   10 H  AHEAD OF UTC  VLADIVOSTOK
-USSR CENTRAL SIB   11 H  AHEAD OF UTC  APR 1 - SEP 30
-USSR EAST SIBERIA  11 H  AHEAD OF UTC  MAGADAN
-USSR EAST SIBERIA  12 H  AHEAD OF UTC  APR 1 - SEP 30
-USSR EAST SIBERIA  12 H  AHEAD OF UTC  PETROPAVLOVSK
-USSR EAST SIBERIA  13 H  AHEAD OF UTC  APR 1 - SEP 30
-USSR EAST SIBERIA  13 H  AHEAD OF UTC  UELEN
-USSR EAST SIBERIA  14 H  AHEAD OF UTC  APR 1 - SEP 30
-VANUATU            11 H  AHEAD OF UTC  (NEW HEBRIDES)
-VANUATU            12 H  AHEAD OF UTC  SEP 25, '88-MAR 25, '89
-VANUATU                                (ESTIMATED)
-VATICAN             1 H  AHEAD OF UTC
-VATICAN             2 H  AHEAD OF UTC  MAR 27 - SEP 24
-VENEZUELA           4 H  BEHIND UTC
-VIETNAM             7 H  AHEAD OF UTC
-VIRGIN ISLANDS      4 H  BEHIND UTC    ST.CROIX, ST.THOMAS,
-VIRGIN ISLANDS                         ST.JOHN
-WAKE ISLAND        12 H  AHEAD OF UTC
-WALES               SEE ENGLAND
-WALLIS/FUTUNA IS.  12 H  AHEAD OF UTC
-WINDWARD ISLANDS    4 H  BEHIND UTC    GRENADA, ST. LUCIA
-YEMEN               3 H  AHEAD OF UTC  BOTH REPUBLICS
-YUGOSLAVIA          1 H  AHEAD OF UTC
-YUGOSLAVIA          2 H  AHEAD OF UTC  MAR 27 - SEP 24
-ZAIRE  EAST         1 H  AHEAD OF UTC  KINSHASA MBANDAKA
-ZAIRE  WEST         2 H  AHEAD OF UTC  LUBUMBASHI, KASAI, KIVU,
-ZAIRE  WEST                            HAUT-ZAIRE, SHABA
-ZAMBIA              2 H  AHEAD OF UTC
-ZIMBABWE            2 H  AHEAD OF UTC
diff --git a/time/yearistype.sh b/time/yearistype.sh
deleted file mode 100644 (file)
index c7a886c..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-#! /bin/sh
-
-: '@(#)yearistype.sh   7.3'
-
-case $#-$2 in
-       2-even)         case $1 in
-                               *[24680])                       exit 0 ;;
-                               *)                              exit 1 ;;
-                       esac ;;
-       2-nonpres)      case $1 in
-                               *[02468][048]|*[13567][26])     exit 1 ;;
-                               *)                              exit 0 ;;
-                       esac ;;
-       2-odd)          case $1 in
-                               *[13579])                       exit 0 ;;
-                               *)                              exit 1 ;;
-                       esac ;;
-       2-uspres)       case $1 in
-                               *[02468][048]|*[13567][26])     exit 0 ;;
-                               *)                              exit 1 ;;
-                       esac ;;
-       2-*)            echo "$0: wild type - $2" >&2
-                       exit 1 ;;
-       *)              echo "$0: usage is $0 year type" >&2
-                       exit 1 ;;
-esac
diff --git a/time/zdump.8 b/time/zdump.8
deleted file mode 100644 (file)
index 23f4946..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-.TH ZDUMP 8
-.SH NAME
-zdump \- time zone dumper
-.SH SYNOPSIS
-.B zdump
-[
-.B \-v
-] [
-.B \-c
-cutoffyear ] [ zonename ... ]
-.SH DESCRIPTION
-.I Zdump
-prints the current time in each
-.I zonename
-named on the command line.
-.PP
-These options are available:
-.TP
-.B \-v
-For each
-.I zonename
-on the command line,
-print the current time,
-the time at the lowest possible time value,
-the time one day after the lowest possible time value,
-the times both one second before and exactly at
-each detected time discontinuity,
-the time at one day less than the highest possible time value,
-and the time at the highest possible time value,
-Each line ends with
-.B isdst=1
-if the given time is Daylight Saving Time or
-.B isdst=0
-otherwise.
-.TP
-.BI "\-c " cutoffyear
-Cut off the verbose output near the start of the given year.
-.SH "SEE ALSO"
-newctime(3), tzfile(5), zic(8)
-.\" @(#)zdump.8        7.2
diff --git a/time/zdump.c b/time/zdump.c
deleted file mode 100644 (file)
index d35df33..0000000
+++ /dev/null
@@ -1,331 +0,0 @@
-#ifndef lint
-#ifndef NOID
-static char    elsieid[] = "@(#)zdump.c        7.12";
-#endif /* !defined NOID */
-#endif /* !defined lint */
-
-/*
-** This code has been made independent of the rest of the time
-** conversion package to increase confidence in the verification it provides.
-** You can use this code to help in verifying other implementations.
-*/
-
-#include "stdio.h"     /* for stdout, stderr */
-#include "string.h"    /* for strcpy */
-#include "sys/types.h" /* for time_t */
-#include "time.h"      /* for struct tm */
-
-#ifndef MAX_STRING_LENGTH
-#define MAX_STRING_LENGTH      1024
-#endif /* !defined MAX_STRING_LENGTH */
-
-#ifndef TRUE
-#define TRUE           1
-#endif /* !defined TRUE */
-
-#ifndef FALSE
-#define FALSE          0
-#endif /* !defined FALSE */
-
-#ifndef EXIT_SUCCESS
-#define EXIT_SUCCESS   0
-#endif /* !defined EXIT_SUCCESS */
-
-#ifndef EXIT_FAILURE
-#define EXIT_FAILURE   1
-#endif /* !defined EXIT_FAILURE */
-
-#ifndef SECSPERMIN
-#define SECSPERMIN     60
-#endif /* !defined SECSPERMIN */
-
-#ifndef MINSPERHOUR
-#define MINSPERHOUR    60
-#endif /* !defined MINSPERHOUR */
-
-#ifndef SECSPERHOUR
-#define SECSPERHOUR    (SECSPERMIN * MINSPERHOUR)
-#endif /* !defined SECSPERHOUR */
-
-#ifndef HOURSPERDAY
-#define HOURSPERDAY    24
-#endif /* !defined HOURSPERDAY */
-
-#ifndef EPOCH_YEAR
-#define EPOCH_YEAR     1970
-#endif /* !defined EPOCH_YEAR */
-
-#ifndef TM_YEAR_BASE
-#define TM_YEAR_BASE   1900
-#endif /* !defined TM_YEAR_BASE */
-
-#ifndef DAYSPERNYEAR
-#define DAYSPERNYEAR   365
-#endif /* !defined DAYSPERNYEAR */
-
-#ifndef isleap
-#define isleap(y) ((((y) % 4) == 0 && ((y) % 100) != 0) || ((y) % 400) == 0)
-#endif /* !defined isleap */
-
-#ifndef GNUC_or_lint
-#ifdef lint
-#define GNUC_or_lint
-#endif /* defined lint */
-#ifdef __GNUC__
-#define GNUC_or_lint
-#endif /* defined __GNUC__ */
-#endif /* !defined GNUC_or_lint */
-
-#ifndef INITIALIZE
-#ifdef GNUC_or_lint
-#define INITIALIZE(x)  ((x) = 0)
-#endif /* defined GNUC_or_lint */
-#ifndef GNUC_or_lint
-#define INITIALIZE(x)
-#endif /* !defined GNUC_or_lint */
-#endif /* !defined INITIALIZE */
-
-extern char ** environ;
-extern int     getopt();
-extern char *  optarg;
-extern int     optind;
-extern time_t  time();
-extern char *  tzname[2];
-
-#ifdef USG
-extern void    exit();
-extern void    perror();
-#endif /* defined USG */
-
-static char *  abbr();
-static long    delta();
-static time_t  hunt();
-static int     longest;
-static char *  progname;
-static void    show();
-
-int
-main(argc, argv)
-int    argc;
-char * argv[];
-{
-       register int            i, c;
-       register int            vflag;
-       register char *         cutoff;
-       register int            cutyear;
-       register long           cuttime;
-       char **                 fakeenv;
-       time_t                  now;
-       time_t                  t, newt;
-       time_t                  hibit;
-       struct tm               tm, newtm;
-
-       INITIALIZE(cuttime);
-       progname = argv[0];
-       vflag = 0;
-       cutoff = NULL;
-       while ((c = getopt(argc, argv, "c:v")) == 'c' || c == 'v')
-               if (c == 'v')
-                       vflag = 1;
-               else    cutoff = optarg;
-       if (c != EOF ||
-               (optind == argc - 1 && strcmp(argv[optind], "=") == 0)) {
-                       (void) fprintf(stderr,
-"%s: usage is %s [ -v ] [ -c cutoff ] zonename ...\n",
-                               argv[0], argv[0]);
-                       (void) exit(EXIT_FAILURE);
-       }
-       if (cutoff != NULL) {
-               int     y;
-
-               cutyear = atoi(cutoff);
-               cuttime = 0;
-               for (y = EPOCH_YEAR; y < cutyear; ++y)
-                       cuttime += DAYSPERNYEAR + isleap(y);
-               cuttime *= SECSPERHOUR * HOURSPERDAY;
-       }
-       (void) time(&now);
-       longest = 0;
-       for (i = optind; i < argc; ++i)
-               if (strlen(argv[i]) > longest)
-                       longest = strlen(argv[i]);
-       for (hibit = 1; (hibit << 1) != 0; hibit <<= 1)
-               continue;
-       {
-               register int    from, to;
-
-               for (i = 0;  environ[i] != NULL;  ++i)
-                       continue;
-               fakeenv = (char **) malloc((i + 2) * sizeof *fakeenv);
-               if (fakeenv == NULL ||
-                       (fakeenv[0] = (char *) malloc(longest + 4)) == NULL) {
-                               (void) perror(progname);
-                               (void) exit(EXIT_FAILURE);
-               }
-               to = 0;
-               (void) strcpy(fakeenv[to++], "TZ=");
-               for (from = 0; environ[from] != NULL; ++from)
-                       if (strncmp(environ[from], "TZ=", 3) != 0)
-                               fakeenv[to++] = environ[from];
-               fakeenv[to] = NULL;
-               environ = fakeenv;
-       }
-       for (i = optind; i < argc; ++i) {
-               static char     buf[MAX_STRING_LENGTH];
-
-               (void) strcpy(&fakeenv[0][3], argv[i]);
-               show(argv[i], now, FALSE);
-               if (!vflag)
-                       continue;
-               /*
-               ** Get lowest value of t.
-               */
-               t = hibit;
-               if (t > 0)              /* time_t is unsigned */
-                       t = 0;
-               show(argv[i], t, TRUE);
-               t += SECSPERHOUR * HOURSPERDAY;
-               show(argv[i], t, TRUE);
-               tm = *localtime(&t);
-               (void) strncpy(buf, abbr(&tm), (sizeof buf) - 1);
-               for ( ; ; ) {
-                       if (cutoff != NULL && t >= cuttime)
-                               break;
-                       newt = t + SECSPERHOUR * 12;
-                       if (cutoff != NULL && newt >= cuttime)
-                               break;
-                       if (newt <= t)
-                               break;
-                       newtm = *localtime(&newt);
-                       if (delta(&newtm, &tm) != (newt - t) ||
-                               newtm.tm_isdst != tm.tm_isdst ||
-                               strcmp(abbr(&newtm), buf) != 0) {
-                                       newt = hunt(argv[i], t, newt);
-                                       newtm = *localtime(&newt);
-                                       (void) strncpy(buf, abbr(&newtm),
-                                               (sizeof buf) - 1);
-                       }
-                       t = newt;
-                       tm = newtm;
-               }
-               /*
-               ** Get highest value of t.
-               */
-               t = ~((time_t) 0);
-               if (t < 0)              /* time_t is signed */
-                       t &= ~hibit;
-               t -= SECSPERHOUR * HOURSPERDAY;
-               show(argv[i], t, TRUE);
-               t += SECSPERHOUR * HOURSPERDAY;
-               show(argv[i], t, TRUE);
-       }
-       if (fflush(stdout) || ferror(stdout)) {
-               (void) fprintf(stderr, "%s: Error writing standard output ",
-                       argv[0]);
-               (void) perror("standard output");
-               (void) exit(EXIT_FAILURE);
-       }
-       exit(EXIT_SUCCESS);
-
-       /* gcc -Wall pacifier */
-       for ( ; ; )
-               continue;
-}
-
-static time_t
-hunt(name, lot, hit)
-char * name;
-time_t lot;
-time_t hit;
-{
-       time_t          t;
-       struct tm       lotm;
-       struct tm       tm;
-       static char     loab[MAX_STRING_LENGTH];
-
-       lotm = *localtime(&lot);
-       (void) strncpy(loab, abbr(&lotm), (sizeof loab) - 1);
-       while ((hit - lot) >= 2) {
-               t = lot / 2 + hit / 2;
-               if (t <= lot)
-                       ++t;
-               else if (t >= hit)
-                       --t;
-               tm = *localtime(&t);
-               if (delta(&tm, &lotm) == (t - lot) &&
-                       tm.tm_isdst == lotm.tm_isdst &&
-                       strcmp(abbr(&tm), loab) == 0) {
-                               lot = t;
-                               lotm = tm;
-               } else  hit = t;
-       }
-       show(name, lot, TRUE);
-       show(name, hit, TRUE);
-       return hit;
-}
-
-/*
-** Thanks to Paul Eggert (eggert@twinsun.com) for logic used in delta.
-*/
-
-static long
-delta(newp, oldp)
-struct tm *    newp;
-struct tm *    oldp;
-{
-       long    result;
-       int     tmy;
-
-       if (newp->tm_year < oldp->tm_year)
-               return -delta(oldp, newp);
-       result = 0;
-       for (tmy = oldp->tm_year; tmy < newp->tm_year; ++tmy)
-               result += DAYSPERNYEAR + isleap(tmy + TM_YEAR_BASE);
-       result += newp->tm_yday - oldp->tm_yday;
-       result *= HOURSPERDAY;
-       result += newp->tm_hour - oldp->tm_hour;
-       result *= MINSPERHOUR;
-       result += newp->tm_min - oldp->tm_min;
-       result *= SECSPERMIN;
-       result += newp->tm_sec - oldp->tm_sec;
-       return result;
-}
-
-extern struct tm *     localtime();
-
-static void
-show(zone, t, v)
-char * zone;
-time_t t;
-int    v;
-{
-       struct tm *     tmp;
-
-       (void) printf("%-*s  ", longest, zone);
-       if (v)
-               (void) printf("%.24s GMT = ", asctime(gmtime(&t)));
-       tmp = localtime(&t);
-       (void) printf("%.24s", asctime(tmp));
-       if (*abbr(tmp) != '\0')
-               (void) printf(" %s", abbr(tmp));
-       if (v) {
-               (void) printf(" isdst=%d", tmp->tm_isdst);
-#ifdef TM_GMTOFF
-               (void) printf(" gmtoff=%ld", tmp->TM_GMTOFF);
-#endif /* defined TM_GMTOFF */
-       }
-       (void) printf("\n");
-}
-
-static char *
-abbr(tmp)
-struct tm *    tmp;
-{
-       register char * result;
-       static char     nada;
-
-       if (tmp->tm_isdst != 0 && tmp->tm_isdst != 1)
-               return &nada;
-       result = tzname[tmp->tm_isdst];
-       return (result == NULL) ? &nada : result;
-}
diff --git a/time/zic.8 b/time/zic.8
deleted file mode 100644 (file)
index b3623aa..0000000
+++ /dev/null
@@ -1,406 +0,0 @@
-.TH ZIC 8
-.SH NAME
-zic \- time zone compiler
-.SH SYNOPSIS
-.B zic
-[
-.B \-v
-] [
-.B \-d
-.I directory
-] [
-.B \-l
-.I localtime
-] [
-.B \-p
-.I posixrules
-] [
-.B \-L
-.I leapsecondfilename
-] [
-.B \-s
-] [
-.B \-y
-.I command
-] [
-.I filename
-\&... ]
-.SH DESCRIPTION
-.if t .ds lq ``
-.if t .ds rq ''
-.if n .ds lq \&"\"
-.if n .ds rq \&"\"
-.de q
-\\$3\*(lq\\$1\*(rq\\$2
-..
-.I Zic
-reads text from the file(s) named on the command line
-and creates the time conversion information files specified in this input.
-If a
-.I filename
-is
-.BR \- ,
-the standard input is read.
-.PP
-These options are available:
-.TP
-.BI "\-d " directory
-Create time conversion information files in the named directory rather than
-in the standard directory named below.
-.TP
-.BI "\-l " timezone
-Use the given time zone as local time.
-.I Zic
-will act as if the input contained a link line of the form
-.sp
-.ti +.5i
-Link   \fItimezone\fP          localtime
-.TP
-.BI "\-p " timezone
-Use the given time zone's rules when handling POSIX-format
-time zone environment variables.
-.I Zic
-will act as if the input contained a link line of the form
-.sp
-.ti +.5i
-Link   \fItimezone\fP          posixrules
-.TP
-.BI "\-L " leapsecondfilename
-Read leap second information from the file with the given name.
-If this option is not used,
-no leap second information appears in output files.
-.TP
-.B \-v
-Complain if a year that appears in a data file is outside the range
-of years representable by
-.IR time (2)
-values.
-.TP
-.B \-s
-Limit time values stored in output files to values that are the same
-whether they're taken to be signed or unsigned.
-You can use this option to generate SVVS-compatible files.
-.TP
-.BI "\-y " command
-Use the given
-.I command
-rather than
-.B yearistype
-when checking year types (see below).
-.PP
-Input lines are made up of fields.
-Fields are separated from one another by any number of white space characters.
-Leading and trailing white space on input lines is ignored.
-An unquoted sharp character (#) in the input introduces a comment which extends
-to the end of the line the sharp character appears on.
-White space characters and sharp characters may be enclosed in double quotes
-(") if they're to be used as part of a field.
-Any line that is blank (after comment stripping) is ignored.
-Non-blank lines are expected to be of one of three types:
-rule lines, zone lines, and link lines.
-.PP
-A rule line has the form
-.nf
-.ti +.5i
-.ta \w'Rule\0\0'u +\w'NAME\0\0'u +\w'FROM\0\0'u +\w'1973\0\0'u +\w'TYPE\0\0'u +\w'Apr\0\0'u +\w'lastSun\0\0'u +\w'2:00\0\0'u +\w'SAVE\0\0'u
-.sp
-Rule   NAME    FROM    TO      TYPE    IN      ON      AT      SAVE    LETTER/S
-.sp
-For example:
-.ti +.5i
-.sp
-Rule   US      1967    1973    \-      Apr     lastSun 2:00    1:00    D
-.sp
-.fi
-The fields that make up a rule line are:
-.TP "\w'LETTER/S'u"
-.B NAME
-Gives the (arbitrary) name of the set of rules this rule is part of.
-.TP
-.B FROM
-Gives the first year in which the rule applies.
-Any integer year can be supplied; the Gregorian calendar is assumed.
-The word
-.B minimum
-(or an abbreviation) means the minimum year representable as an integer.
-The word
-.B maximum
-(or an abbreviation) means the maximum year representable as an integer.
-Rules can describe times that are not representable as time values,
-with the unrepresentable times ignored; this allows rules to be portable
-among hosts with differing time value types.
-.TP
-.B TO
-Gives the final year in which the rule applies.
-In addition to
-.B minimum
-and
-.B maximum
-(as above),
-the word
-.B only
-(or an abbreviation)
-may be used to repeat the value of the
-.B FROM
-field.
-.TP
-.B TYPE
-Gives the type of year in which the rule applies.
-If
-.B TYPE
-is
-.B \-
-then the rule applies in all years between
-.B FROM
-and
-.B TO
-inclusive.
-If
-.B TYPE
-is something else, then
-.I zic
-executes the command
-.ti +.5i
-\fByearistype\fP \fIyear\fP \fItype\fP
-.br
-to check the type of a year:
-an exit status of zero is taken to mean that the year is of the given type;
-an exit status of one is taken to mean that the year is not of the given type.
-.TP
-.B IN
-Names the month in which the rule takes effect.
-Month names may be abbreviated.
-.TP
-.B ON
-Gives the day on which the rule takes effect.
-Recognized forms include:
-.nf
-.in +.5i
-.sp
-.ta \w'Sun<=25\0\0'u
-5      the fifth of the month
-lastSun        the last Sunday in the month
-lastMon        the last Monday in the month
-Sun>=8 first Sunday on or after the eighth
-Sun<=25        last Sunday on or before the 25th
-.fi
-.in -.5i
-.sp
-Names of days of the week may be abbreviated or spelled out in full.
-Note that there must be no spaces within the
-.B ON
-field.
-.TP
-.B AT
-Gives the time of day at which the rule takes effect.
-Recognized forms include:
-.nf
-.in +.5i
-.sp
-.ta \w'1:28:13\0\0'u
-2      time in hours
-2:00   time in hours and minutes
-15:00  24-hour format time (for times after noon)
-1:28:14        time in hours, minutes, and seconds
-.fi
-.in -.5i
-.sp
-Any of these forms may be followed by the letter
-.B w
-if the given time is local
-.q "wall clock"
-time,
-.B s
-if the given time is local
-.q standard
-time, or
-.B u
-(or
-.B g
-or
-.BR z )
-if the given time is universal time;
-in the absence of an indicator,
-wall clock time is assumed.
-.TP
-.B SAVE
-Gives the amount of time to be added to local standard time when the rule is in
-effect.
-This field has the same format as the
-.B AT
-field
-(although, of course, the
-.B w
-and
-.B s
-suffixes are not used).
-.TP
-.B LETTER/S
-Gives the
-.q "variable part"
-(for example, the
-.q S
-or
-.q D
-in
-.q EST
-or
-.q EDT )
-of time zone abbreviations to be used when this rule is in effect.
-If this field is
-.BR \- ,
-the variable part is null.
-.PP
-A zone line has the form
-.sp
-.nf
-.ti +.5i
-.ta \w'Zone\0\0'u +\w'Australia/Adelaide\0\0'u +\w'GMTOFF\0\0'u +\w'RULES/SAVE\0\0'u +\w'FORMAT\0\0'u
-Zone   NAME    GMTOFF  RULES/SAVE      FORMAT  [UNTIL]
-.sp
-For example:
-.sp
-.ti +.5i
-Zone   Australia/Adelaide      9:30    Aus     CST     1971 Oct 31 2:00
-.sp
-.fi
-The fields that make up a zone line are:
-.TP "\w'GMTOFF'u"
-.B NAME
-The name of the time zone.
-This is the name used in creating the time conversion information file for the
-zone.
-.TP
-.B GMTOFF
-The amount of time to add to GMT to get standard time in this zone.
-This field has the same format as the
-.B AT
-and
-.B SAVE
-fields of rule lines;
-begin the field with a minus sign if time must be subtracted from GMT.
-.TP
-.B RULES/SAVE
-The name of the rule(s) that apply in the time zone or,
-alternately, an amount of time to add to local standard time.
-If this field is
-.B \-
-then standard time always applies in the time zone.
-.TP
-.B FORMAT
-The format for time zone abbreviations in this time zone.
-The pair of characters
-.B %s
-is used to show where the
-.q "variable part"
-of the time zone abbreviation goes.
-.TP
-.B UNTIL
-The time at which the GMT offset or the rule(s) change for a location.
-It is specified as a year, a month, a day, and a time of day.
-If this is specified,
-the time zone information is generated from the given GMT offset
-and rule change until the time specified.
-.IP
-The next line must be a
-.q continuation
-line; this has the same form as a zone line except that the
-string
-.q Zone
-and the name are omitted, as the continuation line will
-place information starting at the time specified as the
-.B UNTIL
-field in the previous line in the file used by the previous line.
-Continuation lines may contain an
-.B UNTIL
-field, just as zone lines do, indicating that the next line is a further
-continuation.
-.PP
-A link line has the form
-.sp
-.nf
-.ti +.5i
-.if t .ta \w'Link\0\0'u +\w'LINK-FROM\0\0'u
-.if n .ta \w'Link\0\0'u +\w'US/Eastern\0\0'u
-Link   LINK-FROM       LINK-TO
-.sp
-For example:
-.sp
-.ti +.5i
-Link   US/Eastern      EST5EDT
-.sp
-.fi
-The
-.B LINK-FROM
-field should appear as the
-.B NAME
-field in some zone line;
-the
-.B LINK-TO
-field is used as an alternate name for that zone.
-.PP
-Except for continuation lines,
-lines may appear in any order in the input.
-.PP
-Lines in the file that describes leap seconds have the following form:
-.nf
-.ti +.5i
-.ta \w'Leap\0\0'u +\w'YEAR\0\0'u +\w'MONTH\0\0'u +\w'DAY\0\0'u +\w'HH:MM:SS\0\0'u +\w'CORR\0\0'u
-.sp
-Leap   YEAR    MONTH   DAY     HH:MM:SS        CORR    R/S
-.sp
-For example:
-.ti +.5i
-.sp
-Leap   1974    Dec     31      23:59:60        +       S
-.sp
-.fi
-The
-.BR YEAR ,
-.BR MONTH ,
-.BR DAY ,
-and
-.B HH:MM:SS
-fields tell when the leap second happened.
-The
-.B CORR
-field
-should be
-.q +
-if a second was added
-or
-.q -
-if a second was skipped.
-.\" There's no need to document the following, since it's impossible for more
-.\" than one leap second to be inserted or deleted at a time.
-.\" The C Standard is in error in suggesting the possibility.
-.\" See Terry J Quinn, The BIPM and the accurate measure of time,
-.\" Proc IEEE 79, 7 (July 1991), 894-905.
-.\"    or
-.\"    .q ++
-.\"    if two seconds were added
-.\"    or
-.\"    .q --
-.\"    if two seconds were skipped.
-The
-.B R/S
-field
-should be (an abbreviation of)
-.q Stationary
-if the leap second time given by the other fields should be interpreted as GMT
-or
-(an abbreviation of)
-.q Rolling
-if the leap second time given by the other fields should be interpreted as
-local wall clock time.
-.SH NOTE
-For areas with more than two types of local time,
-you may need to use local standard time in the
-.B AT
-field of the earliest transition time's rule to ensure that
-the earliest transition time recorded in the compiled file is correct.
-.SH FILE
-/usr/local/etc/zoneinfo        standard directory used for created files
-.SH "SEE ALSO"
-newctime(3), tzfile(5), zdump(8)
-.\" @(#)zic.8  7.10
diff --git a/time/zic.c b/time/zic.c
deleted file mode 100644 (file)
index 73ea468..0000000
+++ /dev/null
@@ -1,1956 +0,0 @@
-#ifndef lint
-#ifndef NOID
-static char    elsieid[] = "@(#)zic.c  7.28";
-#endif /* !defined NOID */
-#endif /* !defined lint */
-
-#include "private.h"
-#include "tzfile.h"
-
-struct rule {
-       const char *    r_filename;
-       int             r_linenum;
-       const char *    r_name;
-
-       int             r_loyear;       /* for example, 1986 */
-       int             r_hiyear;       /* for example, 1986 */
-       const char *    r_yrtype;
-
-       int             r_month;        /* 0..11 */
-
-       int             r_dycode;       /* see below */
-       int             r_dayofmonth;
-       int             r_wday;
-
-       long            r_tod;          /* time from midnight */
-       int             r_todisstd;     /* above is standard time if TRUE */
-                                       /* or wall clock time if FALSE */
-       int             r_todisuniv;    /* above is universal time if TRUE */
-                                       /* or local time if FALSE */
-       long            r_stdoff;       /* offset from standard time */
-       const char *    r_abbrvar;      /* variable part of abbreviation */
-
-       int             r_todo;         /* a rule to do (used in outzone) */
-       time_t          r_temp;         /* used in outzone */
-};
-
-/*
-**     r_dycode                r_dayofmonth    r_wday
-*/
-
-#define DC_DOM         0       /* 1..31 */     /* unused */
-#define DC_DOWGEQ      1       /* 1..31 */     /* 0..6 (Sun..Sat) */
-#define DC_DOWLEQ      2       /* 1..31 */     /* 0..6 (Sun..Sat) */
-
-struct zone {
-       const char *    z_filename;
-       int             z_linenum;
-
-       const char *    z_name;
-       long            z_gmtoff;
-       const char *    z_rule;
-       const char *    z_format;
-
-       long            z_stdoff;
-
-       struct rule *   z_rules;
-       int             z_nrules;
-
-       struct rule     z_untilrule;
-       time_t          z_untiltime;
-};
-
-extern int     emkdir P((const char * name, int mode));
-extern int     getopt P((int argc, char * argv[], const char * options));
-extern char *  icatalloc P((char * old, const char * new));
-extern char *  icpyalloc P((const char * string));
-extern void    ifree P((char * p));
-extern char *  imalloc P((int n));
-extern void *  irealloc P((void * old, int n));
-extern int     link P((const char * fromname, const char * toname));
-extern char *  optarg;
-extern int     optind;
-extern char *  scheck P((const char * string, const char * format));
-
-static void    addtt P((time_t starttime, int type));
-static int     addtype P((long gmtoff, const char * abbr, int isdst,
-                               int ttisstd));
-static void    leapadd P((time_t t, int positive, int rolling, int count));
-static void    adjleap P((void));
-static void    associate P((void));
-static int     ciequal P((const char * ap, const char * bp));
-static void    convert P((long val, char * buf));
-static void    dolink P((const char * fromfile, const char * tofile));
-static void    eat P((const char * name, int num));
-static void    eats P((const char * name, int num,
-                       const char * rname, int rnum));
-static long    eitol P((int i));
-static void    error P((const char * message));
-static char ** getfields P((char * buf));
-static long    gethms P((const char * string, const char * errstrng,
-                       int signable));
-static void    infile P((const char * filename));
-static void    inleap P((char ** fields, int nfields));
-static void    inlink P((char ** fields, int nfields));
-static void    inrule P((char ** fields, int nfields));
-static int     inzcont P((char ** fields, int nfields));
-static int     inzone P((char ** fields, int nfields));
-static int     inzsub P((char ** fields, int nfields, int iscont));
-static int     itsabbr P((const char * abbr, const char * word));
-static int     itsdir P((const char * name));
-static int     lowerit P((int c));
-static char *  memcheck P((char * tocheck));
-static int     mkdirs P((char * filename));
-static void    newabbr P((const char * abbr));
-static long    oadd P((long t1, long t2));
-static void    outzone P((const struct zone * zp, int ntzones));
-static void    puttzcode P((long code, FILE * fp));
-static int     rcomp P((const genericptr_T leftp, const genericptr_T rightp));
-static time_t  rpytime P((const struct rule * rp, int wantedy));
-static void    rulesub P((struct rule * rp,
-                       const char * loyearp, const char * hiyearp,
-                       const char * typep, const char * monthp,
-                       const char * dayp, const char * timep));
-static void    setboundaries P((void));
-static time_t  tadd P((time_t t1, long t2));
-static void    usage P((void));
-static void    writezone P((const char * name));
-static int     yearistype P((int year, const char * type));
-
-static int             charcnt;
-static int             errors;
-static const char *    filename;
-static int             leapcnt;
-static int             linenum;
-static int             max_int;
-static time_t          max_time;
-static int             max_year;
-static int             min_int;
-static time_t          min_time;
-static int             min_year;
-static int             noise;
-static const char *    rfilename;
-static int             rlinenum;
-static const char *    progname;
-static int             timecnt;
-static int             typecnt;
-static int             tt_signed;
-
-/*
-** Line codes.
-*/
-
-#define LC_RULE                0
-#define LC_ZONE                1
-#define LC_LINK                2
-#define LC_LEAP                3
-
-/*
-** Which fields are which on a Zone line.
-*/
-
-#define ZF_NAME                1
-#define ZF_GMTOFF      2
-#define ZF_RULE                3
-#define ZF_FORMAT      4
-#define ZF_TILYEAR     5
-#define ZF_TILMONTH    6
-#define ZF_TILDAY      7
-#define ZF_TILTIME     8
-#define ZONE_MINFIELDS 5
-#define ZONE_MAXFIELDS 9
-
-/*
-** Which fields are which on a Zone continuation line.
-*/
-
-#define ZFC_GMTOFF     0
-#define ZFC_RULE       1
-#define ZFC_FORMAT     2
-#define ZFC_TILYEAR    3
-#define ZFC_TILMONTH   4
-#define ZFC_TILDAY     5
-#define ZFC_TILTIME    6
-#define ZONEC_MINFIELDS        3
-#define ZONEC_MAXFIELDS        7
-
-/*
-** Which files are which on a Rule line.
-*/
-
-#define RF_NAME                1
-#define RF_LOYEAR      2
-#define RF_HIYEAR      3
-#define RF_COMMAND     4
-#define RF_MONTH       5
-#define RF_DAY         6
-#define RF_TOD         7
-#define RF_STDOFF      8
-#define RF_ABBRVAR     9
-#define RULE_FIELDS    10
-
-/*
-** Which fields are which on a Link line.
-*/
-
-#define LF_FROM                1
-#define LF_TO          2
-#define LINK_FIELDS    3
-
-/*
-** Which fields are which on a Leap line.
-*/
-
-#define LP_YEAR                1
-#define LP_MONTH       2
-#define LP_DAY         3
-#define LP_TIME                4
-#define LP_CORR                5
-#define LP_ROLL                6
-#define LEAP_FIELDS    7
-
-/*
-** Year synonyms.
-*/
-
-#define YR_MINIMUM     0
-#define YR_MAXIMUM     1
-#define YR_ONLY                2
-
-static struct rule *   rules;
-static int             nrules; /* number of rules */
-
-static struct zone *   zones;
-static int             nzones; /* number of zones */
-
-struct link {
-       const char *    l_filename;
-       int             l_linenum;
-       const char *    l_from;
-       const char *    l_to;
-};
-
-static struct link *   links;
-static int             nlinks;
-
-struct lookup {
-       const char *    l_word;
-       const int       l_value;
-};
-
-static struct lookup const *   byword P((const char * string,
-                                       const struct lookup * lp));
-
-static struct lookup const     line_codes[] = {
-       { "Rule",       LC_RULE },
-       { "Zone",       LC_ZONE },
-       { "Link",       LC_LINK },
-       { "Leap",       LC_LEAP },
-       { NULL,         0}
-};
-
-static struct lookup const     mon_names[] = {
-       { "January",    TM_JANUARY },
-       { "February",   TM_FEBRUARY },
-       { "March",      TM_MARCH },
-       { "April",      TM_APRIL },
-       { "May",        TM_MAY },
-       { "June",       TM_JUNE },
-       { "July",       TM_JULY },
-       { "August",     TM_AUGUST },
-       { "September",  TM_SEPTEMBER },
-       { "October",    TM_OCTOBER },
-       { "November",   TM_NOVEMBER },
-       { "December",   TM_DECEMBER },
-       { NULL,         0 }
-};
-
-static struct lookup const     wday_names[] = {
-       { "Sunday",     TM_SUNDAY },
-       { "Monday",     TM_MONDAY },
-       { "Tuesday",    TM_TUESDAY },
-       { "Wednesday",  TM_WEDNESDAY },
-       { "Thursday",   TM_THURSDAY },
-       { "Friday",     TM_FRIDAY },
-       { "Saturday",   TM_SATURDAY },
-       { NULL,         0 }
-};
-
-static struct lookup const     lasts[] = {
-       { "last-Sunday",        TM_SUNDAY },
-       { "last-Monday",        TM_MONDAY },
-       { "last-Tuesday",       TM_TUESDAY },
-       { "last-Wednesday",     TM_WEDNESDAY },
-       { "last-Thursday",      TM_THURSDAY },
-       { "last-Friday",        TM_FRIDAY },
-       { "last-Saturday",      TM_SATURDAY },
-       { NULL,                 0 }
-};
-
-static struct lookup const     begin_years[] = {
-       { "minimum",    YR_MINIMUM },
-       { "maximum",    YR_MAXIMUM },
-       { NULL,         0 }
-};
-
-static struct lookup const     end_years[] = {
-       { "minimum",    YR_MINIMUM },
-       { "maximum",    YR_MAXIMUM },
-       { "only",       YR_ONLY },
-       { NULL,         0 }
-};
-
-static struct lookup const     leap_types[] = {
-       { "Rolling",    TRUE },
-       { "Stationary", FALSE },
-       { NULL,         0 }
-};
-
-static const int       len_months[2][MONSPERYEAR] = {
-       { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
-       { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
-};
-
-static const int       len_years[2] = {
-       DAYSPERNYEAR, DAYSPERLYEAR
-};
-
-static time_t          ats[TZ_MAX_TIMES];
-static unsigned char   types[TZ_MAX_TIMES];
-static long            gmtoffs[TZ_MAX_TYPES];
-static char            isdsts[TZ_MAX_TYPES];
-static unsigned char   abbrinds[TZ_MAX_TYPES];
-static char            ttisstds[TZ_MAX_TYPES];
-static char            chars[TZ_MAX_CHARS];
-static time_t          trans[TZ_MAX_LEAPS];
-static long            corr[TZ_MAX_LEAPS];
-static char            roll[TZ_MAX_LEAPS];
-
-/*
-** Memory allocation.
-*/
-
-static char *
-memcheck(ptr)
-char * const   ptr;
-{
-       if (ptr == NULL) {
-               (void) perror(progname);
-               (void) exit(EXIT_FAILURE);
-       }
-       return ptr;
-}
-
-#define emalloc(size)          memcheck(imalloc(size))
-#define erealloc(ptr, size)    memcheck(irealloc((ptr), (size)))
-#define ecpyalloc(ptr)         memcheck(icpyalloc(ptr))
-#define ecatalloc(oldp, newp)  memcheck(icatalloc((oldp), (newp)))
-
-/*
-** Error handling.
-*/
-
-static void
-eats(name, num, rname, rnum)
-const char * const     name;
-const int              num;
-const char * const     rname;
-const int              rnum;
-{
-       filename = name;
-       linenum = num;
-       rfilename = rname;
-       rlinenum = rnum;
-}
-
-static void
-eat(name, num)
-const char * const     name;
-const int              num;
-{
-       eats(name, num, (char *) NULL, -1);
-}
-
-static void
-error(string)
-const char * const     string;
-{
-       /*
-       ** Match the format of "cc" to allow sh users to
-       **      zic ... 2>&1 | error -t "*" -v
-       ** on BSD systems.
-       */
-       (void) fprintf(stderr, "\"%s\", line %d: %s",
-               filename, linenum, string);
-       if (rfilename != NULL)
-               (void) fprintf(stderr, " (rule from \"%s\", line %d)",
-                       rfilename, rlinenum);
-       (void) fprintf(stderr, "\n");
-       ++errors;
-}
-
-static void
-usage P((void))
-{
-       (void) fprintf(stderr,
-"%s: usage is %s [ -s ] [ -v ] [ -l localtime ] [ -p posixrules ] [ -d directory ] \n\
-\t[ -L leapseconds ] [ -y yearistype ] [ filename ... ]\n",
-               progname, progname);
-       (void) exit(EXIT_FAILURE);
-}
-
-static const char *    psxrules;
-static const char *    lcltime;
-static const char *    directory;
-static const char *    leapsec;
-static const char *    yitcommand;
-static int             sflag = FALSE;
-
-int
-main(argc, argv)
-int    argc;
-char * argv[];
-{
-       register int    i, j;
-       register int    c;
-
-#ifdef unix
-       (void) umask(umask(022) | 022);
-#endif /* defined unix */
-       progname = argv[0];
-       while ((c = getopt(argc, argv, "d:l:p:L:vsy:")) != EOF)
-               switch (c) {
-                       default:
-                               usage();
-                       case 'd':
-                               if (directory == NULL)
-                                       directory = optarg;
-                               else {
-                                       (void) fprintf(stderr,
-"%s: More than one -d option specified\n",
-                                               progname);
-                                       (void) exit(EXIT_FAILURE);
-                               }
-                               break;
-                       case 'l':
-                               if (lcltime == NULL)
-                                       lcltime = optarg;
-                               else {
-                                       (void) fprintf(stderr,
-"%s: More than one -l option specified\n",
-                                               progname);
-                                       (void) exit(EXIT_FAILURE);
-                               }
-                               break;
-                       case 'p':
-                               if (psxrules == NULL)
-                                       psxrules = optarg;
-                               else {
-                                       (void) fprintf(stderr,
-"%s: More than one -p option specified\n",
-                                               progname);
-                                       (void) exit(EXIT_FAILURE);
-                               }
-                               break;
-                       case 'y':
-                               if (yitcommand == NULL)
-                                       yitcommand = optarg;
-                               else {
-                                       (void) fprintf(stderr,
-"%s: More than one -y option specified\n",
-                                               progname);
-                                       (void) exit(EXIT_FAILURE);
-                               }
-                               break;
-                       case 'L':
-                               if (leapsec == NULL)
-                                       leapsec = optarg;
-                               else {
-                                       (void) fprintf(stderr,
-"%s: More than one -L option specified\n",
-                                               progname);
-                                       (void) exit(EXIT_FAILURE);
-                               }
-                               break;
-                       case 'v':
-                               noise = TRUE;
-                               break;
-                       case 's':
-                               sflag = TRUE;
-                               break;
-               }
-       if (optind == argc - 1 && strcmp(argv[optind], "=") == 0)
-               usage();        /* usage message by request */
-       if (directory == NULL)
-               directory = TZDIR;
-       if (yitcommand == NULL)
-               yitcommand = "yearistype";
-
-       setboundaries();
-
-       if (optind < argc && leapsec != NULL) {
-               infile(leapsec);
-               adjleap();
-       }
-
-       for (i = optind; i < argc; ++i)
-               infile(argv[i]);
-       if (errors)
-               (void) exit(EXIT_FAILURE);
-       associate();
-       for (i = 0; i < nzones; i = j) {
-               /*
-               ** Find the next non-continuation zone entry.
-               */
-               for (j = i + 1; j < nzones && zones[j].z_name == NULL; ++j)
-                       continue;
-               outzone(&zones[i], j - i);
-       }
-       /*
-       ** Make links.
-       */
-       for (i = 0; i < nlinks; ++i)
-               dolink(links[i].l_from, links[i].l_to);
-       if (lcltime != NULL)
-               dolink(lcltime, TZDEFAULT);
-       if (psxrules != NULL)
-               dolink(psxrules, TZDEFRULES);
-       return (errors == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
-}
-
-static void
-dolink(fromfile, tofile)
-const char * const     fromfile;
-const char * const     tofile;
-{
-       register char * fromname;
-       register char * toname;
-
-       if (fromfile[0] == '/')
-               fromname = ecpyalloc(fromfile);
-       else {
-               fromname = ecpyalloc(directory);
-               fromname = ecatalloc(fromname, "/");
-               fromname = ecatalloc(fromname, fromfile);
-       }
-       if (tofile[0] == '/')
-               toname = ecpyalloc(tofile);
-       else {
-               toname = ecpyalloc(directory);
-               toname = ecatalloc(toname, "/");
-               toname = ecatalloc(toname, tofile);
-       }
-       /*
-       ** We get to be careful here since
-       ** there's a fair chance of root running us.
-       */
-       if (!itsdir(toname))
-               (void) remove(toname);
-       if (link(fromname, toname) != 0) {
-               if (mkdirs(toname) != 0)
-                       (void) exit(EXIT_FAILURE);
-               if (link(fromname, toname) != 0) {
-                       (void) fprintf(stderr, "%s: Can't link from %s to ",
-                               progname, fromname);
-                       (void) perror(toname);
-                       (void) exit(EXIT_FAILURE);
-               }
-       }
-       ifree(fromname);
-       ifree(toname);
-}
-
-static void
-setboundaries P((void))
-{
-       register time_t bit;
-       register int bii;
-
-       for (bit = 1; bit > 0; bit <<= 1)
-               continue;
-       if (bit == 0) {         /* time_t is an unsigned type */
-               tt_signed = FALSE;
-               min_time = 0;
-               max_time = ~(time_t) 0;
-               if (sflag)
-                       max_time >>= 1;
-       } else {
-               tt_signed = TRUE;
-               min_time = bit;
-               max_time = bit;
-               ++max_time;
-               max_time = -max_time;
-               if (sflag)
-                       min_time = 0;
-       }
-       min_year = TM_YEAR_BASE + gmtime(&min_time)->tm_year;
-       max_year = TM_YEAR_BASE + gmtime(&max_time)->tm_year;
-
-       for (bii = 1; bii > 0; bii <<= 1)
-               continue;
-       min_int = bii;
-       max_int = -1 - bii;
-}
-
-static int
-itsdir(name)
-const char * const     name;
-{
-       register char * myname;
-       register int    accres;
-
-       myname = ecpyalloc(name);
-       myname = ecatalloc(myname, "/.");
-       accres = access(myname, 0);
-       ifree(myname);
-       return accres == 0;
-}
-
-/*
-** Associate sets of rules with zones.
-*/
-
-/*
-** Sort by rule name.
-*/
-
-static int
-rcomp(cp1, cp2)
-const genericptr_T     cp1;
-const genericptr_T     cp2;
-{
-       return strcmp(((struct rule *) cp1)->r_name,
-               ((struct rule *) cp2)->r_name);
-}
-
-static void
-associate P((void))
-{
-       register struct zone *  zp;
-       register struct rule *  rp;
-       register int            base, out;
-       register int            i;
-
-       if (nrules != 0)
-               (void) qsort((genericptr_T) rules,
-                       (qsort_size_T) nrules,
-                       (qsort_size_T) sizeof *rules, rcomp);
-       for (i = 0; i < nzones; ++i) {
-               zp = &zones[i];
-               zp->z_rules = NULL;
-               zp->z_nrules = 0;
-       }
-       for (base = 0; base < nrules; base = out) {
-               rp = &rules[base];
-               for (out = base + 1; out < nrules; ++out)
-                       if (strcmp(rp->r_name, rules[out].r_name) != 0)
-                               break;
-               for (i = 0; i < nzones; ++i) {
-                       zp = &zones[i];
-                       if (strcmp(zp->z_rule, rp->r_name) != 0)
-                               continue;
-                       zp->z_rules = rp;
-                       zp->z_nrules = out - base;
-               }
-       }
-       for (i = 0; i < nzones; ++i) {
-               zp = &zones[i];
-               if (zp->z_nrules == 0) {
-                       /*
-                       ** Maybe we have a local standard time offset.
-                       */
-                       eat(zp->z_filename, zp->z_linenum);
-                       zp->z_stdoff = gethms(zp->z_rule, "unruly zone", TRUE);
-                       /*
-                       ** Note, though, that if there's no rule,
-                       ** a '%s' in the format is a bad thing.
-                       */
-                       if (strchr(zp->z_format, '%') != 0)
-                               error("%s in ruleless zone");
-               }
-       }
-       if (errors)
-               (void) exit(EXIT_FAILURE);
-}
-
-static void
-infile(name)
-const char *   name;
-{
-       register FILE *                 fp;
-       register char **                fields;
-       register char *                 cp;
-       register const struct lookup *  lp;
-       register int                    nfields;
-       register int                    wantcont;
-       register int                    num;
-       char                            buf[BUFSIZ];
-
-       if (strcmp(name, "-") == 0) {
-               name = "standard input";
-               fp = stdin;
-       } else if ((fp = fopen(name, "r")) == NULL) {
-               (void) fprintf(stderr, "%s: Can't open ", progname);
-               (void) perror(name);
-               (void) exit(EXIT_FAILURE);
-       }
-       wantcont = FALSE;
-       for (num = 1; ; ++num) {
-               eat(name, num);
-               if (fgets(buf, (int) sizeof buf, fp) != buf)
-                       break;
-               cp = strchr(buf, '\n');
-               if (cp == NULL) {
-                       error("line too long");
-                       (void) exit(EXIT_FAILURE);
-               }
-               *cp = '\0';
-               fields = getfields(buf);
-               nfields = 0;
-               while (fields[nfields] != NULL) {
-                       static char     nada;
-
-                       if (ciequal(fields[nfields], "-"))
-                               fields[nfields] = &nada;
-                       ++nfields;
-               }
-               if (nfields == 0) {
-                       /* nothing to do */
-               } else if (wantcont) {
-                       wantcont = inzcont(fields, nfields);
-               } else {
-                       lp = byword(fields[0], line_codes);
-                       if (lp == NULL)
-                               error("input line of unknown type");
-                       else switch ((int) (lp->l_value)) {
-                               case LC_RULE:
-                                       inrule(fields, nfields);
-                                       wantcont = FALSE;
-                                       break;
-                               case LC_ZONE:
-                                       wantcont = inzone(fields, nfields);
-                                       break;
-                               case LC_LINK:
-                                       inlink(fields, nfields);
-                                       wantcont = FALSE;
-                                       break;
-                               case LC_LEAP:
-                                       if (name != leapsec)
-                                               (void) fprintf(stderr,
-"%s: Leap line in non leap seconds file %s\n",
-                                                       progname, name);
-                                       else    inleap(fields, nfields);
-                                       wantcont = FALSE;
-                                       break;
-                               default:        /* "cannot happen" */
-                                       (void) fprintf(stderr,
-"%s: panic: Invalid l_value %d\n",
-                                               progname, lp->l_value);
-                                       (void) exit(EXIT_FAILURE);
-                       }
-               }
-               ifree((char *) fields);
-       }
-       if (ferror(fp)) {
-               (void) fprintf(stderr, "%s: Error reading ", progname);
-               (void) perror(filename);
-               (void) exit(EXIT_FAILURE);
-       }
-       if (fp != stdin && fclose(fp)) {
-               (void) fprintf(stderr, "%s: Error closing ", progname);
-               (void) perror(filename);
-               (void) exit(EXIT_FAILURE);
-       }
-       if (wantcont)
-               error("expected continuation line not found");
-}
-
-/*
-** Convert a string of one of the forms
-**     h       -h      hh:mm   -hh:mm  hh:mm:ss        -hh:mm:ss
-** into a number of seconds.
-** A null string maps to zero.
-** Call error with errstring and return zero on errors.
-*/
-
-static long
-gethms(string, errstring, signable)
-const char *           string;
-const char * const     errstring;
-const int              signable;
-{
-       int     hh, mm, ss, sign;
-
-       if (string == NULL || *string == '\0')
-               return 0;
-       if (!signable)
-               sign = 1;
-       else if (*string == '-') {
-               sign = -1;
-               ++string;
-       } else  sign = 1;
-       if (sscanf(string, scheck(string, "%d"), &hh) == 1)
-               mm = ss = 0;
-       else if (sscanf(string, scheck(string, "%d:%d"), &hh, &mm) == 2)
-               ss = 0;
-       else if (sscanf(string, scheck(string, "%d:%d:%d"),
-               &hh, &mm, &ss) != 3) {
-                       error(errstring);
-                       return 0;
-       }
-       if (hh < 0 || hh >= HOURSPERDAY ||
-               mm < 0 || mm >= MINSPERHOUR ||
-               ss < 0 || ss > SECSPERMIN) {
-                       error(errstring);
-                       return 0;
-       }
-       return eitol(sign) *
-               (eitol(hh * MINSPERHOUR + mm) *
-               eitol(SECSPERMIN) + eitol(ss));
-}
-
-static void
-inrule(fields, nfields)
-register char ** const fields;
-const int              nfields;
-{
-       static struct rule      r;
-
-       if (nfields != RULE_FIELDS) {
-               error("wrong number of fields on Rule line");
-               return;
-       }
-       if (*fields[RF_NAME] == '\0') {
-               error("nameless rule");
-               return;
-       }
-       r.r_filename = filename;
-       r.r_linenum = linenum;
-       r.r_stdoff = gethms(fields[RF_STDOFF], "invalid saved time", TRUE);
-       rulesub(&r, fields[RF_LOYEAR], fields[RF_HIYEAR], fields[RF_COMMAND],
-               fields[RF_MONTH], fields[RF_DAY], fields[RF_TOD]);
-       r.r_name = ecpyalloc(fields[RF_NAME]);
-       r.r_abbrvar = ecpyalloc(fields[RF_ABBRVAR]);
-       rules = (struct rule *) (void *) erealloc((char *) rules,
-               (int) ((nrules + 1) * sizeof *rules));
-       rules[nrules++] = r;
-}
-
-static int
-inzone(fields, nfields)
-register char ** const fields;
-const int              nfields;
-{
-       register int    i;
-       static char *   buf;
-
-       if (nfields < ZONE_MINFIELDS || nfields > ZONE_MAXFIELDS) {
-               error("wrong number of fields on Zone line");
-               return FALSE;
-       }
-       if (strcmp(fields[ZF_NAME], TZDEFAULT) == 0 && lcltime != NULL) {
-               buf = erealloc(buf, (int) (132 + strlen(TZDEFAULT)));
-               (void) sprintf(buf,
-"\"Zone %s\" line and -l option are mutually exclusive",
-                       TZDEFAULT);
-               error(buf);
-               return FALSE;
-       }
-       if (strcmp(fields[ZF_NAME], TZDEFRULES) == 0 && psxrules != NULL) {
-               buf = erealloc(buf, (int) (132 + strlen(TZDEFRULES)));
-               (void) sprintf(buf,
-"\"Zone %s\" line and -p option are mutually exclusive",
-                       TZDEFRULES);
-               error(buf);
-               return FALSE;
-       }
-       for (i = 0; i < nzones; ++i)
-               if (zones[i].z_name != NULL &&
-                       strcmp(zones[i].z_name, fields[ZF_NAME]) == 0) {
-                               buf = erealloc(buf, (int) (132 +
-                                       strlen(fields[ZF_NAME]) +
-                                       strlen(zones[i].z_filename)));
-                               (void) sprintf(buf,
-"duplicate zone name %s (file \"%s\", line %d)",
-                                       fields[ZF_NAME],
-                                       zones[i].z_filename,
-                                       zones[i].z_linenum);
-                               error(buf);
-                               return FALSE;
-               }
-       return inzsub(fields, nfields, FALSE);
-}
-
-static int
-inzcont(fields, nfields)
-register char ** const fields;
-const int              nfields;
-{
-       if (nfields < ZONEC_MINFIELDS || nfields > ZONEC_MAXFIELDS) {
-               error("wrong number of fields on Zone continuation line");
-               return FALSE;
-       }
-       return inzsub(fields, nfields, TRUE);
-}
-
-static int
-inzsub(fields, nfields, iscont)
-register char ** const fields;
-const int              nfields;
-const int              iscont;
-{
-       register char *         cp;
-       static struct zone      z;
-       register int            i_gmtoff, i_rule, i_format;
-       register int            i_untilyear, i_untilmonth;
-       register int            i_untilday, i_untiltime;
-       register int            hasuntil;
-
-       if (iscont) {
-               i_gmtoff = ZFC_GMTOFF;
-               i_rule = ZFC_RULE;
-               i_format = ZFC_FORMAT;
-               i_untilyear = ZFC_TILYEAR;
-               i_untilmonth = ZFC_TILMONTH;
-               i_untilday = ZFC_TILDAY;
-               i_untiltime = ZFC_TILTIME;
-               z.z_name = NULL;
-       } else {
-               i_gmtoff = ZF_GMTOFF;
-               i_rule = ZF_RULE;
-               i_format = ZF_FORMAT;
-               i_untilyear = ZF_TILYEAR;
-               i_untilmonth = ZF_TILMONTH;
-               i_untilday = ZF_TILDAY;
-               i_untiltime = ZF_TILTIME;
-               z.z_name = ecpyalloc(fields[ZF_NAME]);
-       }
-       z.z_filename = filename;
-       z.z_linenum = linenum;
-       z.z_gmtoff = gethms(fields[i_gmtoff], "invalid GMT offset", TRUE);
-       if ((cp = strchr(fields[i_format], '%')) != 0) {
-               if (*++cp != 's' || strchr(cp, '%') != 0) {
-                       error("invalid abbreviation format");
-                       return FALSE;
-               }
-       }
-       z.z_rule = ecpyalloc(fields[i_rule]);
-       z.z_format = ecpyalloc(fields[i_format]);
-       hasuntil = nfields > i_untilyear;
-       if (hasuntil) {
-               z.z_untilrule.r_filename = filename;
-               z.z_untilrule.r_linenum = linenum;
-               rulesub(&z.z_untilrule,
-                       fields[i_untilyear],
-                       "only",
-                       "",
-                       (nfields > i_untilmonth) ?
-                       fields[i_untilmonth] : "Jan",
-                       (nfields > i_untilday) ? fields[i_untilday] : "1",
-                       (nfields > i_untiltime) ? fields[i_untiltime] : "0");
-               z.z_untiltime = rpytime(&z.z_untilrule,
-                       z.z_untilrule.r_loyear);
-               if (iscont && nzones > 0 &&
-                       z.z_untiltime > min_time &&
-                       z.z_untiltime < max_time &&
-                       zones[nzones - 1].z_untiltime > min_time &&
-                       zones[nzones - 1].z_untiltime < max_time &&
-                       zones[nzones - 1].z_untiltime >= z.z_untiltime) {
-error("Zone continuation line end time is not after end time of previous line");
-                               return FALSE;
-               }
-       }
-       zones = (struct zone *) (void *) erealloc((char *) zones,
-               (int) ((nzones + 1) * sizeof *zones));
-       zones[nzones++] = z;
-       /*
-       ** If there was an UNTIL field on this line,
-       ** there's more information about the zone on the next line.
-       */
-       return hasuntil;
-}
-
-static void
-inleap(fields, nfields)
-register char ** const fields;
-const int              nfields;
-{
-       register const char *           cp;
-       register const struct lookup *  lp;
-       register int                    i, j;
-       int                             year, month, day;
-       long                            dayoff, tod;
-       time_t                          t;
-
-       if (nfields != LEAP_FIELDS) {
-               error("wrong number of fields on Leap line");
-               return;
-       }
-       dayoff = 0;
-       cp = fields[LP_YEAR];
-       if (sscanf(cp, scheck(cp, "%d"), &year) != 1) {
-                       /*
-                        * Leapin' Lizards!
-                        */
-                       error("invalid leaping year");
-                       return;
-       }
-       j = EPOCH_YEAR;
-       while (j != year) {
-               if (year > j) {
-                       i = len_years[isleap(j)];
-                       ++j;
-               } else {
-                       --j;
-                       i = -len_years[isleap(j)];
-               }
-               dayoff = oadd(dayoff, eitol(i));
-       }
-       if ((lp = byword(fields[LP_MONTH], mon_names)) == NULL) {
-               error("invalid month name");
-               return;
-       }
-       month = lp->l_value;
-       j = TM_JANUARY;
-       while (j != month) {
-               i = len_months[isleap(year)][j];
-               dayoff = oadd(dayoff, eitol(i));
-               ++j;
-       }
-       cp = fields[LP_DAY];
-       if (sscanf(cp, scheck(cp, "%d"), &day) != 1 ||
-               day <= 0 || day > len_months[isleap(year)][month]) {
-                       error("invalid day of month");
-                       return;
-       }
-       dayoff = oadd(dayoff, eitol(day - 1));
-       if (dayoff < 0 && !tt_signed) {
-               error("time before zero");
-               return;
-       }
-       t = (time_t) dayoff * SECSPERDAY;
-       /*
-       ** Cheap overflow check.
-       */
-       if (t / SECSPERDAY != dayoff) {
-               error("time overflow");
-               return;
-       }
-       tod = gethms(fields[LP_TIME], "invalid time of day", FALSE);
-       cp = fields[LP_CORR];
-       {
-               register int    positive;
-               int             count;
-
-               if (strcmp(cp, "") == 0) { /* infile() turns "-" into "" */
-                       positive = FALSE;
-                       count = 1;
-               } else if (strcmp(cp, "--") == 0) {
-                       positive = FALSE;
-                       count = 2;
-               } else if (strcmp(cp, "+") == 0) {
-                       positive = TRUE;
-                       count = 1;
-               } else if (strcmp(cp, "++") == 0) {
-                       positive = TRUE;
-                       count = 2;
-               } else {
-                       error("illegal CORRECTION field on Leap line");
-                       return;
-               }
-               if ((lp = byword(fields[LP_ROLL], leap_types)) == NULL) {
-                       error("illegal Rolling/Stationary field on Leap line");
-                       return;
-               }
-               leapadd(tadd(t, tod), positive, lp->l_value, count);
-       }
-}
-
-static void
-inlink(fields, nfields)
-register char ** const fields;
-const int              nfields;
-{
-       struct link     l;
-
-       if (nfields != LINK_FIELDS) {
-               error("wrong number of fields on Link line");
-               return;
-       }
-       if (*fields[LF_FROM] == '\0') {
-               error("blank FROM field on Link line");
-               return;
-       }
-       if (*fields[LF_TO] == '\0') {
-               error("blank TO field on Link line");
-               return;
-       }
-       l.l_filename = filename;
-       l.l_linenum = linenum;
-       l.l_from = ecpyalloc(fields[LF_FROM]);
-       l.l_to = ecpyalloc(fields[LF_TO]);
-       links = (struct link *) (void *) erealloc((char *) links,
-               (int) ((nlinks + 1) * sizeof *links));
-       links[nlinks++] = l;
-}
-
-static void
-rulesub(rp, loyearp, hiyearp, typep, monthp, dayp, timep)
-register struct rule * const   rp;
-const char * const             loyearp;
-const char * const             hiyearp;
-const char * const             typep;
-const char * const             monthp;
-const char * const             dayp;
-const char * const             timep;
-{
-       register const struct lookup *  lp;
-       register const char *           cp;
-       register char *                 dp;
-       register char *                 ep;
-
-       if ((lp = byword(monthp, mon_names)) == NULL) {
-               error("invalid month name");
-               return;
-       }
-       rp->r_month = lp->l_value;
-       rp->r_todisstd = FALSE;
-       rp->r_todisuniv = FALSE;
-       dp = ecpyalloc(timep);
-       if (*dp != '\0') {
-               ep = dp + strlen(dp) - 1;
-               switch (lowerit(*ep)) {
-                       case 's':       /* Standard */
-                               rp->r_todisstd = TRUE;
-                               rp->r_todisuniv = FALSE;
-                               *ep = '\0';
-                               break;
-                       case 'w':       /* Wall */
-                               rp->r_todisstd = FALSE;
-                               rp->r_todisuniv = FALSE;
-                               *ep = '\0';
-                       case 'g':       /* Greenwich */
-                       case 'u':       /* Universal */
-                       case 'z':       /* Zulu */
-                               rp->r_todisstd = TRUE;
-                               rp->r_todisuniv = TRUE;
-                               *ep = '\0';
-                               break;
-               }
-       }
-       rp->r_tod = gethms(dp, "invalid time of day", FALSE);
-       ifree(dp);
-       /*
-       ** Year work.
-       */
-       cp = loyearp;
-       if ((lp = byword(cp, begin_years)) != NULL) switch ((int) lp->l_value) {
-               case YR_MINIMUM:
-                       rp->r_loyear = min_int;
-                       break;
-               case YR_MAXIMUM:
-                       rp->r_loyear = max_int;
-                       break;
-               default:        /* "cannot happen" */
-                       (void) fprintf(stderr,
-                               "%s: panic: Invalid l_value %d\n",
-                               progname, lp->l_value);
-                       (void) exit(EXIT_FAILURE);
-       } else if (sscanf(cp, scheck(cp, "%d"), &rp->r_loyear) != 1) {
-               error("invalid starting year");
-               return;
-       }
-       cp = hiyearp;
-       if ((lp = byword(cp, end_years)) != NULL) switch ((int) lp->l_value) {
-               case YR_MINIMUM:
-                       rp->r_hiyear = min_int;
-                       break;
-               case YR_MAXIMUM:
-                       rp->r_hiyear = max_int;
-                       break;
-               case YR_ONLY:
-                       rp->r_hiyear = rp->r_loyear;
-                       break;
-               default:        /* "cannot happen" */
-                       (void) fprintf(stderr,
-                               "%s: panic: Invalid l_value %d\n",
-                               progname, lp->l_value);
-                       (void) exit(EXIT_FAILURE);
-       } else if (sscanf(cp, scheck(cp, "%d"), &rp->r_hiyear) != 1) {
-               error("invalid ending year");
-               return;
-       }
-       if (rp->r_loyear > rp->r_hiyear) {
-               error("starting year greater than ending year");
-               return;
-       }
-       if (*typep == '\0')
-               rp->r_yrtype = NULL;
-       else {
-               if (rp->r_loyear == rp->r_hiyear) {
-                       error("typed single year");
-                       return;
-               }
-               rp->r_yrtype = ecpyalloc(typep);
-       }
-       /*
-       ** Day work.
-       ** Accept things such as:
-       **      1
-       **      last-Sunday
-       **      Sun<=20
-       **      Sun>=7
-       */
-       dp = ecpyalloc(dayp);
-       if ((lp = byword(dp, lasts)) != NULL) {
-               rp->r_dycode = DC_DOWLEQ;
-               rp->r_wday = lp->l_value;
-               rp->r_dayofmonth = len_months[1][rp->r_month];
-       } else {
-               if ((ep = strchr(dp, '<')) != 0)
-                       rp->r_dycode = DC_DOWLEQ;
-               else if ((ep = strchr(dp, '>')) != 0)
-                       rp->r_dycode = DC_DOWGEQ;
-               else {
-                       ep = dp;
-                       rp->r_dycode = DC_DOM;
-               }
-               if (rp->r_dycode != DC_DOM) {
-                       *ep++ = 0;
-                       if (*ep++ != '=') {
-                               error("invalid day of month");
-                               ifree(dp);
-                               return;
-                       }
-                       if ((lp = byword(dp, wday_names)) == NULL) {
-                               error("invalid weekday name");
-                               ifree(dp);
-                               return;
-                       }
-                       rp->r_wday = lp->l_value;
-               }
-               if (sscanf(ep, scheck(ep, "%d"), &rp->r_dayofmonth) != 1 ||
-                       rp->r_dayofmonth <= 0 ||
-                       (rp->r_dayofmonth > len_months[1][rp->r_month])) {
-                               error("invalid day of month");
-                               ifree(dp);
-                               return;
-               }
-       }
-       ifree(dp);
-}
-
-static void
-convert(val, buf)
-const long     val;
-char * const   buf;
-{
-       register int    i;
-       register long   shift;
-
-       for (i = 0, shift = 24; i < 4; ++i, shift -= 8)
-               buf[i] = val >> shift;
-}
-
-static void
-puttzcode(val, fp)
-const long     val;
-FILE * const   fp;
-{
-       char    buf[4];
-
-       convert(val, buf);
-       (void) fwrite((genericptr_T) buf,
-               (fwrite_size_T) sizeof buf,
-               (fwrite_size_T) 1, fp);
-}
-
-static void
-writezone(name)
-const char * const     name;
-{
-       register FILE *         fp;
-       register int            i, j;
-       static char *           fullname;
-       static struct tzhead    tzh;
-
-       fullname = erealloc(fullname,
-               (int) (strlen(directory) + 1 + strlen(name) + 1));
-       (void) sprintf(fullname, "%s/%s", directory, name);
-       if ((fp = fopen(fullname, "wb")) == NULL) {
-               if (mkdirs(fullname) != 0)
-                       (void) exit(EXIT_FAILURE);
-               if ((fp = fopen(fullname, "wb")) == NULL) {
-                       (void) fprintf(stderr, "%s: Can't create ", progname);
-                       (void) perror(fullname);
-                       (void) exit(EXIT_FAILURE);
-               }
-       }
-       convert(eitol(typecnt), tzh.tzh_ttisstdcnt);
-       convert(eitol(leapcnt), tzh.tzh_leapcnt);
-       convert(eitol(timecnt), tzh.tzh_timecnt);
-       convert(eitol(typecnt), tzh.tzh_typecnt);
-       convert(eitol(charcnt), tzh.tzh_charcnt);
-       (void) fwrite((genericptr_T) &tzh,
-               (fwrite_size_T) sizeof tzh,
-               (fwrite_size_T) 1, fp);
-       for (i = 0; i < timecnt; ++i) {
-               j = leapcnt;
-               while (--j >= 0)
-                       if (ats[i] >= trans[j]) {
-                               ats[i] = tadd(ats[i], corr[j]);
-                               break;
-                       }
-               puttzcode((long) ats[i], fp);
-       }
-       if (timecnt > 0)
-               (void) fwrite((genericptr_T) types,
-                       (fwrite_size_T) sizeof types[0],
-                       (fwrite_size_T) timecnt, fp);
-       for (i = 0; i < typecnt; ++i) {
-               puttzcode((long) gmtoffs[i], fp);
-               (void) putc(isdsts[i], fp);
-               (void) putc(abbrinds[i], fp);
-       }
-       if (charcnt != 0)
-               (void) fwrite((genericptr_T) chars,
-                       (fwrite_size_T) sizeof chars[0],
-                       (fwrite_size_T) charcnt, fp);
-       for (i = 0; i < leapcnt; ++i) {
-               if (roll[i]) {
-                       if (timecnt == 0 || trans[i] < ats[0]) {
-                               j = 0;
-                               while (isdsts[j])
-                                       if (++j >= typecnt) {
-                                               j = 0;
-                                               break;
-                                       }
-                       } else {
-                               j = 1;
-                               while (j < timecnt && trans[i] >= ats[j])
-                                       ++j;
-                               j = types[j - 1];
-                       }
-                       puttzcode((long) tadd(trans[i], -gmtoffs[j]), fp);
-               } else  puttzcode((long) trans[i], fp);
-               puttzcode((long) corr[i], fp);
-       }
-       for (i = 0; i < typecnt; ++i)
-               (void) putc(ttisstds[i], fp);
-       if (ferror(fp) || fclose(fp)) {
-               (void) fprintf(stderr, "%s: Write error on ", progname);
-               (void) perror(fullname);
-               (void) exit(EXIT_FAILURE);
-       }
-}
-
-static void
-outzone(zpfirst, zonecount)
-const struct zone * const      zpfirst;
-const int                      zonecount;
-{
-       register const struct zone *    zp;
-       register struct rule *          rp;
-       register int                    i, j;
-       register int                    usestart, useuntil;
-       register time_t                 starttime, untiltime;
-       register long                   gmtoff;
-       register long                   stdoff;
-       register int                    year;
-       register long                   startoff;
-       register int                    startisdst;
-       register int                    startttisstd;
-       register int                    type;
-       char                            startbuf[BUFSIZ];
-
-       INITIALIZE(untiltime);
-       INITIALIZE(starttime);
-       INITIALIZE(startoff);
-       /*
-       ** Now. . .finally. . .generate some useful data!
-       */
-       timecnt = 0;
-       typecnt = 0;
-       charcnt = 0;
-       /*
-       ** A guess that may well be corrected later.
-       */
-       stdoff = 0;
-       /*
-       ** Thanks to Earl Chew (earl@dnd.icp.nec.com.au)
-       ** for noting the need to unconditionally initialize startttisstd.
-       */
-       startttisstd = FALSE;
-#ifdef lint
-       starttime = 0;
-#endif /* defined lint */
-       for (i = 0; i < zonecount; ++i) {
-               zp = &zpfirst[i];
-               usestart = i > 0 && (zp - 1)->z_untiltime > min_time;
-               useuntil = i < (zonecount - 1);
-               if (useuntil && zp->z_untiltime <= min_time)
-                       continue;
-               gmtoff = zp->z_gmtoff;
-               eat(zp->z_filename, zp->z_linenum);
-               startisdst = -1;
-               if (zp->z_nrules == 0) {
-                       stdoff = zp->z_stdoff;
-                       (void) strcpy(startbuf, zp->z_format);
-                       type = addtype(oadd(zp->z_gmtoff, stdoff),
-                               startbuf, stdoff != 0, startttisstd);
-                       if (usestart)
-                               addtt(starttime, type);
-                       else if (stdoff != 0)
-                               addtt(min_time, type);
-               } else for (year = min_year; year <= max_year; ++year) {
-                       if (useuntil && year > zp->z_untilrule.r_hiyear)
-                               break;
-                       /*
-                       ** Mark which rules to do in the current year.
-                       ** For those to do, calculate rpytime(rp, year);
-                       */
-                       for (j = 0; j < zp->z_nrules; ++j) {
-                               rp = &zp->z_rules[j];
-                               eats(zp->z_filename, zp->z_linenum,
-                                       rp->r_filename, rp->r_linenum);
-                               rp->r_todo = year >= rp->r_loyear &&
-                                               year <= rp->r_hiyear &&
-                                               yearistype(year, rp->r_yrtype);
-                               if (rp->r_todo)
-                                       rp->r_temp = rpytime(rp, year);
-                       }
-                       for ( ; ; ) {
-                               register int    k;
-                               register time_t jtime, ktime;
-                               register long   offset;
-                               char            buf[BUFSIZ];
-
-                               INITIALIZE(ktime);
-                               if (useuntil) {
-                                       /*
-                                       ** Turn untiltime into GMT
-                                       ** assuming the current gmtoff and
-                                       ** stdoff values.
-                                       */
-                                       untiltime = zp->z_untiltime;
-                                       if (!zp->z_untilrule.r_todisuniv)
-                                               untiltime = tadd(untiltime,
-                                                       -gmtoff);
-                                       if (!zp->z_untilrule.r_todisstd)
-                                               untiltime = tadd(untiltime,
-                                                       -stdoff);
-                               }
-                               /*
-                               ** Find the rule (of those to do, if any)
-                               ** that takes effect earliest in the year.
-                               */
-                               k = -1;
-#ifdef lint
-                               ktime = 0;
-#endif /* defined lint */
-                               for (j = 0; j < zp->z_nrules; ++j) {
-                                       rp = &zp->z_rules[j];
-                                       if (!rp->r_todo)
-                                               continue;
-                                       eats(zp->z_filename, zp->z_linenum,
-                                               rp->r_filename, rp->r_linenum);
-                                       offset = rp->r_todisuniv ? 0 : gmtoff;
-                                       if (!rp->r_todisstd)
-                                               offset = oadd(offset, stdoff);
-                                       jtime = rp->r_temp;
-                                       if (jtime == min_time ||
-                                               jtime == max_time)
-                                                       continue;
-                                       jtime = tadd(jtime, -offset);
-                                       if (k < 0 || jtime < ktime) {
-                                               k = j;
-                                               ktime = jtime;
-                                       }
-                               }
-                               if (k < 0)
-                                       break;  /* go on to next year */
-                               rp = &zp->z_rules[k];
-                               rp->r_todo = FALSE;
-                               if (useuntil && ktime >= untiltime)
-                                       break;
-                               if (usestart) {
-                                   if (ktime < starttime) {
-                                       stdoff = rp->r_stdoff;
-                                       startoff = oadd(zp->z_gmtoff,
-                                               rp->r_stdoff);
-                                       (void) sprintf(startbuf, zp->z_format,
-                                               rp->r_abbrvar);
-                                       startisdst = rp->r_stdoff != 0;
-                                       continue;
-                                   }
-                                   usestart = FALSE;
-                                   if (ktime != starttime) {
-                                       if (startisdst < 0 &&
-                                           zp->z_gmtoff !=
-                                           (zp - 1)->z_gmtoff) {
-                                               type = (timecnt == 0) ? 0 :
-                                                       types[timecnt - 1];
-                                               startoff = oadd(gmtoffs[type],
-                                                       -(zp - 1)->z_gmtoff);
-                                               startisdst = startoff != 0;
-                                               startoff = oadd(startoff,
-                                                       zp->z_gmtoff);
-                                               (void) strcpy(startbuf,
-                                                       &chars[abbrinds[type]]);
-                                       }
-                                       if (startisdst >= 0)
-addtt(starttime, addtype(startoff, startbuf, startisdst, startttisstd));
-                                   }
-                               }
-                               eats(zp->z_filename, zp->z_linenum,
-                                       rp->r_filename, rp->r_linenum);
-                               (void) sprintf(buf, zp->z_format,
-                                       rp->r_abbrvar);
-                               offset = oadd(zp->z_gmtoff, rp->r_stdoff);
-                               type = addtype(offset, buf, rp->r_stdoff != 0,
-                                       rp->r_todisstd);
-                               addtt(ktime, type);
-                               stdoff = rp->r_stdoff;
-                       }
-               }
-               /*
-               ** Now we may get to set starttime for the next zone line.
-               */
-               if (useuntil) {
-                       starttime = tadd(zp->z_untiltime, -gmtoff);
-                       startttisstd = zp->z_untilrule.r_todisstd;
-                       if (!startttisstd)
-                               starttime = tadd(starttime, -stdoff);
-               }
-       }
-       writezone(zpfirst->z_name);
-}
-
-static void
-addtt(starttime, type)
-const time_t   starttime;
-const int      type;
-{
-       if (timecnt != 0 && type == types[timecnt - 1])
-               return; /* easy enough! */
-       if (timecnt == 0 && type == 0 && isdsts[0] == 0)
-               return; /* handled by default rule */
-       if (timecnt >= TZ_MAX_TIMES) {
-               error("too many transitions?!");
-               (void) exit(EXIT_FAILURE);
-       }
-       ats[timecnt] = starttime;
-       types[timecnt] = type;
-       ++timecnt;
-}
-
-static int
-addtype(gmtoff, abbr, isdst, ttisstd)
-const long             gmtoff;
-const char * const     abbr;
-const int              isdst;
-const int              ttisstd;
-{
-       register int    i, j;
-
-       /*
-       ** See if there's already an entry for this zone type.
-       ** If so, just return its index.
-       */
-       for (i = 0; i < typecnt; ++i) {
-               if (gmtoff == gmtoffs[i] && isdst == isdsts[i] &&
-                       strcmp(abbr, &chars[abbrinds[i]]) == 0 &&
-                       ttisstd == ttisstds[i])
-                               return i;
-       }
-       /*
-       ** There isn't one; add a new one, unless there are already too
-       ** many.
-       */
-       if (typecnt >= TZ_MAX_TYPES) {
-               error("too many local time types");
-               (void) exit(EXIT_FAILURE);
-       }
-       gmtoffs[i] = gmtoff;
-       isdsts[i] = isdst;
-       ttisstds[i] = ttisstd;
-
-       for (j = 0; j < charcnt; ++j)
-               if (strcmp(&chars[j], abbr) == 0)
-                       break;
-       if (j == charcnt)
-               newabbr(abbr);
-       abbrinds[i] = j;
-       ++typecnt;
-       return i;
-}
-
-static void
-leapadd(t, positive, rolling, count)
-const time_t   t;
-const int      positive;
-const int      rolling;
-int            count;
-{
-       register int    i, j;
-
-       if (leapcnt + (positive ? count : 1) > TZ_MAX_LEAPS) {
-               error("too many leap seconds");
-               (void) exit(EXIT_FAILURE);
-       }
-       for (i = 0; i < leapcnt; ++i)
-               if (t <= trans[i]) {
-                       if (t == trans[i]) {
-                               error("repeated leap second moment");
-                               (void) exit(EXIT_FAILURE);
-                       }
-                       break;
-               }
-       do {
-               for (j = leapcnt; j > i; --j) {
-                       trans[j] = trans[j - 1];
-                       corr[j] = corr[j - 1];
-                       roll[j] = roll[j - 1];
-               }
-               trans[i] = t;
-               corr[i] = positive ? 1L : eitol(-count);
-               roll[i] = rolling;
-               ++leapcnt;
-       } while (positive && --count != 0);
-}
-
-static void
-adjleap P((void))
-{
-       register int    i;
-       register long   last = 0;
-
-       /*
-       ** propagate leap seconds forward
-       */
-       for (i = 0; i < leapcnt; ++i) {
-               trans[i] = tadd(trans[i], last);
-               last = corr[i] += last;
-       }
-}
-
-static int
-yearistype(year, type)
-const int              year;
-const char * const     type;
-{
-       static char *   buf;
-       int             result;
-
-       if (type == NULL || *type == '\0')
-               return TRUE;
-       buf = erealloc(buf, (int) (132 + strlen(yitcommand) + strlen(type)));
-       (void) sprintf(buf, "%s %d %s", yitcommand, year, type);
-       result = system(buf);
-       if (result == 0)
-               return TRUE;
-       if (result == (1 << 8))
-               return FALSE;
-       error("Wild result from command execution");
-       (void) fprintf(stderr, "%s: command was '%s', result was %d\n",
-               progname, buf, result);
-       for ( ; ; )
-               (void) exit(EXIT_FAILURE);
-}
-
-static int
-lowerit(a)
-const int      a;
-{
-       return (isascii(a) && isupper(a)) ? tolower(a) : a;
-}
-
-static int
-ciequal(ap, bp)                /* case-insensitive equality */
-register const char *  ap;
-register const char *  bp;
-{
-       while (lowerit(*ap) == lowerit(*bp++))
-               if (*ap++ == '\0')
-                       return TRUE;
-       return FALSE;
-}
-
-static int
-itsabbr(abbr, word)
-register const char *  abbr;
-register const char *  word;
-{
-       if (lowerit(*abbr) != lowerit(*word))
-               return FALSE;
-       ++word;
-       while (*++abbr != '\0')
-               do if (*word == '\0')
-                       return FALSE;
-                               while (lowerit(*word++) != lowerit(*abbr));
-       return TRUE;
-}
-
-static const struct lookup *
-byword(word, table)
-register const char * const            word;
-register const struct lookup * const   table;
-{
-       register const struct lookup *  foundlp;
-       register const struct lookup *  lp;
-
-       if (word == NULL || table == NULL)
-               return NULL;
-       /*
-       ** Look for exact match.
-       */
-       for (lp = table; lp->l_word != NULL; ++lp)
-               if (ciequal(word, lp->l_word))
-                       return lp;
-       /*
-       ** Look for inexact match.
-       */
-       foundlp = NULL;
-       for (lp = table; lp->l_word != NULL; ++lp)
-               if (itsabbr(word, lp->l_word))
-                       if (foundlp == NULL)
-                               foundlp = lp;
-                       else    return NULL;    /* multiple inexact matches */
-       return foundlp;
-}
-
-static char **
-getfields(cp)
-register char *        cp;
-{
-       register char *         dp;
-       register char **        array;
-       register int            nsubs;
-
-       if (cp == NULL)
-               return NULL;
-       array = (char **) (void *)
-               emalloc((int) ((strlen(cp) + 1) * sizeof *array));
-       nsubs = 0;
-       for ( ; ; ) {
-               while (isascii(*cp) && isspace(*cp))
-                       ++cp;
-               if (*cp == '\0' || *cp == '#')
-                       break;
-               array[nsubs++] = dp = cp;
-               do {
-                       if ((*dp = *cp++) != '"')
-                               ++dp;
-                       else while ((*dp = *cp++) != '"')
-                               if (*dp != '\0')
-                                       ++dp;
-                               else    error("Odd number of quotation marks");
-               } while (*cp != '\0' && *cp != '#' &&
-                       (!isascii(*cp) || !isspace(*cp)));
-               if (isascii(*cp) && isspace(*cp))
-                       ++cp;
-               *dp = '\0';
-       }
-       array[nsubs] = NULL;
-       return array;
-}
-
-static long
-oadd(t1, t2)
-const long     t1;
-const long     t2;
-{
-       register long   t;
-
-       t = t1 + t2;
-       if ((t2 > 0 && t <= t1) || (t2 < 0 && t >= t1)) {
-               error("time overflow");
-               (void) exit(EXIT_FAILURE);
-       }
-       return t;
-}
-
-static time_t
-tadd(t1, t2)
-const time_t   t1;
-const long     t2;
-{
-       register time_t t;
-
-       if (t1 == max_time && t2 > 0)
-               return max_time;
-       if (t1 == min_time && t2 < 0)
-               return min_time;
-       t = t1 + t2;
-       if ((t2 > 0 && t <= t1) || (t2 < 0 && t >= t1)) {
-               error("time overflow");
-               (void) exit(EXIT_FAILURE);
-       }
-       return t;
-}
-
-/*
-** Given a rule, and a year, compute the date - in seconds since January 1,
-** 1970, 00:00 LOCAL time - in that year that the rule refers to.
-*/
-
-static time_t
-rpytime(rp, wantedy)
-register const struct rule * const     rp;
-register const int                     wantedy;
-{
-       register int    y, m, i;
-       register long   dayoff;                 /* with a nod to Margaret O. */
-       register time_t t;
-
-       if (wantedy == min_int)
-               return min_time;
-       if (wantedy == max_int)
-               return max_time;
-       dayoff = 0;
-       m = TM_JANUARY;
-       y = EPOCH_YEAR;
-       while (wantedy != y) {
-               if (wantedy > y) {
-                       i = len_years[isleap(y)];
-                       ++y;
-               } else {
-                       --y;
-                       i = -len_years[isleap(y)];
-               }
-               dayoff = oadd(dayoff, eitol(i));
-       }
-       while (m != rp->r_month) {
-               i = len_months[isleap(y)][m];
-               dayoff = oadd(dayoff, eitol(i));
-               ++m;
-       }
-       i = rp->r_dayofmonth;
-       if (m == TM_FEBRUARY && i == 29 && !isleap(y)) {
-               if (rp->r_dycode == DC_DOWLEQ)
-                       --i;
-               else {
-                       error("use of 2/29 in non leap-year");
-                       (void) exit(EXIT_FAILURE);
-               }
-       }
-       --i;
-       dayoff = oadd(dayoff, eitol(i));
-       if (rp->r_dycode == DC_DOWGEQ || rp->r_dycode == DC_DOWLEQ) {
-               register long   wday;
-
-#define LDAYSPERWEEK   ((long) DAYSPERWEEK)
-               wday = eitol(EPOCH_WDAY);
-               /*
-               ** Don't trust mod of negative numbers.
-               */
-               if (dayoff >= 0)
-                       wday = (wday + dayoff) % LDAYSPERWEEK;
-               else {
-                       wday -= ((-dayoff) % LDAYSPERWEEK);
-                       if (wday < 0)
-                               wday += LDAYSPERWEEK;
-               }
-               while (wday != eitol(rp->r_wday))
-                       if (rp->r_dycode == DC_DOWGEQ) {
-                               dayoff = oadd(dayoff, (long) 1);
-                               if (++wday >= LDAYSPERWEEK)
-                                       wday = 0;
-                               ++i;
-                       } else {
-                               dayoff = oadd(dayoff, (long) -1);
-                               if (--wday < 0)
-                                       wday = LDAYSPERWEEK - 1;
-                               --i;
-                       }
-               if (i < 0 || i >= len_months[isleap(y)][m]) {
-                       error("no day in month matches rule");
-                       (void) exit(EXIT_FAILURE);
-               }
-       }
-       if (dayoff < 0 && !tt_signed)
-               return min_time;
-       t = (time_t) dayoff * SECSPERDAY;
-       /*
-       ** Cheap overflow check.
-       */
-       if (t / SECSPERDAY != dayoff)
-               return (dayoff > 0) ? max_time : min_time;
-       return tadd(t, rp->r_tod);
-}
-
-static void
-newabbr(string)
-const char * const     string;
-{
-       register int    i;
-
-       i = strlen(string) + 1;
-       if (charcnt + i > TZ_MAX_CHARS) {
-               error("too many, or too long, time zone abbreviations");
-               (void) exit(EXIT_FAILURE);
-       }
-       (void) strcpy(&chars[charcnt], string);
-       charcnt += eitol(i);
-}
-
-static int
-mkdirs(argname)
-char * const   argname;
-{
-       register char * name;
-       register char * cp;
-
-       if (argname == NULL || *argname == '\0')
-               return 0;
-       cp = name = ecpyalloc(argname);
-       while ((cp = strchr(cp + 1, '/')) != 0) {
-               *cp = '\0';
-#ifndef unix
-               /*
-               ** MS-DOS drive specifier?
-               */
-               if (strlen(name) == 2 && isascii(name[0]) &&
-                       isalpha(name[0]) && name[1] == ':') {
-                               *cp = '/';
-                               continue;
-               }
-#endif /* !defined unix */
-               if (!itsdir(name)) {
-                       /*
-                       ** It doesn't seem to exist, so we try to create it.
-                       */
-                       if (emkdir(name, 0755) != 0) {
-                               (void) fprintf(stderr,
-                                       "%s: Can't create directory ",
-                                       progname);
-                               (void) perror(name);
-                               ifree(name);
-                               return -1;
-                       }
-               }
-               *cp = '/';
-       }
-       ifree(name);
-       return 0;
-}
-
-static long
-eitol(i)
-const int      i;
-{
-       long    l;
-
-       l = i;
-       if ((i < 0 && l >= 0) || (i == 0 && l != 0) || (i > 0 && l <= 0)) {
-               (void) fprintf(stderr,
-                       "%s: %d did not sign extend correctly\n",
-                       progname, i);
-               (void) exit(EXIT_FAILURE);
-       }
-       return l;
-}
-
-/*
-** UNIX was a registered trademark of UNIX System Laboratories in 1993.
-*/
diff --git a/uio.h-diff b/uio.h-diff
new file mode 100644 (file)
index 0000000..48be527
--- /dev/null
@@ -0,0 +1,20 @@
+--- /usr/include/sys/uio.h~    Sun Jan 24 20:02:24 1993
++++ /usr/include/sys/uio.h     Thu Oct 12 12:29:00 1995
+@@ -32,6 +32,7 @@
+ /* Structure describing a section of memory.  */
++#if 0
+ struct iovec
+   {
+     /* Starting address.  */
+@@ -39,6 +40,9 @@
+     /* Length in bytes.  */
+     size_t iov_len;
+   };
++#else
++#include <linux/uio.h>
++#endif
+ __BEGIN_DECLS
diff --git a/util-linux-2.1.Announce b/util-linux-2.1.Announce
new file mode 100644 (file)
index 0000000..0906617
--- /dev/null
@@ -0,0 +1,48 @@
+
+util-linux-2.1.tar.gz     (source distribution)
+util-linux-2.1.bin.tar.gz (binary distribution)
+
+    WARNING: THIS COLLECTION DOES *NOT* SUPPORT SHADOW PASSWORDS.
+
+    WARNING: THIS COLLECTION DOES *NOT* SUPPORT SYSTEM V INITTAB.
+
+    WARNING: USE GNU TAR -- OTHER TARS WILL FAIL SILENTLY!
+
+    WARNING: DO *NOT* INSTALL WITHOUT THINKING.
+
+    WARNING: *READ* the util-linux-2.1.bin.Notes file *BEFORE* and *AFTER*
+             installation: there are a few links you must make by hand.
+
+    This is a collection of many assorted utilities for Linux.  Some are
+    system utilities that are not easily available anywhere elsewhere
+    (e.g., mkfs.minix, mkswap); others are BSD ports of common utilities
+    that are not yet contained in any FSF package (e.g., col); others are
+    non-System-V alternatives to common utilities (e.g., simpleinit,
+    agetty, login, passwd).
+
+    The arrangement, as nearly as I can determine, conforms to the Linux
+    Filesystem Structure, Interim Release 1.1, October 9, 1994, with *NO*
+    exceptions.  A copy of the standards document can be found at
+    tsx-11.mit.edu:/pub/linux/docs/linux-standards/fsstnd/*.
+
+    Many people provided patches and suggestions.  I deeply appreciate
+    this.
+
+
+HIGHLIGHTS for version 2.1:
+
+1) Directory structure rearrange, with configuration support for those who
+   use shadow passwords and System V init (no support is provided for these
+   things, but your utilities won't get overwritten if you do a "make
+   install" after you properly edit MCONFIG).
+2) fdisk and cfdisk should work as expected with 2GB+ disk drives
+3) As usual, lots of stuff was updated and added, including mount, vipw,
+   readprofile
+4) Some stuff was also deleted, and can now be found elsewhere:
+    fsck wrapper: tsx-11.mit.edu:/pub/linux/ALPHA/ext2fs/e2fsprogs*
+    pwd, su: prep.ai.mit.edu:/pub/gnu/sh-utils*
+    ed: prep.ai.mit.edu:/pub/gnu/ed*
+    od: prep.ai.mit.edu:/pub/gnu/textutils*
+    uudecode/uuencode: prep.ai.mit.edu:/pub/gnu/sharutils*
+    bdflush/update: ftp.funet.fi:/pub/OS/Linux/PEOPLE/Linus/v1.1/bdflush*
+
diff --git a/util-linux-2.1.bin.Notes b/util-linux-2.1.bin.Notes
new file mode 100644 (file)
index 0000000..a2ac394
--- /dev/null
@@ -0,0 +1,549 @@
+util-linux: Miscellaneous utilities for Linux
+%n util-linux
+%v 2.1
+%c *
+%l *
+%b *
+%d *
+%f ftp.cs.unc.edu:/pub/users/faith/linux/utils
+%t util-linux-2.1.tar.gz
+%w utils
+%%
+# These lines describe an automated build procedure, please ignore them.
+%setup
+make
+%doc COPYING.GPL COPYING.UCB
+%doc ./time/README.time ./disk-utils/README.cfdisk
+%doc ./disk-utils/README.fdisk ./disk-utils/README.bootutils-0.1
+%doc ./sys-utils/README.setserial ./makedev-1.4.1/README.MAKEDEV-C
+%doc ./misc-utils/README.script ./misc-utils/README.hostname
+%doc ./misc-utils/README.namei ./misc-utils/README.cal
+%doc ./misc-utils/README1.namei ./text-utils/README.col
+%doc ./mount/README.mount ./selection/README.selection
+%doc ./login-utils/README.getty ./login-utils/README.admutil
+%doc ./login-utils/README.poeigl
+%doc util-linux-$VERSION.Announce util-linux-$VERSION.lsm
+cp -a $BUILDDIR/$NAME-$VERSION/example.files /usr/doc/$WHERE/$NAME-$VERSION
+* rm -rf /usr/lib/zoneinfo
+* make install
+%i set -x
+%i /usr/sbin/zic -l US/Eastern
+%i /usr/sbin/zic -p America/New_York
+%i set +x
+%i echo 'WARNING: Check time zone!  (If necessary, change with zic).'
+%i echo 'WARNING: Check /etc/rc for initalization of /var/adm/utmp'
+%i echo 'WARNING: /etc/rc should run /sbin/update, *NOT* /sbin/bdflush'
+exit
+# Please ignore the previous lines. . .
+# The informative part of the notes file starts here:
+
+WARNING: THE PROGRAMS IN THIS SUITE DO *NOT* SUPPORT SHADOW PASSWORD FILES!
+
+WARNING: THIS COLLECTION DOES *NOT* SUPPORT SYSTEM V INITTAB.
+
+WARNING: USE GNU TAR -- OTHER TARS WILL FAIL SILENTLY!
+
+WARNING: DO *NOT* INSTALL WITHOUT THINKING.
+
+WARNING: Read the util-linux-2.1.bin.Notes file *BEFORE* and *AFTER*
+         installation: there are a few links you must make by hand.
+
+WARNING: The agetty, simpleinit, login, passwd, and other programs in this
+         package are *NOT* System V compliant.  These utilities are meant
+         to be used by people who build their own systems.  If you are not
+         a wizard, do *NOT* blindly install these utilities: they could
+         prevent you from logging into your system.  Have a boot floppy
+         ready, especially if you don't know what you are doing.
+
+WARNING: The binary distribution was tarred using GNU TAR AND THE -S OPTION!
+         This means that holes will be preserved, but that ONLY GNU TAR
+         WILL WORK ON THE BINARY DISTRIBUTION (in fact, other, inferior,
+         tar programs will fail silently).  YOU HAVE BEEN WARNED!
+
+WARNING: localtime and posixtime default to US/Eastern -- change these now.
+
+
+
+To install from the binary distribution:
+
+1) Get binary distribution (see the .lsm file for locations)
+2) cd /
+3) gtar zpxvf util-linux-2.1.bin.tar.gz
+   (or: pms -i util-linux-2.1.bin.tar.gz)
+4) *IF* you want to use agetty and simpleinit, then make softlinks from
+   /sbin/init to simpleinit and from /sbin/getty to agetty, but make sure
+   that your /etc/inittab is set up right (this is *NOT* the System V
+   compatible init!), or you will be hosed.
+5) Run zic -l and/or zic -p to set your timezone.  The distribution is set
+   up to use /usr/lib/zoneinfo/US/Eastern as the default.  This was
+   installed with "zic -l US/Eastern"
+6) Remove all the old binaries from previous locations.
+
+
+
+To install from source:
+
+1) Get source distribution (see the .lsm file for locations)
+2) Untar util-linux-2.1.tar.gz in /usr/src
+3) cd util-linux-2.1
+4) Edit MCONFIG:
+
+   If you use the shadow password suite and do _not_ want to install
+   programs like login and passwd that do not support shadow passwords,
+   then set HAVE_SHADOW to yes
+
+   If you use the System V init suite and do _not_ want to install programs
+   like agetty, simpleinit, and shutdown, then set HAVE_SYSVINIT to yes
+
+   If you don't like the compile-time options or the directories, then
+   change them.  Note that you also can say something like "make OPT=-g
+   LDFLAGS=" in order to make a complete debugging version without editing
+   the MCONFIG at all.
+
+5) make
+6) make install
+7) If you want to use simpleinit and agetty, then make softlinks from
+   /sbin/init to simpleinit and from /sbin/getty to agetty, but make sure
+   that your /etc/inittab is set up right (this is *NOT* the System V
+   compatible init!), or you will be hosed.  If you are using the SysV
+   init and/or some other getty, they you can keep using those.
+8) Run zic -l and/or zic -p to set your timezone.  The distribution is set
+   up to use /usr/lib/zoneinfo/US/Eastern as the default.  This was
+   installed with "zic -l US/Eastern"
+9) Remove all the old binaries from previous locations.
+
+
+
+HIGHLIGHTS for version 2.1:
+
+1) Directory structure rearrange, with configuration support for those who
+   use shadow passwords and System V init (no support is provided for these
+   things, but your utilities won't get overwritten if you do a "make
+   install" after you properly edit MCONFIG).
+2) fdisk and cfdisk should work as expected with 2GB+ disk drives
+3) As usual, lots of stuff was updated and added, including mount, vipw,
+   readprofile
+4) Some stuff was also deleted, and can now be found elsewhere:
+    fsck wrapper: tsx-11.mit.edu:/pub/linux/ALPHA/ext2fs/e2fsprogs*
+    pwd, su: prep.ai.mit.edu:/pub/gnu/sh-utils*
+    ed: prep.ai.mit.edu:/pub/gnu/ed*
+    od: prep.ai.mit.edu:/pub/gnu/textutils*
+    uudecode/uuencode: prep.ai.mit.edu:/pub/gnu/sharutils*
+    bdflush/update: ftp.funet.fi:/pub/OS/Linux/PEOPLE/Linus/v1.1/bdflush*
+
+
+
+PARTIAL HISTORY OF UTIL-LINUX:
+
+bsd:
+    Nothing in this directory gets installed, but some BSD programs need
+    this support:
+        err.c: 8.1 (Berkeley) 6/4/93
+        err.h: 8.1 (Berkeley) 6/2/93
+        getopt.c: 4.13 (Berkeley) 2/23/91
+        pathnames.h: 5.3 (Berkeley) 5/9/89 with extensive modifications for
+                     Linux
+
+disk-utils:
+    cfdisk: 0.8 BETA (>2GB) from Kevin E. Martin (martin@cs.unc.edu) with
+            modifications for disks > 2GB.
+            ftp.cs.unc.edu:/pub/users/martin/linux/cfdisk-0.8.tar.gz
+    fdformat: Werner Almesberger (almesber@nessie.cs.id.ethz.ch), with
+              modifications by Marcel Mol (marcel@dutecad.et.tudelft.nl)).
+              Later, updated with a September 1992 version by Werner.
+    fdisk: A. V. Le Blanc (LeBlanc@mcc.ac.uk) fdisk 1.5 release, with
+           patched from Kevin Martin for DOS and OS/2 compatibility (1.5a);
+           Rik Faith (1.5b, 2.0).
+    frag: Werner Almesberger (1.0), Steffen Zahn (1.1), Rob Hooft (1.2), 
+          Steffen Zahn (szahn%masterix@emndev.siemens.co.at) (1.3), Michael
+          Bischoff <mbi@mo.math.nat.tu-bs.de> (1.4).
+    fsck.minix, mkfs.minix: Linus Torvalds, with modifications by: Rik
+                            Faith (faith@cs.unc.edu), Scott Heavner
+                            (sdh@po.cwru.edu), Dr. Wettstein
+                            (greg%wind.uucp@plains.nodak.edu), Daniel
+                            Quinlan (quinlan@yggdrasil.com).
+    mkswap: Linus Torvalds, with modifications by Mike Jagdis
+            (jaggy@purplet.demon.co.uk. )
+    setfdprm: Werner Almesberger (almesber@nessie.cs.id.ethz.ch)
+    llseek.c: from Remy Card's e2fsprogs-0.5b-WIP.tar.gz
+
+games:
+    banner: (8.3 (Berkeley) 4/2/94)
+    ddate: Druel the Chaotic aka Jeremy Johnson aka mpython@gnu.ai.mit.edu,
+           with modifications by Lee Harvey Oswald Smith, K.S.C.
+
+login-utils:
+    agetty: W. Z. Venema, ported by Peter Orbaek <poe@daimi.aau.dk>.
+            ftp.daimi.aau.dk:/pub/linux/poe/poeigl-1.32.tar.gz
+    chfn: Salvatore Valente <svalente@athena.mit.edu>
+    chsh: Salvatore Valente <svalente@athena.mit.edu>
+    last: 5.11 w/year (Berkeley) 6/29/88; Port by Michael Haardt with
+          changes by Peter Orbaek.
+          ftp://ftp.daimi.aau.dk/pub/linux/poe/admutil-1.14.tar.gz
+    login: 5.40 (Berkeley) 5/9/89; with ports by Michael Glad and Peter Orbaek
+           ftp.daimi.aau.dk:/pub/linux/poe/poeigl-1.32.tar.gz
+    mesg: Miquel van Smoorenburg (miquels@htsa.aha.nl,
+          miquels@drinkel.nl.mugnet.org).  From his sysvinit.tar.Z package.
+    newgrp: Michael Haardt, with modifications by Peter Orbaek.
+            ftp://ftp.daimi.aau.dk/pub/linux/poe/admutil-1.14.tar.gz
+    passwd: Peter Orbaek, with yp modifications by Alvaro Martinez
+            Echevarria (alvaro@enano.etsit.upm.es)
+            ftp://ftp.daimi.aau.dk/pub/linux/poe/admutil-1.14.tar.gz
+    shutdown: Peter Orbaek, with new modifications by Stephen Tweedie, Rik
+              Faith, and Dave (gentzel@nova.enet.dec.com).
+              ftp://ftp.daimi.aau.dk/pub/linux/poe/admutil-1.14.tar.gz
+    simpleinit: Peter Orbaek
+                ftp.daimi.aau.dk:/pub/linux/poe/poeigl-1.32.tar.gz
+    vipw: 5.16 (Berkeley) 3/3/91, with modifications by Mike Grupenhoff
+          <kashmir@umiacs.UMD.EDU> 
+    wall: 5.14 (Berkeley) 3/2/91 [From the BSD NET-2 (4.3bsd-reno)
+          distribution at wuarchive.wustl.edu:/mirrors/4.3-reno]
+
+makedev-1.4:
+    MAKEDEV-C: David A. Holland (dholland@husc.harvard.edu)
+               This version MODIFIED by Rik Faith (faith@cs.unc.edu)
+               sunsite.unc.edu:/pub/Linux/system/Admin/MAKEDEV-C-1.4.tar.gz
+
+
+misc-utils:
+    cal: 8.4 (Berkeley) 4/2/94, with modifications by Rik Faith and
+         Hein@student.tu-clausthal.de (Jochen Hein).
+         ftp.cdrom.com:/pub/bsd-sources/4.4BSD-Lite/usr/src/usr.bin
+    clear: Rik Faith
+    domainname: Peter Orbaek
+            ftp.daimi.aau.dk:/pub/linux/poe/poeigl-1.32.tar.gz
+    dsplit: David Arnstein (arnstein@netcom.com)
+            gatekeeper.dec.com:/pub/usenet/comp.sources.misc/volume40/dsplit
+    getopt (getoptprog): jhunix.hcf.jhu.edu:
+           /pub/public_domain_software/NetBSD/usr/src/usr.bin/getopt
+    hostid: Mitch DSouza (m.dsouza@mrc-apu.cam.ac.uk)
+            ftp.daimi.aau.dk:/pub/linux/poe/poeigl-1.32.tar.gz
+    hostname/dnsdomainname: Peter Tobias <tobias@server.et-inf.fho-emden.de>
+              This version (1.6) should also be available soon in:
+              nic.funet.fi:/pub/OS/Linux/PEOPLE/Linus/net-source/base/NetKit-A*
+    kill: BSD version, modified by Salvatore Valente <svalente@mit.edu>
+    logger: 8.1 (Berkeley) 6/6/93, with modifications by Rik Faith
+            ftp.cdrom.com:/pub/bsd-sources/4.4BSD-Lite/usr/src/usr.bin
+    look.c: 8.1 (Berkeley) 6/14/93, with modifications by Rik Faith
+            ftp.cdrom.com:/pub/bsd-sources/4.4BSD-Lite/usr/src/usr.bin
+    mcookie: Rik Faith (faith@cs.unc.edu)
+    md5sum: Branki Lankester and Colin Plumb.  The MD5 message-digest
+            algorithm is in the Public Domain.  This implementation
+            calculates message-digest information only, and can NOT be used
+            for encryption.  Therefore it is exportable from the USA.
+            Original sources in the MIT version of PGP 2.6.2.
+    namei: Roger S. Southwick, with modifications by Steve Tell.
+    reset: Rik Faith
+    script: 5.13 (Berkeley) 3/5/91, with modifications by Rick Sladkey
+            (jrs@world.std.com), Harald Koenig
+            (koenig@nova.tat.physik.uni-tuebingen.de).
+    setterm: Gordon Irlam (gordoni@cs.ua.oz.au), with modifications by
+             Peter MacDonald, Mika Liljeberg (liljeber@cs.Helsinki.FI),
+             John Walder (j-walder@uiuc.edu) [for dosemu].
+    tsort: 5.3 (Berkeley) 6/1/90
+           wuarchive.wustl.edu:/mirrors/4.3-reno
+    whereis: 5.5 (Berkeley) 4/18/91
+             wuarchive.wustl.edu:/mirrors/4.3-reno
+    write: 4.22 (Berkeley) 6/1/90, with modifications by Mike Grupenhoff
+           (kashmir@umiacs.umd.edu) .
+           wuarchive.wustl.edu:/mirrors/4.3-reno
+
+mount:
+    mount, umount, swapon
+
+    Rick Sladkey put together the mount-0.99.6.tar.Z package, and Stephen
+    Tweedie provided updates.  The utilities were originally from that
+    package (all appear to be by Doug Quale (quale@saavik.cs.wisc.edu),
+    with modifications by H. J. Lu (hlu@eecs.wsu.edu) on 11/25/92; Rick
+    Sladkey (jrs@world.std.com) in January 1993; and Stephen Tweedie
+    <sct@dcs.ed.ac.uk> on 8 October 1993.  This distribution mount now
+    supports NFS stuff.  I have modified the man pages.  I have also added
+    a small patch from Hamish Glen Coleman (t933093@minyos.xx.rmit.OZ.AU)
+    which restores the -o semantics.
+    
+    Updated with Rick Sladkey's mount-0.99.14.tar.gz package, and with
+    extra patches from Rick.  Adam J. Richter allowed -t option to be
+    optional. Patrick J. Volkerding (volkerdi@mhd1.moorhead.msus.edu) and
+    Mitchum DSouza both provided patches that fixed the (null) problem when
+    not using -t. Mitchum DSouza
+    (mitch@mrc-applied-psychology.cambridge.ac.uk) added support for loop
+    device mounts. Sebastian Lederer
+    (lederer@next-pc.informatik.uni-bonn.de) added support for sending an
+    unmount RPC call to the server when an NFS-filesystem is unmounted.
+    Sander van Malssen (svm@kozmix.hacktic.nl) added support for remounting
+    readonly file systems readonly.  Mike Grupenhoff
+    <kashmir@umiacs.UMD.EDU> added a probe of the superblock for the type
+    before /proc/filesystems is checked.  Andries.Brouwer@cwi.nl fixed up
+    error reporting.
+
+selection:
+    The complete selection-1.5 package, by Andrew Haylett
+    <ajh@gec-mrc.co.uk>, 17th June 1993, is included.  Kernel patches are
+    no longer necessary for modern kernels, but these were tiny so I left
+    them in for historical reasons.  The Makefile was modified for this
+    distribution.  With changes from Rick Sladkey.
+
+sys-utils:
+    MAKEDEV: Nick Holloway <Nick.Holloway@alfie.demon.co.uk>
+    arch: Rik Faith <faith@cs.unc.edu>
+    chroot: Rick Sladkey <jrs@world.std.com>
+    clock: Originally from the timesrc-1.2.tar.Z package, Charles Hedrick,
+           hedrick@cs.rutgers.edu (V1.0); Rob Hooft, hooft@chem.ruu.nl
+           (V1.1); Harald Koenig (koenig@nova.tat.physik.uni-tuebingen.de)
+           (V1.2).  With additional changes: Hamish Coleman
+           (hamish@zot.apana.org.au) (V1.2a); Alan Modra
+           (alan@spri.levels.unisa.edu.au (V1.3, V1.4).
+    ctrlaltdel: Peter Orbaek <poe@daimi.aau.dk>
+                ftp://ftp.daimi.aau.dk/pub/linux/poe/admutil-1.14.tar.gz
+    dmesg: Theodore Ts'o (tytso@athena.mit.edu); Rick Sladkey
+           (jrs@world.std.com)
+    ipcrm: From the ipcdelta.tar.z distribution by krishna
+           balasub@cis.ohio-state.edu on 3/15/93.  ipc.info and ipc.texi
+           are also from that distribution.
+    ipcs: Also from the ipcdelta.tar.z distribution by krishna
+          balasub@cis.ohio-state.edu, with patches from Mike Jagdis
+          (jaggy@purplet.demon.co.uk)
+    kbdrate: Rik Faith (faith@cs.unc.edu), with patches from
+             Andries.Brouwer@cwi.nl and John Bowman
+             (bowman@hagar.ph.utexas.edu)
+    lpcntl: Nigel Gamble (nigel@gate.net)
+    rdev: almesber@nessie.cs.id.ethz.ch (Werner Almesberger), with
+          modifications from Peter MacDonald, Stephen Tweedie
+          (sct@dcs.ed.ac.uk), and Dave (gentzel@nova.enet.dec.com)
+    readprofile: Alessandro Rubini
+    renice: 8.1 (Berkeley) 6/9/93
+            ftp.cdrom.com:/pub/bsd-sources/4.4BSD-Lite/usr/src/usr.bin
+    setserial: Michael K. Johnson (johnsonm@stolaf.edu) re-released Rick
+               Sladkey's setserial in January 1993, with changes by
+               Theodore Ts'o (tytso@mit.edu).  I think that Theodore also
+               did extensive changes for version 2.01, I can't find any
+               notes about this in the documentation. However, Theodore
+               Ts'o (tytso@ATHENA.MIT.EDU) released version 2.10, and that
+               is now included.
+    setsid: Rick Sladkey <jrs@world.std.com>
+    sln: Mike Parker and David MacKenzie (from Linux's libc)
+    sync: Nick Holloway, with thanks to James Bonfield
+    tunelp: Michael K. Johnson (johnsonm@nigel.vnet.net)
+    update_state: Rik Faith (faith@cs.unc.edu)
+
+syslogd:
+   5.45 (Berkeley) 3/2/91
+
+   Most of the changes for syslogd come from Rick Sladkey
+   (jrs@world.std.com), but I'd like to thank other people who sent in
+   changes (which usually got forwarded to Rick): Carsten Paeth
+   (calle@calle.in-berlin.de) and Kaz Sasayama (kaz@lilia.iijnet.or.jp).
+
+text-utils:
+    col: 5.3 (Berkeley) 2/2/91; with patches from Andries.Brouwer@cwi.nl
+         and Carl Christofferson (cchris@connected.com)
+         wuarchive.wustl.edu:/mirrors/4.3-reno/{bin,usr.bin}
+    colcrt: 8.1 (Berkeley) 6/6/93 (Bill Joy)
+            ftp.cdrom.com:/pub/bsd-sources/4.4BSD-Lite/usr/src/usr.bin
+    colrm: 5.4 (Berkeley) 6/1/90 (Jeff Schriebman)
+    column: 8.3 (Berkeley) 4/2/94
+            ftp.cdrom.com:/pub/bsd-sources/4.4BSD-Lite/usr/src/usr.bin
+    hexdump: 5.5 (Berkeley) 6/1/90
+             wuarchive.wustl.edu:/mirrors/4.3-reno/{bin,usr.bin}
+    more: 5.19 (Berkeley) 6/29/88 (Eric Shienbrood, Geoff Peck, John Foderaro)
+    rev: 5.2 (Berkeley) 3/21/92; with modifications by Charles Hannum
+         (mycroft@gnu.ai.mit.edu), Brian Koehmstedt (bpk@gnu.ai.mit.edu),
+         bjdouma@xs4all.nl
+         wuarchive.wustl.edu:/mirrors/4.3-reno/{bin,usr.bin}
+    strings: 5.10 (Berkeley) 5/23/91; with patches from Vitor Duarte
+             <vad@fct.unl.pt>
+             wuarchive.wustl.edu:/mirrors/4.3-reno/{bin,usr.bin}
+    ul: 8.1 (Berkeley) 6/6/93
+        ftp.cdrom.com:/pub/bsd-sources/4.4BSD-Lite/usr/src/usr.bin
+
+time:
+    elsie.nci.nih.gov:/pub/classictzcode.tar.gz
+    elsie.nci.nih.gov:/pub/classictzdata.tar.gz
+    (The zoneinfo database was updated Dec 1994.)
+
+%%
+* bin/arch
+* bin/dmesg
+* bin/dnsdomainname
+* bin/domainname
+* bin/hostname
+* bin/kill
+* bin/login
+* bin/more
+* bin/mount
+* bin/setserial
+* bin/sync
+* bin/umount
+* dev/MAKEDEV
+* dev/MAKEDEV-C
+* etc/DEVINFO
+* etc/MAKEDEV.cfg
+* etc/fdprm
+* sbin/agetty
+* sbin/cfdisk
+* sbin/clock
+* sbin/fastboot
+* sbin/fasthalt
+* sbin/fdisk
+* sbin/fsck.minix
+* sbin/halt
+* sbin/kbdrate
+* sbin/mkfs.minix
+* sbin/mkswap
+* sbin/reboot
+* sbin/shutdown
+* sbin/simpleinit
+* sbin/sln
+* sbin/swapoff
+* sbin/swapon
+* usr/bin/cal
+* usr/bin/chfn
+* usr/bin/chsh
+* usr/bin/clear
+* usr/bin/col
+* usr/bin/colcrt
+* usr/bin/colrm
+* usr/bin/column
+* usr/bin/dsplit
+* usr/bin/fdformat
+* usr/bin/getopt
+* usr/bin/hexdump
+* usr/bin/hostid
+* usr/bin/ipcrm
+* usr/bin/ipcs
+* usr/bin/last
+* usr/bin/logger
+* usr/bin/look
+* usr/bin/lpcntl
+* usr/bin/mcookie
+* usr/bin/md5sum
+* usr/bin/mesg
+* usr/bin/namei
+* usr/bin/newgrp
+* usr/bin/passwd
+* usr/bin/ramsize
+* usr/bin/rdev
+* usr/bin/readprofile
+* usr/bin/renice
+* usr/bin/reset
+* usr/bin/rev
+* usr/bin/rootflags
+* usr/bin/script
+* usr/bin/selection
+* usr/bin/setfdprm
+* usr/bin/setsid
+* usr/bin/setterm
+* usr/bin/strings
+* usr/bin/swapdev
+* usr/bin/tsort
+* usr/bin/tunelp
+* usr/bin/ul
+* usr/bin/vidmode
+* usr/bin/wall
+* usr/bin/whereis
+* usr/bin/write
+* usr/info/ipc.info
+* usr/lib/libz.a
+* usr/lib/more.help
+* usr/lib/zoneinfo
+* usr/man/man1/arch.1
+* usr/man/man1/cal.1
+* usr/man/man1/chfn.1
+* usr/man/man1/chsh.1
+* usr/man/man1/clear.1
+* usr/man/man1/col.1
+* usr/man/man1/colcrt.1
+* usr/man/man1/colrm.1
+* usr/man/man1/column.1
+* usr/man/man1/dnsdomainname.1
+* usr/man/man1/domainname.1
+* usr/man/man1/dsplit.1
+* usr/man/man1/getopt.1
+* usr/man/man1/hexdump.1
+* usr/man/man1/hostid.1
+* usr/man/man1/hostname.1
+* usr/man/man1/kill.1
+* usr/man/man1/last.1
+* usr/man/man1/logger.1
+* usr/man/man1/login.1
+* usr/man/man1/look.1
+* usr/man/man1/md5sum.1
+* usr/man/man1/mesg.1
+* usr/man/man1/more.1
+* usr/man/man1/namei.1
+* usr/man/man1/newgrp.1
+* usr/man/man1/passwd.1
+* usr/man/man1/readprofile.1
+* usr/man/man1/reset.1
+* usr/man/man1/rev.1
+* usr/man/man1/script.1
+* usr/man/man1/selection.1
+* usr/man/man1/setterm.1
+* usr/man/man1/strings.1
+* usr/man/man1/tsort.1
+* usr/man/man1/ul.1
+* usr/man/man1/wall.1
+* usr/man/man1/whereis.1
+* usr/man/man1/write.1
+* usr/man/man3/newctime.3
+* usr/man/man3/newtzset.3
+* usr/man/man5/DEVINFO.5
+* usr/man/man5/MAKEDEV.cfg.5
+* usr/man/man5/fstab.5
+* usr/man/man5/nfs.5
+* usr/man/man5/syslog.conf.5
+* usr/man/man5/tzfile.5
+* usr/man/man6/banner.6
+* usr/man/man6/ddate.6
+* usr/man/man8/MAKEDEV-C.8
+* usr/man/man8/MAKEDEV.8
+* usr/man/man8/agetty.8
+* usr/man/man8/cfdisk.8
+* usr/man/man8/chroot.8
+* usr/man/man8/clock.8
+* usr/man/man8/ctrlaltdel.8
+* usr/man/man8/dmesg.8
+* usr/man/man8/fastboot.8
+* usr/man/man8/fasthalt.8
+* usr/man/man8/fdformat.8
+* usr/man/man8/fdisk.8
+* usr/man/man8/frag.8
+* usr/man/man8/fsck.minix.8
+* usr/man/man8/halt.8
+* usr/man/man8/ipcrm.8
+* usr/man/man8/ipcs.8
+* usr/man/man8/kbdrate.8
+* usr/man/man8/lpcntl.8
+* usr/man/man8/mkfs.minix.8
+* usr/man/man8/mkswap.8
+* usr/man/man8/mount.8
+* usr/man/man8/ramsize.8
+* usr/man/man8/rdev.8
+* usr/man/man8/reboot.8
+* usr/man/man8/renice.8
+* usr/man/man8/rootflags.8
+* usr/man/man8/setfdprm.8
+* usr/man/man8/setserial.8
+* usr/man/man8/setsid.8
+* usr/man/man8/shutdown.8
+* usr/man/man8/simpleinit.8
+* usr/man/man8/swapdev.8
+* usr/man/man8/swapoff.8
+* usr/man/man8/swapon.8
+* usr/man/man8/sync.8
+* usr/man/man8/syslogd.8
+* usr/man/man8/tunelp.8
+* usr/man/man8/umount.8
+* usr/man/man8/update_state.8
+* usr/man/man8/vidmode.8
+* usr/man/man8/vipw.8
+* usr/man/man8/zdump.8
+* usr/man/man8/zic.8
+* usr/sbin/chroot
+* usr/sbin/ctrlaltdel
+* usr/sbin/frag
+* usr/sbin/syslogd
+* usr/sbin/update_state
+* usr/sbin/vipw
+* usr/sbin/zdump
+* usr/sbin/zic
diff --git a/util-linux-2.1.lsm b/util-linux-2.1.lsm
new file mode 100644 (file)
index 0000000..a3c8d51
--- /dev/null
@@ -0,0 +1,23 @@
+Begin3
+Title:          util-linux: Miscellaneous utilities for Linux
+Version:        2.1
+Entered-date:   Thu Feb 16 09:23:18 1995
+Description:    reboot shutdown simpleinit sln swapoff swapon cal chfn chsh
+                clear col colcrt colrm column dnsdomainname domainname
+                dsplit fdformat getopt hexdump hostid hostname ipcrm ipcs
+                last logger look lpcntl mcookie md5sum mesg namei newgrp
+                passwd ramsize rdev readprofile renice reset rev rootflags
+                script selection setfdprm setsid setterm strings swapdev
+                tsort tunelp ul vidmode wall whereis write chroot
+                ctrlaltdel frag syslogd update_state vipw zdump zic
+Keywords:       essential utilities
+Author:         several
+Maintained-by:  faith@cs.unc.edu (Rik Faith)
+Primary-site:   ftp.cs.unc.edu /pub/users/faith/linux
+                640k util-linux-2.1.tar.gz
+                570k util-linux-2.1.bin.tar.gz
+Alternate-site: tsx-11.mit.edu /pub/linux/packages/utils
+Alternate-site: sunsite.unc.edu /pub/Linux/system/Misc
+Platforms:      Linux 1.1.8x, GNU tar
+Copying-policy: GPL, BSD, others
+End
diff --git a/util-linux-2.2.bin.Notes b/util-linux-2.2.bin.Notes
deleted file mode 120000 (symlink)
index 100b938..0000000
+++ /dev/null
@@ -1 +0,0 @@
-README
\ No newline at end of file