summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gnu/usr.bin/man/makewhatis/makewhatis.local.855
-rw-r--r--gnu/usr.bin/man/makewhatis/makewhatis.local.sh35
-rw-r--r--lib/libc/locale/setlocale.c284
-rw-r--r--lib/libc/stdio/asprintf.c59
-rw-r--r--release/floppies/boot/Makefile4
-rw-r--r--release/floppies/boot/crunch/crunch.conf20
-rw-r--r--release/floppies/boot/verbatim/etc/services4
-rw-r--r--release/floppies/doFS.sh120
-rw-r--r--release/floppies/fixit/Makefile6
-rw-r--r--release/floppies/fixit/crunch/crunch.conf45
-rw-r--r--release/floppies/fixit/image/Makefile16
-rw-r--r--release/floppies/fixit/verbatim/.profile15
-rw-r--r--release/floppies/write_mfs_in_kernel.c70
-rw-r--r--share/doc/handbook/linuxemu.sgml700
-rw-r--r--share/man/man4/update.482
-rw-r--r--share/man/man5/hosts.lpd.553
-rw-r--r--usr.bin/sgmls/sgmls/alloc.h8
-rw-r--r--usr.bin/sgmls/sgmls/catalog.c925
-rw-r--r--usr.bin/sgmls/sgmls/catalog.h45
19 files changed, 2546 insertions, 0 deletions
diff --git a/gnu/usr.bin/man/makewhatis/makewhatis.local.8 b/gnu/usr.bin/man/makewhatis/makewhatis.local.8
new file mode 100644
index 000000000000..acf52121f07c
--- /dev/null
+++ b/gnu/usr.bin/man/makewhatis/makewhatis.local.8
@@ -0,0 +1,55 @@
+.\" (c) Wolfram Schneider, Berlin. April 1996. Public Domain.
+.\"
+.\" $Id: makewhatis.local.8,v 1.1 1996/05/14 10:27:26 wosch Exp $
+
+.Dd April, 26, 1996
+.Dt MAKEWHATIS.LOCAL 8
+.Os FreeBSD 2.2
+
+.Sh NAME
+.Nm makewhatis.local , catman.local
+.Nd start makewhatis for local file systems
+
+.Sh SYNOPSIS
+.Nm /usr/libexec/makewhatis.local
+.Op options
+.Ar directories ...
+.Nm /usr/libexec/catman.local
+.Op options
+.Ar directories ...
+
+
+.Sh DESCRIPTION
+.Nm
+start
+.Xr makewhatis 1
+only for file systems physically mounted on the system
+where the
+.Nm
+is being executed. Running makewhatis
+from
+.Pa /etc/weekly
+for rw nfs-mounted /usr may kill
+your NFS server -- all NFS clients start makewhatis at the same time!
+So use this wrapper for
+.Xr cron 8
+instead calling makewhatis directly.
+
+.Sh FILES
+.Bl -tag -width /etc/weekly.XXX -compact
+.It Pa /etc/weekly
+run
+.Nm
+every week
+.El
+
+.Sh SEE ALSO
+.Xr makewhatis 1 ,
+.Xr catman 1 ,
+.Xr find 1 ,
+.Xr cron 8 .
+
+.Sh HISTORY
+The
+.Nm
+command appeared in FreeBSD 2.2.
diff --git a/gnu/usr.bin/man/makewhatis/makewhatis.local.sh b/gnu/usr.bin/man/makewhatis/makewhatis.local.sh
new file mode 100644
index 000000000000..d566920cdd83
--- /dev/null
+++ b/gnu/usr.bin/man/makewhatis/makewhatis.local.sh
@@ -0,0 +1,35 @@
+#!/bin/sh
+# (c) Wolfram Schneider, Berlin. April 1996. Public Domain.
+#
+# makewhatis.local - start makewhatis(1) only for file systems
+# physically mounted on the system
+#
+# Running makewhatis from /etc/weekly for rw nfs-mounted /usr may kill
+# your NFS server -- all clients start makewhatis at the same time!
+# So use this wrapper instead calling makewhatis directly.
+#
+# PS: this wrapper works also for catman(1)
+#
+# $Id: makewhatis.local.sh,v 1.1 1996/05/14 10:27:27 wosch Exp $
+
+PATH=/bin:/usr/bin:$PATH; export PATH
+opt= dirs= localdirs=
+
+for arg
+do
+ case "$arg" in
+ -*) opt="$opt $arg";;
+ *) dirs="$dirs $arg";;
+ esac
+done
+
+dirs=`echo $dirs | sed 's/:/ /g'`
+case X"$dirs" in X) echo "usage: $0 [options] directories ..."; exit 1;; esac
+
+localdirs=`find -H $dirs -fstype local -type d -prune -print`
+
+case X"$localdirs" in
+ X) echo "$0: no local-mounted manual directories found: $dirs"
+ exit 1;;
+ *) exec `basename $0 .local` $opt $localdirs;;
+esac
diff --git a/lib/libc/locale/setlocale.c b/lib/libc/locale/setlocale.c
new file mode 100644
index 000000000000..11f21398e76f
--- /dev/null
+++ b/lib/libc/locale/setlocale.c
@@ -0,0 +1,284 @@
+/*
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Paul Borman at Krystal Technologies.
+ *
+ * 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.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)setlocale.c 8.1 (Berkeley) 7/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <limits.h>
+#include <locale.h>
+#include <rune.h>
+#include <stdlib.h>
+#include <string.h>
+#include "collate.h"
+
+/*
+ * Category names for getenv()
+ */
+static char *categories[_LC_LAST] = {
+ "LC_ALL",
+ "LC_COLLATE",
+ "LC_CTYPE",
+ "LC_MONETARY",
+ "LC_NUMERIC",
+ "LC_TIME",
+};
+
+/*
+ * Current locales for each category
+ */
+static char current_categories[_LC_LAST][32] = {
+ "C",
+ "C",
+ "C",
+ "C",
+ "C",
+ "C",
+};
+
+/*
+ * The locales we are going to try and load
+ */
+static char new_categories[_LC_LAST][32];
+
+static char current_locale_string[_LC_LAST * 33];
+char *_PathLocale;
+
+static char *currentlocale __P((void));
+static char *loadlocale __P((int));
+
+extern int __time_load_locale __P((const char *)); /* strftime.c */
+
+#ifdef XPG4
+extern int _xpg4_setrunelocale __P((char *));
+#endif
+
+char *
+setlocale(category, locale)
+ int category;
+ const char *locale;
+{
+ int found, i, len;
+ char *env, *r;
+
+ if (!_PathLocale && !(_PathLocale = getenv("PATH_LOCALE")))
+ _PathLocale = _PATH_LOCALE;
+
+ if (category < 0 || category >= _LC_LAST)
+ return (NULL);
+
+ if (!locale)
+ return (category ?
+ current_categories[category] : currentlocale());
+
+ /*
+ * Default to the current locale for everything.
+ */
+ for (i = 1; i < _LC_LAST; ++i)
+ (void)strcpy(new_categories[i], current_categories[i]);
+
+ /*
+ * Now go fill up new_categories from the locale argument
+ */
+ if (!*locale) {
+ env = getenv(categories[category]);
+
+ if (!env)
+ env = getenv(categories[0]);
+
+ if (!env)
+ env = getenv("LANG");
+
+ if (!env)
+ env = "C";
+
+ (void) strncpy(new_categories[category], env, 31);
+ new_categories[category][31] = 0;
+ if (!category) {
+ for (i = 1; i < _LC_LAST; ++i) {
+ if (!(env = getenv(categories[i])))
+ env = new_categories[0];
+ (void)strncpy(new_categories[i], env, 31);
+ new_categories[i][31] = 0;
+ }
+ }
+ } else if (category) {
+ (void)strncpy(new_categories[category], locale, 31);
+ new_categories[category][31] = 0;
+ } else {
+ if ((r = strchr(locale, '/')) == 0) {
+ for (i = 1; i < _LC_LAST; ++i) {
+ (void)strncpy(new_categories[i], locale, 31);
+ new_categories[i][31] = 0;
+ }
+ } else {
+ for (i = 1; r[1] == '/'; ++r);
+ if (!r[1])
+ return (NULL); /* Hmm, just slashes... */
+ do {
+ len = r - locale > 31 ? 31 : r - locale;
+ (void)strncpy(new_categories[i++], locale, len);
+ new_categories[i++][len] = 0;
+ locale = r;
+ while (*locale == '/')
+ ++locale;
+ while (*++r && *r != '/');
+ } while (*locale);
+ while (i < _LC_LAST)
+ (void)strcpy(new_categories[i],
+ new_categories[i-1]);
+ }
+ }
+
+ if (category)
+ return (loadlocale(category));
+
+ found = 0;
+ for (i = 1; i < _LC_LAST; ++i)
+ if (loadlocale(i) != NULL)
+ found = 1;
+ if (found)
+ return (currentlocale());
+ return (NULL);
+}
+
+/* To be compatible with crt0 hack */
+void
+_startup_setlocale(category, locale)
+ int category;
+ const char *locale;
+{
+#ifndef XPG4
+ (void) setlocale(category, locale);
+#endif
+}
+
+static char *
+currentlocale()
+{
+ int i, len;
+
+ (void)strcpy(current_locale_string, current_categories[1]);
+
+ for (i = 2; i < _LC_LAST; ++i)
+ if (strcmp(current_categories[1], current_categories[i])) {
+ len = strlen(current_categories[1]) + 1 +
+ strlen(current_categories[2]) + 1 +
+ strlen(current_categories[3]) + 1 +
+ strlen(current_categories[4]) + 1 +
+ strlen(current_categories[5]) + 1;
+ if (len > sizeof(current_locale_string))
+ return NULL;
+ (void) strcpy(current_locale_string, current_categories[1]);
+ (void) strcat(current_locale_string, "/");
+ (void) strcat(current_locale_string, current_categories[2]);
+ (void) strcat(current_locale_string, "/");
+ (void) strcat(current_locale_string, current_categories[3]);
+ (void) strcat(current_locale_string, "/");
+ (void) strcat(current_locale_string, current_categories[4]);
+ (void) strcat(current_locale_string, "/");
+ (void) strcat(current_locale_string, current_categories[5]);
+ break;
+ }
+ return (current_locale_string);
+}
+
+static char *
+loadlocale(category)
+ int category;
+{
+#if 0
+ char name[PATH_MAX];
+#endif
+ if (strcmp(new_categories[category],
+ current_categories[category]) == 0)
+ return (current_categories[category]);
+
+ if (category == LC_CTYPE) {
+#ifdef XPG4
+ if (_xpg4_setrunelocale(new_categories[LC_CTYPE]))
+#else
+ if (setrunelocale(new_categories[LC_CTYPE]))
+#endif
+ return (NULL);
+ (void)strcpy(current_categories[LC_CTYPE],
+ new_categories[LC_CTYPE]);
+ return (current_categories[LC_CTYPE]);
+ }
+
+ if (category == LC_COLLATE) {
+ if (__collate_load_tables(new_categories[LC_COLLATE]) < 0)
+ return (NULL);
+ (void)strcpy(current_categories[LC_COLLATE],
+ new_categories[LC_COLLATE]);
+ return (current_categories[LC_COLLATE]);
+ }
+
+ if (category == LC_TIME) {
+ if (__time_load_locale(new_categories[LC_TIME]) < 0)
+ return (NULL);
+ (void)strcpy(current_categories[LC_TIME],
+ new_categories[LC_TIME]);
+ return (current_categories[LC_TIME]);
+ }
+
+ if (!strcmp(new_categories[category], "C") ||
+ !strcmp(new_categories[category], "POSIX")) {
+
+ /*
+ * Some day this will need to reset the locale to the default
+ * C locale. Since we have no way to change them as of yet,
+ * there is no need to reset them.
+ */
+ (void)strcpy(current_categories[category],
+ new_categories[category]);
+ return (current_categories[category]);
+ }
+#if 0
+ /*
+ * Some day we will actually look at this file.
+ */
+ (void)snprintf(name, sizeof(name), "%s/%s/%s",
+ _PathLocale, new_categories[category], categories[category]);
+#endif
+ switch (category) {
+ case LC_MONETARY:
+ case LC_NUMERIC:
+ return (NULL);
+ }
+ /* Just in case...*/
+ return (NULL);
+}
diff --git a/lib/libc/stdio/asprintf.c b/lib/libc/stdio/asprintf.c
new file mode 100644
index 000000000000..9b4d05b4397b
--- /dev/null
+++ b/lib/libc/stdio/asprintf.c
@@ -0,0 +1,59 @@
+/*-
+ * Copyright (c) 1996 Peter Wemm <peter@freebsd.org>
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ */
+
+#if defined(LIBC_RCS) && !defined(lint)
+static char rcsid[] = "$Id$";
+#endif /* LIBC_RCS and not lint */
+
+#include <stdio.h>
+#if __STDC__
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+
+#if __STDC__
+int
+asprintf(char **str, char const *fmt, ...)
+#else
+int
+asprintf(str, fmt, va_alist)
+ char **str;
+ char *fmt;
+ va_dcl
+#endif
+{
+ int ret;
+ va_list ap;
+
+#if __STDC__
+ va_start(ap, fmt);
+#else
+ va_start(ap);
+#endif
+ ret = vasprintf(str, fmt, ap);
+ va_end(ap);
+ return (ret);
+}
diff --git a/release/floppies/boot/Makefile b/release/floppies/boot/Makefile
new file mode 100644
index 000000000000..2dd894d898d9
--- /dev/null
+++ b/release/floppies/boot/Makefile
@@ -0,0 +1,4 @@
+# $Id: Makefile,v 1.214 1996/05/02 08:18:28 jkh Exp $
+SUBDIR= crunch mfs floppy
+
+.include <bsd.subdir.mk>
diff --git a/release/floppies/boot/crunch/crunch.conf b/release/floppies/boot/crunch/crunch.conf
new file mode 100644
index 000000000000..b9d6f14b65f7
--- /dev/null
+++ b/release/floppies/boot/crunch/crunch.conf
@@ -0,0 +1,20 @@
+# $Id: boot_crunch.conf,v 1.23 1996/02/08 18:02:51 phk Exp $
+
+srcdirs /usr/src/bin
+srcdirs /usr/src/release
+srcdirs /usr/src/sbin/i386
+srcdirs /usr/src/sbin
+srcdirs /usr/src/usr.bin
+srcdirs /usr/src/gnu/usr.bin
+srcdirs /usr/src/usr.sbin
+
+progs sh find
+progs pwd ft ppp
+progs sysinstall newfs gzip cpio bad144 fsck ifconfig route slattach
+progs mount_nfs
+ln gzip gunzip
+ln gzip zcat
+ln sh -sh
+
+libs -ll -ledit -lutil -lkvm -lmd
+libs -ldialog -lncurses -lmytinfo -L/usr/src/release/libdisk/obj -ldisk -lipx
diff --git a/release/floppies/boot/verbatim/etc/services b/release/floppies/boot/verbatim/etc/services
new file mode 100644
index 000000000000..bd1beff4d9a7
--- /dev/null
+++ b/release/floppies/boot/verbatim/etc/services
@@ -0,0 +1,4 @@
+nameserver 42/tcp name
+ftp 21/tcp
+domain 53/tcp nameserver
+domain 53/udp nameserver
diff --git a/release/floppies/doFS.sh b/release/floppies/doFS.sh
new file mode 100644
index 000000000000..16932269363f
--- /dev/null
+++ b/release/floppies/doFS.sh
@@ -0,0 +1,120 @@
+:
+#set -ex
+
+VNDEVICE=vn0
+export BLOCKSIZE=512
+
+LABELDIR=$1 ; shift
+MNT=$1 ; shift
+FSSIZE=$1 ; shift
+FSPROTO=$1 ; shift
+FSINODE=$1 ; shift
+FSLABEL=$1 ; shift
+OLDFSSIZE=${FSSIZE}
+OLDFSINODE=${FSINODE}
+
+deadlock=40
+
+while true
+do
+ rm -f fs-image
+
+ if [ ! -b /dev/${VNDEVICE} -o ! -c /dev/r${VNDEVICE} ] ; then
+ ( cd /dev && sh MAKEDEV ${VNDEVICE} )
+ fi
+
+ umount /dev/${VNDEVICE} 2>/dev/null || true
+
+ umount ${MNT} 2>/dev/null || true
+
+ vnconfig -u /dev/r${VNDEVICE} 2>/dev/null || true
+
+ dd of=fs-image if=/dev/zero count=${FSSIZE} bs=1k 2>/dev/null
+ # this suppresses the `invalid primary partition table: no magic'
+ awk 'BEGIN {printf "%c%c", 85, 170}' |\
+ dd of=fs-image obs=1 seek=510 conv=notrunc 2>/dev/null
+
+ vnconfig -s labels -c /dev/r${VNDEVICE} fs-image
+
+ sed '/^minimum:/,$d' /etc/disktab > /etc/disktab.tmp
+ cat /etc/disktab.tmp > /etc/disktab
+ rm -f /etc/disktab.tmp
+ (
+ a=`expr ${FSSIZE} \* 2`
+ echo
+ echo "minimum:ty=mfs:se#512:nt#1:rm#300:\\"
+ echo " :ns#$a:nc#1:\\"
+ echo " :pa#$a:oa#0:ba#4096:fa#512:\\"
+ echo " :pc#$a:oc#0:bc#4096:fc#512:"
+ echo
+ ) >> /etc/disktab
+
+ disklabel -w -r -B \
+ -b ${LABELDIR}/boot1 \
+ -s ${LABELDIR}/boot2 \
+ /dev/r${VNDEVICE} minimum
+
+ newfs -u 0 -t 0 -i ${FSINODE} -m 0 -T minimum /dev/r${VNDEVICE}a
+
+ mount /dev/${VNDEVICE}a ${MNT}
+
+ if ( set -e && cd ${FSPROTO} && find . -print | cpio -dump ${MNT} )
+ then
+ ;
+ else
+ echo " $FSINODE and $FSSIZE failed, reverting.."
+ FSSIZE=`expr ${FSSIZE} + 10`
+ #FSSIZE=${OLDFSSIZE}
+ FSINODE=${FSINODE}
+ continue
+ fi
+
+ set `df -i /mnt | tail -1`
+#/dev/vn0a 937 932 5 99% 342 328 51% /mnt
+
+ umount ${MNT}
+
+ fsck -p /dev/r${VNDEVICE}a < /dev/null
+
+ vnconfig -u /dev/r${VNDEVICE} 2>/dev/null || true
+
+ if [ $FSLABEL != "minimum" ] ; then
+ echo ${FSSIZE} > fs-image.size
+ break
+ fi
+
+ OLDFSSIZE=${FSSIZE}
+ OLDFSINODE=${FSINODE}
+ echo ">>> Filesystem is ${FSSIZE} K, $4 left"
+ echo ">>> ${FSINODE} bytes/inode, $7 left"
+ echo ">>> `expr ${FSSIZE} \* 1024 / ${FSINODE}`"
+ if [ $4 -gt 128 ] ; then
+ echo "Reducing size"
+ FSSIZE=`expr ${FSSIZE} - $4 / 2`
+ continue
+ fi
+ if [ $7 -gt 128 ] ; then
+ echo "Increasing bytes per inode"
+ FSINODE=`expr ${FSINODE} + 8192`
+ continue
+ fi
+ if [ $4 -gt 32 ] ; then
+ echo "Reducing size"
+ FSSIZE=`expr ${FSSIZE} - 4`
+ FSINODE=`expr ${FSINODE} - 1024`
+ continue
+ fi
+ if [ $7 -gt 64 ] ; then
+ echo "Increasing bytes per inode"
+ FSINODE=`expr ${FSINODE} + 8192`
+ continue
+ fi
+ if [ $deadlock -eq 0 ] ; then
+ echo "Avoiding deadlock, giving up"
+ echo ${FSSIZE} > fs-image.size
+ break
+ fi
+ deadlock=`expr $deadlock - 1`
+ echo ${FSSIZE} > fs-image.size
+ break;
+done
diff --git a/release/floppies/fixit/Makefile b/release/floppies/fixit/Makefile
new file mode 100644
index 000000000000..ee278f76ab4c
--- /dev/null
+++ b/release/floppies/fixit/Makefile
@@ -0,0 +1,6 @@
+###
+# $Id: Makefile,v 1.214 1996/05/02 08:18:28 jkh Exp $
+#
+SUBDIR= crunch image
+
+.include <bsd.subdir.mk>
diff --git a/release/floppies/fixit/crunch/crunch.conf b/release/floppies/fixit/crunch/crunch.conf
new file mode 100644
index 000000000000..f31652ea1e87
--- /dev/null
+++ b/release/floppies/fixit/crunch/crunch.conf
@@ -0,0 +1,45 @@
+# $Id: fixit_crunch.conf,v 1.6 1996/01/03 23:41:03 joerg Exp $
+
+# first, we list the source dirs that our programs reside in. These are
+# searched in order listed to find the dir containing each program.
+
+srcdirs /usr/src/bin
+srcdirs /usr/src/sbin/i386
+srcdirs /usr/src/sbin
+srcdirs /usr/src/gnu/usr.bin
+srcdirs /usr/src/usr.bin
+srcdirs /usr/src/usr.sbin
+srcdirs /usr/src/usr.bin/vi
+
+# second, we list all the programs we want to include in our crunched binary.
+# The order doesn't matter. Any program that needs hard links to it gets an
+# `ln' directive.
+
+# /bin stuff
+
+progs cat chmod chroot cp date dd df echo ed expr hostname kill ln ls mkdir
+progs mt mv pwd rcp rm rmdir sleep stty sync test
+
+ln test [
+
+# /sbin stuff
+
+progs badsect chown clri disklabel dump dmesg fdisk
+progs mknod mount newfs ping reboot restore scsi swapon umount
+
+progs mount_msdos mount_cd9660 mount_nfs
+ln dump rdump
+ln restore rrestore
+ln newfs mount_mfs
+
+# /usr/bin stuff
+
+progs ftp rsh sed telnet rlogin common find grep
+ln common vi
+ln common view
+ln common ex
+
+# finally, we specify the libraries to link in with our binary
+
+libs -lcrypt -ltelnet -lutil -ll
+libs -lcurses -ltermcap -ledit -lgnuregex -lkvm -lscsi
diff --git a/release/floppies/fixit/image/Makefile b/release/floppies/fixit/image/Makefile
new file mode 100644
index 000000000000..a8a80c4403be
--- /dev/null
+++ b/release/floppies/fixit/image/Makefile
@@ -0,0 +1,16 @@
+###
+# $Id: Makefile,v 1.214 1996/05/02 08:18:28 jkh Exp $
+#
+# What are we if we weren't told..
+CRUNCH?= fixit
+CRUNCHDIRS= ../crunch
+TOP=${.CURDIR}/../../../..
+FS_BIN=${.CURDIR}/../..
+
+# the directories you want on the fs
+FS_DIRS= dev stand bin sbin etc mnt mnt1 mnt2 mnt3 mnt4 tmp
+# a subdir that contains a verbatim image to be copied to the fs
+VERBATIM= ../verbatim
+
+.include "../../crunch_fs.mk"
+all: fs_image
diff --git a/release/floppies/fixit/verbatim/.profile b/release/floppies/fixit/verbatim/.profile
new file mode 100644
index 000000000000..f5664e8d6eb8
--- /dev/null
+++ b/release/floppies/fixit/verbatim/.profile
@@ -0,0 +1,15 @@
+:
+# $Id: fixit.profile,v 1.1 1995/03/15 06:14:19 phk Exp $
+PATH=/stand
+BLOCKSIZE=K
+PS1="Fixit# "
+
+echo '+---------------------------------------------------+'
+echo '| You are now running from a FreeBSD "fixit" floppy |'
+echo '+---------------------------------------------------+'
+echo
+echo 'Good Luck!'
+echo
+
+export PATH BLOCKSIZE PS1
+
diff --git a/release/floppies/write_mfs_in_kernel.c b/release/floppies/write_mfs_in_kernel.c
new file mode 100644
index 000000000000..886bdd234dd8
--- /dev/null
+++ b/release/floppies/write_mfs_in_kernel.c
@@ -0,0 +1,70 @@
+/*
+ * ----------------------------------------------------------------------------
+ * "THE BEER-WARE LICENSE" (Revision 42):
+ * <phk@login.dknet.dk> wrote this file. As long as you retain this notice you
+ * can do whatever you want with this stuff. If we meet some day, and you think
+ * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
+ * ----------------------------------------------------------------------------
+ *
+ * $Id: write_mfs_in_kernel.c,v 1.1 1995/04/25 03:45:18 phk Exp $
+ *
+ * This program patches a filesystem into a kernel made with MFS_ROOT
+ * option.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/stat.h>
+#include <ufs/ffs/fs.h>
+
+main(int argc, char **argv)
+{
+ unsigned char *buf_kernel, *buf_fs, *p,*q;
+ int fd_kernel, fd_fs;
+ struct stat st_kernel, st_fs;
+ u_long l;
+
+ if (argc < 3) {
+ fprintf(stderr,"Usage:\n\t%s kernel fs\n");
+ exit(2);
+ }
+ fd_kernel = open(argv[1],O_RDWR);
+ if (fd_kernel < 0) { perror(argv[1]); exit(2); }
+ fstat(fd_kernel,&st_kernel);
+ fd_fs = open(argv[2],O_RDONLY);
+ if (fd_fs < 0) { perror(argv[2]); exit(2); }
+ fstat(fd_fs,&st_fs);
+ buf_kernel = malloc(st_kernel.st_size);
+ if (!buf_kernel) { perror("malloc"); exit(2); }
+ buf_fs = malloc(st_fs.st_size);
+ if (!buf_fs) { perror("malloc"); exit(2); }
+ if (st_kernel.st_size != read(fd_kernel,buf_kernel,st_kernel.st_size))
+ { perror(argv[1]); exit(2); }
+ if (st_fs.st_size != read(fd_fs,buf_fs,st_fs.st_size))
+ { perror(argv[2]); exit(2); }
+ for(l=0,p=buf_kernel; l < st_kernel.st_size - st_fs.st_size ; l++,p++ )
+ if(*p == 'M' && !strcmp(p,"MFS Filesystem goes here"))
+ goto found;
+ fprintf(stderr,"MFS filesystem signature not found in %s\n",argv[1]);
+ exit(1);
+ found:
+ for(l=0,q= p + SBOFF; l < st_fs.st_size - SBOFF ; l++,q++ )
+ if (*q)
+ goto fail;
+ memcpy(p+SBOFF,buf_fs+SBOFF,st_fs.st_size-SBOFF);
+ lseek(fd_kernel,0L,SEEK_SET);
+ if (st_kernel.st_size != write(fd_kernel,buf_kernel,st_kernel.st_size))
+ { perror(argv[1]); exit(2); }
+ exit(0);
+ fail:
+ l += SBOFF;
+ fprintf(stderr,"Obstruction in kernel after %ld bytes (%ld Kbyte)\n",
+ l, l/1024);
+ fprintf(stderr,"Filesystem is %ld bytes (%ld Kbyte)\n",
+ (u_long)st_fs.st_size, (u_long)st_fs.st_size/1024);
+ exit(1);
+}
diff --git a/share/doc/handbook/linuxemu.sgml b/share/doc/handbook/linuxemu.sgml
new file mode 100644
index 000000000000..5652380596fd
--- /dev/null
+++ b/share/doc/handbook/linuxemu.sgml
@@ -0,0 +1,700 @@
+<!-- $Id: linuxemu.sgml,v 1.7 1996/05/21 04:06:00 jkh Exp $ -->
+<!-- The FreeBSD Documentation Project -->
+
+<chapt><heading>Linux Emulation<label id="linuxemu"></heading>
+
+<p><em>Contributed by &a.brian and &a.rich;</em>
+
+<sect><heading>How to install the Linux emulator</heading>
+
+<p>Linux emulation in FreeBSD has reached a point where it is possible
+to run a large fraction of Linux binaries in both a.out and ELF
+format. The linux emulation in the -STABLE branch is capable of
+running Linux DOOM and Mathematica; the version present in
+FreeBSD-CURRENT is vastly more capable and runs all these as well as
+Quake, Abuse, IDL, netrek for Linux and a whole host of other
+programs.
+
+There are some Linux-specific operating system features that are not
+supported on FreeBSD. Linux binaries will not work on FreeBSD if they
+use the Linux /proc filesystem (which is different from the optional
+FreeBSD /proc filesystem) or i386-specific calls, such as enabling
+virtual 8086 mode.
+
+<p>To tell whether your kernel is configured for Linux
+compatibility simply run any Linux binary. If it
+prints the error message
+<tscreen>
+<verb>
+linux-executable: Exec format error. Wrong Architecture.
+</verb>
+</tscreen>
+then you do not have linux compatibility support and
+you need to configure and install a new kernel.
+
+Depending on which version of FreeBSD you are running, how you get
+Linux-emulation up will vary slightly:
+
+<sect1><heading>Installing Linux Emulation in 2.1-STABLE</heading>
+
+<p>The GENERIC kernel in 2.1-stable is not configured for linux
+compatibility so you you must reconfigure your kernel for it. There
+are two ways to do this: 1. linking the emulator statically in the
+kernel itself and 2. configuring your kernel to dynamically load the
+linux loadable kernel module (LKM).
+
+<p>To enable the emulator, add the following to your configuration file
+(c.f. /sys/i386/conf/LINT):
+<tscreen>
+<verb>
+options "COMPAT_LINUX"
+</verb>
+</tscreen>
+If you want to run doom or other applications
+that need shared memory
+also add the following.
+<tscreen>
+<verb>
+options SYSVSHM
+</verb>
+</tscreen>
+The linux system calls require 4.3 BSD system call compatibility. So
+make sure you have the following.
+<tscreen>
+<verb>
+options "COMPAT_43"
+</verb>
+</tscreen>
+
+If you prefer to statically link the emulator in the kernel rather than
+use the loadable kernel module (LKM), then add
+<tscreen>
+<verb>
+options LINUX
+</verb>
+</tscreen>
+Then run config and install the new kernel as described in the
+<ref id="kernelconfig" name="kernel configuration"> section.
+
+If you decide to use the LKM you must also install the loadable
+module. A mismatch of versions between the kernel and loadable
+module can cause the kernel to crash, so the safest thing to do is to
+reinstall the LKM when you install the kernel.
+<tscreen>
+<verb>
+% cd /usr/src/lkm/linux
+% make all install
+</verb>
+</tscreen>
+Once you have installed the kernel and the LKM, you can invoke
+`linux' as root to load the LKM.
+<tscreen>
+<verb>
+% linux
+Linux emulator installed
+Module loaded as ID 0
+%
+</verb>
+</tscreen>
+To see whether the LKM is loaded, run `modstat'.
+<tscreen>
+<verb>
+% modstat
+Type Id Off Loadaddr Size Info Rev Module Name
+EXEC 0 3 f0baf000 0018 f0bb4000 1 linux_emulator
+%
+</verb>
+</tscreen>
+You can cause the LKM to be loaded when the system boots in either of
+two ways. On FreeBSD-CURRENT and FreeBSD-STABLE enable it in
+/etc/sysconfig
+<tscreen>
+<verb>
+linux=YES
+</verb>
+</tscreen>
+by changing it from NO to YES. FreeBSD 2.1 RELEASE and earlier do not
+have such a line and on those you will need to edit /etc/rc.local to
+add the following line.
+<tscreen>
+<verb>
+linux
+</verb>
+</tscreen>
+
+<sect1><heading>Installing Linux Emulation in 2.2-CURRENT</heading>
+
+<p>In -current it is no longer necessary to specify options "LINUX"
+or options "COMPAT_LINUX". Linux emulation is done with an LKM
+(``Loadable Kernel Module'') so it can be installed on the fly without
+having to reboot. You will need the following things in your startup files,
+however:
+<enum>
+<item> In /etc/sysconfig, you need the following line:
+<tscreen>
+<verb>
+linux=YES
+</verb>
+</tscreen>
+<item> This, in turn, triggers the following action in /etc/rc.i386:
+<tscreen>
+<verb>
+# Start the Linux binary emulation if requested.
+if [ "X${linux}" = X"YES" ]; then
+ echo -n ' '; linux
+ # XXX BOGUS - Linux script shouldn't make any output on success
+fi
+</verb>
+</tscreen>
+</enum>
+
+<p>If you want to verify it is running, modstat will do that:
+<tscreen>
+<verb>
+% modstat
+Type Id Off Loadaddr Size Info Rev Module Name
+EXEC 0 4 f09e6000 001c f09ec010 1 linux_mod
+%
+</verb>
+</tscreen>
+However, there have been reports that this fails on some
+FreeBSD-current systems. If for some reason you cannot load the linux
+LKM, then statically link the emulator in the kernel by adding
+<tscreen>
+<verb>
+options LINUX
+</verb>
+</tscreen>
+to your kernel config file. Then run config and install the new
+kernel as described in the <ref id="kernelconfig" name="kernel
+configuration"> section.
+
+<sect1><heading>Installing Linux Runtime Libraries</heading>
+
+<sect2><heading>Installing using the linux_lib port</heading>
+
+<p>Most linux applications use shared libraries, so you are still not
+done until you install the shared libraries. It is possible to do
+this by hand, however, it is vastly simpler to just grab the
+linux_lib port:
+<tscreen>
+<verb>
+% cd /usr/ports-current/emulators/linux_lib
+% make all install
+</verb>
+</tscreen>
+
+and you should have a working linux emulator. Legend (and the mail
+archives :-) seems to hold that Linux emulation works best with
+linux binaries linked against the ZMAGIC libraries; QMAGIC libraries
+(such as those used in Slackware V2.0) may tend to give the
+Linuxulator heartburn. As of this writing (March 1996) ELF emulation
+is still in the formulative stages but seems to work pretty well. Also,
+expect some programs to complain about incorrect minor versions. In
+general this does not seem to be a problem.
+
+<sect2><heading>Installing libraries manually</heading>
+
+<p>If you don't have the ``ports'' distribution, you can install the
+libraries by hand instead. You will need the Linux shared libraries
+that the program depends on and the runtime linker. Also, you will
+need to create a "shadow root" directory, /compat/linux, for Linux
+libraries on your FreeBSD system. Any shared libraries opened by
+Linux programs run under FreeBSD will look in this tree first. So, if
+a Linux program loads, for example, /lib/libc.so, FreeBSD will first
+try to open /compat/linux/lib/libc.so, and if that does not exist then
+it will try /lib/libc.so. Shared libraries should be installed in the
+shadow tree /compat/linux/lib rather than the paths that the Linux
+ld.so reports.
+
+
+FreeBSD-current works slightly differently with respect to
+/compat/linux. On -current, all files, not just libraries, are
+searched for from the ``shadow root'' /compat/linux.
+
+Generally, you will need to look for the shared libraries that Linux
+binaries depend on only the first few times that you install a Linux
+program on your FreeBSD system. After a while, you will have a sufficient
+set of Linux shared libraries on your system to be able to run newly
+imported Linux binaries without any extra work.
+
+<sect2><heading>How to install additional shared libraries</heading>
+
+<p>What if you install the linux_lib port and your application still
+complains about missing shared libraries? How do you know which
+shared libraries Linux binaries need, and where to get them?
+Basically, there are 2 possibilities (when following these
+instructions: you will need to be root on your FreeBSD system to do
+the necessary installation steps).
+
+<p>If you have access to a Linux system, see what shared libraries
+it needs, and copy them to your FreeBSD system. Example: you have
+just ftp'ed the Linux binary of Doom. Put it on the Linux
+system you have access to, and check which shared libraries it
+needs by running `ldd linuxxdoom':
+
+<tscreen>
+<verb>
+% ldd linuxxdoom
+libXt.so.3 (DLL Jump 3.1) => /usr/X11/lib/libXt.so.3.1.0
+libX11.so.3 (DLL Jump 3.1) => /usr/X11/lib/libX11.so.3.1.0
+libc.so.4 (DLL Jump 4.5pl26) => /lib/libc.so.4.6.29
+</verb>
+</tscreen>
+
+<p>You would need go get all the files from the last column, and
+put them under /compat/linux, with the names in the first column
+as symbolic links pointing to them. This means you eventually have
+these files on your FreeBSD system:
+<tscreen>
+<verb>
+/compat/linux/usr/X11/lib/libXt.so.3.1.0
+/compat/linux/usr/X11/lib/libXt.so.3 -> libXt.so.3.1.0
+/compat/linux/usr/X11/lib/libX11.so.3.1.0
+/compat/linux/usr/X11/lib/libX11.so.3 -> libX11.so.3.1.0
+/compat/linux/lib/libc.so.4.6.29
+/compat/linux/lib/libc.so.4 -> libc.so.4.6.29
+</verb>
+</tscreen>
+
+<p>Note that if you already have a Linux shared library with a
+matching major revision number to the first column of the 'ldd'
+output, you will not need to copy the file named in the last column to
+your system, the one you already have should work. It is advisable to
+copy the shared library anyway if it is a newer version, though. You
+can remove the old one, as long as you make the symbolic link point to
+the new one. So, if you have these libraries on your system:
+<tscreen>
+<verb>
+/compat/linux/lib/libc.so.4.6.27
+/compat/linux/lib/libc.so.4 -> libc.so.4.6.27
+</verb>
+</tscreen>
+
+and you find a new binary that claims to require a later version
+according to the output of ldd:
+<tscreen>
+<verb>
+libc.so.4 (DLL Jump 4.5pl26) -> libc.so.4.6.29
+</verb>
+</tscreen>
+
+If it is only one or two versions out of date in the in the trailing
+digit then do not worry about copying /lib/libc.so.4.6.29 too, because
+the program should work fine with the slightly older version.
+However, if you like you can decide to replace the libc.so anyway, and
+that should leave you with:
+<tscreen>
+<verb>
+/compat/linux/lib/libc.so.4.6.29
+/compat/linux/lib/libc.so.4 -> libc.so.4.6.29
+</verb>
+</tscreen>
+
+<p>Please note that the symbolic link mechanism is <em>only</em>
+needed for Linux binaries, the FreeBSD runtime linker takes care of
+looking for matching major revision numbers itself, you do not need to
+worry about that.
+
+<sect2><heading>Configuring the ld.so -- for FreeBSD-current only</heading>
+
+<p>This section applies only to FreeBSD-current only. Those running
+FreeBSD-stable should skip this section.
+
+<p>Finally, if you run FreeBSD-current you must make sure that you
+have the Linux runtime linker and its config files on your system. You
+should copy these files from the Linux system to their appropriate
+place on your FreeBSD system (to the /compat/linux tree):
+<tscreen>
+<verb>
+/compat/linux/lib/ld.so
+/compat/linux/etc/ld.so.config
+</verb>
+</tscreen>
+
+<p>If you do not have access to a Linux system, you should get the
+extra files you need from various ftp sites. Information on where to
+look for the various files is appended below. For now, let us assume
+you know where to get the files.
+
+<p>
+Retrieve the following files (all from the same ftp site to avoid any
+version mismatches), and install them under /compat/linux
+(i.e. /foo/bar is installed as /compat/linux/foo/bar):
+<tscreen>
+<verb>
+/sbin/ldconfig
+/usr/bin/ldd
+/lib/libc.so.x.y.z
+/lib/ld.so
+</verb>
+</tscreen>
+
+<p>ldconfig and ldd do not necessarily need to be under /compat/linux,
+you can install them elsewhere in the system too. Just make sure they
+do not conflict with their FreeBSD counterparts. A good idea would be
+to install them in /usr/local/bin as ldconfig-linux and ldd-linux.
+<p>
+Create the file /compat/linux/etc/ld.so.conf, containing the
+directories in which the Linux runtime linker should look
+for shared libs. It is a plain text file, containing a directory
+name on each line. /lib and /usr/lib are standard, you could
+add the following:
+<tscreen>
+<verb>
+/usr/X11/lib
+/usr/local/lib
+</verb>
+</tscreen>
+
+<p>When a linux binary opens a library such as /lib/libc.so the
+emulator maps the name to /compat/linux/lib/libc.so internally. All
+linux libraries should be installed under /compat/linux (e.g.
+/compat/linux/lib/libc.so, /compat/linux/usr/X11/lib/libX11.so, etc.)
+in order for the emulator to find them.
+
+<p>Those running FreeBSD-current should run the Linux ldconfig program.
+<tscreen>
+<verb>
+% cd /compat/linux/lib
+% /compat/linux/sbin/ldconfig
+</verb>
+</tscreen>
+
+<p>Ldconfig is statically linked, so it does not need any shared
+libraries to run. It creates the file /compat/linux/etc/ld.so.cache
+which contains the names of all the shared libraries. It should rerun
+to recreate this file whenever you install additional shared
+libraries.
+
+On FreeBSD-stable do not install /compat/linux/etc/ld.so.cache or run
+ldconfig becuase in FreeBSD-stable the syscalls are implemented
+differently and ldconfig is not needed or used.
+
+<p>You should now be set up for Linux binaries which only need a
+shared libc. You can test this by running the Linux ldd on
+itself. Suppose that you have it installed as ldd-linux, it should
+produce something like:
+<tscreen>
+<verb>
+% ldd-linux `which ldd-linux`
+libc.so.4 (DLL Jump 4.5pl26) => /lib/libc.so.4.6.29
+</verb>
+</tscreen>
+
+<p>This being done, you are ready to install new Linux binaries.
+Whenever you install a new Linux program, you should check if it needs
+shared libraries, and if so, whether you have them installed in the
+/compat/linux tree. To do this, you run the Linux version ldd on the
+new program, and watch its output. ldd (see also the manual page for
+ldd(1)) will print a list of shared libraries that the program depends
+on, in the form majorname (jumpversion) => fullname.
+
+<p>If it prints "not found" instead of fullname it means that you
+need an extra library. Which library this is, is shown in majorname,
+which will be of the form libXXXX.so.N You will need to find a
+libXXXX.so.N.mm on a Linux ftp site, and install it on your
+system. The XXXX (name) and N (major revision number) should match;
+the minor number(s) mm are less important, though it is advised to
+take the most recent version.
+
+<sect1><heading>Configuring the host name resolver</heading>
+
+<p>If DNS does not work or you get the messages
+<tscreen>
+<verb>
+resolv+: "bind" is an invalid keyword
+resolv+: "hosts" is an invalid keyword
+</verb>
+</tscreen>
+
+then you need to configure a /compat/linux/etc/host.conf file
+containing:
+<tscreen>
+<verb>
+order hosts, bind
+multi on
+</verb>
+</tscreen>
+
+where the order here specifies that /etc/hosts is searched first and
+DNS is searched second. When /compat/linux/etc/host.conf is not
+installed linux applications find FreeBSD's /etc/host.conf and
+complain about the incompatible FreeBSD syntax. You should remove
+`bind,' if you have not configured a name-server using the
+/etc/resolv.conf file.
+
+<p>Lastly, those who run FreeBSD-stable need to set an the
+RESOLV_HOST_CONF environment variable so that applications will know
+how to search the host tables. If you run FreeBSD-current you can
+skip this. For the /bin/csh shell use:
+<tscreen>
+<verb>
+setenv RESOLV_HOST_CONF /compat/linux/etc/host.conf
+</verb>
+</tscreen>
+
+For /bin/sh use:
+<tscreen>
+<verb>
+RESOLV_HOST_CONF=/compat/linux/etc/host.conf; export RESOLV_HOST_CONF
+</verb>
+</tscreen>
+
+<sect1><heading>Finding the necessary files</heading>
+
+<p>Note: the information below is valid as of the time this document
+was written, but certain details such as names of ftp sites,
+directories and distribution names may have changed by the time you
+read this.
+
+<p>Linux is distributed by several groups that make their own set
+of binaries that they distribute. Each distribution has its own
+name, like ``Slackware'' or ``Yggdrasil''. The distributions are
+available on a lot of ftp sites. Sometimes the files are unpacked,
+and you can get the individual files you need, but mostly they
+are stored in distribution sets, usually consisting of subdirectories
+with gzipped tar files in them. The primary ftp sites for the
+distributions are:
+<verb>
+sunsite.unc.edu:/pub/Linux/distributions
+tsx-11.mit.edu:/pub/linux/distributions
+</verb>
+
+<p>
+Some European mirrors:
+<verb>
+ftp.luth.se:/pub/linux/distributions
+ftp.demon.co.uk:/pub/linux/distributions
+src.doc.ic.ac.uk:/packages/linux/distributions
+</verb>
+
+<p>For simplicity, let us concentrate on Slackware here. This
+distribution consists of a number of subdirectories, containing
+separate packages. Normally, they are controlled by an install
+program, but you can retrieve files "by hand" too. First of all, you
+will need to look in the "contents" subdir of the distribution. You
+will find a lot of small text files here describing the contents of the
+separate packages. The fastest way to look something up is to retrieve
+all the files in the contents subdirectory, and grep through them for
+the file you need. Here is an example of a list of files that you
+might need, and in which contents-file you will find it by grepping
+through them:
+<tabular ca=ll>
+Library <colsep>Package <rowsep>
+ld.so <colsep>ldso <rowsep>
+ldconfig <colsep>ldso <rowsep>
+ldd <colsep>ldso <rowsep>
+libc.so.4 <colsep>shlibs <rowsep>
+libX11.so.6.0 <colsep>xf_lib <rowsep>
+libXt.so.6.0 <colsep>xf_lib <rowsep>
+libX11.so.3 <colsep>oldlibs <rowsep>
+libXt.so.3 <colsep>oldlibs <rowsep>
+</tabular>
+
+<p>So, in this case, you will need the packages ldso, shlibs, xf_lib
+and oldlibs. In each of the contents-files for these packages, look
+for a line saying ``PACKAGE LOCATION'', it will tell you on which `disk'
+the package is, in our case it will tell us in which subdirectory we
+need to look. For our example, we would find the following locations:
+<tabular ca=ll>
+Package <colsep>Location <rowsep>
+ldso <colsep>diska2 <rowsep>
+shlibs <colsep>diska2 <rowsep>
+oldlibs <colsep>diskx6 <rowsep>
+xf_lib <colsep>diskx9 <rowsep>
+</tabular>
+
+<p>The locations called ``diskXX'' refer to the ``slakware/XX''
+subdirectories of the distribution, others may be found in the
+``contrib'' subdirectory. In this case, we could now retrieve the
+packages we need by retrieving the following files (relative to
+the root of the Slackware distribution tree):
+<tscreen>
+<verb>
+slakware/a2/ldso.tgz
+slakware/a2/shlibs.tgz
+slakware/x6/oldlibs/tgz
+slakware/x9/xf_lib.tgz
+</verb>
+</tscreen>
+
+<p>Extract the files from these gzipped tarfiles in your
+/compat/linux directory (possibly omitting or afterwards
+removing files you don't need), and you are done.
+
+<p><bf>See also:</bf>
+<verb>
+ftp.freebsd.org:pub/FreeBSD/2.0.5-RELEASE/xperimnt/linux-emu/README
+
+/usr/src/sys/i386/ibcs2/README.iBCS2
+</verb>
+
+<sect><heading>How to Install Mathematica on FreeBSD<label id="mathematica"></heading>
+
+<p><em>Contributed by &a.rich and &a.chuck</em>
+
+This document shows how to install the Linux binary
+distribution of Mathematica 2.2 on FreeBSD 2.1.
+
+<p>Mathematica supports Linux but not FreeBSD as it stands. So once
+you have configured your system for Linux compatibility you have most
+of what you need to run Mathematica.
+
+<p>For those who already have the student edition of
+Mathematica for DOS the cost of upgrading to the Linux
+version at the time this was written, March 1996, was
+&dollar;45.00. It can be ordered directly from Wolfram at
+(217) 398-6500 and paid for by credit card.
+
+<sect1><heading>Unpacking the Mathematica distribution</heading>
+<p>The binaries are currently distributed by Wolfram on CDROM.
+The CDROM has about a dozen tar files, each of which is a binary
+distribution for one of the supported architectures. The one
+for Linux is named LINUX.TAR. You can, for example, unpack this
+into /usr/local/Mathematica:
+<tscreen>
+<verb>
+% cd /usr/local
+% mkdir Mathematica
+% cd Mathematica
+% tar -xvf /cdrom/LINUX.TAR
+</verb>
+</tscreen>
+
+<sect1><heading>Obtaining your Mathematica Password</heading>
+<p>Before you can run Mathematica you will have to obtain
+a password from Wolfram that corresponds to your
+`machine ID.'
+
+<p>Once you have installed the linux compatibility runtime
+libraries and unpacked the mathematica you can obtain
+the `machine ID' by running the program `mathinfo' in
+the Install directory.
+<tscreen>
+<verb>
+% cd /usr/local/Mathematica/Install
+% mathinfo
+LINUX: 'ioctl' fd=5, typ=0x89(), num=0x27 not implemented
+richc.isdn.bcm.tmc.edu 9845-03452-90255
+%
+</verb>
+</tscreen>
+So, for example, the `machine ID' of `richc' is `9845-03452-90255'.
+You can ignore the message about the ioctl that is not
+implemented. It won't prevent Mathematica from running
+in any way and you can safely ignore it, though you
+will see the message every time you run Mathematica.
+
+<p>When you register with Wolfram, either by email, phone
+or fax, you'll give them the 'machine ID' and they will
+respond with a corresponding password consisting of
+groups of numbers. You need to add them both along
+with the machine name and license number in your
+mathpass file.
+
+You can do this by invoking:
+<tscreen>
+<verb>
+% cd /usr/local/Mathematica/Install
+% math.install
+</verb>
+</tscreen>
+It will ask you to enter your license number and the
+Wolfram supplied password. If you get them mixed up or
+for some reason the math.install fails, That's OK,
+because you can simply edit the file 'mathpass' in this
+same directory to correct the info manually.
+
+<p>After getting past the password, math.install will ask
+you if you accept their canned install defaults, or if
+you want to use your own. If you are like us and
+distrust all install programs, you probably want to
+specify the actual directories. Beware. Although the
+math.install program asks you to specify directories,
+it won't create them for you, so you should perhaps
+have a second window open with another shell so that
+you can create them before you give them to the install
+program. Or, if it fails, you
+can create the directories and then restart the
+math.install program. The directories we chose to
+create beforehand and specify to math.install were:
+<tscreen>
+<verb>
+/usr/local/Mathematica/bin for binaries
+/usr/local/Mathematica/man/man1 for man pages
+/usr/local/Mathematica/lib/X11 for the XKeysymb file
+</verb>
+</tscreen>
+You can also tell it to use /tmp/math.record for the
+system record file, where it puts logs of sessions.
+After this math.install will continue on to
+unpacking things and placing everything where it should
+go.
+
+<p>The Mathematica Notebook feature is included separately,
+as the X Front End, and you have to install it separately.
+To get the X Front End stuff correctly installed, cd
+into the /usr/local/Mathematica/FrontEnd directory and
+executed the ./xfe.install shell script. You'll have
+to tell it where to put things, but you don't have to
+create any directories because it uses all the same
+directories that had been created for math.install.
+When it finished, there should be a new shell script in
+/usr/local/Mathematica/bin called "mathematica".
+
+<p>Lastly, you need to modify each of the shell scripts that
+Mathematica has installed. At the beginning of every shell script in
+/usr/local/Mathematica/bin add the following line:
+<tscreen>
+<verb>
+XKEYSYMDB=/usr/local/Mathematica/lib/X11/XKeysymDB; export XKEYSYMDB
+</verb>
+</tscreen>
+This tells Mathematica were to find it's own version of the key
+mapping file XKeysymDB. Without this you will get pages of error
+messages about missing key mappings.
+
+On FreeBSD-stable you need to add the following as well:
+<tscreen>
+<verb>
+RESOLV_HOST_CONF=/compat/linux/etc/host.conf; export RESOLV_HOST_CONF
+</verb>
+</tscreen>
+This tells Mathematica to use the linux version of host.conf. This
+file has a different syntax from FreeBSD's host.conf, so you'll get an
+error message about /etc/host.conf if you leave this out.
+
+<p>You might want to also modify your /etc/manpath.config file
+to read the new man directory, and you may need to edit your
+~/.cshrc file to add /usr/local/Mathematica/bin
+to your path.
+
+<p>That's about all it takes, With this you should be able
+to type "mathematica" and get a really slick looking
+Mathematica Notebook screen up. Mathematica has included
+the Motif user interfaces, but it's compiled in statically,
+so you don't need the Motif libraries. Good luck doing this
+yourself!
+
+<sect1><heading>Bugs</heading>
+
+<p>The Notebook front end is known to hang sometimes when reading
+notebook files with an error messages similar to:
+<tscreen>
+<verb>
+File .../Untitled-1.mb appears to be broken for OMPR.257.0
+</verb>
+</tscreen>
+
+We haven't found the cause for this, but it only affects the
+Notebook's X window front end, not the mathematica engine itself. So
+the command line interface invoked by 'math' is unaffected by this
+bug.
+
+<sect1><heading>Acknowledgments</heading>
+
+<p>A well-deserved thanks should go to &a.sos; and &a.peter;
+who made linux emulation what it is today, and Michael Smith who
+drove these two guys like dogs to get it to the point where it runs
+Linux binaries better than linux! :-)
diff --git a/share/man/man4/update.4 b/share/man/man4/update.4
new file mode 100644
index 000000000000..faaf35301a07
--- /dev/null
+++ b/share/man/man4/update.4
@@ -0,0 +1,82 @@
+.\" Copyright (c) 1996
+.\" Mike Pritchard <mpp@FreeBSD.org>. All rights reserved.
+.\"
+.\" Copyright (c) 1991, 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.
+.\"
+.Dd February 11, 1996
+.Dt UPDATE 4
+.Os FreeBSD
+.Sh NAME
+.Nm update
+.Nd flush internal filesystem caches to disk periodically
+.Sh SYNOPSIS
+.Nm update
+.Sh DESCRIPTION
+The
+.Nm update
+kernel process helps protect the integrity of disk volumes
+by flushing
+volatile cached filesystem data
+to disk. This is done at thirty second intervals by default.
+The time period may be changed by using
+.Xr sysctl 8
+to modify the
+.Va kern.update
+variable.
+The
+.Nm update
+process does the equivalent of the
+.Xr sync 2
+function call to do the task.
+.Sh SEE ALSO
+.Xr sync 2 ,
+.Xr fsck 8 ,
+.Xr init 8 ,
+.Xr rc 8 ,
+.Xr sync 8 ,
+.Xr sysctl 8
+.Sh BUGS
+It is possible on some systems that a
+.Xr sync
+occurring simultaneously with a crash may cause
+file system damage. See
+.Xr fsck 8 .
+.Sh HISTORY
+An
+.Nm update
+command appeared in
+.At v6 ,
+and was usually started by /etc/rc when the system went multi-user.
+A kernel initiated
+.Nm update
+process first appeared in
+.Fx 2.0 .
diff --git a/share/man/man5/hosts.lpd.5 b/share/man/man5/hosts.lpd.5
new file mode 100644
index 000000000000..4edef0a929ef
--- /dev/null
+++ b/share/man/man5/hosts.lpd.5
@@ -0,0 +1,53 @@
+.\" Copyright (c) 1983, 1991, 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.
+.\"
+.Dd Mai 1996
+.Dt HOSTS.LPD 5
+.Os FreeBSD
+.Sh NAME
+.Nm hosts.lpd
+.Nd trusted hosts that may use local print services
+.Sh DESCRIPTION
+The
+.Nm hosts.lpd
+file contains a list of hostnames or IP addresses
+that are allowed to use your local print services.
+List every hostname or IP address on a line itself.
+.Sh FILES
+.Bl -tag -width /etc/hosts.lpdxxxxx -compact
+.It Pa /etc/hosts.lpd
+The
+.Nm hosts.lpd
+file resides in
+.Pa /etc .
+.Sh SEE ALSO
+.Xr printcap 5 ,
+.Xr lpd 8 .
diff --git a/usr.bin/sgmls/sgmls/alloc.h b/usr.bin/sgmls/sgmls/alloc.h
new file mode 100644
index 000000000000..d732178e735d
--- /dev/null
+++ b/usr.bin/sgmls/sgmls/alloc.h
@@ -0,0 +1,8 @@
+/* alloc.h */
+
+typedef unsigned SIZE_T;
+
+/* Like malloc and realloc, but don't return if no memory is available. */
+
+extern UNIV xmalloc P((SIZE_T));
+extern UNIV xrealloc P((UNIV, SIZE_T));
diff --git a/usr.bin/sgmls/sgmls/catalog.c b/usr.bin/sgmls/sgmls/catalog.c
new file mode 100644
index 000000000000..164b97d04957
--- /dev/null
+++ b/usr.bin/sgmls/sgmls/catalog.c
@@ -0,0 +1,925 @@
+/* Normalize public identifiers to handle ISO 8879[-:]1986 problem.
+What should happen if there's a duplicate in a single catalog entry file? */
+
+#include "config.h"
+#include "std.h"
+#include "catalog.h"
+
+#ifdef USE_PROTOTYPES
+#define P(parms) parms
+#else
+#define P(parms) ()
+#endif
+
+#include "alloc.h"
+
+#define MINIMUM_DATA_CHARS \
+"abcdefghijklmnopqrstuvwxyz\
+ABCDEFGHIJKLMNOPQRSTUVWXYZ\
+0123456789-.'()+,/:=?"
+
+#define N_DECL_TYPE 3
+#define PUBLIC_ID_MAP N_DECL_TYPE
+#define N_TABLES (N_DECL_TYPE + 1)
+
+enum literal_type {
+ NORMAL_LITERAL,
+ MINIMUM_LITERAL
+};
+
+typedef enum {
+ EOF_PARAM,
+ NAME_PARAM,
+ LITERAL_PARAM
+} PARAM_TYPE;
+
+enum catalog_error {
+ E_NAME_EXPECTED,
+ E_LITERAL_EXPECTED,
+ E_ARG_EXPECTED,
+ E_MINIMUM_DATA,
+ E_EOF_COMMENT,
+ E_EOF_LITERAL,
+ E_NUL_CHAR,
+ E_CANNOT_OPEN,
+ E_GETC,
+ E_FCLOSE
+};
+
+#define FIRST_SYSTEM_ERROR E_CANNOT_OPEN
+
+#define HASH_TABLE_INITIAL_SIZE 8
+#define HASH_TABLE_MAX_SIZE (((SIZE_T)-1)/sizeof(struct hash_table_entry *))
+
+struct hash_table_entry {
+ int file_index;
+ const char *key;
+ const char *system_id;
+};
+
+/* Number of bytes per string block. */
+#define BLOCK_SIZE 1000
+
+/* Bytes follow the struct. */
+
+struct string_block {
+ struct string_block *next;
+};
+
+struct hash_table {
+ struct hash_table_entry **v;
+ SIZE_T size; /* must be power of 2 */
+ SIZE_T used;
+ SIZE_T used_limit;
+};
+
+struct catalog {
+ struct hash_table tables[N_TABLES];
+ char **files;
+ int n_files;
+ struct string_block *blocks;
+ char *block_ptr;
+ SIZE_T block_spare;
+ CATALOG_ERROR_HANDLER error_handler;
+ int loaded;
+};
+
+struct parser {
+ FILE *fp;
+ struct catalog *cat;
+ char *param;
+ SIZE_T param_length;
+ SIZE_T param_alloc;
+ int file_index;
+ const char *filename;
+ unsigned long newline_count;
+ char minimum_data[256];
+};
+
+static
+VOID add_catalog_file P((struct catalog *cat, const char *filename,
+ SIZE_T length));
+static
+VOID load P((struct catalog *cat));
+static
+VOID parse_file P((struct parser *parser));
+static
+VOID parse_public P((struct parser *parser));
+static
+VOID parse_name_map P((struct parser *parser,
+ int decl_type));
+static
+int parse_arg P((struct parser *parser));
+static
+PARAM_TYPE parse_param P((struct parser *parser, enum literal_type));
+static
+VOID skip_comment P((struct parser *parser));
+static
+PARAM_TYPE parse_literal P((struct parser *parser, int lit,
+ enum literal_type));
+static
+PARAM_TYPE parse_name P((struct parser *parser, int first_char));
+static
+VOID param_grow P((struct parser *parser));
+static
+const char *param_save P((struct parser *parser));
+static
+char *alloc_bytes P((struct catalog *catalog, SIZE_T n));
+static
+int param_equal P((struct parser *parser, const char *key));
+static
+int hash_table_add P((struct hash_table *table, const char *s,
+ const char *system_id, int file_index));
+static
+struct hash_table_entry *hash_table_lookup P((struct hash_table *table,
+ const char *s));
+static
+struct hash_table_entry *hash_table_lookup_subst P((struct hash_table *table,
+ const char *subst_table,
+ const char *s));
+static
+VOID hash_table_init P((struct hash_table *p));
+static
+VOID hash_table_delete P((struct hash_table *p));
+static
+SIZE_T hash_table_start_index P((struct hash_table *p, const char *s));
+static
+int subst_equal P((const char *subst_table, const char *s1, const char *s2));
+static
+VOID error P((struct parser *parser, enum catalog_error err));
+
+#define param_char(parser, c) \
+ ((((parser)->param_length < (parser)->param_alloc) \
+ || (param_grow(parser), 1)), \
+ ((parser)->param[(parser)->param_length] = (c)), \
+ ((parser)->param_length += 1))
+
+#define param_init(parser) ((parser)->param_length = 0)
+#define param_chop(parser) \
+ ((parser)->param_length = (parser)->param_length - 1)
+
+const char *catalog_error_text(error_number)
+ int error_number;
+{
+ static const char *text[] = {
+ "Name expected",
+ "Literal expected",
+ "Missing argument",
+ "Only minimum data characters allowed in a public identifier",
+ "End of file in comment",
+ "End of file in literal",
+ "Nul character is not allowed",
+ "Cannot open `%s': %s",
+ "Error reading `%s': %s",
+ "Error closing `%s': %s"
+ };
+ if (error_number >= 0 && error_number < sizeof(text)/sizeof(text[0]))
+ return text[error_number];
+ else
+ return "(invalid error number)";
+}
+
+
+CATALOG catalog_create(error_handler)
+ CATALOG_ERROR_HANDLER error_handler;
+{
+ int i;
+ struct catalog *p = (struct catalog *)xmalloc(sizeof(struct catalog));
+ p->loaded = 0;
+ p->n_files = 0;
+ p->files = 0;
+ p->error_handler = error_handler;
+ p->blocks = 0;
+ p->block_spare = 0;
+ p->block_ptr = 0;
+ for (i = 0; i < N_TABLES; i++)
+ hash_table_init(p->tables + i);
+ return (CATALOG)p;
+}
+
+VOID catalog_delete(cat)
+ CATALOG cat;
+{
+ int i;
+ struct string_block *block;
+ struct catalog *catalog = (struct catalog *)cat;
+ for (i = 0; i < 4; i++)
+ hash_table_delete(catalog->tables + i);
+ if (catalog->files)
+ free(catalog->files);
+ block = catalog->blocks;
+ while (block) {
+ struct string_block *tem = block;
+ block = block->next;
+ free((UNIV)tem);
+ }
+ catalog->blocks = 0;
+ free((UNIV)catalog);
+}
+
+VOID catalog_load_file(p, filename)
+ CATALOG p;
+ const char *filename;
+{
+ add_catalog_file((struct catalog *)p, filename, strlen(filename));
+}
+
+int catalog_lookup_entity(cat, public_id, name, decl_type, subst_table,
+ system_id, catalog_file)
+ CATALOG cat;
+ const char *public_id;
+ const char *name;
+ enum catalog_decl_type decl_type;
+ const char *subst_table;
+ const char **system_id;
+ const char **catalog_file;
+{
+ struct catalog *catalog = (struct catalog *)cat;
+ const struct hash_table_entry *entry = 0;
+ if (!catalog->loaded)
+ load(catalog);
+ if (public_id)
+ entry = hash_table_lookup(catalog->tables + PUBLIC_ID_MAP, public_id);
+ if (name
+ && decl_type >= 0
+ && decl_type < N_DECL_TYPE
+ && (!entry || entry->file_index > 0)) {
+ const struct hash_table_entry *entity_entry = 0;
+ if (!subst_table)
+ entity_entry = hash_table_lookup(catalog->tables + decl_type, name);
+ else
+ entity_entry = hash_table_lookup_subst(catalog->tables + decl_type,
+ subst_table, name);
+ if (!entry
+ || (entity_entry
+ && entity_entry->file_index < entry->file_index))
+ entry = entity_entry;
+ }
+ if (!entry)
+ return 0;
+ *system_id = entry->system_id;
+ *catalog_file = catalog->files[entry->file_index];
+ return 1;
+}
+
+static
+VOID add_catalog_file(cat, filename, length)
+ struct catalog *cat;
+ const char *filename;
+ SIZE_T length;
+{
+ char *s;
+ if (!cat->files)
+ cat->files = (char **)xmalloc(sizeof(char *));
+ else
+ cat->files
+ = (char **)xrealloc(cat->files, (cat->n_files + 1)*sizeof(char *));
+ s = alloc_bytes(cat, length + 1);
+ memcpy(s, filename, length);
+ s[length] = '\0';
+ cat->files[cat->n_files] = s;
+ cat->n_files += 1;
+}
+
+static
+VOID load(cat)
+ struct catalog *cat;
+{
+ int i;
+ const char *p;
+ struct parser parser;
+ const char *env_var;
+ int optional_file_index = cat->n_files;
+
+ cat->loaded = 1;
+ parser.param = 0;
+ parser.param_alloc = 0;
+ parser.cat = cat;
+ for (i = 0; i < 256; i++)
+ parser.minimum_data[i] = 0;
+ for (p = MINIMUM_DATA_CHARS; *p; p++)
+ parser.minimum_data[(unsigned char)*p] = 1;
+ env_var = getenv(CATALOG_FILES_ENV_VAR);
+ if (!env_var || *env_var == '\0')
+ env_var = DEFAULT_CATALOG_FILES;
+ for (;;) {
+ for (p = env_var; *p && *p != PATH_FILE_SEP; p++)
+ ;
+ if (p > env_var)
+ add_catalog_file(cat, env_var, p - env_var);
+ if (!*p)
+ break;
+ env_var = p + 1;
+ }
+ for (i = 0; i < cat->n_files; i++) {
+ parser.filename = cat->files[i];
+ parser.newline_count = 0;
+ parser.fp = fopen(cat->files[i], "r");
+ if (!parser.fp) {
+ if (i < optional_file_index)
+ error(&parser, E_CANNOT_OPEN);
+ }
+ else {
+ parser.file_index = i;
+ parse_file(&parser);
+ errno = 0;
+ if (fclose(parser.fp) < 0)
+ error(&parser, E_FCLOSE);
+ }
+ }
+ if (parser.param)
+ free(parser.param);
+}
+
+static
+VOID parse_file(parser)
+ struct parser *parser;
+{
+ int skipping = 0;
+ for (;;) {
+ PARAM_TYPE type = parse_param(parser, NORMAL_LITERAL);
+ if (type == NAME_PARAM) {
+ if (param_equal(parser, "PUBLIC"))
+ parse_public(parser);
+ else if (param_equal(parser, "ENTITY"))
+ parse_name_map(parser, CATALOG_ENTITY_DECL);
+ else if (param_equal(parser, "DOCTYPE"))
+ parse_name_map(parser, CATALOG_DOCTYPE_DECL);
+ else if (param_equal(parser, "LINKTYPE"))
+ parse_name_map(parser, CATALOG_LINKTYPE_DECL);
+ else
+ skipping = 1;
+ }
+ else if (type == EOF_PARAM)
+ break;
+ else if (!skipping) {
+ skipping = 1;
+ error(parser, E_NAME_EXPECTED);
+ }
+ }
+}
+
+static
+VOID parse_public(parser)
+ struct parser *parser;
+{
+ const char *public_id;
+
+ if (parse_param(parser, MINIMUM_LITERAL) != LITERAL_PARAM)
+ error(parser, E_LITERAL_EXPECTED);
+ public_id = param_save(parser);
+ if (!parse_arg(parser))
+ return;
+ hash_table_add(parser->cat->tables + PUBLIC_ID_MAP,
+ public_id, param_save(parser), parser->file_index);
+}
+
+static
+VOID parse_name_map(parser, decl_type)
+ struct parser *parser;
+ int decl_type;
+{
+ const char *name;
+
+ if (!parse_arg(parser))
+ return;
+ name = param_save(parser);
+ if (!parse_arg(parser))
+ return;
+ hash_table_add(parser->cat->tables + decl_type,
+ name, param_save(parser), parser->file_index);
+}
+
+static
+int parse_arg(parser)
+ struct parser *parser;
+{
+ PARAM_TYPE parm = parse_param(parser, NORMAL_LITERAL);
+ if (parm != NAME_PARAM && parm != LITERAL_PARAM) {
+ error(parser, E_ARG_EXPECTED);
+ return 0;
+ }
+ return 1;
+}
+
+static
+PARAM_TYPE parse_param(parser, lit_type)
+ struct parser *parser;
+ enum literal_type lit_type;
+{
+ for (;;) {
+ int c = getc(parser->fp);
+ switch (c) {
+ case EOF:
+ if (ferror(parser->fp))
+ error(parser, E_GETC);
+ return EOF_PARAM;
+ case '"':
+ case '\'':
+ return parse_literal(parser, c, lit_type);
+ case '\n':
+ parser->newline_count += 1;
+ break;
+ case '\t':
+ case ' ':
+ break;
+ case '\0':
+ error(parser, E_NUL_CHAR);
+ break;
+ case '-':
+ c = getc(parser->fp);
+ if (c == '-') {
+ skip_comment(parser);
+ break;
+ }
+ ungetc(c, parser->fp);
+ c = '-';
+ /* fall through */
+ default:
+ return parse_name(parser, c);
+ }
+ }
+}
+
+static
+VOID skip_comment(parser)
+ struct parser *parser;
+{
+ FILE *fp = parser->fp;
+ for (;;) {
+ int c = getc(fp);
+ if (c == '-') {
+ c = getc(fp);
+ if (c == '-')
+ return;
+ }
+ if (c == EOF) {
+ if (ferror(fp))
+ error(parser, E_GETC);
+ error(parser, E_EOF_COMMENT);
+ return;
+ }
+ if (c == '\n')
+ parser->newline_count += 1;
+ }
+}
+
+static
+PARAM_TYPE parse_literal(parser, lit, lit_type)
+ struct parser *parser;
+ int lit;
+ enum literal_type lit_type;
+{
+ enum { no, yes_begin, yes_middle } skipping = yes_begin;
+ FILE *fp = parser->fp;
+ param_init(parser);
+ for (;;) {
+ int c = getc(fp);
+ if (c == lit)
+ break;
+ switch (c) {
+ case '\0':
+ error(parser, E_NUL_CHAR);
+ break;
+ case EOF:
+ if (ferror(fp))
+ error(parser, E_GETC);
+ error(parser, E_EOF_LITERAL);
+ return LITERAL_PARAM;
+ case '\n':
+ parser->newline_count += 1;
+ /* fall through */
+ case ' ':
+ if (lit_type == MINIMUM_LITERAL) {
+ if (skipping == no) {
+ param_char(parser, ' ');
+ skipping = yes_middle;
+ }
+ }
+ else
+ param_char(parser, c);
+ break;
+ default:
+ if (lit_type == MINIMUM_LITERAL) {
+ if (!parser->minimum_data[c])
+ error(parser, E_MINIMUM_DATA);
+ else {
+ skipping = no;
+ param_char(parser, c);
+ }
+ }
+ else
+ param_char(parser, c);
+ break;
+ }
+ }
+ if (skipping == yes_middle)
+ param_chop(parser);
+ return LITERAL_PARAM;
+}
+
+static
+PARAM_TYPE parse_name(parser, first_char)
+ struct parser *parser;
+ int first_char;
+{
+ FILE *fp = parser->fp;
+ param_init(parser);
+ param_char(parser, first_char);
+ for (;;) {
+ int c = getc(fp);
+ switch (c) {
+ case '\0':
+ error(parser, E_NUL_CHAR);
+ break;
+ case EOF:
+ if (ferror(fp))
+ error(parser, E_GETC);
+ goto done;
+ case '\n':
+ parser->newline_count += 1;
+ goto done;
+ case ' ':
+ case '\t':
+ goto done;
+ case '"':
+ case '\'':
+ ungetc(c, fp);
+ goto done;
+ default:
+ param_char(parser, c);
+ }
+ }
+ done:
+ return NAME_PARAM;
+}
+
+static
+VOID param_grow(parser)
+ struct parser *parser;
+{
+ if (parser->param_alloc == 0) {
+ parser->param_alloc = 256;
+ parser->param = xmalloc(parser->param_alloc);
+ }
+ else {
+ parser->param_alloc *= 2;
+ parser->param = xrealloc(parser->param, parser->param_alloc);
+ }
+}
+
+static
+const char *param_save(parser)
+ struct parser *parser;
+{
+ char *s = alloc_bytes(parser->cat, parser->param_length + 1);
+ memcpy(s, parser->param, parser->param_length);
+ s[parser->param_length] = '\0';
+ return s;
+}
+
+static
+char *alloc_bytes(catalog, n)
+ struct catalog *catalog;
+ SIZE_T n;
+{
+ char *tem;
+ if (n > catalog->block_spare) {
+ struct string_block *block;
+ SIZE_T block_size = n > BLOCK_SIZE ? n : BLOCK_SIZE;
+ block
+ = (struct string_block *)xmalloc(sizeof(struct string_block)
+ + block_size);
+ block->next = catalog->blocks;
+ catalog->blocks = block;
+ catalog->block_ptr = (char *)(block + 1);
+ catalog->block_spare = block_size;
+ }
+ tem = catalog->block_ptr;
+ catalog->block_ptr += n;
+ catalog->block_spare -= n;
+ return tem;
+}
+
+
+/* Return 1 if the current parameter is equal to key. */
+
+static
+int param_equal(parser, key)
+ struct parser *parser;
+ const char *key;
+{
+ const char *param = parser->param;
+ SIZE_T param_length = parser->param_length;
+ for (; param_length > 0; param++, param_length--, key++) {
+ unsigned char c;
+ if (*key == '\0')
+ return 0;
+ c = *param;
+ if (islower(c))
+ c = toupper(c);
+ if (c != (unsigned char)*key)
+ return 0;
+ }
+ return *key == '\0';
+}
+
+/* Return 0 if it was a duplicate. */
+
+static
+int hash_table_add(table, s, system_id, file_index)
+ struct hash_table *table;
+ const char *s;
+ const char *system_id;
+ int file_index;
+{
+ SIZE_T i;
+ struct hash_table_entry *p;
+
+ if (table->size > 0) {
+ i = hash_table_start_index(table, s);
+ while (table->v[i] != 0) {
+ if (strcmp(table->v[i]->key, s) == 0)
+ return 0;
+ if (i == 0)
+ i = table->size;
+ i--;
+ }
+ }
+ if (table->used >= table->used_limit) {
+ SIZE_T j;
+ struct hash_table_entry **old_table = table->v;
+ SIZE_T old_size = table->size;
+ if (old_size == 0) {
+ table->size = HASH_TABLE_INITIAL_SIZE;
+ table->used_limit = table->size/2;
+ }
+ else {
+ if (old_size > HASH_TABLE_MAX_SIZE/2) {
+ if (old_size == HASH_TABLE_MAX_SIZE)
+ return 0; /* FIXME: give an error? */
+ table->size = HASH_TABLE_MAX_SIZE;
+ table->used_limit = HASH_TABLE_MAX_SIZE - 1;
+ }
+ else {
+ table->size = (old_size << 1);
+ table->used_limit = table->size/2;
+ }
+ }
+ table->v
+ = (struct hash_table_entry **)xmalloc(sizeof(struct hash_table_entry *)
+ * table->size);
+ for (j = 0; j < table->size; j++)
+ table->v[j] = 0;
+ for (j = 0; j < old_size; j++)
+ if (old_table[j]) {
+ SIZE_T k = hash_table_start_index(table, old_table[j]->key);
+ while (table->v[k] != 0) {
+ if (k == 0)
+ k = table->size;
+ k--;
+ }
+ table->v[k] = old_table[j];
+ }
+ if (old_table)
+ free((UNIV)old_table);
+ i = hash_table_start_index(table, s);
+ while (table->v[i] != 0) {
+ if (i == 0)
+ i = table->size;
+ i--;
+ }
+ }
+ p = (struct hash_table_entry *)xmalloc(sizeof(struct hash_table_entry));
+ p->key = s;
+ p->system_id = system_id;
+ p->file_index = file_index;
+ table->v[i] = p;
+ table->used += 1;
+ return 1;
+}
+
+static
+struct hash_table_entry *hash_table_lookup(table, s)
+ struct hash_table *table;
+ const char *s;
+{
+ if (table->size > 0) {
+ SIZE_T i;
+ i = hash_table_start_index(table, s);
+ while (table->v[i] != 0) {
+ if (strcmp(table->v[i]->key, s) == 0)
+ return table->v[i];
+ if (i == 0)
+ i = table->size;
+ i--;
+ }
+ }
+ return 0;
+}
+
+static
+struct hash_table_entry *hash_table_lookup_subst(table, subst_table, s)
+ struct hash_table *table;
+ const char *subst_table;
+ const char *s;
+{
+ SIZE_T i;
+ for (i = 0; i < table->size; i++) {
+ struct hash_table_entry *p = table->v[i];
+ if (p && subst_equal(subst_table, s, p->key))
+ return p;
+ }
+ return 0;
+}
+
+static
+VOID hash_table_init(p)
+ struct hash_table *p;
+{
+ p->v = 0;
+ p->size = 0;
+ p->used = 0;
+ p->used_limit = 0;
+}
+
+static
+VOID hash_table_delete(p)
+ struct hash_table *p;
+{
+ if (p->v) {
+ SIZE_T i;
+ for (i = 0; i < p->size; i++)
+ if (p->v[i])
+ free(p->v[i]);
+ free(p->v);
+ }
+}
+
+static
+SIZE_T hash_table_start_index(p, s)
+ struct hash_table *p;
+ const char *s;
+{
+ unsigned long h = 0;
+ while (*s)
+ h = (h << 5) + h + (unsigned char)*s++;
+ return (h & (p->size - 1));
+}
+
+/* s1 has already been substituted; s2 has not */
+
+static
+int subst_equal(subst_table, s1, s2)
+ const char *subst_table;
+ const char *s1;
+ const char *s2;
+{
+ for (; *s1 == subst_table[(unsigned char)*s2]; s1++, s2++)
+ if (*s1 == '\0')
+ return 1;
+ return 0;
+}
+
+static
+VOID error(parser, err)
+ struct parser *parser;
+ enum catalog_error err;
+{
+ (*parser->cat->error_handler)(parser->filename,
+ parser->newline_count + 1,
+ err,
+ (err >= FIRST_SYSTEM_ERROR
+ ? CATALOG_SYSTEM_ERROR
+ : 0),
+ (err >= FIRST_SYSTEM_ERROR
+ ? errno
+ : 0));
+}
+
+#ifdef MAIN
+
+static const char *program_name;
+
+#include "getopt.h"
+
+static VOID usage P((void));
+static VOID out_of_memory P((void));
+static VOID handle_catalog_error P((const char *filename,
+ unsigned long lineno,
+ int error_number,
+ unsigned flags,
+ int sys_errno));
+
+int main(argc, argv)
+ int argc;
+ char **argv;
+{
+ int entity_flag = 0;
+ enum catalog_decl_type entity_type = CATALOG_NO_DECL;
+ char *public_id = 0;
+ char *name = 0;
+ int exit_status;
+ int opt;
+ CATALOG catalog;
+ int i;
+ const char *file;
+ const char *system_id;
+
+ program_name = argv[0];
+
+ while ((opt = getopt(argc, argv, "edl")) != EOF)
+ switch (opt) {
+ case 'e':
+ entity_flag = 1;
+ entity_type = CATALOG_ENTITY_DECL;
+ break;
+ case 'd':
+ entity_flag = 1;
+ entity_type = CATALOG_DOCTYPE_DECL;
+ break;
+ case 'l':
+ entity_flag = 1;
+ entity_type = CATALOG_LINKTYPE_DECL;
+ break;
+ case '?':
+ usage();
+ }
+ if (argc - optind < 2)
+ usage();
+ if (entity_flag)
+ name = argv[optind];
+ else
+ public_id = argv[optind];
+
+ catalog = catalog_create(handle_catalog_error);
+ for (i = optind + 1; i < argc; i++)
+ catalog_load_file(catalog, argv[i]);
+ if (catalog_lookup_entity(catalog, public_id, name, entity_type, (char *)0,
+ &system_id, &file)) {
+ exit_status = 0;
+ fprintf(stderr, "%s (%s)\n", system_id, file);
+ }
+ else {
+ fprintf(stderr, "not found\n");
+ exit_status = 1;
+ }
+ catalog_delete(catalog);
+ return exit_status;
+}
+
+static
+VOID usage()
+{
+ fprintf(stderr, "usage: %s [-e] [-d] [-l] id file ...\n",
+ program_name);
+ exit(1);
+}
+
+static
+VOID handle_catalog_error(filename, lineno, error_number, flags, sys_errno)
+ const char *filename;
+ unsigned long lineno;
+ int error_number;
+ unsigned flags;
+ int sys_errno;
+{
+ fprintf(stderr, "%s:", program_name);
+ if (flags & CATALOG_SYSTEM_ERROR) {
+ putc(' ', stderr);
+ fprintf(stderr, catalog_error_text(error_number), filename);
+ putc('\n', stderr);
+ }
+ else
+ fprintf(stderr, "%s:%lu: %s\n", filename, lineno,
+ catalog_error_text(error_number));
+ fflush(stderr);
+}
+
+UNIV xmalloc(n)
+ SIZE_T n;
+{
+ UNIV p = malloc(n);
+ if (!p)
+ out_of_memory();
+ return p;
+}
+
+UNIV xrealloc(p, n)
+ UNIV p;
+ SIZE_T n;
+{
+ p = realloc(p, n);
+ if (!p)
+ out_of_memory();
+ return p;
+}
+
+static
+VOID out_of_memory()
+{
+ fprintf(stderr, "%s: out of memory\n", program_name);
+ exit(1);
+}
+
+#endif /* MAIN */
diff --git a/usr.bin/sgmls/sgmls/catalog.h b/usr.bin/sgmls/sgmls/catalog.h
new file mode 100644
index 000000000000..b9509a5c9af4
--- /dev/null
+++ b/usr.bin/sgmls/sgmls/catalog.h
@@ -0,0 +1,45 @@
+#ifndef CATALOG_H
+#define CATALOG_H 1
+
+enum catalog_decl_type {
+ CATALOG_NO_DECL = -1,
+ CATALOG_ENTITY_DECL,
+ CATALOG_DOCTYPE_DECL,
+ CATALOG_LINKTYPE_DECL
+};
+
+#define CATALOG_SYSTEM_ERROR 1
+
+#ifdef __STDC__
+
+typedef void *CATALOG;
+typedef void (*CATALOG_ERROR_HANDLER)(const char *filename,
+ unsigned long lineno,
+ int error_number,
+ unsigned flags,
+ int sys_errno);
+CATALOG catalog_create(CATALOG_ERROR_HANDLER);
+void catalog_load_file(CATALOG, const char *);
+void catalog_delete(CATALOG);
+int catalog_lookup_entity(CATALOG,
+ const char *public_id,
+ const char *name,
+ enum catalog_decl_type,
+ const char *subst_table,
+ const char **system_id,
+ const char **catalog_file);
+const char *catalog_error_text(int error_number);
+
+#else /* not __STDC__ */
+
+typedef char *CATALOG;
+typedef void (*CATALOG_ERROR_HANDLER)();
+CATALOG catalog_create();
+void catalog_load_file();
+void catalog_delete();
+int catalog_lookup_entity();
+char *catalog_error_text();
+
+#endif /* not __STDC__ */
+
+#endif /* not CATALOG_H */